aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-01-11 22:20:12 +0000
committerChristian Grothoff <christian@grothoff.org>2012-01-11 22:20:12 +0000
commitbaaef78cd06674caac97c96cf3061a7a376b5422 (patch)
tree1a8dce03fdaf7e9e05fa0568fa7f0ecbadfd03c7
parent2f31bf62ac7c57984f9e674fca3fc9eb68b1b656 (diff)
downloadgnunet-baaef78cd06674caac97c96cf3061a7a376b5422.tar.gz
gnunet-baaef78cd06674caac97c96cf3061a7a376b5422.zip
-building IPv4 TCP reply messages for TUN
-rw-r--r--src/vpn/gnunet-service-vpn.c119
1 files changed, 98 insertions, 21 deletions
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c
index 9739e24d0..ad00d4c99 100644
--- a/src/vpn/gnunet-service-vpn.c
+++ b/src/vpn/gnunet-service-vpn.c
@@ -1158,6 +1158,90 @@ receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1158 const struct GNUNET_MessageHeader *message, 1158 const struct GNUNET_MessageHeader *message,
1159 const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) 1159 const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1160{ 1160{
1161 struct TunnelState *ts = *tunnel_ctx;
1162 const struct GNUNET_EXIT_TcpDataMessage *data;
1163 size_t mlen;
1164
1165 mlen = ntohs (message->size);
1166 if (mlen < sizeof (struct GNUNET_EXIT_TcpDataMessage))
1167 {
1168 GNUNET_break_op (0);
1169 return GNUNET_SYSERR;
1170 }
1171 if (NULL == ts->heap_node)
1172 {
1173 GNUNET_break_op (0);
1174 return GNUNET_SYSERR;
1175 }
1176 data = (const struct GNUNET_EXIT_TcpDataMessage *) message;
1177 mlen -= sizeof (struct GNUNET_EXIT_TcpDataMessage);
1178 switch (ts->af)
1179 {
1180 case AF_INET:
1181 {
1182 size_t size = sizeof (struct ip4_header)
1183 + sizeof (struct tcp_packet)
1184 + sizeof (struct GNUNET_MessageHeader) +
1185 sizeof (struct tun_header) +
1186 mlen;
1187 {
1188 char buf[size];
1189 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
1190 struct tun_header *tun = (struct tun_header*) &msg[1];
1191 struct ip4_header *ipv4 = (struct ip4_header *) &tun[1];
1192 struct tcp_packet *tcp = (struct tcp_packet *) &ipv4[1];
1193 msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1194 msg->size = htons (size);
1195 tun->flags = htons (0);
1196 tun->proto = htons (ETH_P_IPV4);
1197 ipv4->version = 4;
1198 ipv4->header_length = sizeof (struct ip4_header) / 4;
1199 ipv4->diff_serv = 0;
1200 ipv4->total_length = htons (sizeof (struct ip4_header) +
1201 sizeof (struct tcp_packet) +
1202 mlen);
1203 ipv4->identification = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
1204 UINT16_MAX + 1);
1205 ipv4->flags = 0;
1206 ipv4->fragmentation_offset = 0;
1207 ipv4->ttl = 255;
1208 ipv4->protocol = IPPROTO_TCP;
1209 ipv4->checksum = 0;
1210 ipv4->source_address = ts->destination_ip.v4;
1211 ipv4->destination_address = ts->source_ip.v4;
1212 ipv4->checksum =
1213 GNUNET_CRYPTO_crc16_n (ipv4, sizeof (struct ip4_header));
1214 *tcp = data->tcp_header;
1215 tcp->spt = htons (ts->destination_port);
1216 tcp->dpt = htons (ts->source_port);
1217 tcp->crc = 0;
1218 memcpy (&tcp[1],
1219 &data[1],
1220 mlen);
1221 {
1222 uint32_t sum = 0;
1223 uint32_t tmp;
1224
1225 sum = GNUNET_CRYPTO_crc16_step (sum,
1226 &ipv4->source_address,
1227 2 * sizeof (struct in_addr));
1228 tmp = htonl ((IPPROTO_TCP << 16) | (mlen + sizeof (struct tcp_packet)));
1229 sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
1230 sum = GNUNET_CRYPTO_crc16_step (sum, tcp, mlen + sizeof (struct tcp_packet));
1231 tcp->crc = GNUNET_CRYPTO_crc16_finish (sum);
1232 }
1233 (void) GNUNET_HELPER_send (helper_handle,
1234 msg,
1235 GNUNET_YES,
1236 NULL, NULL);
1237 }
1238 }
1239 break;
1240 case AF_INET6:
1241 break;
1242 default:
1243 GNUNET_assert (0);
1244 }
1161 // FIXME: parse message, build IP packet, give to TUN! 1245 // FIXME: parse message, build IP packet, give to TUN!
1162#if 0 1246#if 0
1163 GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1); 1247 GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1);
@@ -1229,11 +1313,11 @@ receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1229 GNUNET_assert (me != NULL); 1313 GNUNET_assert (me != NULL);
1230 1314
1231 pkt6->tcp_hdr.crc = 0; 1315 pkt6->tcp_hdr.crc = 0;
1232 uint32_t sum = 0;
1233 uint32_t tmp;
1234 1316
1235 sum = 1317 uint32_t sum = 0;
1236 GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.sadr, 16); 1318 uint32_t tmp;
1319
1320 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.sadr, 16);
1237 sum = 1321 sum =
1238 GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.dadr, 16); 1322 GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.dadr, 16);
1239 tmp = htonl (pktlen); 1323 tmp = htonl (pktlen);
@@ -1246,6 +1330,7 @@ receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1246 ntohs (pkt6->ip6_hdr.paylgth)); 1330 ntohs (pkt6->ip6_hdr.paylgth));
1247 pkt6->tcp_hdr.crc = GNUNET_CRYPTO_crc16_finish (sum); 1331 pkt6->tcp_hdr.crc = GNUNET_CRYPTO_crc16_finish (sum);
1248 1332
1333
1249 (void) GNUNET_HELPER_send (helper_handle, 1334 (void) GNUNET_HELPER_send (helper_handle,
1250 &pkt6->shdr, 1335 &pkt6->shdr,
1251 GNUNET_YES, 1336 GNUNET_YES,
@@ -1312,23 +1397,6 @@ receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1312 1397
1313 GNUNET_assert (me != NULL); 1398 GNUNET_assert (me != NULL);
1314 pkt4->tcp_hdr.crc = 0; 1399 pkt4->tcp_hdr.crc = 0;
1315 uint32_t sum = 0;
1316 uint32_t tmp;
1317
1318 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) &pkt4->ip_hdr.sadr, 4);
1319 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) &pkt4->ip_hdr.dadr, 4);
1320
1321 tmp = (0x06 << 16) | (0xffff & pktlen); // 0x06 for TCP?
1322
1323 tmp = htonl (tmp);
1324
1325 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4);
1326
1327 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt4->tcp_hdr, pktlen);
1328 pkt4->tcp_hdr.crc = GNUNET_CRYPTO_crc16_finish (sum);
1329
1330 pkt4->ip_hdr.chks =
1331 GNUNET_CRYPTO_crc16_n ((uint16_t *) & pkt4->ip_hdr, 5 * 4);
1332 1400
1333 (void) GNUNET_HELPER_send (helper_handle, 1401 (void) GNUNET_HELPER_send (helper_handle,
1334 &pkt4->shdr, 1402 &pkt4->shdr,
@@ -1337,6 +1405,15 @@ receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1337 1405
1338 } 1406 }
1339#endif 1407#endif
1408
1409#if 0
1410 // FIXME: refresh entry to avoid expiration...
1411 struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
1412
1413 GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node,
1414 GNUNET_TIME_absolute_get ().abs_value);
1415
1416#endif
1340 return GNUNET_OK; 1417 return GNUNET_OK;
1341} 1418}
1342 1419