aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-01-11 17:26:19 +0000
committerChristian Grothoff <christian@grothoff.org>2012-01-11 17:26:19 +0000
commit354a420bc1ddcc46b837a4e99e874195a53b7d57 (patch)
treea36c69a2652bde6a62ef7f35ae3f793dec229775
parentf1b851a7ece3a993bb07269a730dd82f7e60a6ac (diff)
downloadgnunet-354a420bc1ddcc46b837a4e99e874195a53b7d57.tar.gz
gnunet-354a420bc1ddcc46b837a4e99e874195a53b7d57.zip
-parsing for UDP IPv4 replies
-rw-r--r--src/vpn/gnunet-service-vpn.c203
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}