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