-building IPv4 TCP reply messages for TUN
[oweals/gnunet.git] / src / vpn / gnunet-daemon-vpn.c
1 /*
2      This file is part of GNUnet.
3      (C) 2010 Christian Grothoff
4
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.
9
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.
14
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.
19 */
20
21 /**
22  * @file vpn/gnunet-daemon-vpn.c
23  * @brief
24  * @author Philipp Toelke
25  */
26 #include "platform.h"
27 #include "gnunet_getopt_lib.h"
28 #include "gnunet_program_lib.h"
29 #include "gnunet-vpn-packet.h"
30 #include "gnunet_common.h"
31 #include "gnunet_protocols.h"
32 #include "gnunet_applications.h"
33 #include <gnunet_mesh_service.h>
34 #include "gnunet_client_lib.h"
35 #include "gnunet_container_lib.h"
36 #include "gnunet_constants.h"
37 #include <block_dns.h>
38 #include "gnunet_dns_service.h"
39
40
41 struct answer_packet_list
42 {
43   struct answer_packet_list *next;
44   struct answer_packet_list *prev;
45   struct GNUNET_SERVER_Client *client;
46   struct answer_packet pkt;
47 };
48
49
50 struct map_entry
51 {
52     /** The description of the service (used for service) */
53   struct GNUNET_vpn_service_descriptor desc;
54
55     /** The real address of the service (used for remote) */
56   char addrlen;
57   char addr[16];
58
59   struct GNUNET_MESH_Tunnel *tunnel;
60   uint16_t namelen;
61   char additional_ports[8192];
62
63   struct GNUNET_CONTAINER_HeapNode *heap_node;
64   GNUNET_HashCode hash;
65     /**
66      * After this struct the name is located in DNS-Format!
67      */
68 };
69
70
71 struct remote_addr
72 {
73   char addrlen;
74   unsigned char addr[16];
75   char proto;
76 };
77
78
79 struct tunnel_notify_queue
80 {
81   struct tunnel_notify_queue *next;
82   struct tunnel_notify_queue *prev;
83   size_t len;
84   void *cls;
85 };
86
87
88 struct tunnel_state
89 {
90   struct GNUNET_MESH_TransmitHandle *th;
91   struct tunnel_notify_queue *head, *tail;
92
93   int addrlen;
94 };
95
96
97 static const struct GNUNET_CONFIGURATION_Handle *cfg;
98
99 static struct GNUNET_MESH_Handle *mesh_handle;
100
101 static struct GNUNET_CONTAINER_MultiHashMap *hashmap;
102
103 static struct GNUNET_CONTAINER_Heap *heap;
104
105 /**
106  * The handle to the helper
107  */
108 static struct GNUNET_HELPER_Handle *helper_handle;
109
110 /**
111  * Arguments to the exit helper.
112  */
113 static char *vpn_argv[7];
114
115 static struct GNUNET_DNS_Handle *dns_handle;
116
117 static struct answer_packet_list *answer_proc_head;
118
119 static struct answer_packet_list *answer_proc_tail;
120
121 /**
122  * If there are at least this many address-mappings, old ones will be removed
123  */
124 static long long unsigned int max_mappings = 200;
125
126 /**
127  * Final status code.
128  */
129 static int ret;
130
131 /**
132  * This hashmap contains the mapping from peer, service-descriptor,
133  * source-port and destination-port to a socket
134  */
135 static struct GNUNET_CONTAINER_MultiHashMap *udp_connections;
136
137 static GNUNET_SCHEDULER_TaskIdentifier conn_task;
138
139 static GNUNET_SCHEDULER_TaskIdentifier shs_task;
140
141 /**
142  * The tunnels that will be used to send tcp- and udp-packets
143  */
144 static struct GNUNET_MESH_Tunnel *tcp_tunnel;
145 static struct GNUNET_MESH_Tunnel *udp_tunnel;
146
147
148 static unsigned int
149 port_in_ports (uint64_t ports, uint16_t port)
150 {
151   uint16_t *ps = (uint16_t *) & ports;
152
153   return ports == 0 || ps[0] == port || ps[1] == port || ps[2] == port ||
154       ps[3] == port;
155 }
156
157
158 /**
159  * Sets a bit active in a bitArray.
160  *
161  * @param bitArray memory area to set the bit in
162  * @param bitIdx which bit to set
163  */
164 static void
165 setBit (char *bitArray, unsigned int bitIdx)
166 {
167   size_t arraySlot;
168   unsigned int targetBit;
169
170   arraySlot = bitIdx / 8;
171   targetBit = (1L << (bitIdx % 8));
172   bitArray[arraySlot] |= targetBit;
173 }
174
175
176 /**
177  * Checks if a bit is active in the bitArray
178  *
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.
182  */
183 static int
184 testBit (char *bitArray, unsigned int bitIdx)
185 {
186   size_t slot;
187   unsigned int targetBit;
188
189   slot = bitIdx / 8;
190   targetBit = (1L << (bitIdx % 8));
191   if (bitArray[slot] & targetBit)
192     return GNUNET_YES;
193   else
194     return GNUNET_NO;
195 }
196
197
198 /**
199  * Function scheduled as very last function, cleans up after us
200  *{{{
201  */
202 static void
203 cleanup (void *cls GNUNET_UNUSED,
204          const struct GNUNET_SCHEDULER_TaskContext *tskctx)
205 {
206   unsigned int i;
207
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)
212   {
213     GNUNET_MESH_disconnect (mesh_handle);
214     mesh_handle = NULL;
215   }
216   if (helper_handle != NULL)
217   {
218     GNUNET_HELPER_stop (helper_handle);
219     helper_handle = NULL;
220   }
221   if (GNUNET_SCHEDULER_NO_TASK != shs_task)
222   {
223     GNUNET_SCHEDULER_cancel (shs_task);
224     shs_task = GNUNET_SCHEDULER_NO_TASK;
225   }
226   if (GNUNET_SCHEDULER_NO_TASK != conn_task)
227   {
228     GNUNET_SCHEDULER_cancel (conn_task);
229     conn_task = GNUNET_SCHEDULER_NO_TASK;
230   }
231   for (i=0;i<5;i++)
232     GNUNET_free_non_null (vpn_argv[i]);
233 }
234
235 /*}}}*/
236
237 /**
238  * @return the hash of the IP-Address if a mapping exists, NULL otherwise
239  */
240 static GNUNET_HashCode *
241 address6_mapping_exists (struct in6_addr *v6addr)
242 {
243   unsigned char *addr = (unsigned char*) v6addr;
244   GNUNET_HashCode *key = GNUNET_malloc (sizeof (GNUNET_HashCode));
245   unsigned char *k = (unsigned char *) key;
246
247   memset (key, 0, sizeof (GNUNET_HashCode));
248   unsigned int i;
249
250   for (i = 0; i < 16; i++)
251     k[15 - i] = addr[i];
252
253   if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (hashmap, key))
254     return key;
255   else
256   {
257     GNUNET_free (key);
258     return NULL;
259   }
260 }
261
262 /**
263  * @return the hash of the IP-Address if a mapping exists, NULL otherwise
264  */
265 static GNUNET_HashCode *
266 address4_mapping_exists (uint32_t addr)
267 {
268   GNUNET_HashCode *key = GNUNET_malloc (sizeof (GNUNET_HashCode));
269
270   memset (key, 0, sizeof (GNUNET_HashCode));
271   unsigned char *c = (unsigned char *) &addr;
272   unsigned char *k = (unsigned char *) key;
273   unsigned int i;
274
275   for (i = 0; i < 4; i++)
276     k[3 - i] = c[i];
277
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]);
281
282   if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (hashmap, key))
283     return key;
284   else
285   {
286     GNUNET_free (key);
287     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Mapping not found!\n");
288     return NULL;
289   }
290 }
291
292
293 static void *
294 initialize_tunnel_state (int addrlen, struct GNUNET_MESH_TransmitHandle *th)
295 {
296   struct tunnel_state *ts = GNUNET_malloc (sizeof *ts);
297
298   ts->addrlen = addrlen;
299   ts->th = th;
300   return ts;
301 }
302
303
304 static void
305 send_icmp4_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
306 {
307   if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
308     return;
309
310   struct ip_icmp *request = cls;
311
312   struct ip_icmp *response = alloca (ntohs (request->shdr.size));
313
314   GNUNET_assert (response != NULL);
315   memset (response, 0, ntohs (request->shdr.size));
316
317   response->shdr.size = request->shdr.size;
318   response->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
319
320   response->tun.flags = 0;
321   response->tun.type = htons (0x0800);
322
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;
329
330   response->ip_hdr.chks =
331       GNUNET_CRYPTO_crc16_n ((uint16_t *) & response->ip_hdr, 20);
332
333   response->icmp_hdr.code = 0;
334   response->icmp_hdr.type = 0x0;
335
336   /* Magic, more Magic! */
337   response->icmp_hdr.chks = request->icmp_hdr.chks + 0x8;
338
339   /* Copy the rest of the packet */
340   memcpy (response + 1, request + 1,
341           ntohs (request->shdr.size) - sizeof (struct ip_icmp));
342
343   (void) GNUNET_HELPER_send (helper_handle,
344                              &response->shdr,
345                              GNUNET_YES,
346                              NULL, NULL);
347   GNUNET_free (request);
348 }
349
350
351 static void
352 send_icmp6_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
353 {
354   if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
355     return;
356
357   struct ip6_icmp *request = cls;
358
359   struct ip6_icmp *response = alloca (ntohs (request->shdr.size));
360
361   GNUNET_assert (response != NULL);
362   memset (response, 0, ntohs (request->shdr.size));
363
364   response->shdr.size = request->shdr.size;
365   response->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
366
367   response->tun.flags = 0;
368   response->tun.type = htons (0x86dd);
369
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);
376
377   response->icmp_hdr.code = 0;
378   response->icmp_hdr.type = 0x81;
379
380   /* Magic, more Magic! */
381   response->icmp_hdr.chks = request->icmp_hdr.chks - 0x1;
382
383   /* Copy the rest of the packet */
384   memcpy (response + 1, request + 1,
385           ntohs (request->shdr.size) - sizeof (struct ip6_icmp));
386
387   (void) GNUNET_HELPER_send (helper_handle,
388                              &response->shdr,
389                              GNUNET_YES,
390                              NULL, NULL);
391   GNUNET_free (request);
392 }
393
394
395 /**
396  * cls is the pointer to a GNUNET_MessageHeader that is
397  * followed by the service-descriptor and the packet that should be sent;
398  */
399 static size_t
400 send_pkt_to_peer_notify_callback (void *cls, size_t size, void *buf)
401 {
402   struct GNUNET_MESH_Tunnel **tunnel = cls;
403
404   struct tunnel_state *ts = GNUNET_MESH_tunnel_get_data (*tunnel);
405
406   ts->th = NULL;
407
408   if (NULL != buf)
409   {
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,
414                 size);
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");
419   }
420   else
421     size = 0;
422
423   if (NULL != ts->head)
424   {
425     struct tunnel_notify_queue *element = ts->head;
426
427     GNUNET_CONTAINER_DLL_remove (ts->head, ts->tail, element);
428
429     ts->th =
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 *)
434                                            NULL, element->len,
435                                            send_pkt_to_peer_notify_callback,
436                                            element->cls);
437
438     /* save the handle */
439     GNUNET_free (element);
440   }
441   GNUNET_free (cls);
442
443   return size;
444 }
445
446
447 static void
448 send_pkt_to_peer (void *cls, const struct GNUNET_PeerIdentity *peer,
449                   const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
450 {
451   /* peer == NULL means that all peers in this request are connected */
452   if (peer == NULL)
453     return;
454   struct GNUNET_MESH_Tunnel **tunnel = cls;
455   struct GNUNET_MessageHeader *hdr =
456       (struct GNUNET_MessageHeader *) (tunnel + 1);
457
458   GNUNET_assert (NULL != tunnel);
459   GNUNET_assert (NULL != *tunnel);
460
461   struct tunnel_state *ts = GNUNET_MESH_tunnel_get_data (*tunnel);
462
463   if (NULL == ts->th)
464   {
465     ts->th =
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,
472                                            cls);
473   }
474   else
475   {
476     struct tunnel_notify_queue *element = GNUNET_malloc (sizeof *element);
477
478     element->cls = cls;
479     element->len = ntohs (hdr->size);
480
481     GNUNET_CONTAINER_DLL_insert_tail (ts->head, ts->tail, element);
482   }
483 }
484
485
486
487
488 /**
489  * Receive packets from the helper-process
490  */
491 static void
492 message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED,
493                const struct GNUNET_MessageHeader *message)
494 {
495   GNUNET_assert (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_HELPER);
496
497   struct tun_pkt *pkt_tun = (struct tun_pkt *) message;
498   GNUNET_HashCode *key;
499
500   /* ethertype is ipv6 */
501   if (ntohs (pkt_tun->tun.type) == 0x86dd)
502   {
503     struct ip6_pkt *pkt6 = (struct ip6_pkt *) message;
504
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;
509
510     pkt6_udp = NULL;            /* make compiler happy */
511     switch (pkt6->ip6_hdr.nxthdr)
512     {
513     case IPPROTO_UDP:
514       pkt6_udp = (struct ip6_udp *) pkt6;
515       /* Send dns-packets to the service-dns */
516       if (ntohs (pkt6_udp->udp_hdr.dpt) == 53)
517       {
518         /* 9 = 8 for the udp-header + 1 for the unsigned char data[1]; */
519         GNUNET_DNS_queue_request_v6 (dns_handle,
520                                      &pkt6->ip6_hdr.dadr,
521                                      &pkt6->ip6_hdr.sadr,
522                                      ntohs (pkt6_udp->udp_hdr.spt),
523                                      ntohs (pkt6_udp->udp_hdr.len) - 8,
524                                      (const void*) pkt6_udp->data);
525
526         break;
527       }
528       /* fall through */
529     case IPPROTO_TCP:
530       pkt6_tcp = (struct ip6_tcp *) pkt6;
531
532       if ((key = address6_mapping_exists (&pkt6->ip6_hdr.dadr)) != NULL)
533       {
534         struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
535
536         GNUNET_assert (me != NULL);
537         GNUNET_free (key);
538
539         size_t size =
540             sizeof (struct GNUNET_MESH_Tunnel *) +
541             sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) +
542             ntohs (pkt6->ip6_hdr.paylgth);
543
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);
548
549         hdr->size =
550             htons (sizeof (struct GNUNET_MessageHeader) +
551                    sizeof (GNUNET_HashCode) + ntohs (pkt6->ip6_hdr.paylgth));
552
553         GNUNET_MESH_ApplicationType app_type = 0;       /* fix compiler uninitialized warning... */
554
555         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "me->addrlen is %d\n",
556                     me->addrlen);
557         if (me->addrlen == 0)
558         {
559           /* This is a mapping to a gnunet-service */
560           memcpy (hc, &me->desc.service_descriptor, sizeof (GNUNET_HashCode));
561
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))))
566           {
567             hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP);
568
569             memcpy (hc + 1, &pkt6_udp->udp_hdr, ntohs (pkt6_udp->udp_hdr.len));
570
571           }
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)))
575           {
576             hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP);
577
578             memcpy (hc + 1, &pkt6_tcp->tcp_hdr, ntohs (pkt6->ip6_hdr.paylgth));
579
580           }
581           else
582           {
583             GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "pip: %d\n",
584                         port_in_ports (me->desc.ports, pkt6_tcp->tcp_hdr.dpt));
585             GNUNET_assert (0);
586           }
587           if (me->tunnel == NULL && NULL != cls)
588           {
589             *cls =
590                 GNUNET_MESH_tunnel_create (mesh_handle,
591                                            initialize_tunnel_state (16, NULL),
592                                            &send_pkt_to_peer, NULL, cls);
593
594             GNUNET_MESH_peer_request_connect_add (*cls,
595                                                   (struct GNUNET_PeerIdentity *)
596                                                   &me->desc.peer);
597             me->tunnel = *cls;
598           }
599           else if (NULL != cls)
600           {
601             *cls = me->tunnel;
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));
606           }
607         }
608         else
609         {
610           /* This is a mapping to a "real" address */
611           struct remote_addr *s = (struct remote_addr *) hc;
612
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)
617           {
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;
623           }
624           else if (s->proto == IPPROTO_TCP)
625           {
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;
631           }
632           else
633           {
634             GNUNET_assert (0);
635           }
636           if (me->tunnel == NULL && NULL != cls)
637           {
638             *cls =
639                 GNUNET_MESH_tunnel_create (mesh_handle,
640                                            initialize_tunnel_state (16, NULL),
641                                            &send_pkt_to_peer, NULL, cls);
642
643             GNUNET_MESH_peer_request_connect_by_type (*cls, app_type);
644             me->tunnel = *cls;
645             if (GNUNET_APPLICATION_TYPE_INTERNET_UDP_GATEWAY == app_type)
646               udp_tunnel = *cls;
647             else if (GNUNET_APPLICATION_TYPE_INTERNET_TCP_GATEWAY == app_type)
648               tcp_tunnel = *cls;
649           }
650           else if (NULL != cls)
651           {
652             *cls = me->tunnel;
653             send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL);
654           }
655         }
656       }
657       else
658       {
659         char pbuf[INET6_ADDRSTRLEN];
660         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
661                     "Packet to %s, which has no mapping\n",
662                     inet_ntop (AF_INET6,
663                                &pkt6->ip6_hdr.dadr,
664                                pbuf,
665                                sizeof (pbuf)));
666       }
667       break;
668     case 0x3a:
669       /* ICMPv6 */
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)
674       {
675         GNUNET_free (key);
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);
679       }
680       break;
681     }
682   }
683   /* ethertype is ipv4 */
684   else if (ntohs (pkt_tun->tun.type) == 0x0800)
685   {
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;
691
692     GNUNET_assert (pkt->ip_hdr.version == 4);
693
694     /* Send dns-packets to the service-dns */
695     if (pkt->ip_hdr.proto == IPPROTO_UDP && ntohs (udp->udp_hdr.dpt) == 53)
696     {
697       GNUNET_DNS_queue_request_v4 (dns_handle,
698                                    &pkt->ip_hdr.dadr,
699                                    &pkt->ip_hdr.sadr,
700                                    ntohs (udp->udp_hdr.spt),
701                                    ntohs (udp->udp_hdr.len) - 8,
702                                    (const void*) udp->data);
703     }
704     else
705     {
706       uint32_t dadr = pkt->ip_hdr.dadr.s_addr;
707       unsigned char *c = (unsigned char *) &dadr;
708
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)
712       {
713       case IPPROTO_TCP:
714       case IPPROTO_UDP:
715         pkt_tcp = (struct ip_tcp *) pkt;
716         pkt_udp = (struct ip_udp *) pkt;
717
718         if ((key = address4_mapping_exists (dadr)) != NULL)
719         {
720           struct map_entry *me =
721               GNUNET_CONTAINER_multihashmap_get (hashmap, key);
722           GNUNET_assert (me != NULL);
723           GNUNET_free (key);
724
725           size_t size =
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;
729
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);
734
735           hdr->size =
736               htons (sizeof (struct GNUNET_MessageHeader) +
737                      sizeof (GNUNET_HashCode) + ntohs (pkt->ip_hdr.tot_lngth) -
738                      4 * pkt->ip_hdr.hdr_lngth);
739
740           GNUNET_MESH_ApplicationType app_type = 0; /* make compiler happy */
741
742           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "me->addrlen is %d\n",
743                       me->addrlen);
744           if (me->addrlen == 0)
745           {
746             /* This is a mapping to a gnunet-service */
747             memcpy (hc, &me->desc.service_descriptor, sizeof (GNUNET_HashCode));
748
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))))
753             {
754               hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP);
755
756               memcpy (hc + 1, &pkt_udp->udp_hdr, ntohs (pkt_udp->udp_hdr.len));
757
758             }
759             else if ((IPPROTO_TCP == pkt->ip_hdr.proto) &&
760                      (me->
761                       desc.service_type & htonl (GNUNET_DNS_SERVICE_TYPE_TCP))
762                      && (port_in_ports (me->desc.ports, pkt_tcp->tcp_hdr.dpt)))
763             {
764               hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP);
765
766               memcpy (hc + 1, &pkt_tcp->tcp_hdr,
767                       ntohs (pkt->ip_hdr.tot_lngth) -
768                       4 * pkt->ip_hdr.hdr_lngth);
769
770             }
771             if (me->tunnel == NULL && NULL != cls)
772             {
773               *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
779                                                      *) &me->desc.peer);
780               me->tunnel = *cls;
781             }
782             else if (NULL != cls)
783             {
784               *cls = me->tunnel;
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),
789                           ntohs (hdr->type));
790             }
791           }
792           else
793           {
794             /* This is a mapping to a "real" address */
795             struct remote_addr *s = (struct remote_addr *) hc;
796
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)
801             {
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;
805             }
806             else if (s->proto == IPPROTO_TCP)
807             {
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;
813             }
814             else
815               GNUNET_assert (0);
816             if (me->tunnel == NULL && NULL != cls)
817             {
818               *cls =
819                   GNUNET_MESH_tunnel_create (mesh_handle,
820                                              initialize_tunnel_state (4, NULL),
821                                              send_pkt_to_peer, NULL, cls);
822
823               GNUNET_MESH_peer_request_connect_by_type (*cls, app_type);
824               me->tunnel = *cls;
825             }
826             else if (NULL != cls)
827             {
828               *cls = me->tunnel;
829               send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL);
830             }
831           }
832         }
833         else
834         {
835           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
836                       "Packet to %x which has no mapping\n", dadr);
837         }
838         break;
839       case 0x01:
840         /* ICMP */
841         pkt_icmp = (struct ip_icmp *) pkt;
842         if (pkt_icmp->icmp_hdr.type == 0x8 &&
843             (key = address4_mapping_exists (dadr)) != NULL)
844         {
845           GNUNET_free (key);
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);
849         }
850         break;
851       }
852     }
853   }
854 }
855
856
857
858 static void
859 collect_mappings (void *cls GNUNET_UNUSED,
860                   const struct GNUNET_SCHEDULER_TaskContext *tc)
861 {
862   if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
863     return;
864
865   struct map_entry *me = GNUNET_CONTAINER_heap_remove_root (heap);
866
867   /* This is free()ed memory! */
868   me->heap_node = NULL;
869
870   /* FIXME! GNUNET_MESH_close_tunnel(me->tunnel); */
871
872   GNUNET_assert (GNUNET_YES ==
873                  GNUNET_CONTAINER_multihashmap_remove (hashmap, &me->hash, me));
874
875   GNUNET_free (me);
876 }
877
878
879 /**
880  * Create a new Address from an answer-packet
881  */
882 static void
883 new_ip6addr (struct in6_addr *v6addr,
884              const GNUNET_HashCode * peer,
885              const GNUNET_HashCode * service_desc)
886 {                               /* {{{ */
887   unsigned char *buf = (unsigned char*) v6addr;
888   char *ipv6addr;
889   unsigned long long ipv6prefix;
890
891   GNUNET_assert (GNUNET_OK ==
892                  GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR",
893                                                         &ipv6addr));
894   GNUNET_assert (GNUNET_OK ==
895                  GNUNET_CONFIGURATION_get_value_number (cfg, "vpn",
896                                                         "IPV6PREFIX",
897                                                         &ipv6prefix));
898   GNUNET_assert (ipv6prefix < 127);
899   ipv6prefix = (ipv6prefix + 7) / 8;
900
901   inet_pton (AF_INET6, ipv6addr, buf);
902   GNUNET_free (ipv6addr);
903
904   int peer_length = 16 - ipv6prefix - 6;
905
906   if (peer_length <= 0)
907     peer_length = 0;
908
909   int service_length = 16 - ipv6prefix - peer_length;
910
911   if (service_length <= 0)
912     service_length = 0;
913
914   memcpy (buf + ipv6prefix, service_desc, service_length);
915   memcpy (buf + ipv6prefix + service_length, peer, peer_length);
916 }
917
918 /*}}}*/
919
920
921 /**
922  * Create a new Address from an answer-packet
923  */
924 static void
925 new_ip6addr_remote (struct in6_addr *v6addr,
926                     unsigned char *addr, char addrlen)
927 {                               /* {{{ */
928   unsigned char *buf = (unsigned char*) v6addr;
929   char *ipv6addr;
930   unsigned long long ipv6prefix;
931
932   GNUNET_assert (GNUNET_OK ==
933                  GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR",
934                                                         &ipv6addr));
935   GNUNET_assert (GNUNET_OK ==
936                  GNUNET_CONFIGURATION_get_value_number (cfg, "vpn",
937                                                         "IPV6PREFIX",
938                                                         &ipv6prefix));
939   GNUNET_assert (ipv6prefix < 127);
940   ipv6prefix = (ipv6prefix + 7) / 8;
941
942   inet_pton (AF_INET6, ipv6addr, buf);
943   GNUNET_free (ipv6addr);
944
945   int local_length = 16 - ipv6prefix;
946
947   memcpy (buf + ipv6prefix, addr, GNUNET_MIN (addrlen, local_length));
948 }
949
950 /*}}}*/
951
952 /**
953  * Create a new Address from an answer-packet
954  */
955 static void
956 new_ip4addr_remote (unsigned char *buf, unsigned char *addr, char addrlen)
957 {                               /* {{{ */
958   char *ipv4addr;
959   char *ipv4mask;
960
961   GNUNET_assert (GNUNET_OK ==
962                  GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4ADDR",
963                                                         &ipv4addr));
964   GNUNET_assert (GNUNET_OK ==
965                  GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4MASK",
966                                                         &ipv4mask));
967   uint32_t mask;
968
969   inet_pton (AF_INET, ipv4addr, buf);
970   int r = inet_pton (AF_INET, ipv4mask, &mask);
971
972   mask = htonl (mask);
973   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "inet_pton: %d; %m; mask: %08x\n", r,
974               mask);
975
976   GNUNET_free (ipv4addr);
977
978   int c;
979
980   if (mask)
981   {
982     mask = (mask ^ (mask - 1)) >> 1;
983     for (c = 0; mask; c++)
984     {
985       mask >>= 1;
986     }
987   }
988   else
989   {
990     c = CHAR_BIT * sizeof (mask);
991   }
992
993   c = 32 - c;
994   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "The mask %s has %d leading 1s.\n",
995               ipv4mask, c);
996
997   GNUNET_free (ipv4mask);
998
999   if (c % 8 == 0)
1000     c = c / 8;
1001   else
1002     GNUNET_assert (0);
1003
1004   memcpy (buf + c, addr, GNUNET_MIN (addrlen, 4 - c));
1005 }
1006
1007 /*}}}*/
1008
1009 /**
1010  * This gets scheduled with cls pointing to an answer_packet and does everything
1011  * needed in order to send it to the helper.
1012  *
1013  * At the moment this means "inventing" and IPv6-Address for .gnunet-services and
1014  * doing nothing for "real" services.
1015  */
1016 static void
1017 process_answer (void *cls, 
1018                 const struct answer_packet *pkt)
1019 {
1020   struct answer_packet_list *list;
1021
1022   /* This answer is about a .gnunet-service
1023    *
1024    * It contains an almost complete DNS-Response, we have to fill in the ip
1025    * at the offset pkt->addroffset
1026    */
1027   if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_SERVICE)
1028   {
1029
1030     GNUNET_HashCode key;
1031
1032     memset (&key, 0, sizeof (GNUNET_HashCode));
1033
1034     list =
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));
1039
1040     unsigned char *c = ((unsigned char *) &list->pkt) + ntohs (pkt->addroffset);
1041     unsigned char *k = (unsigned char *) &key;
1042
1043     new_ip6addr ((struct in6_addr*) c, 
1044                  &pkt->service_descr.peer,
1045                  &pkt->service_descr.service_descriptor);
1046     /*
1047      * Copy the newly generated ip-address to the key backwarts (as only the first part is hashed)
1048      */
1049     unsigned int i;
1050
1051     for (i = 0; i < 16; i++)
1052       k[15 - i] = c[i];
1053
1054     uint16_t namelen = strlen ((char *) pkt->data + 12) + 1;
1055
1056     struct map_entry *value =
1057         GNUNET_malloc (sizeof (struct map_entry) + namelen);
1058     char *name = (char *) (value + 1);
1059
1060     value->namelen = namelen;
1061     memcpy (name, pkt->data + 12, namelen);
1062
1063     memcpy (&value->desc, &pkt->service_descr,
1064             sizeof (struct GNUNET_vpn_service_descriptor));
1065
1066     memset (value->additional_ports, 0, 8192);
1067
1068     memcpy (&value->hash, &key, sizeof (GNUNET_HashCode));
1069
1070     if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (hashmap, &key))
1071     {
1072       GNUNET_CONTAINER_multihashmap_put (hashmap, &key, value,
1073                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1074
1075       value->heap_node =
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);
1080     }
1081     else
1082       GNUNET_free (value);
1083
1084
1085     list->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_IP;
1086
1087
1088   }
1089   else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REV)
1090   {
1091     GNUNET_HashCode key;
1092
1093     memset (&key, 0, sizeof key);
1094     unsigned char *k = (unsigned char *) &key;
1095     const unsigned char *s = pkt->data + 12;
1096     int i = 0;
1097
1098     /* Whoever designed the reverse IPv6-lookup is batshit insane */
1099     for (i = 0; i < 16; i++)
1100     {
1101       unsigned char c1 = s[(4 * i) + 1];
1102       unsigned char c2 = s[(4 * i) + 3];
1103
1104       if (c1 <= '9')
1105         k[i] = c1 - '0';
1106       else
1107         k[i] = c1 - 87;         /* 87 is the difference between 'a' and 10 */
1108       if (c2 <= '9')
1109         k[i] += 16 * (c2 - '0');
1110       else
1111         k[i] += 16 * (c2 - 87);
1112     }
1113
1114     struct map_entry *map_entry =
1115         GNUNET_CONTAINER_multihashmap_get (hashmap, &key);
1116     uint16_t offset = ntohs (pkt->addroffset);
1117
1118     if (map_entry == NULL)
1119       return;
1120
1121     GNUNET_CONTAINER_heap_update_cost (heap, map_entry->heap_node,
1122                                        GNUNET_TIME_absolute_get ().abs_value);
1123
1124
1125     unsigned short namelen = htons (map_entry->namelen);
1126     char *name = (char *) (map_entry + 1);
1127
1128     list =
1129         GNUNET_malloc (sizeof (struct answer_packet_list) -
1130                        sizeof (struct answer_packet) + offset + 2 +
1131                        ntohs (namelen));
1132
1133     struct answer_packet *rpkt = &list->pkt;
1134
1135     /* The offset points to the first byte belonging to the address */
1136     memcpy (rpkt, pkt, offset - 1);
1137
1138     rpkt->subtype = GNUNET_DNS_ANSWER_TYPE_IP;
1139     rpkt->hdr.size = ntohs (offset + 2 + ntohs (namelen));
1140
1141     memcpy (((char *) rpkt) + offset, &namelen, 2);
1142     memcpy (((char *) rpkt) + offset + 2, name, ntohs (namelen));
1143
1144   }
1145   else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_IP)
1146   {
1147     list =
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));
1152   }
1153   else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REMOTE_AAAA)
1154   {
1155
1156     GNUNET_HashCode key;
1157
1158     memset (&key, 0, sizeof (GNUNET_HashCode));
1159
1160     list =
1161         GNUNET_malloc (htons (pkt->hdr.size) +
1162                        sizeof (struct answer_packet_list) -
1163                        sizeof (struct answer_packet));
1164
1165     memcpy (&list->pkt, pkt, htons (pkt->hdr.size));
1166     list->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_IP;
1167
1168     unsigned char *c = ((unsigned char *) &list->pkt) + ntohs (list->pkt.addroffset);
1169
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;
1177
1178     /*
1179      * Copy the newly generated ip-address to the key backwards (as only the first part is used in the hash-table)
1180      */
1181     unsigned int i;
1182
1183     for (i = 0; i < 16; i++)
1184       k[15 - i] = c[i];
1185
1186     uint16_t namelen = strlen ((char *) pkt->data + 12) + 1;
1187
1188     struct map_entry *value =
1189         GNUNET_malloc (sizeof (struct map_entry) + namelen);
1190     char *name = (char *) (value + 1);
1191
1192     value->namelen = namelen;
1193     memcpy (name, pkt->data + 12, namelen);
1194
1195     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting addrlen to %d\n",
1196                 pkt->addrsize);
1197     value->addrlen = pkt->addrsize;
1198     memcpy (&value->addr, &pkt->addr, pkt->addrsize);
1199     memset (value->additional_ports, 0, 8192);
1200
1201     memcpy (&value->hash, &key, sizeof (GNUNET_HashCode));
1202
1203     if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (hashmap, &key))
1204     {
1205       GNUNET_CONTAINER_multihashmap_put (hashmap, &key, value,
1206                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1207       value->heap_node =
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);
1212     }
1213     else
1214       GNUNET_free (value);
1215
1216
1217   }
1218   else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REMOTE_A)
1219   {
1220     list =
1221         GNUNET_malloc (htons (pkt->hdr.size) +
1222                        sizeof (struct answer_packet_list) -
1223                        sizeof (struct answer_packet));
1224
1225     memcpy (&list->pkt, pkt, htons (pkt->hdr.size));
1226     list->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_IP;
1227
1228     GNUNET_HashCode key;
1229
1230     memset (&key, 0, sizeof (GNUNET_HashCode));
1231
1232     unsigned char *c = ((unsigned char *) &list->pkt) + ntohs (pkt->addroffset);
1233
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],
1236                 c[1], c[2], c[3]);
1237     unsigned char *k = (unsigned char *) &key;
1238
1239     /*
1240      * Copy the newly generated ip-address to the key backwards (as only the first part is used in the hash-table)
1241      */
1242     unsigned int i;
1243
1244     for (i = 0; i < 4; i++)
1245       k[3 - i] = c[i];
1246
1247     uint16_t namelen = strlen ((char *) pkt->data + 12) + 1;
1248
1249     struct map_entry *value =
1250         GNUNET_malloc (sizeof (struct map_entry) + namelen);
1251     char *name = (char *) (value + 1);
1252
1253     value->namelen = namelen;
1254     memcpy (name, pkt->data + 12, namelen);
1255
1256     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting addrlen to %d\n",
1257                 pkt->addrsize);
1258     value->addrlen = pkt->addrsize;
1259     memcpy (&value->addr, &pkt->addr, pkt->addrsize);
1260     memset (value->additional_ports, 0, 8192);
1261
1262     memcpy (&value->hash, &key, sizeof (GNUNET_HashCode));
1263
1264     if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (hashmap, &key))
1265     {
1266       GNUNET_CONTAINER_multihashmap_put (hashmap, &key, value,
1267                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1268       value->heap_node =
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);
1276     }
1277     else
1278       GNUNET_free (value);
1279
1280   }
1281   else
1282   {
1283     GNUNET_break (0);
1284     return;
1285   }
1286
1287   GNUNET_CONTAINER_DLL_insert_after (answer_proc_head, answer_proc_tail,
1288                                      answer_proc_tail, list);
1289
1290 }
1291
1292
1293 /**
1294  * @brief Add the port to the list of additional ports in the map_entry
1295  *
1296  * @param me the map_entry
1297  * @param port the port in host-byte-order
1298  */
1299 static void
1300 add_additional_port (struct map_entry *me, uint16_t port)
1301 {
1302   setBit (me->additional_ports, port);
1303 }
1304
1305 static int
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)
1310 {
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;
1316
1317   if (16 == ts->addrlen)
1318   {
1319     size_t size =
1320         sizeof (struct ip6_udp) + ntohs (pkt->len) - 1 -
1321         sizeof (struct udp_pkt);
1322
1323     struct ip6_udp *pkt6 = alloca (size);
1324
1325     GNUNET_assert (pkt6 != NULL);
1326
1327     if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK)
1328       new_ip6addr (&pkt6->ip6_hdr.sadr, &other->hashPubKey, desc);
1329     else
1330       new_ip6addr_remote (&pkt6->ip6_hdr.sadr, s->addr, s->addrlen);
1331
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));
1335
1336     pkt6->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1337     pkt6->shdr.size = htons (size);
1338
1339     pkt6->tun.flags = 0;
1340     pkt6->tun.type = htons (0x86dd);
1341
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;
1349
1350     {
1351       char *ipv6addr;
1352
1353       GNUNET_assert (GNUNET_OK ==
1354                      GNUNET_CONFIGURATION_get_value_string (cfg, "vpn",
1355                                                             "IPV6ADDR",
1356                                                             &ipv6addr));
1357       inet_pton (AF_INET6, ipv6addr, &pkt6->ip6_hdr.dadr);
1358       GNUNET_free (ipv6addr);
1359     }
1360     memcpy (&pkt6->udp_hdr, pkt, ntohs (pkt->len));
1361
1362     GNUNET_HashCode *key = address6_mapping_exists (&pkt6->ip6_hdr.sadr);
1363
1364     GNUNET_assert (key != NULL);
1365
1366     struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
1367
1368     GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node,
1369                                        GNUNET_TIME_absolute_get ().abs_value);
1370
1371     GNUNET_free (key);
1372
1373     GNUNET_assert (me != NULL);
1374     if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK)
1375     {
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)))
1380       {
1381         add_additional_port (me, ntohs (pkt6->udp_hdr.spt));
1382       }
1383     }
1384
1385     pkt6->udp_hdr.crc = 0;
1386     uint32_t sum = 0;
1387
1388     sum =
1389         GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.sadr, 16);
1390     sum =
1391         GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.dadr, 16);
1392     uint32_t tmp = (pkt6->udp_hdr.len & 0xffff);
1393
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);
1397
1398     sum =
1399         GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->udp_hdr,
1400                                    ntohs (pkt->len));
1401     pkt6->udp_hdr.crc = GNUNET_CRYPTO_crc16_finish (sum);
1402     
1403     (void) GNUNET_HELPER_send (helper_handle,
1404                                &pkt6->shdr,
1405                                GNUNET_YES,
1406                                NULL, NULL);
1407   }
1408   else
1409   {
1410     size_t size =
1411         sizeof (struct ip_udp) + ntohs (pkt->len) - 1 - sizeof (struct udp_pkt);
1412
1413     struct ip_udp *pkt4 = alloca (size);
1414
1415     GNUNET_assert (pkt4 != NULL);
1416
1417     GNUNET_assert (ntohs (message->type) ==
1418                    GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP_BACK);
1419     uint32_t sadr;
1420
1421     new_ip4addr_remote ((unsigned char *) &sadr, s->addr, s->addrlen);
1422     pkt4->ip_hdr.sadr.s_addr = sadr;
1423
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));
1427
1428     pkt4->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1429     pkt4->shdr.size = htons (size);
1430
1431     pkt4->tun.flags = 0;
1432     pkt4->tun.type = htons (0x0800);
1433
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 */
1444
1445     {
1446       char *ipv4addr;
1447       uint32_t dadr;
1448
1449       GNUNET_assert (GNUNET_OK ==
1450                      GNUNET_CONFIGURATION_get_value_string (cfg, "vpn",
1451                                                             "IPV4ADDR",
1452                                                             &ipv4addr));
1453       inet_pton (AF_INET, ipv4addr, &dadr);
1454       GNUNET_free (ipv4addr);
1455       pkt4->ip_hdr.dadr.s_addr = dadr;
1456     }
1457     memcpy (&pkt4->udp_hdr, pkt, ntohs (pkt->len));
1458
1459     GNUNET_HashCode *key = address4_mapping_exists (pkt4->ip_hdr.sadr.s_addr);
1460
1461     GNUNET_assert (key != NULL);
1462
1463     struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
1464
1465     GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node,
1466                                        GNUNET_TIME_absolute_get ().abs_value);
1467
1468     GNUNET_free (key);
1469
1470     GNUNET_assert (me != NULL);
1471
1472     pkt4->udp_hdr.crc = 0;      /* Optional for IPv4 */
1473
1474     pkt4->ip_hdr.chks =
1475         GNUNET_CRYPTO_crc16_n ((uint16_t *) & pkt4->ip_hdr, 5 * 4);
1476
1477     (void) GNUNET_HELPER_send (helper_handle,
1478                                &pkt4->shdr,
1479                                GNUNET_YES,
1480                                NULL, NULL);
1481   }
1482
1483   return GNUNET_OK;
1484 }
1485
1486 static int
1487 receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1488                   void **tunnel_ctx,
1489                   const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1490                   const struct GNUNET_MessageHeader *message,
1491                   const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1492 {
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;
1498
1499   size_t pktlen =
1500       ntohs (message->size) - sizeof (struct GNUNET_MessageHeader) -
1501       sizeof (GNUNET_HashCode);
1502
1503   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1504               "Received TCP-Packet back, addrlen = %d\n", s->addrlen);
1505
1506   if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP_BACK ||
1507       ts->addrlen == 16)
1508   {
1509     size_t size = pktlen + sizeof (struct ip6_tcp) - 1;
1510
1511     struct ip6_tcp *pkt6 = alloca (size);
1512
1513     memset (pkt6, 0, size);
1514
1515     GNUNET_assert (pkt6 != NULL);
1516
1517     if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP_BACK)
1518       new_ip6addr (&pkt6->ip6_hdr.sadr, &other->hashPubKey, desc);
1519     else
1520       new_ip6addr_remote (&pkt6->ip6_hdr.sadr, s->addr, s->addrlen);
1521
1522     pkt6->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1523     pkt6->shdr.size = htons (size);
1524
1525     pkt6->tun.flags = 0;
1526     pkt6->tun.type = htons (0x86dd);
1527
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;
1535
1536     {
1537       char *ipv6addr;
1538
1539       GNUNET_assert (GNUNET_OK ==
1540                      GNUNET_CONFIGURATION_get_value_string (cfg, "vpn",
1541                                                             "IPV6ADDR",
1542                                                             &ipv6addr));
1543       inet_pton (AF_INET6, ipv6addr, &pkt6->ip6_hdr.dadr);
1544       GNUNET_free (ipv6addr);
1545     }
1546     memcpy (&pkt6->tcp_hdr, pkt, pktlen);
1547
1548     GNUNET_HashCode *key = address6_mapping_exists (&pkt6->ip6_hdr.sadr);
1549
1550     GNUNET_assert (key != NULL);
1551
1552     struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
1553
1554     GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node,
1555                                        GNUNET_TIME_absolute_get ().abs_value);
1556
1557     GNUNET_free (key);
1558
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));
1563
1564     pkt6->tcp_hdr.crc = 0;
1565     uint32_t sum = 0;
1566     uint32_t tmp;
1567
1568     sum =
1569         GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt6->ip6_hdr.sadr, 16);
1570     sum =
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);
1576
1577     sum =
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);
1581
1582     (void) GNUNET_HELPER_send (helper_handle,
1583                                &pkt6->shdr,
1584                                GNUNET_YES,
1585                                NULL, NULL);
1586   }
1587   else
1588   {
1589     size_t size = pktlen + sizeof (struct ip_tcp) - 1;
1590
1591     struct ip_tcp *pkt4 = alloca (size);
1592
1593     GNUNET_assert (pkt4 != NULL);
1594     memset (pkt4, 0, size);
1595
1596     GNUNET_assert (ntohs (message->type) ==
1597                    GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP_BACK);
1598     uint32_t sadr;
1599
1600     new_ip4addr_remote ((unsigned char *) &sadr, s->addr, s->addrlen);
1601     pkt4->ip_hdr.sadr.s_addr = sadr;
1602
1603     pkt4->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1604     pkt4->shdr.size = htons (size);
1605
1606     pkt4->tun.flags = 0;
1607     pkt4->tun.type = htons (0x0800);
1608
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 */
1619
1620     {
1621       char *ipv4addr;
1622       uint32_t dadr;
1623
1624       GNUNET_assert (GNUNET_OK ==
1625                      GNUNET_CONFIGURATION_get_value_string (cfg, "vpn",
1626                                                             "IPV4ADDR",
1627                                                             &ipv4addr));
1628       inet_pton (AF_INET, ipv4addr, &dadr);
1629       GNUNET_free (ipv4addr);
1630       pkt4->ip_hdr.dadr.s_addr = dadr;
1631     }
1632
1633     memcpy (&pkt4->tcp_hdr, pkt, pktlen);
1634
1635     GNUNET_HashCode *key = address4_mapping_exists (pkt4->ip_hdr.sadr.s_addr);
1636
1637     GNUNET_assert (key != NULL);
1638
1639     struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
1640
1641     GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node,
1642                                        GNUNET_TIME_absolute_get ().abs_value);
1643
1644     GNUNET_free (key);
1645
1646     GNUNET_assert (me != NULL);
1647     pkt4->tcp_hdr.crc = 0;
1648     uint32_t sum = 0;
1649     uint32_t tmp;
1650
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);
1653
1654     tmp = (0x06 << 16) | (0xffff & pktlen);     // 0x06 for TCP?
1655
1656     tmp = htonl (tmp);
1657
1658     sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & tmp, 4);
1659
1660     sum = GNUNET_CRYPTO_crc16_step (sum, (uint16_t *) & pkt4->tcp_hdr, pktlen);
1661     pkt4->tcp_hdr.crc = GNUNET_CRYPTO_crc16_finish (sum);
1662
1663     pkt4->ip_hdr.chks =
1664         GNUNET_CRYPTO_crc16_n ((uint16_t *) & pkt4->ip_hdr, 5 * 4);
1665
1666     (void) GNUNET_HELPER_send (helper_handle,
1667                                &pkt4->shdr,
1668                                GNUNET_YES,
1669                                NULL, NULL);
1670
1671   }
1672
1673   return GNUNET_OK;
1674 }
1675
1676 static void *
1677 new_tunnel (void *cls, struct GNUNET_MESH_Tunnel *tunnel,
1678             const struct GNUNET_PeerIdentity *initiator,
1679             const struct GNUNET_ATS_Information *atsi)
1680 {
1681   /* Why should anyone open an inbound tunnel to vpn? */
1682   GNUNET_break (0);
1683   return NULL;
1684 }
1685
1686 static void
1687 cleaner (void *cls, const struct GNUNET_MESH_Tunnel *tunnel, void *tunnel_ctx)
1688 {
1689   /* Why should anyone open an inbound tunnel to vpn? */
1690   GNUNET_break (0);
1691 }
1692
1693 /**
1694  * Main function that will be run by the scheduler.
1695  *
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
1700  */
1701 static void
1702 run (void *cls, char *const *args GNUNET_UNUSED,
1703      const char *cfgfile GNUNET_UNUSED,
1704      const struct GNUNET_CONFIGURATION_Handle *cfg_)
1705 {
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},
1711     {NULL, 0, 0}
1712   };
1713   static const GNUNET_MESH_ApplicationType types[] = {
1714     GNUNET_APPLICATION_TYPE_END
1715   };
1716   char *ifname;
1717   char *ipv6addr;
1718   char *ipv6prefix;
1719   char *ipv4addr;
1720   char *ipv4mask;
1721
1722   mesh_handle =
1723       GNUNET_MESH_connect (cfg_, 42, NULL, new_tunnel, cleaner, handlers,
1724                            types);
1725   cfg = cfg_;
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",
1729                                          &max_mappings);
1730   udp_connections = GNUNET_CONTAINER_multihashmap_create (65536);
1731   dns_handle = GNUNET_DNS_connect (cfg,
1732                                    &process_answer,
1733                                    NULL);
1734   if (GNUNET_SYSERR ==
1735       GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IFNAME", &ifname))
1736   {
1737     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1738                 "No entry 'IFNAME' in configuration!\n");
1739     exit (1);
1740   }
1741
1742   if (GNUNET_SYSERR ==
1743       GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR", &ipv6addr))
1744   {
1745     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1746                 "No entry 'IPV6ADDR' in configuration!\n");
1747     exit (1);
1748   }
1749
1750   if (GNUNET_SYSERR ==
1751       GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6PREFIX",
1752                                              &ipv6prefix))
1753   {
1754     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1755                 "No entry 'IPV6PREFIX' in configuration!\n");
1756     exit (1);
1757   }
1758
1759   if (GNUNET_SYSERR ==
1760       GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4ADDR", &ipv4addr))
1761   {
1762     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1763                 "No entry 'IPV4ADDR' in configuration!\n");
1764     exit (1);
1765   }
1766
1767   if (GNUNET_SYSERR ==
1768       GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4MASK", &ipv4mask))
1769   {
1770     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1771                 "No entry 'IPV4MASK' in configuration!\n");
1772     exit (1);
1773   }
1774
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;
1781   vpn_argv[6] = NULL;
1782   
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);
1787 }
1788
1789 /**
1790  * The main function to obtain template from gnunetd.
1791  *
1792  * @param argc number of arguments from the command line
1793  * @param argv command line arguments
1794  * @return 0 ok, 1 on error
1795  */
1796 int
1797 main (int argc, char *const *argv)
1798 {
1799   static const struct GNUNET_GETOPT_CommandLineOption options[] = {
1800     GNUNET_GETOPT_OPTION_END
1801   };
1802
1803   return (GNUNET_OK ==
1804           GNUNET_PROGRAM_run (argc, argv, "vpn", gettext_noop ("help text"),
1805                               options, &run, NULL)) ? ret : 1;
1806 }
1807
1808 /* end of gnunet-daemon-vpn.c */