diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-01-11 22:25:04 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-01-11 22:25:04 +0000 |
commit | e6a36775a87092d175e202fca020fd2d2d67e730 (patch) | |
tree | ab2038ba948134979daf71fca3d38d62c5caf9dd /src | |
parent | baaef78cd06674caac97c96cf3061a7a376b5422 (diff) | |
download | gnunet-e6a36775a87092d175e202fca020fd2d2d67e730.tar.gz gnunet-e6a36775a87092d175e202fca020fd2d2d67e730.zip |
-building IPv6 TCP reply messages for TUN
Diffstat (limited to 'src')
-rw-r--r-- | src/vpn/gnunet-service-vpn.c | 204 |
1 files changed, 43 insertions, 161 deletions
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c index ad00d4c99..5b2999d77 100644 --- a/src/vpn/gnunet-service-vpn.c +++ b/src/vpn/gnunet-service-vpn.c | |||
@@ -1238,173 +1238,55 @@ receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1238 | } | 1238 | } |
1239 | break; | 1239 | break; |
1240 | case AF_INET6: | 1240 | case AF_INET6: |
1241 | break; | ||
1242 | default: | ||
1243 | GNUNET_assert (0); | ||
1244 | } | ||
1245 | // FIXME: parse message, build IP packet, give to TUN! | ||
1246 | #if 0 | ||
1247 | GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1); | ||
1248 | struct remote_addr *s = (struct remote_addr *) desc; | ||
1249 | struct tcp_pkt *pkt = (struct tcp_pkt *) (desc + 1); | ||
1250 | const struct GNUNET_PeerIdentity *other = sender; | ||
1251 | struct TunnelState *ts = *tunnel_ctx; | ||
1252 | |||
1253 | size_t pktlen = | ||
1254 | ntohs (message->size) - sizeof (struct GNUNET_MessageHeader) - | ||
1255 | sizeof (GNUNET_HashCode); | ||
1256 | |||
1257 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1258 | "Received TCP-Packet back, addrlen = %d\n", s->addrlen); | ||
1259 | |||
1260 | if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP_BACK || | ||
1261 | ts->addrlen == 16) | ||
1262 | { | ||
1263 | size_t size = pktlen + sizeof (struct ip6_tcp) - 1; | ||
1264 | |||
1265 | struct ip6_tcp *pkt6 = alloca (size); | ||
1266 | |||
1267 | memset (pkt6, 0, size); | ||
1268 | |||
1269 | GNUNET_assert (pkt6 != NULL); | ||
1270 | |||
1271 | if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP_BACK) | ||
1272 | new_ip6addr (&pkt6->ip6_hdr.sadr, &other->hashPubKey, desc); | ||
1273 | else | ||
1274 | new_ip6addr_remote (&pkt6->ip6_hdr.sadr, s->addr, s->addrlen); | ||
1275 | |||
1276 | pkt6->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
1277 | pkt6->shdr.size = htons (size); | ||
1278 | |||
1279 | pkt6->tun.flags = 0; | ||
1280 | pkt6->tun.type = htons (0x86dd); | ||
1281 | |||
1282 | pkt6->ip6_hdr.version = 6; | ||
1283 | pkt6->ip6_hdr.tclass_h = 0; | ||
1284 | pkt6->ip6_hdr.tclass_l = 0; | ||
1285 | pkt6->ip6_hdr.flowlbl = 0; | ||
1286 | pkt6->ip6_hdr.paylgth = htons (pktlen); | ||
1287 | pkt6->ip6_hdr.nxthdr = IPPROTO_TCP; | ||
1288 | pkt6->ip6_hdr.hoplmt = 0xff; | ||
1289 | |||
1290 | { | 1241 | { |
1291 | char *ipv6addr; | 1242 | size_t size = sizeof (struct ip6_header) |
1292 | 1243 | + sizeof (struct tcp_packet) | |
1293 | GNUNET_assert (GNUNET_OK == | 1244 | + sizeof (struct GNUNET_MessageHeader) + |
1294 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", | 1245 | sizeof (struct tun_header) + |
1295 | "IPV6ADDR", | 1246 | mlen; |
1296 | &ipv6addr)); | 1247 | { |
1297 | inet_pton (AF_INET6, ipv6addr, &pkt6->ip6_hdr.dadr); | 1248 | char buf[size]; |
1298 | GNUNET_free (ipv6addr); | 1249 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; |
1299 | } | 1250 | struct tun_header *tun = (struct tun_header*) &msg[1]; |
1300 | memcpy (&pkt6->tcp_hdr, pkt, pktlen); | 1251 | struct ip6_header *ipv6 = (struct ip6_header *) &tun[1]; |
1301 | 1252 | struct tcp_packet *tcp = (struct tcp_packet *) &ipv6[1]; | |
1302 | GNUNET_HashCode *key = address6_mapping_exists (&pkt6->ip6_hdr.sadr); | 1253 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); |
1303 | 1254 | msg->size = htons (size); | |
1304 | GNUNET_assert (key != NULL); | 1255 | tun->flags = htons (0); |
1305 | 1256 | tun->proto = htons (ETH_P_IPV6); | |
1306 | struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key); | 1257 | ipv6->traffic_class_h = 0; |
1307 | 1258 | ipv6->version = 6; | |
1308 | GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node, | 1259 | ipv6->traffic_class_l = 0; |
1309 | GNUNET_TIME_absolute_get ().abs_value); | 1260 | ipv6->flow_label = 0; |
1310 | 1261 | ipv6->payload_length = htons (sizeof (struct tcp_packet) + sizeof (struct ip6_header) + mlen); | |
1311 | GNUNET_free (key); | 1262 | ipv6->next_header = IPPROTO_TCP; |
1312 | 1263 | ipv6->hop_limit = 255; | |
1313 | GNUNET_assert (me != NULL); | 1264 | ipv6->source_address = ts->destination_ip.v6; |
1314 | 1265 | ipv6->destination_address = ts->source_ip.v6; | |
1315 | pkt6->tcp_hdr.crc = 0; | 1266 | tcp->spt = htons (ts->destination_port); |
1316 | 1267 | tcp->dpt = htons (ts->source_port); | |
1268 | tcp->crc = 0; | ||
1269 | { | ||
1317 | uint32_t sum = 0; | 1270 | uint32_t sum = 0; |
1318 | uint32_t tmp; | 1271 | uint32_t tmp; |
1319 | 1272 | ||
1320 | sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.sadr, 16); | 1273 | sum = GNUNET_CRYPTO_crc16_step (sum, &ipv6->source_address, 2 * sizeof (struct in6_addr)); |
1321 | sum = | 1274 | tmp = htonl (sizeof (struct tcp_packet) + mlen); |
1322 | GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.dadr, 16); | 1275 | sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t)); |
1323 | tmp = htonl (pktlen); | 1276 | tmp = htonl (IPPROTO_TCP); |
1324 | sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4); | 1277 | sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t)); |
1325 | tmp = htonl (((pkt6->ip6_hdr.nxthdr & 0x000000ff))); | 1278 | sum = GNUNET_CRYPTO_crc16_step (sum, tcp, |
1326 | sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4); | 1279 | sizeof (struct tcp_packet) + mlen); |
1327 | 1280 | tcp->crc = GNUNET_CRYPTO_crc16_finish (sum); | |
1328 | sum = | 1281 | } |
1329 | GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->tcp_hdr, | 1282 | (void) GNUNET_HELPER_send (helper_handle, |
1330 | ntohs (pkt6->ip6_hdr.paylgth)); | 1283 | msg, |
1331 | pkt6->tcp_hdr.crc = GNUNET_CRYPTO_crc16_finish (sum); | 1284 | GNUNET_YES, |
1332 | 1285 | NULL, NULL); | |
1333 | 1286 | } | |
1334 | (void) GNUNET_HELPER_send (helper_handle, | ||
1335 | &pkt6->shdr, | ||
1336 | GNUNET_YES, | ||
1337 | NULL, NULL); | ||
1338 | } | ||
1339 | else | ||
1340 | { | ||
1341 | size_t size = pktlen + sizeof (struct ip_tcp) - 1; | ||
1342 | |||
1343 | struct ip_tcp *pkt4 = alloca (size); | ||
1344 | |||
1345 | GNUNET_assert (pkt4 != NULL); | ||
1346 | memset (pkt4, 0, size); | ||
1347 | |||
1348 | GNUNET_assert (ntohs (message->type) == | ||
1349 | GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP_BACK); | ||
1350 | uint32_t sadr; | ||
1351 | |||
1352 | new_ip4addr_remote ((unsigned char *) &sadr, s->addr, s->addrlen); | ||
1353 | pkt4->ip_hdr.sadr.s_addr = sadr; | ||
1354 | |||
1355 | pkt4->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
1356 | pkt4->shdr.size = htons (size); | ||
1357 | |||
1358 | pkt4->tun.flags = 0; | ||
1359 | pkt4->tun.type = htons (0x0800); | ||
1360 | |||
1361 | pkt4->ip_hdr.version = 4; | ||
1362 | pkt4->ip_hdr.hdr_lngth = 5; | ||
1363 | pkt4->ip_hdr.diff_serv = 0; | ||
1364 | pkt4->ip_hdr.tot_lngth = htons (20 + pktlen); | ||
1365 | pkt4->ip_hdr.ident = 0; | ||
1366 | pkt4->ip_hdr.flags = 0; | ||
1367 | pkt4->ip_hdr.frag_off = 0; | ||
1368 | pkt4->ip_hdr.ttl = 255; | ||
1369 | pkt4->ip_hdr.proto = IPPROTO_TCP; | ||
1370 | pkt4->ip_hdr.chks = 0; /* Will be calculated later */ | ||
1371 | |||
1372 | { | ||
1373 | char *ipv4addr; | ||
1374 | uint32_t dadr; | ||
1375 | |||
1376 | GNUNET_assert (GNUNET_OK == | ||
1377 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", | ||
1378 | "IPV4ADDR", | ||
1379 | &ipv4addr)); | ||
1380 | inet_pton (AF_INET, ipv4addr, &dadr); | ||
1381 | GNUNET_free (ipv4addr); | ||
1382 | pkt4->ip_hdr.dadr.s_addr = dadr; | ||
1383 | } | 1287 | } |
1384 | 1288 | break; | |
1385 | memcpy (&pkt4->tcp_hdr, pkt, pktlen); | ||
1386 | |||
1387 | GNUNET_HashCode *key = address4_mapping_exists (pkt4->ip_hdr.sadr.s_addr); | ||
1388 | |||
1389 | GNUNET_assert (key != NULL); | ||
1390 | |||
1391 | struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key); | ||
1392 | |||
1393 | GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node, | ||
1394 | GNUNET_TIME_absolute_get ().abs_value); | ||
1395 | |||
1396 | GNUNET_free (key); | ||
1397 | |||
1398 | GNUNET_assert (me != NULL); | ||
1399 | pkt4->tcp_hdr.crc = 0; | ||
1400 | |||
1401 | (void) GNUNET_HELPER_send (helper_handle, | ||
1402 | &pkt4->shdr, | ||
1403 | GNUNET_YES, | ||
1404 | NULL, NULL); | ||
1405 | |||
1406 | } | 1289 | } |
1407 | #endif | ||
1408 | 1290 | ||
1409 | #if 0 | 1291 | #if 0 |
1410 | // FIXME: refresh entry to avoid expiration... | 1292 | // FIXME: refresh entry to avoid expiration... |