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