cf72bf9642eeced7e49fac39e3e7e825bce202ee
[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  * - need some statistics
29  * - test
30  *
31  * Code cleanup:
32  * - factor out crc computations from DNS/EXIT/VPN into shared library?
33  *
34  * Design:
35  * - which code should advertise services? the service model is right
36  *   now a bit odd, especially as this code DOES the exit and knows
37  *   the DNS "name", but OTOH this is clearly NOT the place to advertise
38  *   the service's existence; maybe the daemon should turn into a 
39  *   service with an API to add local-exit services dynamically?
40  */
41 #include "platform.h"
42 #include "gnunet_util_lib.h"
43 #include "gnunet_protocols.h"
44 #include "gnunet_applications.h"
45 #include "gnunet_mesh_service.h"
46 #include "gnunet_constants.h"
47 #include "tcpip_tun.h"
48 #include "exit.h"
49
50 /**
51  * Information about an address.
52  */
53 struct SocketAddress
54 {
55   /**
56    * AF_INET or AF_INET6.
57    */
58   int af;
59
60   /**
61    * Remote address information.
62    */
63   union
64   {
65     /**
66      * Address, if af is AF_INET.
67      */
68     struct in_addr ipv4;
69
70     /**
71      * Address, if af is AF_INET6.
72      */
73     struct in6_addr ipv6;
74   } address;
75   
76   /**
77    * IPPROTO_TCP or IPPROTO_UDP;
78    */
79   uint8_t proto;
80
81   /**
82    * Remote port, in host byte order!
83    */
84   uint16_t port;
85
86 };
87
88 /**
89  * This struct is saved into the services-hashmap to represent
90  * a service this peer is specifically offering an exit for
91  * (for a specific domain name).
92  */
93 struct LocalService
94 {
95
96   /**
97    * Remote address to use for the service.
98    */
99   struct SocketAddress address;
100
101   /**
102    * DNS name of the service.
103    */
104   char *name;
105
106   /**
107    * Port I am listening on within GNUnet for this service, in host
108    * byte order.  (as we may redirect ports).
109    */
110   uint16_t my_port;
111
112 };
113
114 /**
115  * Information we use to track a connection (the classical 6-tuple of
116  * IP-version, protocol, source-IP, destination-IP, source-port and
117  * destinatin-port.
118  */
119 struct RedirectInformation 
120 {
121
122   /**
123    * Address information for the other party (equivalent of the
124    * arguments one would give to "connect").
125    */
126   struct SocketAddress remote_address;
127
128   /**
129    * Address information we used locally (AF and proto must match
130    * "remote_address").  Equivalent of the arguments one would give to
131    * "bind".
132    */
133   struct SocketAddress local_address;
134
135   /* 
136      Note 1: additional information might be added here in the
137      future to support protocols that require special handling,
138      such as ftp/tftp 
139
140      Note 2: we might also sometimes not match on all components
141      of the tuple, to support protocols where things do not always
142      fully map.
143   */
144 };
145
146
147 /**
148  * Queue of messages to a tunnel.
149  */
150 struct TunnelMessageQueue
151 {
152   /**
153    * This is a doubly-linked list.
154    */
155   struct TunnelMessageQueue *next;
156
157   /**
158    * This is a doubly-linked list.
159    */
160   struct TunnelMessageQueue *prev;
161
162   /**
163    * Payload to send via the tunnel.
164    */
165   const void *payload;
166
167   /**
168    * Number of bytes in 'payload'.
169    */
170   size_t len;
171 };
172
173
174 /**
175  * This struct is saved into connections_map to allow finding the
176  * right tunnel given an IP packet from TUN.  It is also associated
177  * with the tunnel's closure so we can find it again for the next
178  * message from the tunnel.
179  */
180 struct TunnelState
181 {
182   /**
183    * Mesh tunnel that is used for this connection.
184    */
185   struct GNUNET_MESH_Tunnel *tunnel;
186
187   /**
188    * Heap node for this state in the connections_heap.
189    */
190   struct GNUNET_CONTAINER_HeapNode *heap_node;
191
192   /**
193    * Key this state has in the connections_map.
194    */
195   GNUNET_HashCode state_key;
196
197   /**
198    * Associated service record, or NULL for no service.
199    */
200   struct LocalService *serv;
201
202   /**
203    * Head of DLL of messages for this tunnel.
204    */
205   struct TunnelMessageQueue *head;
206
207   /**
208    * Tail of DLL of messages for this tunnel.
209    */
210   struct TunnelMessageQueue *tail;
211
212   /**
213    * Active tunnel transmission request (or NULL).
214    */
215   struct GNUNET_MESH_TransmitHandle *th;
216
217   /**
218    * Primary redirection information for this connection.
219    */
220   struct RedirectInformation ri;
221
222 };
223
224
225 /**
226  * The handle to the configuration used throughout the process
227  */
228 static const struct GNUNET_CONFIGURATION_Handle *cfg;
229
230 /**
231  * The handle to the helper
232  */
233 static struct GNUNET_HELPER_Handle *helper_handle;
234
235 /**
236  * Arguments to the exit helper.
237  */
238 static char *exit_argv[7];
239
240 /**
241  * IPv6 prefix (0..127) from configuration file.
242  */
243 static unsigned long long ipv6prefix;
244
245 /**
246  * The handle to mesh
247  */
248 static struct GNUNET_MESH_Handle *mesh_handle;
249
250 /**
251  * This hashmaps contains the mapping from peer, service-descriptor,
252  * source-port and destination-port to a struct TunnelState
253  */
254 static struct GNUNET_CONTAINER_MultiHashMap *connections_map;
255
256 /**
257  * Heap so we can quickly find "old" connections.
258  */
259 static struct GNUNET_CONTAINER_Heap *connections_heap;
260
261 /**
262  * If there are at least this many connections, old ones will be removed
263  */
264 static long long unsigned int max_connections = 200;
265
266 /**
267  * This hashmaps saves interesting things about the configured UDP services
268  */
269 static struct GNUNET_CONTAINER_MultiHashMap *udp_services;
270
271 /**
272  * This hashmaps saves interesting things about the configured TCP services
273  */
274 static struct GNUNET_CONTAINER_MultiHashMap *tcp_services;
275
276 /**
277  * Are we an IPv4-exit?
278  */
279 static int ipv4_exit;
280
281 /**
282  * Are we an IPv6-exit?
283  */
284 static int ipv6_exit;
285
286 /**
287  * Do we support IPv4 at all on the TUN interface?
288  */
289 static int ipv4_enabled;
290
291 /**
292  * Do we support IPv6 at all on the TUN interface?
293  */
294 static int ipv6_enabled;
295
296
297 /**
298  * Given IP information about a connection, calculate the respective
299  * hash we would use for the 'connections_map'.
300  *
301  * @param hash resulting hash
302  * @param ri information about the connection
303  */
304 static void
305 hash_redirect_info (GNUNET_HashCode *hash, 
306                     const struct RedirectInformation *ri)
307 {
308   char *off;
309
310   memset (hash, 0, sizeof (GNUNET_HashCode));
311   /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
312      so we put the IP address in there (and hope for few collisions) */
313   off = (char*) hash;
314   switch (ri->remote_address.af)
315   {
316   case AF_INET:
317     memcpy (off, &ri->remote_address.address.ipv4, sizeof (struct in_addr));
318     off += sizeof (struct in_addr);
319     break;
320   case AF_INET6:
321     memcpy (off, &ri->remote_address.address.ipv6, sizeof (struct in6_addr));
322     off += sizeof (struct in_addr);
323     break;
324   default:
325     GNUNET_assert (0);
326   }
327   memcpy (off, &ri->remote_address.port, sizeof (uint16_t));
328   off += sizeof (uint16_t);
329   switch (ri->local_address.af)
330   {
331   case AF_INET:
332     memcpy (off, &ri->local_address.address.ipv4, sizeof (struct in_addr));
333     off += sizeof (struct in_addr);
334     break;
335   case AF_INET6:
336     memcpy (off, &ri->local_address.address.ipv6, sizeof (struct in6_addr));
337     off += sizeof (struct in_addr);
338     break;
339   default:
340     GNUNET_assert (0);
341   }
342   memcpy (off, &ri->local_address.port, sizeof (uint16_t));
343   off += sizeof (uint16_t);
344   memcpy (off, &ri->remote_address.proto, sizeof (uint8_t));
345   off += sizeof (uint8_t);
346 }
347
348
349 /**
350  * Get our connection tracking state.  Warns if it does not exists,
351  * refreshes the timestamp if it does exist.
352  *
353  * @param af address family
354  * @param protocol IPPROTO_UDP or IPPROTO_TCP
355  * @param destination_ip target IP
356  * @param destination_port target port
357  * @param local_ip local IP
358  * @param local_port local port
359  * @param state_key set to hash's state if non-NULL
360  * @return NULL if we have no tracking information for this tuple
361  */
362 static struct TunnelState *
363 get_redirect_state (int af,
364                     int protocol,                   
365                     const void *destination_ip,
366                     uint16_t destination_port,
367                     const void *local_ip,
368                     uint16_t local_port,
369                     GNUNET_HashCode *state_key)
370 {
371   struct RedirectInformation ri;
372   GNUNET_HashCode key;
373   struct TunnelState *state;
374
375   ri.remote_address.af = af;
376   if (af == AF_INET)
377     ri.remote_address.address.ipv4 = *((struct in_addr*) destination_ip);
378   else
379     ri.remote_address.address.ipv6 = * ((struct in6_addr*) destination_ip);
380   ri.remote_address.port = destination_port;
381   ri.remote_address.proto = protocol;
382   ri.local_address.af = af;
383   if (af == AF_INET)
384     ri.local_address.address.ipv4 = *((struct in_addr*) local_ip);
385   else
386     ri.local_address.address.ipv6 = * ((struct in6_addr*) local_ip);
387   ri.local_address.port = local_port;
388   ri.local_address.proto = protocol;
389   hash_redirect_info (&key, &ri);
390   if (NULL != state_key)
391     *state_key = key;
392   state = GNUNET_CONTAINER_multihashmap_get (connections_map, &key);
393   if (NULL == state)
394     return NULL;
395   /* Mark this connection as freshly used */
396   if (NULL == state_key)
397     GNUNET_CONTAINER_heap_update_cost (connections_heap, 
398                                        state->heap_node,
399                                        GNUNET_TIME_absolute_get ().abs_value);
400   return state;
401 }
402
403
404 /**
405  * Given a service descriptor and a destination port, find the
406  * respective service entry.
407  *
408  * @param service_map map of services (TCP or UDP)
409  * @param desc service descriptor
410  * @param dpt destination port
411  * @return NULL if we are not aware of such a service
412  */
413 static struct LocalService *
414 find_service (struct GNUNET_CONTAINER_MultiHashMap *service_map,
415               const GNUNET_HashCode *desc,
416               uint16_t dpt)
417 {
418   char key[sizeof (GNUNET_HashCode) + sizeof (uint16_t)];
419
420   memcpy (&key[0], &dpt, sizeof (uint16_t));
421   memcpy (&key[sizeof(uint16_t)], desc, sizeof (GNUNET_HashCode));
422   return GNUNET_CONTAINER_multihashmap_get (service_map,
423                                             (GNUNET_HashCode *) key);
424 }
425
426
427 /**
428  * Free memory associated with a service record.
429  *
430  * @param cls unused
431  * @param key service descriptor
432  * @param value service record to free
433  * @return GNUNET_OK
434  */
435 static int
436 free_service_record (void *cls,
437                      const GNUNET_HashCode *key,
438                      void *value)
439 {
440   struct LocalService *service = value;
441
442   GNUNET_free_non_null (service->name);
443   GNUNET_free (service);
444   return GNUNET_OK;
445 }
446
447
448 /**
449  * Given a service descriptor and a destination port, find the
450  * respective service entry.
451  *
452  * @param service_map map of services (TCP or UDP)
453  * @param name name of the service 
454  * @param dpt destination port
455  * @param service service information record to store (service->name will be set).
456  */
457 static void
458 store_service (struct GNUNET_CONTAINER_MultiHashMap *service_map,
459                const char *name,
460                uint16_t dpt,
461                struct LocalService *service)
462 {
463   char key[sizeof (GNUNET_HashCode) + sizeof (uint16_t)];
464   GNUNET_HashCode desc;
465
466   GNUNET_CRYPTO_hash (name, strlen (name) + 1, &desc);
467   service->name = GNUNET_strdup (name);
468   memcpy (&key[0], &dpt, sizeof (uint16_t));
469   memcpy (&key[sizeof(uint16_t)], &desc, sizeof (GNUNET_HashCode));
470   if (GNUNET_OK !=
471       GNUNET_CONTAINER_multihashmap_put (service_map,
472                                          (GNUNET_HashCode *) key,
473                                          service,
474                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
475   {
476     free_service_record (NULL, (GNUNET_HashCode *) key, service);
477     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
478                 _("Got duplicate service records for `%s:%u'\n"),
479                 name,
480                 (unsigned int) dpt);
481   }
482 }
483
484
485 /**
486  * MESH is ready to receive a message for the tunnel.  Transmit it.
487  *
488  * @param cls the 'struct TunnelState'.
489  * @param size number of bytes available in buf
490  * @param buf where to copy the message
491  * @return number of bytes copied to buf
492  */
493 static size_t
494 send_to_peer_notify_callback (void *cls, size_t size, void *buf)
495 {
496   struct TunnelState *s = cls;
497   struct GNUNET_MESH_Tunnel *tunnel = s->tunnel;
498   struct TunnelMessageQueue *tnq;
499
500   s->th = NULL;
501   tnq = s->head;
502   GNUNET_assert (size >= tnq->len);
503   memcpy (buf, tnq->payload, tnq->len);
504   size = tnq->len;
505   GNUNET_CONTAINER_DLL_remove (s->head, 
506                                s->tail,
507                                tnq);  
508   GNUNET_free (tnq);
509   if (NULL != (tnq = s->head))
510     s->th = GNUNET_MESH_notify_transmit_ready (tunnel, 
511                                                GNUNET_NO /* corking */, 
512                                                0 /* priority */,
513                                                GNUNET_TIME_UNIT_FOREVER_REL,
514                                                NULL,
515                                                tnq->len,
516                                                &send_to_peer_notify_callback,
517                                                s);
518   return size;
519 }
520
521
522 /**
523  * Send the given packet via the mesh tunnel.
524  *
525  * @param mesh_tunnel destination
526  * @param payload message to transmit
527  * @param payload_length number of bytes in payload
528  * @param desc descriptor to add before payload (optional)
529  * @param mtype message type to use
530  */
531 static void
532 send_packet_to_mesh_tunnel (struct GNUNET_MESH_Tunnel *mesh_tunnel,
533                             const void *payload,
534                             size_t payload_length,
535                             const GNUNET_HashCode *desc,
536                             uint16_t mtype)
537 {
538   struct TunnelState *s;
539   struct TunnelMessageQueue *tnq;
540   struct GNUNET_MessageHeader *msg;
541   size_t len;
542   GNUNET_HashCode *dp;
543
544   len = sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + payload_length;
545   if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
546   {
547     GNUNET_break (0);
548     return;
549   }
550   tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueue) + len);
551   tnq->payload = &tnq[1];
552   tnq->len = len;
553   msg = (struct GNUNET_MessageHeader *) &tnq[1];
554   msg->size = htons ((uint16_t) len);
555   msg->type = htons (mtype);
556   if (NULL != desc)
557   {
558     dp = (GNUNET_HashCode *) &msg[1];
559     *dp = *desc;  
560     memcpy (&dp[1], payload, payload_length);
561   }
562   else
563   {
564     memcpy (&msg[1], payload, payload_length);
565   }
566   s = GNUNET_MESH_tunnel_get_data (mesh_tunnel);
567   GNUNET_assert (NULL != s);
568   GNUNET_CONTAINER_DLL_insert_tail (s->head, s->tail, tnq);
569   if (NULL == s->th)
570     s->th = GNUNET_MESH_notify_transmit_ready (mesh_tunnel, GNUNET_NO /* cork */, 0 /* priority */,
571                                                GNUNET_TIME_UNIT_FOREVER_REL,
572                                                NULL, len,
573                                                &send_to_peer_notify_callback,
574                                                s);
575 }
576
577
578 /**
579  * @brief Handles an UDP packet received from the helper.
580  *
581  * @param udp A pointer to the Packet
582  * @param pktlen number of bytes in 'udp'
583  * @param af address family (AFINET or AF_INET6)
584  * @param destination_ip destination IP-address of the IP packet (should 
585  *                       be our local address)
586  * @param source_ip original source IP-address of the IP packet (should
587  *                       be the original destination address)
588  */
589 static void
590 udp_from_helper (const struct udp_packet *udp, 
591                  size_t pktlen,
592                  int af,
593                  const void *destination_ip, 
594                  const void *source_ip)
595 {
596   struct TunnelState *state;
597
598   {
599     char sbuf[INET6_ADDRSTRLEN];
600     char dbuf[INET6_ADDRSTRLEN];
601     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
602                 "Received UDP packet going from %s:%u to %s:%u\n",
603                 inet_ntop (af,
604                            source_ip,
605                            sbuf, sizeof (sbuf)),
606                 (unsigned int) ntohs (udp->spt),
607                 inet_ntop (af,
608                            source_ip,
609                            dbuf, sizeof (dbuf)),
610                 (unsigned int) ntohs (udp->dpt));
611   }
612   if (pktlen < sizeof (struct udp_packet))
613   {
614     /* blame kernel */
615     GNUNET_break (0);
616     return;
617   }
618   if (pktlen != ntohs (udp->len))
619   {
620     /* blame kernel */
621     GNUNET_break (0);
622     return;
623   }
624   state = get_redirect_state (af, IPPROTO_UDP,
625                               source_ip,
626                               ntohs (udp->spt),
627                               destination_ip,
628                               ntohs (udp->dpt),
629                               NULL);
630   if (NULL == state)
631   {
632     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
633                 _("Packet dropped, have no matching connection information\n"));
634     return;
635   }
636   send_packet_to_mesh_tunnel (state->tunnel,
637                               &udp[1], pktlen - sizeof (struct udp_packet),
638                               NULL,
639                               state->serv != NULL
640                               ? GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK 
641                               : GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP_BACK);
642 }
643
644
645 /**
646  * @brief Handles a TCP packet received from the helper.
647  *
648  * @param tcp A pointer to the Packet
649  * @param pktlen the length of the packet, including its header
650  * @param af address family (AFINET or AF_INET6)
651  * @param destination_ip destination IP-address of the IP packet (should 
652  *                       be our local address)
653  * @param source_ip original source IP-address of the IP packet (should
654  *                       be the original destination address)
655  */
656 static void
657 tcp_from_helper (const struct tcp_packet *tcp, 
658                  size_t pktlen,
659                  int af,
660                  const void *destination_ip,
661                  const void *source_ip)
662 {
663   struct TunnelState *state;
664   char buf[pktlen];
665   struct tcp_packet *mtcp;
666
667   {
668     char sbuf[INET6_ADDRSTRLEN];
669     char dbuf[INET6_ADDRSTRLEN];
670     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
671                 "Received TCP packet going from %s:%u to %s:%u\n",
672                 inet_ntop (af,
673                            source_ip,
674                            sbuf, sizeof (sbuf)),
675                 (unsigned int) ntohs (tcp->spt),
676                 inet_ntop (af,
677                            source_ip,
678                            dbuf, sizeof (dbuf)),
679                 (unsigned int) ntohs (tcp->dpt));
680   }
681   if (pktlen < sizeof (struct tcp_packet))
682   {
683     /* blame kernel */
684     GNUNET_break (0);
685     return;
686   }
687   state = get_redirect_state (af, IPPROTO_TCP,
688                               source_ip, 
689                               ntohs (tcp->spt),
690                               destination_ip,
691                               ntohs (tcp->dpt),
692                               NULL);
693   if (NULL == state)
694   {
695     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
696                 _("Packet dropped, have no matching connection information\n"));
697     
698     return;
699   }
700   /* mug port numbers and crc to avoid information leakage;
701      sender will need to lookup the correct values anyway */
702   memcpy (buf, tcp, pktlen);  
703   mtcp = (struct tcp_packet *) buf;
704   mtcp->spt = 0;
705   mtcp->dpt = 0;
706   mtcp->crc = 0;
707   send_packet_to_mesh_tunnel (state->tunnel,
708                               mtcp, pktlen,
709                               NULL,
710                               state->serv != NULL
711                               ? GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP_BACK 
712                               : GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP_BACK);
713 }
714
715
716 /**
717  * Receive packets from the helper-process
718  *
719  * @param cls unused
720  * @param client unsued
721  * @param message message received from helper
722  */
723 static void
724 message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED,
725                const struct GNUNET_MessageHeader *message)
726 {
727   const struct tun_header *pkt_tun;
728   size_t size;
729
730   if (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER)
731   {
732     GNUNET_break (0);
733     return;
734   }
735   size = ntohs (message->size);
736   if (size < sizeof (struct tun_header) + sizeof (struct GNUNET_MessageHeader))
737   {
738     GNUNET_break (0);
739     return;
740   }
741   pkt_tun = (const struct tun_header *) &message[1];
742   size -= sizeof (struct tun_header) + sizeof (struct GNUNET_MessageHeader);
743   switch (ntohs (pkt_tun->proto))
744   {
745   case ETH_P_IPV6:
746     {
747       const struct ip6_header *pkt6;
748
749       if (size < sizeof (struct ip6_header))
750       {
751         /* Kernel to blame? */
752         GNUNET_break (0);
753         return;
754       }
755       pkt6 = (struct ip6_header *) &pkt_tun[1];
756       if (size != ntohs (pkt6->payload_length))
757       {
758         /* Kernel to blame? */
759         GNUNET_break (0);
760         return;
761       }
762       size -= sizeof (struct ip6_header);
763       switch (pkt6->next_header)
764       {
765       case IPPROTO_UDP:
766         udp_from_helper ((const struct udp_packet *) &pkt6[1], size,
767                          AF_INET6,
768                          &pkt6->destination_address, 
769                          &pkt6->source_address);
770         break;
771       case IPPROTO_TCP:
772         tcp_from_helper ((const struct tcp_packet *) &pkt6[1], size,
773                          AF_INET6,
774                          &pkt6->destination_address, 
775                          &pkt6->source_address);
776         break;
777       default:
778         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
779                     _("IPv6 packet with unsupported next header received.  Ignored.\n"));
780         return;
781       }
782     }
783     break;
784   case ETH_P_IPV4:
785     {
786       const struct ip4_header *pkt4;
787
788       if (size < sizeof (struct ip4_header))
789       {
790         /* Kernel to blame? */
791         GNUNET_break (0);
792         return;
793       }
794       pkt4 = (const struct ip4_header *) &pkt_tun[1];
795       if (size != ntohs (pkt4->total_length))
796       {
797         /* Kernel to blame? */
798         GNUNET_break (0);
799         return;
800       }
801       if (pkt4->header_length * 4 != sizeof (struct ip4_header))
802       {
803         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
804                     _("IPv4 packet options received.  Ignored.\n"));
805         return;
806       }
807       size -= sizeof (struct ip4_header);
808       switch (pkt4->protocol)
809       {
810       case IPPROTO_UDP:
811         udp_from_helper ((const struct udp_packet *) &pkt4[1], size,
812                          AF_INET,
813                          &pkt4->destination_address, 
814                          &pkt4->source_address);
815       case IPPROTO_TCP:
816         tcp_from_helper ((const struct tcp_packet *) &pkt4[1], size,
817                          AF_INET,
818                          &pkt4->destination_address, 
819                          &pkt4->source_address);
820         break;
821       default:
822         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
823                     _("IPv4 packet with unsupported next header received.  Ignored.\n"));
824         return;
825       }
826     }
827     break;
828   default:
829     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
830                 _("Packet from unknown protocol %u received.  Ignored.\n"),
831                 ntohs (pkt_tun->proto));
832     break;
833   }
834 }
835
836
837 /**
838  * We need to create a (unique) fresh local address (IP+port).
839  * Fill one in.
840  *
841  * @param af desired address family
842  * @param proto desired protocol (IPPROTO_UDP or IPPROTO_TCP)
843  * @param local_address address to initialize
844  */
845 static void
846 setup_fresh_address (int af,
847                      uint8_t proto,
848                      struct SocketAddress *local_address)
849 {
850   local_address->af = af;
851   local_address->proto = (uint8_t) proto;
852   /* default "local" port range is often 32768--61000,
853      so we pick a random value in that range */  
854   local_address->port 
855     = (uint16_t) 32768 + GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 
856                                                    28232);      
857   switch (af)
858   {
859   case AF_INET:
860     {
861       const char *ipv4addr = exit_argv[4];
862       const char *ipv4mask = exit_argv[5];
863       struct in_addr addr;
864       struct in_addr mask;
865       struct in_addr rnd;
866
867       GNUNET_assert (1 == inet_pton (AF_INET, ipv4addr, &addr));
868       GNUNET_assert (1 == inet_pton (AF_INET, ipv4mask, &mask));           
869       if (0 == ~mask.s_addr)
870       {
871         /* only one valid IP anyway */
872         local_address->address.ipv4 = addr;
873         return;
874       }
875       /* Given 192.168.0.1/255.255.0.0, we want a mask 
876          of '192.168.255.255', thus:  */
877       mask.s_addr = addr.s_addr | ~mask.s_addr;
878       /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
879       do
880         {
881           rnd.s_addr = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 
882                                                  UINT32_MAX);   
883           local_address->address.ipv4.s_addr = (addr.s_addr | rnd.s_addr) & mask.s_addr;
884         }
885       while ( (local_address->address.ipv4.s_addr == addr.s_addr) ||
886               (local_address->address.ipv4.s_addr == mask.s_addr) );
887     }
888     break;
889   case AF_INET6:
890     {
891       const char *ipv6addr = exit_argv[2];
892       struct in6_addr addr;
893       struct in6_addr mask;
894       struct in6_addr rnd;
895       int i;
896
897       GNUNET_assert (1 == inet_pton (AF_INET6, ipv6addr, &addr));
898       GNUNET_assert (ipv6prefix < 128);
899       if (ipv6prefix == 127)
900       {
901         /* only one valid IP anyway */
902         local_address->address.ipv6 = addr;
903         return;
904       }
905       /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
906          thus: */
907       mask = addr;
908       for (i=127;i>=128-ipv6prefix;i--)
909         mask.s6_addr[i / 8] |= (1 << (i % 8));
910       
911       /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */
912       do
913         {
914           for (i=0;i<16;i++)
915           {
916             rnd.s6_addr[i] = (unsigned char) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 
917                                                                        256);
918             local_address->address.ipv6.s6_addr[i]
919               = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
920           }
921         }
922       while ( (0 == memcmp (&local_address->address.ipv6,
923                             &addr,
924                             sizeof (struct in6_addr))) ||
925               (0 == memcmp (&local_address->address.ipv6,
926                             &mask,
927                             sizeof (struct in6_addr))) );
928     }
929     break;
930   default:
931     GNUNET_assert (0);
932   }  
933 }
934
935
936 /**
937  * We are starting a fresh connection (TCP or UDP) and need
938  * to pick a source port and IP address (within the correct
939  * range and address family) to associate replies with the
940  * connection / correct mesh tunnel.  This function generates
941  * a "fresh" source IP and source port number for a connection
942  * After picking a good source address, this function sets up
943  * the state in the 'connections_map' and 'connections_heap'
944  * to allow finding the state when needed later.  The function
945  * also makes sure that we remain within memory limits by
946  * cleaning up 'old' states.
947  *
948  * @param state skeleton state to setup a record for; should
949  *              'state->ri.remote_address' filled in so that
950  *              this code can determine which AF/protocol is
951  *              going to be used (the 'tunnel' should also
952  *              already be set); after calling this function,
953  *              heap_node and the local_address will be
954  *              also initialized (heap_node != NULL can be
955  *              used to test if a state has been fully setup).
956  */
957 static void
958 setup_state_record (struct TunnelState *state)
959 {
960   GNUNET_HashCode key;
961   struct TunnelState *s;
962
963   /* generate fresh, unique address */
964   do
965   {
966     setup_fresh_address (state->serv->address.af,
967                          state->serv->address.proto,
968                          &state->ri.local_address);
969   } while (NULL != get_redirect_state (state->ri.remote_address.af,
970                                        state->ri.remote_address.proto,
971                                        &state->ri.remote_address.address,
972                                        state->ri.remote_address.port,
973                                        &state->ri.local_address.address,
974                                        state->ri.local_address.port,
975                                        &key));
976   {
977     char buf[INET6_ADDRSTRLEN];
978     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
979                 "Picked local address %s:%u for new connection\n",
980                 inet_ntop (state->ri.local_address.af, 
981                            &state->ri.local_address.address,
982                            buf, sizeof (buf)),
983                 (unsigned int) state->ri.local_address.port);  
984   }
985   GNUNET_assert (GNUNET_OK ==
986                  GNUNET_CONTAINER_multihashmap_put (connections_map, 
987                                                     &key, state,
988                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
989   state->heap_node = GNUNET_CONTAINER_heap_insert (connections_heap,
990                                                    state,
991                                                    GNUNET_TIME_absolute_get ().abs_value);   
992   while (GNUNET_CONTAINER_heap_get_size (connections_heap) > max_connections)
993   {
994     s = GNUNET_CONTAINER_heap_remove_root (connections_heap);
995     GNUNET_assert (state != s);
996     s->heap_node = NULL;
997     GNUNET_MESH_tunnel_destroy (s->tunnel);
998     GNUNET_assert (GNUNET_OK ==
999                    GNUNET_CONTAINER_multihashmap_remove (connections_map,
1000                                                          &s->state_key, 
1001                                                          s));
1002     GNUNET_free (s);
1003   }
1004 }
1005
1006
1007 /**
1008  * Prepare an IPv4 packet for transmission via the TUN interface.
1009  * Initializes the IP header and calculates checksums (IP+UDP/TCP).
1010  * For UDP, the UDP header will be fully created, whereas for TCP
1011  * only the ports and checksum will be filled in.  So for TCP,
1012  * a skeleton TCP header must be part of the provided payload.
1013  *
1014  * @param payload payload of the packet (starting with UDP payload or
1015  *                TCP header, depending on protocol)
1016  * @param payload_length number of bytes in 'payload'
1017  * @param protocol IPPROTO_UDP or IPPROTO_TCP
1018  * @param src_address source address to use (IP and port)
1019  * @param dst_address destination address to use (IP and port)
1020  * @param pkt6 where to write the assembled packet; must
1021  *        contain enough space for the IP header, UDP/TCP header
1022  *        AND the payload
1023  */
1024 static void
1025 prepare_ipv4_packet (const void *payload, size_t payload_length,
1026                      int protocol,
1027                      const struct tcp_packet *tcp_header,
1028                      const struct SocketAddress *src_address,
1029                      const struct SocketAddress *dst_address,
1030                      struct ip4_header *pkt4)
1031 {
1032   size_t len;
1033
1034   len = payload_length;
1035   switch (protocol)
1036   {
1037   case IPPROTO_UDP:
1038     len += sizeof (struct udp_packet);
1039     break;
1040   case IPPROTO_TCP:
1041     len += sizeof (struct tcp_packet);
1042     GNUNET_assert (NULL != tcp_header);
1043     break;
1044   default:
1045     GNUNET_break (0);
1046     return;
1047   }
1048   if (len + sizeof (struct ip4_header) > UINT16_MAX)
1049   {
1050     GNUNET_break (0);
1051     return;
1052   }
1053
1054   pkt4->version = 4;
1055   pkt4->header_length = sizeof (struct ip4_header) / 4;
1056   pkt4->diff_serv = 0;
1057   pkt4->total_length = htons ((uint16_t) (sizeof (struct ip4_header) + len));
1058   pkt4->identification = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 
1059                                                               UINT16_MAX + 1);
1060   pkt4->flags = 0;
1061   pkt4->fragmentation_offset = 0;
1062   pkt4->ttl = 255;
1063   pkt4->protocol = protocol;
1064   pkt4->checksum = 0;
1065   pkt4->destination_address = dst_address->address.ipv4;
1066   pkt4->source_address = src_address->address.ipv4;
1067   pkt4->checksum = GNUNET_CRYPTO_crc16_n (pkt4, sizeof (struct ip4_header));
1068
1069   switch (protocol)
1070   {
1071   case IPPROTO_UDP:
1072     {
1073       struct udp_packet *pkt4_udp = (struct udp_packet *) &pkt4[1];
1074
1075       pkt4_udp->spt = htons (src_address->port);
1076       pkt4_udp->dpt = htons (dst_address->port);
1077       pkt4_udp->crc = 0;  /* Optional for IPv4 */
1078       pkt4_udp->len = htons ((uint16_t) payload_length);
1079       memcpy (&pkt4_udp[1], payload, payload_length);
1080     }
1081     break;
1082   case IPPROTO_TCP:
1083     {
1084       struct tcp_packet *pkt4_tcp = (struct tcp_packet *) &pkt4[1];
1085       
1086       memcpy (pkt4_tcp, tcp_header, sizeof (struct tcp_packet));
1087       memcpy (&pkt4_tcp[1], payload, payload_length);
1088       pkt4_tcp->spt = htons (src_address->port);
1089       pkt4_tcp->dpt = htons (dst_address->port);
1090       pkt4_tcp->crc = 0;
1091       uint32_t sum = 0;
1092       sum = GNUNET_CRYPTO_crc16_step (sum, 
1093                                       &pkt4->source_address,
1094                                       sizeof (struct in_addr) * 2);
1095       uint32_t tmp = htonl ((protocol << 16) | (0xffff & len));
1096       sum = GNUNET_CRYPTO_crc16_step (sum, & tmp, sizeof (uint32_t));
1097       sum = GNUNET_CRYPTO_crc16_step (sum, & pkt4_tcp, len);
1098       pkt4_tcp->crc = GNUNET_CRYPTO_crc16_finish (sum);
1099     }
1100     break;
1101   default:
1102     GNUNET_assert (0);
1103   }
1104 }
1105
1106
1107 /**
1108  * Prepare an IPv6 packet for transmission via the TUN interface.
1109  * Initializes the IP header and calculates checksums (IP+UDP/TCP).
1110  * For UDP, the UDP header will be fully created, whereas for TCP
1111  * only the ports and checksum will be filled in.  So for TCP,
1112  * a skeleton TCP header must be part of the provided payload.
1113  *
1114  * @param payload payload of the packet (starting with UDP payload or
1115  *                TCP header, depending on protocol)
1116  * @param payload_length number of bytes in 'payload'
1117  * @param protocol IPPROTO_UDP or IPPROTO_TCP
1118  * @param src_address source address to use (IP and port)
1119  * @param dst_address destination address to use (IP and port)
1120  * @param pkt6 where to write the assembled packet; must
1121  *        contain enough space for the IP header, UDP/TCP header
1122  *        AND the payload
1123  */
1124 static void
1125 prepare_ipv6_packet (const void *payload, size_t payload_length,
1126                      int protocol,
1127                      const struct tcp_packet *tcp_header,
1128                      const struct SocketAddress *src_address,
1129                      const struct SocketAddress *dst_address,
1130                      struct ip6_header *pkt6)
1131 {
1132   size_t len;
1133
1134   len = payload_length;
1135   switch (protocol)
1136   {
1137   case IPPROTO_UDP:
1138     len += sizeof (struct udp_packet);
1139     break;
1140   case IPPROTO_TCP:
1141     /* tcp_header (with port/crc not set) must be part of payload! */
1142     if (len < sizeof (struct tcp_packet))
1143     {
1144       GNUNET_break (0);
1145       return;
1146     }
1147     break;
1148   default:
1149     GNUNET_break (0);
1150     return;
1151   }
1152   if (len > UINT16_MAX)
1153   {
1154     GNUNET_break (0);
1155     return;
1156   }
1157
1158   pkt6->version = 6;
1159   pkt6->next_header = protocol;
1160   pkt6->payload_length = htons ((uint16_t) (len + sizeof (struct ip6_header)));
1161   pkt6->hop_limit = 255;
1162   pkt6->destination_address = dst_address->address.ipv6;
1163   pkt6->source_address = src_address->address.ipv6;
1164
1165   switch (protocol)
1166   {
1167   case IPPROTO_UDP:
1168     {
1169       struct udp_packet *pkt6_udp = (struct udp_packet *) &pkt6[1];
1170
1171       memcpy (&pkt6[1], payload, payload_length);
1172       pkt6_udp->crc = 0;
1173       pkt6_udp->spt = htons (src_address->port);
1174       pkt6_udp->dpt = htons (dst_address->port);
1175       pkt6_udp->len = htons ((uint16_t) payload_length);
1176
1177       uint32_t sum = 0;
1178       sum = GNUNET_CRYPTO_crc16_step (sum,
1179                                       &pkt6->source_address,
1180                                       sizeof (struct in6_addr) * 2);
1181       uint32_t tmp = htons (len);
1182       sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
1183       tmp = htonl (pkt6->next_header);
1184       sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
1185       sum = GNUNET_CRYPTO_crc16_step (sum, pkt6_udp, len);
1186       pkt6_udp->crc = GNUNET_CRYPTO_crc16_finish (sum);
1187     }
1188     break;
1189   case IPPROTO_TCP:
1190     {
1191       struct tcp_packet *pkt6_tcp = (struct tcp_packet *) pkt6;
1192       
1193       memcpy (pkt6_tcp, payload, payload_length);
1194       pkt6_tcp->crc = 0;
1195       pkt6_tcp->spt = htons (src_address->port);
1196       pkt6_tcp->dpt = htons (dst_address->port);
1197
1198       uint32_t sum = 0;
1199       sum = GNUNET_CRYPTO_crc16_step (sum, &pkt6->source_address, 
1200                                       sizeof (struct in6_addr) * 2);
1201       uint32_t tmp = htonl (len);
1202       sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
1203       tmp = htonl (pkt6->next_header);
1204       sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));      
1205       sum = GNUNET_CRYPTO_crc16_step (sum,  pkt6_tcp, len);
1206       pkt6_tcp->crc = GNUNET_CRYPTO_crc16_finish (sum);
1207     }
1208     break;
1209   default:
1210     GNUNET_assert (0);
1211     break;
1212   }
1213 }
1214
1215
1216 /**
1217  * Send a TCP packet via the TUN interface.
1218  *
1219  * @param destination_address IP and port to use for the TCP packet's destination
1220  * @param source_address IP and port to use for the TCP packet's source
1221  * @param tcp header template to use
1222  * @param payload payload of the TCP packet
1223  * @param payload_length number of bytes in 'payload'
1224  */
1225 static void
1226 send_tcp_packet_via_tun (const struct SocketAddress *destination_address,
1227                          const struct SocketAddress *source_address,
1228                          const struct tcp_packet *tcp_header,
1229                          const void *payload, size_t payload_length)
1230 {
1231   size_t len;
1232
1233   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1234               "Sending packet with %u bytes TCP payload via TUN\n",
1235               (unsigned int) payload_length);
1236   len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct tun_header);
1237   switch (source_address->af)
1238   {
1239   case AF_INET:
1240     len += sizeof (struct ip4_header);
1241     break;
1242   case AF_INET6:
1243     len += sizeof (struct ip6_header);
1244     break;
1245   default:
1246     GNUNET_break (0);
1247     return;
1248   }
1249   len += payload_length;
1250   if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1251   {
1252     GNUNET_break (0);
1253     return;
1254   }
1255   {
1256     char buf[len];
1257     struct GNUNET_MessageHeader *hdr;
1258     struct tun_header *tun;
1259     
1260     hdr= (struct GNUNET_MessageHeader *) buf;
1261     hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1262     hdr->size = htons (len);
1263     tun = (struct tun_header*) &hdr[1];
1264     tun->flags = htons (0);
1265     switch (source_address->af)
1266     {
1267     case AF_INET:
1268       {
1269         struct ip4_header * ipv4 = (struct ip4_header*) &tun[1];
1270         
1271         tun->proto = htons (ETH_P_IPV4);
1272         prepare_ipv4_packet (payload, payload_length,
1273                              IPPROTO_TCP,
1274                              tcp_header, 
1275                              source_address,
1276                              destination_address,
1277                              ipv4);
1278       }
1279       break;
1280     case AF_INET6:
1281       {
1282         struct ip6_header * ipv6 = (struct ip6_header*) &tun[1];
1283         
1284         tun->proto = htons (ETH_P_IPV6);
1285         prepare_ipv6_packet (payload, payload_length, 
1286                              IPPROTO_TCP,
1287                              tcp_header, 
1288                              source_address,
1289                              destination_address,
1290                              ipv6);
1291       }
1292       break;    
1293     default:
1294       GNUNET_assert (0);
1295       break;
1296     }
1297     (void) GNUNET_HELPER_send (helper_handle,
1298                                (const struct GNUNET_MessageHeader*) buf,
1299                                GNUNET_YES,
1300                                NULL, NULL);
1301   }
1302 }
1303
1304
1305 /**
1306  * Process a request via mesh to send a request to a TCP service
1307  * offered by this system.
1308  *
1309  * @param cls closure, NULL
1310  * @param tunnel connection to the other end
1311  * @param tunnel_ctx pointer to our 'struct TunnelState *'
1312  * @param sender who sent the message
1313  * @param message the actual message
1314  * @param atsi performance data for the connection
1315  * @return GNUNET_OK to keep the connection open,
1316  *         GNUNET_SYSERR to close it (signal serious error)
1317  */
1318 static int
1319 receive_tcp_service (void *unused GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1320                      void **tunnel_ctx GNUNET_UNUSED,
1321                      const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1322                      const struct GNUNET_MessageHeader *message,
1323                      const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1324 {
1325   struct TunnelState *state = *tunnel_ctx;
1326   const struct GNUNET_EXIT_TcpServiceStartMessage *start;
1327   uint16_t pkt_len = ntohs (message->size);
1328
1329   /* check that we got at least a valid header */
1330   if (pkt_len < sizeof (struct GNUNET_EXIT_TcpServiceStartMessage))
1331   {
1332     GNUNET_break_op (0);
1333     return GNUNET_SYSERR;
1334   }
1335   start = (const struct GNUNET_EXIT_TcpServiceStartMessage*) message;
1336   pkt_len -= sizeof (struct GNUNET_EXIT_TcpServiceStartMessage);
1337   if ( (NULL == state) ||
1338        (NULL != state->serv) ||
1339        (NULL != state->heap_node) )
1340   {
1341     GNUNET_break_op (0);
1342     return GNUNET_SYSERR;
1343   }
1344   GNUNET_break_op (ntohl (start->reserved) == 0);
1345   /* setup fresh connection */
1346   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1347               "Received data from %s for forwarding to TCP service %s on port %u\n",
1348               GNUNET_i2s (sender),
1349               GNUNET_h2s (&start->service_descriptor),
1350               (unsigned int) ntohs (start->tcp_header.dpt));  
1351   if (NULL == (state->serv = find_service (tcp_services, &start->service_descriptor, 
1352                                            ntohs (start->tcp_header.dpt))))
1353   {
1354     GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
1355                 _("No service found for %s on port %d!\n"),
1356                 "TCP",
1357                 ntohs (start->tcp_header.dpt));
1358     return GNUNET_SYSERR;
1359   }
1360   state->ri.remote_address = state->serv->address;    
1361   setup_state_record (state);
1362   send_tcp_packet_via_tun (&state->ri.remote_address,
1363                            &state->ri.local_address,
1364                            &start->tcp_header,
1365                            &start[1], pkt_len);
1366   return GNUNET_YES;
1367 }
1368
1369
1370 /**
1371  * Process a request to forward TCP data to the Internet via this peer.
1372  *
1373  * @param cls closure, NULL
1374  * @param tunnel connection to the other end
1375  * @param tunnel_ctx pointer to our 'struct TunnelState *'
1376  * @param sender who sent the message
1377  * @param message the actual message
1378  * @param atsi performance data for the connection
1379  * @return GNUNET_OK to keep the connection open,
1380  *         GNUNET_SYSERR to close it (signal serious error)
1381  */
1382 static int
1383 receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1384                     void **tunnel_ctx GNUNET_UNUSED,
1385                     const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1386                     const struct GNUNET_MessageHeader *message,
1387                     const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1388 {
1389   struct TunnelState *state = *tunnel_ctx;
1390   const struct GNUNET_EXIT_TcpInternetStartMessage *start;
1391   uint16_t pkt_len = ntohs (message->size);
1392   const struct in_addr *v4;
1393   const struct in6_addr *v6;
1394   const void *payload;
1395   int af;
1396
1397   if (pkt_len < sizeof (struct GNUNET_EXIT_TcpInternetStartMessage))
1398   {
1399     GNUNET_break_op (0);
1400     return GNUNET_SYSERR;
1401   }
1402   start = (const struct GNUNET_EXIT_TcpInternetStartMessage*) message;
1403   pkt_len -= sizeof (struct GNUNET_EXIT_TcpInternetStartMessage);  
1404   if ( (NULL == state) ||
1405        (NULL != state->serv) ||
1406        (NULL != state->heap_node) )
1407   {
1408     GNUNET_break_op (0);
1409     return GNUNET_SYSERR;
1410   }
1411   af = (int) ntohl (start->af);
1412   state->ri.remote_address.af = af;
1413   switch (af)
1414   {
1415   case AF_INET:
1416     if (pkt_len < sizeof (struct in_addr))
1417     {
1418       GNUNET_break_op (0);
1419       return GNUNET_SYSERR;
1420     }
1421     v4 = (const struct in_addr*) &start[1];
1422     payload = &v4[1];
1423     pkt_len -= sizeof (struct in_addr);
1424     state->ri.remote_address.address.ipv4 = *v4;
1425     break;
1426   case AF_INET6:
1427     if (pkt_len < sizeof (struct in6_addr))
1428     {
1429       GNUNET_break_op (0);
1430       return GNUNET_SYSERR;
1431     }
1432     v6 = (const struct in6_addr*) &start[1];
1433     payload = &v6[1];
1434     pkt_len -= sizeof (struct in_addr);
1435     state->ri.remote_address.address.ipv6 = *v6;
1436     break;
1437   default:
1438     GNUNET_break_op (0);
1439     return GNUNET_SYSERR;
1440   }
1441   {
1442     char buf[INET6_ADDRSTRLEN];
1443     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1444                 "Received data from %s for starting TCP stream to %s:%u\n",
1445                 GNUNET_i2s (sender),
1446                 inet_ntop (af, 
1447                            &state->ri.remote_address.address,
1448                            buf, sizeof (buf)),
1449                 (unsigned int) ntohs (start->tcp_header.dpt));  
1450   }
1451
1452   state->ri.remote_address.proto = IPPROTO_TCP;
1453   state->ri.remote_address.port = ntohs (start->tcp_header.dpt);
1454   setup_state_record (state);
1455   send_tcp_packet_via_tun (&state->ri.remote_address,
1456                            &state->ri.local_address,
1457                            &start->tcp_header,
1458                            payload, pkt_len);
1459   return GNUNET_YES;
1460 }
1461
1462
1463 /**
1464  * Process a request to forward TCP data on an established 
1465  * connection via this peer.
1466  *
1467  * @param cls closure, NULL
1468  * @param tunnel connection to the other end
1469  * @param tunnel_ctx pointer to our 'struct TunnelState *'
1470  * @param sender who sent the message
1471  * @param message the actual message
1472  * @param atsi performance data for the connection
1473  * @return GNUNET_OK to keep the connection open,
1474  *         GNUNET_SYSERR to close it (signal serious error)
1475  */
1476 static int
1477 receive_tcp_data (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1478                   void **tunnel_ctx GNUNET_UNUSED,
1479                   const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1480                   const struct GNUNET_MessageHeader *message,
1481                   const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1482 {
1483   struct TunnelState *state = *tunnel_ctx;
1484   const struct GNUNET_EXIT_TcpDataMessage *data;
1485   uint16_t pkt_len = ntohs (message->size);
1486
1487   if (pkt_len < sizeof (struct GNUNET_EXIT_TcpDataMessage))
1488   {
1489     GNUNET_break_op (0);
1490     return GNUNET_SYSERR;
1491   }
1492   data = (const struct GNUNET_EXIT_TcpDataMessage*) message;
1493   pkt_len -= sizeof (struct GNUNET_EXIT_TcpDataMessage);  
1494   if ( (NULL == state) ||
1495        (NULL == state->heap_node) )
1496   {
1497     /* connection should have been up! */
1498     GNUNET_break_op (0);
1499     /* FIXME: call statistics */
1500     return GNUNET_SYSERR;
1501   }
1502   GNUNET_break_op (ntohl (data->reserved) == 0);
1503   {
1504     char buf[INET6_ADDRSTRLEN];
1505     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1506                 "Received additional data from %s for TCP stream to %s:%u\n",
1507                 GNUNET_i2s (sender),
1508                 inet_ntop (state->ri.remote_address.af, 
1509                            &state->ri.remote_address.address,
1510                            buf, sizeof (buf)),
1511                 (unsigned int) state->ri.remote_address.port);
1512   }
1513
1514   send_tcp_packet_via_tun (&state->ri.remote_address,
1515                            &state->ri.local_address,
1516                            &data->tcp_header,
1517                            &data[1], pkt_len);
1518   return GNUNET_YES;
1519 }
1520
1521
1522 /**
1523  * Send a UDP packet via the TUN interface.
1524  *
1525  * @param destination_address IP and port to use for the UDP packet's destination
1526  * @param source_address IP and port to use for the UDP packet's source
1527  * @param payload payload of the UDP packet (does NOT include UDP header)
1528  * @param payload_length number of bytes of data in payload
1529  */
1530 static void
1531 send_udp_packet_via_tun (const struct SocketAddress *destination_address,
1532                          const struct SocketAddress *source_address,
1533                          const void *payload, size_t payload_length)
1534 {
1535   size_t len;
1536
1537   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1538               "Sending packet with %u bytes UDP payload via TUN\n",
1539               (unsigned int) payload_length);
1540   len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct tun_header);
1541   switch (source_address->af)
1542   {
1543   case AF_INET:
1544     len += sizeof (struct ip4_header);
1545     break;
1546   case AF_INET6:
1547     len += sizeof (struct ip6_header);
1548     break;
1549   default:
1550     GNUNET_break (0);
1551     return;
1552   }
1553   len += sizeof (struct udp_packet);
1554   len += payload_length;
1555   if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1556   {
1557     GNUNET_break (0);
1558     return;
1559   }
1560   {
1561     char buf[len];
1562     struct GNUNET_MessageHeader *hdr;
1563     struct tun_header *tun;
1564     
1565     hdr= (struct GNUNET_MessageHeader *) buf;
1566     hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1567     hdr->size = htons (len);
1568     tun = (struct tun_header*) &hdr[1];
1569     tun->flags = htons (0);
1570     switch (source_address->af)
1571     {
1572     case AF_INET:
1573       {
1574         struct ip4_header * ipv4 = (struct ip4_header*) &tun[1];
1575         
1576         tun->proto = htons (ETH_P_IPV4);
1577         prepare_ipv4_packet (payload, payload_length,
1578                              IPPROTO_UDP,
1579                              NULL,
1580                              source_address,
1581                              destination_address,
1582                              ipv4);
1583       }
1584       break;
1585     case AF_INET6:
1586       {
1587         struct ip6_header * ipv6 = (struct ip6_header*) &tun[1];
1588         
1589         tun->proto = htons (ETH_P_IPV6);
1590         prepare_ipv6_packet (payload, payload_length, 
1591                              IPPROTO_UDP,
1592                              NULL,
1593                              source_address,
1594                              destination_address,
1595                              ipv6);
1596       }
1597       break;    
1598     default:
1599       GNUNET_assert (0);
1600       break;
1601     }
1602     (void) GNUNET_HELPER_send (helper_handle,
1603                                (const struct GNUNET_MessageHeader*) buf,
1604                                GNUNET_YES,
1605                                NULL, NULL);
1606   }
1607 }
1608
1609
1610 /**
1611  * Process a request to forward UDP data to the Internet via this peer.
1612  *
1613  * @param cls closure, NULL
1614  * @param tunnel connection to the other end
1615  * @param tunnel_ctx pointer to our 'struct TunnelState *'
1616  * @param sender who sent the message
1617  * @param message the actual message
1618  * @param atsi performance data for the connection
1619  * @return GNUNET_OK to keep the connection open,
1620  *         GNUNET_SYSERR to close it (signal serious error)
1621  */
1622 static int
1623 receive_udp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1624                     void **tunnel_ctx GNUNET_UNUSED,
1625                     const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1626                     const struct GNUNET_MessageHeader *message,
1627                     const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1628 {
1629   struct TunnelState *state = *tunnel_ctx;
1630   const struct GNUNET_EXIT_UdpInternetMessage *msg;
1631   uint16_t pkt_len = ntohs (message->size);
1632   const struct in_addr *v4;
1633   const struct in6_addr *v6;
1634   const void *payload;
1635   int af;
1636
1637   if (pkt_len < sizeof (struct GNUNET_EXIT_UdpInternetMessage))
1638   {
1639     GNUNET_break_op (0);
1640     return GNUNET_SYSERR;
1641   }
1642   msg = (const struct GNUNET_EXIT_UdpInternetMessage*) message;
1643   pkt_len -= sizeof (struct GNUNET_EXIT_UdpInternetMessage);  
1644   af = (int) ntohl (msg->af);
1645   state->ri.remote_address.af = af;
1646   switch (af)
1647   {
1648   case AF_INET:
1649     if (pkt_len < sizeof (struct in_addr))
1650     {
1651       GNUNET_break_op (0);
1652       return GNUNET_SYSERR;
1653     }
1654     v4 = (const struct in_addr*) &msg[1];
1655     payload = &v4[1];
1656     pkt_len -= sizeof (struct in_addr);
1657     state->ri.remote_address.address.ipv4 = *v4;
1658     break;
1659   case AF_INET6:
1660     if (pkt_len < sizeof (struct in6_addr))
1661     {
1662       GNUNET_break_op (0);
1663       return GNUNET_SYSERR;
1664     }
1665     v6 = (const struct in6_addr*) &msg[1];
1666     payload = &v6[1];
1667     pkt_len -= sizeof (struct in_addr);
1668     state->ri.remote_address.address.ipv6 = *v6;
1669     break;
1670   default:
1671     GNUNET_break_op (0);
1672     return GNUNET_SYSERR;
1673   }
1674   {
1675     char buf[INET6_ADDRSTRLEN];
1676     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1677                 "Received data from %s for forwarding to UDP %s:%u\n",
1678                 GNUNET_i2s (sender),
1679                 inet_ntop (af, 
1680                            &state->ri.remote_address.address,
1681                            buf, sizeof (buf)),
1682                 (unsigned int) ntohs (msg->destination_port));  
1683   }
1684   state->ri.remote_address.proto = IPPROTO_UDP;
1685   state->ri.remote_address.port = msg->destination_port;
1686   if (NULL == state->heap_node)
1687     setup_state_record (state);
1688   if (0 != ntohs (msg->source_port))
1689     state->ri.local_address.port = msg->source_port;
1690   send_udp_packet_via_tun (&state->ri.remote_address,
1691                            &state->ri.local_address,
1692                            payload, pkt_len);
1693   return GNUNET_YES;
1694 }
1695
1696
1697 /**
1698  * Process a request via mesh to send a request to a UDP service
1699  * offered by this system.
1700  *
1701  * @param cls closure, NULL
1702  * @param tunnel connection to the other end
1703  * @param tunnel_ctx pointer to our 'struct TunnelState *'
1704  * @param sender who sent the message
1705  * @param message the actual message
1706  * @param atsi performance data for the connection
1707  * @return GNUNET_OK to keep the connection open,
1708  *         GNUNET_SYSERR to close it (signal serious error)
1709  */
1710 static int
1711 receive_udp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1712                      void **tunnel_ctx,
1713                      const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1714                      const struct GNUNET_MessageHeader *message,
1715                      const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1716 {
1717   struct TunnelState *state = *tunnel_ctx;
1718   const struct GNUNET_EXIT_UdpServiceMessage *msg;
1719   uint16_t pkt_len = ntohs (message->size);
1720
1721   /* check that we got at least a valid header */
1722   if (pkt_len < sizeof (struct GNUNET_EXIT_UdpServiceMessage))
1723   {
1724     GNUNET_break_op (0);
1725     return GNUNET_SYSERR;
1726   }
1727   msg = (const struct GNUNET_EXIT_UdpServiceMessage*) message;
1728   pkt_len -= sizeof (struct GNUNET_EXIT_UdpServiceMessage);
1729   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1730               "Received data from %s for forwarding to UDP service %s on port %u\n",
1731               GNUNET_i2s (sender),
1732               GNUNET_h2s (&msg->service_descriptor),
1733               (unsigned int) ntohs (msg->destination_port));  
1734   if (NULL == (state->serv = find_service (udp_services, &msg->service_descriptor, 
1735                                            ntohs (msg->destination_port))))
1736   {
1737     GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
1738                 _("No service found for %s on port %d!\n"),
1739                 "UDP",
1740                 ntohs (msg->destination_port));
1741     return GNUNET_SYSERR;
1742   }
1743   state->ri.remote_address = state->serv->address;    
1744   setup_state_record (state);
1745   if (0 != ntohs (msg->source_port))
1746     state->ri.local_address.port = msg->source_port;
1747   send_udp_packet_via_tun (&state->ri.remote_address,
1748                            &state->ri.local_address,
1749                            &msg[1], pkt_len);
1750   return GNUNET_YES;
1751 }
1752
1753
1754 /**
1755  * Callback from GNUNET_MESH for new tunnels.
1756  *
1757  * @param cls closure
1758  * @param tunnel new handle to the tunnel
1759  * @param initiator peer that started the tunnel
1760  * @param atsi performance information for the tunnel
1761  * @return initial tunnel context for the tunnel
1762  */
1763 static void *
1764 new_tunnel (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1765             const struct GNUNET_PeerIdentity *initiator GNUNET_UNUSED,
1766             const struct GNUNET_ATS_Information *ats GNUNET_UNUSED)
1767 {
1768   struct TunnelState *s = GNUNET_malloc (sizeof (struct TunnelState));
1769
1770   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1771               "Received inbound tunnel from `%s'\n",
1772               GNUNET_i2s (initiator));
1773   s->tunnel = tunnel;
1774   return s;
1775 }
1776
1777
1778 /**
1779  * Function called by mesh whenever an inbound tunnel is destroyed.
1780  * Should clean up any associated state.
1781  *
1782  * @param cls closure (set from GNUNET_MESH_connect)
1783  * @param tunnel connection to the other end (henceforth invalid)
1784  * @param tunnel_ctx place where local state associated
1785  *                   with the tunnel is stored
1786  */
1787 static void
1788 clean_tunnel (void *cls GNUNET_UNUSED, const struct GNUNET_MESH_Tunnel *tunnel,
1789               void *tunnel_ctx)
1790 {
1791   struct TunnelState *s = tunnel_ctx;
1792   struct TunnelMessageQueue *tnq;
1793
1794   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1795               "Tunnel destroyed\n");
1796   while (NULL != (tnq = s->head))
1797   {
1798     GNUNET_CONTAINER_DLL_remove (s->head,
1799                                  s->tail,
1800                                  tnq);
1801     GNUNET_free (tnq);
1802   }
1803   if (s->heap_node != NULL)
1804   {
1805     GNUNET_assert (GNUNET_YES ==
1806                    GNUNET_CONTAINER_multihashmap_remove (connections_map,
1807                                                          &s->state_key,
1808                                                          s));
1809     GNUNET_CONTAINER_heap_remove_node (s->heap_node);
1810     s->heap_node = NULL;
1811   }
1812   if (NULL != s->th)
1813   {
1814     GNUNET_MESH_notify_transmit_ready_cancel (s->th);
1815     s->th = NULL;
1816   }
1817   GNUNET_free (s);
1818 }
1819
1820
1821 /**
1822  * Function that frees everything from a hashmap
1823  *
1824  * @param cls unused
1825  * @param hash key
1826  * @param value value to free
1827  */
1828 static int
1829 free_iterate (void *cls GNUNET_UNUSED,
1830               const GNUNET_HashCode * hash GNUNET_UNUSED, void *value)
1831 {
1832   GNUNET_free (value);
1833   return GNUNET_YES;
1834 }
1835
1836
1837 /**
1838  * Function scheduled as very last function, cleans up after us
1839  */
1840 static void
1841 cleanup (void *cls GNUNET_UNUSED,
1842          const struct GNUNET_SCHEDULER_TaskContext *tskctx)
1843 {
1844   unsigned int i;
1845
1846   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1847               "Exit service is shutting down now\n");
1848   if (helper_handle != NULL)
1849   {
1850     GNUNET_HELPER_stop (helper_handle);
1851     helper_handle = NULL;
1852   }
1853   if (mesh_handle != NULL)
1854   {
1855     GNUNET_MESH_disconnect (mesh_handle);
1856     mesh_handle = NULL;
1857   }
1858   if (NULL != connections_map)
1859   {
1860     GNUNET_CONTAINER_multihashmap_iterate (connections_map, &free_iterate, NULL);
1861     GNUNET_CONTAINER_multihashmap_destroy (connections_map);
1862     connections_map = NULL;
1863   }
1864   if (NULL != connections_heap)
1865   {
1866     GNUNET_CONTAINER_heap_destroy (connections_heap);
1867     connections_heap = NULL;
1868   }
1869   if (NULL != tcp_services)
1870   {
1871     GNUNET_CONTAINER_multihashmap_iterate (tcp_services, &free_service_record, NULL);
1872     GNUNET_CONTAINER_multihashmap_destroy (tcp_services);
1873     tcp_services = NULL;
1874   }
1875   if (NULL != udp_services)
1876   {
1877     GNUNET_CONTAINER_multihashmap_iterate (udp_services, &free_service_record, NULL);
1878     GNUNET_CONTAINER_multihashmap_destroy (udp_services);
1879     udp_services = NULL;
1880   }
1881   for (i=0;i<5;i++)
1882     GNUNET_free_non_null (exit_argv[i]);
1883 }
1884
1885
1886 /**
1887  * Add services to the service map.
1888  *
1889  * @param proto IPPROTO_TCP or IPPROTO_UDP
1890  * @param cpy copy of the service descriptor (can be mutilated)
1891  * @param name DNS name of the service
1892  */
1893 static void
1894 add_services (int proto,
1895               char *cpy,
1896               const char *name)
1897 {
1898   char *redirect;
1899   char *hostname;
1900   char *hostport;
1901   struct LocalService *serv;
1902
1903   for (redirect = strtok (cpy, " "); redirect != NULL;
1904        redirect = strtok (NULL, " "))
1905   {
1906     if (NULL == (hostname = strstr (redirect, ":")))
1907     {
1908       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1909                   "option `%s' for domain `%s' is not formatted correctly!\n",
1910                   redirect,
1911                   name);
1912       continue;
1913     }
1914     hostname[0] = '\0';
1915     hostname++;
1916     if (NULL == (hostport = strstr (hostname, ":")))
1917     {
1918       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1919                   "option `%s' for domain `%s' is not formatted correctly!\n",
1920                   redirect,
1921                   name);
1922       continue;
1923     }
1924     hostport[0] = '\0';
1925     hostport++;
1926     
1927     int local_port = atoi (redirect);
1928     int remote_port = atoi (hostport);
1929     
1930     if (!((local_port > 0) && (local_port < 65536)))
1931     {
1932       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1933                   "`%s' is not a valid port number (for domain `%s')!", redirect,
1934                   name);
1935       continue;
1936     }
1937     if (!((remote_port > 0) && (remote_port < 65536)))
1938     {
1939       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1940                   "`%s' is not a valid port number (for domain `%s')!", hostport,
1941                   name);
1942       continue;
1943     }
1944
1945     serv = GNUNET_malloc (sizeof (struct LocalService));
1946     serv->my_port = (uint16_t) local_port;
1947     serv->address.port = remote_port;
1948     if (0 == strcmp ("localhost4", hostname))
1949     {
1950       const char *ip4addr = exit_argv[4];
1951
1952       serv->address.af = AF_INET;      
1953       GNUNET_assert (1 != inet_pton (AF_INET, ip4addr, &serv->address.address.ipv4));
1954     }
1955     else if (0 == strcmp ("localhost6", hostname))
1956     {
1957       const char *ip6addr = exit_argv[2];
1958
1959       serv->address.af = AF_INET6;
1960       GNUNET_assert (1 == inet_pton (AF_INET6, ip6addr, &serv->address.address.ipv6));
1961     }
1962     else
1963     {
1964       struct addrinfo *res;      
1965       int ret;
1966
1967       ret = getaddrinfo (hostname, NULL, NULL, &res);      
1968       if ( (ret != 0) || (res == NULL) )
1969       {
1970         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1971                     _("No addresses found for hostname `%s' of service `%s'!\n"),
1972                     hostname,
1973                     name);
1974         GNUNET_free (serv);
1975         continue;
1976       }
1977       
1978       serv->address.af = res->ai_family;
1979       switch (res->ai_family)
1980       {
1981         case AF_INET:
1982           serv->address.address.ipv4 = ((struct sockaddr_in *) res->ai_addr)->sin_addr;
1983           break;
1984         case AF_INET6:
1985           serv->address.address.ipv6 = ((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
1986           break;
1987       default:
1988         freeaddrinfo (res);
1989         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1990                     _("No IP addresses found for hostname `%s' of service `%s'!\n"),
1991                     hostname,
1992                     name);
1993         GNUNET_free (serv);
1994         continue;
1995       }
1996       freeaddrinfo (res);
1997     }
1998     store_service ((IPPROTO_UDP == proto) ? udp_services : tcp_services,
1999                    name,
2000                    local_port,
2001                    serv);
2002   }
2003 }
2004
2005
2006 /**
2007  * Reads the configuration servicecfg and populates udp_services
2008  *
2009  * @param cls unused
2010  * @param section name of section in config, equal to hostname
2011  */
2012 static void
2013 read_service_conf (void *cls GNUNET_UNUSED, const char *section)
2014 {
2015   char *cpy;
2016
2017   if ((strlen (section) < 8) ||
2018       (0 != strcmp (".gnunet.", section + (strlen (section) - 8))))
2019     return;
2020   if (GNUNET_OK ==
2021       GNUNET_CONFIGURATION_get_value_string (cfg, section, "UDP_REDIRECTS",
2022                                              &cpy))
2023   {
2024     add_services (IPPROTO_UDP, cpy, section);
2025     GNUNET_free (cpy);
2026   }
2027   if (GNUNET_OK ==
2028       GNUNET_CONFIGURATION_get_value_string (cfg, section, "TCP_REDIRECTS",
2029                                              &cpy))
2030   {
2031     add_services (IPPROTO_TCP, cpy, section);
2032     GNUNET_free (cpy);
2033   }
2034 }
2035
2036
2037 /**
2038  * @brief Main function that will be run by the scheduler.
2039  *
2040  * @param cls closure
2041  * @param args remaining command-line arguments
2042  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
2043  * @param cfg_ configuration
2044  */
2045 static void
2046 run (void *cls, char *const *args GNUNET_UNUSED,
2047      const char *cfgfile GNUNET_UNUSED,
2048      const struct GNUNET_CONFIGURATION_Handle *cfg_)
2049 {
2050   static struct GNUNET_MESH_MessageHandler handlers[] = {
2051     {&receive_udp_service, GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE, 0},
2052     {&receive_udp_remote, GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET, 0},
2053     {&receive_tcp_service, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START, 0},
2054     {&receive_tcp_remote, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START, 0},
2055     {&receive_tcp_data, GNUNET_MESSAGE_TYPE_VPN_TCP_DATA, 0},
2056     {NULL, 0, 0}
2057   };
2058
2059   static GNUNET_MESH_ApplicationType apptypes[] = {
2060     GNUNET_APPLICATION_TYPE_END,
2061     GNUNET_APPLICATION_TYPE_END,
2062     GNUNET_APPLICATION_TYPE_END
2063   };
2064   unsigned int app_idx;
2065   char *exit_ifname;
2066   char *tun_ifname;
2067   char *ipv6addr;
2068   char *ipv6prefix_s;
2069   char *ipv4addr;
2070   char *ipv4mask;
2071   struct in_addr v4;
2072   struct in6_addr v6;
2073
2074   cfg = cfg_;
2075   ipv4_exit = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "EXIT_IPV4");
2076   ipv6_exit = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "EXIT_IPV6"); 
2077   ipv4_enabled = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_IPV4");
2078   ipv6_enabled = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_IPV6"); 
2079   if (ipv4_exit && (! ipv4_enabled))
2080   {
2081     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2082                 _("Cannot enable IPv4 exit but disable IPv4 on TUN interface, will use ENABLE_IPv4=YES\n"));
2083     ipv4_enabled = GNUNET_YES;
2084   }
2085   if (ipv6_exit && (! ipv6_enabled))
2086   {
2087     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2088                 _("Cannot enable IPv6 exit but disable IPv6 on TUN interface, will use ENABLE_IPv6=YES\n"));
2089     ipv6_enabled = GNUNET_YES;
2090   }
2091   if (! (ipv4_enabled || ipv6_enabled))
2092   {
2093     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2094                 _("No useful service enabled.  Exiting.\n"));
2095     GNUNET_SCHEDULER_shutdown ();
2096     return;    
2097   }
2098   app_idx = 0;
2099   if (GNUNET_YES == ipv4_exit)    
2100   {
2101     apptypes[app_idx] = GNUNET_APPLICATION_TYPE_IPV4_GATEWAY;
2102     app_idx++;
2103   }
2104   if (GNUNET_YES == ipv6_exit)    
2105   {
2106     apptypes[app_idx] = GNUNET_APPLICATION_TYPE_IPV6_GATEWAY;
2107     app_idx++;
2108   }
2109
2110   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls);
2111
2112   if (GNUNET_OK !=
2113       GNUNET_CONFIGURATION_get_value_number (cfg, "exit", "MAX_CONNECTIONS",
2114                                              &max_connections))
2115     max_connections = 1024;
2116   exit_argv[0] = GNUNET_strdup ("exit-gnunet");
2117   if (GNUNET_SYSERR ==
2118       GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "TUN_IFNAME", &tun_ifname))
2119   {
2120     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2121                 "No entry 'TUN_IFNAME' in configuration!\n");
2122     GNUNET_SCHEDULER_shutdown ();
2123     return;
2124   }
2125   exit_argv[1] = tun_ifname;
2126   if (ipv4_enabled)
2127   {
2128     if (GNUNET_SYSERR ==
2129         GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "EXIT_IFNAME", &exit_ifname))
2130     {
2131       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2132                   "No entry 'EXIT_IFNAME' in configuration!\n");
2133       GNUNET_SCHEDULER_shutdown ();
2134       return;
2135     }
2136     exit_argv[2] = exit_ifname;
2137   }
2138   else
2139   {
2140     exit_argv[2] = GNUNET_strdup ("%");
2141   }
2142   if (GNUNET_YES == ipv6_enabled)
2143   {
2144     if ( (GNUNET_SYSERR ==
2145           GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6ADDR",
2146                                                  &ipv6addr) ||
2147           (1 != inet_pton (AF_INET6, ipv6addr, &v6))) )
2148     {
2149       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2150                   "No valid entry 'IPV6ADDR' in configuration!\n");
2151       GNUNET_SCHEDULER_shutdown ();
2152       return;
2153     }
2154     exit_argv[3] = ipv6addr;
2155     if (GNUNET_SYSERR ==
2156         GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6PREFIX",
2157                                                &ipv6prefix_s))
2158     {
2159       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2160                   "No entry 'IPV6PREFIX' in configuration!\n");
2161       GNUNET_SCHEDULER_shutdown ();
2162       return;
2163     }
2164     exit_argv[4] = ipv6prefix_s;
2165     if ( (GNUNET_OK !=
2166           GNUNET_CONFIGURATION_get_value_number (cfg, "exit",
2167                                                  "IPV6PREFIX",
2168                                                  &ipv6prefix)) ||
2169          (ipv6prefix >= 127) )
2170     {
2171       GNUNET_SCHEDULER_shutdown ();
2172       return;
2173     }
2174   } 
2175   else
2176   {
2177     /* IPv6 explicitly disabled */
2178     exit_argv[3] = GNUNET_strdup ("-");
2179     exit_argv[4] = GNUNET_strdup ("-");
2180   }
2181   if (GNUNET_YES == ipv4_enabled)
2182   {
2183     if ( (GNUNET_SYSERR ==
2184           GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4ADDR",
2185                                                  &ipv4addr) ||
2186           (1 != inet_pton (AF_INET, ipv4addr, &v4))) )
2187       {
2188         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2189                     "No valid entry for 'IPV4ADDR' in configuration!\n");
2190         GNUNET_SCHEDULER_shutdown ();
2191         return;
2192       }
2193     exit_argv[5] = ipv4addr;
2194     if ( (GNUNET_SYSERR ==
2195           GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4MASK",
2196                                                  &ipv4mask) ||
2197           (1 != inet_pton (AF_INET, ipv4mask, &v4))) )
2198     {
2199       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2200                   "No valid entry 'IPV4MASK' in configuration!\n");
2201       GNUNET_SCHEDULER_shutdown ();
2202       return;
2203     }
2204     exit_argv[6] = ipv4mask;
2205   }
2206   else
2207   {
2208     /* IPv4 explicitly disabled */
2209     exit_argv[5] = GNUNET_strdup ("-");
2210     exit_argv[6] = GNUNET_strdup ("-");
2211   }
2212   exit_argv[7] = NULL;
2213
2214   udp_services = GNUNET_CONTAINER_multihashmap_create (65536);
2215   tcp_services = GNUNET_CONTAINER_multihashmap_create (65536);
2216   GNUNET_CONFIGURATION_iterate_sections (cfg, &read_service_conf, NULL);
2217
2218   connections_map = GNUNET_CONTAINER_multihashmap_create (65536);
2219   connections_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
2220   mesh_handle 
2221     = GNUNET_MESH_connect (cfg, 42 /* queue size */, NULL, 
2222                            &new_tunnel, 
2223                            &clean_tunnel, handlers,
2224                            apptypes);
2225   if (NULL == mesh_handle)
2226   {
2227     GNUNET_SCHEDULER_shutdown ();
2228     return;
2229   }
2230   helper_handle = GNUNET_HELPER_start ("gnunet-helper-exit", 
2231                                        exit_argv,
2232                                        &message_token, NULL);
2233 }
2234
2235
2236 /**
2237  * The main function
2238  *
2239  * @param argc number of arguments from the command line
2240  * @param argv command line arguments
2241  * @return 0 ok, 1 on error
2242  */
2243 int
2244 main (int argc, char *const *argv)
2245 {
2246   static const struct GNUNET_GETOPT_CommandLineOption options[] = {
2247     GNUNET_GETOPT_OPTION_END
2248   };
2249
2250   return (GNUNET_OK ==
2251           GNUNET_PROGRAM_run (argc, argv, "gnunet-daemon-exit",
2252                               gettext_noop
2253                               ("Daemon to run to provide an IP exit node for the VPN"),
2254                               options, &run, NULL)) ? 0 : 1;
2255 }
2256
2257
2258 /* end of gnunet-daemon-exit.c */