fix compile errors
[oweals/gnunet.git] / src / vpn / gnunet-service-vpn.c
1 /*
2      This file is part of GNUnet.
3      (C) 2010, 2011, 2012 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-service-vpn.c
23  * @brief service that opens a virtual interface and allows its clients
24  *        to allocate IPs on the virtual interface and to then redirect
25  *        IP traffic received on those IPs via the GNUnet mesh 
26  * @author Philipp Toelke
27  * @author Christian Grothoff
28  *
29  * TODO:
30  * - create secondary mesh tunnels if needed / check overall tunnel creation/management code!
31  * => test!
32  * - better message queue management (bounded state, drop oldest/RED?)
33  * - improve support for deciding which tunnels to keep and which ones to destroy
34  * - add back ICMP support (especially needed for IPv6)
35  * - consider moving IP-header building / checksumming code into shared library
36  *   with dns/exit/vpn (libgnunettun_tcpip?)
37  */
38 #include "platform.h"
39 #include "gnunet_util_lib.h"
40 #include "gnunet_common.h"
41 #include "gnunet_protocols.h"
42 #include "gnunet_applications.h"
43 #include "gnunet_mesh_service.h"
44 #include "gnunet_constants.h"
45 #include "tcpip_tun.h"
46 #include "vpn.h"
47 #include "exit.h"
48
49 /**
50  * Information we track for each IP address to determine which tunnel
51  * to send the traffic over to the destination.
52  */
53 struct DestinationEntry
54 {
55   /**
56    * Information about the tunnel to use, NULL if no tunnel
57    * is available right now.
58    */
59   struct GNUNET_MESH_Tunnel *tunnel;
60
61   /**
62    * Entry for this entry in the destination_heap.
63    */
64   struct GNUNET_CONTAINER_HeapNode *heap_node;
65
66   /**
67    * GNUNET_NO if this is a tunnel to an Internet-exit,
68    * GNUNET_YES if this tunnel is to a service.
69    */
70   int is_service;
71
72   /**
73    * Details about the connection (depending on is_service).
74    */
75   union
76   {
77
78     struct
79     {
80       /**
81        * The description of the service (only used for service tunnels).
82        */
83       GNUNET_HashCode service_descriptor;
84
85       /**
86        * Peer offering the service.
87        */
88       struct GNUNET_PeerIdentity target;
89
90     } service_destination;
91
92     struct 
93     {
94   
95       /**
96        * Address family used (AF_INET or AF_INET6).
97        */
98       int af;
99       
100       /**
101        * IP address of the ultimate destination (only used for exit tunnels).
102        */
103       union
104       {
105         /**
106          * Address if af is AF_INET.
107          */
108         struct in_addr v4;
109         
110         /**
111          * Address if af is AF_INET6.
112          */
113         struct in6_addr v6;
114       } ip;
115
116     } exit_destination;
117
118   } details;
119     
120 };
121
122
123 /**
124  * A messages we have in queue for a particular tunnel.
125  */
126 struct TunnelMessageQueueEntry
127 {
128   /**
129    * This is a doubly-linked list.
130    */
131   struct TunnelMessageQueueEntry *next;
132
133   /**
134    * This is a doubly-linked list.
135    */
136   struct TunnelMessageQueueEntry *prev;
137   
138   /**
139    * Number of bytes in 'msg'.
140    */
141   size_t len;
142
143   /**
144    * Message to transmit, allocated at the end of this struct.
145    */
146   const void *msg;
147 };
148
149
150 /**
151  * State we keep for each of our tunnels.
152  */
153 struct TunnelState
154 {
155   /**
156    * Active transmission handle, NULL for none.
157    */
158   struct GNUNET_MESH_TransmitHandle *th;
159
160   /**
161    * Entry for this entry in the tunnel_heap, NULL as long as this
162    * tunnel state is not fully bound.
163    */
164   struct GNUNET_CONTAINER_HeapNode *heap_node;
165
166   /**
167    * Head of list of messages scheduled for transmission.
168    */
169   struct TunnelMessageQueueEntry *head;
170
171   /**
172    * Tail of list of messages scheduled for transmission.
173    */
174   struct TunnelMessageQueueEntry *tail;
175
176   /**
177    * Client that needs to be notified about the tunnel being
178    * up as soon as a peer is connected; NULL for none.
179    */
180   struct GNUNET_SERVER_Client *client;
181
182   /**
183    * ID of the client request that caused us to setup this entry.
184    */ 
185   uint64_t request_id;
186
187   /**
188    * Destination to which this tunnel leads.  Note that
189    * this struct is NOT in the destination_map (but a
190    * local copy) and that the 'heap_node' should always
191    * be NULL.
192    */
193   struct DestinationEntry destination;
194
195   /**
196    * GNUNET_NO if this is a tunnel to an Internet-exit,
197    * GNUNET_YES if this tunnel is to a service.
198    */
199   int is_service;
200
201   /**
202    * Addess family used for this tunnel on the local TUN interface.
203    */
204   int af;
205
206   /**
207    * IP address of the source on our end, initially uninitialized.
208    */
209   union
210   {
211     /**
212      * Address if af is AF_INET.
213      */
214     struct in_addr v4;
215     
216     /**
217      * Address if af is AF_INET6.
218      */
219     struct in6_addr v6;
220
221   } source_ip;
222
223   /**
224    * Destination IP address used by the source on our end (this is the IP
225    * that we pick freely within the VPN's tunnel IP range).
226    */
227   union
228   {
229     /**
230      * Address if af is AF_INET.
231      */
232     struct in_addr v4;
233     
234     /**
235      * Address if af is AF_INET6.
236      */
237     struct in6_addr v6;
238
239   } destination_ip;
240
241   /**
242    * Source port used by the sender on our end; 0 for uninitialized.
243    */
244   uint16_t source_port;
245
246   /**
247    * Destination port used by the sender on our end; 0 for uninitialized.
248    */
249   uint16_t destination_port;
250
251 };
252
253
254 /**
255  * Configuration we use.
256  */
257 static const struct GNUNET_CONFIGURATION_Handle *cfg;
258
259 /**
260  * Handle to the mesh service.
261  */
262 static struct GNUNET_MESH_Handle *mesh_handle;
263
264 /**
265  * Map from IP address to destination information (possibly with a
266  * MESH tunnel handle for fast setup).
267  */
268 static struct GNUNET_CONTAINER_MultiHashMap *destination_map;
269
270 /**
271  * Min-Heap sorted by activity time to expire old mappings.
272  */
273 static struct GNUNET_CONTAINER_Heap *destination_heap;
274
275 /**
276  * Map from source and destination address (IP+port) to connection
277  * information (mostly with the respective MESH tunnel handle).
278  */
279 static struct GNUNET_CONTAINER_MultiHashMap *tunnel_map;
280
281 /**
282  * Min-Heap sorted by activity time to expire old mappings.
283  */
284 static struct GNUNET_CONTAINER_Heap *tunnel_heap;
285
286 /**
287  * The handle to the VPN helper process "gnunet-helper-vpn".
288  */
289 static struct GNUNET_HELPER_Handle *helper_handle;
290
291 /**
292  * Arguments to the vpn helper.
293  */
294 static char *vpn_argv[7];
295
296 /**
297  * Length of the prefix of the VPN's IPv6 network.
298  */
299 static unsigned long long ipv6prefix;
300
301 /**
302  * Notification context for sending replies to clients.
303  */
304 static struct GNUNET_SERVER_NotificationContext *nc;
305
306 /**
307  * If there are more than this number of address-mappings, old ones
308  * will be removed
309  */
310 static unsigned long long max_destination_mappings;
311
312 /**
313  * If there are more than this number of open tunnels, old ones
314  * will be removed
315  */
316 static unsigned long long max_tunnel_mappings;
317
318
319 /**
320  * Compute the key under which we would store an entry in the
321  * destination_map for the given IP address.
322  *
323  * @param af address family (AF_INET or AF_INET6)
324  * @param address IP address, struct in_addr or struct in6_addr
325  * @param key where to store the key
326  */
327 static void
328 get_destination_key_from_ip (int af,
329                              const void *address,
330                              GNUNET_HashCode *key)
331 {
332   switch (af)
333   {
334   case AF_INET:
335     GNUNET_CRYPTO_hash (address,
336                         sizeof (struct in_addr),
337                         key);
338     break;
339   case AF_INET6:
340     GNUNET_CRYPTO_hash (address,
341                         sizeof (struct in6_addr),
342                         key);
343     break;
344   default:
345     GNUNET_assert (0);
346     break;
347   }
348 }
349
350
351 /**
352  * Compute the key under which we would store an entry in the
353  * tunnel_map for the given socket address pair.
354  *
355  * @param af address family (AF_INET or AF_INET6)
356  * @param protocol IPPROTO_TCP or IPPROTO_UDP
357  * @param source_ip sender's source IP, struct in_addr or struct in6_addr
358  * @param source_port sender's source port
359  * @param destination_ip sender's destination IP, struct in_addr or struct in6_addr
360  * @param destination_port sender's destination port
361  * @param key where to store the key
362  */
363 static void
364 get_tunnel_key_from_ips (int af,
365                          uint8_t protocol,
366                          const void *source_ip,
367                          uint16_t source_port,
368                          const void *destination_ip,
369                          uint16_t destination_port,
370                          GNUNET_HashCode *key)
371 {
372   char *off;
373
374   memset (key, 0, sizeof (GNUNET_HashCode));
375   /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
376      so we put the ports in there (and hope for few collisions) */
377   off = (char*) key;
378   memcpy (off, &source_port, sizeof (uint16_t));
379   off += sizeof (uint16_t);
380   memcpy (off, &destination_port, sizeof (uint16_t));
381   off += sizeof (uint16_t);
382   switch (af)
383   {
384   case AF_INET:
385     memcpy (off, source_ip, sizeof (struct in_addr));
386     off += sizeof (struct in_addr);
387     memcpy (off, destination_ip, sizeof (struct in_addr));
388     off += sizeof (struct in_addr);
389     break;
390   case AF_INET6:
391     memcpy (off, source_ip, sizeof (struct in6_addr));
392     off += sizeof (struct in6_addr);
393     memcpy (off, destination_ip, sizeof (struct in6_addr));
394     off += sizeof (struct in6_addr);
395     break;
396   default:
397     GNUNET_assert (0);
398     break;
399   }
400   memcpy (off, &protocol, sizeof (uint8_t));
401   off += sizeof (uint8_t);  
402 }
403
404
405 /**
406  * Notify the client about the result of its request.
407  *
408  * @param client client to notify
409  * @param request_id original request ID to include in response
410  * @param result_af resulting address family
411  * @param addr resulting IP address
412  */
413 static void
414 send_client_reply (struct GNUNET_SERVER_Client *client,
415                    uint64_t request_id,
416                    int result_af,
417                    const void *addr)
418 {
419   char buf[sizeof (struct RedirectToIpResponseMessage) + sizeof (struct in6_addr)];
420   struct RedirectToIpResponseMessage *res;
421   size_t rlen;
422
423   switch (result_af)
424   {
425   case AF_INET:
426     rlen = sizeof (struct in_addr);    
427     break;
428   case AF_INET6:
429     rlen = sizeof (struct in6_addr);
430     break;
431   case AF_UNSPEC:
432     rlen = 0;
433     break;
434   default:
435     GNUNET_assert (0);
436     return;
437   }
438   res = (struct RedirectToIpResponseMessage *) buf;
439   res->header.size = htons (sizeof (struct RedirectToIpResponseMessage) + rlen);
440   res->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP);
441   res->result_af = htonl (result_af);
442   res->request_id = request_id;
443   memcpy (&res[1], addr, rlen);
444   GNUNET_SERVER_notification_context_add (nc, client);
445   GNUNET_SERVER_notification_context_unicast (nc,
446                                               client,
447                                               &res->header,
448                                               GNUNET_NO);
449 }
450
451
452 /**
453  * Method called whenever a peer has disconnected from the tunnel.
454  *
455  * @param cls closure
456  * @param peer peer identity the tunnel stopped working with
457  */
458 static void
459 tunnel_peer_disconnect_handler (void *cls,
460                                 const struct
461                                 GNUNET_PeerIdentity * peer)
462 {
463   /* FIXME: should we do anything here? 
464    - stop transmitting to the tunnel (start queueing?)
465    - possibly destroy the tunnel entirely (unless service tunnel?) 
466   */
467 }
468
469
470 /**
471  * Method called whenever a peer has connected to the tunnel.  Notifies
472  * the waiting client that the tunnel is now up.
473  *
474  * @param cls closure
475  * @param peer peer identity the tunnel was created to, NULL on timeout
476  * @param atsi performance data for the connection
477  */
478 static void
479 tunnel_peer_connect_handler (void *cls,
480                              const struct GNUNET_PeerIdentity
481                              * peer,
482                              const struct
483                              GNUNET_ATS_Information * atsi)
484 {
485   struct TunnelState *ts = cls;
486
487   if (NULL == ts->client)
488     return; /* nothing to do */
489   send_client_reply (ts->client,
490                      ts->request_id,
491                      ts->af,
492                      &ts->destination_ip);
493   GNUNET_SERVER_client_drop (ts->client);
494   ts->client = NULL;
495 }
496
497
498 /**
499  * Send a message from the message queue via mesh.
500  *
501  * @param cls the 'struct TunnelState' with the message queue
502  * @param size number of bytes available in buf
503  * @param buf where to copy the message
504  * @return number of bytes copied to buf
505  */
506 static size_t
507 send_to_peer_notify_callback (void *cls, size_t size, void *buf)
508 {
509   struct TunnelState *ts = cls;
510   struct TunnelMessageQueueEntry *tnq;
511   size_t ret;
512
513   ts->th = NULL;
514   if (NULL == buf)
515     return 0;
516   tnq = ts->head;
517   GNUNET_assert (NULL != tnq);
518   GNUNET_assert (size >= tnq->len);
519   GNUNET_CONTAINER_DLL_remove (ts->head,
520                                ts->tail,
521                                tnq);
522   memcpy (buf, tnq->msg, tnq->len);
523   ret = tnq->len;
524   GNUNET_free (tnq);
525   if (NULL != (tnq = ts->head))
526     ts->th = GNUNET_MESH_notify_transmit_ready (ts->destination.tunnel, 
527                                                 GNUNET_NO /* cork */, 
528                                                 42 /* priority */,
529                                                 GNUNET_TIME_UNIT_FOREVER_REL,
530                                                 NULL, 
531                                                 tnq->len,
532                                                 &send_to_peer_notify_callback,
533                                                 ts);
534   return ret;
535 }
536
537
538 /**
539  * Add the given message to the given tunnel and
540  * trigger the transmission process.
541  *
542  * @param tnq message to queue
543  * @param ts tunnel to queue the message for
544  */
545 static void
546 send_to_tunnel (struct TunnelMessageQueueEntry *tnq,
547                 struct TunnelState *ts)
548 {
549   GNUNET_CONTAINER_DLL_insert_tail (ts->head,
550                                     ts->tail,
551                                     tnq);
552   if (NULL == ts->th)
553     ts->th = GNUNET_MESH_notify_transmit_ready (ts->destination.tunnel, 
554                                                 GNUNET_NO /* cork */,
555                                                 42 /* priority */,
556                                                 GNUNET_TIME_UNIT_FOREVER_REL,
557                                                 NULL, 
558                                                 tnq->len,
559                                                 &send_to_peer_notify_callback,
560                                                 ts);
561 }
562
563
564 /**
565  * Route a packet via mesh to the given destination.  
566  *
567  * @param destination description of the destination
568  * @param af address family on this end (AF_INET or AF_INET6)
569  * @param protocol IPPROTO_TCP or IPPROTO_UDP
570  * @param source_ip source IP used by the sender (struct in_addr or struct in6_addr)
571  * @param destination_ip destination IP used by the sender (struct in_addr or struct in6_addr)
572  * @param payload payload of the packet after the IP header
573  * @param payload_length number of bytes in payload
574  */
575 static void
576 route_packet (struct DestinationEntry *destination,
577               int af,
578               uint8_t protocol,
579               const void *source_ip,
580               const void *destination_ip,
581               const void *payload,
582               size_t payload_length)
583 {
584   GNUNET_HashCode key;
585   struct TunnelState *ts;
586   struct TunnelMessageQueueEntry *tnq;
587   size_t alen;
588   size_t mlen;
589   GNUNET_MESH_ApplicationType app_type;
590   int is_new;
591   const struct udp_packet *udp;
592   const struct tcp_packet *tcp;
593     
594   switch (protocol)
595   {
596   case IPPROTO_UDP:
597     {
598       if (payload_length < sizeof (struct udp_packet))
599       {
600         /* blame kernel? */
601         GNUNET_break (0);
602         return;
603       }
604       udp = payload;
605       get_tunnel_key_from_ips (af,
606                                IPPROTO_UDP,
607                                source_ip,
608                                ntohs (udp->spt),
609                                destination_ip,
610                                ntohs (udp->dpt),
611                                &key);
612     }
613     break;
614   case IPPROTO_TCP:
615     {
616       if (payload_length < sizeof (struct tcp_packet))
617       {
618         /* blame kernel? */
619         GNUNET_break (0);
620         return;
621       }
622       tcp = payload;
623       get_tunnel_key_from_ips (af,
624                                IPPROTO_TCP,
625                                source_ip,
626                                ntohs (tcp->spt),
627                                destination_ip,
628                                ntohs (tcp->dpt),
629                                &key);
630     }
631     break;
632   default:
633     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
634                 _("Protocol %u not supported, dropping\n"),
635                 (unsigned int) protocol);
636     return;
637   }
638
639   if (! destination->is_service)
640   {  
641     switch (destination->details.exit_destination.af)
642     {
643     case AF_INET:
644       alen = sizeof (struct in_addr);
645       app_type = GNUNET_APPLICATION_TYPE_IPV4_GATEWAY; 
646      break;
647     case AF_INET6:
648       alen = sizeof (struct in6_addr);
649       app_type = GNUNET_APPLICATION_TYPE_IPV6_GATEWAY; 
650       break;
651     default:
652       alen = 0;
653       GNUNET_assert (0);
654     }
655   }
656   else
657   {
658     /* make compiler happy */
659     alen = 0;
660     app_type = 0;
661   }
662
663   // FIXME: something is horrifically wrong here about
664   // how we lookup 'ts', match it and how we decide about
665   // creating new tunnels!
666   /* find tunnel */
667   is_new = GNUNET_NO;
668   ts = GNUNET_CONTAINER_multihashmap_get (tunnel_map,
669                                           &key);
670   if (NULL == ts)
671   {
672     /* create new tunnel */
673     is_new = GNUNET_YES;
674     ts = GNUNET_malloc (sizeof (struct TunnelState));
675     ts->destination.tunnel = GNUNET_MESH_tunnel_create (mesh_handle,
676                                                         ts,
677                                                         &tunnel_peer_connect_handler,
678                                                         &tunnel_peer_disconnect_handler, 
679                                                         ts);
680     if (destination->is_service)
681       GNUNET_MESH_peer_request_connect_add (ts->destination.tunnel,
682                                             &destination->details.service_destination.target);
683     else
684       GNUNET_MESH_peer_request_connect_by_type (ts->destination.tunnel,
685                                                 app_type);
686   }
687   
688   /* send via tunnel */
689   switch (protocol)
690   {
691   case IPPROTO_UDP:
692     if (destination->is_service)
693     {
694       struct GNUNET_EXIT_UdpServiceMessage *usm;
695
696       mlen = sizeof (struct GNUNET_EXIT_UdpServiceMessage) + 
697         payload_length - sizeof (struct udp_packet);
698       if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
699       {
700         GNUNET_break (0);
701         return;
702       }
703       tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + mlen);
704       usm = (struct GNUNET_EXIT_UdpServiceMessage *) &tnq[1];
705       usm->header.size = htons ((uint16_t) mlen);
706       usm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE);
707       /* if the source port is below 32000, we assume it has a special
708          meaning; if not, we pick a random port (this is a heuristic) */
709       usm->source_port = (ntohs (udp->spt) < 32000) ? udp->spt : 0;
710       usm->destination_port = udp->dpt;
711       usm->service_descriptor = destination->details.service_destination.service_descriptor;
712       memcpy (&usm[1],
713               &udp[1],
714               payload_length - sizeof (struct udp_packet));
715     }
716     else
717     {
718       struct GNUNET_EXIT_UdpInternetMessage *uim;
719       struct in_addr *ip4dst;
720       struct in6_addr *ip6dst;
721       void *payload;
722
723       mlen = sizeof (struct GNUNET_EXIT_UdpInternetMessage) + 
724         alen + payload_length - sizeof (struct udp_packet);
725       if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
726       {
727         GNUNET_break (0);
728         return;
729       }
730       tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + 
731                            mlen);
732       uim = (struct GNUNET_EXIT_UdpInternetMessage *) &tnq[1];
733       uim->header.size = htons ((uint16_t) mlen);
734       uim->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET); 
735       uim->af = htonl (destination->details.exit_destination.af);
736       uim->source_port = (ntohs (udp->spt) < 32000) ? udp->spt : 0;
737       uim->destination_port = udp->dpt;
738       switch (destination->details.exit_destination.af)
739       {
740       case AF_INET:
741         ip4dst = (struct in_addr *) &uim[1];
742         *ip4dst = destination->details.exit_destination.ip.v4;
743         payload = &ip4dst[1];
744         break;
745       case AF_INET6:
746         ip6dst = (struct in6_addr *) &uim[1];
747         *ip6dst = destination->details.exit_destination.ip.v6;
748         payload = &ip6dst[1];
749         break;
750       default:
751         GNUNET_assert (0);
752       }
753       memcpy (payload,
754               &udp[1],
755               payload_length - sizeof (struct udp_packet));
756     }
757     break;
758   case IPPROTO_TCP:
759     if (is_new)
760     {
761       if (destination->is_service)
762       {
763         struct GNUNET_EXIT_TcpServiceStartMessage *tsm;
764
765         mlen = sizeof (struct GNUNET_EXIT_TcpServiceStartMessage) + 
766           payload_length - sizeof (struct tcp_packet);
767         if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
768         {
769           GNUNET_break (0);
770           return;
771         }
772         tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + mlen);
773         tsm = (struct  GNUNET_EXIT_TcpServiceStartMessage *) &tnq[1];
774         tsm->header.size = htons ((uint16_t) mlen);
775         tsm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START);
776         tsm->reserved = htonl (0);
777         tsm->service_descriptor = destination->details.service_destination.service_descriptor;
778         tsm->tcp_header = *tcp;
779         memcpy (&tsm[1],
780                 &tcp[1],
781                 payload_length - sizeof (struct tcp_packet));
782       }
783       else
784       {
785         struct GNUNET_EXIT_TcpInternetStartMessage *tim;
786         struct in_addr *ip4dst;
787         struct in6_addr *ip6dst;
788         void *payload;
789
790         mlen = sizeof (struct GNUNET_EXIT_TcpInternetStartMessage) + 
791           alen + payload_length - sizeof (struct tcp_packet);
792         if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
793         {
794           GNUNET_break (0);
795           return;
796         }
797         tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + mlen);
798         tim = (struct  GNUNET_EXIT_TcpInternetStartMessage *) &tnq[1];
799         tim->header.size = htons ((uint16_t) mlen);
800         tim->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START);
801         tim->af = htonl (destination->details.exit_destination.af);     
802         tim->tcp_header = *tcp;
803         switch (destination->details.exit_destination.af)
804         {
805         case AF_INET:
806           ip4dst = (struct in_addr *) &tim[1];
807           *ip4dst = destination->details.exit_destination.ip.v4;
808           payload = &ip4dst[1];
809           break;
810         case AF_INET6:
811           ip6dst = (struct in6_addr *) &tim[1];
812           *ip6dst = destination->details.exit_destination.ip.v6;
813           payload = &ip6dst[1];
814           break;
815         default:
816           GNUNET_assert (0);
817         }
818         memcpy (payload,
819                 &tcp[1],
820                 payload_length - sizeof (struct tcp_packet));
821       }
822     }
823     else
824     {
825       struct GNUNET_EXIT_TcpDataMessage *tdm;
826
827       mlen = sizeof (struct GNUNET_EXIT_TcpDataMessage) + 
828         alen + payload_length - sizeof (struct tcp_packet);
829       if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
830       {
831         GNUNET_break (0);
832         return;
833       }
834       tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + mlen);
835       tdm = (struct  GNUNET_EXIT_TcpDataMessage *) &tnq[1];
836       tdm->header.size = htons ((uint16_t) mlen);
837       tdm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_TCP_DATA);
838       tdm->reserved = htonl (0);
839       tdm->tcp_header = *tcp;
840       memcpy (&tdm[1],
841               &tcp[1],
842               payload_length - sizeof (struct tcp_packet));
843      }
844     break;
845   default:
846     /* not supported above, how can we get here !? */
847     GNUNET_assert (0);
848     break;
849   }
850   send_to_tunnel (tnq, ts);
851 }
852
853
854 /**
855  * Receive packets from the helper-process (someone send to the local
856  * virtual tunnel interface).  Find the destination mapping, and if it
857  * exists, identify the correct MESH tunnel (or possibly create it)
858  * and forward the packet.
859  *
860  * @param cls closure, NULL
861  * @param client NULL
862  * @param message message we got from the client (VPN tunnel interface)
863  */
864 static void
865 message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED,
866                const struct GNUNET_MessageHeader *message)
867 {
868   const struct tun_header *tun;
869   size_t mlen;
870   GNUNET_HashCode key;
871   struct DestinationEntry *de;
872
873   mlen = ntohs (message->size);
874   if ( (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) ||
875        (mlen < sizeof (struct GNUNET_MessageHeader) + sizeof (struct tun_header)) )
876   {
877     GNUNET_break (0);
878     return;
879   }
880   tun = (const struct tun_header *) &message[1];
881   mlen -= (sizeof (struct GNUNET_MessageHeader) + sizeof (struct tun_header));
882   switch (ntohs (tun->proto))
883   {
884   case ETH_P_IPV6:
885     {
886       const struct ip6_header *pkt6;
887       
888       if (mlen < sizeof (struct ip6_header))
889       {
890         /* blame kernel */
891         GNUNET_break (0);
892         return;
893       }
894       pkt6 = (const struct ip6_header *) &tun[1];
895       get_destination_key_from_ip (AF_INET6,
896                                    &pkt6->destination_address,
897                                    &key);
898       de = GNUNET_CONTAINER_multihashmap_get (destination_map, &key);
899       /* FIXME: do we need to guard against hash collision? */
900       if (NULL == de)
901       {
902         char buf[INET6_ADDRSTRLEN];
903         
904         GNUNET_log (GNUNET_ERROR_TYPE_INFO,
905                     _("Packet received for unmapped destination `%s' (dropping it)\n"),
906                     inet_ntop (AF_INET6,
907                                &pkt6->destination_address,
908                                buf,
909                                sizeof (buf)));
910         return;
911       }
912       route_packet (de,
913                     AF_INET6,
914                     pkt6->next_header,
915                     &pkt6->source_address,                  
916                     &pkt6->destination_address,             
917                     &pkt6[1],
918                     mlen - sizeof (struct ip6_header));
919     }
920     break;
921   case ETH_P_IPV4:
922     {
923       struct ip4_header *pkt4;
924
925       if (mlen < sizeof (struct ip4_header))
926       {
927         /* blame kernel */
928         GNUNET_break (0);
929         return;
930       }
931       pkt4 = (struct ip4_header *) &tun[1];
932       get_destination_key_from_ip (AF_INET,
933                                    &pkt4->destination_address,
934                                    &key);
935       de = GNUNET_CONTAINER_multihashmap_get (destination_map, &key);
936       /* FIXME: do we need to guard against hash collision? */
937       if (NULL == de)
938       {
939         char buf[INET_ADDRSTRLEN];
940         
941         GNUNET_log (GNUNET_ERROR_TYPE_INFO,
942                     _("Packet received for unmapped destination `%s' (dropping it)\n"),
943                     inet_ntop (AF_INET,
944                                &pkt4->destination_address,
945                                buf,
946                                sizeof (buf)));
947         return;
948       }
949       if (pkt4->header_length * 4 != sizeof (struct ip4_header))
950       {
951         GNUNET_log (GNUNET_ERROR_TYPE_INFO,
952                     _("Received IPv4 packet with options (dropping it)\n"));                
953         return;
954       }
955       route_packet (de,
956                     AF_INET,
957                     pkt4->protocol,
958                     &pkt4->source_address,                  
959                     &pkt4->destination_address,             
960                     &pkt4[1],
961                     mlen - sizeof (struct ip4_header));
962     }
963     break;
964   default:
965     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
966                 _("Received packet of unknown protocol %d from TUN (dropping it)\n"),
967                 (unsigned int) ntohs (tun->proto));
968     break;
969   }
970 }
971
972
973 /**
974  * We got a UDP packet back from the MESH tunnel.  Pass it on to the
975  * local virtual interface via the helper.
976  *
977  * @param cls closure, NULL
978  * @param tunnel connection to the other end
979  * @param tunnel_ctx pointer to our 'struct TunnelState *'
980  * @param sender who sent the message
981  * @param message the actual message
982  * @param atsi performance data for the connection
983  * @return GNUNET_OK to keep the connection open,
984  *         GNUNET_SYSERR to close it (signal serious error)
985  */ 
986 static int
987 receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
988                   void **tunnel_ctx, const struct GNUNET_PeerIdentity *sender,
989                   const struct GNUNET_MessageHeader *message,
990                   const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
991 {
992   struct TunnelState *ts = *tunnel_ctx;
993   const struct GNUNET_EXIT_UdpReplyMessage *reply;
994   size_t mlen;
995
996   mlen = ntohs (message->size);
997   if (mlen < sizeof (struct GNUNET_EXIT_UdpReplyMessage))
998   {
999     GNUNET_break_op (0);
1000     return GNUNET_SYSERR;
1001   }
1002   if (NULL == ts->heap_node)
1003   {
1004     GNUNET_break_op (0);
1005     return GNUNET_SYSERR;
1006   }
1007   reply = (const struct GNUNET_EXIT_UdpReplyMessage *) message;
1008   mlen -= sizeof (struct GNUNET_EXIT_UdpReplyMessage);
1009   switch (ts->af)
1010   {
1011   case AF_INET:
1012     {
1013       size_t size = sizeof (struct ip4_header) 
1014         + sizeof (struct udp_packet) 
1015         + sizeof (struct GNUNET_MessageHeader) +
1016         sizeof (struct tun_header) +
1017         mlen;
1018       {
1019         char buf[size];
1020         struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
1021         struct tun_header *tun = (struct tun_header*) &msg[1];
1022         struct ip4_header *ipv4 = (struct ip4_header *) &tun[1];
1023         struct udp_packet *udp = (struct udp_packet *) &ipv4[1];
1024         msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1025         msg->size = htons (size);
1026         tun->flags = htons (0);
1027         tun->proto = htons (ETH_P_IPV4);
1028         ipv4->version = 4;
1029         ipv4->header_length = sizeof (struct ip4_header) / 4;
1030         ipv4->diff_serv = 0;
1031         ipv4->total_length = htons (sizeof (struct ip4_header) +
1032                                     sizeof (struct udp_packet) +
1033                                     mlen);
1034         ipv4->identification = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 
1035                                                                     UINT16_MAX + 1);
1036         ipv4->flags = 0;
1037         ipv4->fragmentation_offset = 0;
1038         ipv4->ttl = 255;
1039         ipv4->protocol = IPPROTO_UDP;
1040         ipv4->checksum = 0; 
1041         ipv4->source_address = ts->destination_ip.v4;
1042         ipv4->destination_address = ts->source_ip.v4;
1043         ipv4->checksum =
1044           GNUNET_CRYPTO_crc16_n (ipv4, sizeof (struct ip4_header));
1045         if (0 == ntohs (reply->source_port))
1046           udp->spt = htons (ts->destination_port);
1047         else
1048           udp->spt = reply->source_port;
1049         if (0 == ntohs (reply->destination_port))
1050           udp->dpt = htons (ts->source_port);
1051         else
1052           udp->dpt = reply->destination_port;
1053         udp->len = htons (mlen + sizeof (struct udp_packet));
1054         udp->crc = 0; // FIXME: optional, but we might want to calculate this one anyway
1055         memcpy (&udp[1],
1056                 &reply[1],
1057                 mlen);
1058         (void) GNUNET_HELPER_send (helper_handle,
1059                                    msg,
1060                                    GNUNET_YES,
1061                                    NULL, NULL);
1062       }
1063     }
1064     break;
1065   case AF_INET6:
1066     {
1067       size_t size = sizeof (struct ip6_header) 
1068         + sizeof (struct udp_packet) 
1069         + sizeof (struct GNUNET_MessageHeader) +
1070         sizeof (struct tun_header) +
1071         mlen;
1072       {
1073         char buf[size];
1074         struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
1075         struct tun_header *tun = (struct tun_header*) &msg[1];
1076         struct ip6_header *ipv6 = (struct ip6_header *) &tun[1];
1077         struct udp_packet *udp = (struct udp_packet *) &ipv6[1];
1078         msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1079         msg->size = htons (size);
1080         tun->flags = htons (0);
1081         tun->proto = htons (ETH_P_IPV6);
1082         ipv6->traffic_class_h = 0;
1083         ipv6->version = 6;
1084         ipv6->traffic_class_l = 0;
1085         ipv6->flow_label = 0;
1086         ipv6->payload_length = htons (sizeof (struct udp_packet) + sizeof (struct ip6_header) + mlen);
1087         ipv6->next_header = IPPROTO_UDP;
1088         ipv6->hop_limit = 255;
1089         ipv6->source_address = ts->destination_ip.v6;
1090         ipv6->destination_address = ts->source_ip.v6;
1091         if (0 == ntohs (reply->source_port))
1092           udp->spt = htons (ts->destination_port);
1093         else
1094           udp->spt = reply->source_port;
1095         if (0 == ntohs (reply->destination_port))
1096           udp->dpt = htons (ts->source_port);
1097         else
1098           udp->dpt = reply->destination_port;
1099         udp->len = htons (mlen + sizeof (struct udp_packet));
1100         udp->crc = 0;
1101         memcpy (&udp[1],
1102                 &reply[1],
1103                 mlen);
1104         {
1105           uint32_t sum = 0;
1106           sum =
1107             GNUNET_CRYPTO_crc16_step (sum, &ipv6->source_address, 
1108                                       sizeof (struct in6_addr) * 2);
1109           uint32_t tmp = udp->len;
1110           sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
1111           tmp = htons (IPPROTO_UDP);
1112           sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
1113           sum = GNUNET_CRYPTO_crc16_step (sum, 
1114                                           udp,
1115                                           ntohs (udp->len));
1116           udp->crc = GNUNET_CRYPTO_crc16_finish (sum);
1117         }
1118         (void) GNUNET_HELPER_send (helper_handle,
1119                                    msg,
1120                                    GNUNET_YES,
1121                                    NULL, NULL);
1122       }
1123     }
1124     break;
1125   default:
1126     GNUNET_assert (0);
1127   }
1128 #if 0
1129   // FIXME: refresh entry to avoid expiration...
1130   struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
1131   
1132   GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node,
1133                                      GNUNET_TIME_absolute_get ().abs_value);
1134   
1135 #endif
1136   return GNUNET_OK;
1137 }
1138
1139
1140 /**
1141  * We got a TCP packet back from the MESH tunnel.  Pass it on to the
1142  * local virtual interface via the helper.
1143  *
1144  * @param cls closure, NULL
1145  * @param tunnel connection to the other end
1146  * @param tunnel_ctx pointer to our 'struct TunnelState *'
1147  * @param sender who sent the message
1148  * @param message the actual message
1149  * @param atsi performance data for the connection
1150  * @return GNUNET_OK to keep the connection open,
1151  *         GNUNET_SYSERR to close it (signal serious error)
1152  */ 
1153 static int
1154 receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1155                   void **tunnel_ctx,
1156                   const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1157                   const struct GNUNET_MessageHeader *message,
1158                   const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1159 {
1160   struct TunnelState *ts = *tunnel_ctx;
1161   const struct GNUNET_EXIT_TcpDataMessage *data;
1162   size_t mlen;
1163
1164   mlen = ntohs (message->size);
1165   if (mlen < sizeof (struct GNUNET_EXIT_TcpDataMessage))
1166   {
1167     GNUNET_break_op (0);
1168     return GNUNET_SYSERR;
1169   }
1170   if (NULL == ts->heap_node)
1171   {
1172     GNUNET_break_op (0);
1173     return GNUNET_SYSERR;
1174   }
1175   data = (const struct GNUNET_EXIT_TcpDataMessage *) message;
1176   mlen -= sizeof (struct GNUNET_EXIT_TcpDataMessage);
1177   switch (ts->af)
1178   {
1179   case AF_INET:
1180     {
1181       size_t size = sizeof (struct ip4_header) 
1182         + sizeof (struct tcp_packet) 
1183         + sizeof (struct GNUNET_MessageHeader) +
1184         sizeof (struct tun_header) +
1185         mlen;
1186       {
1187         char buf[size];
1188         struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
1189         struct tun_header *tun = (struct tun_header*) &msg[1];
1190         struct ip4_header *ipv4 = (struct ip4_header *) &tun[1];
1191         struct tcp_packet *tcp = (struct tcp_packet *) &ipv4[1];
1192         msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1193         msg->size = htons (size);
1194         tun->flags = htons (0);
1195         tun->proto = htons (ETH_P_IPV4);
1196         ipv4->version = 4;
1197         ipv4->header_length = sizeof (struct ip4_header) / 4;
1198         ipv4->diff_serv = 0;
1199         ipv4->total_length = htons (sizeof (struct ip4_header) +
1200                                     sizeof (struct tcp_packet) +
1201                                     mlen);
1202         ipv4->identification = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 
1203                                                                     UINT16_MAX + 1);
1204         ipv4->flags = 0;
1205         ipv4->fragmentation_offset = 0;
1206         ipv4->ttl = 255;
1207         ipv4->protocol = IPPROTO_TCP;
1208         ipv4->checksum = 0; 
1209         ipv4->source_address = ts->destination_ip.v4;
1210         ipv4->destination_address = ts->source_ip.v4;
1211         ipv4->checksum =
1212           GNUNET_CRYPTO_crc16_n (ipv4, sizeof (struct ip4_header));
1213         *tcp = data->tcp_header;
1214         tcp->spt = htons (ts->destination_port);
1215         tcp->dpt = htons (ts->source_port);
1216         tcp->crc = 0;
1217         memcpy (&tcp[1],
1218                 &data[1],
1219                 mlen);
1220         {
1221           uint32_t sum = 0;
1222           uint32_t tmp;
1223           
1224           sum = GNUNET_CRYPTO_crc16_step (sum, 
1225                                           &ipv4->source_address,
1226                                           2 * sizeof (struct in_addr));   
1227           tmp = htonl ((IPPROTO_TCP << 16) | (mlen + sizeof (struct tcp_packet)));
1228           sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
1229           sum = GNUNET_CRYPTO_crc16_step (sum, tcp, mlen + sizeof (struct tcp_packet));
1230           tcp->crc = GNUNET_CRYPTO_crc16_finish (sum);
1231         }
1232         (void) GNUNET_HELPER_send (helper_handle,
1233                                    msg,
1234                                    GNUNET_YES,
1235                                    NULL, NULL);
1236       }
1237     }
1238     break;
1239   case AF_INET6:
1240     {
1241       size_t size = sizeof (struct ip6_header) 
1242         + sizeof (struct tcp_packet) 
1243         + sizeof (struct GNUNET_MessageHeader) +
1244         sizeof (struct tun_header) +
1245         mlen;
1246       {
1247         char buf[size];
1248         struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
1249         struct tun_header *tun = (struct tun_header*) &msg[1];
1250         struct ip6_header *ipv6 = (struct ip6_header *) &tun[1];
1251         struct tcp_packet *tcp = (struct tcp_packet *) &ipv6[1];
1252         msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1253         msg->size = htons (size);
1254         tun->flags = htons (0);
1255         tun->proto = htons (ETH_P_IPV6);
1256         ipv6->traffic_class_h = 0;
1257         ipv6->version = 6;
1258         ipv6->traffic_class_l = 0;
1259         ipv6->flow_label = 0;
1260         ipv6->payload_length = htons (sizeof (struct tcp_packet) + sizeof (struct ip6_header) + mlen);
1261         ipv6->next_header = IPPROTO_TCP;
1262         ipv6->hop_limit = 255;
1263         ipv6->source_address = ts->destination_ip.v6;
1264         ipv6->destination_address = ts->source_ip.v6;
1265         tcp->spt = htons (ts->destination_port);
1266         tcp->dpt = htons (ts->source_port);
1267         tcp->crc = 0;
1268         {
1269           uint32_t sum = 0;
1270           uint32_t tmp;
1271
1272           sum = GNUNET_CRYPTO_crc16_step (sum, &ipv6->source_address, 2 * sizeof (struct in6_addr));
1273           tmp = htonl (sizeof (struct tcp_packet) + mlen);
1274           sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
1275           tmp = htonl (IPPROTO_TCP);
1276           sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
1277           sum = GNUNET_CRYPTO_crc16_step (sum, tcp,
1278                                           sizeof (struct tcp_packet) + mlen);
1279           tcp->crc = GNUNET_CRYPTO_crc16_finish (sum);
1280         }
1281         (void) GNUNET_HELPER_send (helper_handle,
1282                                    msg,
1283                                    GNUNET_YES,
1284                                    NULL, NULL);
1285       }
1286     }
1287     break;
1288   }
1289
1290 #if 0
1291   // FIXME: refresh entry to avoid expiration...
1292   struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
1293   
1294   GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node,
1295                                      GNUNET_TIME_absolute_get ().abs_value);
1296   
1297 #endif
1298   return GNUNET_OK;
1299 }
1300
1301
1302 /**
1303  * Allocate an IPv4 address from the range of the tunnel
1304  * for a new redirection.
1305  *
1306  * @param v4 where to store the address
1307  * @return GNUNET_OK on success,
1308  *         GNUNET_SYSERR on error
1309  */
1310 static int
1311 allocate_v4_address (struct in_addr *v4)
1312 {
1313   const char *ipv4addr = vpn_argv[4];
1314   const char *ipv4mask = vpn_argv[5];
1315   struct in_addr addr;
1316   struct in_addr mask;
1317   struct in_addr rnd;
1318   GNUNET_HashCode key;
1319   unsigned int tries;
1320
1321   GNUNET_assert (1 == inet_pton (AF_INET, ipv4addr, &addr));
1322   GNUNET_assert (1 == inet_pton (AF_INET, ipv4mask, &mask));           
1323   /* Given 192.168.0.1/255.255.0.0, we want a mask 
1324      of '192.168.255.255', thus:  */
1325   mask.s_addr = addr.s_addr | ~mask.s_addr;  
1326   tries = 0;
1327   do
1328     {
1329       tries++;
1330       if (tries > 16)
1331       {
1332         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1333                     _("Failed to find unallocated IPv4 address in VPN's range\n"));
1334         return GNUNET_SYSERR;
1335       }
1336       /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
1337       rnd.s_addr = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 
1338                                              UINT32_MAX);       
1339       v4->s_addr = (addr.s_addr | rnd.s_addr) & mask.s_addr;          
1340       get_destination_key_from_ip (AF_INET,
1341                                    v4,
1342                                    &key);
1343     }
1344   while ( (GNUNET_YES ==
1345            GNUNET_CONTAINER_multihashmap_contains (destination_map,
1346                                                    &key)) ||
1347           (v4->s_addr == addr.s_addr) ||
1348           (v4->s_addr == mask.s_addr) );
1349   return GNUNET_OK;
1350 }
1351
1352
1353 /**
1354  * Allocate an IPv6 address from the range of the tunnel
1355  * for a new redirection.
1356  *
1357  * @param v6 where to store the address
1358  * @return GNUNET_OK on success,
1359  *         GNUNET_SYSERR on error
1360  */
1361 static int
1362 allocate_v6_address (struct in6_addr *v6)
1363 {
1364   const char *ipv6addr = vpn_argv[2];
1365   struct in6_addr addr;
1366   struct in6_addr mask;
1367   struct in6_addr rnd;
1368   int i;
1369   GNUNET_HashCode key;
1370   unsigned int tries;
1371
1372   GNUNET_assert (1 == inet_pton (AF_INET6, ipv6addr, &addr));
1373   GNUNET_assert (ipv6prefix < 128);
1374   /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
1375      thus: */
1376   mask = addr;
1377   for (i=127;i>=128-ipv6prefix;i--)
1378     mask.s6_addr[i / 8] |= (1 << (i % 8));
1379   
1380   /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */
1381   tries = 0;
1382   do
1383     {
1384       tries++;
1385       if (tries > 16)
1386         {
1387           GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1388                       _("Failed to find unallocated IPv6 address in VPN's range\n"));
1389           return GNUNET_SYSERR;
1390
1391         }
1392       for (i=0;i<16;i++)
1393         {
1394           rnd.s6_addr[i] = (unsigned char) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 
1395                                                                      256);
1396           v6->s6_addr[i]
1397             = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
1398         }
1399       get_destination_key_from_ip (AF_INET6,
1400                                    v6,
1401                                    &key);
1402     }
1403   while ( (GNUNET_YES ==
1404            GNUNET_CONTAINER_multihashmap_contains (destination_map,
1405                                                    &key)) ||
1406           (0 == memcmp (v6,
1407                         &addr,
1408                         sizeof (struct in6_addr))) ||
1409           (0 == memcmp (v6,
1410                         &mask,
1411                         sizeof (struct in6_addr))) );
1412   return GNUNET_OK;
1413 }
1414
1415
1416 /**
1417  * A client asks us to setup a redirection via some exit
1418  * node to a particular IP.  Setup the redirection and
1419  * give the client the allocated IP.
1420  *
1421  * @param cls unused
1422  * @param client requesting client
1423  * @param message redirection request (a 'struct RedirectToIpRequestMessage')
1424  */
1425 static void
1426 service_redirect_to_ip (void *cls GNUNET_UNUSED, struct GNUNET_SERVER_Client *client,
1427                         const struct GNUNET_MessageHeader *message)
1428 {
1429   size_t mlen;
1430   size_t alen;
1431   const struct RedirectToIpRequestMessage *msg;
1432   int addr_af;
1433   int result_af;
1434   struct in_addr v4;
1435   struct in6_addr v6;
1436   void *addr;
1437   struct DestinationEntry *de;
1438   GNUNET_HashCode key;
1439   struct TunnelState *ts;
1440   GNUNET_MESH_ApplicationType app_type;
1441   
1442   /* validate and parse request */
1443   mlen = ntohs (message->size);
1444   if (mlen < sizeof (struct RedirectToIpRequestMessage))
1445   {
1446     GNUNET_break (0);
1447     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1448     return;
1449   }
1450   alen = mlen - sizeof (struct RedirectToIpRequestMessage);
1451   msg = (const struct RedirectToIpRequestMessage *) message;
1452   addr_af = (int) htonl (msg->addr_af);
1453   switch (addr_af)
1454   {
1455   case AF_INET:
1456     if (alen != sizeof (struct in_addr))
1457     {
1458       GNUNET_break (0);
1459       GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1460       return;      
1461     }
1462     app_type = GNUNET_APPLICATION_TYPE_IPV4_GATEWAY; 
1463     break;
1464   case AF_INET6:
1465     if (alen != sizeof (struct in6_addr))
1466     {
1467       GNUNET_break (0);
1468       GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1469       return;      
1470     }
1471     app_type = GNUNET_APPLICATION_TYPE_IPV6_GATEWAY; 
1472     break;
1473   default:
1474     GNUNET_break (0);
1475     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1476     return;      
1477   }
1478
1479   /* allocate response IP */
1480   addr = NULL;
1481   result_af = (int) htonl (msg->result_af);
1482   switch (result_af)
1483   {
1484   case AF_INET:
1485     if (GNUNET_OK !=
1486         allocate_v4_address (&v4))
1487       result_af = AF_UNSPEC;
1488     else
1489       addr = &v4;
1490     break;
1491   case AF_INET6:
1492     if (GNUNET_OK !=
1493         allocate_v6_address (&v6))
1494       result_af = AF_UNSPEC;
1495     else
1496       addr = &v6;
1497     break;
1498   case AF_UNSPEC:
1499     if (GNUNET_OK ==
1500         allocate_v4_address (&v4))
1501     {
1502       addr = &v4;
1503       result_af = AF_INET;
1504     }
1505     else if (GNUNET_OK ==
1506         allocate_v6_address (&v6))
1507     {
1508       addr = &v6;
1509       result_af = AF_INET6;
1510     }
1511     break;
1512   default:
1513     GNUNET_break (0);
1514     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1515     return;      
1516   }
1517   if ( (result_af == AF_UNSPEC) ||
1518        (GNUNET_NO == ntohl (msg->nac)) )
1519   {
1520     /* send reply "instantly" */
1521     send_client_reply (client,
1522                        msg->request_id,
1523                        result_af,
1524                        addr);
1525   }
1526   if (result_af == AF_UNSPEC)
1527   {
1528     /* failure, we're done */
1529     GNUNET_SERVER_receive_done (client, GNUNET_OK);
1530     return;
1531   }
1532   
1533   /* setup destination record */
1534   de = GNUNET_malloc (sizeof (struct DestinationEntry));
1535   de->is_service = GNUNET_NO;
1536   de->details.exit_destination.af = addr_af;
1537   memcpy (&de->details.exit_destination.ip,
1538           &msg[1],
1539           alen);
1540   get_destination_key_from_ip (result_af,
1541                                addr,
1542                                &key);
1543   GNUNET_assert (GNUNET_OK ==
1544                  GNUNET_CONTAINER_multihashmap_put (destination_map,
1545                                                     &key,
1546                                                     de,
1547                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
1548   de->heap_node = GNUNET_CONTAINER_heap_insert (destination_heap,
1549                                                 de,
1550                                                 GNUNET_TIME_absolute_ntoh (msg->expiration_time).abs_value);
1551   /* setup tunnel to destination */
1552   ts = GNUNET_malloc (sizeof (struct TunnelState));
1553   if (GNUNET_NO != ntohl (msg->nac))
1554   {
1555     ts->request_id = msg->request_id;
1556     ts->client = client;
1557     GNUNET_SERVER_client_keep (client);
1558   }
1559   ts->destination = *de;
1560   ts->destination.heap_node = NULL;
1561   ts->is_service = GNUNET_NO;
1562   ts->af = result_af;
1563   if (result_af == AF_INET) 
1564     ts->destination_ip.v4 = v4;
1565   else
1566     ts->destination_ip.v6 = v6;
1567   de->tunnel = GNUNET_MESH_tunnel_create (mesh_handle,
1568                                           ts,
1569                                           &tunnel_peer_connect_handler,
1570                                           &tunnel_peer_disconnect_handler,
1571                                           ts);
1572   GNUNET_MESH_peer_request_connect_by_type (de->tunnel,
1573                                             app_type);  
1574   /* we're done */
1575   GNUNET_SERVER_receive_done (client, GNUNET_OK);
1576 }
1577
1578
1579 /**
1580  * A client asks us to setup a redirection to a particular peer
1581  * offering a service.  Setup the redirection and give the client the
1582  * allocated IP.
1583  *
1584  * @param cls unused
1585  * @param client requesting client
1586  * @param message redirection request (a 'struct RedirectToPeerRequestMessage')
1587  */
1588 static void
1589 service_redirect_to_service (void *cls GNUNET_UNUSED, struct GNUNET_SERVER_Client *client,
1590                              const struct GNUNET_MessageHeader *message)
1591 {
1592   const struct RedirectToServiceRequestMessage *msg;
1593   int result_af;
1594   struct in_addr v4;
1595   struct in6_addr v6;
1596   void *addr;
1597   struct DestinationEntry *de;
1598   GNUNET_HashCode key;
1599   struct TunnelState *ts;
1600   
1601   /*  parse request */
1602   msg = (const struct RedirectToServiceRequestMessage *) message;
1603
1604   /* allocate response IP */
1605   addr = NULL;
1606   result_af = (int) htonl (msg->result_af);
1607   switch (result_af)
1608   {
1609   case AF_INET:
1610     if (GNUNET_OK !=
1611         allocate_v4_address (&v4))
1612       result_af = AF_UNSPEC;
1613     else
1614       addr = &v4;
1615     break;
1616   case AF_INET6:
1617     if (GNUNET_OK !=
1618         allocate_v6_address (&v6))
1619       result_af = AF_UNSPEC;
1620     else
1621       addr = &v6;
1622     break;
1623   case AF_UNSPEC:
1624     if (GNUNET_OK ==
1625         allocate_v4_address (&v4))
1626     {
1627       addr = &v4;
1628       result_af = AF_INET;
1629     }
1630     else if (GNUNET_OK ==
1631         allocate_v6_address (&v6))
1632     {
1633       addr = &v6;
1634       result_af = AF_INET6;
1635     }
1636     break;
1637   default:
1638     GNUNET_break (0);
1639     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1640     return;      
1641   }
1642   if ( (result_af == AF_UNSPEC) ||
1643        (GNUNET_NO == ntohl (msg->nac)) )
1644   {
1645     /* send reply "instantly" */
1646     send_client_reply (client,
1647                        msg->request_id,
1648                        result_af,
1649                        addr);
1650   }
1651   if (result_af == AF_UNSPEC)
1652   {
1653     /* failure, we're done */
1654     GNUNET_SERVER_receive_done (client, GNUNET_OK);
1655     return;
1656   }
1657   
1658   /* setup destination record */
1659   de = GNUNET_malloc (sizeof (struct DestinationEntry));
1660   de->is_service = GNUNET_YES;
1661   de->details.service_destination.service_descriptor = msg->service_descriptor;
1662   de->details.service_destination.target = msg->target;
1663   get_destination_key_from_ip (result_af,
1664                                addr,
1665                                &key);
1666   GNUNET_assert (GNUNET_OK ==
1667                  GNUNET_CONTAINER_multihashmap_put (destination_map,
1668                                                     &key,
1669                                                     de,
1670                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
1671   de->heap_node = GNUNET_CONTAINER_heap_insert (destination_heap,
1672                                                 de,
1673                                                 GNUNET_TIME_absolute_ntoh (msg->expiration_time).abs_value);
1674
1675   /* setup tunnel to destination */
1676   ts = GNUNET_malloc (sizeof (struct TunnelState));
1677   if (GNUNET_NO != ntohl (msg->nac))
1678   {
1679     ts->request_id = msg->request_id;
1680     ts->client = client;
1681     GNUNET_SERVER_client_keep (client);
1682   }
1683   ts->destination = *de;
1684   ts->destination.heap_node = NULL;
1685   ts->is_service = GNUNET_YES;
1686   ts->af = result_af;
1687   if (result_af == AF_INET) 
1688     ts->destination_ip.v4 = v4;
1689   else
1690     ts->destination_ip.v6 = v6;
1691   de->tunnel = GNUNET_MESH_tunnel_create (mesh_handle,
1692                                           ts,
1693                                           &tunnel_peer_connect_handler,
1694                                           &tunnel_peer_disconnect_handler,
1695                                           ts);
1696   GNUNET_MESH_peer_request_connect_add (de->tunnel,
1697                                         &msg->target);  
1698   /* we're done */
1699   GNUNET_SERVER_receive_done (client, GNUNET_OK);
1700 }
1701
1702
1703
1704 /**
1705  * Function called for inbound tunnels.  As we don't offer
1706  * any mesh services, this function should never be called.
1707  *
1708  * @param cls closure
1709  * @param tunnel new handle to the tunnel
1710  * @param initiator peer that started the tunnel
1711  * @param atsi performance information for the tunnel
1712  * @return initial tunnel context for the tunnel
1713  *         (can be NULL -- that's not an error)
1714  */ 
1715 static void *
1716 inbound_tunnel_cb (void *cls, struct GNUNET_MESH_Tunnel *tunnel,
1717                    const struct GNUNET_PeerIdentity *initiator,
1718                    const struct GNUNET_ATS_Information *atsi)
1719 {
1720   /* Why should anyone open an inbound tunnel to vpn? */
1721   GNUNET_break (0);
1722   return NULL;
1723 }
1724
1725
1726 /**
1727  * Function called whenever an inbound tunnel is destroyed.  Should clean up
1728  * any associated state.
1729  *
1730  * @param cls closure (set from GNUNET_MESH_connect)
1731  * @param tunnel connection to the other end (henceforth invalid)
1732  * @param tunnel_ctx place where local state associated
1733  *                   with the tunnel is stored
1734  */ 
1735 static void
1736 tunnel_cleaner (void *cls, const struct GNUNET_MESH_Tunnel *tunnel, void *tunnel_ctx)
1737 {
1738   /* FIXME: is this function called for outbound tunnels that go down?
1739      Should we clean up something here? */
1740   GNUNET_break (0);
1741 }
1742
1743
1744 /**
1745  * Free memory occupied by an entry in the destination map.
1746  *
1747  * @param cls unused
1748  * @param key unused
1749  * @param value a 'struct DestinationEntry *'
1750  * @return GNUNET_OK (continue to iterate)
1751  */
1752 static int
1753 cleanup_destination (void *cls,
1754                      const GNUNET_HashCode *key,
1755                      void *value)
1756 {
1757   struct DestinationEntry *de = value;
1758
1759   if (NULL != de->tunnel)
1760   {
1761     GNUNET_MESH_tunnel_destroy (de->tunnel);
1762     de->tunnel = NULL;
1763   }
1764   /*
1765   if (NULL != ts->heap_node)
1766   {
1767     GNUNET_CONTAINER_heap_remove_node (ts->heap_node);
1768     ts->heap_node = NULL;
1769   }
1770   */
1771   GNUNET_free (de);
1772   return GNUNET_OK;
1773 }
1774
1775
1776 /**
1777  * Free memory occupied by an entry in the tunnel map.
1778  *
1779  * @param cls unused
1780  * @param key unused
1781  * @param value a 'struct TunnelState *'
1782  * @return GNUNET_OK (continue to iterate)
1783  */
1784 static int
1785 cleanup_tunnel (void *cls,
1786                 const GNUNET_HashCode *key,
1787                 void *value)
1788 {
1789   struct TunnelState *ts = value;
1790   struct TunnelMessageQueueEntry *tnq;
1791
1792   while (NULL != (tnq = ts->head))
1793   {
1794     GNUNET_CONTAINER_DLL_remove (ts->head,
1795                                  ts->tail,
1796                                  tnq);
1797     GNUNET_free (tnq);
1798   }
1799   if (NULL != ts->client)
1800   {
1801     GNUNET_SERVER_client_drop (ts->client);
1802     ts->client = NULL;
1803   }
1804   if (NULL != ts->th)
1805   {
1806     GNUNET_MESH_notify_transmit_ready_cancel (ts->th);
1807     ts->th = NULL;
1808   }
1809   if (NULL != ts->destination.tunnel)
1810   {
1811     GNUNET_MESH_tunnel_destroy (ts->destination.tunnel);
1812     ts->destination.tunnel = NULL;
1813   }
1814   if (NULL != ts->heap_node)
1815   {
1816     GNUNET_CONTAINER_heap_remove_node (ts->heap_node);
1817     ts->heap_node = NULL;
1818   }
1819   // FIXME...
1820   GNUNET_free (ts);
1821   return GNUNET_OK;
1822 }
1823
1824
1825 /**
1826  * Function scheduled as very last function, cleans up after us
1827  *
1828  * @param cls unused
1829  * @param tc unused
1830  */
1831 static void
1832 cleanup (void *cls GNUNET_UNUSED,
1833          const struct GNUNET_SCHEDULER_TaskContext *tc)
1834 {
1835   unsigned int i;
1836
1837   if (NULL != destination_map)
1838   {  
1839     GNUNET_CONTAINER_multihashmap_iterate (destination_map,
1840                                            &cleanup_destination,
1841                                            NULL);
1842     GNUNET_CONTAINER_multihashmap_destroy (destination_map);
1843     destination_map = NULL;
1844   }
1845   if (NULL != destination_heap)
1846   {
1847     GNUNET_CONTAINER_heap_destroy (destination_heap);
1848     destination_heap = NULL;
1849   }
1850   if (NULL != tunnel_map)
1851   {  
1852     GNUNET_CONTAINER_multihashmap_iterate (tunnel_map,
1853                                            &cleanup_tunnel,
1854                                            NULL);
1855     GNUNET_CONTAINER_multihashmap_destroy (tunnel_map);
1856     tunnel_map = NULL;
1857   }
1858   if (NULL != tunnel_heap)
1859   {
1860     GNUNET_CONTAINER_heap_destroy (tunnel_heap);
1861     tunnel_heap = NULL;
1862   }
1863   if (NULL != mesh_handle)
1864   {
1865     GNUNET_MESH_disconnect (mesh_handle);
1866     mesh_handle = NULL;
1867   }
1868   if (NULL != helper_handle)
1869     {
1870     GNUNET_HELPER_stop (helper_handle);
1871     helper_handle = NULL;
1872   }
1873   if (NULL != nc)
1874   {
1875     GNUNET_SERVER_notification_context_destroy (nc);
1876     nc = NULL;
1877   }
1878   for (i=0;i<5;i++)
1879     GNUNET_free_non_null (vpn_argv[i]);
1880 }
1881
1882
1883 /**
1884  * A client disconnected, clean up all references to it.
1885  *
1886  * @param cls the client that disconnected
1887  * @param key unused
1888  * @param value a 'struct TunnelState *'
1889  * @return GNUNET_OK (continue to iterate)
1890  */
1891 static int
1892 cleanup_tunnel_client (void *cls,
1893                        const GNUNET_HashCode *key,
1894                        void *value)
1895 {
1896   struct GNUNET_SERVER_Client *client = cls;
1897   struct TunnelState *ts = value;
1898
1899   if (client == ts->client)
1900   {
1901     GNUNET_SERVER_client_drop (ts->client);
1902     ts->client = NULL;
1903   }
1904   return GNUNET_OK;
1905 }
1906
1907   
1908 /**
1909  * A client has disconnected from us.  If we are currently building
1910  * a tunnel for it, cancel the operation.
1911  *
1912  * @param cls unused
1913  * @param client handle to the client that disconnected
1914  */
1915 static void
1916 client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
1917 {
1918   // FIXME: check that all truly all 'struct TunnelState's 
1919   // with clients are always in the tunnel map!
1920   GNUNET_CONTAINER_multihashmap_iterate (tunnel_map,
1921                                          &cleanup_tunnel_client,
1922                                          client);
1923 }
1924
1925
1926 /**
1927  * Main function that will be run by the scheduler.
1928  *
1929  * @param cls closure
1930  * @param server the initialized server
1931  * @param cfg_ configuration
1932  */
1933 static void
1934 run (void *cls,
1935      struct GNUNET_SERVER_Handle *server,
1936      const struct GNUNET_CONFIGURATION_Handle *cfg_)
1937 {
1938   static const struct GNUNET_SERVER_MessageHandler service_handlers[] = {
1939     /* callback, cls, type, size */
1940     {&service_redirect_to_ip, NULL, GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP, 0},
1941     {&service_redirect_to_service, NULL, 
1942      GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_SERVICE, 
1943      sizeof (struct RedirectToServiceRequestMessage) },
1944     {NULL, NULL, 0, 0}
1945   };
1946   static const struct GNUNET_MESH_MessageHandler mesh_handlers[] = {
1947     {receive_udp_back, GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK, 0},
1948     {receive_tcp_back, GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP_BACK, 0},
1949     {receive_udp_back, GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP_BACK, 0},
1950     {receive_tcp_back, GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP_BACK, 0},
1951     {NULL, 0, 0}
1952   };
1953   static const GNUNET_MESH_ApplicationType types[] = {
1954     GNUNET_APPLICATION_TYPE_END
1955   };
1956   char *ifname;
1957   char *ipv6addr;
1958   char *ipv6prefix_s;
1959   char *ipv4addr;
1960   char *ipv4mask;
1961   struct in_addr v4;
1962   struct in6_addr v6;
1963
1964   cfg = cfg_;
1965   if (GNUNET_OK !=
1966       GNUNET_CONFIGURATION_get_value_number (cfg, "vpn", "MAX_MAPPING",
1967                                              &max_destination_mappings))
1968     max_destination_mappings = 200;
1969   if (GNUNET_OK !=
1970       GNUNET_CONFIGURATION_get_value_number (cfg, "vpn", "MAX_TUNNELS",
1971                                              &max_tunnel_mappings))
1972     max_tunnel_mappings = 200;
1973
1974   destination_map = GNUNET_CONTAINER_multihashmap_create (max_destination_mappings * 2);
1975   destination_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
1976   tunnel_map = GNUNET_CONTAINER_multihashmap_create (max_tunnel_mappings * 2);
1977   tunnel_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
1978
1979
1980   vpn_argv[0] = GNUNET_strdup ("vpn-gnunet");
1981   if (GNUNET_SYSERR ==
1982       GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IFNAME", &ifname))
1983   {
1984     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1985                 "No entry 'IFNAME' in configuration!\n");
1986     GNUNET_SCHEDULER_shutdown ();
1987     return;
1988   }
1989   vpn_argv[1] = ifname;
1990   if ( (GNUNET_SYSERR ==
1991         GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR",
1992                                                &ipv6addr) ||
1993         (1 != inet_pton (AF_INET6, ipv6addr, &v6))) )
1994   {
1995     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1996                 "No valid entry 'IPV6ADDR' in configuration!\n");
1997     GNUNET_SCHEDULER_shutdown ();
1998     return;
1999   }
2000   vpn_argv[2] = ipv6addr;
2001   if (GNUNET_SYSERR ==
2002       GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6PREFIX",
2003                                              &ipv6prefix_s))
2004   {
2005     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2006                 "No entry 'IPV6PREFIX' in configuration!\n");
2007     GNUNET_SCHEDULER_shutdown ();
2008     return;
2009   }
2010   vpn_argv[3] = ipv6prefix_s;
2011   if ( (GNUNET_OK !=
2012         GNUNET_CONFIGURATION_get_value_number (cfg, "vpn",
2013                                                "IPV6PREFIX",
2014                                                &ipv6prefix)) ||
2015        (ipv6prefix >= 127) )
2016   {
2017     GNUNET_SCHEDULER_shutdown ();
2018     return;
2019   }
2020
2021   if ( (GNUNET_SYSERR ==
2022         GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4ADDR",
2023                                                &ipv4addr) ||
2024         (1 != inet_pton (AF_INET, ipv4addr, &v4))) )
2025   {
2026     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2027                 "No valid entry for 'IPV4ADDR' in configuration!\n");
2028     GNUNET_SCHEDULER_shutdown ();
2029     return;
2030   }
2031   vpn_argv[4] = ipv4addr;
2032   if ( (GNUNET_SYSERR ==
2033         GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4MASK",
2034                                                &ipv4mask) ||
2035         (1 != inet_pton (AF_INET, ipv4mask, &v4))) )
2036   {
2037     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2038                 "No valid entry 'IPV4MASK' in configuration!\n");
2039     GNUNET_SCHEDULER_shutdown ();
2040     return;
2041   }
2042   vpn_argv[5] = ipv4mask;
2043   vpn_argv[6] = NULL;
2044
2045   mesh_handle =
2046     GNUNET_MESH_connect (cfg_, 42 /* queue length */, NULL, 
2047                          &inbound_tunnel_cb, 
2048                          &tunnel_cleaner, 
2049                          mesh_handlers,
2050                          types);
2051   helper_handle = GNUNET_HELPER_start ("gnunet-helper-vpn", vpn_argv,
2052                                        &message_token, NULL);
2053   nc = GNUNET_SERVER_notification_context_create (server, 1);
2054   GNUNET_SERVER_add_handlers (server, service_handlers);
2055   GNUNET_SERVER_disconnect_notify (server, &client_disconnect, NULL);
2056   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls);
2057 }
2058
2059
2060 /**
2061  * The main function of the VPN service.
2062  *
2063  * @param argc number of arguments from the command line
2064  * @param argv command line arguments
2065  * @return 0 ok, 1 on error
2066  */
2067 int
2068 main (int argc, char *const *argv)
2069 {
2070   return (GNUNET_OK ==
2071           GNUNET_SERVICE_run (argc, argv, "vpn", 
2072                               GNUNET_SERVICE_OPTION_NONE,
2073                               &run, NULL)) ? 0 : 1;
2074 }
2075
2076 /* end of gnunet-service-vpn.c */