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