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