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