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