2 This file is part of GNUnet.
3 (C) 2010 Christian Grothoff
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
22 * @file vpn/gnunet-daemon-vpn.c
24 * @author Philipp Toelke
27 #include "gnunet_getopt_lib.h"
28 #include "gnunet_program_lib.h"
29 #include "gnunet-vpn-packet.h"
30 #include "gnunet_common.h"
31 #include "gnunet_protocols.h"
32 #include "gnunet_applications.h"
33 #include <gnunet_mesh_service.h>
34 #include "gnunet_client_lib.h"
35 #include "gnunet_container_lib.h"
36 #include "gnunet_constants.h"
37 #include <block_dns.h>
38 #include "gnunet_dns_service.h"
39 #include "gnunet-daemon-vpn.h"
40 #include "gnunet-vpn-checksum.h"
42 const struct GNUNET_CONFIGURATION_Handle *cfg;
43 struct GNUNET_MESH_Handle *mesh_handle;
44 struct GNUNET_CONTAINER_MultiHashMap *hashmap;
45 static struct GNUNET_CONTAINER_Heap *heap;
48 * The handle to the helper
50 static struct GNUNET_HELPER_Handle *helper_handle;
53 * Arguments to the exit helper.
55 static char *vpn_argv[7];
57 struct GNUNET_DNS_Handle *dns_handle;
59 struct answer_packet_list *answer_proc_head;
61 struct answer_packet_list *answer_proc_tail;
64 struct tunnel_notify_queue
66 struct tunnel_notify_queue *next;
67 struct tunnel_notify_queue *prev;
73 * If there are at least this many address-mappings, old ones will be removed
75 static long long unsigned int max_mappings = 200;
83 * This hashmap contains the mapping from peer, service-descriptor,
84 * source-port and destination-port to a socket
86 static struct GNUNET_CONTAINER_MultiHashMap *udp_connections;
88 GNUNET_SCHEDULER_TaskIdentifier conn_task;
90 GNUNET_SCHEDULER_TaskIdentifier shs_task;
94 * The tunnels that will be used to send tcp- and udp-packets
96 static struct GNUNET_MESH_Tunnel *tcp_tunnel;
97 static struct GNUNET_MESH_Tunnel *udp_tunnel;
102 * Sets a bit active in a bitArray.
104 * @param bitArray memory area to set the bit in
105 * @param bitIdx which bit to set
108 setBit (char *bitArray, unsigned int bitIdx)
111 unsigned int targetBit;
113 arraySlot = bitIdx / 8;
114 targetBit = (1L << (bitIdx % 8));
115 bitArray[arraySlot] |= targetBit;
120 * Checks if a bit is active in the bitArray
122 * @param bitArray memory area to set the bit in
123 * @param bitIdx which bit to test
124 * @return GNUNET_YES if the bit is set, GNUNET_NO if not.
127 testBit (char *bitArray, unsigned int bitIdx)
130 unsigned int targetBit;
133 targetBit = (1L << (bitIdx % 8));
134 if (bitArray[slot] & targetBit)
142 * Function scheduled as very last function, cleans up after us
146 cleanup (void *cls GNUNET_UNUSED,
147 const struct GNUNET_SCHEDULER_TaskContext *tskctx)
151 GNUNET_assert (0 != (tskctx->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN));
152 /* close the connection to the service-dns */
153 GNUNET_DNS_disconnect (dns_handle);
154 if (mesh_handle != NULL)
156 GNUNET_MESH_disconnect (mesh_handle);
159 if (helper_handle != NULL)
161 GNUNET_HELPER_stop (helper_handle);
162 helper_handle = NULL;
164 if (GNUNET_SCHEDULER_NO_TASK != shs_task)
166 GNUNET_SCHEDULER_cancel (shs_task);
167 shs_task = GNUNET_SCHEDULER_NO_TASK;
169 if (GNUNET_SCHEDULER_NO_TASK != conn_task)
171 GNUNET_SCHEDULER_cancel (conn_task);
172 conn_task = GNUNET_SCHEDULER_NO_TASK;
175 GNUNET_free_non_null (vpn_argv[i]);
181 * @return the hash of the IP-Address if a mapping exists, NULL otherwise
184 address6_mapping_exists (struct in6_addr *v6addr)
186 unsigned char *addr = (unsigned char*) v6addr;
187 GNUNET_HashCode *key = GNUNET_malloc (sizeof (GNUNET_HashCode));
188 unsigned char *k = (unsigned char *) key;
190 memset (key, 0, sizeof (GNUNET_HashCode));
193 for (i = 0; i < 16; i++)
196 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (hashmap, key))
206 * @return the hash of the IP-Address if a mapping exists, NULL otherwise
209 address4_mapping_exists (uint32_t addr)
211 GNUNET_HashCode *key = GNUNET_malloc (sizeof (GNUNET_HashCode));
213 memset (key, 0, sizeof (GNUNET_HashCode));
214 unsigned char *c = (unsigned char *) &addr;
215 unsigned char *k = (unsigned char *) key;
218 for (i = 0; i < 4; i++)
221 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
222 "a4_m_e: getting with key %08x, addr is %08x, %d.%d.%d.%d\n",
223 *((uint32_t *) (key)), addr, c[0], c[1], c[2], c[3]);
225 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (hashmap, key))
230 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Mapping not found!\n");
237 initialize_tunnel_state (int addrlen, struct GNUNET_MESH_TransmitHandle *th)
239 struct tunnel_state *ts = GNUNET_malloc (sizeof *ts);
241 ts->addrlen = addrlen;
247 * Send an dns-answer-packet to the helper
250 helper_write (void *cls GNUNET_UNUSED,
253 struct answer_packet_list *ans = answer_proc_head;
257 if (GNUNET_SYSERR == status)
260 size_t len = ntohs (ans->pkt.hdr.size);
262 GNUNET_assert (ans->pkt.subtype == GNUNET_DNS_ANSWER_TYPE_IP);
264 GNUNET_assert (20 == sizeof (struct ip_hdr));
265 GNUNET_assert (8 == sizeof (struct udp_pkt));
267 size_t data_len = len - sizeof (struct answer_packet) + 1;
271 if (ans->pkt.addrlen == 16)
274 sizeof (struct ip6_hdr) + sizeof (struct udp_dns) + data_len;
276 sizeof (struct GNUNET_MessageHeader) + sizeof (struct pkt_tun) +
279 struct ip6_udp_dns *pkt = alloca (pkt_len);
281 GNUNET_assert (pkt != NULL);
282 memset (pkt, 0, pkt_len);
284 /* set the gnunet-header */
285 pkt->shdr.size = htons (pkt_len);
286 pkt->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
288 /* set the tun-header (no flags and ethertype of IPv4) */
290 pkt->tun.type = htons (0x86dd);
292 memcpy (&pkt->ip6_hdr.sadr, ans->pkt.from, 16);
293 memcpy (&pkt->ip6_hdr.dadr, ans->pkt.to, 16);
295 /* set the udp-header */
296 pkt->udp_dns.udp_hdr.spt = htons (53);
297 pkt->udp_dns.udp_hdr.dpt = ans->pkt.dst_port;
298 pkt->udp_dns.udp_hdr.len = htons (net_len - sizeof (struct ip6_hdr));
299 pkt->udp_dns.udp_hdr.crc = 0;
302 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt->ip6_hdr.sadr, 16);
303 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt->ip6_hdr.dadr, 16);
304 uint32_t tmp = (pkt->udp_dns.udp_hdr.len & 0xffff);
306 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4);
307 tmp = htons (((pkt->ip6_hdr.nxthdr & 0x00ff)));
308 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4);
311 GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt->udp_dns.udp_hdr,
312 ntohs (net_len - sizeof (struct ip6_hdr)));
313 pkt->udp_dns.udp_hdr.crc = GNUNET_CRYPTO_crc16_finish (sum);
315 pkt->ip6_hdr.version = 6;
316 pkt->ip6_hdr.paylgth = net_len - sizeof (struct ip6_hdr);
317 pkt->ip6_hdr.nxthdr = IPPROTO_UDP;
318 pkt->ip6_hdr.hoplmt = 0xff;
320 memcpy (&pkt->udp_dns.data, ans->pkt.data, data_len);
321 (void) GNUNET_HELPER_send (helper_handle,
324 &helper_write, NULL);
326 else if (ans->pkt.addrlen == 4)
329 sizeof (struct ip_hdr) + sizeof (struct udp_dns) + data_len;
331 sizeof (struct GNUNET_MessageHeader) + sizeof (struct pkt_tun) +
334 struct ip_udp_dns *pkt = alloca (pkt_len);
336 GNUNET_assert (pkt != NULL);
337 memset (pkt, 0, pkt_len);
339 /* set the gnunet-header */
340 pkt->shdr.size = htons (pkt_len);
341 pkt->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
343 /* set the tun-header (no flags and ethertype of IPv4) */
345 pkt->tun.type = htons (0x0800);
347 /* set the ip-header */
348 pkt->ip_hdr.version = 4;
349 pkt->ip_hdr.hdr_lngth = 5;
350 pkt->ip_hdr.diff_serv = 0;
351 pkt->ip_hdr.tot_lngth = htons (net_len);
352 pkt->ip_hdr.ident = 0;
353 pkt->ip_hdr.flags = 0;
354 pkt->ip_hdr.frag_off = 0;
355 pkt->ip_hdr.ttl = 255;
356 pkt->ip_hdr.proto = IPPROTO_UDP;
357 pkt->ip_hdr.chks = 0; /* Will be calculated later */
359 memcpy (&pkt->ip_hdr.sadr, ans->pkt.from, 4);
360 memcpy (&pkt->ip_hdr.dadr, ans->pkt.to, 4);
363 GNUNET_CRYPTO_crc16_n ((uint16_t *) & pkt->ip_hdr, 5 * 4);
365 /* set the udp-header */
366 pkt->udp_dns.udp_hdr.spt = htons (53);
367 pkt->udp_dns.udp_hdr.dpt = ans->pkt.dst_port;
368 pkt->udp_dns.udp_hdr.len = htons (net_len - sizeof (struct ip_hdr));
369 pkt->udp_dns.udp_hdr.crc = 0; /* Optional for IPv4 */
371 memcpy (&pkt->udp_dns.data, ans->pkt.data, data_len);
372 (void) GNUNET_HELPER_send (helper_handle,
375 &helper_write, NULL);
380 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Wrong addrlen = %d\n",
383 return; /* convince compiler that we're done here */
386 GNUNET_CONTAINER_DLL_remove (answer_proc_head, answer_proc_tail, ans);
392 * Receive packets from the helper-process
395 message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED,
396 const struct GNUNET_MessageHeader *message)
398 GNUNET_assert (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_HELPER);
400 struct tun_pkt *pkt_tun = (struct tun_pkt *) message;
401 GNUNET_HashCode *key;
403 /* ethertype is ipv6 */
404 if (ntohs (pkt_tun->tun.type) == 0x86dd)
406 struct ip6_pkt *pkt6 = (struct ip6_pkt *) message;
408 GNUNET_assert (pkt6->ip6_hdr.version == 6);
409 struct ip6_tcp *pkt6_tcp;
410 struct ip6_udp *pkt6_udp;
411 struct ip6_icmp *pkt6_icmp;
413 pkt6_udp = NULL; /* make compiler happy */
414 switch (pkt6->ip6_hdr.nxthdr)
417 pkt6_udp = (struct ip6_udp *) pkt6;
418 /* Send dns-packets to the service-dns */
419 if (ntohs (pkt6_udp->udp_hdr.dpt) == 53)
421 /* 9 = 8 for the udp-header + 1 for the unsigned char data[1]; */
422 GNUNET_DNS_queue_request_v6 (dns_handle,
425 ntohs (pkt6_udp->udp_hdr.spt),
426 ntohs (pkt6_udp->udp_hdr.len) - 8,
427 (const void*) pkt6_udp->data);
433 pkt6_tcp = (struct ip6_tcp *) pkt6;
435 if ((key = address6_mapping_exists (&pkt6->ip6_hdr.dadr)) != NULL)
437 struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
439 GNUNET_assert (me != NULL);
443 sizeof (struct GNUNET_MESH_Tunnel *) +
444 sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) +
445 ntohs (pkt6->ip6_hdr.paylgth);
447 struct GNUNET_MESH_Tunnel **cls = GNUNET_malloc (size);
448 struct GNUNET_MessageHeader *hdr =
449 (struct GNUNET_MessageHeader *) (cls + 1);
450 GNUNET_HashCode *hc = (GNUNET_HashCode *) (hdr + 1);
453 htons (sizeof (struct GNUNET_MessageHeader) +
454 sizeof (GNUNET_HashCode) + ntohs (pkt6->ip6_hdr.paylgth));
456 GNUNET_MESH_ApplicationType app_type = 0; /* fix compiler uninitialized warning... */
458 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "me->addrlen is %d\n",
460 if (me->addrlen == 0)
462 /* This is a mapping to a gnunet-service */
463 memcpy (hc, &me->desc.service_descriptor, sizeof (GNUNET_HashCode));
465 if (IPPROTO_UDP == pkt6->ip6_hdr.nxthdr &&
466 (me->desc.service_type & htonl (GNUNET_DNS_SERVICE_TYPE_UDP)) &&
467 (port_in_ports (me->desc.ports, pkt6_udp->udp_hdr.dpt) ||
468 testBit (me->additional_ports, ntohs (pkt6_udp->udp_hdr.dpt))))
470 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP);
472 memcpy (hc + 1, &pkt6_udp->udp_hdr, ntohs (pkt6_udp->udp_hdr.len));
475 else if (IPPROTO_TCP == pkt6->ip6_hdr.nxthdr &&
476 (me->desc.service_type & htonl (GNUNET_DNS_SERVICE_TYPE_TCP))
477 && (port_in_ports (me->desc.ports, pkt6_tcp->tcp_hdr.dpt)))
479 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP);
481 memcpy (hc + 1, &pkt6_tcp->tcp_hdr, ntohs (pkt6->ip6_hdr.paylgth));
486 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "pip: %d\n",
487 port_in_ports (me->desc.ports, pkt6_tcp->tcp_hdr.dpt));
490 if (me->tunnel == NULL && NULL != cls)
493 GNUNET_MESH_tunnel_create (mesh_handle,
494 initialize_tunnel_state (16, NULL),
495 &send_pkt_to_peer, NULL, cls);
497 GNUNET_MESH_peer_request_connect_add (*cls,
498 (struct GNUNET_PeerIdentity *)
502 else if (NULL != cls)
505 send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL);
506 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
507 "Queued to send IPv6 to peer %x, type %d\n",
508 *((unsigned int *) &me->desc.peer), ntohs (hdr->type));
513 /* This is a mapping to a "real" address */
514 struct remote_addr *s = (struct remote_addr *) hc;
516 s->addrlen = me->addrlen;
517 memcpy (s->addr, me->addr, me->addrlen);
518 s->proto = pkt6->ip6_hdr.nxthdr;
519 if (s->proto == IPPROTO_UDP)
521 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP);
522 memcpy (hc + 1, &pkt6_udp->udp_hdr, ntohs (pkt6_udp->udp_hdr.len));
523 app_type = GNUNET_APPLICATION_TYPE_INTERNET_UDP_GATEWAY;
524 if (NULL != udp_tunnel)
525 me->tunnel = udp_tunnel;
527 else if (s->proto == IPPROTO_TCP)
529 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP);
530 memcpy (hc + 1, &pkt6_tcp->tcp_hdr, ntohs (pkt6->ip6_hdr.paylgth));
531 app_type = GNUNET_APPLICATION_TYPE_INTERNET_TCP_GATEWAY;
532 if (NULL != tcp_tunnel)
533 me->tunnel = tcp_tunnel;
539 if (me->tunnel == NULL && NULL != cls)
542 GNUNET_MESH_tunnel_create (mesh_handle,
543 initialize_tunnel_state (16, NULL),
544 &send_pkt_to_peer, NULL, cls);
546 GNUNET_MESH_peer_request_connect_by_type (*cls, app_type);
548 if (GNUNET_APPLICATION_TYPE_INTERNET_UDP_GATEWAY == app_type)
550 else if (GNUNET_APPLICATION_TYPE_INTERNET_TCP_GATEWAY == app_type)
553 else if (NULL != cls)
556 send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL);
562 char pbuf[INET6_ADDRSTRLEN];
563 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
564 "Packet to %s, which has no mapping\n",
573 pkt6_icmp = (struct ip6_icmp *) pkt6;
574 /* If this packet is an icmp-echo-request and a mapping exists, answer */
575 if (pkt6_icmp->icmp_hdr.type == 0x80 &&
576 (key = address6_mapping_exists (&pkt6->ip6_hdr.dadr)) != NULL)
579 pkt6_icmp = GNUNET_malloc (ntohs (pkt6->shdr.size));
580 memcpy (pkt6_icmp, pkt6, ntohs (pkt6->shdr.size));
581 GNUNET_SCHEDULER_add_now (&send_icmp6_response, pkt6_icmp);
586 /* ethertype is ipv4 */
587 else if (ntohs (pkt_tun->tun.type) == 0x0800)
589 struct ip_pkt *pkt = (struct ip_pkt *) message;
590 struct ip_udp *udp = (struct ip_udp *) message;
591 struct ip_tcp *pkt_tcp;
592 struct ip_udp *pkt_udp;
593 struct ip_icmp *pkt_icmp;
595 GNUNET_assert (pkt->ip_hdr.version == 4);
597 /* Send dns-packets to the service-dns */
598 if (pkt->ip_hdr.proto == IPPROTO_UDP && ntohs (udp->udp_hdr.dpt) == 53)
600 GNUNET_DNS_queue_request_v4 (dns_handle,
603 ntohs (udp->udp_hdr.spt),
604 ntohs (udp->udp_hdr.len) - 8,
605 (const void*) udp->data);
609 uint32_t dadr = pkt->ip_hdr.dadr.s_addr;
610 unsigned char *c = (unsigned char *) &dadr;
612 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Packet to %d.%d.%d.%d, proto %x\n",
613 c[0], c[1], c[2], c[3], pkt->ip_hdr.proto);
614 switch (pkt->ip_hdr.proto)
618 pkt_tcp = (struct ip_tcp *) pkt;
619 pkt_udp = (struct ip_udp *) pkt;
621 if ((key = address4_mapping_exists (dadr)) != NULL)
623 struct map_entry *me =
624 GNUNET_CONTAINER_multihashmap_get (hashmap, key);
625 GNUNET_assert (me != NULL);
629 sizeof (struct GNUNET_MESH_Tunnel *) +
630 sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) +
631 ntohs (pkt->ip_hdr.tot_lngth) - 4 * pkt->ip_hdr.hdr_lngth;
633 struct GNUNET_MESH_Tunnel **cls = GNUNET_malloc (size);
634 struct GNUNET_MessageHeader *hdr =
635 (struct GNUNET_MessageHeader *) (cls + 1);
636 GNUNET_HashCode *hc = (GNUNET_HashCode *) (hdr + 1);
639 htons (sizeof (struct GNUNET_MessageHeader) +
640 sizeof (GNUNET_HashCode) + ntohs (pkt->ip_hdr.tot_lngth) -
641 4 * pkt->ip_hdr.hdr_lngth);
643 GNUNET_MESH_ApplicationType app_type = 0; /* make compiler happy */
645 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "me->addrlen is %d\n",
647 if (me->addrlen == 0)
649 /* This is a mapping to a gnunet-service */
650 memcpy (hc, &me->desc.service_descriptor, sizeof (GNUNET_HashCode));
652 if ((IPPROTO_UDP == pkt->ip_hdr.proto) &&
653 (me->desc.service_type & htonl (GNUNET_DNS_SERVICE_TYPE_UDP)) &&
654 (port_in_ports (me->desc.ports, pkt_udp->udp_hdr.dpt) ||
655 testBit (me->additional_ports, ntohs (pkt_udp->udp_hdr.dpt))))
657 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP);
659 memcpy (hc + 1, &pkt_udp->udp_hdr, ntohs (pkt_udp->udp_hdr.len));
662 else if ((IPPROTO_TCP == pkt->ip_hdr.proto) &&
664 desc.service_type & htonl (GNUNET_DNS_SERVICE_TYPE_TCP))
665 && (port_in_ports (me->desc.ports, pkt_tcp->tcp_hdr.dpt)))
667 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP);
669 memcpy (hc + 1, &pkt_tcp->tcp_hdr,
670 ntohs (pkt->ip_hdr.tot_lngth) -
671 4 * pkt->ip_hdr.hdr_lngth);
674 if (me->tunnel == NULL && NULL != cls)
677 GNUNET_MESH_tunnel_create (mesh_handle,
678 initialize_tunnel_state (4, NULL),
679 send_pkt_to_peer, NULL, cls);
680 GNUNET_MESH_peer_request_connect_add (*cls,
681 (struct GNUNET_PeerIdentity
685 else if (NULL != cls)
688 send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL);
689 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
690 "Queued to send IPv4 to peer %x, type %d\n",
691 *((unsigned int *) &me->desc.peer),
697 /* This is a mapping to a "real" address */
698 struct remote_addr *s = (struct remote_addr *) hc;
700 s->addrlen = me->addrlen;
701 memcpy (s->addr, me->addr, me->addrlen);
702 s->proto = pkt->ip_hdr.proto;
703 if (s->proto == IPPROTO_UDP)
705 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP);
706 memcpy (hc + 1, &pkt_udp->udp_hdr, ntohs (pkt_udp->udp_hdr.len));
707 app_type = GNUNET_APPLICATION_TYPE_INTERNET_UDP_GATEWAY;
709 else if (s->proto == IPPROTO_TCP)
711 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP);
712 memcpy (hc + 1, &pkt_tcp->tcp_hdr,
713 ntohs (pkt->ip_hdr.tot_lngth) -
714 4 * pkt->ip_hdr.hdr_lngth);
715 app_type = GNUNET_APPLICATION_TYPE_INTERNET_TCP_GATEWAY;
719 if (me->tunnel == NULL && NULL != cls)
722 GNUNET_MESH_tunnel_create (mesh_handle,
723 initialize_tunnel_state (4, NULL),
724 send_pkt_to_peer, NULL, cls);
726 GNUNET_MESH_peer_request_connect_by_type (*cls, app_type);
729 else if (NULL != cls)
732 send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL);
738 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
739 "Packet to %x which has no mapping\n", dadr);
744 pkt_icmp = (struct ip_icmp *) pkt;
745 if (pkt_icmp->icmp_hdr.type == 0x8 &&
746 (key = address4_mapping_exists (dadr)) != NULL)
749 pkt_icmp = GNUNET_malloc (ntohs (pkt->shdr.size));
750 memcpy (pkt_icmp, pkt, ntohs (pkt->shdr.size));
751 GNUNET_SCHEDULER_add_now (&send_icmp4_response, pkt_icmp);
762 collect_mappings (void *cls GNUNET_UNUSED,
763 const struct GNUNET_SCHEDULER_TaskContext *tc)
765 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
768 struct map_entry *me = GNUNET_CONTAINER_heap_remove_root (heap);
770 /* This is free()ed memory! */
771 me->heap_node = NULL;
773 /* FIXME! GNUNET_MESH_close_tunnel(me->tunnel); */
775 GNUNET_assert (GNUNET_YES ==
776 GNUNET_CONTAINER_multihashmap_remove (hashmap, &me->hash, me));
782 send_icmp4_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
784 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
787 struct ip_icmp *request = cls;
789 struct ip_icmp *response = alloca (ntohs (request->shdr.size));
791 GNUNET_assert (response != NULL);
792 memset (response, 0, ntohs (request->shdr.size));
794 response->shdr.size = request->shdr.size;
795 response->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
797 response->tun.flags = 0;
798 response->tun.type = htons (0x0800);
800 response->ip_hdr.hdr_lngth = 5;
801 response->ip_hdr.version = 4;
802 response->ip_hdr.proto = 0x01;
803 response->ip_hdr.dadr = request->ip_hdr.sadr;
804 response->ip_hdr.sadr = request->ip_hdr.dadr;
805 response->ip_hdr.tot_lngth = request->ip_hdr.tot_lngth;
807 response->ip_hdr.chks =
808 GNUNET_CRYPTO_crc16_n ((uint16_t *) & response->ip_hdr, 20);
810 response->icmp_hdr.code = 0;
811 response->icmp_hdr.type = 0x0;
813 /* Magic, more Magic! */
814 response->icmp_hdr.chks = request->icmp_hdr.chks + 0x8;
816 /* Copy the rest of the packet */
817 memcpy (response + 1, request + 1,
818 ntohs (request->shdr.size) - sizeof (struct ip_icmp));
820 (void) GNUNET_HELPER_send (helper_handle,
824 GNUNET_free (request);
828 send_icmp6_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
830 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
833 struct ip6_icmp *request = cls;
835 struct ip6_icmp *response = alloca (ntohs (request->shdr.size));
837 GNUNET_assert (response != NULL);
838 memset (response, 0, ntohs (request->shdr.size));
840 response->shdr.size = request->shdr.size;
841 response->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
843 response->tun.flags = 0;
844 response->tun.type = htons (0x86dd);
846 response->ip6_hdr.hoplmt = 255;
847 response->ip6_hdr.paylgth = request->ip6_hdr.paylgth;
848 response->ip6_hdr.nxthdr = 0x3a;
849 response->ip6_hdr.version = 6;
850 memcpy (&response->ip6_hdr.sadr, &request->ip6_hdr.dadr, 16);
851 memcpy (&response->ip6_hdr.dadr, &request->ip6_hdr.sadr, 16);
853 response->icmp_hdr.code = 0;
854 response->icmp_hdr.type = 0x81;
856 /* Magic, more Magic! */
857 response->icmp_hdr.chks = request->icmp_hdr.chks - 0x1;
859 /* Copy the rest of the packet */
860 memcpy (response + 1, request + 1,
861 ntohs (request->shdr.size) - sizeof (struct ip6_icmp));
863 (void) GNUNET_HELPER_send (helper_handle,
867 GNUNET_free (request);
871 * cls is the pointer to a GNUNET_MessageHeader that is
872 * followed by the service-descriptor and the packet that should be sent;
875 send_pkt_to_peer_notify_callback (void *cls, size_t size, void *buf)
877 struct GNUNET_MESH_Tunnel **tunnel = cls;
879 struct tunnel_state *ts = GNUNET_MESH_tunnel_get_data (*tunnel);
885 struct GNUNET_MessageHeader *hdr =
886 (struct GNUNET_MessageHeader *) (tunnel + 1);
887 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
888 "send_pkt_to_peer_notify_callback: buf = %x; size = %u;\n", buf,
890 GNUNET_assert (size >= ntohs (hdr->size));
891 memcpy (buf, hdr, ntohs (hdr->size));
892 size = ntohs (hdr->size);
893 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sent!\n");
898 if (NULL != ts->head)
900 struct tunnel_notify_queue *element = ts->head;
902 GNUNET_CONTAINER_DLL_remove (ts->head, ts->tail, element);
905 GNUNET_MESH_notify_transmit_ready (*tunnel, GNUNET_NO, 42,
906 GNUNET_TIME_relative_divide
907 (GNUNET_CONSTANTS_MAX_CORK_DELAY, 2),
908 (const struct GNUNET_PeerIdentity *)
910 send_pkt_to_peer_notify_callback,
913 /* save the handle */
914 GNUNET_free (element);
922 port_in_ports (uint64_t ports, uint16_t port)
924 uint16_t *ps = (uint16_t *) & ports;
926 return ports == 0 || ps[0] == port || ps[1] == port || ps[2] == port ||
931 send_pkt_to_peer (void *cls, const struct GNUNET_PeerIdentity *peer,
932 const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
934 /* peer == NULL means that all peers in this request are connected */
937 struct GNUNET_MESH_Tunnel **tunnel = cls;
938 struct GNUNET_MessageHeader *hdr =
939 (struct GNUNET_MessageHeader *) (tunnel + 1);
941 GNUNET_assert (NULL != tunnel);
942 GNUNET_assert (NULL != *tunnel);
944 struct tunnel_state *ts = GNUNET_MESH_tunnel_get_data (*tunnel);
949 GNUNET_MESH_notify_transmit_ready (*tunnel, GNUNET_NO, 42,
950 GNUNET_TIME_relative_divide
951 (GNUNET_CONSTANTS_MAX_CORK_DELAY, 2),
952 (const struct GNUNET_PeerIdentity *)
953 NULL, ntohs (hdr->size),
954 send_pkt_to_peer_notify_callback,
959 struct tunnel_notify_queue *element = GNUNET_malloc (sizeof *element);
962 element->len = ntohs (hdr->size);
964 GNUNET_CONTAINER_DLL_insert_tail (ts->head, ts->tail, element);
969 * Create a new Address from an answer-packet
972 new_ip6addr (struct in6_addr *v6addr,
973 const GNUNET_HashCode * peer,
974 const GNUNET_HashCode * service_desc)
976 unsigned char *buf = (unsigned char*) v6addr;
978 unsigned long long ipv6prefix;
980 GNUNET_assert (GNUNET_OK ==
981 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR",
983 GNUNET_assert (GNUNET_OK ==
984 GNUNET_CONFIGURATION_get_value_number (cfg, "vpn",
987 GNUNET_assert (ipv6prefix < 127);
988 ipv6prefix = (ipv6prefix + 7) / 8;
990 inet_pton (AF_INET6, ipv6addr, buf);
991 GNUNET_free (ipv6addr);
993 int peer_length = 16 - ipv6prefix - 6;
995 if (peer_length <= 0)
998 int service_length = 16 - ipv6prefix - peer_length;
1000 if (service_length <= 0)
1003 memcpy (buf + ipv6prefix, service_desc, service_length);
1004 memcpy (buf + ipv6prefix + service_length, peer, peer_length);
1011 * Create a new Address from an answer-packet
1014 new_ip6addr_remote (struct in6_addr *v6addr,
1015 unsigned char *addr, char addrlen)
1017 unsigned char *buf = (unsigned char*) v6addr;
1019 unsigned long long ipv6prefix;
1021 GNUNET_assert (GNUNET_OK ==
1022 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR",
1024 GNUNET_assert (GNUNET_OK ==
1025 GNUNET_CONFIGURATION_get_value_number (cfg, "vpn",
1028 GNUNET_assert (ipv6prefix < 127);
1029 ipv6prefix = (ipv6prefix + 7) / 8;
1031 inet_pton (AF_INET6, ipv6addr, buf);
1032 GNUNET_free (ipv6addr);
1034 int local_length = 16 - ipv6prefix;
1036 memcpy (buf + ipv6prefix, addr, GNUNET_MIN (addrlen, local_length));
1042 * Create a new Address from an answer-packet
1045 new_ip4addr_remote (unsigned char *buf, unsigned char *addr, char addrlen)
1050 GNUNET_assert (GNUNET_OK ==
1051 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4ADDR",
1053 GNUNET_assert (GNUNET_OK ==
1054 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4MASK",
1058 inet_pton (AF_INET, ipv4addr, buf);
1059 int r = inet_pton (AF_INET, ipv4mask, &mask);
1061 mask = htonl (mask);
1062 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "inet_pton: %d; %m; mask: %08x\n", r,
1065 GNUNET_free (ipv4addr);
1071 mask = (mask ^ (mask - 1)) >> 1;
1072 for (c = 0; mask; c++)
1079 c = CHAR_BIT * sizeof (mask);
1083 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "The mask %s has %d leading 1s.\n",
1086 GNUNET_free (ipv4mask);
1093 memcpy (buf + c, addr, GNUNET_MIN (addrlen, 4 - c));
1099 * This gets scheduled with cls pointing to an answer_packet and does everything
1100 * needed in order to send it to the helper.
1102 * At the moment this means "inventing" and IPv6-Address for .gnunet-services and
1103 * doing nothing for "real" services.
1106 process_answer (void *cls,
1107 const struct answer_packet *pkt)
1109 struct answer_packet_list *list;
1111 /* This answer is about a .gnunet-service
1113 * It contains an almost complete DNS-Response, we have to fill in the ip
1114 * at the offset pkt->addroffset
1116 if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_SERVICE)
1119 GNUNET_HashCode key;
1121 memset (&key, 0, sizeof (GNUNET_HashCode));
1124 GNUNET_malloc (htons (pkt->hdr.size) +
1125 sizeof (struct answer_packet_list) -
1126 sizeof (struct answer_packet));
1127 memcpy (&list->pkt, pkt, htons (pkt->hdr.size));
1129 unsigned char *c = ((unsigned char *) &list->pkt) + ntohs (pkt->addroffset);
1130 unsigned char *k = (unsigned char *) &key;
1132 new_ip6addr ((struct in6_addr*) c,
1133 &pkt->service_descr.peer,
1134 &pkt->service_descr.service_descriptor);
1136 * Copy the newly generated ip-address to the key backwarts (as only the first part is hashed)
1140 for (i = 0; i < 16; i++)
1143 uint16_t namelen = strlen ((char *) pkt->data + 12) + 1;
1145 struct map_entry *value =
1146 GNUNET_malloc (sizeof (struct map_entry) + namelen);
1147 char *name = (char *) (value + 1);
1149 value->namelen = namelen;
1150 memcpy (name, pkt->data + 12, namelen);
1152 memcpy (&value->desc, &pkt->service_descr,
1153 sizeof (struct GNUNET_vpn_service_descriptor));
1155 memset (value->additional_ports, 0, 8192);
1157 memcpy (&value->hash, &key, sizeof (GNUNET_HashCode));
1159 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (hashmap, &key))
1161 GNUNET_CONTAINER_multihashmap_put (hashmap, &key, value,
1162 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1165 GNUNET_CONTAINER_heap_insert (heap, value,
1166 GNUNET_TIME_absolute_get ().abs_value);
1167 if (GNUNET_CONTAINER_heap_get_size (heap) > max_mappings)
1168 GNUNET_SCHEDULER_add_now (collect_mappings, NULL);
1171 GNUNET_free (value);
1174 list->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_IP;
1178 else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REV)
1180 GNUNET_HashCode key;
1182 memset (&key, 0, sizeof key);
1183 unsigned char *k = (unsigned char *) &key;
1184 const unsigned char *s = pkt->data + 12;
1187 /* Whoever designed the reverse IPv6-lookup is batshit insane */
1188 for (i = 0; i < 16; i++)
1190 unsigned char c1 = s[(4 * i) + 1];
1191 unsigned char c2 = s[(4 * i) + 3];
1196 k[i] = c1 - 87; /* 87 is the difference between 'a' and 10 */
1198 k[i] += 16 * (c2 - '0');
1200 k[i] += 16 * (c2 - 87);
1203 struct map_entry *map_entry =
1204 GNUNET_CONTAINER_multihashmap_get (hashmap, &key);
1205 uint16_t offset = ntohs (pkt->addroffset);
1207 if (map_entry == NULL)
1210 GNUNET_CONTAINER_heap_update_cost (heap, map_entry->heap_node,
1211 GNUNET_TIME_absolute_get ().abs_value);
1214 unsigned short namelen = htons (map_entry->namelen);
1215 char *name = (char *) (map_entry + 1);
1218 GNUNET_malloc (sizeof (struct answer_packet_list) -
1219 sizeof (struct answer_packet) + offset + 2 +
1222 struct answer_packet *rpkt = &list->pkt;
1224 /* The offset points to the first byte belonging to the address */
1225 memcpy (rpkt, pkt, offset - 1);
1227 rpkt->subtype = GNUNET_DNS_ANSWER_TYPE_IP;
1228 rpkt->hdr.size = ntohs (offset + 2 + ntohs (namelen));
1230 memcpy (((char *) rpkt) + offset, &namelen, 2);
1231 memcpy (((char *) rpkt) + offset + 2, name, ntohs (namelen));
1234 else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_IP)
1237 GNUNET_malloc (htons (pkt->hdr.size) +
1238 sizeof (struct answer_packet_list) -
1239 sizeof (struct answer_packet));
1240 memcpy (&list->pkt, pkt, htons (pkt->hdr.size));
1242 else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REMOTE_AAAA)
1245 GNUNET_HashCode key;
1247 memset (&key, 0, sizeof (GNUNET_HashCode));
1250 GNUNET_malloc (htons (pkt->hdr.size) +
1251 sizeof (struct answer_packet_list) -
1252 sizeof (struct answer_packet));
1254 memcpy (&list->pkt, pkt, htons (pkt->hdr.size));
1255 list->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_IP;
1257 unsigned char *c = ((unsigned char *) &list->pkt) + ntohs (list->pkt.addroffset);
1259 new_ip6addr_remote ((struct in6_addr*) c,
1260 list->pkt.addr, list->pkt.addrsize);
1261 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1262 "New mapping to %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
1263 c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8], c[9],
1264 c[10], c[11], c[12], c[13], c[14], c[15]);
1265 unsigned char *k = (unsigned char *) &key;
1268 * Copy the newly generated ip-address to the key backwards (as only the first part is used in the hash-table)
1272 for (i = 0; i < 16; i++)
1275 uint16_t namelen = strlen ((char *) pkt->data + 12) + 1;
1277 struct map_entry *value =
1278 GNUNET_malloc (sizeof (struct map_entry) + namelen);
1279 char *name = (char *) (value + 1);
1281 value->namelen = namelen;
1282 memcpy (name, pkt->data + 12, namelen);
1284 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting addrlen to %d\n",
1286 value->addrlen = pkt->addrsize;
1287 memcpy (&value->addr, &pkt->addr, pkt->addrsize);
1288 memset (value->additional_ports, 0, 8192);
1290 memcpy (&value->hash, &key, sizeof (GNUNET_HashCode));
1292 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (hashmap, &key))
1294 GNUNET_CONTAINER_multihashmap_put (hashmap, &key, value,
1295 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1297 GNUNET_CONTAINER_heap_insert (heap, value,
1298 GNUNET_TIME_absolute_get ().abs_value);
1299 if (GNUNET_CONTAINER_heap_get_size (heap) > max_mappings)
1300 GNUNET_SCHEDULER_add_now (collect_mappings, NULL);
1303 GNUNET_free (value);
1307 else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REMOTE_A)
1310 GNUNET_malloc (htons (pkt->hdr.size) +
1311 sizeof (struct answer_packet_list) -
1312 sizeof (struct answer_packet));
1314 memcpy (&list->pkt, pkt, htons (pkt->hdr.size));
1315 list->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_IP;
1317 GNUNET_HashCode key;
1319 memset (&key, 0, sizeof (GNUNET_HashCode));
1321 unsigned char *c = ((unsigned char *) &list->pkt) + ntohs (pkt->addroffset);
1323 new_ip4addr_remote (c, list->pkt.addr, pkt->addrsize);
1324 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New mapping to %d.%d.%d.%d\n", c[0],
1326 unsigned char *k = (unsigned char *) &key;
1329 * Copy the newly generated ip-address to the key backwards (as only the first part is used in the hash-table)
1333 for (i = 0; i < 4; i++)
1336 uint16_t namelen = strlen ((char *) pkt->data + 12) + 1;
1338 struct map_entry *value =
1339 GNUNET_malloc (sizeof (struct map_entry) + namelen);
1340 char *name = (char *) (value + 1);
1342 value->namelen = namelen;
1343 memcpy (name, pkt->data + 12, namelen);
1345 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting addrlen to %d\n",
1347 value->addrlen = pkt->addrsize;
1348 memcpy (&value->addr, &pkt->addr, pkt->addrsize);
1349 memset (value->additional_ports, 0, 8192);
1351 memcpy (&value->hash, &key, sizeof (GNUNET_HashCode));
1353 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (hashmap, &key))
1355 GNUNET_CONTAINER_multihashmap_put (hashmap, &key, value,
1356 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1358 GNUNET_CONTAINER_heap_insert (heap, value,
1359 GNUNET_TIME_absolute_get ().abs_value);
1360 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1361 "Mapping is saved in the hashmap with key %08x.\n",
1362 *((uint32_t *) (&key)));
1363 if (GNUNET_CONTAINER_heap_get_size (heap) > max_mappings)
1364 GNUNET_SCHEDULER_add_now (collect_mappings, NULL);
1367 GNUNET_free (value);
1376 GNUNET_CONTAINER_DLL_insert_after (answer_proc_head, answer_proc_tail,
1377 answer_proc_tail, list);
1383 * @brief Add the port to the list of additional ports in the map_entry
1385 * @param me the map_entry
1386 * @param port the port in host-byte-order
1389 add_additional_port (struct map_entry *me, uint16_t port)
1391 setBit (me->additional_ports, port);
1395 receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1396 void **tunnel_ctx, const struct GNUNET_PeerIdentity *sender,
1397 const struct GNUNET_MessageHeader *message,
1398 const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1400 GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1);
1401 struct remote_addr *s = (struct remote_addr *) desc;
1402 struct udp_pkt *pkt = (struct udp_pkt *) (desc + 1);
1403 const struct GNUNET_PeerIdentity *other = sender;
1404 struct tunnel_state *ts = *tunnel_ctx;
1406 if (16 == ts->addrlen)
1409 sizeof (struct ip6_udp) + ntohs (pkt->len) - 1 -
1410 sizeof (struct udp_pkt);
1412 struct ip6_udp *pkt6 = alloca (size);
1414 GNUNET_assert (pkt6 != NULL);
1416 if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK)
1417 new_ip6addr (&pkt6->ip6_hdr.sadr, &other->hashPubKey, desc);
1419 new_ip6addr_remote (&pkt6->ip6_hdr.sadr, s->addr, s->addrlen);
1421 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1422 "Relaying calc:%d gnu:%d udp:%d bytes!\n", size,
1423 ntohs (message->size), ntohs (pkt->len));
1425 pkt6->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1426 pkt6->shdr.size = htons (size);
1428 pkt6->tun.flags = 0;
1429 pkt6->tun.type = htons (0x86dd);
1431 pkt6->ip6_hdr.version = 6;
1432 pkt6->ip6_hdr.tclass_h = 0;
1433 pkt6->ip6_hdr.tclass_l = 0;
1434 pkt6->ip6_hdr.flowlbl = 0;
1435 pkt6->ip6_hdr.paylgth = pkt->len;
1436 pkt6->ip6_hdr.nxthdr = IPPROTO_UDP;
1437 pkt6->ip6_hdr.hoplmt = 0xff;
1442 GNUNET_assert (GNUNET_OK ==
1443 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn",
1446 inet_pton (AF_INET6, ipv6addr, &pkt6->ip6_hdr.dadr);
1447 GNUNET_free (ipv6addr);
1449 memcpy (&pkt6->udp_hdr, pkt, ntohs (pkt->len));
1451 GNUNET_HashCode *key = address6_mapping_exists (&pkt6->ip6_hdr.sadr);
1453 GNUNET_assert (key != NULL);
1455 struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
1457 GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node,
1458 GNUNET_TIME_absolute_get ().abs_value);
1462 GNUNET_assert (me != NULL);
1463 if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK)
1465 GNUNET_assert (me->desc.
1466 service_type & htonl (GNUNET_DNS_SERVICE_TYPE_UDP));
1467 if (!port_in_ports (me->desc.ports, pkt6->udp_hdr.spt) &&
1468 !testBit (me->additional_ports, ntohs (pkt6->udp_hdr.spt)))
1470 add_additional_port (me, ntohs (pkt6->udp_hdr.spt));
1474 pkt6->udp_hdr.crc = 0;
1478 GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.sadr, 16);
1480 GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.dadr, 16);
1481 uint32_t tmp = (pkt6->udp_hdr.len & 0xffff);
1483 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4);
1484 tmp = htons (((pkt6->ip6_hdr.nxthdr & 0x00ff)));
1485 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4);
1488 GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->udp_hdr,
1490 pkt6->udp_hdr.crc = GNUNET_CRYPTO_crc16_finish (sum);
1492 (void) GNUNET_HELPER_send (helper_handle,
1500 sizeof (struct ip_udp) + ntohs (pkt->len) - 1 - sizeof (struct udp_pkt);
1502 struct ip_udp *pkt4 = alloca (size);
1504 GNUNET_assert (pkt4 != NULL);
1506 GNUNET_assert (ntohs (message->type) ==
1507 GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP_BACK);
1510 new_ip4addr_remote ((unsigned char *) &sadr, s->addr, s->addrlen);
1511 pkt4->ip_hdr.sadr.s_addr = sadr;
1513 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1514 "Relaying calc:%d gnu:%d udp:%d bytes!\n", size,
1515 ntohs (message->size), ntohs (pkt->len));
1517 pkt4->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1518 pkt4->shdr.size = htons (size);
1520 pkt4->tun.flags = 0;
1521 pkt4->tun.type = htons (0x0800);
1523 pkt4->ip_hdr.version = 4;
1524 pkt4->ip_hdr.hdr_lngth = 5;
1525 pkt4->ip_hdr.diff_serv = 0;
1526 pkt4->ip_hdr.tot_lngth = htons (20 + ntohs (pkt->len));
1527 pkt4->ip_hdr.ident = 0;
1528 pkt4->ip_hdr.flags = 0;
1529 pkt4->ip_hdr.frag_off = 0;
1530 pkt4->ip_hdr.ttl = 255;
1531 pkt4->ip_hdr.proto = IPPROTO_UDP;
1532 pkt4->ip_hdr.chks = 0; /* Will be calculated later */
1538 GNUNET_assert (GNUNET_OK ==
1539 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn",
1542 inet_pton (AF_INET, ipv4addr, &dadr);
1543 GNUNET_free (ipv4addr);
1544 pkt4->ip_hdr.dadr.s_addr = dadr;
1546 memcpy (&pkt4->udp_hdr, pkt, ntohs (pkt->len));
1548 GNUNET_HashCode *key = address4_mapping_exists (pkt4->ip_hdr.sadr.s_addr);
1550 GNUNET_assert (key != NULL);
1552 struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
1554 GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node,
1555 GNUNET_TIME_absolute_get ().abs_value);
1559 GNUNET_assert (me != NULL);
1561 pkt4->udp_hdr.crc = 0; /* Optional for IPv4 */
1564 GNUNET_CRYPTO_crc16_n ((uint16_t *) & pkt4->ip_hdr, 5 * 4);
1566 (void) GNUNET_HELPER_send (helper_handle,
1576 receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1578 const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1579 const struct GNUNET_MessageHeader *message,
1580 const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1582 GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1);
1583 struct remote_addr *s = (struct remote_addr *) desc;
1584 struct tcp_pkt *pkt = (struct tcp_pkt *) (desc + 1);
1585 const struct GNUNET_PeerIdentity *other = sender;
1586 struct tunnel_state *ts = *tunnel_ctx;
1589 ntohs (message->size) - sizeof (struct GNUNET_MessageHeader) -
1590 sizeof (GNUNET_HashCode);
1592 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1593 "Received TCP-Packet back, addrlen = %d\n", s->addrlen);
1595 if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP_BACK ||
1598 size_t size = pktlen + sizeof (struct ip6_tcp) - 1;
1600 struct ip6_tcp *pkt6 = alloca (size);
1602 memset (pkt6, 0, size);
1604 GNUNET_assert (pkt6 != NULL);
1606 if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP_BACK)
1607 new_ip6addr (&pkt6->ip6_hdr.sadr, &other->hashPubKey, desc);
1609 new_ip6addr_remote (&pkt6->ip6_hdr.sadr, s->addr, s->addrlen);
1611 pkt6->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1612 pkt6->shdr.size = htons (size);
1614 pkt6->tun.flags = 0;
1615 pkt6->tun.type = htons (0x86dd);
1617 pkt6->ip6_hdr.version = 6;
1618 pkt6->ip6_hdr.tclass_h = 0;
1619 pkt6->ip6_hdr.tclass_l = 0;
1620 pkt6->ip6_hdr.flowlbl = 0;
1621 pkt6->ip6_hdr.paylgth = htons (pktlen);
1622 pkt6->ip6_hdr.nxthdr = IPPROTO_TCP;
1623 pkt6->ip6_hdr.hoplmt = 0xff;
1628 GNUNET_assert (GNUNET_OK ==
1629 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn",
1632 inet_pton (AF_INET6, ipv6addr, &pkt6->ip6_hdr.dadr);
1633 GNUNET_free (ipv6addr);
1635 memcpy (&pkt6->tcp_hdr, pkt, pktlen);
1637 GNUNET_HashCode *key = address6_mapping_exists (&pkt6->ip6_hdr.sadr);
1639 GNUNET_assert (key != NULL);
1641 struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
1643 GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node,
1644 GNUNET_TIME_absolute_get ().abs_value);
1648 GNUNET_assert (me != NULL);
1649 if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK)
1650 GNUNET_assert (me->desc.
1651 service_type & htonl (GNUNET_DNS_SERVICE_TYPE_TCP));
1653 pkt6->tcp_hdr.crc = 0;
1658 GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.sadr, 16);
1660 GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.dadr, 16);
1661 tmp = htonl (pktlen);
1662 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4);
1663 tmp = htonl (((pkt6->ip6_hdr.nxthdr & 0x000000ff)));
1664 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4);
1667 GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->tcp_hdr,
1668 ntohs (pkt6->ip6_hdr.paylgth));
1669 pkt6->tcp_hdr.crc = GNUNET_CRYPTO_crc16_finish (sum);
1671 (void) GNUNET_HELPER_send (helper_handle,
1678 size_t size = pktlen + sizeof (struct ip_tcp) - 1;
1680 struct ip_tcp *pkt4 = alloca (size);
1682 GNUNET_assert (pkt4 != NULL);
1683 memset (pkt4, 0, size);
1685 GNUNET_assert (ntohs (message->type) ==
1686 GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP_BACK);
1689 new_ip4addr_remote ((unsigned char *) &sadr, s->addr, s->addrlen);
1690 pkt4->ip_hdr.sadr.s_addr = sadr;
1692 pkt4->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1693 pkt4->shdr.size = htons (size);
1695 pkt4->tun.flags = 0;
1696 pkt4->tun.type = htons (0x0800);
1698 pkt4->ip_hdr.version = 4;
1699 pkt4->ip_hdr.hdr_lngth = 5;
1700 pkt4->ip_hdr.diff_serv = 0;
1701 pkt4->ip_hdr.tot_lngth = htons (20 + pktlen);
1702 pkt4->ip_hdr.ident = 0;
1703 pkt4->ip_hdr.flags = 0;
1704 pkt4->ip_hdr.frag_off = 0;
1705 pkt4->ip_hdr.ttl = 255;
1706 pkt4->ip_hdr.proto = IPPROTO_TCP;
1707 pkt4->ip_hdr.chks = 0; /* Will be calculated later */
1713 GNUNET_assert (GNUNET_OK ==
1714 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn",
1717 inet_pton (AF_INET, ipv4addr, &dadr);
1718 GNUNET_free (ipv4addr);
1719 pkt4->ip_hdr.dadr.s_addr = dadr;
1722 memcpy (&pkt4->tcp_hdr, pkt, pktlen);
1724 GNUNET_HashCode *key = address4_mapping_exists (pkt4->ip_hdr.sadr.s_addr);
1726 GNUNET_assert (key != NULL);
1728 struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
1730 GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node,
1731 GNUNET_TIME_absolute_get ().abs_value);
1735 GNUNET_assert (me != NULL);
1736 pkt4->tcp_hdr.crc = 0;
1740 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) &pkt4->ip_hdr.sadr, 4);
1741 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) &pkt4->ip_hdr.dadr, 4);
1743 tmp = (0x06 << 16) | (0xffff & pktlen); // 0x06 for TCP?
1747 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4);
1749 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt4->tcp_hdr, pktlen);
1750 pkt4->tcp_hdr.crc = GNUNET_CRYPTO_crc16_finish (sum);
1753 GNUNET_CRYPTO_crc16_n ((uint16_t *) & pkt4->ip_hdr, 5 * 4);
1755 (void) GNUNET_HELPER_send (helper_handle,
1766 new_tunnel (void *cls, struct GNUNET_MESH_Tunnel *tunnel,
1767 const struct GNUNET_PeerIdentity *initiator,
1768 const struct GNUNET_ATS_Information *atsi)
1770 /* Why should anyone open an inbound tunnel to vpn? */
1776 cleaner (void *cls, const struct GNUNET_MESH_Tunnel *tunnel, void *tunnel_ctx)
1778 /* Why should anyone open an inbound tunnel to vpn? */
1783 * Main function that will be run by the scheduler.
1785 * @param cls closure
1786 * @param args remaining command-line arguments
1787 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
1788 * @param cfg_ configuration
1791 run (void *cls, char *const *args GNUNET_UNUSED,
1792 const char *cfgfile GNUNET_UNUSED,
1793 const struct GNUNET_CONFIGURATION_Handle *cfg_)
1795 static const struct GNUNET_MESH_MessageHandler handlers[] = {
1796 {receive_udp_back, GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK, 0},
1797 {receive_tcp_back, GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP_BACK, 0},
1798 {receive_udp_back, GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP_BACK, 0},
1799 {receive_tcp_back, GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP_BACK, 0},
1802 static const GNUNET_MESH_ApplicationType types[] = {
1803 GNUNET_APPLICATION_TYPE_END
1812 GNUNET_MESH_connect (cfg_, 42, NULL, new_tunnel, cleaner, handlers,
1815 hashmap = GNUNET_CONTAINER_multihashmap_create (65536);
1816 heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
1817 GNUNET_CONFIGURATION_get_value_number (cfg, "vpn", "MAX_MAPPINGg",
1819 udp_connections = GNUNET_CONTAINER_multihashmap_create (65536);
1820 dns_handle = GNUNET_DNS_connect (cfg,
1823 if (GNUNET_SYSERR ==
1824 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IFNAME", &ifname))
1826 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1827 "No entry 'IFNAME' in configuration!\n");
1831 if (GNUNET_SYSERR ==
1832 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR", &ipv6addr))
1834 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1835 "No entry 'IPV6ADDR' in configuration!\n");
1839 if (GNUNET_SYSERR ==
1840 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6PREFIX",
1843 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1844 "No entry 'IPV6PREFIX' in configuration!\n");
1848 if (GNUNET_SYSERR ==
1849 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4ADDR", &ipv4addr))
1851 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1852 "No entry 'IPV4ADDR' in configuration!\n");
1856 if (GNUNET_SYSERR ==
1857 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4MASK", &ipv4mask))
1859 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1860 "No entry 'IPV4MASK' in configuration!\n");
1864 vpn_argv[0] = GNUNET_strdup ("vpn-gnunet");
1865 vpn_argv[1] = ifname;
1866 vpn_argv[2] = ipv6addr;
1867 vpn_argv[3] = ipv6prefix;
1868 vpn_argv[4] = ipv4addr;
1869 vpn_argv[5] = ipv4mask;
1872 helper_handle = GNUNET_HELPER_start ("gnunet-helper-vpn", vpn_argv,
1873 &message_token, NULL);
1874 GNUNET_DNS_restart_hijack (dns_handle);
1875 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls);
1879 * The main function to obtain template from gnunetd.
1881 * @param argc number of arguments from the command line
1882 * @param argv command line arguments
1883 * @return 0 ok, 1 on error
1886 main (int argc, char *const *argv)
1888 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
1889 GNUNET_GETOPT_OPTION_END
1892 return (GNUNET_OK ==
1893 GNUNET_PROGRAM_run (argc, argv, "vpn", gettext_noop ("help text"),
1894 options, &run, NULL)) ? ret : 1;
1897 /* end of gnunet-daemon-vpn.c */