-logging
[oweals/gnunet.git] / src / vpn / gnunet-service-vpn.c
1 /*
2      This file is part of GNUnet.
3      Copyright (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 cadet
26  * @author Philipp Toelke
27  * @author Christian Grothoff
28  *
29  * TODO:
30  * - keep multiple peers/cadet channels ready as alternative exits /
31  *   detect & recover from channel-to-exit failure gracefully
32  */
33 #include "platform.h"
34 #include "gnunet_util_lib.h"
35 #include "gnunet_common.h"
36 #include "gnunet_protocols.h"
37 #include "gnunet_applications.h"
38 #include "gnunet_cadet_service.h"
39 #include "gnunet_statistics_service.h"
40 #include "gnunet_constants.h"
41 #include "gnunet_tun_lib.h"
42 #include "gnunet_regex_service.h"
43 #include "vpn.h"
44 #include "exit.h"
45
46
47 /**
48  * Maximum number of messages we allow in the queue for cadet.
49  */
50 #define MAX_MESSAGE_QUEUE_SIZE 4
51
52
53 /**
54  * State we keep for each of our channels.
55  */
56 struct ChannelState;
57
58 /**
59  * Information we track for each IP address to determine which channel
60  * to send the traffic over to the destination.
61  */
62 struct DestinationEntry;
63
64 /**
65  * List of channels we keep for each destination port for a given
66  * destination entry.
67  */
68 struct DestinationChannel
69 {
70
71   /**
72    * Kept in a DLL.
73    */
74   struct DestinationChannel *next;
75
76   /**
77    * Kept in a DLL.
78    */
79   struct DestinationChannel *prev;
80
81   /**
82    * Destination entry list this `struct DestinationChannel` belongs with.
83    */
84   struct DestinationEntry *destination;
85
86   /**
87    * Pre-allocated channel for this destination, or NULL for none.
88    */
89   struct ChannelState *ts;
90
91   /**
92    * Destination port this channel state is used for.
93    */
94   uint16_t destination_port;
95
96 };
97
98
99 /**
100  * Information we track for each IP address to determine which channel
101  * to send the traffic over to the destination.
102  */
103 struct DestinationEntry
104 {
105
106   /**
107    * Key under which this entry is in the 'destination_map' (only valid
108    * if 'heap_node != NULL').
109    */
110   struct GNUNET_HashCode key;
111
112   /**
113    * Head of DLL of channels associated with this destination.
114    */
115   struct DestinationChannel *dt_head;
116
117   /**
118    * Tail of DLL of channels associated with this destination.
119    */
120   struct DestinationChannel *dt_tail;
121
122   /**
123    * Entry for this entry in the destination_heap.
124    */
125   struct GNUNET_CONTAINER_HeapNode *heap_node;
126
127   /**
128    * #GNUNET_NO if this is a channel to an Internet-exit,
129    * #GNUNET_YES if this channel is to a service.
130    */
131   int is_service;
132
133   /**
134    * Details about the connection (depending on is_service).
135    */
136   union
137   {
138
139     struct
140     {
141       /**
142        * The description of the service (only used for service channels).
143        */
144       struct GNUNET_HashCode service_descriptor;
145
146       /**
147        * Peer offering the service.
148        */
149       struct GNUNET_PeerIdentity target;
150
151     } service_destination;
152
153     struct
154     {
155
156       /**
157        * Address family used (AF_INET or AF_INET6).
158        */
159       int af;
160
161       /**
162        * IP address of the ultimate destination (only used for exit channels).
163        */
164       union
165       {
166         /**
167          * Address if af is AF_INET.
168          */
169         struct in_addr v4;
170
171         /**
172          * Address if af is AF_INET6.
173          */
174         struct in6_addr v6;
175       } ip;
176
177     } exit_destination;
178
179   } details;
180
181 };
182
183
184 /**
185  * A messages we have in queue for a particular channel.
186  */
187 struct ChannelMessageQueueEntry
188 {
189   /**
190    * This is a doubly-linked list.
191    */
192   struct ChannelMessageQueueEntry *next;
193
194   /**
195    * This is a doubly-linked list.
196    */
197   struct ChannelMessageQueueEntry *prev;
198
199   /**
200    * Number of bytes in 'msg'.
201    */
202   size_t len;
203
204   /**
205    * Message to transmit, allocated at the end of this struct.
206    */
207   const void *msg;
208 };
209
210
211 /**
212  * State we keep for each of our channels.
213  */
214 struct ChannelState
215 {
216
217   /**
218    * Information about the channel to use, NULL if no channel
219    * is available right now.
220    */
221   struct GNUNET_CADET_Channel *channel;
222
223   /**
224    * Active query with REGEX to locate exit.
225    */
226   struct GNUNET_REGEX_Search *search;
227
228   /**
229    * Active transmission handle, NULL for none.
230    */
231   struct GNUNET_CADET_TransmitHandle *th;
232
233   /**
234    * Entry for this entry in the channel_heap, NULL as long as this
235    * channel state is not fully bound.
236    */
237   struct GNUNET_CONTAINER_HeapNode *heap_node;
238
239   /**
240    * Head of list of messages scheduled for transmission.
241    */
242   struct ChannelMessageQueueEntry *tmq_head;
243
244   /**
245    * Tail of list of messages scheduled for transmission.
246    */
247   struct ChannelMessageQueueEntry *tmq_tail;
248
249   /**
250    * Destination entry that has a pointer to this channel state;
251    * NULL if this channel state is in the channel map.
252    */
253   struct DestinationChannel *destination_container;
254
255   /**
256    * Destination to which this channel leads.  Note that
257    * this struct is NOT in the destination_map (but a
258    * local copy) and that the 'heap_node' should always
259    * be NULL.
260    */
261   struct DestinationEntry destination;
262
263   /**
264    * Addess family used for this channel on the local TUN interface.
265    */
266   int af;
267
268   /**
269    * Length of the doubly linked 'tmq_head/tmq_tail' list.
270    */
271   unsigned int tmq_length;
272
273   /**
274    * IPPROTO_TCP or IPPROTO_UDP once bound.
275    */
276   uint8_t protocol;
277
278   /**
279    * IP address of the source on our end, initially uninitialized.
280    */
281   union
282   {
283     /**
284      * Address if af is AF_INET.
285      */
286     struct in_addr v4;
287
288     /**
289      * Address if af is AF_INET6.
290      */
291     struct in6_addr v6;
292
293   } source_ip;
294
295   /**
296    * Destination IP address used by the source on our end (this is the IP
297    * that we pick freely within the VPN's channel IP range).
298    */
299   union
300   {
301     /**
302      * Address if af is AF_INET.
303      */
304     struct in_addr v4;
305
306     /**
307      * Address if af is AF_INET6.
308      */
309     struct in6_addr v6;
310
311   } destination_ip;
312
313   /**
314    * Source port used by the sender on our end; 0 for uninitialized.
315    */
316   uint16_t source_port;
317
318   /**
319    * Destination port used by the sender on our end; 0 for uninitialized.
320    */
321   uint16_t destination_port;
322
323 };
324
325
326 /**
327  * Return value from #main().
328  */
329 static int global_ret;
330
331 /**
332  * Configuration we use.
333  */
334 static const struct GNUNET_CONFIGURATION_Handle *cfg;
335
336 /**
337  * Handle to the cadet service.
338  */
339 static struct GNUNET_CADET_Handle *cadet_handle;
340
341 /**
342  * Map from IP address to destination information (possibly with a
343  * CADET channel handle for fast setup).
344  */
345 static struct GNUNET_CONTAINER_MultiHashMap *destination_map;
346
347 /**
348  * Min-Heap sorted by activity time to expire old mappings.
349  */
350 static struct GNUNET_CONTAINER_Heap *destination_heap;
351
352 /**
353  * Map from source and destination address (IP+port) to connection
354  * information (mostly with the respective CADET channel handle).
355  */
356 static struct GNUNET_CONTAINER_MultiHashMap *channel_map;
357
358 /**
359  * Min-Heap sorted by activity time to expire old mappings; values are
360  * of type 'struct ChannelState'.
361  */
362 static struct GNUNET_CONTAINER_Heap *channel_heap;
363
364 /**
365  * Statistics.
366  */
367 static struct GNUNET_STATISTICS_Handle *stats;
368
369 /**
370  * The handle to the VPN helper process "gnunet-helper-vpn".
371  */
372 static struct GNUNET_HELPER_Handle *helper_handle;
373
374 /**
375  * Arguments to the vpn helper.
376  */
377 static char *vpn_argv[7];
378
379 /**
380  * Length of the prefix of the VPN's IPv6 network.
381  */
382 static unsigned long long ipv6prefix;
383
384 /**
385  * Notification context for sending replies to clients.
386  */
387 static struct GNUNET_SERVER_NotificationContext *nc;
388
389 /**
390  * If there are more than this number of address-mappings, old ones
391  * will be removed
392  */
393 static unsigned long long max_destination_mappings;
394
395 /**
396  * If there are more than this number of open channels, old ones
397  * will be removed
398  */
399 static unsigned long long max_channel_mappings;
400
401
402 /**
403  * Compute the key under which we would store an entry in the
404  * destination_map for the given IP address.
405  *
406  * @param af address family (AF_INET or AF_INET6)
407  * @param address IP address, struct in_addr or struct in6_addr
408  * @param key where to store the key
409  */
410 static void
411 get_destination_key_from_ip (int af,
412                              const void *address,
413                              struct GNUNET_HashCode *key)
414 {
415   switch (af)
416   {
417   case AF_INET:
418     GNUNET_CRYPTO_hash (address,
419                         sizeof (struct in_addr),
420                         key);
421     break;
422   case AF_INET6:
423     GNUNET_CRYPTO_hash (address,
424                         sizeof (struct in6_addr),
425                         key);
426     break;
427   default:
428     GNUNET_assert (0);
429     break;
430   }
431 }
432
433
434 /**
435  * Compute the key under which we would store an entry in the
436  * channel_map for the given socket address pair.
437  *
438  * @param af address family (AF_INET or AF_INET6)
439  * @param protocol IPPROTO_TCP or IPPROTO_UDP
440  * @param source_ip sender's source IP, struct in_addr or struct in6_addr
441  * @param source_port sender's source port
442  * @param destination_ip sender's destination IP, struct in_addr or struct in6_addr
443  * @param destination_port sender's destination port
444  * @param key where to store the key
445  */
446 static void
447 get_channel_key_from_ips (int af,
448                           uint8_t protocol,
449                           const void *source_ip,
450                           uint16_t source_port,
451                           const void *destination_ip,
452                           uint16_t destination_port,
453                           struct GNUNET_HashCode *key)
454 {
455   char *off;
456
457   memset (key, 0, sizeof (struct GNUNET_HashCode));
458   /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
459      so we put the ports in there (and hope for few collisions) */
460   off = (char*) key;
461   memcpy (off, &source_port, sizeof (uint16_t));
462   off += sizeof (uint16_t);
463   memcpy (off, &destination_port, sizeof (uint16_t));
464   off += sizeof (uint16_t);
465   switch (af)
466   {
467   case AF_INET:
468     memcpy (off, source_ip, sizeof (struct in_addr));
469     off += sizeof (struct in_addr);
470     memcpy (off, destination_ip, sizeof (struct in_addr));
471     off += sizeof (struct in_addr);
472     break;
473   case AF_INET6:
474     memcpy (off, source_ip, sizeof (struct in6_addr));
475     off += sizeof (struct in6_addr);
476     memcpy (off, destination_ip, sizeof (struct in6_addr));
477     off += sizeof (struct in6_addr);
478     break;
479   default:
480     GNUNET_assert (0);
481     break;
482   }
483   memcpy (off, &protocol, sizeof (uint8_t));
484   /* off += sizeof (uint8_t);  */
485 }
486
487
488 /**
489  * Notify the client about the result of its request.
490  *
491  * @param client client to notify
492  * @param request_id original request ID to include in response
493  * @param result_af resulting address family
494  * @param addr resulting IP address
495  */
496 static void
497 send_client_reply (struct GNUNET_SERVER_Client *client,
498                    uint64_t request_id,
499                    int result_af,
500                    const void *addr)
501 {
502   char buf[sizeof (struct RedirectToIpResponseMessage) + sizeof (struct in6_addr)] GNUNET_ALIGN;
503   struct RedirectToIpResponseMessage *res;
504   size_t rlen;
505
506   switch (result_af)
507   {
508   case AF_INET:
509     rlen = sizeof (struct in_addr);
510     break;
511   case AF_INET6:
512     rlen = sizeof (struct in6_addr);
513     break;
514   case AF_UNSPEC:
515     rlen = 0;
516     break;
517   default:
518     GNUNET_assert (0);
519     return;
520   }
521   res = (struct RedirectToIpResponseMessage *) buf;
522   res->header.size = htons (sizeof (struct RedirectToIpResponseMessage) + rlen);
523   res->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP);
524   res->result_af = htonl (result_af);
525   res->request_id = request_id;
526   memcpy (&res[1], addr, rlen);
527   GNUNET_SERVER_notification_context_add (nc, client);
528   GNUNET_SERVER_notification_context_unicast (nc,
529                                               client,
530                                               &res->header,
531                                               GNUNET_NO);
532 }
533
534
535 /**
536  * Free resources associated with a channel state.
537  *
538  * @param ts state to free
539  */
540 static void
541 free_channel_state (struct ChannelState *ts)
542 {
543   struct GNUNET_HashCode key;
544   struct ChannelMessageQueueEntry *tnq;
545   struct GNUNET_CADET_Channel *channel;
546
547   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
548               "Cleaning up channel state\n");
549   GNUNET_STATISTICS_update (stats,
550                             gettext_noop ("# Active channels"),
551                             -1, GNUNET_NO);
552   while (NULL != (tnq = ts->tmq_head))
553   {
554     GNUNET_CONTAINER_DLL_remove (ts->tmq_head,
555                                  ts->tmq_tail,
556                                  tnq);
557     ts->tmq_length--;
558     GNUNET_free (tnq);
559   }
560   GNUNET_assert (0 == ts->tmq_length);
561   if (NULL != ts->th)
562   {
563     GNUNET_CADET_notify_transmit_ready_cancel (ts->th);
564     ts->th = NULL;
565   }
566   GNUNET_assert (NULL == ts->destination.heap_node);
567   if (NULL != (channel = ts->channel))
568   {
569     ts->channel = NULL;
570     GNUNET_CADET_channel_destroy (channel);
571   }
572   if (NULL != ts->search)
573   {
574     GNUNET_REGEX_search_cancel (ts->search);
575     ts->search = NULL;
576   }
577   if (NULL != ts->heap_node)
578   {
579     GNUNET_CONTAINER_heap_remove_node (ts->heap_node);
580     ts->heap_node = NULL;
581     get_channel_key_from_ips (ts->af,
582                              ts->protocol,
583                              &ts->source_ip,
584                              ts->source_port,
585                              &ts->destination_ip,
586                              ts->destination_port,
587                              &key);
588     GNUNET_assert (GNUNET_YES ==
589                    GNUNET_CONTAINER_multihashmap_remove (channel_map,
590                                                          &key,
591                                                          ts));
592   }
593   if (NULL != ts->destination_container)
594   {
595     GNUNET_assert (ts == ts->destination_container->ts);
596     ts->destination_container->ts = NULL;
597     ts->destination_container = NULL;
598   }
599   GNUNET_free (ts);
600 }
601
602
603 /**
604  * Send a message from the message queue via cadet.
605  *
606  * @param cls the `struct ChannelState` with the message queue
607  * @param size number of bytes available in @a buf
608  * @param buf where to copy the message
609  * @return number of bytes copied to @a buf
610  */
611 static size_t
612 send_to_peer_notify_callback (void *cls, size_t size, void *buf)
613 {
614   struct ChannelState *ts = cls;
615   struct ChannelMessageQueueEntry *tnq;
616   size_t ret;
617
618   ts->th = NULL;
619   if (NULL == buf)
620     return 0;
621   tnq = ts->tmq_head;
622   GNUNET_assert (NULL != tnq);
623   GNUNET_assert (size >= tnq->len);
624   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
625               "Sending %u bytes via cadet channel\n",
626               tnq->len);
627   GNUNET_CONTAINER_DLL_remove (ts->tmq_head,
628                                ts->tmq_tail,
629                                tnq);
630   ts->tmq_length--;
631   memcpy (buf, tnq->msg, tnq->len);
632   ret = tnq->len;
633   GNUNET_free (tnq);
634   if (NULL != (tnq = ts->tmq_head))
635     ts->th = GNUNET_CADET_notify_transmit_ready (ts->channel,
636                                                 GNUNET_NO /* cork */,
637                                                 GNUNET_TIME_UNIT_FOREVER_REL,
638                                                 tnq->len,
639                                                 &send_to_peer_notify_callback,
640                                                 ts);
641   GNUNET_STATISTICS_update (stats,
642                             gettext_noop ("# Bytes given to cadet for transmission"),
643                             ret, GNUNET_NO);
644   return ret;
645 }
646
647
648 /**
649  * Add the given message to the given channel and trigger the
650  * transmission process.
651  *
652  * @param tnq message to queue
653  * @param ts channel to queue the message for
654  */
655 static void
656 send_to_channel (struct ChannelMessageQueueEntry *tnq,
657                 struct ChannelState *ts)
658 {
659   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
660               "Queueing %u bytes for transmission via cadet channel\n",
661               tnq->len);
662   GNUNET_assert (NULL != ts->channel);
663   GNUNET_CONTAINER_DLL_insert_tail (ts->tmq_head,
664                                     ts->tmq_tail,
665                                     tnq);
666   ts->tmq_length++;
667   if (ts->tmq_length > MAX_MESSAGE_QUEUE_SIZE)
668   {
669     struct ChannelMessageQueueEntry *dq;
670
671     dq = ts->tmq_head;
672     GNUNET_assert (dq != tnq);
673     GNUNET_CONTAINER_DLL_remove (ts->tmq_head,
674                                  ts->tmq_tail,
675                                  dq);
676     ts->tmq_length--;
677     GNUNET_CADET_notify_transmit_ready_cancel (ts->th);
678     ts->th = NULL;
679     GNUNET_STATISTICS_update (stats,
680                               gettext_noop ("# Bytes dropped in cadet queue (overflow)"),
681                               dq->len,
682                               GNUNET_NO);
683     GNUNET_free (dq);
684   }
685   if (NULL == ts->th)
686     ts->th = GNUNET_CADET_notify_transmit_ready (ts->channel,
687                                                 GNUNET_NO /* cork */,
688                                                 GNUNET_TIME_UNIT_FOREVER_REL,
689                                                 tnq->len,
690                                                 &send_to_peer_notify_callback,
691                                                 ts);
692 }
693
694
695 /**
696  * Output destination of a channel for diagnostics.
697  *
698  * @param de destination to process
699  * @return diagnostic string describing destination
700  */
701 static const char *
702 print_channel_destination (const struct DestinationEntry *de)
703 {
704   static char dest[256];
705
706   if (de->is_service)
707   {
708     GNUNET_snprintf (dest,
709                      sizeof (dest),
710                      "HS: %s-%s\n",
711                      GNUNET_i2s (&de->details.service_destination.target),
712                      GNUNET_h2s (&de->details.service_destination.service_descriptor));
713   }
714   else
715   {
716     inet_ntop (de->details.exit_destination.af,
717                &de->details.exit_destination.ip,
718                dest,
719                sizeof (dest));
720   }
721   return dest;
722 }
723
724
725 /**
726  * Regex has found a potential exit peer for us; consider using it.
727  *
728  * @param cls the `struct ChannelState`
729  * @param id Peer providing a regex that matches the string.
730  * @param get_path Path of the get request.
731  * @param get_path_length Lenght of @a get_path.
732  * @param put_path Path of the put request.
733  * @param put_path_length Length of the @a put_path.
734  */
735 static void
736 handle_regex_result (void *cls,
737                      const struct GNUNET_PeerIdentity *id,
738                      const struct GNUNET_PeerIdentity *get_path,
739                      unsigned int get_path_length,
740                      const struct GNUNET_PeerIdentity *put_path,
741                      unsigned int put_path_length)
742 {
743   struct ChannelState *ts = cls;
744   unsigned int apptype;
745
746   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
747               "Exit %s found for destination %s!\n",
748               GNUNET_i2s (id),
749               print_channel_destination (&ts->destination));
750   GNUNET_REGEX_search_cancel (ts->search);
751   ts->search = NULL;
752   switch (ts->af)
753   {
754   case AF_INET:
755     apptype = GNUNET_APPLICATION_TYPE_IPV4_GATEWAY;
756     break;
757   case AF_INET6:
758     apptype = GNUNET_APPLICATION_TYPE_IPV6_GATEWAY;
759     break;
760   default:
761     GNUNET_break (0);
762     return;
763   }
764   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
765               "Creating tunnel to %s for destination %s!\n",
766               GNUNET_i2s (id),
767               print_channel_destination (&ts->destination));
768   ts->channel = GNUNET_CADET_channel_create (cadet_handle,
769                                              ts,
770                                              id,
771                                              apptype,
772                                              GNUNET_CADET_OPTION_DEFAULT);
773 }
774
775
776 /**
777  * Initialize the given destination entry's cadet channel.
778  *
779  * @param dt destination channel for which we need to setup a channel
780  * @param client_af address family of the address returned to the client
781  * @return channel state of the channel that was created
782  */
783 static struct ChannelState *
784 create_channel_to_destination (struct DestinationChannel *dt,
785                                int client_af)
786 {
787   struct ChannelState *ts;
788   unsigned int apptype;
789
790   GNUNET_STATISTICS_update (stats,
791                             gettext_noop ("# Cadet channels created"),
792                             1, GNUNET_NO);
793   GNUNET_assert (NULL == dt->ts);
794   switch (client_af)
795   {
796   case AF_INET:
797     apptype = GNUNET_APPLICATION_TYPE_IPV4_GATEWAY;
798     break;
799   case AF_INET6:
800     apptype = GNUNET_APPLICATION_TYPE_IPV6_GATEWAY;
801     break;
802   default:
803     GNUNET_break (0);
804     return NULL;
805   }
806   ts = GNUNET_new (struct ChannelState);
807   ts->af = client_af;
808   ts->destination = *dt->destination;
809   ts->destination.heap_node = NULL; /* copy is NOT in destination heap */
810   dt->ts = ts;
811   ts->destination_container = dt; /* we are referenced from dt */
812   if (dt->destination->is_service)
813   {
814     ts->channel = GNUNET_CADET_channel_create (cadet_handle,
815                                                ts,
816                                                &dt->destination->details.service_destination.target,
817                                                apptype,
818                                                GNUNET_CADET_OPTION_DEFAULT);
819     if (NULL == ts->channel)
820     {
821       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
822                   _("Failed to setup cadet channel!\n"));
823       GNUNET_free (ts);
824       return NULL;
825     }
826     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
827                 "Creating channel to peer %s offering service %s\n",
828                 GNUNET_i2s (&dt->destination->details.service_destination.target),
829                 GNUNET_h2s (&dt->destination->details.service_destination.service_descriptor));
830   }
831   else
832   {
833     char *policy;
834
835     switch (dt->destination->details.exit_destination.af)
836     {
837     case AF_INET:
838     {
839       char address[GNUNET_TUN_IPV4_REGEXLEN];
840
841       GNUNET_TUN_ipv4toregexsearch (&dt->destination->details.exit_destination.ip.v4,
842                                     dt->destination_port,
843                                     address);
844       GNUNET_asprintf (&policy,
845                        "%s%s",
846                        GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX,
847                        address);
848       break;
849     }
850     case AF_INET6:
851     {
852       char address[GNUNET_TUN_IPV6_REGEXLEN];
853
854       GNUNET_TUN_ipv6toregexsearch (&dt->destination->details.exit_destination.ip.v6,
855                                     dt->destination_port,
856                                     address);
857       GNUNET_asprintf (&policy,
858                        "%s%s",
859                        GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX,
860                        address);
861       break;
862     }
863     default:
864       GNUNET_assert (0);
865       break;
866     }
867
868     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
869                 "Requesting connect by string: %s\n",
870                 policy);
871     ts->search = GNUNET_REGEX_search (cfg,
872                                       policy,
873                                       &handle_regex_result,
874                                       ts);
875     GNUNET_free (policy);
876   }
877   return ts;
878 }
879
880
881 /**
882  * We have too many active channels.  Clean up the oldest channel.
883  *
884  * @param except channel that must NOT be cleaned up, even if it is the oldest
885  */
886 static void
887 expire_channel (struct ChannelState *except)
888 {
889   struct ChannelState *ts;
890
891   ts = GNUNET_CONTAINER_heap_peek (channel_heap);
892   GNUNET_assert (NULL != ts);
893   if (except == ts)
894     return; /* can't do this */
895   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
896               "Tearing down expired channel to %s\n",
897               print_channel_destination (&except->destination));
898   free_channel_state (ts);
899 }
900
901
902 /**
903  * Route a packet via cadet to the given destination.
904  *
905  * @param destination description of the destination
906  * @param af address family on this end (AF_INET or AF_INET6)
907  * @param protocol IPPROTO_TCP or IPPROTO_UDP or IPPROTO_ICMP or IPPROTO_ICMPV6
908  * @param source_ip source IP used by the sender (struct in_addr or struct in6_addr)
909  * @param destination_ip destination IP used by the sender (struct in_addr or struct in6_addr)
910  * @param payload payload of the packet after the IP header
911  * @param payload_length number of bytes in @a payload
912  */
913 static void
914 route_packet (struct DestinationEntry *destination,
915               int af,
916               uint8_t protocol,
917               const void *source_ip,
918               const void *destination_ip,
919               const void *payload,
920               size_t payload_length)
921 {
922   struct GNUNET_HashCode key;
923   struct ChannelState *ts;
924   struct ChannelMessageQueueEntry *tnq;
925   size_t alen;
926   size_t mlen;
927   int is_new;
928   const struct GNUNET_TUN_UdpHeader *udp;
929   const struct GNUNET_TUN_TcpHeader *tcp;
930   const struct GNUNET_TUN_IcmpHeader *icmp;
931   struct DestinationChannel *dt;
932   uint16_t source_port;
933   uint16_t destination_port;
934
935   switch (protocol)
936   {
937   case IPPROTO_UDP:
938     {
939       if (payload_length < sizeof (struct GNUNET_TUN_UdpHeader))
940       {
941         /* blame kernel? */
942         GNUNET_break (0);
943         return;
944       }
945       tcp = NULL; /* make compiler happy */
946       icmp = NULL;  /* make compiler happy */
947       udp = payload;
948       if (udp->len < sizeof (struct GNUNET_TUN_UdpHeader))
949       {
950         GNUNET_break_op (0);
951         return;
952       }
953       source_port = ntohs (udp->source_port);
954       destination_port = ntohs (udp->destination_port);
955       get_channel_key_from_ips (af,
956                                IPPROTO_UDP,
957                                source_ip,
958                                source_port,
959                                destination_ip,
960                                destination_port,
961                                &key);
962     }
963     break;
964   case IPPROTO_TCP:
965     {
966       if (payload_length < sizeof (struct GNUNET_TUN_TcpHeader))
967       {
968         /* blame kernel? */
969         GNUNET_break (0);
970         return;
971       }
972       udp = NULL; /* make compiler happy */
973       icmp = NULL;  /* make compiler happy */
974       tcp = payload;
975       if (tcp->off * 4 < sizeof (struct GNUNET_TUN_TcpHeader))
976       {
977         GNUNET_break_op (0);
978         return;
979       }
980       source_port = ntohs (tcp->source_port);
981       destination_port = ntohs (tcp->destination_port);
982       get_channel_key_from_ips (af,
983                                IPPROTO_TCP,
984                                source_ip,
985                                source_port,
986                                destination_ip,
987                                destination_port,
988                                &key);
989     }
990     break;
991   case IPPROTO_ICMP:
992   case IPPROTO_ICMPV6:
993     {
994       if ( (AF_INET == af) ^ (protocol == IPPROTO_ICMP) )
995       {
996         GNUNET_break (0);
997         return;
998       }
999       if (payload_length < sizeof (struct GNUNET_TUN_IcmpHeader))
1000       {
1001         /* blame kernel? */
1002         GNUNET_break (0);
1003         return;
1004       }
1005       tcp = NULL; /* make compiler happy */
1006       udp = NULL;  /* make compiler happy */
1007       icmp = payload;
1008       source_port = 0;
1009       destination_port = 0;
1010       get_channel_key_from_ips (af,
1011                                protocol,
1012                                source_ip,
1013                                0,
1014                                destination_ip,
1015                                0,
1016                                &key);
1017     }
1018     break;
1019   default:
1020     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1021                 _("Protocol %u not supported, dropping\n"),
1022                 (unsigned int) protocol);
1023     return;
1024   }
1025   alen = 0;
1026   if (! destination->is_service)
1027   {
1028     switch (destination->details.exit_destination.af)
1029     {
1030     case AF_INET:
1031       alen = sizeof (struct in_addr);
1032      break;
1033     case AF_INET6:
1034       alen = sizeof (struct in6_addr);
1035       break;
1036     default:
1037       GNUNET_assert (0);
1038     }
1039
1040     {
1041       char sbuf[INET6_ADDRSTRLEN];
1042       char dbuf[INET6_ADDRSTRLEN];
1043       char xbuf[INET6_ADDRSTRLEN];
1044
1045       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1046                   "Routing %s packet from %s:%u -> %s:%u to destination %s:%u\n",
1047                   (protocol == IPPROTO_TCP) ? "TCP" : "UDP",
1048                   inet_ntop (af, source_ip, sbuf, sizeof (sbuf)),
1049                   source_port,
1050                   inet_ntop (af, destination_ip, dbuf, sizeof (dbuf)),
1051                   destination_port,
1052                   inet_ntop (destination->details.exit_destination.af,
1053                              &destination->details.exit_destination.ip,
1054                              xbuf, sizeof (xbuf)),
1055                   destination_port);
1056     }
1057     for (dt = destination->dt_head; NULL != dt; dt = dt->next)
1058       if (dt->destination_port == destination_port)
1059         break;
1060   }
1061   else
1062   {
1063     {
1064       char sbuf[INET6_ADDRSTRLEN];
1065       char dbuf[INET6_ADDRSTRLEN];
1066
1067       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1068                   "Routing %s packet from %s:%u -> %s:%u to service %s at peer %s\n",
1069                   (protocol == IPPROTO_TCP) ? "TCP" : "UDP",
1070                   inet_ntop (af, source_ip, sbuf, sizeof (sbuf)),
1071                   source_port,
1072                   inet_ntop (af, destination_ip, dbuf, sizeof (dbuf)),
1073                   destination_port,
1074                   GNUNET_h2s (&destination->details.service_destination.service_descriptor),
1075                   GNUNET_i2s (&destination->details.service_destination.target));
1076     }
1077     dt = destination->dt_head;
1078   }
1079   if (NULL == dt)
1080   {
1081     dt = GNUNET_new (struct DestinationChannel);
1082     dt->destination = destination;
1083     GNUNET_CONTAINER_DLL_insert (destination->dt_head,
1084                                  destination->dt_tail,
1085                                  dt);
1086     dt->destination_port = destination_port;
1087   }
1088
1089   /* see if we have an existing channel for this destination */
1090   ts = GNUNET_CONTAINER_multihashmap_get (channel_map,
1091                                           &key);
1092   if (NULL == ts)
1093   {
1094     /* need to either use the existing channel from the destination (if still
1095        available) or create a fresh one */
1096     is_new = GNUNET_YES;
1097     if (NULL == dt->ts)
1098       ts = create_channel_to_destination (dt, af);
1099     else
1100       ts = dt->ts;
1101     if (NULL == ts)
1102       return;
1103     dt->ts = NULL;
1104     ts->destination_container = NULL; /* no longer 'contained' */
1105     /* now bind existing "unbound" channel to our IP/port tuple */
1106     ts->protocol = protocol;
1107     ts->af = af;
1108     if (AF_INET == af)
1109     {
1110       ts->source_ip.v4 = * (const struct in_addr *) source_ip;
1111       ts->destination_ip.v4 = * (const struct in_addr *) destination_ip;
1112     }
1113     else
1114     {
1115       ts->source_ip.v6 = * (const struct in6_addr *) source_ip;
1116       ts->destination_ip.v6 = * (const struct in6_addr *) destination_ip;
1117     }
1118     ts->source_port = source_port;
1119     ts->destination_port = destination_port;
1120     ts->heap_node = GNUNET_CONTAINER_heap_insert (channel_heap,
1121                                                   ts,
1122                                                   GNUNET_TIME_absolute_get ().abs_value_us);
1123     GNUNET_assert (GNUNET_YES ==
1124                    GNUNET_CONTAINER_multihashmap_put (channel_map,
1125                                                       &key,
1126                                                       ts,
1127                                                       GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1128     GNUNET_STATISTICS_update (stats,
1129                               gettext_noop ("# Active channels"),
1130                               1, GNUNET_NO);
1131     while (GNUNET_CONTAINER_multihashmap_size (channel_map) > max_channel_mappings)
1132       expire_channel (ts);
1133   }
1134   else
1135   {
1136     is_new = GNUNET_NO;
1137     GNUNET_CONTAINER_heap_update_cost (channel_heap,
1138                                        ts->heap_node,
1139                                        GNUNET_TIME_absolute_get ().abs_value_us);
1140   }
1141   if (NULL == ts->channel)
1142   {
1143     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1144                 "Packet dropped, channel to %s not yet ready (%s)\n",
1145                 print_channel_destination (&ts->destination),
1146                 (NULL == ts->search)
1147                 ? "EXIT search failed"
1148                 : "EXIT search active");
1149     GNUNET_STATISTICS_update (stats,
1150                               gettext_noop ("# Packets dropped (channel not yet online)"),
1151                               1,
1152                               GNUNET_NO);
1153     return;
1154   }
1155
1156   /* send via channel */
1157   switch (protocol)
1158   {
1159   case IPPROTO_UDP:
1160     if (destination->is_service)
1161     {
1162       struct GNUNET_EXIT_UdpServiceMessage *usm;
1163
1164       mlen = sizeof (struct GNUNET_EXIT_UdpServiceMessage) +
1165         payload_length - sizeof (struct GNUNET_TUN_UdpHeader);
1166       if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1167       {
1168         GNUNET_break (0);
1169         return;
1170       }
1171       tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen);
1172       tnq->len = mlen;
1173       tnq->msg = &tnq[1];
1174       usm = (struct GNUNET_EXIT_UdpServiceMessage *) &tnq[1];
1175       usm->header.size = htons ((uint16_t) mlen);
1176       usm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE);
1177       /* if the source port is below 32000, we assume it has a special
1178          meaning; if not, we pick a random port (this is a heuristic) */
1179       usm->source_port = (ntohs (udp->source_port) < 32000) ? udp->source_port : 0;
1180       usm->destination_port = udp->destination_port;
1181       usm->service_descriptor = destination->details.service_destination.service_descriptor;
1182       memcpy (&usm[1],
1183               &udp[1],
1184               payload_length - sizeof (struct GNUNET_TUN_UdpHeader));
1185     }
1186     else
1187     {
1188       struct GNUNET_EXIT_UdpInternetMessage *uim;
1189       struct in_addr *ip4dst;
1190       struct in6_addr *ip6dst;
1191       void *payload;
1192
1193       mlen = sizeof (struct GNUNET_EXIT_UdpInternetMessage) +
1194         alen + payload_length - sizeof (struct GNUNET_TUN_UdpHeader);
1195       if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1196       {
1197         GNUNET_break (0);
1198         return;
1199       }
1200       tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen);
1201       tnq->len = mlen;
1202       tnq->msg = &tnq[1];
1203       uim = (struct GNUNET_EXIT_UdpInternetMessage *) &tnq[1];
1204       uim->header.size = htons ((uint16_t) mlen);
1205       uim->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET);
1206       uim->af = htonl (destination->details.exit_destination.af);
1207       uim->source_port = (ntohs (udp->source_port) < 32000) ? udp->source_port : 0;
1208       uim->destination_port = udp->destination_port;
1209       switch (destination->details.exit_destination.af)
1210       {
1211       case AF_INET:
1212         ip4dst = (struct in_addr *) &uim[1];
1213         *ip4dst = destination->details.exit_destination.ip.v4;
1214         payload = &ip4dst[1];
1215         break;
1216       case AF_INET6:
1217         ip6dst = (struct in6_addr *) &uim[1];
1218         *ip6dst = destination->details.exit_destination.ip.v6;
1219         payload = &ip6dst[1];
1220         break;
1221       default:
1222         GNUNET_assert (0);
1223       }
1224       memcpy (payload,
1225               &udp[1],
1226               payload_length - sizeof (struct GNUNET_TUN_UdpHeader));
1227     }
1228     break;
1229   case IPPROTO_TCP:
1230     if (is_new)
1231     {
1232       if (destination->is_service)
1233       {
1234         struct GNUNET_EXIT_TcpServiceStartMessage *tsm;
1235
1236         mlen = sizeof (struct GNUNET_EXIT_TcpServiceStartMessage) +
1237           payload_length - sizeof (struct GNUNET_TUN_TcpHeader);
1238         if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1239         {
1240           GNUNET_break (0);
1241           return;
1242         }
1243         tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen);
1244         tnq->len = mlen;
1245         tnq->msg = &tnq[1];
1246         tsm = (struct  GNUNET_EXIT_TcpServiceStartMessage *) &tnq[1];
1247         tsm->header.size = htons ((uint16_t) mlen);
1248         tsm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START);
1249         tsm->reserved = htonl (0);
1250         tsm->service_descriptor = destination->details.service_destination.service_descriptor;
1251         tsm->tcp_header = *tcp;
1252         memcpy (&tsm[1],
1253                 &tcp[1],
1254                 payload_length - sizeof (struct GNUNET_TUN_TcpHeader));
1255       }
1256       else
1257       {
1258         struct GNUNET_EXIT_TcpInternetStartMessage *tim;
1259         struct in_addr *ip4dst;
1260         struct in6_addr *ip6dst;
1261         void *payload;
1262
1263         mlen = sizeof (struct GNUNET_EXIT_TcpInternetStartMessage) +
1264           alen + payload_length - sizeof (struct GNUNET_TUN_TcpHeader);
1265         if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1266         {
1267           GNUNET_break (0);
1268           return;
1269         }
1270         tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen);
1271         tnq->len = mlen;
1272         tnq->msg = &tnq[1];
1273         tim = (struct  GNUNET_EXIT_TcpInternetStartMessage *) &tnq[1];
1274         tim->header.size = htons ((uint16_t) mlen);
1275         tim->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START);
1276         tim->af = htonl (destination->details.exit_destination.af);
1277         tim->tcp_header = *tcp;
1278         switch (destination->details.exit_destination.af)
1279         {
1280         case AF_INET:
1281           ip4dst = (struct in_addr *) &tim[1];
1282           *ip4dst = destination->details.exit_destination.ip.v4;
1283           payload = &ip4dst[1];
1284           break;
1285         case AF_INET6:
1286           ip6dst = (struct in6_addr *) &tim[1];
1287           *ip6dst = destination->details.exit_destination.ip.v6;
1288           payload = &ip6dst[1];
1289           break;
1290         default:
1291           GNUNET_assert (0);
1292         }
1293         memcpy (payload,
1294                 &tcp[1],
1295                 payload_length - sizeof (struct GNUNET_TUN_TcpHeader));
1296       }
1297     }
1298     else
1299     {
1300       struct GNUNET_EXIT_TcpDataMessage *tdm;
1301
1302       mlen = sizeof (struct GNUNET_EXIT_TcpDataMessage) +
1303         payload_length - sizeof (struct GNUNET_TUN_TcpHeader);
1304       if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1305       {
1306         GNUNET_break (0);
1307         return;
1308       }
1309       tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen);
1310       tnq->len = mlen;
1311       tnq->msg = &tnq[1];
1312       tdm = (struct  GNUNET_EXIT_TcpDataMessage *) &tnq[1];
1313       tdm->header.size = htons ((uint16_t) mlen);
1314       tdm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT);
1315       tdm->reserved = htonl (0);
1316       tdm->tcp_header = *tcp;
1317       memcpy (&tdm[1],
1318               &tcp[1],
1319               payload_length - sizeof (struct GNUNET_TUN_TcpHeader));
1320      }
1321     break;
1322   case IPPROTO_ICMP:
1323   case IPPROTO_ICMPV6:
1324     if (destination->is_service)
1325     {
1326       struct GNUNET_EXIT_IcmpServiceMessage *ism;
1327
1328       mlen = sizeof (struct GNUNET_EXIT_IcmpServiceMessage) +
1329         payload_length - sizeof (struct GNUNET_TUN_IcmpHeader);
1330       if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1331       {
1332         GNUNET_break (0);
1333         return;
1334       }
1335       tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen);
1336       tnq->msg = &tnq[1];
1337       ism = (struct GNUNET_EXIT_IcmpServiceMessage *) &tnq[1];
1338       ism->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE);
1339       ism->af = htonl (af); /* need to tell destination ICMP protocol family! */
1340       ism->service_descriptor = destination->details.service_destination.service_descriptor;
1341       ism->icmp_header = *icmp;
1342       /* ICMP protocol translation will be done by the receiver (as we don't know
1343          the target AF); however, we still need to possibly discard the payload
1344          depending on the ICMP type */
1345       switch (af)
1346       {
1347       case AF_INET:
1348         switch (icmp->type)
1349         {
1350         case GNUNET_TUN_ICMPTYPE_ECHO_REPLY:
1351         case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST:
1352           break;
1353         case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE:
1354         case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH:
1355         case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED:
1356           /* throw away ICMP payload, won't be useful for the other side anyway */
1357           payload_length = sizeof (struct GNUNET_TUN_IcmpHeader);
1358           break;
1359         default:
1360           GNUNET_STATISTICS_update (stats,
1361                                     gettext_noop ("# ICMPv4 packets dropped (not allowed)"),
1362                                     1, GNUNET_NO);
1363           return;
1364         }
1365         /* end of AF_INET */
1366         break;
1367       case AF_INET6:
1368         switch (icmp->type)
1369         {
1370         case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
1371         case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
1372         case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
1373         case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM:
1374           /* throw away ICMP payload, won't be useful for the other side anyway */
1375           payload_length = sizeof (struct GNUNET_TUN_IcmpHeader);
1376           break;
1377         case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
1378         case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY:
1379           break;
1380         default:
1381           GNUNET_STATISTICS_update (stats,
1382                                     gettext_noop ("# ICMPv6 packets dropped (not allowed)"),
1383                                     1, GNUNET_NO);
1384           return;
1385         }
1386         /* end of AF_INET6 */
1387         break;
1388       default:
1389         GNUNET_assert (0);
1390         break;
1391       }
1392
1393       /* update length calculations, as payload_length may have changed */
1394       mlen = sizeof (struct GNUNET_EXIT_IcmpServiceMessage) +
1395         alen + payload_length - sizeof (struct GNUNET_TUN_IcmpHeader);
1396       tnq->len = mlen;
1397       ism->header.size = htons ((uint16_t) mlen);
1398       /* finally, copy payload (if there is any left...) */
1399       memcpy (&ism[1],
1400               &icmp[1],
1401               payload_length - sizeof (struct GNUNET_TUN_IcmpHeader));
1402     }
1403     else
1404     {
1405       struct GNUNET_EXIT_IcmpInternetMessage *iim;
1406       struct in_addr *ip4dst;
1407       struct in6_addr *ip6dst;
1408       void *payload;
1409
1410       mlen = sizeof (struct GNUNET_EXIT_IcmpInternetMessage) +
1411         alen + payload_length - sizeof (struct GNUNET_TUN_IcmpHeader);
1412       if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1413       {
1414         GNUNET_break (0);
1415         return;
1416       }
1417       tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen);
1418       tnq->msg = &tnq[1];
1419       iim = (struct GNUNET_EXIT_IcmpInternetMessage *) &tnq[1];
1420       iim->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET);
1421       iim->icmp_header = *icmp;
1422       /* Perform ICMP protocol-translation (depending on destination AF and source AF)
1423          and throw away ICMP payload depending on ICMP message type */
1424       switch (af)
1425       {
1426       case AF_INET:
1427         switch (icmp->type)
1428         {
1429         case GNUNET_TUN_ICMPTYPE_ECHO_REPLY:
1430           if (destination->details.exit_destination.af == AF_INET6)
1431             iim->icmp_header.type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY;
1432           break;
1433         case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST:
1434           if (destination->details.exit_destination.af == AF_INET6)
1435             iim->icmp_header.type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST;
1436           break;
1437         case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE:
1438           if (destination->details.exit_destination.af == AF_INET6)
1439             iim->icmp_header.type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE;
1440           /* throw away IP-payload, exit will have to make it up anyway */
1441           payload_length = sizeof (struct GNUNET_TUN_IcmpHeader);
1442           break;
1443         case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED:
1444           if (destination->details.exit_destination.af == AF_INET6)
1445             iim->icmp_header.type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED;
1446           /* throw away IP-payload, exit will have to make it up anyway */
1447           payload_length = sizeof (struct GNUNET_TUN_IcmpHeader);
1448           break;
1449         case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH:
1450           if (destination->details.exit_destination.af == AF_INET6)
1451             {
1452               GNUNET_STATISTICS_update (stats,
1453                                         gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"),
1454                                         1, GNUNET_NO);
1455               GNUNET_free (tnq);
1456               return;
1457             }
1458           /* throw away IP-payload, exit will have to make it up anyway */
1459           payload_length = sizeof (struct GNUNET_TUN_IcmpHeader);
1460           break;
1461         default:
1462           GNUNET_STATISTICS_update (stats,
1463                                     gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
1464                                     1, GNUNET_NO);
1465           GNUNET_free (tnq);
1466           return;
1467         }
1468         /* end of AF_INET */
1469         break;
1470       case AF_INET6:
1471         switch (icmp->type)
1472           {
1473           case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
1474             if (destination->details.exit_destination.af == AF_INET6)
1475               iim->icmp_header.type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE;
1476             /* throw away IP-payload, exit will have to make it up anyway */
1477             payload_length = sizeof (struct GNUNET_TUN_IcmpHeader);
1478             break;
1479           case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
1480             if (destination->details.exit_destination.af == AF_INET)
1481               iim->icmp_header.type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED;
1482             /* throw away IP-payload, exit will have to make it up anyway */
1483             payload_length = sizeof (struct GNUNET_TUN_IcmpHeader);
1484             break;
1485           case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
1486             if (destination->details.exit_destination.af == AF_INET)
1487             {
1488               GNUNET_STATISTICS_update (stats,
1489                                         gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"),
1490                                         1, GNUNET_NO);
1491               GNUNET_free (tnq);
1492               return;
1493             }
1494             /* throw away IP-payload, exit will have to make it up anyway */
1495             payload_length = sizeof (struct GNUNET_TUN_IcmpHeader);
1496             break;
1497           case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM:
1498             if (destination->details.exit_destination.af == AF_INET)
1499             {
1500               GNUNET_STATISTICS_update (stats,
1501                                         gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"),
1502                                         1, GNUNET_NO);
1503               GNUNET_free (tnq);
1504               return;
1505             }
1506             /* throw away IP-payload, exit will have to make it up anyway */
1507             payload_length = sizeof (struct GNUNET_TUN_IcmpHeader);
1508             break;
1509           case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
1510             if (destination->details.exit_destination.af == AF_INET)
1511               iim->icmp_header.type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST;
1512             break;
1513           case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY:
1514             if (destination->details.exit_destination.af == AF_INET)
1515               iim->icmp_header.type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY;
1516             break;
1517           default:
1518             GNUNET_STATISTICS_update (stats,
1519                                       gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
1520                                       1, GNUNET_NO);
1521             GNUNET_free (tnq);
1522             return;
1523           }
1524         /* end of AF_INET6 */
1525         break;
1526       default:
1527         GNUNET_assert (0);
1528       }
1529       /* update length calculations, as payload_length may have changed */
1530       mlen = sizeof (struct GNUNET_EXIT_IcmpInternetMessage) +
1531         alen + payload_length - sizeof (struct GNUNET_TUN_IcmpHeader);
1532       tnq->len = mlen;
1533       iim->header.size = htons ((uint16_t) mlen);
1534
1535       /* need to tell destination ICMP protocol family! */
1536       iim->af = htonl (destination->details.exit_destination.af);
1537       switch (destination->details.exit_destination.af)
1538       {
1539       case AF_INET:
1540         ip4dst = (struct in_addr *) &iim[1];
1541         *ip4dst = destination->details.exit_destination.ip.v4;
1542         payload = &ip4dst[1];
1543         break;
1544       case AF_INET6:
1545         ip6dst = (struct in6_addr *) &iim[1];
1546         *ip6dst = destination->details.exit_destination.ip.v6;
1547         payload = &ip6dst[1];
1548         break;
1549       default:
1550         GNUNET_assert (0);
1551       }
1552       memcpy (payload,
1553               &icmp[1],
1554               payload_length - sizeof (struct GNUNET_TUN_IcmpHeader));
1555     }
1556     break;
1557   default:
1558     /* not supported above, how can we get here !? */
1559     GNUNET_assert (0);
1560     break;
1561   }
1562   send_to_channel (tnq, ts);
1563 }
1564
1565
1566 /**
1567  * Receive packets from the helper-process (someone send to the local
1568  * virtual channel interface).  Find the destination mapping, and if it
1569  * exists, identify the correct CADET channel (or possibly create it)
1570  * and forward the packet.
1571  *
1572  * @param cls closure, NULL
1573  * @param client NULL
1574  * @param message message we got from the client (VPN channel interface)
1575  */
1576 static int
1577 message_token (void *cls,
1578                void *client,
1579                const struct GNUNET_MessageHeader *message)
1580 {
1581   const struct GNUNET_TUN_Layer2PacketHeader *tun;
1582   size_t mlen;
1583   struct GNUNET_HashCode key;
1584   struct DestinationEntry *de;
1585
1586   GNUNET_STATISTICS_update (stats,
1587                             gettext_noop ("# Packets received from TUN interface"),
1588                             1, GNUNET_NO);
1589   mlen = ntohs (message->size);
1590   if ( (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) ||
1591        (mlen < sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader)) )
1592   {
1593     GNUNET_break (0);
1594     return GNUNET_OK;
1595   }
1596   tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1];
1597   mlen -= (sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader));
1598   switch (ntohs (tun->proto))
1599   {
1600   case ETH_P_IPV6:
1601     {
1602       const struct GNUNET_TUN_IPv6Header *pkt6;
1603
1604       if (mlen < sizeof (struct GNUNET_TUN_IPv6Header))
1605       {
1606         /* blame kernel */
1607         GNUNET_break (0);
1608         return GNUNET_OK;
1609       }
1610       pkt6 = (const struct GNUNET_TUN_IPv6Header *) &tun[1];
1611       get_destination_key_from_ip (AF_INET6,
1612                                    &pkt6->destination_address,
1613                                    &key);
1614       de = GNUNET_CONTAINER_multihashmap_get (destination_map, &key);
1615       if (NULL == de)
1616       {
1617         char buf[INET6_ADDRSTRLEN];
1618
1619         GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1620                     _("Packet received for unmapped destination `%s' (dropping it)\n"),
1621                     inet_ntop (AF_INET6,
1622                                &pkt6->destination_address,
1623                                buf,
1624                                sizeof (buf)));
1625         return GNUNET_OK;
1626       }
1627       route_packet (de,
1628                     AF_INET6,
1629                     pkt6->next_header,
1630                     &pkt6->source_address,
1631                     &pkt6->destination_address,
1632                     &pkt6[1],
1633                     mlen - sizeof (struct GNUNET_TUN_IPv6Header));
1634     }
1635     break;
1636   case ETH_P_IPV4:
1637     {
1638       struct GNUNET_TUN_IPv4Header *pkt4;
1639
1640       if (mlen < sizeof (struct GNUNET_TUN_IPv4Header))
1641       {
1642         /* blame kernel */
1643         GNUNET_break (0);
1644         return GNUNET_OK;
1645       }
1646       pkt4 = (struct GNUNET_TUN_IPv4Header *) &tun[1];
1647       get_destination_key_from_ip (AF_INET,
1648                                    &pkt4->destination_address,
1649                                    &key);
1650       de = GNUNET_CONTAINER_multihashmap_get (destination_map, &key);
1651       if (NULL == de)
1652       {
1653         char buf[INET_ADDRSTRLEN];
1654
1655         GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1656                     _("Packet received for unmapped destination `%s' (dropping it)\n"),
1657                     inet_ntop (AF_INET,
1658                                &pkt4->destination_address,
1659                                buf,
1660                                sizeof (buf)));
1661         return GNUNET_OK;
1662       }
1663       if (pkt4->header_length * 4 != sizeof (struct GNUNET_TUN_IPv4Header))
1664       {
1665         GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1666                     _("Received IPv4 packet with options (dropping it)\n"));
1667         return GNUNET_OK;
1668       }
1669       route_packet (de,
1670                     AF_INET,
1671                     pkt4->protocol,
1672                     &pkt4->source_address,
1673                     &pkt4->destination_address,
1674                     &pkt4[1],
1675                     mlen - sizeof (struct GNUNET_TUN_IPv4Header));
1676     }
1677     break;
1678   default:
1679     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1680                 _("Received packet of unknown protocol %d from TUN (dropping it)\n"),
1681                 (unsigned int) ntohs (tun->proto));
1682     break;
1683   }
1684   return GNUNET_OK;
1685 }
1686
1687
1688 /**
1689  * Synthesize a plausible ICMP payload for an ICMP error
1690  * response on the given channel.
1691  *
1692  * @param ts channel information
1693  * @param ipp IPv4 header to fill in (ICMP payload)
1694  * @param udp "UDP" header to fill in (ICMP payload); might actually
1695  *            also be the first 8 bytes of the TCP header
1696  */
1697 static void
1698 make_up_icmpv4_payload (struct ChannelState *ts,
1699                         struct GNUNET_TUN_IPv4Header *ipp,
1700                         struct GNUNET_TUN_UdpHeader *udp)
1701 {
1702   GNUNET_TUN_initialize_ipv4_header (ipp,
1703                                      ts->protocol,
1704                                      sizeof (struct GNUNET_TUN_TcpHeader),
1705                                      &ts->source_ip.v4,
1706                                      &ts->destination_ip.v4);
1707   udp->source_port = htons (ts->source_port);
1708   udp->destination_port = htons (ts->destination_port);
1709   udp->len = htons (0);
1710   udp->crc = htons (0);
1711 }
1712
1713
1714 /**
1715  * Synthesize a plausible ICMP payload for an ICMP error
1716  * response on the given channel.
1717  *
1718  * @param ts channel information
1719  * @param ipp IPv6 header to fill in (ICMP payload)
1720  * @param udp "UDP" header to fill in (ICMP payload); might actually
1721  *            also be the first 8 bytes of the TCP header
1722  */
1723 static void
1724 make_up_icmpv6_payload (struct ChannelState *ts,
1725                         struct GNUNET_TUN_IPv6Header *ipp,
1726                         struct GNUNET_TUN_UdpHeader *udp)
1727 {
1728   GNUNET_TUN_initialize_ipv6_header (ipp,
1729                                      ts->protocol,
1730                                      sizeof (struct GNUNET_TUN_TcpHeader),
1731                                      &ts->source_ip.v6,
1732                                      &ts->destination_ip.v6);
1733   udp->source_port = htons (ts->source_port);
1734   udp->destination_port = htons (ts->destination_port);
1735   udp->len = htons (0);
1736   udp->crc = htons (0);
1737 }
1738
1739
1740 /**
1741  * We got an ICMP packet back from the CADET channel.  Pass it on to the
1742  * local virtual interface via the helper.
1743  *
1744  * @param cls closure, NULL
1745  * @param channel connection to the other end
1746  * @param channel_ctx pointer to our 'struct ChannelState *'
1747  * @param message the actual message
1748  * @return #GNUNET_OK to keep the connection open,
1749  *         #GNUNET_SYSERR to close it (signal serious error)
1750  */
1751 static int
1752 receive_icmp_back (void *cls,
1753                    struct GNUNET_CADET_Channel *channel,
1754                    void **channel_ctx,
1755                    const struct GNUNET_MessageHeader *message)
1756 {
1757   struct ChannelState *ts = *channel_ctx;
1758   const struct GNUNET_EXIT_IcmpToVPNMessage *i2v;
1759   size_t mlen;
1760
1761   GNUNET_STATISTICS_update (stats,
1762                             gettext_noop ("# ICMP packets received from cadet"),
1763                             1, GNUNET_NO);
1764   mlen = ntohs (message->size);
1765   if (mlen < sizeof (struct GNUNET_EXIT_IcmpToVPNMessage))
1766   {
1767     GNUNET_break_op (0);
1768     return GNUNET_SYSERR;
1769   }
1770   if (NULL == ts->heap_node)
1771   {
1772     GNUNET_break_op (0);
1773     return GNUNET_SYSERR;
1774   }
1775   if (AF_UNSPEC == ts->af)
1776   {
1777     GNUNET_break_op (0);
1778     return GNUNET_SYSERR;
1779   }
1780   i2v = (const struct GNUNET_EXIT_IcmpToVPNMessage *) message;
1781   mlen -= sizeof (struct GNUNET_EXIT_IcmpToVPNMessage);
1782   {
1783     char sbuf[INET6_ADDRSTRLEN];
1784     char dbuf[INET6_ADDRSTRLEN];
1785
1786     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1787                 "Received ICMP packet from cadet, sending %u bytes from %s -> %s via TUN\n",
1788                 (unsigned int) mlen,
1789                 inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof (sbuf)),
1790                 inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf)));
1791   }
1792   switch (ts->af)
1793   {
1794   case AF_INET:
1795     {
1796       size_t size = sizeof (struct GNUNET_TUN_IPv4Header)
1797         + sizeof (struct GNUNET_TUN_IcmpHeader)
1798         + sizeof (struct GNUNET_MessageHeader) +
1799         sizeof (struct GNUNET_TUN_Layer2PacketHeader) +
1800         mlen;
1801       {
1802         /* reserve some extra space in case we have an ICMP type here where
1803            we will need to make up the payload ourselves */
1804         char buf[size + sizeof (struct GNUNET_TUN_IPv4Header) + 8] GNUNET_ALIGN;
1805         struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
1806         struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1];
1807         struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *) &tun[1];
1808         struct GNUNET_TUN_IcmpHeader *icmp = (struct GNUNET_TUN_IcmpHeader *) &ipv4[1];
1809         msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1810         tun->flags = htons (0);
1811         tun->proto = htons (ETH_P_IPV4);
1812         GNUNET_TUN_initialize_ipv4_header (ipv4,
1813                                            IPPROTO_ICMP,
1814                                            sizeof (struct GNUNET_TUN_IcmpHeader) + mlen,
1815                                            &ts->destination_ip.v4,
1816                                            &ts->source_ip.v4);
1817         *icmp = i2v->icmp_header;
1818         memcpy (&icmp[1],
1819                 &i2v[1],
1820                 mlen);
1821         /* For some ICMP types, we need to adjust (make up) the payload here.
1822            Also, depending on the AF used on the other side, we have to
1823            do ICMP PT (translate ICMP types) */
1824         switch (ntohl (i2v->af))
1825         {
1826         case AF_INET:
1827           switch (icmp->type)
1828           {
1829           case GNUNET_TUN_ICMPTYPE_ECHO_REPLY:
1830           case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST:
1831             break;
1832           case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE:
1833           case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH:
1834           case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED:
1835             {
1836               struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header *) &icmp[1];
1837               struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1];
1838
1839               if (mlen != 0)
1840                 {
1841                   /* sender did not strip ICMP payload? */
1842                   GNUNET_break_op (0);
1843                   return GNUNET_SYSERR;
1844                 }
1845               size += sizeof (struct GNUNET_TUN_IPv4Header) + 8;
1846               GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
1847               make_up_icmpv4_payload (ts, ipp, udp);
1848             }
1849             break;
1850           default:
1851             GNUNET_break_op (0);
1852             GNUNET_STATISTICS_update (stats,
1853                                       gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
1854                                       1, GNUNET_NO);
1855             return GNUNET_SYSERR;
1856           }
1857           /* end AF_INET */
1858           break;
1859         case AF_INET6:
1860           /* ICMP PT 6-to-4 and possibly making up payloads */
1861           switch (icmp->type)
1862           {
1863           case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
1864             icmp->type = GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE;
1865             {
1866               struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header *) &icmp[1];
1867               struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1];
1868
1869               if (mlen != 0)
1870                 {
1871                   /* sender did not strip ICMP payload? */
1872                   GNUNET_break_op (0);
1873                   return GNUNET_SYSERR;
1874                 }
1875               size += sizeof (struct GNUNET_TUN_IPv4Header) + 8;
1876               GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
1877               make_up_icmpv4_payload (ts, ipp, udp);
1878             }
1879             break;
1880           case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
1881             icmp->type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED;
1882             {
1883               struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header *) &icmp[1];
1884               struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1];
1885
1886               if (mlen != 0)
1887                 {
1888                   /* sender did not strip ICMP payload? */
1889                   GNUNET_break_op (0);
1890                   return GNUNET_SYSERR;
1891                 }
1892               size += sizeof (struct GNUNET_TUN_IPv4Header) + 8;
1893               GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
1894               make_up_icmpv4_payload (ts, ipp, udp);
1895             }
1896             break;
1897           case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
1898           case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM:
1899             GNUNET_STATISTICS_update (stats,
1900                                       gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"),
1901                                       1, GNUNET_NO);
1902             return GNUNET_OK;
1903           case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
1904             icmp->type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST;
1905             break;
1906           case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY:
1907             icmp->type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY;
1908             break;
1909           default:
1910             GNUNET_break_op (0);
1911             GNUNET_STATISTICS_update (stats,
1912                                       gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
1913                                       1, GNUNET_NO);
1914             return GNUNET_SYSERR;
1915           }
1916           /* end AF_INET6 */
1917           break;
1918         default:
1919           GNUNET_break_op (0);
1920           return GNUNET_SYSERR;
1921         }
1922         msg->size = htons (size);
1923         GNUNET_TUN_calculate_icmp_checksum (icmp,
1924                                             &i2v[1],
1925                                             mlen);
1926         (void) GNUNET_HELPER_send (helper_handle,
1927                                    msg,
1928                                    GNUNET_YES,
1929                                    NULL, NULL);
1930       }
1931     }
1932     break;
1933   case AF_INET6:
1934     {
1935       size_t size = sizeof (struct GNUNET_TUN_IPv6Header)
1936         + sizeof (struct GNUNET_TUN_IcmpHeader)
1937         + sizeof (struct GNUNET_MessageHeader) +
1938         sizeof (struct GNUNET_TUN_Layer2PacketHeader) +
1939         mlen;
1940       {
1941         char buf[size + sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
1942         struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
1943         struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1];
1944         struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *) &tun[1];
1945         struct GNUNET_TUN_IcmpHeader *icmp = (struct GNUNET_TUN_IcmpHeader *) &ipv6[1];
1946         msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1947         tun->flags = htons (0);
1948         tun->proto = htons (ETH_P_IPV6);
1949         GNUNET_TUN_initialize_ipv6_header (ipv6,
1950                                            IPPROTO_ICMPV6,
1951                                            sizeof (struct GNUNET_TUN_IcmpHeader) + mlen,
1952                                            &ts->destination_ip.v6,
1953                                            &ts->source_ip.v6);
1954         *icmp = i2v->icmp_header;
1955         memcpy (&icmp[1],
1956                 &i2v[1],
1957                 mlen);
1958
1959         /* For some ICMP types, we need to adjust (make up) the payload here.
1960            Also, depending on the AF used on the other side, we have to
1961            do ICMP PT (translate ICMP types) */
1962         switch (ntohl (i2v->af))
1963         {
1964         case AF_INET:
1965           /* ICMP PT 4-to-6 and possibly making up payloads */
1966           switch (icmp->type)
1967           {
1968           case GNUNET_TUN_ICMPTYPE_ECHO_REPLY:
1969             icmp->type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY;
1970             break;
1971           case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST:
1972             icmp->type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST;
1973             break;
1974           case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE:
1975             icmp->type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE;
1976             {
1977               struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header *) &icmp[1];
1978               struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1];
1979
1980               if (mlen != 0)
1981                 {
1982                   /* sender did not strip ICMP payload? */
1983                   GNUNET_break_op (0);
1984                   return GNUNET_SYSERR;
1985                 }
1986               size += sizeof (struct GNUNET_TUN_IPv6Header) + 8;
1987               GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
1988               make_up_icmpv6_payload (ts, ipp, udp);
1989             }
1990             break;
1991           case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED:
1992             icmp->type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED;
1993             {
1994               struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header *) &icmp[1];
1995               struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1];
1996
1997               if (mlen != 0)
1998                 {
1999                   /* sender did not strip ICMP payload? */
2000                   GNUNET_break_op (0);
2001                   return GNUNET_SYSERR;
2002                 }
2003               size += sizeof (struct GNUNET_TUN_IPv6Header) + 8;
2004               GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
2005               make_up_icmpv6_payload (ts, ipp, udp);
2006             }
2007             break;
2008           case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH:
2009             GNUNET_STATISTICS_update (stats,
2010                                       gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"),
2011                                       1, GNUNET_NO);
2012             return GNUNET_OK;
2013           default:
2014             GNUNET_break_op (0);
2015             GNUNET_STATISTICS_update (stats,
2016                                       gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
2017                                       1, GNUNET_NO);
2018             return GNUNET_SYSERR;
2019           }
2020           /* end AF_INET */
2021           break;
2022         case AF_INET6:
2023           switch (icmp->type)
2024           {
2025           case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
2026           case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
2027           case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
2028           case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM:
2029             {
2030               struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header *) &icmp[1];
2031               struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1];
2032
2033               if (mlen != 0)
2034                 {
2035                   /* sender did not strip ICMP payload? */
2036                   GNUNET_break_op (0);
2037                   return GNUNET_SYSERR;
2038                 }
2039               size += sizeof (struct GNUNET_TUN_IPv6Header) + 8;
2040               GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
2041               make_up_icmpv6_payload (ts, ipp, udp);
2042             }
2043             break;
2044           case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
2045             break;
2046           default:
2047             GNUNET_break_op (0);
2048             GNUNET_STATISTICS_update (stats,
2049                                       gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
2050                                       1, GNUNET_NO);
2051             return GNUNET_SYSERR;
2052           }
2053           /* end AF_INET6 */
2054           break;
2055         default:
2056           GNUNET_break_op (0);
2057           return GNUNET_SYSERR;
2058         }
2059         msg->size = htons (size);
2060         GNUNET_TUN_calculate_icmp_checksum (icmp,
2061                                             &i2v[1], mlen);
2062         (void) GNUNET_HELPER_send (helper_handle,
2063                                    msg,
2064                                    GNUNET_YES,
2065                                    NULL, NULL);
2066       }
2067     }
2068     break;
2069   default:
2070     GNUNET_assert (0);
2071   }
2072   GNUNET_CONTAINER_heap_update_cost (channel_heap,
2073                                      ts->heap_node,
2074                                      GNUNET_TIME_absolute_get ().abs_value_us);
2075   return GNUNET_OK;
2076 }
2077
2078
2079 /**
2080  * We got a UDP packet back from the CADET channel.  Pass it on to the
2081  * local virtual interface via the helper.
2082  *
2083  * @param cls closure, NULL
2084  * @param channel connection to the other end
2085  * @param channel_ctx pointer to our 'struct ChannelState *'
2086  * @param message the actual message
2087  * @return #GNUNET_OK to keep the connection open,
2088  *         #GNUNET_SYSERR to close it (signal serious error)
2089  */
2090 static int
2091 receive_udp_back (void *cls,
2092                   struct GNUNET_CADET_Channel *channel,
2093                   void **channel_ctx,
2094                   const struct GNUNET_MessageHeader *message)
2095 {
2096   struct ChannelState *ts = *channel_ctx;
2097   const struct GNUNET_EXIT_UdpReplyMessage *reply;
2098   size_t mlen;
2099
2100   GNUNET_STATISTICS_update (stats,
2101                             gettext_noop ("# UDP packets received from cadet"),
2102                             1, GNUNET_NO);
2103   mlen = ntohs (message->size);
2104   if (mlen < sizeof (struct GNUNET_EXIT_UdpReplyMessage))
2105   {
2106     GNUNET_break_op (0);
2107     return GNUNET_SYSERR;
2108   }
2109   if (NULL == ts->heap_node)
2110   {
2111     GNUNET_break_op (0);
2112     return GNUNET_SYSERR;
2113   }
2114   if (AF_UNSPEC == ts->af)
2115   {
2116     GNUNET_break_op (0);
2117     return GNUNET_SYSERR;
2118   }
2119   reply = (const struct GNUNET_EXIT_UdpReplyMessage *) message;
2120   mlen -= sizeof (struct GNUNET_EXIT_UdpReplyMessage);
2121   {
2122     char sbuf[INET6_ADDRSTRLEN];
2123     char dbuf[INET6_ADDRSTRLEN];
2124
2125     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2126                 "Received UDP reply from cadet, sending %u bytes from %s:%u -> %s:%u via TUN\n",
2127                 (unsigned int) mlen,
2128                 inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof (sbuf)),
2129                 ts->destination_port,
2130                 inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf)),
2131                 ts->source_port);
2132   }
2133   switch (ts->af)
2134   {
2135   case AF_INET:
2136     {
2137       size_t size = sizeof (struct GNUNET_TUN_IPv4Header)
2138         + sizeof (struct GNUNET_TUN_UdpHeader)
2139         + sizeof (struct GNUNET_MessageHeader) +
2140         sizeof (struct GNUNET_TUN_Layer2PacketHeader) +
2141         mlen;
2142       {
2143         char buf[size] GNUNET_ALIGN;
2144         struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
2145         struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1];
2146         struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *) &tun[1];
2147         struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipv4[1];
2148         msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
2149         msg->size = htons (size);
2150         tun->flags = htons (0);
2151         tun->proto = htons (ETH_P_IPV4);
2152         GNUNET_TUN_initialize_ipv4_header (ipv4,
2153                                            IPPROTO_UDP,
2154                                            sizeof (struct GNUNET_TUN_UdpHeader) + mlen,
2155                                            &ts->destination_ip.v4,
2156                                            &ts->source_ip.v4);
2157         if (0 == ntohs (reply->source_port))
2158           udp->source_port = htons (ts->destination_port);
2159         else
2160           udp->source_port = reply->source_port;
2161         if (0 == ntohs (reply->destination_port))
2162           udp->destination_port = htons (ts->source_port);
2163         else
2164           udp->destination_port = reply->destination_port;
2165         udp->len = htons (mlen + sizeof (struct GNUNET_TUN_UdpHeader));
2166         GNUNET_TUN_calculate_udp4_checksum (ipv4,
2167                                             udp,
2168                                             &reply[1],
2169                                             mlen);
2170         memcpy (&udp[1],
2171                 &reply[1],
2172                 mlen);
2173         (void) GNUNET_HELPER_send (helper_handle,
2174                                    msg,
2175                                    GNUNET_YES,
2176                                    NULL, NULL);
2177       }
2178     }
2179     break;
2180   case AF_INET6:
2181     {
2182       size_t size = sizeof (struct GNUNET_TUN_IPv6Header)
2183         + sizeof (struct GNUNET_TUN_UdpHeader)
2184         + sizeof (struct GNUNET_MessageHeader) +
2185         sizeof (struct GNUNET_TUN_Layer2PacketHeader) +
2186         mlen;
2187       {
2188         char buf[size] GNUNET_ALIGN;
2189         struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
2190         struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1];
2191         struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *) &tun[1];
2192         struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipv6[1];
2193         msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
2194         msg->size = htons (size);
2195         tun->flags = htons (0);
2196         tun->proto = htons (ETH_P_IPV6);
2197         GNUNET_TUN_initialize_ipv6_header (ipv6,
2198                                            IPPROTO_UDP,
2199                                            sizeof (struct GNUNET_TUN_UdpHeader) + mlen,
2200                                            &ts->destination_ip.v6,
2201                                            &ts->source_ip.v6);
2202         if (0 == ntohs (reply->source_port))
2203           udp->source_port = htons (ts->destination_port);
2204         else
2205           udp->source_port = reply->source_port;
2206         if (0 == ntohs (reply->destination_port))
2207           udp->destination_port = htons (ts->source_port);
2208         else
2209           udp->destination_port = reply->destination_port;
2210         udp->len = htons (mlen + sizeof (struct GNUNET_TUN_UdpHeader));
2211         GNUNET_TUN_calculate_udp6_checksum (ipv6,
2212                                             udp,
2213                                             &reply[1], mlen);
2214         memcpy (&udp[1],
2215                 &reply[1],
2216                 mlen);
2217         (void) GNUNET_HELPER_send (helper_handle,
2218                                    msg,
2219                                    GNUNET_YES,
2220                                    NULL, NULL);
2221       }
2222     }
2223     break;
2224   default:
2225     GNUNET_assert (0);
2226   }
2227   GNUNET_CONTAINER_heap_update_cost (channel_heap,
2228                                      ts->heap_node,
2229                                      GNUNET_TIME_absolute_get ().abs_value_us);
2230   return GNUNET_OK;
2231 }
2232
2233
2234 /**
2235  * We got a TCP packet back from the CADET channel.  Pass it on to the
2236  * local virtual interface via the helper.
2237  *
2238  * @param cls closure, NULL
2239  * @param channel connection to the other end
2240  * @param channel_ctx pointer to our `struct ChannelState *`
2241  * @param message the actual message
2242  * @return #GNUNET_OK to keep the connection open,
2243  *         #GNUNET_SYSERR to close it (signal serious error)
2244  */
2245 static int
2246 receive_tcp_back (void *cls,
2247                   struct GNUNET_CADET_Channel *channel,
2248                   void **channel_ctx,
2249                   const struct GNUNET_MessageHeader *message)
2250 {
2251   struct ChannelState *ts = *channel_ctx;
2252   const struct GNUNET_EXIT_TcpDataMessage *data;
2253   size_t mlen;
2254
2255   GNUNET_STATISTICS_update (stats,
2256                             gettext_noop ("# TCP packets received from cadet"),
2257                             1, GNUNET_NO);
2258   mlen = ntohs (message->size);
2259   if (mlen < sizeof (struct GNUNET_EXIT_TcpDataMessage))
2260   {
2261     GNUNET_break_op (0);
2262     return GNUNET_SYSERR;
2263   }
2264   if (NULL == ts->heap_node)
2265   {
2266     GNUNET_break_op (0);
2267     return GNUNET_SYSERR;
2268   }
2269   data = (const struct GNUNET_EXIT_TcpDataMessage *) message;
2270   mlen -= sizeof (struct GNUNET_EXIT_TcpDataMessage);
2271   {
2272     char sbuf[INET6_ADDRSTRLEN];
2273     char dbuf[INET6_ADDRSTRLEN];
2274
2275     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2276                 "Received TCP reply from cadet, sending %u bytes from %s:%u -> %s:%u via TUN\n",
2277                 (unsigned int) mlen,
2278                 inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof (sbuf)),
2279                 ts->destination_port,
2280                 inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf)),
2281                 ts->source_port);
2282   }
2283   if (data->tcp_header.off * 4 < sizeof (struct GNUNET_TUN_TcpHeader))
2284   {
2285     GNUNET_break_op (0);
2286     return GNUNET_SYSERR;
2287   }
2288   switch (ts->af)
2289   {
2290   case AF_INET:
2291     {
2292       size_t size = sizeof (struct GNUNET_TUN_IPv4Header)
2293         + sizeof (struct GNUNET_TUN_TcpHeader)
2294         + sizeof (struct GNUNET_MessageHeader) +
2295         sizeof (struct GNUNET_TUN_Layer2PacketHeader) +
2296         mlen;
2297       {
2298         char buf[size] GNUNET_ALIGN;
2299         struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
2300         struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1];
2301         struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *) &tun[1];
2302         struct GNUNET_TUN_TcpHeader *tcp = (struct GNUNET_TUN_TcpHeader *) &ipv4[1];
2303         msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
2304         msg->size = htons (size);
2305         tun->flags = htons (0);
2306         tun->proto = htons (ETH_P_IPV4);
2307         GNUNET_TUN_initialize_ipv4_header (ipv4,
2308                                            IPPROTO_TCP,
2309                                            sizeof (struct GNUNET_TUN_TcpHeader) + mlen,
2310                                            &ts->destination_ip.v4,
2311                                            &ts->source_ip.v4);
2312         *tcp = data->tcp_header;
2313         tcp->source_port = htons (ts->destination_port);
2314         tcp->destination_port = htons (ts->source_port);
2315         GNUNET_TUN_calculate_tcp4_checksum (ipv4,
2316                                             tcp,
2317                                             &data[1],
2318                                             mlen);
2319         memcpy (&tcp[1],
2320                 &data[1],
2321                 mlen);
2322         (void) GNUNET_HELPER_send (helper_handle,
2323                                    msg,
2324                                    GNUNET_YES,
2325                                    NULL, NULL);
2326       }
2327     }
2328     break;
2329   case AF_INET6:
2330     {
2331       size_t size = sizeof (struct GNUNET_TUN_IPv6Header)
2332         + sizeof (struct GNUNET_TUN_TcpHeader)
2333         + sizeof (struct GNUNET_MessageHeader) +
2334         sizeof (struct GNUNET_TUN_Layer2PacketHeader) +
2335         mlen;
2336       {
2337         char buf[size] GNUNET_ALIGN;
2338         struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
2339         struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1];
2340         struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *) &tun[1];
2341         struct GNUNET_TUN_TcpHeader *tcp = (struct GNUNET_TUN_TcpHeader *) &ipv6[1];
2342         msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
2343         msg->size = htons (size);
2344         tun->flags = htons (0);
2345         tun->proto = htons (ETH_P_IPV6);
2346         GNUNET_TUN_initialize_ipv6_header (ipv6,
2347                                            IPPROTO_TCP,
2348                                            sizeof (struct GNUNET_TUN_TcpHeader) + mlen,
2349                                            &ts->destination_ip.v6,
2350                                            &ts->source_ip.v6);
2351         *tcp = data->tcp_header;
2352         tcp->source_port = htons (ts->destination_port);
2353         tcp->destination_port = htons (ts->source_port);
2354         GNUNET_TUN_calculate_tcp6_checksum (ipv6,
2355                                             tcp,
2356                                             &data[1],
2357                                             mlen);
2358         memcpy (&tcp[1],
2359                 &data[1],
2360                 mlen);
2361         (void) GNUNET_HELPER_send (helper_handle,
2362                                    msg,
2363                                    GNUNET_YES,
2364                                    NULL, NULL);
2365       }
2366     }
2367     break;
2368   }
2369   GNUNET_CONTAINER_heap_update_cost (channel_heap,
2370                                      ts->heap_node,
2371                                      GNUNET_TIME_absolute_get ().abs_value_us);
2372   return GNUNET_OK;
2373 }
2374
2375
2376 /**
2377  * Allocate an IPv4 address from the range of the channel
2378  * for a new redirection.
2379  *
2380  * @param v4 where to store the address
2381  * @return #GNUNET_OK on success,
2382  *         #GNUNET_SYSERR on error
2383  */
2384 static int
2385 allocate_v4_address (struct in_addr *v4)
2386 {
2387   const char *ipv4addr = vpn_argv[4];
2388   const char *ipv4mask = vpn_argv[5];
2389   struct in_addr addr;
2390   struct in_addr mask;
2391   struct in_addr rnd;
2392   struct GNUNET_HashCode key;
2393   unsigned int tries;
2394
2395   GNUNET_assert (1 == inet_pton (AF_INET, ipv4addr, &addr));
2396   GNUNET_assert (1 == inet_pton (AF_INET, ipv4mask, &mask));
2397   /* Given 192.168.0.1/255.255.0.0, we want a mask
2398      of '192.168.255.255', thus:  */
2399   mask.s_addr = addr.s_addr | ~mask.s_addr;
2400   tries = 0;
2401   do
2402     {
2403       tries++;
2404       if (tries > 16)
2405       {
2406         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2407                     _("Failed to find unallocated IPv4 address in VPN's range\n"));
2408         return GNUNET_SYSERR;
2409       }
2410       /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
2411       rnd.s_addr = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
2412                                              UINT32_MAX);
2413       v4->s_addr = (addr.s_addr | rnd.s_addr) & mask.s_addr;
2414       get_destination_key_from_ip (AF_INET,
2415                                    v4,
2416                                    &key);
2417     }
2418   while ( (GNUNET_YES ==
2419            GNUNET_CONTAINER_multihashmap_contains (destination_map,
2420                                                    &key)) ||
2421           (v4->s_addr == addr.s_addr) ||
2422           (v4->s_addr == mask.s_addr) );
2423   return GNUNET_OK;
2424 }
2425
2426
2427 /**
2428  * Allocate an IPv6 address from the range of the channel
2429  * for a new redirection.
2430  *
2431  * @param v6 where to store the address
2432  * @return #GNUNET_OK on success,
2433  *         #GNUNET_SYSERR on error
2434  */
2435 static int
2436 allocate_v6_address (struct in6_addr *v6)
2437 {
2438   const char *ipv6addr = vpn_argv[2];
2439   struct in6_addr addr;
2440   struct in6_addr mask;
2441   struct in6_addr rnd;
2442   int i;
2443   struct GNUNET_HashCode key;
2444   unsigned int tries;
2445
2446   GNUNET_assert (1 == inet_pton (AF_INET6, ipv6addr, &addr));
2447   GNUNET_assert (ipv6prefix < 128);
2448   /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
2449      thus: */
2450   mask = addr;
2451   for (i=127;i>=ipv6prefix;i--)
2452     mask.s6_addr[i / 8] |= (1 << (i % 8));
2453
2454   /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */
2455   tries = 0;
2456   do
2457     {
2458       tries++;
2459       if (tries > 16)
2460         {
2461           GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2462                       _("Failed to find unallocated IPv6 address in VPN's range\n"));
2463           return GNUNET_SYSERR;
2464
2465         }
2466       for (i=0;i<16;i++)
2467         {
2468           rnd.s6_addr[i] = (unsigned char) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
2469                                                                      256);
2470           v6->s6_addr[i]
2471             = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
2472         }
2473       get_destination_key_from_ip (AF_INET6,
2474                                    v6,
2475                                    &key);
2476     }
2477   while ( (GNUNET_YES ==
2478            GNUNET_CONTAINER_multihashmap_contains (destination_map,
2479                                                    &key)) ||
2480           (0 == memcmp (v6,
2481                         &addr,
2482                         sizeof (struct in6_addr))) ||
2483           (0 == memcmp (v6,
2484                         &mask,
2485                         sizeof (struct in6_addr))) );
2486   return GNUNET_OK;
2487 }
2488
2489
2490 /**
2491  * Free resources occupied by a destination entry.
2492  *
2493  * @param de entry to free
2494  */
2495 static void
2496 free_destination_entry (struct DestinationEntry *de)
2497 {
2498   struct DestinationChannel *dt;
2499
2500   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2501               "Cleaning up destination entry `%s'\n",
2502               print_channel_destination (de));
2503   GNUNET_STATISTICS_update (stats,
2504                             gettext_noop ("# Active destinations"),
2505                             -1, GNUNET_NO);
2506   while (NULL != (dt = de->dt_head))
2507   {
2508     GNUNET_CONTAINER_DLL_remove (de->dt_head,
2509                                  de->dt_tail,
2510                                  dt);
2511     if (NULL != dt->ts)
2512     {
2513       free_channel_state (dt->ts);
2514       GNUNET_assert (NULL == dt->ts);
2515     }
2516     GNUNET_free (dt);
2517   }
2518   if (NULL != de->heap_node)
2519   {
2520     GNUNET_CONTAINER_heap_remove_node (de->heap_node);
2521     de->heap_node = NULL;
2522     GNUNET_assert (GNUNET_YES ==
2523                    GNUNET_CONTAINER_multihashmap_remove (destination_map,
2524                                                          &de->key,
2525                                                          de));
2526   }
2527   GNUNET_free (de);
2528 }
2529
2530
2531 /**
2532  * We have too many active destinations.  Clean up the oldest destination.
2533  *
2534  * @param except destination that must NOT be cleaned up, even if it is the oldest
2535  */
2536 static void
2537 expire_destination (struct DestinationEntry *except)
2538 {
2539   struct DestinationEntry *de;
2540
2541   de = GNUNET_CONTAINER_heap_peek (destination_heap);
2542   GNUNET_assert (NULL != de);
2543   if (except == de)
2544     return; /* can't do this */
2545   free_destination_entry (de);
2546 }
2547
2548
2549 /**
2550  * Allocate an IP address for the response.
2551  *
2552  * @param result_af desired address family; set to the actual
2553  *        address family; can initially be AF_UNSPEC if there
2554  *        is no preference; will be set to AF_UNSPEC if the
2555  *        allocation failed
2556  * @param addr set to either v4 or v6 depending on which
2557  *         storage location was used; set to NULL if allocation failed
2558  * @param v4 storage space for an IPv4 address
2559  * @param v6 storage space for an IPv6 address
2560  * @return #GNUNET_OK normally, #GNUNET_SYSERR if `* result_af` was
2561  *         an unsupported address family (not AF_INET, AF_INET6 or AF_UNSPEC)
2562  */
2563 static int
2564 allocate_response_ip (int *result_af,
2565                       void **addr,
2566                       struct in_addr *v4,
2567                       struct in6_addr *v6)
2568 {
2569   *addr = NULL;
2570   switch (*result_af)
2571   {
2572   case AF_INET:
2573     if (GNUNET_OK !=
2574         allocate_v4_address (v4))
2575       *result_af = AF_UNSPEC;
2576     else
2577       *addr = v4;
2578     break;
2579   case AF_INET6:
2580     if (GNUNET_OK !=
2581         allocate_v6_address (v6))
2582       *result_af = AF_UNSPEC;
2583     else
2584       *addr = v6;
2585     break;
2586   case AF_UNSPEC:
2587     if (GNUNET_OK ==
2588         allocate_v4_address (v4))
2589     {
2590       *addr = v4;
2591       *result_af = AF_INET;
2592     }
2593     else if (GNUNET_OK ==
2594         allocate_v6_address (v6))
2595     {
2596       *addr = v6;
2597       *result_af = AF_INET6;
2598     }
2599     break;
2600   default:
2601     GNUNET_break (0);
2602     return GNUNET_SYSERR;
2603   }
2604   return GNUNET_OK;
2605 }
2606
2607
2608 /**
2609  * A client asks us to setup a redirection via some exit node to a
2610  * particular IP.  Setup the redirection and give the client the
2611  * allocated IP.
2612  *
2613  * @param cls unused
2614  * @param client requesting client
2615  * @param message redirection request (a `struct RedirectToIpRequestMessage`)
2616  */
2617 static void
2618 service_redirect_to_ip (void *cls,
2619                         struct GNUNET_SERVER_Client *client,
2620                         const struct GNUNET_MessageHeader *message)
2621 {
2622   size_t mlen;
2623   size_t alen;
2624   const struct RedirectToIpRequestMessage *msg;
2625   int addr_af;
2626   int result_af;
2627   struct in_addr v4;
2628   struct in6_addr v6;
2629   void *addr;
2630   struct DestinationEntry *de;
2631   struct GNUNET_HashCode key;
2632
2633   /* validate and parse request */
2634   mlen = ntohs (message->size);
2635   if (mlen < sizeof (struct RedirectToIpRequestMessage))
2636   {
2637     GNUNET_break (0);
2638     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2639     return;
2640   }
2641   alen = mlen - sizeof (struct RedirectToIpRequestMessage);
2642   msg = (const struct RedirectToIpRequestMessage *) message;
2643   addr_af = (int) htonl (msg->addr_af);
2644   switch (addr_af)
2645   {
2646   case AF_INET:
2647     if (alen != sizeof (struct in_addr))
2648     {
2649       GNUNET_break (0);
2650       GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2651       return;
2652     }
2653     break;
2654   case AF_INET6:
2655     if (alen != sizeof (struct in6_addr))
2656     {
2657       GNUNET_break (0);
2658       GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2659       return;
2660     }
2661     break;
2662   default:
2663     GNUNET_break (0);
2664     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2665     return;
2666   }
2667
2668   /* allocate response IP */
2669   result_af = (int) htonl (msg->result_af);
2670   if (GNUNET_OK != allocate_response_ip (&result_af,
2671                                          &addr,
2672                                          &v4, &v6))
2673   {
2674     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2675     return;
2676   }
2677   /* send reply with our IP address */
2678   send_client_reply (client,
2679                      msg->request_id,
2680                      result_af,
2681                      addr);
2682   if (result_af == AF_UNSPEC)
2683   {
2684     /* failure, we're done */
2685     GNUNET_SERVER_receive_done (client, GNUNET_OK);
2686     return;
2687   }
2688
2689   {
2690     char sbuf[INET6_ADDRSTRLEN];
2691     char dbuf[INET6_ADDRSTRLEN];
2692
2693     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2694                 "Allocated address %s for redirection via exit to %s\n",
2695                 inet_ntop (result_af, addr, sbuf, sizeof (sbuf)),
2696                 inet_ntop (addr_af,
2697                            &msg[1], dbuf, sizeof (dbuf)));
2698   }
2699
2700   /* setup destination record */
2701   de = GNUNET_new (struct DestinationEntry);
2702   de->is_service = GNUNET_NO;
2703   de->details.exit_destination.af = addr_af;
2704   memcpy (&de->details.exit_destination.ip,
2705           &msg[1],
2706           alen);
2707   get_destination_key_from_ip (result_af,
2708                                addr,
2709                                &key);
2710   de->key = key;
2711   GNUNET_assert (GNUNET_OK ==
2712                  GNUNET_CONTAINER_multihashmap_put (destination_map,
2713                                                     &key,
2714                                                     de,
2715                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
2716   de->heap_node = GNUNET_CONTAINER_heap_insert (destination_heap,
2717                                                 de,
2718                                                 GNUNET_TIME_absolute_ntoh (msg->expiration_time).abs_value_us);
2719   GNUNET_STATISTICS_update (stats,
2720                             gettext_noop ("# Active destinations"),
2721                             1, GNUNET_NO);
2722   while (GNUNET_CONTAINER_multihashmap_size (destination_map) > max_destination_mappings)
2723     expire_destination (de);
2724   GNUNET_SERVER_receive_done (client, GNUNET_OK);
2725 }
2726
2727
2728 /**
2729  * A client asks us to setup a redirection to a particular peer
2730  * offering a service.  Setup the redirection and give the client the
2731  * allocated IP.
2732  *
2733  * @param cls unused
2734  * @param client requesting client
2735  * @param message redirection request (a `struct RedirectToPeerRequestMessage`)
2736  */
2737 static void
2738 service_redirect_to_service (void *cls,
2739                              struct GNUNET_SERVER_Client *client,
2740                              const struct GNUNET_MessageHeader *message)
2741 {
2742   const struct RedirectToServiceRequestMessage *msg;
2743   int result_af;
2744   struct in_addr v4;
2745   struct in6_addr v6;
2746   void *addr;
2747   struct DestinationEntry *de;
2748   struct GNUNET_HashCode key;
2749   struct ChannelState *ts;
2750   struct DestinationChannel *dt;
2751
2752   /*  parse request */
2753   msg = (const struct RedirectToServiceRequestMessage *) message;
2754
2755   /* allocate response IP */
2756   result_af = (int) htonl (msg->result_af);
2757   if (GNUNET_OK != allocate_response_ip (&result_af,
2758                                          &addr,
2759                                          &v4, &v6))
2760   {
2761     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2762     return;
2763   }
2764   send_client_reply (client,
2765                      msg->request_id,
2766                      result_af,
2767                      addr);
2768   if (result_af == AF_UNSPEC)
2769   {
2770     /* failure, we're done */
2771     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2772                 _("Failed to allocate IP address for new destination\n"));
2773     GNUNET_SERVER_receive_done (client, GNUNET_OK);
2774     return;
2775   }
2776
2777   {
2778     char sbuf[INET6_ADDRSTRLEN];
2779
2780     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2781                 "Allocated address %s for redirection to service %s on peer %s\n",
2782                 inet_ntop (result_af, addr, sbuf, sizeof (sbuf)),
2783                 GNUNET_h2s (&msg->service_descriptor),
2784                 GNUNET_i2s (&msg->target));
2785   }
2786
2787   /* setup destination record */
2788   de = GNUNET_new (struct DestinationEntry);
2789   de->is_service = GNUNET_YES;
2790   de->details.service_destination.service_descriptor = msg->service_descriptor;
2791   de->details.service_destination.target = msg->target;
2792   get_destination_key_from_ip (result_af,
2793                                addr,
2794                                &key);
2795   de->key = key;
2796   GNUNET_assert (GNUNET_OK ==
2797                  GNUNET_CONTAINER_multihashmap_put (destination_map,
2798                                                     &key,
2799                                                     de,
2800                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
2801   de->heap_node = GNUNET_CONTAINER_heap_insert (destination_heap,
2802                                                 de,
2803                                                 GNUNET_TIME_absolute_ntoh (msg->expiration_time).abs_value_us);
2804   while (GNUNET_CONTAINER_multihashmap_size (destination_map) > max_destination_mappings)
2805     expire_destination (de);
2806
2807   dt = GNUNET_new (struct DestinationChannel);
2808   dt->destination = de;
2809   GNUNET_CONTAINER_DLL_insert (de->dt_head,
2810                                de->dt_tail,
2811                                dt);
2812   ts = create_channel_to_destination (dt,
2813                                       result_af);
2814   switch (result_af)
2815   {
2816   case AF_INET:
2817     ts->destination_ip.v4 = v4;
2818     break;
2819   case AF_INET6:
2820     ts->destination_ip.v6 = v6;
2821     break;
2822   default:
2823     GNUNET_assert (0);
2824   }
2825   /* we're done */
2826   GNUNET_SERVER_receive_done (client, GNUNET_OK);
2827 }
2828
2829
2830 /**
2831  * Function called whenever a channel is destroyed.  Should clean up
2832  * any associated state.
2833  *
2834  * @param cls closure (set from #GNUNET_CADET_connect)
2835  * @param channel connection to the other end (henceforth invalid)
2836  * @param channel_ctx place where local state associated
2837  *                   with the channel is stored (our `struct ChannelState`)
2838  */
2839 static void
2840 channel_cleaner (void *cls,
2841                  const struct GNUNET_CADET_Channel *channel,
2842                  void *channel_ctx)
2843 {
2844   struct ChannelState *ts = channel_ctx;
2845
2846   ts->channel = NULL; /* we must not call GNUNET_CADET_channel_destroy() anymore */
2847   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2848               "CADET notified us about death of channel to `%s'\n",
2849               print_channel_destination (&ts->destination));
2850   free_channel_state (ts);
2851 }
2852
2853
2854 /**
2855  * Free memory occupied by an entry in the destination map.
2856  *
2857  * @param cls unused
2858  * @param key unused
2859  * @param value a `struct DestinationEntry *`
2860  * @return #GNUNET_OK (continue to iterate)
2861  */
2862 static int
2863 cleanup_destination (void *cls,
2864                      const struct GNUNET_HashCode *key,
2865                      void *value)
2866 {
2867   struct DestinationEntry *de = value;
2868
2869   free_destination_entry (de);
2870   return GNUNET_OK;
2871 }
2872
2873
2874 /**
2875  * Free memory occupied by an entry in the channel map.
2876  *
2877  * @param cls unused
2878  * @param key unused
2879  * @param value a `struct ChannelState *`
2880  * @return #GNUNET_OK (continue to iterate)
2881  */
2882 static int
2883 cleanup_channel (void *cls,
2884                  const struct GNUNET_HashCode *key,
2885                  void *value)
2886 {
2887   struct ChannelState *ts = value;
2888
2889   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2890               "Tearing down channel to `%s' during cleanup\n",
2891               print_channel_destination (&ts->destination));
2892   free_channel_state (ts);
2893   return GNUNET_OK;
2894 }
2895
2896
2897 /**
2898  * Function scheduled as very last function, cleans up after us
2899  *
2900  * @param cls unused
2901  * @param tc unused
2902  */
2903 static void
2904 cleanup (void *cls,
2905          const struct GNUNET_SCHEDULER_TaskContext *tc)
2906 {
2907   unsigned int i;
2908
2909   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2910               "VPN is shutting down\n");
2911   if (NULL != destination_map)
2912   {
2913     GNUNET_CONTAINER_multihashmap_iterate (destination_map,
2914                                            &cleanup_destination,
2915                                            NULL);
2916     GNUNET_CONTAINER_multihashmap_destroy (destination_map);
2917     destination_map = NULL;
2918   }
2919   if (NULL != destination_heap)
2920   {
2921     GNUNET_CONTAINER_heap_destroy (destination_heap);
2922     destination_heap = NULL;
2923   }
2924   if (NULL != channel_map)
2925   {
2926     GNUNET_CONTAINER_multihashmap_iterate (channel_map,
2927                                            &cleanup_channel,
2928                                            NULL);
2929     GNUNET_CONTAINER_multihashmap_destroy (channel_map);
2930     channel_map = NULL;
2931   }
2932   if (NULL != channel_heap)
2933   {
2934     GNUNET_CONTAINER_heap_destroy (channel_heap);
2935     channel_heap = NULL;
2936   }
2937   if (NULL != cadet_handle)
2938   {
2939     GNUNET_CADET_disconnect (cadet_handle);
2940     cadet_handle = NULL;
2941   }
2942   if (NULL != helper_handle)
2943   {
2944     GNUNET_HELPER_stop (helper_handle, GNUNET_NO);
2945     helper_handle = NULL;
2946   }
2947   if (NULL != nc)
2948   {
2949     GNUNET_SERVER_notification_context_destroy (nc);
2950     nc = NULL;
2951   }
2952   if (NULL != stats)
2953   {
2954     GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
2955     stats = NULL;
2956   }
2957   for (i=0;i<5;i++)
2958     GNUNET_free_non_null (vpn_argv[i]);
2959 }
2960
2961
2962 /**
2963  * Main function that will be run by the scheduler.
2964  *
2965  * @param cls closure
2966  * @param server the initialized server
2967  * @param cfg_ configuration
2968  */
2969 static void
2970 run (void *cls,
2971      struct GNUNET_SERVER_Handle *server,
2972      const struct GNUNET_CONFIGURATION_Handle *cfg_)
2973 {
2974   static const struct GNUNET_SERVER_MessageHandler service_handlers[] = {
2975     /* callback, cls, type, size */
2976     { &service_redirect_to_ip, NULL, GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP, 0},
2977     { &service_redirect_to_service, NULL,
2978      GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_SERVICE,
2979      sizeof (struct RedirectToServiceRequestMessage) },
2980     {NULL, NULL, 0, 0}
2981   };
2982   static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = {
2983     { &receive_udp_back, GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY, 0},
2984     { &receive_tcp_back, GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN, 0},
2985     { &receive_icmp_back, GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN, 0},
2986     {NULL, 0, 0}
2987   };
2988   char *ifname;
2989   char *ipv6addr;
2990   char *ipv6prefix_s;
2991   char *ipv4addr;
2992   char *ipv4mask;
2993   struct in_addr v4;
2994   struct in6_addr v6;
2995   char *binary;
2996
2997   binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-vpn");
2998
2999   if (GNUNET_YES !=
3000       GNUNET_OS_check_helper_binary (binary,
3001                                      GNUNET_YES,
3002                                      "-d gnunet-vpn - - 169.1.3.3.7 255.255.255.0")) //ipv4 only please!
3003   {
3004     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3005                 "`%s' is not SUID, refusing to run.\n",
3006                 "gnunet-helper-vpn");
3007     GNUNET_free (binary);
3008     global_ret = 1;
3009     /* we won't "really" exit here, as the 'service' is still running;
3010        however, as no handlers are registered, the service won't do
3011        anything either */
3012     return;
3013   }
3014   GNUNET_free (binary);
3015   cfg = cfg_;
3016   stats = GNUNET_STATISTICS_create ("vpn", cfg);
3017   if (GNUNET_OK !=
3018       GNUNET_CONFIGURATION_get_value_number (cfg, "VPN", "MAX_MAPPING",
3019                                              &max_destination_mappings))
3020     max_destination_mappings = 200;
3021   if (GNUNET_OK !=
3022       GNUNET_CONFIGURATION_get_value_number (cfg, "VPN", "MAX_TUNNELS",
3023                                              &max_channel_mappings))
3024     max_channel_mappings = 200;
3025
3026   destination_map = GNUNET_CONTAINER_multihashmap_create (max_destination_mappings * 2, GNUNET_NO);
3027   destination_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
3028   channel_map = GNUNET_CONTAINER_multihashmap_create (max_channel_mappings * 2, GNUNET_NO);
3029   channel_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
3030
3031
3032   vpn_argv[0] = GNUNET_strdup ("vpn-gnunet");
3033   if (GNUNET_SYSERR ==
3034       GNUNET_CONFIGURATION_get_value_string (cfg, "VPN", "IFNAME", &ifname))
3035   {
3036     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "VPN", "IFNAME");
3037     GNUNET_SCHEDULER_shutdown ();
3038     return;
3039   }
3040   vpn_argv[1] = ifname;
3041   ipv6addr = NULL;
3042   if (GNUNET_OK == GNUNET_NETWORK_test_pf (PF_INET6))
3043   {
3044     if ( (GNUNET_SYSERR ==
3045           GNUNET_CONFIGURATION_get_value_string (cfg, "VPN", "IPV6ADDR",
3046                                                  &ipv6addr) ||
3047           (1 != inet_pton (AF_INET6, ipv6addr, &v6))) )
3048     {
3049       GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "VPN", "IPV6ADDR",
3050                                  _("Must specify valid IPv6 address"));
3051       GNUNET_SCHEDULER_shutdown ();
3052       GNUNET_free_non_null (ipv6addr);
3053       return;
3054     }
3055     vpn_argv[2] = ipv6addr;
3056     ipv6prefix_s = NULL;
3057     if (GNUNET_SYSERR ==
3058         GNUNET_CONFIGURATION_get_value_string (cfg, "VPN", "IPV6PREFIX",
3059                                                &ipv6prefix_s))
3060     {
3061       GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "VPN", "IPV6PREFIX");
3062       GNUNET_SCHEDULER_shutdown ();
3063       GNUNET_free_non_null (ipv6prefix_s);
3064       return;
3065     }
3066     vpn_argv[3] = ipv6prefix_s;
3067     if ( (GNUNET_OK !=
3068           GNUNET_CONFIGURATION_get_value_number (cfg, "VPN",
3069                                                  "IPV6PREFIX",
3070                                                  &ipv6prefix)) ||
3071          (ipv6prefix >= 127) )
3072     {
3073       GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "VPN", "IPV4MASK",
3074                                  _("Must specify valid IPv6 mask"));
3075       GNUNET_SCHEDULER_shutdown ();
3076       return;
3077     }
3078   }
3079   else
3080   {
3081     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3082                 _("IPv6 support disabled as this system does not support IPv6\n"));
3083     vpn_argv[2] = GNUNET_strdup ("-");
3084     vpn_argv[3] = GNUNET_strdup ("-");
3085   }
3086   if (GNUNET_OK == GNUNET_NETWORK_test_pf (PF_INET))
3087   {
3088     ipv4addr = NULL;
3089     if ( (GNUNET_SYSERR ==
3090           GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4ADDR",
3091                                                  &ipv4addr) ||
3092           (1 != inet_pton (AF_INET, ipv4addr, &v4))) )
3093     {
3094       GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "VPN", "IPV4ADDR",
3095                                  _("Must specify valid IPv4 address"));
3096       GNUNET_SCHEDULER_shutdown ();
3097       GNUNET_free_non_null (ipv4addr);
3098       return;
3099     }
3100     vpn_argv[4] = ipv4addr;
3101     ipv4mask = NULL;
3102     if ( (GNUNET_SYSERR ==
3103           GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4MASK",
3104                                                  &ipv4mask) ||
3105           (1 != inet_pton (AF_INET, ipv4mask, &v4))) )
3106     {
3107       GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "VPN", "IPV4MASK",
3108                                  _("Must specify valid IPv4 mask"));
3109       GNUNET_SCHEDULER_shutdown ();
3110       GNUNET_free_non_null (ipv4mask);
3111       return;
3112     }
3113     vpn_argv[5] = ipv4mask;
3114   }
3115   else
3116   {
3117     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3118                 _("IPv4 support disabled as this system does not support IPv4\n"));
3119     vpn_argv[4] = GNUNET_strdup ("-");
3120     vpn_argv[5] = GNUNET_strdup ("-");
3121   }
3122   vpn_argv[6] = NULL;
3123
3124   cadet_handle =
3125     GNUNET_CADET_connect (cfg_, NULL,
3126                          NULL,
3127                          &channel_cleaner,
3128                          cadet_handlers,
3129                          NULL);
3130   helper_handle = GNUNET_HELPER_start (GNUNET_NO,
3131                                        "gnunet-helper-vpn", vpn_argv,
3132                                        &message_token, NULL, NULL);
3133   nc = GNUNET_SERVER_notification_context_create (server, 1);
3134   GNUNET_SERVER_add_handlers (server, service_handlers);
3135   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls);
3136 }
3137
3138
3139 /**
3140  * The main function of the VPN service.
3141  *
3142  * @param argc number of arguments from the command line
3143  * @param argv command line arguments
3144  * @return 0 ok, 1 on error
3145  */
3146 int
3147 main (int argc, char *const *argv)
3148 {
3149   return (GNUNET_OK ==
3150           GNUNET_SERVICE_run (argc, argv, "vpn",
3151                               GNUNET_SERVICE_OPTION_NONE,
3152                               &run, NULL)) ? global_ret : 1;
3153 }
3154
3155 /* end of gnunet-service-vpn.c */