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