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