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