-again moving towards DNS API sanity
[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-daemon-vpn-helper.h"
39 #include "gnunet_dns_service.h"
40 #include "gnunet-daemon-vpn.h"
41 #include "gnunet-vpn-checksum.h"
42
43 const struct GNUNET_CONFIGURATION_Handle *cfg;
44 struct GNUNET_MESH_Handle *mesh_handle;
45 struct GNUNET_CONTAINER_MultiHashMap *hashmap;
46 static struct GNUNET_CONTAINER_Heap *heap;
47
48 struct GNUNET_DNS_Handle *dns_handle;
49
50 struct answer_packet_list *answer_proc_head;
51
52 struct answer_packet_list *answer_proc_tail;
53
54
55 struct tunnel_notify_queue
56 {
57   struct tunnel_notify_queue *next;
58   struct tunnel_notify_queue *prev;
59   size_t len;
60   void *cls;
61 };
62
63 /**
64  * If there are at least this many address-mappings, old ones will be removed
65  */
66 static long long unsigned int max_mappings = 200;
67
68 /**
69  * Final status code.
70  */
71 static int ret;
72
73 /**
74  * This hashmap contains the mapping from peer, service-descriptor,
75  * source-port and destination-port to a socket
76  */
77 static struct GNUNET_CONTAINER_MultiHashMap *udp_connections;
78
79 GNUNET_SCHEDULER_TaskIdentifier conn_task;
80
81 GNUNET_SCHEDULER_TaskIdentifier shs_task;
82
83
84 /**
85  * Sets a bit active in a bitArray.
86  *
87  * @param bitArray memory area to set the bit in
88  * @param bitIdx which bit to set
89  */
90 static void
91 setBit (char *bitArray, unsigned int bitIdx)
92 {
93   size_t arraySlot;
94   unsigned int targetBit;
95
96   arraySlot = bitIdx / 8;
97   targetBit = (1L << (bitIdx % 8));
98   bitArray[arraySlot] |= targetBit;
99 }
100
101
102 /**
103  * Checks if a bit is active in the bitArray
104  *
105  * @param bitArray memory area to set the bit in
106  * @param bitIdx which bit to test
107  * @return GNUNET_YES if the bit is set, GNUNET_NO if not.
108  */
109 int
110 testBit (char *bitArray, unsigned int bitIdx)
111 {
112   size_t slot;
113   unsigned int targetBit;
114
115   slot = bitIdx / 8;
116   targetBit = (1L << (bitIdx % 8));
117   if (bitArray[slot] & targetBit)
118     return GNUNET_YES;
119   else
120     return GNUNET_NO;
121 }
122
123
124 /**
125  * Function scheduled as very last function, cleans up after us
126  *{{{
127  */
128 static void
129 cleanup (void *cls GNUNET_UNUSED,
130          const struct GNUNET_SCHEDULER_TaskContext *tskctx)
131 {
132   GNUNET_assert (0 != (tskctx->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN));
133
134   /* stop the helper */
135   cleanup_helper (helper_handle);
136
137   /* close the connection to the service-dns */
138   GNUNET_DNS_disconnect (dns_handle);
139   if (mesh_handle != NULL)
140   {
141     GNUNET_MESH_disconnect (mesh_handle);
142     mesh_handle = NULL;
143   }
144   if (GNUNET_SCHEDULER_NO_TASK != shs_task)
145   {
146     GNUNET_SCHEDULER_cancel (shs_task);
147     shs_task = GNUNET_SCHEDULER_NO_TASK;
148   }
149   if (GNUNET_SCHEDULER_NO_TASK != conn_task)
150   {
151     GNUNET_SCHEDULER_cancel (conn_task);
152     conn_task = GNUNET_SCHEDULER_NO_TASK;
153   }
154 }
155
156 /*}}}*/
157
158 /**
159  * @return the hash of the IP-Address if a mapping exists, NULL otherwise
160  */
161 GNUNET_HashCode *
162 address6_mapping_exists (struct in6_addr *v6addr)
163 {
164   unsigned char *addr = (unsigned char*) v6addr;
165   GNUNET_HashCode *key = GNUNET_malloc (sizeof (GNUNET_HashCode));
166   unsigned char *k = (unsigned char *) key;
167
168   memset (key, 0, sizeof (GNUNET_HashCode));
169   unsigned int i;
170
171   for (i = 0; i < 16; i++)
172     k[15 - i] = addr[i];
173
174   if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (hashmap, key))
175     return key;
176   else
177   {
178     GNUNET_free (key);
179     return NULL;
180   }
181 }
182
183 /**
184  * @return the hash of the IP-Address if a mapping exists, NULL otherwise
185  */
186 GNUNET_HashCode *
187 address4_mapping_exists (uint32_t addr)
188 {
189   GNUNET_HashCode *key = GNUNET_malloc (sizeof (GNUNET_HashCode));
190
191   memset (key, 0, sizeof (GNUNET_HashCode));
192   unsigned char *c = (unsigned char *) &addr;
193   unsigned char *k = (unsigned char *) key;
194   unsigned int i;
195
196   for (i = 0; i < 4; i++)
197     k[3 - i] = c[i];
198
199   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
200               "a4_m_e: getting with key %08x, addr is %08x, %d.%d.%d.%d\n",
201               *((uint32_t *) (key)), addr, c[0], c[1], c[2], c[3]);
202
203   if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (hashmap, key))
204     return key;
205   else
206   {
207     GNUNET_free (key);
208     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Mapping not found!\n");
209     return NULL;
210   }
211 }
212
213 static void
214 collect_mappings (void *cls GNUNET_UNUSED,
215                   const struct GNUNET_SCHEDULER_TaskContext *tc)
216 {
217   if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
218     return;
219
220   struct map_entry *me = GNUNET_CONTAINER_heap_remove_root (heap);
221
222   /* This is free()ed memory! */
223   me->heap_node = NULL;
224
225   /* FIXME! GNUNET_MESH_close_tunnel(me->tunnel); */
226
227   GNUNET_assert (GNUNET_YES ==
228                  GNUNET_CONTAINER_multihashmap_remove (hashmap, &me->hash, me));
229
230   GNUNET_free (me);
231 }
232
233 void
234 send_icmp4_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
235 {
236   if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
237     return;
238
239   struct ip_icmp *request = cls;
240
241   struct ip_icmp *response = alloca (ntohs (request->shdr.size));
242
243   GNUNET_assert (response != NULL);
244   memset (response, 0, ntohs (request->shdr.size));
245
246   response->shdr.size = request->shdr.size;
247   response->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
248
249   response->tun.flags = 0;
250   response->tun.type = htons (0x0800);
251
252   response->ip_hdr.hdr_lngth = 5;
253   response->ip_hdr.version = 4;
254   response->ip_hdr.proto = 0x01;
255   response->ip_hdr.dadr = request->ip_hdr.sadr;
256   response->ip_hdr.sadr = request->ip_hdr.dadr;
257   response->ip_hdr.tot_lngth = request->ip_hdr.tot_lngth;
258
259   response->ip_hdr.chks =
260       calculate_ip_checksum ((uint16_t *) & response->ip_hdr, 20);
261
262   response->icmp_hdr.code = 0;
263   response->icmp_hdr.type = 0x0;
264
265   /* Magic, more Magic! */
266   response->icmp_hdr.chks = request->icmp_hdr.chks + 0x8;
267
268   /* Copy the rest of the packet */
269   memcpy (response + 1, request + 1,
270           ntohs (request->shdr.size) - sizeof (struct ip_icmp));
271
272   write_to_helper (response, ntohs (response->shdr.size));
273
274   GNUNET_free (request);
275 }
276
277 void
278 send_icmp6_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
279 {
280   if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
281     return;
282
283   struct ip6_icmp *request = cls;
284
285   struct ip6_icmp *response = alloca (ntohs (request->shdr.size));
286
287   GNUNET_assert (response != NULL);
288   memset (response, 0, ntohs (request->shdr.size));
289
290   response->shdr.size = request->shdr.size;
291   response->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
292
293   response->tun.flags = 0;
294   response->tun.type = htons (0x86dd);
295
296   response->ip6_hdr.hoplmt = 255;
297   response->ip6_hdr.paylgth = request->ip6_hdr.paylgth;
298   response->ip6_hdr.nxthdr = 0x3a;
299   response->ip6_hdr.version = 6;
300   memcpy (&response->ip6_hdr.sadr, &request->ip6_hdr.dadr, 16);
301   memcpy (&response->ip6_hdr.dadr, &request->ip6_hdr.sadr, 16);
302
303   response->icmp_hdr.code = 0;
304   response->icmp_hdr.type = 0x81;
305
306   /* Magic, more Magic! */
307   response->icmp_hdr.chks = request->icmp_hdr.chks - 0x1;
308
309   /* Copy the rest of the packet */
310   memcpy (response + 1, request + 1,
311           ntohs (request->shdr.size) - sizeof (struct ip6_icmp));
312
313   write_to_helper (response, ntohs (response->shdr.size));
314
315   GNUNET_free (request);
316 }
317
318 /**
319  * cls is the pointer to a GNUNET_MessageHeader that is
320  * followed by the service-descriptor and the packet that should be sent;
321  */
322 static size_t
323 send_pkt_to_peer_notify_callback (void *cls, size_t size, void *buf)
324 {
325   struct GNUNET_MESH_Tunnel **tunnel = cls;
326
327   struct tunnel_state *ts = GNUNET_MESH_tunnel_get_data (*tunnel);
328
329   ts->th = NULL;
330
331   if (NULL != buf)
332   {
333     struct GNUNET_MessageHeader *hdr =
334         (struct GNUNET_MessageHeader *) (tunnel + 1);
335     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
336                 "send_pkt_to_peer_notify_callback: buf = %x; size = %u;\n", buf,
337                 size);
338     GNUNET_assert (size >= ntohs (hdr->size));
339     memcpy (buf, hdr, ntohs (hdr->size));
340     size = ntohs (hdr->size);
341     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sent!\n");
342   }
343   else
344     size = 0;
345
346   if (NULL != ts->head)
347   {
348     struct tunnel_notify_queue *element = ts->head;
349
350     GNUNET_CONTAINER_DLL_remove (ts->head, ts->tail, element);
351
352     ts->th =
353         GNUNET_MESH_notify_transmit_ready (*tunnel, GNUNET_NO, 42,
354                                            GNUNET_TIME_relative_divide
355                                            (GNUNET_CONSTANTS_MAX_CORK_DELAY, 2),
356                                            (const struct GNUNET_PeerIdentity *)
357                                            NULL, element->len,
358                                            send_pkt_to_peer_notify_callback,
359                                            element->cls);
360
361     /* save the handle */
362     GNUNET_free (element);
363   }
364   GNUNET_free (cls);
365
366   return size;
367 }
368
369 unsigned int
370 port_in_ports (uint64_t ports, uint16_t port)
371 {
372   uint16_t *ps = (uint16_t *) & ports;
373
374   return ports == 0 || ps[0] == port || ps[1] == port || ps[2] == port ||
375       ps[3] == port;
376 }
377
378 void
379 send_pkt_to_peer (void *cls, const struct GNUNET_PeerIdentity *peer,
380                   const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
381 {
382   /* peer == NULL means that all peers in this request are connected */
383   if (peer == NULL)
384     return;
385   struct GNUNET_MESH_Tunnel **tunnel = cls;
386   struct GNUNET_MessageHeader *hdr =
387       (struct GNUNET_MessageHeader *) (tunnel + 1);
388
389   GNUNET_assert (NULL != tunnel);
390   GNUNET_assert (NULL != *tunnel);
391
392   struct tunnel_state *ts = GNUNET_MESH_tunnel_get_data (*tunnel);
393
394   if (NULL == ts->th)
395   {
396     ts->th =
397         GNUNET_MESH_notify_transmit_ready (*tunnel, GNUNET_NO, 42,
398                                            GNUNET_TIME_relative_divide
399                                            (GNUNET_CONSTANTS_MAX_CORK_DELAY, 2),
400                                            (const struct GNUNET_PeerIdentity *)
401                                            NULL, ntohs (hdr->size),
402                                            send_pkt_to_peer_notify_callback,
403                                            cls);
404   }
405   else
406   {
407     struct tunnel_notify_queue *element = GNUNET_malloc (sizeof *element);
408
409     element->cls = cls;
410     element->len = ntohs (hdr->size);
411
412     GNUNET_CONTAINER_DLL_insert_tail (ts->head, ts->tail, element);
413   }
414 }
415
416 /**
417  * Create a new Address from an answer-packet
418  */
419 void
420 new_ip6addr (struct in6_addr *v6addr,
421              const GNUNET_HashCode * peer,
422              const GNUNET_HashCode * service_desc)
423 {                               /* {{{ */
424   unsigned char *buf = (unsigned char*) v6addr;
425   char *ipv6addr;
426   unsigned long long ipv6prefix;
427
428   GNUNET_assert (GNUNET_OK ==
429                  GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR",
430                                                         &ipv6addr));
431   GNUNET_assert (GNUNET_OK ==
432                  GNUNET_CONFIGURATION_get_value_number (cfg, "vpn",
433                                                         "IPV6PREFIX",
434                                                         &ipv6prefix));
435   GNUNET_assert (ipv6prefix < 127);
436   ipv6prefix = (ipv6prefix + 7) / 8;
437
438   inet_pton (AF_INET6, ipv6addr, buf);
439   GNUNET_free (ipv6addr);
440
441   int peer_length = 16 - ipv6prefix - 6;
442
443   if (peer_length <= 0)
444     peer_length = 0;
445
446   int service_length = 16 - ipv6prefix - peer_length;
447
448   if (service_length <= 0)
449     service_length = 0;
450
451   memcpy (buf + ipv6prefix, service_desc, service_length);
452   memcpy (buf + ipv6prefix + service_length, peer, peer_length);
453 }
454
455 /*}}}*/
456
457
458 /**
459  * Create a new Address from an answer-packet
460  */
461 void
462 new_ip6addr_remote (struct in6_addr *v6addr,
463                     unsigned char *addr, char addrlen)
464 {                               /* {{{ */
465   unsigned char *buf = (unsigned char*) v6addr;
466   char *ipv6addr;
467   unsigned long long ipv6prefix;
468
469   GNUNET_assert (GNUNET_OK ==
470                  GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR",
471                                                         &ipv6addr));
472   GNUNET_assert (GNUNET_OK ==
473                  GNUNET_CONFIGURATION_get_value_number (cfg, "vpn",
474                                                         "IPV6PREFIX",
475                                                         &ipv6prefix));
476   GNUNET_assert (ipv6prefix < 127);
477   ipv6prefix = (ipv6prefix + 7) / 8;
478
479   inet_pton (AF_INET6, ipv6addr, buf);
480   GNUNET_free (ipv6addr);
481
482   int local_length = 16 - ipv6prefix;
483
484   memcpy (buf + ipv6prefix, addr, GNUNET_MIN (addrlen, local_length));
485 }
486
487 /*}}}*/
488
489 /**
490  * Create a new Address from an answer-packet
491  */
492 void
493 new_ip4addr_remote (unsigned char *buf, unsigned char *addr, char addrlen)
494 {                               /* {{{ */
495   char *ipv4addr;
496   char *ipv4mask;
497
498   GNUNET_assert (GNUNET_OK ==
499                  GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4ADDR",
500                                                         &ipv4addr));
501   GNUNET_assert (GNUNET_OK ==
502                  GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4MASK",
503                                                         &ipv4mask));
504   uint32_t mask;
505
506   inet_pton (AF_INET, ipv4addr, buf);
507   int r = inet_pton (AF_INET, ipv4mask, &mask);
508
509   mask = htonl (mask);
510   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "inet_pton: %d; %m; mask: %08x\n", r,
511               mask);
512
513   GNUNET_free (ipv4addr);
514
515   int c;
516
517   if (mask)
518   {
519     mask = (mask ^ (mask - 1)) >> 1;
520     for (c = 0; mask; c++)
521     {
522       mask >>= 1;
523     }
524   }
525   else
526   {
527     c = CHAR_BIT * sizeof (mask);
528   }
529
530   c = 32 - c;
531   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "The mask %s has %d leading 1s.\n",
532               ipv4mask, c);
533
534   GNUNET_free (ipv4mask);
535
536   if (c % 8 == 0)
537     c = c / 8;
538   else
539     GNUNET_assert (0);
540
541   memcpy (buf + c, addr, GNUNET_MIN (addrlen, 4 - c));
542 }
543
544 /*}}}*/
545
546 /**
547  * This gets scheduled with cls pointing to an answer_packet and does everything
548  * needed in order to send it to the helper.
549  *
550  * At the moment this means "inventing" and IPv6-Address for .gnunet-services and
551  * doing nothing for "real" services.
552  */
553 void
554 process_answer (void *cls, 
555                 const struct answer_packet *pkt)
556 {
557   struct answer_packet_list *list;
558
559   /* This answer is about a .gnunet-service
560    *
561    * It contains an almost complete DNS-Response, we have to fill in the ip
562    * at the offset pkt->addroffset
563    */
564   if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_SERVICE)
565   {
566
567     GNUNET_HashCode key;
568
569     memset (&key, 0, sizeof (GNUNET_HashCode));
570
571     list =
572         GNUNET_malloc (htons (pkt->hdr.size) +
573                        sizeof (struct answer_packet_list) -
574                        sizeof (struct answer_packet));
575     memcpy (&list->pkt, pkt, htons (pkt->hdr.size));
576
577     unsigned char *c = ((unsigned char *) &list->pkt) + ntohs (pkt->addroffset);
578     unsigned char *k = (unsigned char *) &key;
579
580     new_ip6addr ((struct in6_addr*) c, 
581                  &pkt->service_descr.peer,
582                  &pkt->service_descr.service_descriptor);
583     /*
584      * Copy the newly generated ip-address to the key backwarts (as only the first part is hashed)
585      */
586     unsigned int i;
587
588     for (i = 0; i < 16; i++)
589       k[15 - i] = c[i];
590
591     uint16_t namelen = strlen ((char *) pkt->data + 12) + 1;
592
593     struct map_entry *value =
594         GNUNET_malloc (sizeof (struct map_entry) + namelen);
595     char *name = (char *) (value + 1);
596
597     value->namelen = namelen;
598     memcpy (name, pkt->data + 12, namelen);
599
600     memcpy (&value->desc, &pkt->service_descr,
601             sizeof (struct GNUNET_vpn_service_descriptor));
602
603     memset (value->additional_ports, 0, 8192);
604
605     memcpy (&value->hash, &key, sizeof (GNUNET_HashCode));
606
607     if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (hashmap, &key))
608     {
609       GNUNET_CONTAINER_multihashmap_put (hashmap, &key, value,
610                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
611
612       value->heap_node =
613           GNUNET_CONTAINER_heap_insert (heap, value,
614                                         GNUNET_TIME_absolute_get ().abs_value);
615       if (GNUNET_CONTAINER_heap_get_size (heap) > max_mappings)
616         GNUNET_SCHEDULER_add_now (collect_mappings, NULL);
617     }
618     else
619       GNUNET_free (value);
620
621
622     list->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_IP;
623
624
625   }
626   else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REV)
627   {
628     GNUNET_HashCode key;
629
630     memset (&key, 0, sizeof key);
631     unsigned char *k = (unsigned char *) &key;
632     const unsigned char *s = pkt->data + 12;
633     int i = 0;
634
635     /* Whoever designed the reverse IPv6-lookup is batshit insane */
636     for (i = 0; i < 16; i++)
637     {
638       unsigned char c1 = s[(4 * i) + 1];
639       unsigned char c2 = s[(4 * i) + 3];
640
641       if (c1 <= '9')
642         k[i] = c1 - '0';
643       else
644         k[i] = c1 - 87;         /* 87 is the difference between 'a' and 10 */
645       if (c2 <= '9')
646         k[i] += 16 * (c2 - '0');
647       else
648         k[i] += 16 * (c2 - 87);
649     }
650
651     struct map_entry *map_entry =
652         GNUNET_CONTAINER_multihashmap_get (hashmap, &key);
653     uint16_t offset = ntohs (pkt->addroffset);
654
655     if (map_entry == NULL)
656       return;
657
658     GNUNET_CONTAINER_heap_update_cost (heap, map_entry->heap_node,
659                                        GNUNET_TIME_absolute_get ().abs_value);
660
661
662     unsigned short namelen = htons (map_entry->namelen);
663     char *name = (char *) (map_entry + 1);
664
665     list =
666         GNUNET_malloc (sizeof (struct answer_packet_list) -
667                        sizeof (struct answer_packet) + offset + 2 +
668                        ntohs (namelen));
669
670     struct answer_packet *rpkt = &list->pkt;
671
672     /* The offset points to the first byte belonging to the address */
673     memcpy (rpkt, pkt, offset - 1);
674
675     rpkt->subtype = GNUNET_DNS_ANSWER_TYPE_IP;
676     rpkt->hdr.size = ntohs (offset + 2 + ntohs (namelen));
677
678     memcpy (((char *) rpkt) + offset, &namelen, 2);
679     memcpy (((char *) rpkt) + offset + 2, name, ntohs (namelen));
680
681   }
682   else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_IP)
683   {
684     list =
685         GNUNET_malloc (htons (pkt->hdr.size) +
686                        sizeof (struct answer_packet_list) -
687                        sizeof (struct answer_packet));
688     memcpy (&list->pkt, pkt, htons (pkt->hdr.size));
689   }
690   else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REMOTE_AAAA)
691   {
692
693     GNUNET_HashCode key;
694
695     memset (&key, 0, sizeof (GNUNET_HashCode));
696
697     list =
698         GNUNET_malloc (htons (pkt->hdr.size) +
699                        sizeof (struct answer_packet_list) -
700                        sizeof (struct answer_packet));
701
702     memcpy (&list->pkt, pkt, htons (pkt->hdr.size));
703     list->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_IP;
704
705     unsigned char *c = ((unsigned char *) &list->pkt) + ntohs (list->pkt.addroffset);
706
707     new_ip6addr_remote ((struct in6_addr*) c,
708                         list->pkt.addr, list->pkt.addrsize);
709     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
710                 "New mapping to %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
711                 c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8], c[9],
712                 c[10], c[11], c[12], c[13], c[14], c[15]);
713     unsigned char *k = (unsigned char *) &key;
714
715     /*
716      * Copy the newly generated ip-address to the key backwards (as only the first part is used in the hash-table)
717      */
718     unsigned int i;
719
720     for (i = 0; i < 16; i++)
721       k[15 - i] = c[i];
722
723     uint16_t namelen = strlen ((char *) pkt->data + 12) + 1;
724
725     struct map_entry *value =
726         GNUNET_malloc (sizeof (struct map_entry) + namelen);
727     char *name = (char *) (value + 1);
728
729     value->namelen = namelen;
730     memcpy (name, pkt->data + 12, namelen);
731
732     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting addrlen to %d\n",
733                 pkt->addrsize);
734     value->addrlen = pkt->addrsize;
735     memcpy (&value->addr, &pkt->addr, pkt->addrsize);
736     memset (value->additional_ports, 0, 8192);
737
738     memcpy (&value->hash, &key, sizeof (GNUNET_HashCode));
739
740     if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (hashmap, &key))
741     {
742       GNUNET_CONTAINER_multihashmap_put (hashmap, &key, value,
743                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
744       value->heap_node =
745           GNUNET_CONTAINER_heap_insert (heap, value,
746                                         GNUNET_TIME_absolute_get ().abs_value);
747       if (GNUNET_CONTAINER_heap_get_size (heap) > max_mappings)
748         GNUNET_SCHEDULER_add_now (collect_mappings, NULL);
749     }
750     else
751       GNUNET_free (value);
752
753
754   }
755   else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REMOTE_A)
756   {
757     list =
758         GNUNET_malloc (htons (pkt->hdr.size) +
759                        sizeof (struct answer_packet_list) -
760                        sizeof (struct answer_packet));
761
762     memcpy (&list->pkt, pkt, htons (pkt->hdr.size));
763     list->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_IP;
764
765     GNUNET_HashCode key;
766
767     memset (&key, 0, sizeof (GNUNET_HashCode));
768
769     unsigned char *c = ((unsigned char *) &list->pkt) + ntohs (pkt->addroffset);
770
771     new_ip4addr_remote (c, list->pkt.addr, pkt->addrsize);
772     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New mapping to %d.%d.%d.%d\n", c[0],
773                 c[1], c[2], c[3]);
774     unsigned char *k = (unsigned char *) &key;
775
776     /*
777      * Copy the newly generated ip-address to the key backwards (as only the first part is used in the hash-table)
778      */
779     unsigned int i;
780
781     for (i = 0; i < 4; i++)
782       k[3 - i] = c[i];
783
784     uint16_t namelen = strlen ((char *) pkt->data + 12) + 1;
785
786     struct map_entry *value =
787         GNUNET_malloc (sizeof (struct map_entry) + namelen);
788     char *name = (char *) (value + 1);
789
790     value->namelen = namelen;
791     memcpy (name, pkt->data + 12, namelen);
792
793     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting addrlen to %d\n",
794                 pkt->addrsize);
795     value->addrlen = pkt->addrsize;
796     memcpy (&value->addr, &pkt->addr, pkt->addrsize);
797     memset (value->additional_ports, 0, 8192);
798
799     memcpy (&value->hash, &key, sizeof (GNUNET_HashCode));
800
801     if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (hashmap, &key))
802     {
803       GNUNET_CONTAINER_multihashmap_put (hashmap, &key, value,
804                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
805       value->heap_node =
806           GNUNET_CONTAINER_heap_insert (heap, value,
807                                         GNUNET_TIME_absolute_get ().abs_value);
808       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
809                   "Mapping is saved in the hashmap with key %08x.\n",
810                   *((uint32_t *) (&key)));
811       if (GNUNET_CONTAINER_heap_get_size (heap) > max_mappings)
812         GNUNET_SCHEDULER_add_now (collect_mappings, NULL);
813     }
814     else
815       GNUNET_free (value);
816
817   }
818   else
819   {
820     GNUNET_break (0);
821     return;
822   }
823
824   GNUNET_CONTAINER_DLL_insert_after (answer_proc_head, answer_proc_tail,
825                                      answer_proc_tail, list);
826
827   schedule_helper_write (GNUNET_TIME_UNIT_FOREVER_REL, NULL);
828
829   return;
830 }
831
832
833 /**
834  * @brief Add the port to the list of additional ports in the map_entry
835  *
836  * @param me the map_entry
837  * @param port the port in host-byte-order
838  */
839 static void
840 add_additional_port (struct map_entry *me, uint16_t port)
841 {
842   setBit (me->additional_ports, port);
843 }
844
845 static int
846 receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
847                   void **tunnel_ctx, const struct GNUNET_PeerIdentity *sender,
848                   const struct GNUNET_MessageHeader *message,
849                   const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
850 {
851   GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1);
852   struct remote_addr *s = (struct remote_addr *) desc;
853   struct udp_pkt *pkt = (struct udp_pkt *) (desc + 1);
854   const struct GNUNET_PeerIdentity *other = sender;
855   struct tunnel_state *ts = *tunnel_ctx;
856
857   if (16 == ts->addrlen)
858   {
859     size_t size =
860         sizeof (struct ip6_udp) + ntohs (pkt->len) - 1 -
861         sizeof (struct udp_pkt);
862
863     struct ip6_udp *pkt6 = alloca (size);
864
865     GNUNET_assert (pkt6 != NULL);
866
867     if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK)
868       new_ip6addr (&pkt6->ip6_hdr.sadr, &other->hashPubKey, desc);
869     else
870       new_ip6addr_remote (&pkt6->ip6_hdr.sadr, s->addr, s->addrlen);
871
872     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
873                 "Relaying calc:%d gnu:%d udp:%d bytes!\n", size,
874                 ntohs (message->size), ntohs (pkt->len));
875
876     pkt6->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
877     pkt6->shdr.size = htons (size);
878
879     pkt6->tun.flags = 0;
880     pkt6->tun.type = htons (0x86dd);
881
882     pkt6->ip6_hdr.version = 6;
883     pkt6->ip6_hdr.tclass_h = 0;
884     pkt6->ip6_hdr.tclass_l = 0;
885     pkt6->ip6_hdr.flowlbl = 0;
886     pkt6->ip6_hdr.paylgth = pkt->len;
887     pkt6->ip6_hdr.nxthdr = IPPROTO_UDP;
888     pkt6->ip6_hdr.hoplmt = 0xff;
889
890     {
891       char *ipv6addr;
892
893       GNUNET_assert (GNUNET_OK ==
894                      GNUNET_CONFIGURATION_get_value_string (cfg, "vpn",
895                                                             "IPV6ADDR",
896                                                             &ipv6addr));
897       inet_pton (AF_INET6, ipv6addr, &pkt6->ip6_hdr.dadr);
898       GNUNET_free (ipv6addr);
899     }
900     memcpy (&pkt6->udp_hdr, pkt, ntohs (pkt->len));
901
902     GNUNET_HashCode *key = address6_mapping_exists (&pkt6->ip6_hdr.sadr);
903
904     GNUNET_assert (key != NULL);
905
906     struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
907
908     GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node,
909                                        GNUNET_TIME_absolute_get ().abs_value);
910
911     GNUNET_free (key);
912
913     GNUNET_assert (me != NULL);
914     if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK)
915     {
916       GNUNET_assert (me->desc.
917                      service_type & htonl (GNUNET_DNS_SERVICE_TYPE_UDP));
918       if (!port_in_ports (me->desc.ports, pkt6->udp_hdr.spt) &&
919           !testBit (me->additional_ports, ntohs (pkt6->udp_hdr.spt)))
920       {
921         add_additional_port (me, ntohs (pkt6->udp_hdr.spt));
922       }
923     }
924
925     pkt6->udp_hdr.crc = 0;
926     uint32_t sum = 0;
927
928     sum =
929         calculate_checksum_update (sum, (uint16_t *) & pkt6->ip6_hdr.sadr, 16);
930     sum =
931         calculate_checksum_update (sum, (uint16_t *) & pkt6->ip6_hdr.dadr, 16);
932     uint32_t tmp = (pkt6->udp_hdr.len & 0xffff);
933
934     sum = calculate_checksum_update (sum, (uint16_t *) & tmp, 4);
935     tmp = htons (((pkt6->ip6_hdr.nxthdr & 0x00ff)));
936     sum = calculate_checksum_update (sum, (uint16_t *) & tmp, 4);
937
938     sum =
939         calculate_checksum_update (sum, (uint16_t *) & pkt6->udp_hdr,
940                                    ntohs (pkt->len));
941     pkt6->udp_hdr.crc = calculate_checksum_end (sum);
942
943     write_to_helper (pkt6, size);
944   }
945   else
946   {
947     size_t size =
948         sizeof (struct ip_udp) + ntohs (pkt->len) - 1 - sizeof (struct udp_pkt);
949
950     struct ip_udp *pkt4 = alloca (size);
951
952     GNUNET_assert (pkt4 != NULL);
953
954     GNUNET_assert (ntohs (message->type) ==
955                    GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP_BACK);
956     uint32_t sadr;
957
958     new_ip4addr_remote ((unsigned char *) &sadr, s->addr, s->addrlen);
959     pkt4->ip_hdr.sadr.s_addr = sadr;
960
961     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
962                 "Relaying calc:%d gnu:%d udp:%d bytes!\n", size,
963                 ntohs (message->size), ntohs (pkt->len));
964
965     pkt4->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
966     pkt4->shdr.size = htons (size);
967
968     pkt4->tun.flags = 0;
969     pkt4->tun.type = htons (0x0800);
970
971     pkt4->ip_hdr.version = 4;
972     pkt4->ip_hdr.hdr_lngth = 5;
973     pkt4->ip_hdr.diff_serv = 0;
974     pkt4->ip_hdr.tot_lngth = htons (20 + ntohs (pkt->len));
975     pkt4->ip_hdr.ident = 0;
976     pkt4->ip_hdr.flags = 0;
977     pkt4->ip_hdr.frag_off = 0;
978     pkt4->ip_hdr.ttl = 255;
979     pkt4->ip_hdr.proto = IPPROTO_UDP;
980     pkt4->ip_hdr.chks = 0;      /* Will be calculated later */
981
982     {
983       char *ipv4addr;
984       uint32_t dadr;
985
986       GNUNET_assert (GNUNET_OK ==
987                      GNUNET_CONFIGURATION_get_value_string (cfg, "vpn",
988                                                             "IPV4ADDR",
989                                                             &ipv4addr));
990       inet_pton (AF_INET, ipv4addr, &dadr);
991       GNUNET_free (ipv4addr);
992       pkt4->ip_hdr.dadr.s_addr = dadr;
993     }
994     memcpy (&pkt4->udp_hdr, pkt, ntohs (pkt->len));
995
996     GNUNET_HashCode *key = address4_mapping_exists (pkt4->ip_hdr.sadr.s_addr);
997
998     GNUNET_assert (key != NULL);
999
1000     struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
1001
1002     GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node,
1003                                        GNUNET_TIME_absolute_get ().abs_value);
1004
1005     GNUNET_free (key);
1006
1007     GNUNET_assert (me != NULL);
1008
1009     pkt4->udp_hdr.crc = 0;      /* Optional for IPv4 */
1010
1011     pkt4->ip_hdr.chks =
1012         calculate_ip_checksum ((uint16_t *) & pkt4->ip_hdr, 5 * 4);
1013
1014     write_to_helper (pkt4, size);
1015   }
1016
1017   return GNUNET_OK;
1018 }
1019
1020 static int
1021 receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1022                   void **tunnel_ctx,
1023                   const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1024                   const struct GNUNET_MessageHeader *message,
1025                   const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1026 {
1027   GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1);
1028   struct remote_addr *s = (struct remote_addr *) desc;
1029   struct tcp_pkt *pkt = (struct tcp_pkt *) (desc + 1);
1030   const struct GNUNET_PeerIdentity *other = sender;
1031   struct tunnel_state *ts = *tunnel_ctx;
1032
1033   size_t pktlen =
1034       ntohs (message->size) - sizeof (struct GNUNET_MessageHeader) -
1035       sizeof (GNUNET_HashCode);
1036
1037   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1038               "Received TCP-Packet back, addrlen = %d\n", s->addrlen);
1039
1040   if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP_BACK ||
1041       ts->addrlen == 16)
1042   {
1043     size_t size = pktlen + sizeof (struct ip6_tcp) - 1;
1044
1045     struct ip6_tcp *pkt6 = alloca (size);
1046
1047     memset (pkt6, 0, size);
1048
1049     GNUNET_assert (pkt6 != NULL);
1050
1051     if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP_BACK)
1052       new_ip6addr (&pkt6->ip6_hdr.sadr, &other->hashPubKey, desc);
1053     else
1054       new_ip6addr_remote (&pkt6->ip6_hdr.sadr, s->addr, s->addrlen);
1055
1056     pkt6->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1057     pkt6->shdr.size = htons (size);
1058
1059     pkt6->tun.flags = 0;
1060     pkt6->tun.type = htons (0x86dd);
1061
1062     pkt6->ip6_hdr.version = 6;
1063     pkt6->ip6_hdr.tclass_h = 0;
1064     pkt6->ip6_hdr.tclass_l = 0;
1065     pkt6->ip6_hdr.flowlbl = 0;
1066     pkt6->ip6_hdr.paylgth = htons (pktlen);
1067     pkt6->ip6_hdr.nxthdr = IPPROTO_TCP;
1068     pkt6->ip6_hdr.hoplmt = 0xff;
1069
1070     {
1071       char *ipv6addr;
1072
1073       GNUNET_assert (GNUNET_OK ==
1074                      GNUNET_CONFIGURATION_get_value_string (cfg, "vpn",
1075                                                             "IPV6ADDR",
1076                                                             &ipv6addr));
1077       inet_pton (AF_INET6, ipv6addr, &pkt6->ip6_hdr.dadr);
1078       GNUNET_free (ipv6addr);
1079     }
1080     memcpy (&pkt6->tcp_hdr, pkt, pktlen);
1081
1082     GNUNET_HashCode *key = address6_mapping_exists (&pkt6->ip6_hdr.sadr);
1083
1084     GNUNET_assert (key != NULL);
1085
1086     struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
1087
1088     GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node,
1089                                        GNUNET_TIME_absolute_get ().abs_value);
1090
1091     GNUNET_free (key);
1092
1093     GNUNET_assert (me != NULL);
1094     if (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK)
1095       GNUNET_assert (me->desc.
1096                      service_type & htonl (GNUNET_DNS_SERVICE_TYPE_TCP));
1097
1098     pkt6->tcp_hdr.crc = 0;
1099     uint32_t sum = 0;
1100     uint32_t tmp;
1101
1102     sum =
1103         calculate_checksum_update (sum, (uint16_t *) & pkt6->ip6_hdr.sadr, 16);
1104     sum =
1105         calculate_checksum_update (sum, (uint16_t *) & pkt6->ip6_hdr.dadr, 16);
1106     tmp = htonl (pktlen);
1107     sum = calculate_checksum_update (sum, (uint16_t *) & tmp, 4);
1108     tmp = htonl (((pkt6->ip6_hdr.nxthdr & 0x000000ff)));
1109     sum = calculate_checksum_update (sum, (uint16_t *) & tmp, 4);
1110
1111     sum =
1112         calculate_checksum_update (sum, (uint16_t *) & pkt6->tcp_hdr,
1113                                    ntohs (pkt6->ip6_hdr.paylgth));
1114     pkt6->tcp_hdr.crc = calculate_checksum_end (sum);
1115
1116     write_to_helper (pkt6, size);
1117   }
1118   else
1119   {
1120     size_t size = pktlen + sizeof (struct ip_tcp) - 1;
1121
1122     struct ip_tcp *pkt4 = alloca (size);
1123
1124     GNUNET_assert (pkt4 != NULL);
1125     memset (pkt4, 0, size);
1126
1127     GNUNET_assert (ntohs (message->type) ==
1128                    GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP_BACK);
1129     uint32_t sadr;
1130
1131     new_ip4addr_remote ((unsigned char *) &sadr, s->addr, s->addrlen);
1132     pkt4->ip_hdr.sadr.s_addr = sadr;
1133
1134     pkt4->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1135     pkt4->shdr.size = htons (size);
1136
1137     pkt4->tun.flags = 0;
1138     pkt4->tun.type = htons (0x0800);
1139
1140     pkt4->ip_hdr.version = 4;
1141     pkt4->ip_hdr.hdr_lngth = 5;
1142     pkt4->ip_hdr.diff_serv = 0;
1143     pkt4->ip_hdr.tot_lngth = htons (20 + pktlen);
1144     pkt4->ip_hdr.ident = 0;
1145     pkt4->ip_hdr.flags = 0;
1146     pkt4->ip_hdr.frag_off = 0;
1147     pkt4->ip_hdr.ttl = 255;
1148     pkt4->ip_hdr.proto = IPPROTO_TCP;
1149     pkt4->ip_hdr.chks = 0;      /* Will be calculated later */
1150
1151     {
1152       char *ipv4addr;
1153       uint32_t dadr;
1154
1155       GNUNET_assert (GNUNET_OK ==
1156                      GNUNET_CONFIGURATION_get_value_string (cfg, "vpn",
1157                                                             "IPV4ADDR",
1158                                                             &ipv4addr));
1159       inet_pton (AF_INET, ipv4addr, &dadr);
1160       GNUNET_free (ipv4addr);
1161       pkt4->ip_hdr.dadr.s_addr = dadr;
1162     }
1163
1164     memcpy (&pkt4->tcp_hdr, pkt, pktlen);
1165
1166     GNUNET_HashCode *key = address4_mapping_exists (pkt4->ip_hdr.sadr.s_addr);
1167
1168     GNUNET_assert (key != NULL);
1169
1170     struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
1171
1172     GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node,
1173                                        GNUNET_TIME_absolute_get ().abs_value);
1174
1175     GNUNET_free (key);
1176
1177     GNUNET_assert (me != NULL);
1178     pkt4->tcp_hdr.crc = 0;
1179     uint32_t sum = 0;
1180     uint32_t tmp;
1181
1182     sum = calculate_checksum_update (sum, (uint16_t *) &pkt4->ip_hdr.sadr, 4);
1183     sum = calculate_checksum_update (sum, (uint16_t *) &pkt4->ip_hdr.dadr, 4);
1184
1185     tmp = (0x06 << 16) | (0xffff & pktlen);     // 0x06 for TCP?
1186
1187     tmp = htonl (tmp);
1188
1189     sum = calculate_checksum_update (sum, (uint16_t *) & tmp, 4);
1190
1191     sum = calculate_checksum_update (sum, (uint16_t *) & pkt4->tcp_hdr, pktlen);
1192     pkt4->tcp_hdr.crc = calculate_checksum_end (sum);
1193
1194     pkt4->ip_hdr.chks =
1195         calculate_ip_checksum ((uint16_t *) & pkt4->ip_hdr, 5 * 4);
1196
1197     write_to_helper (pkt4, size);
1198   }
1199
1200   return GNUNET_OK;
1201 }
1202
1203 static void *
1204 new_tunnel (void *cls, struct GNUNET_MESH_Tunnel *tunnel,
1205             const struct GNUNET_PeerIdentity *initiator,
1206             const struct GNUNET_ATS_Information *atsi)
1207 {
1208   /* Why should anyone open an inbound tunnel to vpn? */
1209   GNUNET_break (0);
1210   return NULL;
1211 }
1212
1213 static void
1214 cleaner (void *cls, const struct GNUNET_MESH_Tunnel *tunnel, void *tunnel_ctx)
1215 {
1216   /* Why should anyone open an inbound tunnel to vpn? */
1217   GNUNET_break (0);
1218 }
1219
1220 /**
1221  * Main function that will be run by the scheduler.
1222  *
1223  * @param cls closure
1224  * @param args remaining command-line arguments
1225  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
1226  * @param cfg_ configuration
1227  */
1228 static void
1229 run (void *cls, char *const *args GNUNET_UNUSED,
1230      const char *cfgfile GNUNET_UNUSED,
1231      const struct GNUNET_CONFIGURATION_Handle *cfg_)
1232 {
1233   static const struct GNUNET_MESH_MessageHandler handlers[] = {
1234     {receive_udp_back, GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK, 0},
1235     {receive_tcp_back, GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP_BACK, 0},
1236     {receive_udp_back, GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP_BACK, 0},
1237     {receive_tcp_back, GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP_BACK, 0},
1238     {NULL, 0, 0}
1239   };
1240
1241   static const GNUNET_MESH_ApplicationType types[] = {
1242     GNUNET_APPLICATION_TYPE_END
1243   };
1244
1245   mesh_handle =
1246       GNUNET_MESH_connect (cfg_, 42, NULL, new_tunnel, cleaner, handlers,
1247                            types);
1248   cfg = cfg_;
1249   hashmap = GNUNET_CONTAINER_multihashmap_create (65536);
1250   heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
1251   GNUNET_CONFIGURATION_get_value_number (cfg, "vpn", "MAX_MAPPINGg",
1252                                          &max_mappings);
1253   udp_connections = GNUNET_CONTAINER_multihashmap_create (65536);
1254   dns_handle = GNUNET_DNS_connect (cfg,
1255                                    &process_answer,
1256                                    NULL);
1257   shs_task =
1258       GNUNET_SCHEDULER_add_after (conn_task, start_helper_and_schedule, NULL);
1259   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls);
1260 }
1261
1262 /**
1263  * The main function to obtain template from gnunetd.
1264  *
1265  * @param argc number of arguments from the command line
1266  * @param argv command line arguments
1267  * @return 0 ok, 1 on error
1268  */
1269 int
1270 main (int argc, char *const *argv)
1271 {
1272   static const struct GNUNET_GETOPT_CommandLineOption options[] = {
1273     GNUNET_GETOPT_OPTION_END
1274   };
1275
1276   return (GNUNET_OK ==
1277           GNUNET_PROGRAM_run (argc, argv, "vpn", gettext_noop ("help text"),
1278                               options, &run, NULL)) ? ret : 1;
1279 }
1280
1281 /* end of gnunet-daemon-vpn.c */