test
[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   struct 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 unsigned long long 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 (struct GNUNET_HashCode *hash, 
329                     const struct RedirectInformation *ri)
330 {
331   char *off;
332
333   memset (hash, 0, sizeof (struct 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                     struct GNUNET_HashCode *state_key)
393 {
394   struct RedirectInformation ri;
395   struct 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 struct GNUNET_HashCode *desc,
446               uint16_t destination_port)
447 {
448   char key[sizeof (struct GNUNET_HashCode) + sizeof (uint16_t)];
449
450   memcpy (&key[0], &destination_port, sizeof (uint16_t));
451   memcpy (&key[sizeof(uint16_t)], desc, sizeof (struct GNUNET_HashCode));
452   return GNUNET_CONTAINER_multihashmap_get (service_map,
453                                             (struct 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 struct 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 (struct GNUNET_HashCode) + sizeof (uint16_t)];
494   struct 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 (struct GNUNET_HashCode));
500   if (GNUNET_OK !=
501       GNUNET_CONTAINER_multihashmap_put (service_map,
502                                          (struct GNUNET_HashCode *) key,
503                                          service,
504                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
505   {
506     free_service_record (NULL, (struct 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                                                GNUNET_TIME_UNIT_FOREVER_REL,
539                                                NULL,
540                                                tnq->len,
541                                                &send_to_peer_notify_callback,
542                                                s);
543     return 0;
544   }
545   GNUNET_assert (size >= tnq->len);
546   memcpy (buf, tnq->payload, tnq->len);
547   size = tnq->len;
548   GNUNET_CONTAINER_DLL_remove (s->head, 
549                                s->tail,
550                                tnq);  
551   GNUNET_free (tnq);
552   if (NULL != (tnq = s->head))
553     s->th = GNUNET_MESH_notify_transmit_ready (tunnel, 
554                                                GNUNET_NO /* corking */, 
555                                                GNUNET_TIME_UNIT_FOREVER_REL,
556                                                NULL,
557                                                tnq->len,
558                                                &send_to_peer_notify_callback,
559                                                s);
560   GNUNET_STATISTICS_update (stats,
561                             gettext_noop ("# Bytes transmitted via mesh tunnels"),
562                             size, GNUNET_NO);
563   return size;
564 }
565
566
567 /**
568  * Send the given packet via the mesh tunnel.
569  *
570  * @param mesh_tunnel destination
571  * @param tnq message to queue
572  */
573 static void
574 send_packet_to_mesh_tunnel (struct GNUNET_MESH_Tunnel *mesh_tunnel,
575                             struct TunnelMessageQueue *tnq)
576 {
577   struct TunnelState *s;
578
579   s = GNUNET_MESH_tunnel_get_data (mesh_tunnel);
580   GNUNET_assert (NULL != s);
581   GNUNET_CONTAINER_DLL_insert_tail (s->head, s->tail, tnq);
582   if (NULL == s->th)
583     s->th = GNUNET_MESH_notify_transmit_ready (mesh_tunnel,
584                                                GNUNET_NO /* cork */,
585                                                GNUNET_TIME_UNIT_FOREVER_REL,
586                                                NULL, tnq->len,
587                                                &send_to_peer_notify_callback,
588                                                s);
589 }
590
591
592 /**
593  * @brief Handles an ICMP packet received from the helper.
594  *
595  * @param icmp A pointer to the Packet
596  * @param pktlen number of bytes in 'icmp'
597  * @param af address family (AFINET or AF_INET6)
598  * @param destination_ip destination IP-address of the IP packet (should 
599  *                       be our local address)
600  * @param source_ip original source IP-address of the IP packet (should
601  *                       be the original destination address)
602  */
603 static void
604 icmp_from_helper (const struct GNUNET_TUN_IcmpHeader *icmp, 
605                   size_t pktlen,
606                   int af,
607                   const void *destination_ip, 
608                   const void *source_ip)
609 {
610   struct TunnelState *state;
611   struct TunnelMessageQueue *tnq;
612   struct GNUNET_EXIT_IcmpToVPNMessage *i2v;
613   const struct GNUNET_TUN_IPv4Header *ipv4;
614   const struct GNUNET_TUN_IPv6Header *ipv6;
615   const struct GNUNET_TUN_UdpHeader *udp;
616   size_t mlen;
617   uint16_t source_port;
618   uint16_t destination_port;
619   uint8_t protocol;
620
621   {
622     char sbuf[INET6_ADDRSTRLEN];
623     char dbuf[INET6_ADDRSTRLEN];
624     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
625                 "Received ICMP packet going from %s to %s\n",
626                 inet_ntop (af,
627                            source_ip,
628                            sbuf, sizeof (sbuf)),
629                 inet_ntop (af,
630                            destination_ip,
631                            dbuf, sizeof (dbuf)));    
632   }
633   if (pktlen < sizeof (struct GNUNET_TUN_IcmpHeader))
634   {
635     /* blame kernel */
636     GNUNET_break (0);
637     return;
638   }
639
640   /* Find out if this is an ICMP packet in response to an existing
641      TCP/UDP packet and if so, figure out ports / protocol of the
642      existing session from the IP data in the ICMP payload */
643   source_port = 0;
644   destination_port = 0;
645   switch (af)
646   {
647   case AF_INET:
648     protocol = IPPROTO_ICMP;
649     switch (icmp->type)
650       {
651       case GNUNET_TUN_ICMPTYPE_ECHO_REPLY:
652       case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST:
653         break;
654       case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE:
655       case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH:
656       case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED:
657         if (pktlen < 
658             sizeof (struct GNUNET_TUN_IcmpHeader) +
659             sizeof (struct GNUNET_TUN_IPv4Header) + 8)
660         {
661           /* blame kernel */
662           GNUNET_break (0);
663           return;
664         }
665         ipv4 = (const struct GNUNET_TUN_IPv4Header *) &icmp[1];
666         protocol = ipv4->protocol;
667         /* could be TCP or UDP, but both have the ports in the right
668            place, so that doesn't matter here */
669         udp = (const struct GNUNET_TUN_UdpHeader *) &ipv4[1];
670         /* swap ports, as they are from the original message */
671         destination_port = ntohs (udp->source_port);
672         source_port = ntohs (udp->destination_port);
673         /* throw away ICMP payload, won't be useful for the other side anyway */
674         pktlen = sizeof (struct GNUNET_TUN_IcmpHeader);
675         break;
676       default:
677         GNUNET_STATISTICS_update (stats,
678                                   gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
679                                   1, GNUNET_NO);
680         return;
681       }
682     break;
683   case AF_INET6:
684     protocol = IPPROTO_ICMPV6;
685     switch (icmp->type)
686       {
687       case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
688       case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
689       case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
690       case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM:
691         if (pktlen < 
692             sizeof (struct GNUNET_TUN_IcmpHeader) +
693             sizeof (struct GNUNET_TUN_IPv6Header) + 8)
694         {
695           /* blame kernel */
696           GNUNET_break (0);
697           return;
698         }
699         ipv6 = (const struct GNUNET_TUN_IPv6Header *) &icmp[1];
700         protocol = ipv6->next_header;
701         /* could be TCP or UDP, but both have the ports in the right
702            place, so that doesn't matter here */
703         udp = (const struct GNUNET_TUN_UdpHeader *) &ipv6[1];
704         /* swap ports, as they are from the original message */
705         destination_port = ntohs (udp->source_port);
706         source_port = ntohs (udp->destination_port);
707         /* throw away ICMP payload, won't be useful for the other side anyway */
708         pktlen = sizeof (struct GNUNET_TUN_IcmpHeader);
709         break;
710       case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
711       case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY:
712         break;
713       default:
714         GNUNET_STATISTICS_update (stats,
715                                   gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
716                                   1, GNUNET_NO);
717         return;
718       }
719     break;
720   default:
721     GNUNET_assert (0);
722   }
723   switch (protocol)
724   {
725   case IPPROTO_ICMP:
726     state = get_redirect_state (af, IPPROTO_ICMP,
727                                 source_ip, 0,
728                                 destination_ip, 0,
729                                 NULL);
730     break;
731   case IPPROTO_ICMPV6:
732     state = get_redirect_state (af, IPPROTO_ICMPV6,
733                                 source_ip, 0,
734                                 destination_ip, 0,
735                                 NULL);
736     break;
737   case IPPROTO_UDP:
738     state = get_redirect_state (af, IPPROTO_UDP,
739                                 source_ip,
740                                 source_port,
741                                 destination_ip,
742                                 destination_port,
743                                 NULL);
744     break;
745   case IPPROTO_TCP:
746     state = get_redirect_state (af, IPPROTO_TCP,
747                                 source_ip,
748                                 source_port,
749                                 destination_ip,
750                                 destination_port,
751                                 NULL);
752     break;
753   default:
754     GNUNET_STATISTICS_update (stats,
755                               gettext_noop ("# ICMP packets dropped (not allowed)"),
756                               1, GNUNET_NO);
757     return;
758   }
759   if (NULL == state)
760   {
761     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
762                 _("ICMP Packet dropped, have no matching connection information\n"));
763     return;
764   }
765   mlen = sizeof (struct GNUNET_EXIT_IcmpToVPNMessage) + pktlen - sizeof (struct GNUNET_TUN_IcmpHeader);
766   tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueue) + mlen);  
767   tnq->payload = &tnq[1];
768   tnq->len = mlen;
769   i2v = (struct GNUNET_EXIT_IcmpToVPNMessage *) &tnq[1];
770   i2v->header.size = htons ((uint16_t) mlen);
771   i2v->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN);
772   i2v->af = htonl (af);
773   memcpy (&i2v->icmp_header,
774           icmp,
775           pktlen);
776   send_packet_to_mesh_tunnel (state->tunnel,
777                               tnq);
778 }
779
780
781 /**
782  * @brief Handles an UDP packet received from the helper.
783  *
784  * @param udp A pointer to the Packet
785  * @param pktlen number of bytes in 'udp'
786  * @param af address family (AFINET or AF_INET6)
787  * @param destination_ip destination IP-address of the IP packet (should 
788  *                       be our local address)
789  * @param source_ip original source IP-address of the IP packet (should
790  *                       be the original destination address)
791  */
792 static void
793 udp_from_helper (const struct GNUNET_TUN_UdpHeader *udp, 
794                  size_t pktlen,
795                  int af,
796                  const void *destination_ip, 
797                  const void *source_ip)
798 {
799   struct TunnelState *state;
800   struct TunnelMessageQueue *tnq;
801   struct GNUNET_EXIT_UdpReplyMessage *urm;
802   size_t mlen;
803
804   {
805     char sbuf[INET6_ADDRSTRLEN];
806     char dbuf[INET6_ADDRSTRLEN];
807     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
808                 "Received UDP packet going from %s:%u to %s:%u\n",
809                 inet_ntop (af,
810                            source_ip,
811                            sbuf, sizeof (sbuf)),
812                 (unsigned int) ntohs (udp->source_port),
813                 inet_ntop (af,
814                            destination_ip,
815                            dbuf, sizeof (dbuf)),
816                 (unsigned int) ntohs (udp->destination_port));
817   }
818   if (pktlen < sizeof (struct GNUNET_TUN_UdpHeader))
819   {
820     /* blame kernel */
821     GNUNET_break (0);
822     return;
823   }
824   if (pktlen != ntohs (udp->len))
825   {
826     /* blame kernel */
827     GNUNET_break (0);
828     return;
829   }
830   state = get_redirect_state (af, IPPROTO_UDP,
831                               source_ip,
832                               ntohs (udp->source_port),
833                               destination_ip,
834                               ntohs (udp->destination_port),
835                               NULL);
836   if (NULL == state)
837   {
838     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
839                 _("UDP Packet dropped, have no matching connection information\n"));
840     return;
841   }
842   mlen = sizeof (struct GNUNET_EXIT_UdpReplyMessage) + pktlen - sizeof (struct GNUNET_TUN_UdpHeader);
843   tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueue) + mlen);  
844   tnq->payload = &tnq[1];
845   tnq->len = mlen;
846   urm = (struct GNUNET_EXIT_UdpReplyMessage *) &tnq[1];
847   urm->header.size = htons ((uint16_t) mlen);
848   urm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY);
849   urm->source_port = htons (0);
850   urm->destination_port = htons (0);
851   memcpy (&urm[1],
852           &udp[1],
853           pktlen - sizeof (struct GNUNET_TUN_UdpHeader));
854   send_packet_to_mesh_tunnel (state->tunnel,
855                               tnq);
856 }
857
858
859 /**
860  * @brief Handles a TCP packet received from the helper.
861  *
862  * @param tcp A pointer to the Packet
863  * @param pktlen the length of the packet, including its TCP header
864  * @param af address family (AFINET or AF_INET6)
865  * @param destination_ip destination IP-address of the IP packet (should 
866  *                       be our local address)
867  * @param source_ip original source IP-address of the IP packet (should
868  *                       be the original destination address)
869  */
870 static void
871 tcp_from_helper (const struct GNUNET_TUN_TcpHeader *tcp, 
872                  size_t pktlen,
873                  int af,
874                  const void *destination_ip,
875                  const void *source_ip)
876 {
877   struct TunnelState *state;
878   char buf[pktlen] GNUNET_ALIGN;
879   struct GNUNET_TUN_TcpHeader *mtcp;
880   struct GNUNET_EXIT_TcpDataMessage *tdm;
881   struct TunnelMessageQueue *tnq;
882   size_t mlen;
883
884   {
885     char sbuf[INET6_ADDRSTRLEN];
886     char dbuf[INET6_ADDRSTRLEN];
887     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
888                 "Received TCP packet with %u bytes going from %s:%u to %s:%u\n",
889                 pktlen - sizeof (struct GNUNET_TUN_TcpHeader),
890                 inet_ntop (af,
891                            source_ip,
892                            sbuf, sizeof (sbuf)),
893                 (unsigned int) ntohs (tcp->source_port),
894                 inet_ntop (af,
895                            destination_ip,
896                            dbuf, sizeof (dbuf)),
897                 (unsigned int) ntohs (tcp->destination_port));
898   }
899   if (pktlen < sizeof (struct GNUNET_TUN_TcpHeader))
900   {
901     /* blame kernel */
902     GNUNET_break (0);
903     return;
904   }
905   state = get_redirect_state (af, IPPROTO_TCP,
906                               source_ip, 
907                               ntohs (tcp->source_port),
908                               destination_ip,
909                               ntohs (tcp->destination_port),
910                               NULL);
911   if (NULL == state)
912   {
913     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
914                 _("TCP Packet dropped, have no matching connection information\n"));
915     
916     return;
917   }
918   /* mug port numbers and crc to avoid information leakage;
919      sender will need to lookup the correct values anyway */
920   memcpy (buf, tcp, pktlen);  
921   mtcp = (struct GNUNET_TUN_TcpHeader *) buf;
922   mtcp->source_port = 0;
923   mtcp->destination_port = 0;
924   mtcp->crc = 0;
925
926   mlen = sizeof (struct GNUNET_EXIT_TcpDataMessage) + (pktlen - sizeof (struct GNUNET_TUN_TcpHeader));
927   if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
928   {
929     GNUNET_break (0);
930     return;
931   }
932
933   tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueue) + mlen);
934   tnq->payload = &tnq[1];
935   tnq->len = mlen;
936   tdm = (struct GNUNET_EXIT_TcpDataMessage *) &tnq[1];
937   tdm->header.size = htons ((uint16_t) mlen);
938   tdm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN);
939   tdm->reserved = htonl (0);
940   memcpy (&tdm->tcp_header,
941           buf, 
942           pktlen);
943   send_packet_to_mesh_tunnel (state->tunnel,
944                               tnq);
945 }
946
947
948 /**
949  * Receive packets from the helper-process
950  *
951  * @param cls unused
952  * @param client unsued
953  * @param message message received from helper
954  */
955 static int
956 message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED,
957                const struct GNUNET_MessageHeader *message)
958 {
959   const struct GNUNET_TUN_Layer2PacketHeader *pkt_tun;
960   size_t size;
961
962   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
963               "Got %u-byte message of type %u from gnunet-helper-exit\n",
964               ntohs (message->size),
965               ntohs (message->type));
966   GNUNET_STATISTICS_update (stats,
967                             gettext_noop ("# Packets received from TUN"),
968                             1, GNUNET_NO);
969   if (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER)
970   {
971     GNUNET_break (0);
972     return GNUNET_OK;
973   }
974   size = ntohs (message->size);
975   if (size < sizeof (struct GNUNET_TUN_Layer2PacketHeader) + sizeof (struct GNUNET_MessageHeader))
976   {
977     GNUNET_break (0);
978     return GNUNET_OK;
979   }
980   GNUNET_STATISTICS_update (stats,
981                             gettext_noop ("# Bytes received from TUN"),
982                             size, GNUNET_NO);
983   pkt_tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1];
984   size -= sizeof (struct GNUNET_TUN_Layer2PacketHeader) + sizeof (struct GNUNET_MessageHeader);
985   switch (ntohs (pkt_tun->proto))
986   {
987   case ETH_P_IPV4:
988     {
989       const struct GNUNET_TUN_IPv4Header *pkt4;
990
991       if (size < sizeof (struct GNUNET_TUN_IPv4Header))
992       {
993         /* Kernel to blame? */
994         GNUNET_break (0);
995         return GNUNET_OK;
996       }
997       pkt4 = (const struct GNUNET_TUN_IPv4Header *) &pkt_tun[1];
998       if (size != ntohs (pkt4->total_length))
999       {
1000         /* Kernel to blame? */
1001         GNUNET_break (0);
1002         return GNUNET_OK;
1003       }
1004       if (pkt4->header_length * 4 != sizeof (struct GNUNET_TUN_IPv4Header))
1005       {
1006         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1007                     _("IPv4 packet options received.  Ignored.\n"));
1008         return GNUNET_OK;
1009       }
1010       
1011       size -= sizeof (struct GNUNET_TUN_IPv4Header);
1012       switch (pkt4->protocol)
1013       {
1014       case IPPROTO_UDP:
1015         udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt4[1], size,
1016                          AF_INET,
1017                          &pkt4->destination_address, 
1018                          &pkt4->source_address);
1019         break;
1020       case IPPROTO_TCP:
1021         tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt4[1], size,
1022                          AF_INET,
1023                          &pkt4->destination_address, 
1024                          &pkt4->source_address);
1025         break;
1026       case IPPROTO_ICMP:
1027         icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt4[1], size,
1028                           AF_INET,
1029                           &pkt4->destination_address, 
1030                           &pkt4->source_address);
1031         break;
1032       default:
1033         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1034                     _("IPv4 packet with unsupported next header %u received.  Ignored.\n"),
1035                     (int) pkt4->protocol);
1036         return GNUNET_OK;
1037       }
1038     }
1039     break;
1040   case ETH_P_IPV6:
1041     {
1042       const struct GNUNET_TUN_IPv6Header *pkt6;
1043
1044       if (size < sizeof (struct GNUNET_TUN_IPv6Header))
1045       {
1046         /* Kernel to blame? */
1047         GNUNET_break (0);
1048         return GNUNET_OK;
1049       }
1050       pkt6 = (struct GNUNET_TUN_IPv6Header *) &pkt_tun[1];
1051       if (size != ntohs (pkt6->payload_length) + sizeof (struct GNUNET_TUN_IPv6Header))
1052       {
1053         /* Kernel to blame? */
1054         GNUNET_break (0);
1055         return GNUNET_OK;
1056       }
1057       size -= sizeof (struct GNUNET_TUN_IPv6Header);
1058       switch (pkt6->next_header)
1059       {
1060       case IPPROTO_UDP:
1061         udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt6[1], size,
1062                          AF_INET6,
1063                          &pkt6->destination_address, 
1064                          &pkt6->source_address);
1065         break;
1066       case IPPROTO_TCP:
1067         tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt6[1], size,
1068                          AF_INET6,
1069                          &pkt6->destination_address, 
1070                          &pkt6->source_address);
1071         break;
1072       case IPPROTO_ICMPV6:
1073         icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt6[1], size,
1074                           AF_INET6,
1075                           &pkt6->destination_address, 
1076                           &pkt6->source_address);
1077         break;
1078       default:
1079         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1080                     _("IPv6 packet with unsupported next header %d received.  Ignored.\n"),
1081                     pkt6->next_header);
1082         return GNUNET_OK;
1083       }
1084     }
1085     break;
1086   default:
1087     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1088                 _("Packet from unknown protocol %u received.  Ignored.\n"),
1089                 ntohs (pkt_tun->proto));
1090     break;
1091   }
1092   return GNUNET_OK;
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   struct 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] GNUNET_ALIGN;
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] GNUNET_ALIGN;
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] GNUNET_ALIGN;
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] GNUNET_ALIGN;
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] GNUNET_ALIGN;
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 struct 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->address.proto = proto;
2857     serv->my_port = (uint16_t) local_port;
2858     serv->address.port = remote_port;
2859     if (0 == strcmp ("localhost4", hostname))
2860     {
2861       const char *ip4addr = exit_argv[5];
2862
2863       serv->address.af = AF_INET;      
2864       GNUNET_assert (1 == inet_pton (AF_INET, ip4addr, &serv->address.address.ipv4));
2865     }
2866     else if (0 == strcmp ("localhost6", hostname))
2867     {
2868       const char *ip6addr = exit_argv[3];
2869
2870       serv->address.af = AF_INET6;
2871       GNUNET_assert (1 == inet_pton (AF_INET6, ip6addr, &serv->address.address.ipv6));
2872     }
2873     else
2874     {
2875       struct addrinfo *res;      
2876       int ret;
2877
2878       ret = getaddrinfo (hostname, NULL, NULL, &res);      
2879       if ( (ret != 0) || (res == NULL) )
2880       {
2881         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2882                     _("No addresses found for hostname `%s' of service `%s'!\n"),
2883                     hostname,
2884                     name);
2885         GNUNET_free (serv);
2886         continue;
2887       }
2888       
2889       serv->address.af = res->ai_family;
2890       switch (res->ai_family)
2891       {
2892       case AF_INET:
2893         if (! ipv4_enabled)
2894         {
2895           GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2896                       _("Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
2897                       name);
2898           freeaddrinfo (res);
2899           GNUNET_free (serv);
2900           continue;
2901         }
2902         serv->address.address.ipv4 = ((struct sockaddr_in *) res->ai_addr)->sin_addr;
2903         break;
2904       case AF_INET6:
2905         if (! ipv6_enabled)
2906         {
2907           GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2908                       _("Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
2909                       name);
2910           freeaddrinfo (res);
2911           GNUNET_free (serv);
2912           continue;
2913         }       
2914         serv->address.address.ipv6 = ((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
2915         break;
2916       default:
2917         freeaddrinfo (res);
2918         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2919                     _("No IP addresses found for hostname `%s' of service `%s'!\n"),
2920                     hostname,
2921                     name);
2922         GNUNET_free (serv);
2923         continue;
2924       }
2925       freeaddrinfo (res);
2926     }
2927     store_service ((IPPROTO_UDP == proto) ? udp_services : tcp_services,
2928                    name,
2929                    local_port,
2930                    serv);
2931   }
2932 }
2933
2934
2935 /**
2936  * Reads the configuration servicecfg and populates udp_services
2937  *
2938  * @param cls unused
2939  * @param section name of section in config, equal to hostname
2940  */
2941 static void
2942 read_service_conf (void *cls GNUNET_UNUSED, const char *section)
2943 {
2944   char *cpy;
2945
2946   if ((strlen (section) < 8) ||
2947       (0 != strcmp (".gnunet.", section + (strlen (section) - 8))))
2948     return;
2949   if (GNUNET_OK ==
2950       GNUNET_CONFIGURATION_get_value_string (cfg, section, "UDP_REDIRECTS",
2951                                              &cpy))
2952   {
2953     add_services (IPPROTO_UDP, cpy, section);
2954     GNUNET_free (cpy);
2955   }
2956   if (GNUNET_OK ==
2957       GNUNET_CONFIGURATION_get_value_string (cfg, section, "TCP_REDIRECTS",
2958                                              &cpy))
2959   {
2960     add_services (IPPROTO_TCP, cpy, section);
2961     GNUNET_free (cpy);
2962   }
2963 }
2964
2965
2966 /**
2967  * Test if the given AF is supported by this system.
2968  * 
2969  * @param af to test
2970  * @return GNUNET_OK if the AF is supported
2971  */
2972 static int
2973 test_af (int af)
2974 {
2975   int s;
2976
2977   s = socket (af, SOCK_STREAM, 0);
2978   if (-1 == s)
2979   {
2980     if (EAFNOSUPPORT == errno)
2981       return GNUNET_NO;
2982     GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
2983                          "socket");
2984     return GNUNET_SYSERR;
2985   }
2986   close (s);
2987   return GNUNET_OK;
2988 }
2989
2990
2991 /**
2992  * @brief Main function that will be run by the scheduler.
2993  *
2994  * @param cls closure
2995  * @param args remaining command-line arguments
2996  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
2997  * @param cfg_ configuration
2998  */
2999 static void
3000 run (void *cls, char *const *args GNUNET_UNUSED,
3001      const char *cfgfile GNUNET_UNUSED,
3002      const struct GNUNET_CONFIGURATION_Handle *cfg_)
3003 {
3004   static struct GNUNET_MESH_MessageHandler handlers[] = {
3005     {&receive_icmp_service, GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE, 0},
3006     {&receive_icmp_remote, GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET, 0},
3007     {&receive_udp_service, GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE, 0},
3008     {&receive_udp_remote, GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET, 0},
3009     {&receive_tcp_service, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START, 0},
3010     {&receive_tcp_remote, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START, 0},
3011     {&receive_tcp_data, GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT, 0},
3012     {NULL, 0, 0}
3013   };
3014
3015   static GNUNET_MESH_ApplicationType apptypes[] = {
3016     GNUNET_APPLICATION_TYPE_END,
3017     GNUNET_APPLICATION_TYPE_END,
3018     GNUNET_APPLICATION_TYPE_END
3019   };
3020   unsigned int app_idx;
3021   char *exit_ifname;
3022   char *tun_ifname;
3023   char *ipv6addr;
3024   char *ipv6prefix_s;
3025   char *ipv4addr;
3026   char *ipv4mask;
3027
3028   if (GNUNET_YES !=
3029       GNUNET_OS_check_helper_binary ("gnunet-helper-exit"))
3030   {
3031     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3032                 _("`%s' must be installed SUID, refusing to run\n"),
3033                 "gnunet-helper-exit");
3034     global_ret = 1;
3035     return;
3036   }
3037   cfg = cfg_;
3038   stats = GNUNET_STATISTICS_create ("exit", cfg);
3039   ipv4_exit = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "EXIT_IPV4");
3040   ipv6_exit = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "EXIT_IPV6"); 
3041   ipv4_enabled = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_IPV4");
3042   ipv6_enabled = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_IPV6"); 
3043
3044   if ( (ipv4_exit || ipv4_enabled) &&
3045        GNUNET_OK != test_af (AF_INET))
3046   {
3047     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3048                 _("This system does not support IPv4, will disable IPv4 functions despite them being enabled in the configuration\n"));
3049     ipv4_exit = GNUNET_NO;
3050     ipv4_enabled = GNUNET_NO;
3051   }
3052   if ( (ipv6_exit || ipv6_enabled) &&
3053        GNUNET_OK != test_af (AF_INET6))
3054   {
3055     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3056                 _("This system does not support IPv6, will disable IPv6 functions despite them being enabled in the configuration\n"));
3057     ipv6_exit = GNUNET_NO;
3058     ipv6_enabled = GNUNET_NO;
3059   }
3060   if (ipv4_exit && (! ipv4_enabled))
3061   {
3062     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3063                 _("Cannot enable IPv4 exit but disable IPv4 on TUN interface, will use ENABLE_IPv4=YES\n"));
3064     ipv4_enabled = GNUNET_YES;
3065   }
3066   if (ipv6_exit && (! ipv6_enabled))
3067   {
3068     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3069                 _("Cannot enable IPv6 exit but disable IPv6 on TUN interface, will use ENABLE_IPv6=YES\n"));
3070     ipv6_enabled = GNUNET_YES;
3071   }
3072   if (! (ipv4_enabled || ipv6_enabled))
3073   {
3074     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3075                 _("No useful service enabled.  Exiting.\n"));
3076     GNUNET_SCHEDULER_shutdown ();
3077     return;    
3078   }
3079   app_idx = 0;
3080   if (GNUNET_YES == ipv4_exit)    
3081   {
3082     apptypes[app_idx] = GNUNET_APPLICATION_TYPE_IPV4_GATEWAY;
3083     app_idx++;
3084   }
3085   if (GNUNET_YES == ipv6_exit)    
3086   {
3087     apptypes[app_idx] = GNUNET_APPLICATION_TYPE_IPV6_GATEWAY;
3088     app_idx++;
3089   }
3090
3091   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls);
3092
3093   if (GNUNET_OK !=
3094       GNUNET_CONFIGURATION_get_value_number (cfg, "exit", "MAX_CONNECTIONS",
3095                                              &max_connections))
3096     max_connections = 1024;
3097   exit_argv[0] = GNUNET_strdup ("exit-gnunet");
3098   if (GNUNET_SYSERR ==
3099       GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "TUN_IFNAME", &tun_ifname))
3100   {
3101     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3102                 "No entry 'TUN_IFNAME' in configuration!\n");
3103     GNUNET_SCHEDULER_shutdown ();
3104     return;
3105   }
3106   exit_argv[1] = tun_ifname;
3107   if (ipv4_enabled)
3108   {
3109     if (GNUNET_SYSERR ==
3110         GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "EXIT_IFNAME", &exit_ifname))
3111     {
3112       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3113                   "No entry 'EXIT_IFNAME' in configuration!\n");
3114       GNUNET_SCHEDULER_shutdown ();
3115       return;
3116     }
3117     exit_argv[2] = exit_ifname;
3118   }
3119   else
3120   {
3121     exit_argv[2] = GNUNET_strdup ("%");
3122   }
3123   
3124
3125   if (GNUNET_YES == ipv6_enabled)
3126   {
3127     if ( (GNUNET_SYSERR ==
3128           GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6ADDR",
3129                                                  &ipv6addr) ||
3130           (1 != inet_pton (AF_INET6, ipv6addr, &exit_ipv6addr))) )
3131     {
3132       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3133                   "No valid entry 'IPV6ADDR' in configuration!\n");
3134       GNUNET_SCHEDULER_shutdown ();
3135       return;
3136     }
3137     exit_argv[3] = ipv6addr;
3138     if (GNUNET_SYSERR ==
3139         GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6PREFIX",
3140                                                &ipv6prefix_s))
3141     {
3142       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3143                   "No entry 'IPV6PREFIX' in configuration!\n");
3144       GNUNET_SCHEDULER_shutdown ();
3145       return;
3146     }
3147     exit_argv[4] = ipv6prefix_s;
3148     if ( (GNUNET_OK !=
3149           GNUNET_CONFIGURATION_get_value_number (cfg, "exit",
3150                                                  "IPV6PREFIX",
3151                                                  &ipv6prefix)) ||
3152          (ipv6prefix >= 127) )
3153     {
3154       GNUNET_SCHEDULER_shutdown ();
3155       return;
3156     }
3157   } 
3158   else
3159   {
3160     /* IPv6 explicitly disabled */
3161     exit_argv[3] = GNUNET_strdup ("-");
3162     exit_argv[4] = GNUNET_strdup ("-");
3163   }
3164   if (GNUNET_YES == ipv4_enabled)
3165   {
3166     if ( (GNUNET_SYSERR ==
3167           GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4ADDR",
3168                                                  &ipv4addr) ||
3169           (1 != inet_pton (AF_INET, ipv4addr, &exit_ipv4addr))) )
3170       {
3171         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3172                     "No valid entry for 'IPV4ADDR' in configuration!\n");
3173         GNUNET_SCHEDULER_shutdown ();
3174         return;
3175       }
3176     exit_argv[5] = ipv4addr;
3177     if ( (GNUNET_SYSERR ==
3178           GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4MASK",
3179                                                  &ipv4mask) ||
3180           (1 != inet_pton (AF_INET, ipv4mask, &exit_ipv4mask))) )
3181     {
3182       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3183                   "No valid entry 'IPV4MASK' in configuration!\n");
3184       GNUNET_SCHEDULER_shutdown ();
3185       return;
3186     }
3187     exit_argv[6] = ipv4mask;
3188   }
3189   else
3190   {
3191     /* IPv4 explicitly disabled */
3192     exit_argv[5] = GNUNET_strdup ("-");
3193     exit_argv[6] = GNUNET_strdup ("-");
3194   }
3195   exit_argv[7] = NULL;
3196
3197   udp_services = GNUNET_CONTAINER_multihashmap_create (65536);
3198   tcp_services = GNUNET_CONTAINER_multihashmap_create (65536);
3199   GNUNET_CONFIGURATION_iterate_sections (cfg, &read_service_conf, NULL);
3200
3201   connections_map = GNUNET_CONTAINER_multihashmap_create (65536);
3202   connections_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
3203   mesh_handle 
3204     = GNUNET_MESH_connect (cfg, NULL, 
3205                            &new_tunnel, 
3206                            &clean_tunnel, handlers,
3207                            apptypes);
3208   if (NULL == mesh_handle)
3209   {
3210     GNUNET_SCHEDULER_shutdown ();
3211     return;
3212   }
3213   helper_handle = GNUNET_HELPER_start (GNUNET_NO,
3214                                        "gnunet-helper-exit", 
3215                                        exit_argv,
3216                                        &message_token,
3217                                        NULL, NULL);
3218 }
3219
3220
3221 /**
3222  * The main function
3223  *
3224  * @param argc number of arguments from the command line
3225  * @param argv command line arguments
3226  * @return 0 ok, 1 on error
3227  */
3228 int
3229 main (int argc, char *const *argv)
3230 {
3231   static const struct GNUNET_GETOPT_CommandLineOption options[] = {
3232     GNUNET_GETOPT_OPTION_END
3233   };
3234
3235   if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
3236     return 2;
3237
3238   return (GNUNET_OK ==
3239           GNUNET_PROGRAM_run (argc, argv, "gnunet-daemon-exit",
3240                               gettext_noop
3241                               ("Daemon to run to provide an IP exit node for the VPN"),
3242                               options, &run, NULL)) ? global_ret : 1;
3243 }
3244
3245
3246 /* end of gnunet-daemon-exit.c */