diff options
Diffstat (limited to 'src/vpn')
-rw-r--r-- | src/vpn/gnunet-service-vpn.c | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c index 4bff262c3..8925c034f 100644 --- a/src/vpn/gnunet-service-vpn.c +++ b/src/vpn/gnunet-service-vpn.c | |||
@@ -1344,6 +1344,145 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, | |||
1344 | 1344 | ||
1345 | 1345 | ||
1346 | /** | 1346 | /** |
1347 | * We got an ICMP packet back from the MESH tunnel. Pass it on to the | ||
1348 | * local virtual interface via the helper. | ||
1349 | * | ||
1350 | * @param cls closure, NULL | ||
1351 | * @param tunnel connection to the other end | ||
1352 | * @param tunnel_ctx pointer to our 'struct TunnelState *' | ||
1353 | * @param sender who sent the message | ||
1354 | * @param message the actual message | ||
1355 | * @param atsi performance data for the connection | ||
1356 | * @return GNUNET_OK to keep the connection open, | ||
1357 | * GNUNET_SYSERR to close it (signal serious error) | ||
1358 | */ | ||
1359 | static int | ||
1360 | receive_icmp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | ||
1361 | void **tunnel_ctx, const struct GNUNET_PeerIdentity *sender, | ||
1362 | const struct GNUNET_MessageHeader *message, | ||
1363 | const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) | ||
1364 | { | ||
1365 | struct TunnelState *ts = *tunnel_ctx; | ||
1366 | const struct GNUNET_EXIT_IcmpToVPNMessage *i2v; | ||
1367 | size_t mlen; | ||
1368 | |||
1369 | GNUNET_STATISTICS_update (stats, | ||
1370 | gettext_noop ("# ICMP packets received from mesh"), | ||
1371 | 1, GNUNET_NO); | ||
1372 | mlen = ntohs (message->size); | ||
1373 | if (mlen < sizeof (struct GNUNET_EXIT_IcmpToVPNMessage)) | ||
1374 | { | ||
1375 | GNUNET_break_op (0); | ||
1376 | return GNUNET_SYSERR; | ||
1377 | } | ||
1378 | if (NULL == ts->heap_node) | ||
1379 | { | ||
1380 | GNUNET_break_op (0); | ||
1381 | return GNUNET_SYSERR; | ||
1382 | } | ||
1383 | if (AF_UNSPEC == ts->af) | ||
1384 | { | ||
1385 | GNUNET_break_op (0); | ||
1386 | return GNUNET_SYSERR; | ||
1387 | } | ||
1388 | i2v = (const struct GNUNET_EXIT_IcmpToVPNMessage *) message; | ||
1389 | mlen -= sizeof (struct GNUNET_EXIT_IcmpToVPNMessage); | ||
1390 | { | ||
1391 | char sbuf[INET6_ADDRSTRLEN]; | ||
1392 | char dbuf[INET6_ADDRSTRLEN]; | ||
1393 | |||
1394 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1395 | "Received ICMP packet from mesh, sending %u bytes from %s -> %s via TUN\n", | ||
1396 | (unsigned int) mlen, | ||
1397 | inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof (sbuf)), | ||
1398 | inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf))); | ||
1399 | } | ||
1400 | switch (ts->af) | ||
1401 | { | ||
1402 | case AF_INET: | ||
1403 | { | ||
1404 | size_t size = sizeof (struct GNUNET_TUN_IPv4Header) | ||
1405 | + sizeof (struct GNUNET_TUN_IcmpHeader) | ||
1406 | + sizeof (struct GNUNET_MessageHeader) + | ||
1407 | sizeof (struct GNUNET_TUN_Layer2PacketHeader) + | ||
1408 | mlen; | ||
1409 | { | ||
1410 | char buf[size]; | ||
1411 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; | ||
1412 | struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; | ||
1413 | struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *) &tun[1]; | ||
1414 | struct GNUNET_TUN_IcmpHeader *icmp = (struct GNUNET_TUN_IcmpHeader *) &ipv4[1]; | ||
1415 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
1416 | msg->size = htons (size); | ||
1417 | tun->flags = htons (0); | ||
1418 | tun->proto = htons (ETH_P_IPV4); | ||
1419 | GNUNET_TUN_initialize_ipv4_header (ipv4, | ||
1420 | IPPROTO_ICMP, | ||
1421 | sizeof (struct GNUNET_TUN_IcmpHeader) + mlen, | ||
1422 | &ts->destination_ip.v4, | ||
1423 | &ts->source_ip.v4); | ||
1424 | *icmp = i2v->icmp_header; | ||
1425 | memcpy (&icmp[1], | ||
1426 | &i2v[1], | ||
1427 | mlen); | ||
1428 | /* FIXME: for some ICMP types, we need to adjust the payload here... */ | ||
1429 | GNUNET_TUN_calculate_icmp_checksum (icmp, | ||
1430 | &i2v[1], | ||
1431 | mlen); | ||
1432 | (void) GNUNET_HELPER_send (helper_handle, | ||
1433 | msg, | ||
1434 | GNUNET_YES, | ||
1435 | NULL, NULL); | ||
1436 | } | ||
1437 | } | ||
1438 | break; | ||
1439 | case AF_INET6: | ||
1440 | { | ||
1441 | size_t size = sizeof (struct GNUNET_TUN_IPv6Header) | ||
1442 | + sizeof (struct GNUNET_TUN_IcmpHeader) | ||
1443 | + sizeof (struct GNUNET_MessageHeader) + | ||
1444 | sizeof (struct GNUNET_TUN_Layer2PacketHeader) + | ||
1445 | mlen; | ||
1446 | { | ||
1447 | char buf[size]; | ||
1448 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; | ||
1449 | struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; | ||
1450 | struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *) &tun[1]; | ||
1451 | struct GNUNET_TUN_IcmpHeader *icmp = (struct GNUNET_TUN_IcmpHeader *) &ipv6[1]; | ||
1452 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
1453 | msg->size = htons (size); | ||
1454 | tun->flags = htons (0); | ||
1455 | tun->proto = htons (ETH_P_IPV6); | ||
1456 | GNUNET_TUN_initialize_ipv6_header (ipv6, | ||
1457 | IPPROTO_ICMP, | ||
1458 | sizeof (struct GNUNET_TUN_IcmpHeader) + mlen, | ||
1459 | &ts->destination_ip.v6, | ||
1460 | &ts->source_ip.v6); | ||
1461 | *icmp = i2v->icmp_header; | ||
1462 | memcpy (&icmp[1], | ||
1463 | &i2v[1], | ||
1464 | mlen); | ||
1465 | /* FIXME: for some ICMP types, we need to adjust the payload here... */ | ||
1466 | GNUNET_TUN_calculate_icmp_checksum (icmp, | ||
1467 | &i2v[1], mlen); | ||
1468 | (void) GNUNET_HELPER_send (helper_handle, | ||
1469 | msg, | ||
1470 | GNUNET_YES, | ||
1471 | NULL, NULL); | ||
1472 | } | ||
1473 | } | ||
1474 | break; | ||
1475 | default: | ||
1476 | GNUNET_assert (0); | ||
1477 | } | ||
1478 | GNUNET_CONTAINER_heap_update_cost (tunnel_heap, | ||
1479 | ts->heap_node, | ||
1480 | GNUNET_TIME_absolute_get ().abs_value); | ||
1481 | return GNUNET_OK; | ||
1482 | } | ||
1483 | |||
1484 | |||
1485 | /** | ||
1347 | * We got a UDP packet back from the MESH tunnel. Pass it on to the | 1486 | * We got a UDP packet back from the MESH tunnel. Pass it on to the |
1348 | * local virtual interface via the helper. | 1487 | * local virtual interface via the helper. |
1349 | * | 1488 | * |
@@ -2315,6 +2454,7 @@ run (void *cls, | |||
2315 | static const struct GNUNET_MESH_MessageHandler mesh_handlers[] = { | 2454 | static const struct GNUNET_MESH_MessageHandler mesh_handlers[] = { |
2316 | { &receive_udp_back, GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY, 0}, | 2455 | { &receive_udp_back, GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY, 0}, |
2317 | { &receive_tcp_back, GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN, 0}, | 2456 | { &receive_tcp_back, GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN, 0}, |
2457 | { &receive_icmp_back, GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN, 0}, | ||
2318 | {NULL, 0, 0} | 2458 | {NULL, 0, 0} |
2319 | }; | 2459 | }; |
2320 | static const GNUNET_MESH_ApplicationType types[] = { | 2460 | static const GNUNET_MESH_ApplicationType types[] = { |