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