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