diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-01-11 17:26:19 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-01-11 17:26:19 +0000 |
commit | 354a420bc1ddcc46b837a4e99e874195a53b7d57 (patch) | |
tree | a36c69a2652bde6a62ef7f35ae3f793dec229775 | |
parent | f1b851a7ece3a993bb07269a730dd82f7e60a6ac (diff) | |
download | gnunet-354a420bc1ddcc46b837a4e99e874195a53b7d57.tar.gz gnunet-354a420bc1ddcc46b837a4e99e874195a53b7d57.zip |
-parsing for UDP IPv4 replies
-rw-r--r-- | src/vpn/gnunet-service-vpn.c | 203 |
1 files changed, 94 insertions, 109 deletions
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c index 3b9fe02e4..7eeb76908 100644 --- a/src/vpn/gnunet-service-vpn.c +++ b/src/vpn/gnunet-service-vpn.c | |||
@@ -990,47 +990,96 @@ receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
990 | const struct GNUNET_MessageHeader *message, | 990 | const struct GNUNET_MessageHeader *message, |
991 | const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) | 991 | const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) |
992 | { | 992 | { |
993 | // FIXME: parse message, build IP packet, give to TUN! | ||
994 | #if 0 | ||
995 | GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1); | ||
996 | struct remote_addr *s = (struct remote_addr *) desc; | ||
997 | struct udp_pkt *pkt = (struct udp_pkt *) (desc + 1); | ||
998 | const struct GNUNET_PeerIdentity *other = sender; | ||
999 | struct TunnelState *ts = *tunnel_ctx; | 993 | struct TunnelState *ts = *tunnel_ctx; |
994 | const struct GNUNET_EXIT_UdpReplyMessage *reply; | ||
995 | size_t mlen; | ||
1000 | 996 | ||
1001 | if (16 == ts->addrlen) | 997 | mlen = ntohs (message->size); |
998 | if (mlen < sizeof (struct GNUNET_EXIT_UdpReplyMessage)) | ||
1002 | { | 999 | { |
1003 | size_t size = | 1000 | GNUNET_break_op (0); |
1004 | sizeof (struct ip6_udp) + ntohs (pkt->len) - 1 - | 1001 | return GNUNET_SYSERR; |
1005 | sizeof (struct udp_pkt); | 1002 | } |
1006 | 1003 | if (NULL == ts->heap_node) | |
1007 | struct ip6_udp *pkt6 = alloca (size); | 1004 | { |
1008 | 1005 | GNUNET_break_op (0); | |
1009 | GNUNET_assert (pkt6 != NULL); | 1006 | return GNUNET_SYSERR; |
1010 | 1007 | } | |
1011 | if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK) | 1008 | reply = (const struct GNUNET_EXIT_UdpReplyMessage *) message; |
1012 | new_ip6addr (&pkt6->ip6_hdr.sadr, &other->hashPubKey, desc); | 1009 | mlen -= sizeof (struct GNUNET_EXIT_UdpReplyMessage); |
1013 | else | 1010 | switch (ts->af) |
1014 | new_ip6addr_remote (&pkt6->ip6_hdr.sadr, s->addr, s->addrlen); | 1011 | { |
1015 | 1012 | case AF_INET: | |
1016 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1013 | { |
1017 | "Relaying calc:%d gnu:%d udp:%d bytes!\n", size, | 1014 | size_t size = sizeof (struct ip4_header) |
1018 | ntohs (message->size), ntohs (pkt->len)); | 1015 | + sizeof (struct udp_packet) |
1019 | 1016 | + sizeof (struct GNUNET_MessageHeader) + | |
1020 | pkt6->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | 1017 | sizeof (struct tun_header) + |
1021 | pkt6->shdr.size = htons (size); | 1018 | mlen; |
1022 | 1019 | { | |
1023 | pkt6->tun.flags = 0; | 1020 | char buf[size]; |
1024 | pkt6->tun.type = htons (0x86dd); | 1021 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; |
1025 | 1022 | struct tun_header *tun = (struct tun_header*) &msg[1]; | |
1026 | pkt6->ip6_hdr.version = 6; | 1023 | struct ip4_header *ipv4 = (struct ip4_header *) &tun[1]; |
1027 | pkt6->ip6_hdr.tclass_h = 0; | 1024 | struct udp_packet *udp = (struct udp_packet *) &ipv4[1]; |
1028 | pkt6->ip6_hdr.tclass_l = 0; | 1025 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); |
1029 | pkt6->ip6_hdr.flowlbl = 0; | 1026 | msg->size = htons (size); |
1030 | pkt6->ip6_hdr.paylgth = pkt->len; | 1027 | tun->flags = htons (0); |
1031 | pkt6->ip6_hdr.nxthdr = IPPROTO_UDP; | 1028 | tun->proto = htons (ETH_P_IPV4); |
1032 | pkt6->ip6_hdr.hoplmt = 0xff; | 1029 | ipv4->version = 4; |
1030 | ipv4->header_length = sizeof (struct ip4_header) / 4; | ||
1031 | ipv4->diff_serv = 0; | ||
1032 | ipv4->total_length = htons (sizeof (struct ip4_header) + | ||
1033 | sizeof (struct udp_packet) + | ||
1034 | mlen); | ||
1035 | ipv4->identification = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, | ||
1036 | UINT16_MAX + 1); | ||
1037 | ipv4->flags = 0; | ||
1038 | ipv4->fragmentation_offset = 0; | ||
1039 | ipv4->ttl = 255; | ||
1040 | ipv4->protocol = IPPROTO_UDP; | ||
1041 | ipv4->checksum = 0; | ||
1042 | ipv4->source_address = ts->destination_ip.v4; | ||
1043 | ipv4->destination_address = ts->source_ip.v4; | ||
1044 | ipv4->checksum = | ||
1045 | GNUNET_CRYPTO_crc16_n (ipv4, sizeof (struct ip4_header)); | ||
1046 | if (0 == ntohs (reply->source_port)) | ||
1047 | udp->spt = htons (ts->destination_port); | ||
1048 | else | ||
1049 | udp->spt = reply->source_port; | ||
1050 | if (0 == ntohs (reply->destination_port)) | ||
1051 | udp->dpt = htons (ts->source_port); | ||
1052 | else | ||
1053 | udp->dpt = reply->destination_port; | ||
1054 | udp->len = htons (mlen + sizeof (struct udp_packet)); | ||
1055 | udp->crc = 0; // FIXME: optional, but we might want to calculate this one anyway | ||
1056 | memcpy (&udp[1], | ||
1057 | &reply[1], | ||
1058 | mlen); | ||
1059 | (void) GNUNET_HELPER_send (helper_handle, | ||
1060 | msg, | ||
1061 | GNUNET_YES, | ||
1062 | NULL, NULL); | ||
1063 | } | ||
1064 | } | ||
1065 | break; | ||
1066 | case AF_INET6: | ||
1067 | // FIXME: parse message, build IP packet, give to TUN! | ||
1068 | #if 0 | ||
1069 | pkt6->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
1070 | pkt6->shdr.size = htons (size); | ||
1033 | 1071 | ||
1072 | pkt6->tun.flags = 0; | ||
1073 | pkt6->tun.type = htons (0x86dd); | ||
1074 | |||
1075 | pkt6->ip6_hdr.version = 6; | ||
1076 | pkt6->ip6_hdr.tclass_h = 0; | ||
1077 | pkt6->ip6_hdr.tclass_l = 0; | ||
1078 | pkt6->ip6_hdr.flowlbl = 0; | ||
1079 | pkt6->ip6_hdr.paylgth = pkt->len; | ||
1080 | pkt6->ip6_hdr.nxthdr = IPPROTO_UDP; | ||
1081 | pkt6->ip6_hdr.hoplmt = 0xff; | ||
1082 | |||
1034 | { | 1083 | { |
1035 | char *ipv6addr; | 1084 | char *ipv6addr; |
1036 | 1085 | ||
@@ -1078,81 +1127,17 @@ receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1078 | &pkt6->shdr, | 1127 | &pkt6->shdr, |
1079 | GNUNET_YES, | 1128 | GNUNET_YES, |
1080 | NULL, NULL); | 1129 | NULL, NULL); |
1130 | #endif | ||
1131 | break; | ||
1132 | default: | ||
1133 | GNUNET_assert (0); | ||
1081 | } | 1134 | } |
1082 | else | 1135 | #if 0 |
1083 | { | 1136 | struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key); |
1084 | size_t size = | ||
1085 | sizeof (struct ip_udp) + ntohs (pkt->len) - 1 - sizeof (struct udp_pkt); | ||
1086 | |||
1087 | struct ip_udp *pkt4 = alloca (size); | ||
1088 | |||
1089 | GNUNET_assert (pkt4 != NULL); | ||
1090 | |||
1091 | GNUNET_assert (ntohs (message->type) == | ||
1092 | GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP_BACK); | ||
1093 | uint32_t sadr; | ||
1094 | |||
1095 | new_ip4addr_remote ((unsigned char *) &sadr, s->addr, s->addrlen); | ||
1096 | pkt4->ip_hdr.sadr.s_addr = sadr; | ||
1097 | |||
1098 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1099 | "Relaying calc:%d gnu:%d udp:%d bytes!\n", size, | ||
1100 | ntohs (message->size), ntohs (pkt->len)); | ||
1101 | |||
1102 | pkt4->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
1103 | pkt4->shdr.size = htons (size); | ||
1104 | |||
1105 | pkt4->tun.flags = 0; | ||
1106 | pkt4->tun.type = htons (0x0800); | ||
1107 | |||
1108 | pkt4->ip_hdr.version = 4; | ||
1109 | pkt4->ip_hdr.hdr_lngth = 5; | ||
1110 | pkt4->ip_hdr.diff_serv = 0; | ||
1111 | pkt4->ip_hdr.tot_lngth = htons (20 + ntohs (pkt->len)); | ||
1112 | pkt4->ip_hdr.ident = 0; | ||
1113 | pkt4->ip_hdr.flags = 0; | ||
1114 | pkt4->ip_hdr.frag_off = 0; | ||
1115 | pkt4->ip_hdr.ttl = 255; | ||
1116 | pkt4->ip_hdr.proto = IPPROTO_UDP; | ||
1117 | pkt4->ip_hdr.chks = 0; /* Will be calculated later */ | ||
1118 | |||
1119 | { | ||
1120 | char *ipv4addr; | ||
1121 | uint32_t dadr; | ||
1122 | |||
1123 | GNUNET_assert (GNUNET_OK == | ||
1124 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", | ||
1125 | "IPV4ADDR", | ||
1126 | &ipv4addr)); | ||
1127 | inet_pton (AF_INET, ipv4addr, &dadr); | ||
1128 | GNUNET_free (ipv4addr); | ||
1129 | pkt4->ip_hdr.dadr.s_addr = dadr; | ||
1130 | } | ||
1131 | memcpy (&pkt4->udp_hdr, pkt, ntohs (pkt->len)); | ||
1132 | |||
1133 | GNUNET_HashCode *key = address4_mapping_exists (pkt4->ip_hdr.sadr.s_addr); | ||
1134 | |||
1135 | GNUNET_assert (key != NULL); | ||
1136 | |||
1137 | struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key); | ||
1138 | |||
1139 | GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node, | ||
1140 | GNUNET_TIME_absolute_get ().abs_value); | ||
1141 | |||
1142 | GNUNET_free (key); | ||
1143 | |||
1144 | GNUNET_assert (me != NULL); | ||
1145 | 1137 | ||
1146 | pkt4->udp_hdr.crc = 0; /* Optional for IPv4 */ | 1138 | GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node, |
1139 | GNUNET_TIME_absolute_get ().abs_value); | ||
1147 | 1140 | ||
1148 | pkt4->ip_hdr.chks = | ||
1149 | GNUNET_CRYPTO_crc16_n ((uint16_t *) & pkt4->ip_hdr, 5 * 4); | ||
1150 | |||
1151 | (void) GNUNET_HELPER_send (helper_handle, | ||
1152 | &pkt4->shdr, | ||
1153 | GNUNET_YES, | ||
1154 | NULL, NULL); | ||
1155 | } | ||
1156 | #endif | 1141 | #endif |
1157 | return GNUNET_OK; | 1142 | return GNUNET_OK; |
1158 | } | 1143 | } |