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