aboutsummaryrefslogtreecommitdiff
path: root/src/vpn
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-01-21 15:03:38 +0000
committerChristian Grothoff <christian@grothoff.org>2012-01-21 15:03:38 +0000
commitc8964e3192015a9723ebcd0aed020f503287c9b0 (patch)
tree45b61c6147b013ab45ea62619201fba51dc7ba15 /src/vpn
parenta53a186e50dc5c18513b1e10c3c044c4865d5994 (diff)
downloadgnunet-c8964e3192015a9723ebcd0aed020f503287c9b0.tar.gz
gnunet-c8964e3192015a9723ebcd0aed020f503287c9b0.zip
-add support for receiving VPN_ICMP_TO_VPN messages
Diffstat (limited to 'src/vpn')
-rw-r--r--src/vpn/gnunet-service-vpn.c140
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 */
1359static int
1360receive_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[] = {