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