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 struct answer_packet_list
43 struct answer_packet_list *next;
44 struct answer_packet_list *prev;
45 struct GNUNET_SERVER_Client *client;
46 struct answer_packet pkt;
52 /** The description of the service (used for service) */
53 struct GNUNET_vpn_service_descriptor desc;
55 /** The real address of the service (used for remote) */
59 struct GNUNET_MESH_Tunnel *tunnel;
61 char additional_ports[8192];
63 struct GNUNET_CONTAINER_HeapNode *heap_node;
66 * After this struct the name is located in DNS-Format!
74 unsigned char addr[16];
79 struct tunnel_notify_queue
81 struct tunnel_notify_queue *next;
82 struct tunnel_notify_queue *prev;
90 struct GNUNET_MESH_TransmitHandle *th;
91 struct tunnel_notify_queue *head, *tail;
97 static const struct GNUNET_CONFIGURATION_Handle *cfg;
99 static struct GNUNET_MESH_Handle *mesh_handle;
101 static struct GNUNET_CONTAINER_MultiHashMap *hashmap;
103 static struct GNUNET_CONTAINER_Heap *heap;
106 * The handle to the helper
108 static struct GNUNET_HELPER_Handle *helper_handle;
111 * Arguments to the exit helper.
113 static char *vpn_argv[7];
115 static struct GNUNET_DNS_Handle *dns_handle;
117 static struct answer_packet_list *answer_proc_head;
119 static struct answer_packet_list *answer_proc_tail;
122 * If there are at least this many address-mappings, old ones will be removed
124 static long long unsigned int max_mappings = 200;
132 * This hashmap contains the mapping from peer, service-descriptor,
133 * source-port and destination-port to a socket
135 static struct GNUNET_CONTAINER_MultiHashMap *udp_connections;
137 static GNUNET_SCHEDULER_TaskIdentifier conn_task;
139 static GNUNET_SCHEDULER_TaskIdentifier shs_task;
142 * The tunnels that will be used to send tcp- and udp-packets
144 static struct GNUNET_MESH_Tunnel *tcp_tunnel;
145 static struct GNUNET_MESH_Tunnel *udp_tunnel;
149 port_in_ports (uint64_t ports, uint16_t port)
151 uint16_t *ps = (uint16_t *) & ports;
153 return ports == 0 || ps[0] == port || ps[1] == port || ps[2] == port ||
159 * Sets a bit active in a bitArray.
161 * @param bitArray memory area to set the bit in
162 * @param bitIdx which bit to set
165 setBit (char *bitArray, unsigned int bitIdx)
168 unsigned int targetBit;
170 arraySlot = bitIdx / 8;
171 targetBit = (1L << (bitIdx % 8));
172 bitArray[arraySlot] |= targetBit;
177 * Checks if a bit is active in the bitArray
179 * @param bitArray memory area to set the bit in
180 * @param bitIdx which bit to test
181 * @return GNUNET_YES if the bit is set, GNUNET_NO if not.
184 testBit (char *bitArray, unsigned int bitIdx)
187 unsigned int targetBit;
190 targetBit = (1L << (bitIdx % 8));
191 if (bitArray[slot] & targetBit)
199 * Function scheduled as very last function, cleans up after us
203 cleanup (void *cls GNUNET_UNUSED,
204 const struct GNUNET_SCHEDULER_TaskContext *tskctx)
208 GNUNET_assert (0 != (tskctx->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN));
209 /* close the connection to the service-dns */
210 GNUNET_DNS_disconnect (dns_handle);
211 if (mesh_handle != NULL)
213 GNUNET_MESH_disconnect (mesh_handle);
216 if (helper_handle != NULL)
218 GNUNET_HELPER_stop (helper_handle);
219 helper_handle = NULL;
221 if (GNUNET_SCHEDULER_NO_TASK != shs_task)
223 GNUNET_SCHEDULER_cancel (shs_task);
224 shs_task = GNUNET_SCHEDULER_NO_TASK;
226 if (GNUNET_SCHEDULER_NO_TASK != conn_task)
228 GNUNET_SCHEDULER_cancel (conn_task);
229 conn_task = GNUNET_SCHEDULER_NO_TASK;
232 GNUNET_free_non_null (vpn_argv[i]);
238 * @return the hash of the IP-Address if a mapping exists, NULL otherwise
240 static GNUNET_HashCode *
241 address6_mapping_exists (struct in6_addr *v6addr)
243 unsigned char *addr = (unsigned char*) v6addr;
244 GNUNET_HashCode *key = GNUNET_malloc (sizeof (GNUNET_HashCode));
245 unsigned char *k = (unsigned char *) key;
247 memset (key, 0, sizeof (GNUNET_HashCode));
250 for (i = 0; i < 16; i++)
253 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (hashmap, key))
263 * @return the hash of the IP-Address if a mapping exists, NULL otherwise
265 static GNUNET_HashCode *
266 address4_mapping_exists (uint32_t addr)
268 GNUNET_HashCode *key = GNUNET_malloc (sizeof (GNUNET_HashCode));
270 memset (key, 0, sizeof (GNUNET_HashCode));
271 unsigned char *c = (unsigned char *) &addr;
272 unsigned char *k = (unsigned char *) key;
275 for (i = 0; i < 4; i++)
278 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
279 "a4_m_e: getting with key %08x, addr is %08x, %d.%d.%d.%d\n",
280 *((uint32_t *) (key)), addr, c[0], c[1], c[2], c[3]);
282 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (hashmap, key))
287 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Mapping not found!\n");
294 initialize_tunnel_state (int addrlen, struct GNUNET_MESH_TransmitHandle *th)
296 struct tunnel_state *ts = GNUNET_malloc (sizeof *ts);
298 ts->addrlen = addrlen;
305 send_icmp4_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
307 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
310 struct ip_icmp *request = cls;
312 struct ip_icmp *response = alloca (ntohs (request->shdr.size));
314 GNUNET_assert (response != NULL);
315 memset (response, 0, ntohs (request->shdr.size));
317 response->shdr.size = request->shdr.size;
318 response->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
320 response->tun.flags = 0;
321 response->tun.type = htons (0x0800);
323 response->ip_hdr.hdr_lngth = 5;
324 response->ip_hdr.version = 4;
325 response->ip_hdr.proto = 0x01;
326 response->ip_hdr.dadr = request->ip_hdr.sadr;
327 response->ip_hdr.sadr = request->ip_hdr.dadr;
328 response->ip_hdr.tot_lngth = request->ip_hdr.tot_lngth;
330 response->ip_hdr.chks =
331 GNUNET_CRYPTO_crc16_n ((uint16_t *) & response->ip_hdr, 20);
333 response->icmp_hdr.code = 0;
334 response->icmp_hdr.type = 0x0;
336 /* Magic, more Magic! */
337 response->icmp_hdr.chks = request->icmp_hdr.chks + 0x8;
339 /* Copy the rest of the packet */
340 memcpy (response + 1, request + 1,
341 ntohs (request->shdr.size) - sizeof (struct ip_icmp));
343 (void) GNUNET_HELPER_send (helper_handle,
347 GNUNET_free (request);
352 send_icmp6_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
354 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
357 struct ip6_icmp *request = cls;
359 struct ip6_icmp *response = alloca (ntohs (request->shdr.size));
361 GNUNET_assert (response != NULL);
362 memset (response, 0, ntohs (request->shdr.size));
364 response->shdr.size = request->shdr.size;
365 response->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
367 response->tun.flags = 0;
368 response->tun.type = htons (0x86dd);
370 response->ip6_hdr.hoplmt = 255;
371 response->ip6_hdr.paylgth = request->ip6_hdr.paylgth;
372 response->ip6_hdr.nxthdr = 0x3a;
373 response->ip6_hdr.version = 6;
374 memcpy (&response->ip6_hdr.sadr, &request->ip6_hdr.dadr, 16);
375 memcpy (&response->ip6_hdr.dadr, &request->ip6_hdr.sadr, 16);
377 response->icmp_hdr.code = 0;
378 response->icmp_hdr.type = 0x81;
380 /* Magic, more Magic! */
381 response->icmp_hdr.chks = request->icmp_hdr.chks - 0x1;
383 /* Copy the rest of the packet */
384 memcpy (response + 1, request + 1,
385 ntohs (request->shdr.size) - sizeof (struct ip6_icmp));
387 (void) GNUNET_HELPER_send (helper_handle,
391 GNUNET_free (request);
396 * cls is the pointer to a GNUNET_MessageHeader that is
397 * followed by the service-descriptor and the packet that should be sent;
400 send_pkt_to_peer_notify_callback (void *cls, size_t size, void *buf)
402 struct GNUNET_MESH_Tunnel **tunnel = cls;
404 struct tunnel_state *ts = GNUNET_MESH_tunnel_get_data (*tunnel);
410 struct GNUNET_MessageHeader *hdr =
411 (struct GNUNET_MessageHeader *) (tunnel + 1);
412 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
413 "send_pkt_to_peer_notify_callback: buf = %x; size = %u;\n", buf,
415 GNUNET_assert (size >= ntohs (hdr->size));
416 memcpy (buf, hdr, ntohs (hdr->size));
417 size = ntohs (hdr->size);
418 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sent!\n");
423 if (NULL != ts->head)
425 struct tunnel_notify_queue *element = ts->head;
427 GNUNET_CONTAINER_DLL_remove (ts->head, ts->tail, element);
430 GNUNET_MESH_notify_transmit_ready (*tunnel, GNUNET_NO, 42,
431 GNUNET_TIME_relative_divide
432 (GNUNET_CONSTANTS_MAX_CORK_DELAY, 2),
433 (const struct GNUNET_PeerIdentity *)
435 send_pkt_to_peer_notify_callback,
438 /* save the handle */
439 GNUNET_free (element);
448 send_pkt_to_peer (void *cls, const struct GNUNET_PeerIdentity *peer,
449 const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
451 /* peer == NULL means that all peers in this request are connected */
454 struct GNUNET_MESH_Tunnel **tunnel = cls;
455 struct GNUNET_MessageHeader *hdr =
456 (struct GNUNET_MessageHeader *) (tunnel + 1);
458 GNUNET_assert (NULL != tunnel);
459 GNUNET_assert (NULL != *tunnel);
461 struct tunnel_state *ts = GNUNET_MESH_tunnel_get_data (*tunnel);
466 GNUNET_MESH_notify_transmit_ready (*tunnel, GNUNET_NO, 42,
467 GNUNET_TIME_relative_divide
468 (GNUNET_CONSTANTS_MAX_CORK_DELAY, 2),
469 (const struct GNUNET_PeerIdentity *)
470 NULL, ntohs (hdr->size),
471 send_pkt_to_peer_notify_callback,
476 struct tunnel_notify_queue *element = GNUNET_malloc (sizeof *element);
479 element->len = ntohs (hdr->size);
481 GNUNET_CONTAINER_DLL_insert_tail (ts->head, ts->tail, element);
489 * Receive packets from the helper-process
492 message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED,
493 const struct GNUNET_MessageHeader *message)
495 GNUNET_assert (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_HELPER);
497 struct tun_pkt *pkt_tun = (struct tun_pkt *) message;
498 GNUNET_HashCode *key;
500 /* ethertype is ipv6 */
501 if (ntohs (pkt_tun->tun.type) == 0x86dd)
503 struct ip6_pkt *pkt6 = (struct ip6_pkt *) message;
505 GNUNET_assert (pkt6->ip6_hdr.version == 6);
506 struct ip6_tcp *pkt6_tcp;
507 struct ip6_udp *pkt6_udp;
508 struct ip6_icmp *pkt6_icmp;
510 pkt6_udp = NULL; /* make compiler happy */
511 switch (pkt6->ip6_hdr.nxthdr)
514 pkt6_udp = (struct ip6_udp *) pkt6;
515 /* Send dns-packets to the service-dns */
516 if (ntohs (pkt6_udp->udp_hdr.dpt) == 53)
518 /* 9 = 8 for the udp-header + 1 for the unsigned char data[1]; */
519 GNUNET_DNS_queue_request_v6 (dns_handle,
522 ntohs (pkt6_udp->udp_hdr.spt),
523 ntohs (pkt6_udp->udp_hdr.len) - 8,
524 (const void*) pkt6_udp->data);
530 pkt6_tcp = (struct ip6_tcp *) pkt6;
532 if ((key = address6_mapping_exists (&pkt6->ip6_hdr.dadr)) != NULL)
534 struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
536 GNUNET_assert (me != NULL);
540 sizeof (struct GNUNET_MESH_Tunnel *) +
541 sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) +
542 ntohs (pkt6->ip6_hdr.paylgth);
544 struct GNUNET_MESH_Tunnel **cls = GNUNET_malloc (size);
545 struct GNUNET_MessageHeader *hdr =
546 (struct GNUNET_MessageHeader *) (cls + 1);
547 GNUNET_HashCode *hc = (GNUNET_HashCode *) (hdr + 1);
550 htons (sizeof (struct GNUNET_MessageHeader) +
551 sizeof (GNUNET_HashCode) + ntohs (pkt6->ip6_hdr.paylgth));
553 GNUNET_MESH_ApplicationType app_type = 0; /* fix compiler uninitialized warning... */
555 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "me->addrlen is %d\n",
557 if (me->addrlen == 0)
559 /* This is a mapping to a gnunet-service */
560 memcpy (hc, &me->desc.service_descriptor, sizeof (GNUNET_HashCode));
562 if (IPPROTO_UDP == pkt6->ip6_hdr.nxthdr &&
563 (me->desc.service_type & htonl (GNUNET_DNS_SERVICE_TYPE_UDP)) &&
564 (port_in_ports (me->desc.ports, pkt6_udp->udp_hdr.dpt) ||
565 testBit (me->additional_ports, ntohs (pkt6_udp->udp_hdr.dpt))))
567 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP);
569 memcpy (hc + 1, &pkt6_udp->udp_hdr, ntohs (pkt6_udp->udp_hdr.len));
572 else if (IPPROTO_TCP == pkt6->ip6_hdr.nxthdr &&
573 (me->desc.service_type & htonl (GNUNET_DNS_SERVICE_TYPE_TCP))
574 && (port_in_ports (me->desc.ports, pkt6_tcp->tcp_hdr.dpt)))
576 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP);
578 memcpy (hc + 1, &pkt6_tcp->tcp_hdr, ntohs (pkt6->ip6_hdr.paylgth));
583 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "pip: %d\n",
584 port_in_ports (me->desc.ports, pkt6_tcp->tcp_hdr.dpt));
587 if (me->tunnel == NULL && NULL != cls)
590 GNUNET_MESH_tunnel_create (mesh_handle,
591 initialize_tunnel_state (16, NULL),
592 &send_pkt_to_peer, NULL, cls);
594 GNUNET_MESH_peer_request_connect_add (*cls,
595 (struct GNUNET_PeerIdentity *)
599 else if (NULL != cls)
602 send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL);
603 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
604 "Queued to send IPv6 to peer %x, type %d\n",
605 *((unsigned int *) &me->desc.peer), ntohs (hdr->type));
610 /* This is a mapping to a "real" address */
611 struct remote_addr *s = (struct remote_addr *) hc;
613 s->addrlen = me->addrlen;
614 memcpy (s->addr, me->addr, me->addrlen);
615 s->proto = pkt6->ip6_hdr.nxthdr;
616 if (s->proto == IPPROTO_UDP)
618 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP);
619 memcpy (hc + 1, &pkt6_udp->udp_hdr, ntohs (pkt6_udp->udp_hdr.len));
620 app_type = GNUNET_APPLICATION_TYPE_INTERNET_UDP_GATEWAY;
621 if (NULL != udp_tunnel)
622 me->tunnel = udp_tunnel;
624 else if (s->proto == IPPROTO_TCP)
626 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP);
627 memcpy (hc + 1, &pkt6_tcp->tcp_hdr, ntohs (pkt6->ip6_hdr.paylgth));
628 app_type = GNUNET_APPLICATION_TYPE_INTERNET_TCP_GATEWAY;
629 if (NULL != tcp_tunnel)
630 me->tunnel = tcp_tunnel;
636 if (me->tunnel == NULL && NULL != cls)
639 GNUNET_MESH_tunnel_create (mesh_handle,
640 initialize_tunnel_state (16, NULL),
641 &send_pkt_to_peer, NULL, cls);
643 GNUNET_MESH_peer_request_connect_by_type (*cls, app_type);
645 if (GNUNET_APPLICATION_TYPE_INTERNET_UDP_GATEWAY == app_type)
647 else if (GNUNET_APPLICATION_TYPE_INTERNET_TCP_GATEWAY == app_type)
650 else if (NULL != cls)
653 send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL);
659 char pbuf[INET6_ADDRSTRLEN];
660 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
661 "Packet to %s, which has no mapping\n",
670 pkt6_icmp = (struct ip6_icmp *) pkt6;
671 /* If this packet is an icmp-echo-request and a mapping exists, answer */
672 if (pkt6_icmp->icmp_hdr.type == 0x80 &&
673 (key = address6_mapping_exists (&pkt6->ip6_hdr.dadr)) != NULL)
676 pkt6_icmp = GNUNET_malloc (ntohs (pkt6->shdr.size));
677 memcpy (pkt6_icmp, pkt6, ntohs (pkt6->shdr.size));
678 GNUNET_SCHEDULER_add_now (&send_icmp6_response, pkt6_icmp);
683 /* ethertype is ipv4 */
684 else if (ntohs (pkt_tun->tun.type) == 0x0800)
686 struct ip_pkt *pkt = (struct ip_pkt *) message;
687 struct ip_udp *udp = (struct ip_udp *) message;
688 struct ip_tcp *pkt_tcp;
689 struct ip_udp *pkt_udp;
690 struct ip_icmp *pkt_icmp;
692 GNUNET_assert (pkt->ip_hdr.version == 4);
694 /* Send dns-packets to the service-dns */
695 if (pkt->ip_hdr.proto == IPPROTO_UDP && ntohs (udp->udp_hdr.dpt) == 53)
697 GNUNET_DNS_queue_request_v4 (dns_handle,
700 ntohs (udp->udp_hdr.spt),
701 ntohs (udp->udp_hdr.len) - 8,
702 (const void*) udp->data);
706 uint32_t dadr = pkt->ip_hdr.dadr.s_addr;
707 unsigned char *c = (unsigned char *) &dadr;
709 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Packet to %d.%d.%d.%d, proto %x\n",
710 c[0], c[1], c[2], c[3], pkt->ip_hdr.proto);
711 switch (pkt->ip_hdr.proto)
715 pkt_tcp = (struct ip_tcp *) pkt;
716 pkt_udp = (struct ip_udp *) pkt;
718 if ((key = address4_mapping_exists (dadr)) != NULL)
720 struct map_entry *me =
721 GNUNET_CONTAINER_multihashmap_get (hashmap, key);
722 GNUNET_assert (me != NULL);
726 sizeof (struct GNUNET_MESH_Tunnel *) +
727 sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) +
728 ntohs (pkt->ip_hdr.tot_lngth) - 4 * pkt->ip_hdr.hdr_lngth;
730 struct GNUNET_MESH_Tunnel **cls = GNUNET_malloc (size);
731 struct GNUNET_MessageHeader *hdr =
732 (struct GNUNET_MessageHeader *) (cls + 1);
733 GNUNET_HashCode *hc = (GNUNET_HashCode *) (hdr + 1);
736 htons (sizeof (struct GNUNET_MessageHeader) +
737 sizeof (GNUNET_HashCode) + ntohs (pkt->ip_hdr.tot_lngth) -
738 4 * pkt->ip_hdr.hdr_lngth);
740 GNUNET_MESH_ApplicationType app_type = 0; /* make compiler happy */
742 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "me->addrlen is %d\n",
744 if (me->addrlen == 0)
746 /* This is a mapping to a gnunet-service */
747 memcpy (hc, &me->desc.service_descriptor, sizeof (GNUNET_HashCode));
749 if ((IPPROTO_UDP == pkt->ip_hdr.proto) &&
750 (me->desc.service_type & htonl (GNUNET_DNS_SERVICE_TYPE_UDP)) &&
751 (port_in_ports (me->desc.ports, pkt_udp->udp_hdr.dpt) ||
752 testBit (me->additional_ports, ntohs (pkt_udp->udp_hdr.dpt))))
754 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP);
756 memcpy (hc + 1, &pkt_udp->udp_hdr, ntohs (pkt_udp->udp_hdr.len));
759 else if ((IPPROTO_TCP == pkt->ip_hdr.proto) &&
761 desc.service_type & htonl (GNUNET_DNS_SERVICE_TYPE_TCP))
762 && (port_in_ports (me->desc.ports, pkt_tcp->tcp_hdr.dpt)))
764 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP);
766 memcpy (hc + 1, &pkt_tcp->tcp_hdr,
767 ntohs (pkt->ip_hdr.tot_lngth) -
768 4 * pkt->ip_hdr.hdr_lngth);
771 if (me->tunnel == NULL && NULL != cls)
774 GNUNET_MESH_tunnel_create (mesh_handle,
775 initialize_tunnel_state (4, NULL),
776 send_pkt_to_peer, NULL, cls);
777 GNUNET_MESH_peer_request_connect_add (*cls,
778 (struct GNUNET_PeerIdentity
782 else if (NULL != cls)
785 send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL);
786 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
787 "Queued to send IPv4 to peer %x, type %d\n",
788 *((unsigned int *) &me->desc.peer),
794 /* This is a mapping to a "real" address */
795 struct remote_addr *s = (struct remote_addr *) hc;
797 s->addrlen = me->addrlen;
798 memcpy (s->addr, me->addr, me->addrlen);
799 s->proto = pkt->ip_hdr.proto;
800 if (s->proto == IPPROTO_UDP)
802 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP);
803 memcpy (hc + 1, &pkt_udp->udp_hdr, ntohs (pkt_udp->udp_hdr.len));
804 app_type = GNUNET_APPLICATION_TYPE_INTERNET_UDP_GATEWAY;
806 else if (s->proto == IPPROTO_TCP)
808 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP);
809 memcpy (hc + 1, &pkt_tcp->tcp_hdr,
810 ntohs (pkt->ip_hdr.tot_lngth) -
811 4 * pkt->ip_hdr.hdr_lngth);
812 app_type = GNUNET_APPLICATION_TYPE_INTERNET_TCP_GATEWAY;
816 if (me->tunnel == NULL && NULL != cls)
819 GNUNET_MESH_tunnel_create (mesh_handle,
820 initialize_tunnel_state (4, NULL),
821 send_pkt_to_peer, NULL, cls);
823 GNUNET_MESH_peer_request_connect_by_type (*cls, app_type);
826 else if (NULL != cls)
829 send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL);
835 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
836 "Packet to %x which has no mapping\n", dadr);
841 pkt_icmp = (struct ip_icmp *) pkt;
842 if (pkt_icmp->icmp_hdr.type == 0x8 &&
843 (key = address4_mapping_exists (dadr)) != NULL)
846 pkt_icmp = GNUNET_malloc (ntohs (pkt->shdr.size));
847 memcpy (pkt_icmp, pkt, ntohs (pkt->shdr.size));
848 GNUNET_SCHEDULER_add_now (&send_icmp4_response, pkt_icmp);
859 collect_mappings (void *cls GNUNET_UNUSED,
860 const struct GNUNET_SCHEDULER_TaskContext *tc)
862 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
865 struct map_entry *me = GNUNET_CONTAINER_heap_remove_root (heap);
867 /* This is free()ed memory! */
868 me->heap_node = NULL;
870 /* FIXME! GNUNET_MESH_close_tunnel(me->tunnel); */
872 GNUNET_assert (GNUNET_YES ==
873 GNUNET_CONTAINER_multihashmap_remove (hashmap, &me->hash, me));
880 * Create a new Address from an answer-packet
883 new_ip6addr (struct in6_addr *v6addr,
884 const GNUNET_HashCode * peer,
885 const GNUNET_HashCode * service_desc)
887 unsigned char *buf = (unsigned char*) v6addr;
889 unsigned long long ipv6prefix;
891 GNUNET_assert (GNUNET_OK ==
892 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR",
894 GNUNET_assert (GNUNET_OK ==
895 GNUNET_CONFIGURATION_get_value_number (cfg, "vpn",
898 GNUNET_assert (ipv6prefix < 127);
899 ipv6prefix = (ipv6prefix + 7) / 8;
901 inet_pton (AF_INET6, ipv6addr, buf);
902 GNUNET_free (ipv6addr);
904 int peer_length = 16 - ipv6prefix - 6;
906 if (peer_length <= 0)
909 int service_length = 16 - ipv6prefix - peer_length;
911 if (service_length <= 0)
914 memcpy (buf + ipv6prefix, service_desc, service_length);
915 memcpy (buf + ipv6prefix + service_length, peer, peer_length);
922 * Create a new Address from an answer-packet
925 new_ip6addr_remote (struct in6_addr *v6addr,
926 unsigned char *addr, char addrlen)
928 unsigned char *buf = (unsigned char*) v6addr;
930 unsigned long long ipv6prefix;
932 GNUNET_assert (GNUNET_OK ==
933 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR",
935 GNUNET_assert (GNUNET_OK ==
936 GNUNET_CONFIGURATION_get_value_number (cfg, "vpn",
939 GNUNET_assert (ipv6prefix < 127);
940 ipv6prefix = (ipv6prefix + 7) / 8;
942 inet_pton (AF_INET6, ipv6addr, buf);
943 GNUNET_free (ipv6addr);
945 int local_length = 16 - ipv6prefix;
947 memcpy (buf + ipv6prefix, addr, GNUNET_MIN (addrlen, local_length));
953 * Create a new Address from an answer-packet
956 new_ip4addr_remote (unsigned char *buf, unsigned char *addr, char addrlen)
961 GNUNET_assert (GNUNET_OK ==
962 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4ADDR",
964 GNUNET_assert (GNUNET_OK ==
965 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4MASK",
969 inet_pton (AF_INET, ipv4addr, buf);
970 int r = inet_pton (AF_INET, ipv4mask, &mask);
973 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "inet_pton: %d; %m; mask: %08x\n", r,
976 GNUNET_free (ipv4addr);
982 mask = (mask ^ (mask - 1)) >> 1;
983 for (c = 0; mask; c++)
990 c = CHAR_BIT * sizeof (mask);
994 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "The mask %s has %d leading 1s.\n",
997 GNUNET_free (ipv4mask);
1004 memcpy (buf + c, addr, GNUNET_MIN (addrlen, 4 - c));
1010 * This gets scheduled with cls pointing to an answer_packet and does everything
1011 * needed in order to send it to the helper.
1013 * At the moment this means "inventing" and IPv6-Address for .gnunet-services and
1014 * doing nothing for "real" services.
1017 process_answer (void *cls,
1018 const struct answer_packet *pkt)
1020 struct answer_packet_list *list;
1022 /* This answer is about a .gnunet-service
1024 * It contains an almost complete DNS-Response, we have to fill in the ip
1025 * at the offset pkt->addroffset
1027 if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_SERVICE)
1030 GNUNET_HashCode key;
1032 memset (&key, 0, sizeof (GNUNET_HashCode));
1035 GNUNET_malloc (htons (pkt->hdr.size) +
1036 sizeof (struct answer_packet_list) -
1037 sizeof (struct answer_packet));
1038 memcpy (&list->pkt, pkt, htons (pkt->hdr.size));
1040 unsigned char *c = ((unsigned char *) &list->pkt) + ntohs (pkt->addroffset);
1041 unsigned char *k = (unsigned char *) &key;
1043 new_ip6addr ((struct in6_addr*) c,
1044 &pkt->service_descr.peer,
1045 &pkt->service_descr.service_descriptor);
1047 * Copy the newly generated ip-address to the key backwarts (as only the first part is hashed)
1051 for (i = 0; i < 16; i++)
1054 uint16_t namelen = strlen ((char *) pkt->data + 12) + 1;
1056 struct map_entry *value =
1057 GNUNET_malloc (sizeof (struct map_entry) + namelen);
1058 char *name = (char *) (value + 1);
1060 value->namelen = namelen;
1061 memcpy (name, pkt->data + 12, namelen);
1063 memcpy (&value->desc, &pkt->service_descr,
1064 sizeof (struct GNUNET_vpn_service_descriptor));
1066 memset (value->additional_ports, 0, 8192);
1068 memcpy (&value->hash, &key, sizeof (GNUNET_HashCode));
1070 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (hashmap, &key))
1072 GNUNET_CONTAINER_multihashmap_put (hashmap, &key, value,
1073 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1076 GNUNET_CONTAINER_heap_insert (heap, value,
1077 GNUNET_TIME_absolute_get ().abs_value);
1078 if (GNUNET_CONTAINER_heap_get_size (heap) > max_mappings)
1079 GNUNET_SCHEDULER_add_now (collect_mappings, NULL);
1082 GNUNET_free (value);
1085 list->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_IP;
1089 else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REV)
1091 GNUNET_HashCode key;
1093 memset (&key, 0, sizeof key);
1094 unsigned char *k = (unsigned char *) &key;
1095 const unsigned char *s = pkt->data + 12;
1098 /* Whoever designed the reverse IPv6-lookup is batshit insane */
1099 for (i = 0; i < 16; i++)
1101 unsigned char c1 = s[(4 * i) + 1];
1102 unsigned char c2 = s[(4 * i) + 3];
1107 k[i] = c1 - 87; /* 87 is the difference between 'a' and 10 */
1109 k[i] += 16 * (c2 - '0');
1111 k[i] += 16 * (c2 - 87);
1114 struct map_entry *map_entry =
1115 GNUNET_CONTAINER_multihashmap_get (hashmap, &key);
1116 uint16_t offset = ntohs (pkt->addroffset);
1118 if (map_entry == NULL)
1121 GNUNET_CONTAINER_heap_update_cost (heap, map_entry->heap_node,
1122 GNUNET_TIME_absolute_get ().abs_value);
1125 unsigned short namelen = htons (map_entry->namelen);
1126 char *name = (char *) (map_entry + 1);
1129 GNUNET_malloc (sizeof (struct answer_packet_list) -
1130 sizeof (struct answer_packet) + offset + 2 +
1133 struct answer_packet *rpkt = &list->pkt;
1135 /* The offset points to the first byte belonging to the address */
1136 memcpy (rpkt, pkt, offset - 1);
1138 rpkt->subtype = GNUNET_DNS_ANSWER_TYPE_IP;
1139 rpkt->hdr.size = ntohs (offset + 2 + ntohs (namelen));
1141 memcpy (((char *) rpkt) + offset, &namelen, 2);
1142 memcpy (((char *) rpkt) + offset + 2, name, ntohs (namelen));
1145 else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_IP)
1148 GNUNET_malloc (htons (pkt->hdr.size) +
1149 sizeof (struct answer_packet_list) -
1150 sizeof (struct answer_packet));
1151 memcpy (&list->pkt, pkt, htons (pkt->hdr.size));
1153 else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REMOTE_AAAA)
1156 GNUNET_HashCode key;
1158 memset (&key, 0, sizeof (GNUNET_HashCode));
1161 GNUNET_malloc (htons (pkt->hdr.size) +
1162 sizeof (struct answer_packet_list) -
1163 sizeof (struct answer_packet));
1165 memcpy (&list->pkt, pkt, htons (pkt->hdr.size));
1166 list->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_IP;
1168 unsigned char *c = ((unsigned char *) &list->pkt) + ntohs (list->pkt.addroffset);
1170 new_ip6addr_remote ((struct in6_addr*) c,
1171 list->pkt.addr, list->pkt.addrsize);
1172 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1173 "New mapping to %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
1174 c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8], c[9],
1175 c[10], c[11], c[12], c[13], c[14], c[15]);
1176 unsigned char *k = (unsigned char *) &key;
1179 * Copy the newly generated ip-address to the key backwards (as only the first part is used in the hash-table)
1183 for (i = 0; i < 16; i++)
1186 uint16_t namelen = strlen ((char *) pkt->data + 12) + 1;
1188 struct map_entry *value =
1189 GNUNET_malloc (sizeof (struct map_entry) + namelen);
1190 char *name = (char *) (value + 1);
1192 value->namelen = namelen;
1193 memcpy (name, pkt->data + 12, namelen);
1195 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting addrlen to %d\n",
1197 value->addrlen = pkt->addrsize;
1198 memcpy (&value->addr, &pkt->addr, pkt->addrsize);
1199 memset (value->additional_ports, 0, 8192);
1201 memcpy (&value->hash, &key, sizeof (GNUNET_HashCode));
1203 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (hashmap, &key))
1205 GNUNET_CONTAINER_multihashmap_put (hashmap, &key, value,
1206 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1208 GNUNET_CONTAINER_heap_insert (heap, value,
1209 GNUNET_TIME_absolute_get ().abs_value);
1210 if (GNUNET_CONTAINER_heap_get_size (heap) > max_mappings)
1211 GNUNET_SCHEDULER_add_now (collect_mappings, NULL);
1214 GNUNET_free (value);
1218 else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REMOTE_A)
1221 GNUNET_malloc (htons (pkt->hdr.size) +
1222 sizeof (struct answer_packet_list) -
1223 sizeof (struct answer_packet));
1225 memcpy (&list->pkt, pkt, htons (pkt->hdr.size));
1226 list->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_IP;
1228 GNUNET_HashCode key;
1230 memset (&key, 0, sizeof (GNUNET_HashCode));
1232 unsigned char *c = ((unsigned char *) &list->pkt) + ntohs (pkt->addroffset);
1234 new_ip4addr_remote (c, list->pkt.addr, pkt->addrsize);
1235 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New mapping to %d.%d.%d.%d\n", c[0],
1237 unsigned char *k = (unsigned char *) &key;
1240 * Copy the newly generated ip-address to the key backwards (as only the first part is used in the hash-table)
1244 for (i = 0; i < 4; i++)
1247 uint16_t namelen = strlen ((char *) pkt->data + 12) + 1;
1249 struct map_entry *value =
1250 GNUNET_malloc (sizeof (struct map_entry) + namelen);
1251 char *name = (char *) (value + 1);
1253 value->namelen = namelen;
1254 memcpy (name, pkt->data + 12, namelen);
1256 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting addrlen to %d\n",
1258 value->addrlen = pkt->addrsize;
1259 memcpy (&value->addr, &pkt->addr, pkt->addrsize);
1260 memset (value->additional_ports, 0, 8192);
1262 memcpy (&value->hash, &key, sizeof (GNUNET_HashCode));
1264 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (hashmap, &key))
1266 GNUNET_CONTAINER_multihashmap_put (hashmap, &key, value,
1267 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1269 GNUNET_CONTAINER_heap_insert (heap, value,
1270 GNUNET_TIME_absolute_get ().abs_value);
1271 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1272 "Mapping is saved in the hashmap with key %08x.\n",
1273 *((uint32_t *) (&key)));
1274 if (GNUNET_CONTAINER_heap_get_size (heap) > max_mappings)
1275 GNUNET_SCHEDULER_add_now (collect_mappings, NULL);
1278 GNUNET_free (value);
1287 GNUNET_CONTAINER_DLL_insert_after (answer_proc_head, answer_proc_tail,
1288 answer_proc_tail, list);
1294 * @brief Add the port to the list of additional ports in the map_entry
1296 * @param me the map_entry
1297 * @param port the port in host-byte-order
1300 add_additional_port (struct map_entry *me, uint16_t port)
1302 setBit (me->additional_ports, port);
1306 receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1307 void **tunnel_ctx, const struct GNUNET_PeerIdentity *sender,
1308 const struct GNUNET_MessageHeader *message,
1309 const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1311 GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1);
1312 struct remote_addr *s = (struct remote_addr *) desc;
1313 struct udp_pkt *pkt = (struct udp_pkt *) (desc + 1);
1314 const struct GNUNET_PeerIdentity *other = sender;
1315 struct tunnel_state *ts = *tunnel_ctx;
1317 if (16 == ts->addrlen)
1320 sizeof (struct ip6_udp) + ntohs (pkt->len) - 1 -
1321 sizeof (struct udp_pkt);
1323 struct ip6_udp *pkt6 = alloca (size);
1325 GNUNET_assert (pkt6 != NULL);
1327 if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK)
1328 new_ip6addr (&pkt6->ip6_hdr.sadr, &other->hashPubKey, desc);
1330 new_ip6addr_remote (&pkt6->ip6_hdr.sadr, s->addr, s->addrlen);
1332 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1333 "Relaying calc:%d gnu:%d udp:%d bytes!\n", size,
1334 ntohs (message->size), ntohs (pkt->len));
1336 pkt6->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1337 pkt6->shdr.size = htons (size);
1339 pkt6->tun.flags = 0;
1340 pkt6->tun.type = htons (0x86dd);
1342 pkt6->ip6_hdr.version = 6;
1343 pkt6->ip6_hdr.tclass_h = 0;
1344 pkt6->ip6_hdr.tclass_l = 0;
1345 pkt6->ip6_hdr.flowlbl = 0;
1346 pkt6->ip6_hdr.paylgth = pkt->len;
1347 pkt6->ip6_hdr.nxthdr = IPPROTO_UDP;
1348 pkt6->ip6_hdr.hoplmt = 0xff;
1353 GNUNET_assert (GNUNET_OK ==
1354 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn",
1357 inet_pton (AF_INET6, ipv6addr, &pkt6->ip6_hdr.dadr);
1358 GNUNET_free (ipv6addr);
1360 memcpy (&pkt6->udp_hdr, pkt, ntohs (pkt->len));
1362 GNUNET_HashCode *key = address6_mapping_exists (&pkt6->ip6_hdr.sadr);
1364 GNUNET_assert (key != NULL);
1366 struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
1368 GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node,
1369 GNUNET_TIME_absolute_get ().abs_value);
1373 GNUNET_assert (me != NULL);
1374 if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK)
1376 GNUNET_assert (me->desc.
1377 service_type & htonl (GNUNET_DNS_SERVICE_TYPE_UDP));
1378 if (!port_in_ports (me->desc.ports, pkt6->udp_hdr.spt) &&
1379 !testBit (me->additional_ports, ntohs (pkt6->udp_hdr.spt)))
1381 add_additional_port (me, ntohs (pkt6->udp_hdr.spt));
1385 pkt6->udp_hdr.crc = 0;
1389 GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.sadr, 16);
1391 GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.dadr, 16);
1392 uint32_t tmp = (pkt6->udp_hdr.len & 0xffff);
1394 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4);
1395 tmp = htons (((pkt6->ip6_hdr.nxthdr & 0x00ff)));
1396 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4);
1399 GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->udp_hdr,
1401 pkt6->udp_hdr.crc = GNUNET_CRYPTO_crc16_finish (sum);
1403 (void) GNUNET_HELPER_send (helper_handle,
1411 sizeof (struct ip_udp) + ntohs (pkt->len) - 1 - sizeof (struct udp_pkt);
1413 struct ip_udp *pkt4 = alloca (size);
1415 GNUNET_assert (pkt4 != NULL);
1417 GNUNET_assert (ntohs (message->type) ==
1418 GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP_BACK);
1421 new_ip4addr_remote ((unsigned char *) &sadr, s->addr, s->addrlen);
1422 pkt4->ip_hdr.sadr.s_addr = sadr;
1424 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1425 "Relaying calc:%d gnu:%d udp:%d bytes!\n", size,
1426 ntohs (message->size), ntohs (pkt->len));
1428 pkt4->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1429 pkt4->shdr.size = htons (size);
1431 pkt4->tun.flags = 0;
1432 pkt4->tun.type = htons (0x0800);
1434 pkt4->ip_hdr.version = 4;
1435 pkt4->ip_hdr.hdr_lngth = 5;
1436 pkt4->ip_hdr.diff_serv = 0;
1437 pkt4->ip_hdr.tot_lngth = htons (20 + ntohs (pkt->len));
1438 pkt4->ip_hdr.ident = 0;
1439 pkt4->ip_hdr.flags = 0;
1440 pkt4->ip_hdr.frag_off = 0;
1441 pkt4->ip_hdr.ttl = 255;
1442 pkt4->ip_hdr.proto = IPPROTO_UDP;
1443 pkt4->ip_hdr.chks = 0; /* Will be calculated later */
1449 GNUNET_assert (GNUNET_OK ==
1450 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn",
1453 inet_pton (AF_INET, ipv4addr, &dadr);
1454 GNUNET_free (ipv4addr);
1455 pkt4->ip_hdr.dadr.s_addr = dadr;
1457 memcpy (&pkt4->udp_hdr, pkt, ntohs (pkt->len));
1459 GNUNET_HashCode *key = address4_mapping_exists (pkt4->ip_hdr.sadr.s_addr);
1461 GNUNET_assert (key != NULL);
1463 struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
1465 GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node,
1466 GNUNET_TIME_absolute_get ().abs_value);
1470 GNUNET_assert (me != NULL);
1472 pkt4->udp_hdr.crc = 0; /* Optional for IPv4 */
1475 GNUNET_CRYPTO_crc16_n ((uint16_t *) & pkt4->ip_hdr, 5 * 4);
1477 (void) GNUNET_HELPER_send (helper_handle,
1487 receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1489 const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1490 const struct GNUNET_MessageHeader *message,
1491 const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1493 GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1);
1494 struct remote_addr *s = (struct remote_addr *) desc;
1495 struct tcp_pkt *pkt = (struct tcp_pkt *) (desc + 1);
1496 const struct GNUNET_PeerIdentity *other = sender;
1497 struct tunnel_state *ts = *tunnel_ctx;
1500 ntohs (message->size) - sizeof (struct GNUNET_MessageHeader) -
1501 sizeof (GNUNET_HashCode);
1503 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1504 "Received TCP-Packet back, addrlen = %d\n", s->addrlen);
1506 if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP_BACK ||
1509 size_t size = pktlen + sizeof (struct ip6_tcp) - 1;
1511 struct ip6_tcp *pkt6 = alloca (size);
1513 memset (pkt6, 0, size);
1515 GNUNET_assert (pkt6 != NULL);
1517 if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP_BACK)
1518 new_ip6addr (&pkt6->ip6_hdr.sadr, &other->hashPubKey, desc);
1520 new_ip6addr_remote (&pkt6->ip6_hdr.sadr, s->addr, s->addrlen);
1522 pkt6->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1523 pkt6->shdr.size = htons (size);
1525 pkt6->tun.flags = 0;
1526 pkt6->tun.type = htons (0x86dd);
1528 pkt6->ip6_hdr.version = 6;
1529 pkt6->ip6_hdr.tclass_h = 0;
1530 pkt6->ip6_hdr.tclass_l = 0;
1531 pkt6->ip6_hdr.flowlbl = 0;
1532 pkt6->ip6_hdr.paylgth = htons (pktlen);
1533 pkt6->ip6_hdr.nxthdr = IPPROTO_TCP;
1534 pkt6->ip6_hdr.hoplmt = 0xff;
1539 GNUNET_assert (GNUNET_OK ==
1540 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn",
1543 inet_pton (AF_INET6, ipv6addr, &pkt6->ip6_hdr.dadr);
1544 GNUNET_free (ipv6addr);
1546 memcpy (&pkt6->tcp_hdr, pkt, pktlen);
1548 GNUNET_HashCode *key = address6_mapping_exists (&pkt6->ip6_hdr.sadr);
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);
1560 if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK)
1561 GNUNET_assert (me->desc.
1562 service_type & htonl (GNUNET_DNS_SERVICE_TYPE_TCP));
1564 pkt6->tcp_hdr.crc = 0;
1569 GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.sadr, 16);
1571 GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.dadr, 16);
1572 tmp = htonl (pktlen);
1573 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4);
1574 tmp = htonl (((pkt6->ip6_hdr.nxthdr & 0x000000ff)));
1575 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4);
1578 GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->tcp_hdr,
1579 ntohs (pkt6->ip6_hdr.paylgth));
1580 pkt6->tcp_hdr.crc = GNUNET_CRYPTO_crc16_finish (sum);
1582 (void) GNUNET_HELPER_send (helper_handle,
1589 size_t size = pktlen + sizeof (struct ip_tcp) - 1;
1591 struct ip_tcp *pkt4 = alloca (size);
1593 GNUNET_assert (pkt4 != NULL);
1594 memset (pkt4, 0, size);
1596 GNUNET_assert (ntohs (message->type) ==
1597 GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP_BACK);
1600 new_ip4addr_remote ((unsigned char *) &sadr, s->addr, s->addrlen);
1601 pkt4->ip_hdr.sadr.s_addr = sadr;
1603 pkt4->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1604 pkt4->shdr.size = htons (size);
1606 pkt4->tun.flags = 0;
1607 pkt4->tun.type = htons (0x0800);
1609 pkt4->ip_hdr.version = 4;
1610 pkt4->ip_hdr.hdr_lngth = 5;
1611 pkt4->ip_hdr.diff_serv = 0;
1612 pkt4->ip_hdr.tot_lngth = htons (20 + pktlen);
1613 pkt4->ip_hdr.ident = 0;
1614 pkt4->ip_hdr.flags = 0;
1615 pkt4->ip_hdr.frag_off = 0;
1616 pkt4->ip_hdr.ttl = 255;
1617 pkt4->ip_hdr.proto = IPPROTO_TCP;
1618 pkt4->ip_hdr.chks = 0; /* Will be calculated later */
1624 GNUNET_assert (GNUNET_OK ==
1625 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn",
1628 inet_pton (AF_INET, ipv4addr, &dadr);
1629 GNUNET_free (ipv4addr);
1630 pkt4->ip_hdr.dadr.s_addr = dadr;
1633 memcpy (&pkt4->tcp_hdr, pkt, pktlen);
1635 GNUNET_HashCode *key = address4_mapping_exists (pkt4->ip_hdr.sadr.s_addr);
1637 GNUNET_assert (key != NULL);
1639 struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
1641 GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node,
1642 GNUNET_TIME_absolute_get ().abs_value);
1646 GNUNET_assert (me != NULL);
1647 pkt4->tcp_hdr.crc = 0;
1651 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) &pkt4->ip_hdr.sadr, 4);
1652 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) &pkt4->ip_hdr.dadr, 4);
1654 tmp = (0x06 << 16) | (0xffff & pktlen); // 0x06 for TCP?
1658 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4);
1660 sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt4->tcp_hdr, pktlen);
1661 pkt4->tcp_hdr.crc = GNUNET_CRYPTO_crc16_finish (sum);
1664 GNUNET_CRYPTO_crc16_n ((uint16_t *) & pkt4->ip_hdr, 5 * 4);
1666 (void) GNUNET_HELPER_send (helper_handle,
1677 new_tunnel (void *cls, struct GNUNET_MESH_Tunnel *tunnel,
1678 const struct GNUNET_PeerIdentity *initiator,
1679 const struct GNUNET_ATS_Information *atsi)
1681 /* Why should anyone open an inbound tunnel to vpn? */
1687 cleaner (void *cls, const struct GNUNET_MESH_Tunnel *tunnel, void *tunnel_ctx)
1689 /* Why should anyone open an inbound tunnel to vpn? */
1694 * Main function that will be run by the scheduler.
1696 * @param cls closure
1697 * @param args remaining command-line arguments
1698 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
1699 * @param cfg_ configuration
1702 run (void *cls, char *const *args GNUNET_UNUSED,
1703 const char *cfgfile GNUNET_UNUSED,
1704 const struct GNUNET_CONFIGURATION_Handle *cfg_)
1706 static const struct GNUNET_MESH_MessageHandler handlers[] = {
1707 {receive_udp_back, GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK, 0},
1708 {receive_tcp_back, GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP_BACK, 0},
1709 {receive_udp_back, GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP_BACK, 0},
1710 {receive_tcp_back, GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP_BACK, 0},
1713 static const GNUNET_MESH_ApplicationType types[] = {
1714 GNUNET_APPLICATION_TYPE_END
1723 GNUNET_MESH_connect (cfg_, 42, NULL, new_tunnel, cleaner, handlers,
1726 hashmap = GNUNET_CONTAINER_multihashmap_create (65536);
1727 heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
1728 GNUNET_CONFIGURATION_get_value_number (cfg, "vpn", "MAX_MAPPINGg",
1730 udp_connections = GNUNET_CONTAINER_multihashmap_create (65536);
1731 dns_handle = GNUNET_DNS_connect (cfg,
1734 if (GNUNET_SYSERR ==
1735 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IFNAME", &ifname))
1737 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1738 "No entry 'IFNAME' in configuration!\n");
1742 if (GNUNET_SYSERR ==
1743 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR", &ipv6addr))
1745 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1746 "No entry 'IPV6ADDR' in configuration!\n");
1750 if (GNUNET_SYSERR ==
1751 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6PREFIX",
1754 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1755 "No entry 'IPV6PREFIX' in configuration!\n");
1759 if (GNUNET_SYSERR ==
1760 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4ADDR", &ipv4addr))
1762 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1763 "No entry 'IPV4ADDR' in configuration!\n");
1767 if (GNUNET_SYSERR ==
1768 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4MASK", &ipv4mask))
1770 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1771 "No entry 'IPV4MASK' in configuration!\n");
1775 vpn_argv[0] = GNUNET_strdup ("vpn-gnunet");
1776 vpn_argv[1] = ifname;
1777 vpn_argv[2] = ipv6addr;
1778 vpn_argv[3] = ipv6prefix;
1779 vpn_argv[4] = ipv4addr;
1780 vpn_argv[5] = ipv4mask;
1783 helper_handle = GNUNET_HELPER_start ("gnunet-helper-vpn", vpn_argv,
1784 &message_token, NULL);
1785 GNUNET_DNS_restart_hijack (dns_handle);
1786 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls);
1790 * The main function to obtain template from gnunetd.
1792 * @param argc number of arguments from the command line
1793 * @param argv command line arguments
1794 * @return 0 ok, 1 on error
1797 main (int argc, char *const *argv)
1799 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
1800 GNUNET_GETOPT_OPTION_END
1803 return (GNUNET_OK ==
1804 GNUNET_PROGRAM_run (argc, argv, "vpn", gettext_noop ("help text"),
1805 options, &run, NULL)) ? ret : 1;
1808 /* end of gnunet-daemon-vpn.c */