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"
41 const struct GNUNET_CONFIGURATION_Handle *cfg;
42 struct GNUNET_MESH_Handle *mesh_handle;
43 struct GNUNET_CONTAINER_MultiHashMap *hashmap;
44 static struct GNUNET_CONTAINER_Heap *heap;
47 * The handle to the helper
49 static struct GNUNET_HELPER_Handle *helper_handle;
52 * Arguments to the exit helper.
54 static char *vpn_argv[7];
56 struct GNUNET_DNS_Handle *dns_handle;
58 struct answer_packet_list *answer_proc_head;
60 struct answer_packet_list *answer_proc_tail;
62 struct answer_packet_list
64 struct answer_packet_list *next GNUNET_PACKED;
65 struct answer_packet_list *prev GNUNET_PACKED;
66 struct GNUNET_SERVER_Client *client;
67 struct answer_packet pkt;
72 send_icmp6_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
74 send_icmp4_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
77 send_udp_service (void *cls, size_t size, void *buf);
80 address6_mapping_exists (struct in6_addr *v6addr);
82 address4_mapping_exists (uint32_t addr);
85 port_in_ports (uint64_t ports, uint16_t port);
88 send_pkt_to_peer (void *cls, const struct GNUNET_PeerIdentity *peer,
89 const struct GNUNET_ATS_Information *atsi);
93 /** The description of the service (used for service) */
94 struct GNUNET_vpn_service_descriptor desc;
96 /** The real address of the service (used for remote) */
100 struct GNUNET_MESH_Tunnel *tunnel;
102 char additional_ports[8192];
104 struct GNUNET_CONTAINER_HeapNode *heap_node;
105 GNUNET_HashCode hash;
107 * After this struct the name is located in DNS-Format!
115 unsigned char addr[16];
121 struct GNUNET_MESH_TransmitHandle *th;
122 struct tunnel_notify_queue *head, *tail;
128 struct tunnel_notify_queue
130 struct tunnel_notify_queue *next;
131 struct tunnel_notify_queue *prev;
137 * If there are at least this many address-mappings, old ones will be removed
139 static long long unsigned int max_mappings = 200;
147 * This hashmap contains the mapping from peer, service-descriptor,
148 * source-port and destination-port to a socket
150 static struct GNUNET_CONTAINER_MultiHashMap *udp_connections;
152 GNUNET_SCHEDULER_TaskIdentifier conn_task;
154 GNUNET_SCHEDULER_TaskIdentifier shs_task;
158 * The tunnels that will be used to send tcp- and udp-packets
160 static struct GNUNET_MESH_Tunnel *tcp_tunnel;
161 static struct GNUNET_MESH_Tunnel *udp_tunnel;
166 * Sets a bit active in a bitArray.
168 * @param bitArray memory area to set the bit in
169 * @param bitIdx which bit to set
172 setBit (char *bitArray, unsigned int bitIdx)
175 unsigned int targetBit;
177 arraySlot = bitIdx / 8;
178 targetBit = (1L << (bitIdx % 8));
179 bitArray[arraySlot] |= targetBit;
184 * Checks if a bit is active in the bitArray
186 * @param bitArray memory area to set the bit in
187 * @param bitIdx which bit to test
188 * @return GNUNET_YES if the bit is set, GNUNET_NO if not.
191 testBit (char *bitArray, unsigned int bitIdx)
194 unsigned int targetBit;
197 targetBit = (1L << (bitIdx % 8));
198 if (bitArray[slot] & targetBit)
206 * Function scheduled as very last function, cleans up after us
210 cleanup (void *cls GNUNET_UNUSED,
211 const struct GNUNET_SCHEDULER_TaskContext *tskctx)
215 GNUNET_assert (0 != (tskctx->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN));
216 /* close the connection to the service-dns */
217 GNUNET_DNS_disconnect (dns_handle);
218 if (mesh_handle != NULL)
220 GNUNET_MESH_disconnect (mesh_handle);
223 if (helper_handle != NULL)
225 GNUNET_HELPER_stop (helper_handle);
226 helper_handle = NULL;
228 if (GNUNET_SCHEDULER_NO_TASK != shs_task)
230 GNUNET_SCHEDULER_cancel (shs_task);
231 shs_task = GNUNET_SCHEDULER_NO_TASK;
233 if (GNUNET_SCHEDULER_NO_TASK != conn_task)
235 GNUNET_SCHEDULER_cancel (conn_task);
236 conn_task = GNUNET_SCHEDULER_NO_TASK;
239 GNUNET_free_non_null (vpn_argv[i]);
245 * @return the hash of the IP-Address if a mapping exists, NULL otherwise
248 address6_mapping_exists (struct in6_addr *v6addr)
250 unsigned char *addr = (unsigned char*) v6addr;
251 GNUNET_HashCode *key = GNUNET_malloc (sizeof (GNUNET_HashCode));
252 unsigned char *k = (unsigned char *) key;
254 memset (key, 0, sizeof (GNUNET_HashCode));
257 for (i = 0; i < 16; i++)
260 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (hashmap, key))
270 * @return the hash of the IP-Address if a mapping exists, NULL otherwise
273 address4_mapping_exists (uint32_t addr)
275 GNUNET_HashCode *key = GNUNET_malloc (sizeof (GNUNET_HashCode));
277 memset (key, 0, sizeof (GNUNET_HashCode));
278 unsigned char *c = (unsigned char *) &addr;
279 unsigned char *k = (unsigned char *) key;
282 for (i = 0; i < 4; i++)
285 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
286 "a4_m_e: getting with key %08x, addr is %08x, %d.%d.%d.%d\n",
287 *((uint32_t *) (key)), addr, c[0], c[1], c[2], c[3]);
289 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (hashmap, key))
294 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Mapping not found!\n");
301 initialize_tunnel_state (int addrlen, struct GNUNET_MESH_TransmitHandle *th)
303 struct tunnel_state *ts = GNUNET_malloc (sizeof *ts);
305 ts->addrlen = addrlen;
311 * Send an dns-answer-packet to the helper
314 helper_write (void *cls GNUNET_UNUSED,
317 struct answer_packet_list *ans = answer_proc_head;
321 if (GNUNET_SYSERR == status)
324 size_t len = ntohs (ans->pkt.hdr.size);
326 GNUNET_assert (ans->pkt.subtype == GNUNET_DNS_ANSWER_TYPE_IP);
328 GNUNET_assert (20 == sizeof (struct ip_hdr));
329 GNUNET_assert (8 == sizeof (struct udp_pkt));
331 size_t data_len = len - sizeof (struct answer_packet) + 1;
335 if (ans->pkt.addrlen == 16)
338 sizeof (struct ip6_hdr) + sizeof (struct udp_dns) + data_len;
340 sizeof (struct GNUNET_MessageHeader) + sizeof (struct pkt_tun) +
343 struct ip6_udp_dns *pkt = alloca (pkt_len);
345 GNUNET_assert (pkt != NULL);
346 memset (pkt, 0, pkt_len);
348 /* set the gnunet-header */
349 pkt->shdr.size = htons (pkt_len);
350 pkt->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
352 /* set the tun-header (no flags and ethertype of IPv4) */
354 pkt->tun.type = htons (0x86dd);
356 memcpy (&pkt->ip6_hdr.sadr, ans->pkt.from, 16);
357 memcpy (&pkt->ip6_hdr.dadr, ans->pkt.to, 16);
359 /* set the udp-header */
360 pkt->udp_dns.udp_hdr.spt = htons (53);
361 pkt->udp_dns.udp_hdr.dpt = ans->pkt.dst_port;
362 pkt->udp_dns.udp_hdr.len = htons (net_len - sizeof (struct ip6_hdr));
363 pkt->udp_dns.udp_hdr.crc = 0;
366 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt->ip6_hdr.sadr, 16);
367 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt->ip6_hdr.dadr, 16);
368 uint32_t tmp = (pkt->udp_dns.udp_hdr.len & 0xffff);
370 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4);
371 tmp = htons (((pkt->ip6_hdr.nxthdr & 0x00ff)));
372 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4);
375 GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt->udp_dns.udp_hdr,
376 ntohs (net_len - sizeof (struct ip6_hdr)));
377 pkt->udp_dns.udp_hdr.crc = GNUNET_CRYPTO_crc16_finish (sum);
379 pkt->ip6_hdr.version = 6;
380 pkt->ip6_hdr.paylgth = net_len - sizeof (struct ip6_hdr);
381 pkt->ip6_hdr.nxthdr = IPPROTO_UDP;
382 pkt->ip6_hdr.hoplmt = 0xff;
384 memcpy (&pkt->udp_dns.data, ans->pkt.data, data_len);
385 (void) GNUNET_HELPER_send (helper_handle,
388 &helper_write, NULL);
390 else if (ans->pkt.addrlen == 4)
393 sizeof (struct ip_hdr) + sizeof (struct udp_dns) + data_len;
395 sizeof (struct GNUNET_MessageHeader) + sizeof (struct pkt_tun) +
398 struct ip_udp_dns *pkt = alloca (pkt_len);
400 GNUNET_assert (pkt != NULL);
401 memset (pkt, 0, pkt_len);
403 /* set the gnunet-header */
404 pkt->shdr.size = htons (pkt_len);
405 pkt->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
407 /* set the tun-header (no flags and ethertype of IPv4) */
409 pkt->tun.type = htons (0x0800);
411 /* set the ip-header */
412 pkt->ip_hdr.version = 4;
413 pkt->ip_hdr.hdr_lngth = 5;
414 pkt->ip_hdr.diff_serv = 0;
415 pkt->ip_hdr.tot_lngth = htons (net_len);
416 pkt->ip_hdr.ident = 0;
417 pkt->ip_hdr.flags = 0;
418 pkt->ip_hdr.frag_off = 0;
419 pkt->ip_hdr.ttl = 255;
420 pkt->ip_hdr.proto = IPPROTO_UDP;
421 pkt->ip_hdr.chks = 0; /* Will be calculated later */
423 memcpy (&pkt->ip_hdr.sadr, ans->pkt.from, 4);
424 memcpy (&pkt->ip_hdr.dadr, ans->pkt.to, 4);
427 GNUNET_CRYPTO_crc16_n ((uint16_t *) & pkt->ip_hdr, 5 * 4);
429 /* set the udp-header */
430 pkt->udp_dns.udp_hdr.spt = htons (53);
431 pkt->udp_dns.udp_hdr.dpt = ans->pkt.dst_port;
432 pkt->udp_dns.udp_hdr.len = htons (net_len - sizeof (struct ip_hdr));
433 pkt->udp_dns.udp_hdr.crc = 0; /* Optional for IPv4 */
435 memcpy (&pkt->udp_dns.data, ans->pkt.data, data_len);
436 (void) GNUNET_HELPER_send (helper_handle,
439 &helper_write, NULL);
444 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Wrong addrlen = %d\n",
447 return; /* convince compiler that we're done here */
450 GNUNET_CONTAINER_DLL_remove (answer_proc_head, answer_proc_tail, ans);
456 * Receive packets from the helper-process
459 message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED,
460 const struct GNUNET_MessageHeader *message)
462 GNUNET_assert (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_HELPER);
464 struct tun_pkt *pkt_tun = (struct tun_pkt *) message;
465 GNUNET_HashCode *key;
467 /* ethertype is ipv6 */
468 if (ntohs (pkt_tun->tun.type) == 0x86dd)
470 struct ip6_pkt *pkt6 = (struct ip6_pkt *) message;
472 GNUNET_assert (pkt6->ip6_hdr.version == 6);
473 struct ip6_tcp *pkt6_tcp;
474 struct ip6_udp *pkt6_udp;
475 struct ip6_icmp *pkt6_icmp;
477 pkt6_udp = NULL; /* make compiler happy */
478 switch (pkt6->ip6_hdr.nxthdr)
481 pkt6_udp = (struct ip6_udp *) pkt6;
482 /* Send dns-packets to the service-dns */
483 if (ntohs (pkt6_udp->udp_hdr.dpt) == 53)
485 /* 9 = 8 for the udp-header + 1 for the unsigned char data[1]; */
486 GNUNET_DNS_queue_request_v6 (dns_handle,
489 ntohs (pkt6_udp->udp_hdr.spt),
490 ntohs (pkt6_udp->udp_hdr.len) - 8,
491 (const void*) pkt6_udp->data);
497 pkt6_tcp = (struct ip6_tcp *) pkt6;
499 if ((key = address6_mapping_exists (&pkt6->ip6_hdr.dadr)) != NULL)
501 struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
503 GNUNET_assert (me != NULL);
507 sizeof (struct GNUNET_MESH_Tunnel *) +
508 sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) +
509 ntohs (pkt6->ip6_hdr.paylgth);
511 struct GNUNET_MESH_Tunnel **cls = GNUNET_malloc (size);
512 struct GNUNET_MessageHeader *hdr =
513 (struct GNUNET_MessageHeader *) (cls + 1);
514 GNUNET_HashCode *hc = (GNUNET_HashCode *) (hdr + 1);
517 htons (sizeof (struct GNUNET_MessageHeader) +
518 sizeof (GNUNET_HashCode) + ntohs (pkt6->ip6_hdr.paylgth));
520 GNUNET_MESH_ApplicationType app_type = 0; /* fix compiler uninitialized warning... */
522 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "me->addrlen is %d\n",
524 if (me->addrlen == 0)
526 /* This is a mapping to a gnunet-service */
527 memcpy (hc, &me->desc.service_descriptor, sizeof (GNUNET_HashCode));
529 if (IPPROTO_UDP == pkt6->ip6_hdr.nxthdr &&
530 (me->desc.service_type & htonl (GNUNET_DNS_SERVICE_TYPE_UDP)) &&
531 (port_in_ports (me->desc.ports, pkt6_udp->udp_hdr.dpt) ||
532 testBit (me->additional_ports, ntohs (pkt6_udp->udp_hdr.dpt))))
534 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP);
536 memcpy (hc + 1, &pkt6_udp->udp_hdr, ntohs (pkt6_udp->udp_hdr.len));
539 else if (IPPROTO_TCP == pkt6->ip6_hdr.nxthdr &&
540 (me->desc.service_type & htonl (GNUNET_DNS_SERVICE_TYPE_TCP))
541 && (port_in_ports (me->desc.ports, pkt6_tcp->tcp_hdr.dpt)))
543 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP);
545 memcpy (hc + 1, &pkt6_tcp->tcp_hdr, ntohs (pkt6->ip6_hdr.paylgth));
550 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "pip: %d\n",
551 port_in_ports (me->desc.ports, pkt6_tcp->tcp_hdr.dpt));
554 if (me->tunnel == NULL && NULL != cls)
557 GNUNET_MESH_tunnel_create (mesh_handle,
558 initialize_tunnel_state (16, NULL),
559 &send_pkt_to_peer, NULL, cls);
561 GNUNET_MESH_peer_request_connect_add (*cls,
562 (struct GNUNET_PeerIdentity *)
566 else if (NULL != cls)
569 send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL);
570 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
571 "Queued to send IPv6 to peer %x, type %d\n",
572 *((unsigned int *) &me->desc.peer), ntohs (hdr->type));
577 /* This is a mapping to a "real" address */
578 struct remote_addr *s = (struct remote_addr *) hc;
580 s->addrlen = me->addrlen;
581 memcpy (s->addr, me->addr, me->addrlen);
582 s->proto = pkt6->ip6_hdr.nxthdr;
583 if (s->proto == IPPROTO_UDP)
585 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP);
586 memcpy (hc + 1, &pkt6_udp->udp_hdr, ntohs (pkt6_udp->udp_hdr.len));
587 app_type = GNUNET_APPLICATION_TYPE_INTERNET_UDP_GATEWAY;
588 if (NULL != udp_tunnel)
589 me->tunnel = udp_tunnel;
591 else if (s->proto == IPPROTO_TCP)
593 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP);
594 memcpy (hc + 1, &pkt6_tcp->tcp_hdr, ntohs (pkt6->ip6_hdr.paylgth));
595 app_type = GNUNET_APPLICATION_TYPE_INTERNET_TCP_GATEWAY;
596 if (NULL != tcp_tunnel)
597 me->tunnel = tcp_tunnel;
603 if (me->tunnel == NULL && NULL != cls)
606 GNUNET_MESH_tunnel_create (mesh_handle,
607 initialize_tunnel_state (16, NULL),
608 &send_pkt_to_peer, NULL, cls);
610 GNUNET_MESH_peer_request_connect_by_type (*cls, app_type);
612 if (GNUNET_APPLICATION_TYPE_INTERNET_UDP_GATEWAY == app_type)
614 else if (GNUNET_APPLICATION_TYPE_INTERNET_TCP_GATEWAY == app_type)
617 else if (NULL != cls)
620 send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL);
626 char pbuf[INET6_ADDRSTRLEN];
627 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
628 "Packet to %s, which has no mapping\n",
637 pkt6_icmp = (struct ip6_icmp *) pkt6;
638 /* If this packet is an icmp-echo-request and a mapping exists, answer */
639 if (pkt6_icmp->icmp_hdr.type == 0x80 &&
640 (key = address6_mapping_exists (&pkt6->ip6_hdr.dadr)) != NULL)
643 pkt6_icmp = GNUNET_malloc (ntohs (pkt6->shdr.size));
644 memcpy (pkt6_icmp, pkt6, ntohs (pkt6->shdr.size));
645 GNUNET_SCHEDULER_add_now (&send_icmp6_response, pkt6_icmp);
650 /* ethertype is ipv4 */
651 else if (ntohs (pkt_tun->tun.type) == 0x0800)
653 struct ip_pkt *pkt = (struct ip_pkt *) message;
654 struct ip_udp *udp = (struct ip_udp *) message;
655 struct ip_tcp *pkt_tcp;
656 struct ip_udp *pkt_udp;
657 struct ip_icmp *pkt_icmp;
659 GNUNET_assert (pkt->ip_hdr.version == 4);
661 /* Send dns-packets to the service-dns */
662 if (pkt->ip_hdr.proto == IPPROTO_UDP && ntohs (udp->udp_hdr.dpt) == 53)
664 GNUNET_DNS_queue_request_v4 (dns_handle,
667 ntohs (udp->udp_hdr.spt),
668 ntohs (udp->udp_hdr.len) - 8,
669 (const void*) udp->data);
673 uint32_t dadr = pkt->ip_hdr.dadr.s_addr;
674 unsigned char *c = (unsigned char *) &dadr;
676 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Packet to %d.%d.%d.%d, proto %x\n",
677 c[0], c[1], c[2], c[3], pkt->ip_hdr.proto);
678 switch (pkt->ip_hdr.proto)
682 pkt_tcp = (struct ip_tcp *) pkt;
683 pkt_udp = (struct ip_udp *) pkt;
685 if ((key = address4_mapping_exists (dadr)) != NULL)
687 struct map_entry *me =
688 GNUNET_CONTAINER_multihashmap_get (hashmap, key);
689 GNUNET_assert (me != NULL);
693 sizeof (struct GNUNET_MESH_Tunnel *) +
694 sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) +
695 ntohs (pkt->ip_hdr.tot_lngth) - 4 * pkt->ip_hdr.hdr_lngth;
697 struct GNUNET_MESH_Tunnel **cls = GNUNET_malloc (size);
698 struct GNUNET_MessageHeader *hdr =
699 (struct GNUNET_MessageHeader *) (cls + 1);
700 GNUNET_HashCode *hc = (GNUNET_HashCode *) (hdr + 1);
703 htons (sizeof (struct GNUNET_MessageHeader) +
704 sizeof (GNUNET_HashCode) + ntohs (pkt->ip_hdr.tot_lngth) -
705 4 * pkt->ip_hdr.hdr_lngth);
707 GNUNET_MESH_ApplicationType app_type = 0; /* make compiler happy */
709 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "me->addrlen is %d\n",
711 if (me->addrlen == 0)
713 /* This is a mapping to a gnunet-service */
714 memcpy (hc, &me->desc.service_descriptor, sizeof (GNUNET_HashCode));
716 if ((IPPROTO_UDP == pkt->ip_hdr.proto) &&
717 (me->desc.service_type & htonl (GNUNET_DNS_SERVICE_TYPE_UDP)) &&
718 (port_in_ports (me->desc.ports, pkt_udp->udp_hdr.dpt) ||
719 testBit (me->additional_ports, ntohs (pkt_udp->udp_hdr.dpt))))
721 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP);
723 memcpy (hc + 1, &pkt_udp->udp_hdr, ntohs (pkt_udp->udp_hdr.len));
726 else if ((IPPROTO_TCP == pkt->ip_hdr.proto) &&
728 desc.service_type & htonl (GNUNET_DNS_SERVICE_TYPE_TCP))
729 && (port_in_ports (me->desc.ports, pkt_tcp->tcp_hdr.dpt)))
731 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP);
733 memcpy (hc + 1, &pkt_tcp->tcp_hdr,
734 ntohs (pkt->ip_hdr.tot_lngth) -
735 4 * pkt->ip_hdr.hdr_lngth);
738 if (me->tunnel == NULL && NULL != cls)
741 GNUNET_MESH_tunnel_create (mesh_handle,
742 initialize_tunnel_state (4, NULL),
743 send_pkt_to_peer, NULL, cls);
744 GNUNET_MESH_peer_request_connect_add (*cls,
745 (struct GNUNET_PeerIdentity
749 else if (NULL != cls)
752 send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL);
753 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
754 "Queued to send IPv4 to peer %x, type %d\n",
755 *((unsigned int *) &me->desc.peer),
761 /* This is a mapping to a "real" address */
762 struct remote_addr *s = (struct remote_addr *) hc;
764 s->addrlen = me->addrlen;
765 memcpy (s->addr, me->addr, me->addrlen);
766 s->proto = pkt->ip_hdr.proto;
767 if (s->proto == IPPROTO_UDP)
769 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP);
770 memcpy (hc + 1, &pkt_udp->udp_hdr, ntohs (pkt_udp->udp_hdr.len));
771 app_type = GNUNET_APPLICATION_TYPE_INTERNET_UDP_GATEWAY;
773 else if (s->proto == IPPROTO_TCP)
775 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP);
776 memcpy (hc + 1, &pkt_tcp->tcp_hdr,
777 ntohs (pkt->ip_hdr.tot_lngth) -
778 4 * pkt->ip_hdr.hdr_lngth);
779 app_type = GNUNET_APPLICATION_TYPE_INTERNET_TCP_GATEWAY;
783 if (me->tunnel == NULL && NULL != cls)
786 GNUNET_MESH_tunnel_create (mesh_handle,
787 initialize_tunnel_state (4, NULL),
788 send_pkt_to_peer, NULL, cls);
790 GNUNET_MESH_peer_request_connect_by_type (*cls, app_type);
793 else if (NULL != cls)
796 send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL);
802 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
803 "Packet to %x which has no mapping\n", dadr);
808 pkt_icmp = (struct ip_icmp *) pkt;
809 if (pkt_icmp->icmp_hdr.type == 0x8 &&
810 (key = address4_mapping_exists (dadr)) != NULL)
813 pkt_icmp = GNUNET_malloc (ntohs (pkt->shdr.size));
814 memcpy (pkt_icmp, pkt, ntohs (pkt->shdr.size));
815 GNUNET_SCHEDULER_add_now (&send_icmp4_response, pkt_icmp);
826 collect_mappings (void *cls GNUNET_UNUSED,
827 const struct GNUNET_SCHEDULER_TaskContext *tc)
829 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
832 struct map_entry *me = GNUNET_CONTAINER_heap_remove_root (heap);
834 /* This is free()ed memory! */
835 me->heap_node = NULL;
837 /* FIXME! GNUNET_MESH_close_tunnel(me->tunnel); */
839 GNUNET_assert (GNUNET_YES ==
840 GNUNET_CONTAINER_multihashmap_remove (hashmap, &me->hash, me));
846 send_icmp4_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
848 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
851 struct ip_icmp *request = cls;
853 struct ip_icmp *response = alloca (ntohs (request->shdr.size));
855 GNUNET_assert (response != NULL);
856 memset (response, 0, ntohs (request->shdr.size));
858 response->shdr.size = request->shdr.size;
859 response->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
861 response->tun.flags = 0;
862 response->tun.type = htons (0x0800);
864 response->ip_hdr.hdr_lngth = 5;
865 response->ip_hdr.version = 4;
866 response->ip_hdr.proto = 0x01;
867 response->ip_hdr.dadr = request->ip_hdr.sadr;
868 response->ip_hdr.sadr = request->ip_hdr.dadr;
869 response->ip_hdr.tot_lngth = request->ip_hdr.tot_lngth;
871 response->ip_hdr.chks =
872 GNUNET_CRYPTO_crc16_n ((uint16_t *) & response->ip_hdr, 20);
874 response->icmp_hdr.code = 0;
875 response->icmp_hdr.type = 0x0;
877 /* Magic, more Magic! */
878 response->icmp_hdr.chks = request->icmp_hdr.chks + 0x8;
880 /* Copy the rest of the packet */
881 memcpy (response + 1, request + 1,
882 ntohs (request->shdr.size) - sizeof (struct ip_icmp));
884 (void) GNUNET_HELPER_send (helper_handle,
888 GNUNET_free (request);
892 send_icmp6_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
894 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
897 struct ip6_icmp *request = cls;
899 struct ip6_icmp *response = alloca (ntohs (request->shdr.size));
901 GNUNET_assert (response != NULL);
902 memset (response, 0, ntohs (request->shdr.size));
904 response->shdr.size = request->shdr.size;
905 response->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
907 response->tun.flags = 0;
908 response->tun.type = htons (0x86dd);
910 response->ip6_hdr.hoplmt = 255;
911 response->ip6_hdr.paylgth = request->ip6_hdr.paylgth;
912 response->ip6_hdr.nxthdr = 0x3a;
913 response->ip6_hdr.version = 6;
914 memcpy (&response->ip6_hdr.sadr, &request->ip6_hdr.dadr, 16);
915 memcpy (&response->ip6_hdr.dadr, &request->ip6_hdr.sadr, 16);
917 response->icmp_hdr.code = 0;
918 response->icmp_hdr.type = 0x81;
920 /* Magic, more Magic! */
921 response->icmp_hdr.chks = request->icmp_hdr.chks - 0x1;
923 /* Copy the rest of the packet */
924 memcpy (response + 1, request + 1,
925 ntohs (request->shdr.size) - sizeof (struct ip6_icmp));
927 (void) GNUNET_HELPER_send (helper_handle,
931 GNUNET_free (request);
935 * cls is the pointer to a GNUNET_MessageHeader that is
936 * followed by the service-descriptor and the packet that should be sent;
939 send_pkt_to_peer_notify_callback (void *cls, size_t size, void *buf)
941 struct GNUNET_MESH_Tunnel **tunnel = cls;
943 struct tunnel_state *ts = GNUNET_MESH_tunnel_get_data (*tunnel);
949 struct GNUNET_MessageHeader *hdr =
950 (struct GNUNET_MessageHeader *) (tunnel + 1);
951 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
952 "send_pkt_to_peer_notify_callback: buf = %x; size = %u;\n", buf,
954 GNUNET_assert (size >= ntohs (hdr->size));
955 memcpy (buf, hdr, ntohs (hdr->size));
956 size = ntohs (hdr->size);
957 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sent!\n");
962 if (NULL != ts->head)
964 struct tunnel_notify_queue *element = ts->head;
966 GNUNET_CONTAINER_DLL_remove (ts->head, ts->tail, element);
969 GNUNET_MESH_notify_transmit_ready (*tunnel, GNUNET_NO, 42,
970 GNUNET_TIME_relative_divide
971 (GNUNET_CONSTANTS_MAX_CORK_DELAY, 2),
972 (const struct GNUNET_PeerIdentity *)
974 send_pkt_to_peer_notify_callback,
977 /* save the handle */
978 GNUNET_free (element);
986 port_in_ports (uint64_t ports, uint16_t port)
988 uint16_t *ps = (uint16_t *) & ports;
990 return ports == 0 || ps[0] == port || ps[1] == port || ps[2] == port ||
995 send_pkt_to_peer (void *cls, const struct GNUNET_PeerIdentity *peer,
996 const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
998 /* peer == NULL means that all peers in this request are connected */
1001 struct GNUNET_MESH_Tunnel **tunnel = cls;
1002 struct GNUNET_MessageHeader *hdr =
1003 (struct GNUNET_MessageHeader *) (tunnel + 1);
1005 GNUNET_assert (NULL != tunnel);
1006 GNUNET_assert (NULL != *tunnel);
1008 struct tunnel_state *ts = GNUNET_MESH_tunnel_get_data (*tunnel);
1013 GNUNET_MESH_notify_transmit_ready (*tunnel, GNUNET_NO, 42,
1014 GNUNET_TIME_relative_divide
1015 (GNUNET_CONSTANTS_MAX_CORK_DELAY, 2),
1016 (const struct GNUNET_PeerIdentity *)
1017 NULL, ntohs (hdr->size),
1018 send_pkt_to_peer_notify_callback,
1023 struct tunnel_notify_queue *element = GNUNET_malloc (sizeof *element);
1026 element->len = ntohs (hdr->size);
1028 GNUNET_CONTAINER_DLL_insert_tail (ts->head, ts->tail, element);
1033 * Create a new Address from an answer-packet
1036 new_ip6addr (struct in6_addr *v6addr,
1037 const GNUNET_HashCode * peer,
1038 const GNUNET_HashCode * service_desc)
1040 unsigned char *buf = (unsigned char*) v6addr;
1042 unsigned long long ipv6prefix;
1044 GNUNET_assert (GNUNET_OK ==
1045 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR",
1047 GNUNET_assert (GNUNET_OK ==
1048 GNUNET_CONFIGURATION_get_value_number (cfg, "vpn",
1051 GNUNET_assert (ipv6prefix < 127);
1052 ipv6prefix = (ipv6prefix + 7) / 8;
1054 inet_pton (AF_INET6, ipv6addr, buf);
1055 GNUNET_free (ipv6addr);
1057 int peer_length = 16 - ipv6prefix - 6;
1059 if (peer_length <= 0)
1062 int service_length = 16 - ipv6prefix - peer_length;
1064 if (service_length <= 0)
1067 memcpy (buf + ipv6prefix, service_desc, service_length);
1068 memcpy (buf + ipv6prefix + service_length, peer, peer_length);
1075 * Create a new Address from an answer-packet
1078 new_ip6addr_remote (struct in6_addr *v6addr,
1079 unsigned char *addr, char addrlen)
1081 unsigned char *buf = (unsigned char*) v6addr;
1083 unsigned long long ipv6prefix;
1085 GNUNET_assert (GNUNET_OK ==
1086 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR",
1088 GNUNET_assert (GNUNET_OK ==
1089 GNUNET_CONFIGURATION_get_value_number (cfg, "vpn",
1092 GNUNET_assert (ipv6prefix < 127);
1093 ipv6prefix = (ipv6prefix + 7) / 8;
1095 inet_pton (AF_INET6, ipv6addr, buf);
1096 GNUNET_free (ipv6addr);
1098 int local_length = 16 - ipv6prefix;
1100 memcpy (buf + ipv6prefix, addr, GNUNET_MIN (addrlen, local_length));
1106 * Create a new Address from an answer-packet
1109 new_ip4addr_remote (unsigned char *buf, unsigned char *addr, char addrlen)
1114 GNUNET_assert (GNUNET_OK ==
1115 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4ADDR",
1117 GNUNET_assert (GNUNET_OK ==
1118 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4MASK",
1122 inet_pton (AF_INET, ipv4addr, buf);
1123 int r = inet_pton (AF_INET, ipv4mask, &mask);
1125 mask = htonl (mask);
1126 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "inet_pton: %d; %m; mask: %08x\n", r,
1129 GNUNET_free (ipv4addr);
1135 mask = (mask ^ (mask - 1)) >> 1;
1136 for (c = 0; mask; c++)
1143 c = CHAR_BIT * sizeof (mask);
1147 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "The mask %s has %d leading 1s.\n",
1150 GNUNET_free (ipv4mask);
1157 memcpy (buf + c, addr, GNUNET_MIN (addrlen, 4 - c));
1163 * This gets scheduled with cls pointing to an answer_packet and does everything
1164 * needed in order to send it to the helper.
1166 * At the moment this means "inventing" and IPv6-Address for .gnunet-services and
1167 * doing nothing for "real" services.
1170 process_answer (void *cls,
1171 const struct answer_packet *pkt)
1173 struct answer_packet_list *list;
1175 /* This answer is about a .gnunet-service
1177 * It contains an almost complete DNS-Response, we have to fill in the ip
1178 * at the offset pkt->addroffset
1180 if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_SERVICE)
1183 GNUNET_HashCode key;
1185 memset (&key, 0, sizeof (GNUNET_HashCode));
1188 GNUNET_malloc (htons (pkt->hdr.size) +
1189 sizeof (struct answer_packet_list) -
1190 sizeof (struct answer_packet));
1191 memcpy (&list->pkt, pkt, htons (pkt->hdr.size));
1193 unsigned char *c = ((unsigned char *) &list->pkt) + ntohs (pkt->addroffset);
1194 unsigned char *k = (unsigned char *) &key;
1196 new_ip6addr ((struct in6_addr*) c,
1197 &pkt->service_descr.peer,
1198 &pkt->service_descr.service_descriptor);
1200 * Copy the newly generated ip-address to the key backwarts (as only the first part is hashed)
1204 for (i = 0; i < 16; i++)
1207 uint16_t namelen = strlen ((char *) pkt->data + 12) + 1;
1209 struct map_entry *value =
1210 GNUNET_malloc (sizeof (struct map_entry) + namelen);
1211 char *name = (char *) (value + 1);
1213 value->namelen = namelen;
1214 memcpy (name, pkt->data + 12, namelen);
1216 memcpy (&value->desc, &pkt->service_descr,
1217 sizeof (struct GNUNET_vpn_service_descriptor));
1219 memset (value->additional_ports, 0, 8192);
1221 memcpy (&value->hash, &key, sizeof (GNUNET_HashCode));
1223 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (hashmap, &key))
1225 GNUNET_CONTAINER_multihashmap_put (hashmap, &key, value,
1226 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1229 GNUNET_CONTAINER_heap_insert (heap, value,
1230 GNUNET_TIME_absolute_get ().abs_value);
1231 if (GNUNET_CONTAINER_heap_get_size (heap) > max_mappings)
1232 GNUNET_SCHEDULER_add_now (collect_mappings, NULL);
1235 GNUNET_free (value);
1238 list->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_IP;
1242 else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REV)
1244 GNUNET_HashCode key;
1246 memset (&key, 0, sizeof key);
1247 unsigned char *k = (unsigned char *) &key;
1248 const unsigned char *s = pkt->data + 12;
1251 /* Whoever designed the reverse IPv6-lookup is batshit insane */
1252 for (i = 0; i < 16; i++)
1254 unsigned char c1 = s[(4 * i) + 1];
1255 unsigned char c2 = s[(4 * i) + 3];
1260 k[i] = c1 - 87; /* 87 is the difference between 'a' and 10 */
1262 k[i] += 16 * (c2 - '0');
1264 k[i] += 16 * (c2 - 87);
1267 struct map_entry *map_entry =
1268 GNUNET_CONTAINER_multihashmap_get (hashmap, &key);
1269 uint16_t offset = ntohs (pkt->addroffset);
1271 if (map_entry == NULL)
1274 GNUNET_CONTAINER_heap_update_cost (heap, map_entry->heap_node,
1275 GNUNET_TIME_absolute_get ().abs_value);
1278 unsigned short namelen = htons (map_entry->namelen);
1279 char *name = (char *) (map_entry + 1);
1282 GNUNET_malloc (sizeof (struct answer_packet_list) -
1283 sizeof (struct answer_packet) + offset + 2 +
1286 struct answer_packet *rpkt = &list->pkt;
1288 /* The offset points to the first byte belonging to the address */
1289 memcpy (rpkt, pkt, offset - 1);
1291 rpkt->subtype = GNUNET_DNS_ANSWER_TYPE_IP;
1292 rpkt->hdr.size = ntohs (offset + 2 + ntohs (namelen));
1294 memcpy (((char *) rpkt) + offset, &namelen, 2);
1295 memcpy (((char *) rpkt) + offset + 2, name, ntohs (namelen));
1298 else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_IP)
1301 GNUNET_malloc (htons (pkt->hdr.size) +
1302 sizeof (struct answer_packet_list) -
1303 sizeof (struct answer_packet));
1304 memcpy (&list->pkt, pkt, htons (pkt->hdr.size));
1306 else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REMOTE_AAAA)
1309 GNUNET_HashCode key;
1311 memset (&key, 0, sizeof (GNUNET_HashCode));
1314 GNUNET_malloc (htons (pkt->hdr.size) +
1315 sizeof (struct answer_packet_list) -
1316 sizeof (struct answer_packet));
1318 memcpy (&list->pkt, pkt, htons (pkt->hdr.size));
1319 list->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_IP;
1321 unsigned char *c = ((unsigned char *) &list->pkt) + ntohs (list->pkt.addroffset);
1323 new_ip6addr_remote ((struct in6_addr*) c,
1324 list->pkt.addr, list->pkt.addrsize);
1325 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1326 "New mapping to %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
1327 c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8], c[9],
1328 c[10], c[11], c[12], c[13], c[14], c[15]);
1329 unsigned char *k = (unsigned char *) &key;
1332 * Copy the newly generated ip-address to the key backwards (as only the first part is used in the hash-table)
1336 for (i = 0; i < 16; i++)
1339 uint16_t namelen = strlen ((char *) pkt->data + 12) + 1;
1341 struct map_entry *value =
1342 GNUNET_malloc (sizeof (struct map_entry) + namelen);
1343 char *name = (char *) (value + 1);
1345 value->namelen = namelen;
1346 memcpy (name, pkt->data + 12, namelen);
1348 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting addrlen to %d\n",
1350 value->addrlen = pkt->addrsize;
1351 memcpy (&value->addr, &pkt->addr, pkt->addrsize);
1352 memset (value->additional_ports, 0, 8192);
1354 memcpy (&value->hash, &key, sizeof (GNUNET_HashCode));
1356 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (hashmap, &key))
1358 GNUNET_CONTAINER_multihashmap_put (hashmap, &key, value,
1359 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1361 GNUNET_CONTAINER_heap_insert (heap, value,
1362 GNUNET_TIME_absolute_get ().abs_value);
1363 if (GNUNET_CONTAINER_heap_get_size (heap) > max_mappings)
1364 GNUNET_SCHEDULER_add_now (collect_mappings, NULL);
1367 GNUNET_free (value);
1371 else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REMOTE_A)
1374 GNUNET_malloc (htons (pkt->hdr.size) +
1375 sizeof (struct answer_packet_list) -
1376 sizeof (struct answer_packet));
1378 memcpy (&list->pkt, pkt, htons (pkt->hdr.size));
1379 list->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_IP;
1381 GNUNET_HashCode key;
1383 memset (&key, 0, sizeof (GNUNET_HashCode));
1385 unsigned char *c = ((unsigned char *) &list->pkt) + ntohs (pkt->addroffset);
1387 new_ip4addr_remote (c, list->pkt.addr, pkt->addrsize);
1388 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New mapping to %d.%d.%d.%d\n", c[0],
1390 unsigned char *k = (unsigned char *) &key;
1393 * Copy the newly generated ip-address to the key backwards (as only the first part is used in the hash-table)
1397 for (i = 0; i < 4; i++)
1400 uint16_t namelen = strlen ((char *) pkt->data + 12) + 1;
1402 struct map_entry *value =
1403 GNUNET_malloc (sizeof (struct map_entry) + namelen);
1404 char *name = (char *) (value + 1);
1406 value->namelen = namelen;
1407 memcpy (name, pkt->data + 12, namelen);
1409 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting addrlen to %d\n",
1411 value->addrlen = pkt->addrsize;
1412 memcpy (&value->addr, &pkt->addr, pkt->addrsize);
1413 memset (value->additional_ports, 0, 8192);
1415 memcpy (&value->hash, &key, sizeof (GNUNET_HashCode));
1417 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (hashmap, &key))
1419 GNUNET_CONTAINER_multihashmap_put (hashmap, &key, value,
1420 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1422 GNUNET_CONTAINER_heap_insert (heap, value,
1423 GNUNET_TIME_absolute_get ().abs_value);
1424 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1425 "Mapping is saved in the hashmap with key %08x.\n",
1426 *((uint32_t *) (&key)));
1427 if (GNUNET_CONTAINER_heap_get_size (heap) > max_mappings)
1428 GNUNET_SCHEDULER_add_now (collect_mappings, NULL);
1431 GNUNET_free (value);
1440 GNUNET_CONTAINER_DLL_insert_after (answer_proc_head, answer_proc_tail,
1441 answer_proc_tail, list);
1447 * @brief Add the port to the list of additional ports in the map_entry
1449 * @param me the map_entry
1450 * @param port the port in host-byte-order
1453 add_additional_port (struct map_entry *me, uint16_t port)
1455 setBit (me->additional_ports, port);
1459 receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1460 void **tunnel_ctx, const struct GNUNET_PeerIdentity *sender,
1461 const struct GNUNET_MessageHeader *message,
1462 const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1464 GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1);
1465 struct remote_addr *s = (struct remote_addr *) desc;
1466 struct udp_pkt *pkt = (struct udp_pkt *) (desc + 1);
1467 const struct GNUNET_PeerIdentity *other = sender;
1468 struct tunnel_state *ts = *tunnel_ctx;
1470 if (16 == ts->addrlen)
1473 sizeof (struct ip6_udp) + ntohs (pkt->len) - 1 -
1474 sizeof (struct udp_pkt);
1476 struct ip6_udp *pkt6 = alloca (size);
1478 GNUNET_assert (pkt6 != NULL);
1480 if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK)
1481 new_ip6addr (&pkt6->ip6_hdr.sadr, &other->hashPubKey, desc);
1483 new_ip6addr_remote (&pkt6->ip6_hdr.sadr, s->addr, s->addrlen);
1485 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1486 "Relaying calc:%d gnu:%d udp:%d bytes!\n", size,
1487 ntohs (message->size), ntohs (pkt->len));
1489 pkt6->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1490 pkt6->shdr.size = htons (size);
1492 pkt6->tun.flags = 0;
1493 pkt6->tun.type = htons (0x86dd);
1495 pkt6->ip6_hdr.version = 6;
1496 pkt6->ip6_hdr.tclass_h = 0;
1497 pkt6->ip6_hdr.tclass_l = 0;
1498 pkt6->ip6_hdr.flowlbl = 0;
1499 pkt6->ip6_hdr.paylgth = pkt->len;
1500 pkt6->ip6_hdr.nxthdr = IPPROTO_UDP;
1501 pkt6->ip6_hdr.hoplmt = 0xff;
1506 GNUNET_assert (GNUNET_OK ==
1507 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn",
1510 inet_pton (AF_INET6, ipv6addr, &pkt6->ip6_hdr.dadr);
1511 GNUNET_free (ipv6addr);
1513 memcpy (&pkt6->udp_hdr, pkt, ntohs (pkt->len));
1515 GNUNET_HashCode *key = address6_mapping_exists (&pkt6->ip6_hdr.sadr);
1517 GNUNET_assert (key != NULL);
1519 struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
1521 GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node,
1522 GNUNET_TIME_absolute_get ().abs_value);
1526 GNUNET_assert (me != NULL);
1527 if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK)
1529 GNUNET_assert (me->desc.
1530 service_type & htonl (GNUNET_DNS_SERVICE_TYPE_UDP));
1531 if (!port_in_ports (me->desc.ports, pkt6->udp_hdr.spt) &&
1532 !testBit (me->additional_ports, ntohs (pkt6->udp_hdr.spt)))
1534 add_additional_port (me, ntohs (pkt6->udp_hdr.spt));
1538 pkt6->udp_hdr.crc = 0;
1542 GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.sadr, 16);
1544 GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.dadr, 16);
1545 uint32_t tmp = (pkt6->udp_hdr.len & 0xffff);
1547 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4);
1548 tmp = htons (((pkt6->ip6_hdr.nxthdr & 0x00ff)));
1549 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4);
1552 GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->udp_hdr,
1554 pkt6->udp_hdr.crc = GNUNET_CRYPTO_crc16_finish (sum);
1556 (void) GNUNET_HELPER_send (helper_handle,
1564 sizeof (struct ip_udp) + ntohs (pkt->len) - 1 - sizeof (struct udp_pkt);
1566 struct ip_udp *pkt4 = alloca (size);
1568 GNUNET_assert (pkt4 != NULL);
1570 GNUNET_assert (ntohs (message->type) ==
1571 GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP_BACK);
1574 new_ip4addr_remote ((unsigned char *) &sadr, s->addr, s->addrlen);
1575 pkt4->ip_hdr.sadr.s_addr = sadr;
1577 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1578 "Relaying calc:%d gnu:%d udp:%d bytes!\n", size,
1579 ntohs (message->size), ntohs (pkt->len));
1581 pkt4->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1582 pkt4->shdr.size = htons (size);
1584 pkt4->tun.flags = 0;
1585 pkt4->tun.type = htons (0x0800);
1587 pkt4->ip_hdr.version = 4;
1588 pkt4->ip_hdr.hdr_lngth = 5;
1589 pkt4->ip_hdr.diff_serv = 0;
1590 pkt4->ip_hdr.tot_lngth = htons (20 + ntohs (pkt->len));
1591 pkt4->ip_hdr.ident = 0;
1592 pkt4->ip_hdr.flags = 0;
1593 pkt4->ip_hdr.frag_off = 0;
1594 pkt4->ip_hdr.ttl = 255;
1595 pkt4->ip_hdr.proto = IPPROTO_UDP;
1596 pkt4->ip_hdr.chks = 0; /* Will be calculated later */
1602 GNUNET_assert (GNUNET_OK ==
1603 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn",
1606 inet_pton (AF_INET, ipv4addr, &dadr);
1607 GNUNET_free (ipv4addr);
1608 pkt4->ip_hdr.dadr.s_addr = dadr;
1610 memcpy (&pkt4->udp_hdr, pkt, ntohs (pkt->len));
1612 GNUNET_HashCode *key = address4_mapping_exists (pkt4->ip_hdr.sadr.s_addr);
1614 GNUNET_assert (key != NULL);
1616 struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
1618 GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node,
1619 GNUNET_TIME_absolute_get ().abs_value);
1623 GNUNET_assert (me != NULL);
1625 pkt4->udp_hdr.crc = 0; /* Optional for IPv4 */
1628 GNUNET_CRYPTO_crc16_n ((uint16_t *) & pkt4->ip_hdr, 5 * 4);
1630 (void) GNUNET_HELPER_send (helper_handle,
1640 receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1642 const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1643 const struct GNUNET_MessageHeader *message,
1644 const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1646 GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1);
1647 struct remote_addr *s = (struct remote_addr *) desc;
1648 struct tcp_pkt *pkt = (struct tcp_pkt *) (desc + 1);
1649 const struct GNUNET_PeerIdentity *other = sender;
1650 struct tunnel_state *ts = *tunnel_ctx;
1653 ntohs (message->size) - sizeof (struct GNUNET_MessageHeader) -
1654 sizeof (GNUNET_HashCode);
1656 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1657 "Received TCP-Packet back, addrlen = %d\n", s->addrlen);
1659 if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP_BACK ||
1662 size_t size = pktlen + sizeof (struct ip6_tcp) - 1;
1664 struct ip6_tcp *pkt6 = alloca (size);
1666 memset (pkt6, 0, size);
1668 GNUNET_assert (pkt6 != NULL);
1670 if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP_BACK)
1671 new_ip6addr (&pkt6->ip6_hdr.sadr, &other->hashPubKey, desc);
1673 new_ip6addr_remote (&pkt6->ip6_hdr.sadr, s->addr, s->addrlen);
1675 pkt6->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1676 pkt6->shdr.size = htons (size);
1678 pkt6->tun.flags = 0;
1679 pkt6->tun.type = htons (0x86dd);
1681 pkt6->ip6_hdr.version = 6;
1682 pkt6->ip6_hdr.tclass_h = 0;
1683 pkt6->ip6_hdr.tclass_l = 0;
1684 pkt6->ip6_hdr.flowlbl = 0;
1685 pkt6->ip6_hdr.paylgth = htons (pktlen);
1686 pkt6->ip6_hdr.nxthdr = IPPROTO_TCP;
1687 pkt6->ip6_hdr.hoplmt = 0xff;
1692 GNUNET_assert (GNUNET_OK ==
1693 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn",
1696 inet_pton (AF_INET6, ipv6addr, &pkt6->ip6_hdr.dadr);
1697 GNUNET_free (ipv6addr);
1699 memcpy (&pkt6->tcp_hdr, pkt, pktlen);
1701 GNUNET_HashCode *key = address6_mapping_exists (&pkt6->ip6_hdr.sadr);
1703 GNUNET_assert (key != NULL);
1705 struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
1707 GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node,
1708 GNUNET_TIME_absolute_get ().abs_value);
1712 GNUNET_assert (me != NULL);
1713 if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK)
1714 GNUNET_assert (me->desc.
1715 service_type & htonl (GNUNET_DNS_SERVICE_TYPE_TCP));
1717 pkt6->tcp_hdr.crc = 0;
1722 GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.sadr, 16);
1724 GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.dadr, 16);
1725 tmp = htonl (pktlen);
1726 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4);
1727 tmp = htonl (((pkt6->ip6_hdr.nxthdr & 0x000000ff)));
1728 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4);
1731 GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->tcp_hdr,
1732 ntohs (pkt6->ip6_hdr.paylgth));
1733 pkt6->tcp_hdr.crc = GNUNET_CRYPTO_crc16_finish (sum);
1735 (void) GNUNET_HELPER_send (helper_handle,
1742 size_t size = pktlen + sizeof (struct ip_tcp) - 1;
1744 struct ip_tcp *pkt4 = alloca (size);
1746 GNUNET_assert (pkt4 != NULL);
1747 memset (pkt4, 0, size);
1749 GNUNET_assert (ntohs (message->type) ==
1750 GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP_BACK);
1753 new_ip4addr_remote ((unsigned char *) &sadr, s->addr, s->addrlen);
1754 pkt4->ip_hdr.sadr.s_addr = sadr;
1756 pkt4->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1757 pkt4->shdr.size = htons (size);
1759 pkt4->tun.flags = 0;
1760 pkt4->tun.type = htons (0x0800);
1762 pkt4->ip_hdr.version = 4;
1763 pkt4->ip_hdr.hdr_lngth = 5;
1764 pkt4->ip_hdr.diff_serv = 0;
1765 pkt4->ip_hdr.tot_lngth = htons (20 + pktlen);
1766 pkt4->ip_hdr.ident = 0;
1767 pkt4->ip_hdr.flags = 0;
1768 pkt4->ip_hdr.frag_off = 0;
1769 pkt4->ip_hdr.ttl = 255;
1770 pkt4->ip_hdr.proto = IPPROTO_TCP;
1771 pkt4->ip_hdr.chks = 0; /* Will be calculated later */
1777 GNUNET_assert (GNUNET_OK ==
1778 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn",
1781 inet_pton (AF_INET, ipv4addr, &dadr);
1782 GNUNET_free (ipv4addr);
1783 pkt4->ip_hdr.dadr.s_addr = dadr;
1786 memcpy (&pkt4->tcp_hdr, pkt, pktlen);
1788 GNUNET_HashCode *key = address4_mapping_exists (pkt4->ip_hdr.sadr.s_addr);
1790 GNUNET_assert (key != NULL);
1792 struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
1794 GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node,
1795 GNUNET_TIME_absolute_get ().abs_value);
1799 GNUNET_assert (me != NULL);
1800 pkt4->tcp_hdr.crc = 0;
1804 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) &pkt4->ip_hdr.sadr, 4);
1805 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) &pkt4->ip_hdr.dadr, 4);
1807 tmp = (0x06 << 16) | (0xffff & pktlen); // 0x06 for TCP?
1811 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4);
1813 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt4->tcp_hdr, pktlen);
1814 pkt4->tcp_hdr.crc = GNUNET_CRYPTO_crc16_finish (sum);
1817 GNUNET_CRYPTO_crc16_n ((uint16_t *) & pkt4->ip_hdr, 5 * 4);
1819 (void) GNUNET_HELPER_send (helper_handle,
1830 new_tunnel (void *cls, struct GNUNET_MESH_Tunnel *tunnel,
1831 const struct GNUNET_PeerIdentity *initiator,
1832 const struct GNUNET_ATS_Information *atsi)
1834 /* Why should anyone open an inbound tunnel to vpn? */
1840 cleaner (void *cls, const struct GNUNET_MESH_Tunnel *tunnel, void *tunnel_ctx)
1842 /* Why should anyone open an inbound tunnel to vpn? */
1847 * Main function that will be run by the scheduler.
1849 * @param cls closure
1850 * @param args remaining command-line arguments
1851 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
1852 * @param cfg_ configuration
1855 run (void *cls, char *const *args GNUNET_UNUSED,
1856 const char *cfgfile GNUNET_UNUSED,
1857 const struct GNUNET_CONFIGURATION_Handle *cfg_)
1859 static const struct GNUNET_MESH_MessageHandler handlers[] = {
1860 {receive_udp_back, GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK, 0},
1861 {receive_tcp_back, GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP_BACK, 0},
1862 {receive_udp_back, GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP_BACK, 0},
1863 {receive_tcp_back, GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP_BACK, 0},
1866 static const GNUNET_MESH_ApplicationType types[] = {
1867 GNUNET_APPLICATION_TYPE_END
1876 GNUNET_MESH_connect (cfg_, 42, NULL, new_tunnel, cleaner, handlers,
1879 hashmap = GNUNET_CONTAINER_multihashmap_create (65536);
1880 heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
1881 GNUNET_CONFIGURATION_get_value_number (cfg, "vpn", "MAX_MAPPINGg",
1883 udp_connections = GNUNET_CONTAINER_multihashmap_create (65536);
1884 dns_handle = GNUNET_DNS_connect (cfg,
1887 if (GNUNET_SYSERR ==
1888 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IFNAME", &ifname))
1890 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1891 "No entry 'IFNAME' in configuration!\n");
1895 if (GNUNET_SYSERR ==
1896 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR", &ipv6addr))
1898 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1899 "No entry 'IPV6ADDR' in configuration!\n");
1903 if (GNUNET_SYSERR ==
1904 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6PREFIX",
1907 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1908 "No entry 'IPV6PREFIX' in configuration!\n");
1912 if (GNUNET_SYSERR ==
1913 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4ADDR", &ipv4addr))
1915 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1916 "No entry 'IPV4ADDR' in configuration!\n");
1920 if (GNUNET_SYSERR ==
1921 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4MASK", &ipv4mask))
1923 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1924 "No entry 'IPV4MASK' in configuration!\n");
1928 vpn_argv[0] = GNUNET_strdup ("vpn-gnunet");
1929 vpn_argv[1] = ifname;
1930 vpn_argv[2] = ipv6addr;
1931 vpn_argv[3] = ipv6prefix;
1932 vpn_argv[4] = ipv4addr;
1933 vpn_argv[5] = ipv4mask;
1936 helper_handle = GNUNET_HELPER_start ("gnunet-helper-vpn", vpn_argv,
1937 &message_token, NULL);
1938 GNUNET_DNS_restart_hijack (dns_handle);
1939 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls);
1943 * The main function to obtain template from gnunetd.
1945 * @param argc number of arguments from the command line
1946 * @param argv command line arguments
1947 * @return 0 ok, 1 on error
1950 main (int argc, char *const *argv)
1952 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
1953 GNUNET_GETOPT_OPTION_END
1956 return (GNUNET_OK ==
1957 GNUNET_PROGRAM_run (argc, argv, "vpn", gettext_noop ("help text"),
1958 options, &run, NULL)) ? ret : 1;
1961 /* end of gnunet-daemon-vpn.c */