-renaming TUN structs to follow namnig conventions
[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   pkt4->version = 4;
1069   pkt4->header_length = sizeof (struct GNUNET_TUN_IPv4Header) / 4;
1070   pkt4->diff_serv = 0;
1071   pkt4->total_length = htons ((uint16_t) (sizeof (struct GNUNET_TUN_IPv4Header) + len));
1072   pkt4->identification = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 
1073                                                               UINT16_MAX + 1);
1074   pkt4->flags = 0;
1075   pkt4->fragmentation_offset = 0;
1076   pkt4->ttl = 255;
1077   pkt4->protocol = protocol;
1078   pkt4->checksum = 0;
1079   pkt4->destination_address = dst_address->address.ipv4;
1080   pkt4->source_address = src_address->address.ipv4;
1081   pkt4->checksum = GNUNET_CRYPTO_crc16_n (pkt4, sizeof (struct GNUNET_TUN_IPv4Header));
1082
1083   switch (protocol)
1084   {
1085   case IPPROTO_UDP:
1086     {
1087       struct GNUNET_TUN_UdpHeader *pkt4_udp = (struct GNUNET_TUN_UdpHeader *) &pkt4[1];
1088
1089       pkt4_udp->spt = htons (src_address->port);
1090       pkt4_udp->dpt = htons (dst_address->port);
1091       pkt4_udp->crc = 0;  /* Optional for IPv4 */
1092       pkt4_udp->len = htons ((uint16_t) payload_length);
1093       memcpy (&pkt4_udp[1], payload, payload_length);
1094     }
1095     break;
1096   case IPPROTO_TCP:
1097     {
1098       struct GNUNET_TUN_TcpHeader *pkt4_tcp = (struct GNUNET_TUN_TcpHeader *) &pkt4[1];
1099       
1100       memcpy (pkt4_tcp, tcp_header, sizeof (struct GNUNET_TUN_TcpHeader));
1101       memcpy (&pkt4_tcp[1], payload, payload_length);
1102       pkt4_tcp->spt = htons (src_address->port);
1103       pkt4_tcp->dpt = htons (dst_address->port);
1104       pkt4_tcp->crc = 0;
1105       uint32_t sum = 0;
1106       sum = GNUNET_CRYPTO_crc16_step (sum, 
1107                                       &pkt4->source_address,
1108                                       sizeof (struct in_addr) * 2);
1109       uint32_t tmp = htonl ((protocol << 16) | (0xffff & len));
1110       sum = GNUNET_CRYPTO_crc16_step (sum, & tmp, sizeof (uint32_t));
1111       sum = GNUNET_CRYPTO_crc16_step (sum, & pkt4_tcp, len);
1112       pkt4_tcp->crc = GNUNET_CRYPTO_crc16_finish (sum);
1113     }
1114     break;
1115   default:
1116     GNUNET_assert (0);
1117   }
1118 }
1119
1120
1121 /**
1122  * Prepare an IPv6 packet for transmission via the TUN interface.
1123  * Initializes the IP header and calculates checksums (IP+UDP/TCP).
1124  * For UDP, the UDP header will be fully created, whereas for TCP
1125  * only the ports and checksum will be filled in.  So for TCP,
1126  * a skeleton TCP header must be part of the provided payload.
1127  *
1128  * @param payload payload of the packet (starting with UDP payload or
1129  *                TCP header, depending on protocol)
1130  * @param payload_length number of bytes in 'payload'
1131  * @param protocol IPPROTO_UDP or IPPROTO_TCP
1132  * @param src_address source address to use (IP and port)
1133  * @param dst_address destination address to use (IP and port)
1134  * @param pkt6 where to write the assembled packet; must
1135  *        contain enough space for the IP header, UDP/TCP header
1136  *        AND the payload
1137  */
1138 static void
1139 prepare_ipv6_packet (const void *payload, size_t payload_length,
1140                      int protocol,
1141                      const struct GNUNET_TUN_TcpHeader *tcp_header,
1142                      const struct SocketAddress *src_address,
1143                      const struct SocketAddress *dst_address,
1144                      struct GNUNET_TUN_IPv6Header *pkt6)
1145 {
1146   size_t len;
1147
1148   len = payload_length;
1149   switch (protocol)
1150   {
1151   case IPPROTO_UDP:
1152     len += sizeof (struct GNUNET_TUN_UdpHeader);
1153     break;
1154   case IPPROTO_TCP:
1155     /* tcp_header (with port/crc not set) must be part of payload! */
1156     if (len < sizeof (struct GNUNET_TUN_TcpHeader))
1157     {
1158       GNUNET_break (0);
1159       return;
1160     }
1161     break;
1162   default:
1163     GNUNET_break (0);
1164     return;
1165   }
1166   if (len > UINT16_MAX)
1167   {
1168     GNUNET_break (0);
1169     return;
1170   }
1171
1172   pkt6->version = 6;
1173   pkt6->next_header = protocol;
1174   pkt6->payload_length = htons ((uint16_t) (len + sizeof (struct GNUNET_TUN_IPv6Header)));
1175   pkt6->hop_limit = 255;
1176   pkt6->destination_address = dst_address->address.ipv6;
1177   pkt6->source_address = src_address->address.ipv6;
1178
1179   switch (protocol)
1180   {
1181   case IPPROTO_UDP:
1182     {
1183       struct GNUNET_TUN_UdpHeader *pkt6_udp = (struct GNUNET_TUN_UdpHeader *) &pkt6[1];
1184
1185       memcpy (&pkt6[1], payload, payload_length);
1186       pkt6_udp->crc = 0;
1187       pkt6_udp->spt = htons (src_address->port);
1188       pkt6_udp->dpt = htons (dst_address->port);
1189       pkt6_udp->len = htons ((uint16_t) payload_length);
1190
1191       uint32_t sum = 0;
1192       sum = GNUNET_CRYPTO_crc16_step (sum,
1193                                       &pkt6->source_address,
1194                                       sizeof (struct in6_addr) * 2);
1195       uint32_t tmp = htons (len);
1196       sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
1197       tmp = htonl (pkt6->next_header);
1198       sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
1199       sum = GNUNET_CRYPTO_crc16_step (sum, pkt6_udp, len);
1200       pkt6_udp->crc = GNUNET_CRYPTO_crc16_finish (sum);
1201     }
1202     break;
1203   case IPPROTO_TCP:
1204     {
1205       struct GNUNET_TUN_TcpHeader *pkt6_tcp = (struct GNUNET_TUN_TcpHeader *) pkt6;
1206       
1207       memcpy (pkt6_tcp, payload, payload_length);
1208       pkt6_tcp->crc = 0;
1209       pkt6_tcp->spt = htons (src_address->port);
1210       pkt6_tcp->dpt = htons (dst_address->port);
1211
1212       uint32_t sum = 0;
1213       sum = GNUNET_CRYPTO_crc16_step (sum, &pkt6->source_address, 
1214                                       sizeof (struct in6_addr) * 2);
1215       uint32_t tmp = htonl (len);
1216       sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
1217       tmp = htonl (pkt6->next_header);
1218       sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));      
1219       sum = GNUNET_CRYPTO_crc16_step (sum,  pkt6_tcp, len);
1220       pkt6_tcp->crc = GNUNET_CRYPTO_crc16_finish (sum);
1221     }
1222     break;
1223   default:
1224     GNUNET_assert (0);
1225     break;
1226   }
1227 }
1228
1229
1230 /**
1231  * Send a TCP packet via the TUN interface.
1232  *
1233  * @param destination_address IP and port to use for the TCP packet's destination
1234  * @param source_address IP and port to use for the TCP packet's source
1235  * @param tcp header template to use
1236  * @param payload payload of the TCP packet
1237  * @param payload_length number of bytes in 'payload'
1238  */
1239 static void
1240 send_tcp_packet_via_tun (const struct SocketAddress *destination_address,
1241                          const struct SocketAddress *source_address,
1242                          const struct GNUNET_TUN_TcpHeader *tcp_header,
1243                          const void *payload, size_t payload_length)
1244 {
1245   size_t len;
1246
1247   GNUNET_STATISTICS_update (stats,
1248                             gettext_noop ("# TCP packets sent via TUN"),
1249                             1, GNUNET_NO);
1250   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1251               "Sending packet with %u bytes TCP payload via TUN\n",
1252               (unsigned int) payload_length);
1253   len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader);
1254   switch (source_address->af)
1255   {
1256   case AF_INET:
1257     len += sizeof (struct GNUNET_TUN_IPv4Header);
1258     break;
1259   case AF_INET6:
1260     len += sizeof (struct GNUNET_TUN_IPv6Header);
1261     break;
1262   default:
1263     GNUNET_break (0);
1264     return;
1265   }
1266   len += payload_length;
1267   if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1268   {
1269     GNUNET_break (0);
1270     return;
1271   }
1272   {
1273     char buf[len];
1274     struct GNUNET_MessageHeader *hdr;
1275     struct GNUNET_TUN_Layer2PacketHeader *tun;
1276     
1277     hdr= (struct GNUNET_MessageHeader *) buf;
1278     hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1279     hdr->size = htons (len);
1280     tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1281     tun->flags = htons (0);
1282     switch (source_address->af)
1283     {
1284     case AF_INET:
1285       {
1286         struct GNUNET_TUN_IPv4Header * ipv4 = (struct GNUNET_TUN_IPv4Header*) &tun[1];
1287         
1288         tun->proto = htons (ETH_P_IPV4);
1289         prepare_ipv4_packet (payload, payload_length,
1290                              IPPROTO_TCP,
1291                              tcp_header, 
1292                              source_address,
1293                              destination_address,
1294                              ipv4);
1295       }
1296       break;
1297     case AF_INET6:
1298       {
1299         struct GNUNET_TUN_IPv6Header * ipv6 = (struct GNUNET_TUN_IPv6Header*) &tun[1];
1300         
1301         tun->proto = htons (ETH_P_IPV6);
1302         prepare_ipv6_packet (payload, payload_length, 
1303                              IPPROTO_TCP,
1304                              tcp_header, 
1305                              source_address,
1306                              destination_address,
1307                              ipv6);
1308       }
1309       break;    
1310     default:
1311       GNUNET_assert (0);
1312       break;
1313     }
1314     (void) GNUNET_HELPER_send (helper_handle,
1315                                (const struct GNUNET_MessageHeader*) buf,
1316                                GNUNET_YES,
1317                                NULL, NULL);
1318   }
1319 }
1320
1321
1322 /**
1323  * Process a request via mesh to send a request to a TCP service
1324  * offered by this system.
1325  *
1326  * @param cls closure, NULL
1327  * @param tunnel connection to the other end
1328  * @param tunnel_ctx pointer to our 'struct TunnelState *'
1329  * @param sender who sent the message
1330  * @param message the actual message
1331  * @param atsi performance data for the connection
1332  * @return GNUNET_OK to keep the connection open,
1333  *         GNUNET_SYSERR to close it (signal serious error)
1334  */
1335 static int
1336 receive_tcp_service (void *unused GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1337                      void **tunnel_ctx GNUNET_UNUSED,
1338                      const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1339                      const struct GNUNET_MessageHeader *message,
1340                      const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1341 {
1342   struct TunnelState *state = *tunnel_ctx;
1343   const struct GNUNET_EXIT_TcpServiceStartMessage *start;
1344   uint16_t pkt_len = ntohs (message->size);
1345
1346   GNUNET_STATISTICS_update (stats,
1347                             gettext_noop ("# TCP service creation requests received via mesh"),
1348                             1, GNUNET_NO);
1349   GNUNET_STATISTICS_update (stats,
1350                             gettext_noop ("# Bytes received from MESH"),
1351                             pkt_len, GNUNET_NO);
1352   /* check that we got at least a valid header */
1353   if (pkt_len < sizeof (struct GNUNET_EXIT_TcpServiceStartMessage))
1354   {
1355     GNUNET_break_op (0);
1356     return GNUNET_SYSERR;
1357   }
1358   start = (const struct GNUNET_EXIT_TcpServiceStartMessage*) message;
1359   pkt_len -= sizeof (struct GNUNET_EXIT_TcpServiceStartMessage);
1360   if ( (NULL == state) ||
1361        (NULL != state->serv) ||
1362        (NULL != state->heap_node) )
1363   {
1364     GNUNET_break_op (0);
1365     return GNUNET_SYSERR;
1366   }
1367   GNUNET_break_op (ntohl (start->reserved) == 0);
1368   /* setup fresh connection */
1369   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1370               "Received data from %s for forwarding to TCP service %s on port %u\n",
1371               GNUNET_i2s (sender),
1372               GNUNET_h2s (&start->service_descriptor),
1373               (unsigned int) ntohs (start->tcp_header.dpt));  
1374   if (NULL == (state->serv = find_service (tcp_services, &start->service_descriptor, 
1375                                            ntohs (start->tcp_header.dpt))))
1376   {
1377     GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
1378                 _("No service found for %s on port %d!\n"),
1379                 "TCP",
1380                 ntohs (start->tcp_header.dpt));
1381     GNUNET_STATISTICS_update (stats,
1382                               gettext_noop ("# TCP requests dropped (no such service)"),
1383                               1, GNUNET_NO);
1384     return GNUNET_SYSERR;
1385   }
1386   state->ri.remote_address = state->serv->address;    
1387   setup_state_record (state);
1388   send_tcp_packet_via_tun (&state->ri.remote_address,
1389                            &state->ri.local_address,
1390                            &start->tcp_header,
1391                            &start[1], pkt_len);
1392   return GNUNET_YES;
1393 }
1394
1395
1396 /**
1397  * Process a request to forward TCP data to the Internet via this peer.
1398  *
1399  * @param cls closure, NULL
1400  * @param tunnel connection to the other end
1401  * @param tunnel_ctx pointer to our 'struct TunnelState *'
1402  * @param sender who sent the message
1403  * @param message the actual message
1404  * @param atsi performance data for the connection
1405  * @return GNUNET_OK to keep the connection open,
1406  *         GNUNET_SYSERR to close it (signal serious error)
1407  */
1408 static int
1409 receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1410                     void **tunnel_ctx GNUNET_UNUSED,
1411                     const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1412                     const struct GNUNET_MessageHeader *message,
1413                     const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1414 {
1415   struct TunnelState *state = *tunnel_ctx;
1416   const struct GNUNET_EXIT_TcpInternetStartMessage *start;
1417   uint16_t pkt_len = ntohs (message->size);
1418   const struct in_addr *v4;
1419   const struct in6_addr *v6;
1420   const void *payload;
1421   int af;
1422
1423   GNUNET_STATISTICS_update (stats,
1424                             gettext_noop ("# Bytes received from MESH"),
1425                             pkt_len, GNUNET_NO);
1426   GNUNET_STATISTICS_update (stats,
1427                             gettext_noop ("# TCP IP-exit creation requests received via mesh"),
1428                             1, GNUNET_NO);
1429   if (pkt_len < sizeof (struct GNUNET_EXIT_TcpInternetStartMessage))
1430   {
1431     GNUNET_break_op (0);
1432     return GNUNET_SYSERR;
1433   }
1434   start = (const struct GNUNET_EXIT_TcpInternetStartMessage*) message;
1435   pkt_len -= sizeof (struct GNUNET_EXIT_TcpInternetStartMessage);  
1436   if ( (NULL == state) ||
1437        (NULL != state->serv) ||
1438        (NULL != state->heap_node) )
1439   {
1440     GNUNET_break_op (0);
1441     return GNUNET_SYSERR;
1442   }
1443   af = (int) ntohl (start->af);
1444   state->ri.remote_address.af = af;
1445   switch (af)
1446   {
1447   case AF_INET:
1448     if (pkt_len < sizeof (struct in_addr))
1449     {
1450       GNUNET_break_op (0);
1451       return GNUNET_SYSERR;
1452     }
1453     if (! ipv4_exit)
1454     {
1455       GNUNET_break_op (0);
1456       return GNUNET_SYSERR;
1457     }
1458     v4 = (const struct in_addr*) &start[1];
1459     payload = &v4[1];
1460     pkt_len -= sizeof (struct in_addr);
1461     state->ri.remote_address.address.ipv4 = *v4;
1462     break;
1463   case AF_INET6:
1464     if (pkt_len < sizeof (struct in6_addr))
1465     {
1466       GNUNET_break_op (0);
1467       return GNUNET_SYSERR;
1468     }
1469     if (! ipv6_exit)
1470     {
1471       GNUNET_break_op (0);
1472       return GNUNET_SYSERR;
1473     }
1474     v6 = (const struct in6_addr*) &start[1];
1475     payload = &v6[1];
1476     pkt_len -= sizeof (struct in_addr);
1477     state->ri.remote_address.address.ipv6 = *v6;
1478     break;
1479   default:
1480     GNUNET_break_op (0);
1481     return GNUNET_SYSERR;
1482   }
1483   {
1484     char buf[INET6_ADDRSTRLEN];
1485     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1486                 "Received data from %s for starting TCP stream to %s:%u\n",
1487                 GNUNET_i2s (sender),
1488                 inet_ntop (af, 
1489                            &state->ri.remote_address.address,
1490                            buf, sizeof (buf)),
1491                 (unsigned int) ntohs (start->tcp_header.dpt));  
1492   }
1493
1494   state->ri.remote_address.proto = IPPROTO_TCP;
1495   state->ri.remote_address.port = ntohs (start->tcp_header.dpt);
1496   setup_state_record (state);
1497   send_tcp_packet_via_tun (&state->ri.remote_address,
1498                            &state->ri.local_address,
1499                            &start->tcp_header,
1500                            payload, pkt_len);
1501   return GNUNET_YES;
1502 }
1503
1504
1505 /**
1506  * Process a request to forward TCP data on an established 
1507  * connection via this peer.
1508  *
1509  * @param cls closure, NULL
1510  * @param tunnel connection to the other end
1511  * @param tunnel_ctx pointer to our 'struct TunnelState *'
1512  * @param sender who sent the message
1513  * @param message the actual message
1514  * @param atsi performance data for the connection
1515  * @return GNUNET_OK to keep the connection open,
1516  *         GNUNET_SYSERR to close it (signal serious error)
1517  */
1518 static int
1519 receive_tcp_data (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1520                   void **tunnel_ctx GNUNET_UNUSED,
1521                   const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1522                   const struct GNUNET_MessageHeader *message,
1523                   const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1524 {
1525   struct TunnelState *state = *tunnel_ctx;
1526   const struct GNUNET_EXIT_TcpDataMessage *data;
1527   uint16_t pkt_len = ntohs (message->size);
1528
1529   GNUNET_STATISTICS_update (stats,
1530                             gettext_noop ("# Bytes received from MESH"),
1531                             pkt_len, GNUNET_NO);
1532   GNUNET_STATISTICS_update (stats,
1533                             gettext_noop ("# TCP data requests received via mesh"),
1534                             1, GNUNET_NO);
1535   if (pkt_len < sizeof (struct GNUNET_EXIT_TcpDataMessage))
1536   {
1537     GNUNET_break_op (0);
1538     return GNUNET_SYSERR;
1539   }
1540   data = (const struct GNUNET_EXIT_TcpDataMessage*) message;
1541   pkt_len -= sizeof (struct GNUNET_EXIT_TcpDataMessage);  
1542   if ( (NULL == state) ||
1543        (NULL == state->heap_node) )
1544   {
1545     /* connection should have been up! */
1546     GNUNET_STATISTICS_update (stats,
1547                               gettext_noop ("# TCP DATA requests dropped (no session)"),
1548                               1, GNUNET_NO);
1549     return GNUNET_SYSERR;
1550   }
1551   GNUNET_break_op (ntohl (data->reserved) == 0);
1552   {
1553     char buf[INET6_ADDRSTRLEN];
1554     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1555                 "Received additional data from %s for TCP stream to %s:%u\n",
1556                 GNUNET_i2s (sender),
1557                 inet_ntop (state->ri.remote_address.af, 
1558                            &state->ri.remote_address.address,
1559                            buf, sizeof (buf)),
1560                 (unsigned int) state->ri.remote_address.port);
1561   }
1562
1563   send_tcp_packet_via_tun (&state->ri.remote_address,
1564                            &state->ri.local_address,
1565                            &data->tcp_header,
1566                            &data[1], pkt_len);
1567   return GNUNET_YES;
1568 }
1569
1570
1571 /**
1572  * Send a UDP packet via the TUN interface.
1573  *
1574  * @param destination_address IP and port to use for the UDP packet's destination
1575  * @param source_address IP and port to use for the UDP packet's source
1576  * @param payload payload of the UDP packet (does NOT include UDP header)
1577  * @param payload_length number of bytes of data in payload
1578  */
1579 static void
1580 send_udp_packet_via_tun (const struct SocketAddress *destination_address,
1581                          const struct SocketAddress *source_address,
1582                          const void *payload, size_t payload_length)
1583 {
1584   size_t len;
1585
1586   GNUNET_STATISTICS_update (stats,
1587                             gettext_noop ("# UDP packets sent via TUN"),
1588                             1, GNUNET_NO);
1589   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1590               "Sending packet with %u bytes UDP payload via TUN\n",
1591               (unsigned int) payload_length);
1592   len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader);
1593   switch (source_address->af)
1594   {
1595   case AF_INET:
1596     len += sizeof (struct GNUNET_TUN_IPv4Header);
1597     break;
1598   case AF_INET6:
1599     len += sizeof (struct GNUNET_TUN_IPv6Header);
1600     break;
1601   default:
1602     GNUNET_break (0);
1603     return;
1604   }
1605   len += sizeof (struct GNUNET_TUN_UdpHeader);
1606   len += payload_length;
1607   if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1608   {
1609     GNUNET_break (0);
1610     return;
1611   }
1612   {
1613     char buf[len];
1614     struct GNUNET_MessageHeader *hdr;
1615     struct GNUNET_TUN_Layer2PacketHeader *tun;
1616     
1617     hdr= (struct GNUNET_MessageHeader *) buf;
1618     hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1619     hdr->size = htons (len);
1620     tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1621     tun->flags = htons (0);
1622     switch (source_address->af)
1623     {
1624     case AF_INET:
1625       {
1626         struct GNUNET_TUN_IPv4Header * ipv4 = (struct GNUNET_TUN_IPv4Header*) &tun[1];
1627         
1628         tun->proto = htons (ETH_P_IPV4);
1629         prepare_ipv4_packet (payload, payload_length,
1630                              IPPROTO_UDP,
1631                              NULL,
1632                              source_address,
1633                              destination_address,
1634                              ipv4);
1635       }
1636       break;
1637     case AF_INET6:
1638       {
1639         struct GNUNET_TUN_IPv6Header * ipv6 = (struct GNUNET_TUN_IPv6Header*) &tun[1];
1640         
1641         tun->proto = htons (ETH_P_IPV6);
1642         prepare_ipv6_packet (payload, payload_length, 
1643                              IPPROTO_UDP,
1644                              NULL,
1645                              source_address,
1646                              destination_address,
1647                              ipv6);
1648       }
1649       break;    
1650     default:
1651       GNUNET_assert (0);
1652       break;
1653     }
1654     (void) GNUNET_HELPER_send (helper_handle,
1655                                (const struct GNUNET_MessageHeader*) buf,
1656                                GNUNET_YES,
1657                                NULL, NULL);
1658   }
1659 }
1660
1661
1662 /**
1663  * Process a request to forward UDP data to the Internet via this peer.
1664  *
1665  * @param cls closure, NULL
1666  * @param tunnel connection to the other end
1667  * @param tunnel_ctx pointer to our 'struct TunnelState *'
1668  * @param sender who sent the message
1669  * @param message the actual message
1670  * @param atsi performance data for the connection
1671  * @return GNUNET_OK to keep the connection open,
1672  *         GNUNET_SYSERR to close it (signal serious error)
1673  */
1674 static int
1675 receive_udp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1676                     void **tunnel_ctx GNUNET_UNUSED,
1677                     const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1678                     const struct GNUNET_MessageHeader *message,
1679                     const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1680 {
1681   struct TunnelState *state = *tunnel_ctx;
1682   const struct GNUNET_EXIT_UdpInternetMessage *msg;
1683   uint16_t pkt_len = ntohs (message->size);
1684   const struct in_addr *v4;
1685   const struct in6_addr *v6;
1686   const void *payload;
1687   int af;
1688
1689   GNUNET_STATISTICS_update (stats,
1690                             gettext_noop ("# Bytes received from MESH"),
1691                             pkt_len, GNUNET_NO);
1692   GNUNET_STATISTICS_update (stats,
1693                             gettext_noop ("# UDP IP-exit requests received via mesh"),
1694                             1, GNUNET_NO);
1695   if (pkt_len < sizeof (struct GNUNET_EXIT_UdpInternetMessage))
1696   {
1697     GNUNET_break_op (0);
1698     return GNUNET_SYSERR;
1699   }
1700   msg = (const struct GNUNET_EXIT_UdpInternetMessage*) message;
1701   pkt_len -= sizeof (struct GNUNET_EXIT_UdpInternetMessage);  
1702   af = (int) ntohl (msg->af);
1703   state->ri.remote_address.af = af;
1704   switch (af)
1705   {
1706   case AF_INET:
1707     if (pkt_len < sizeof (struct in_addr))
1708     {
1709       GNUNET_break_op (0);
1710       return GNUNET_SYSERR;
1711     }
1712     if (! ipv4_exit)
1713     {
1714       GNUNET_break_op (0);
1715       return GNUNET_SYSERR;
1716     }
1717     v4 = (const struct in_addr*) &msg[1];
1718     payload = &v4[1];
1719     pkt_len -= sizeof (struct in_addr);
1720     state->ri.remote_address.address.ipv4 = *v4;
1721     break;
1722   case AF_INET6:
1723     if (pkt_len < sizeof (struct in6_addr))
1724     {
1725       GNUNET_break_op (0);
1726       return GNUNET_SYSERR;
1727     }
1728     if (! ipv6_exit)
1729     {
1730       GNUNET_break_op (0);
1731       return GNUNET_SYSERR;
1732     }
1733     v6 = (const struct in6_addr*) &msg[1];
1734     payload = &v6[1];
1735     pkt_len -= sizeof (struct in_addr);
1736     state->ri.remote_address.address.ipv6 = *v6;
1737     break;
1738   default:
1739     GNUNET_break_op (0);
1740     return GNUNET_SYSERR;
1741   }
1742   {
1743     char buf[INET6_ADDRSTRLEN];
1744     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1745                 "Received data from %s for forwarding to UDP %s:%u\n",
1746                 GNUNET_i2s (sender),
1747                 inet_ntop (af, 
1748                            &state->ri.remote_address.address,
1749                            buf, sizeof (buf)),
1750                 (unsigned int) ntohs (msg->destination_port));  
1751   }
1752   state->ri.remote_address.proto = IPPROTO_UDP;
1753   state->ri.remote_address.port = msg->destination_port;
1754   if (NULL == state->heap_node)
1755     setup_state_record (state);
1756   if (0 != ntohs (msg->source_port))
1757     state->ri.local_address.port = msg->source_port;
1758   send_udp_packet_via_tun (&state->ri.remote_address,
1759                            &state->ri.local_address,
1760                            payload, pkt_len);
1761   return GNUNET_YES;
1762 }
1763
1764
1765 /**
1766  * Process a request via mesh to send a request to a UDP service
1767  * offered by this system.
1768  *
1769  * @param cls closure, NULL
1770  * @param tunnel connection to the other end
1771  * @param tunnel_ctx pointer to our 'struct TunnelState *'
1772  * @param sender who sent the message
1773  * @param message the actual message
1774  * @param atsi performance data for the connection
1775  * @return GNUNET_OK to keep the connection open,
1776  *         GNUNET_SYSERR to close it (signal serious error)
1777  */
1778 static int
1779 receive_udp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1780                      void **tunnel_ctx,
1781                      const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1782                      const struct GNUNET_MessageHeader *message,
1783                      const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1784 {
1785   struct TunnelState *state = *tunnel_ctx;
1786   const struct GNUNET_EXIT_UdpServiceMessage *msg;
1787   uint16_t pkt_len = ntohs (message->size);
1788
1789   GNUNET_STATISTICS_update (stats,
1790                             gettext_noop ("# Bytes received from MESH"),
1791                             pkt_len, GNUNET_NO);
1792   GNUNET_STATISTICS_update (stats,
1793                             gettext_noop ("# UDP service requests received via mesh"),
1794                             1, GNUNET_NO);
1795   /* check that we got at least a valid header */
1796   if (pkt_len < sizeof (struct GNUNET_EXIT_UdpServiceMessage))
1797   {
1798     GNUNET_break_op (0);
1799     return GNUNET_SYSERR;
1800   }
1801   msg = (const struct GNUNET_EXIT_UdpServiceMessage*) message;
1802   pkt_len -= sizeof (struct GNUNET_EXIT_UdpServiceMessage);
1803   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1804               "Received data from %s for forwarding to UDP service %s on port %u\n",
1805               GNUNET_i2s (sender),
1806               GNUNET_h2s (&msg->service_descriptor),
1807               (unsigned int) ntohs (msg->destination_port));  
1808   if (NULL == (state->serv = find_service (udp_services, &msg->service_descriptor, 
1809                                            ntohs (msg->destination_port))))
1810   {
1811     GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
1812                 _("No service found for %s on port %d!\n"),
1813                 "UDP",
1814                 ntohs (msg->destination_port));
1815     GNUNET_STATISTICS_update (stats,
1816                               gettext_noop ("# UDP requests dropped (no such service)"),
1817                               1, GNUNET_NO);
1818     return GNUNET_SYSERR;
1819   }
1820   state->ri.remote_address = state->serv->address;    
1821   setup_state_record (state);
1822   if (0 != ntohs (msg->source_port))
1823     state->ri.local_address.port = msg->source_port;
1824   send_udp_packet_via_tun (&state->ri.remote_address,
1825                            &state->ri.local_address,
1826                            &msg[1], pkt_len);
1827   return GNUNET_YES;
1828 }
1829
1830
1831 /**
1832  * Callback from GNUNET_MESH for new tunnels.
1833  *
1834  * @param cls closure
1835  * @param tunnel new handle to the tunnel
1836  * @param initiator peer that started the tunnel
1837  * @param atsi performance information for the tunnel
1838  * @return initial tunnel context for the tunnel
1839  */
1840 static void *
1841 new_tunnel (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1842             const struct GNUNET_PeerIdentity *initiator GNUNET_UNUSED,
1843             const struct GNUNET_ATS_Information *ats GNUNET_UNUSED)
1844 {
1845   struct TunnelState *s = GNUNET_malloc (sizeof (struct TunnelState));
1846
1847   GNUNET_STATISTICS_update (stats,
1848                             gettext_noop ("# Inbound MESH tunnels created"),
1849                             1, GNUNET_NO);
1850   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1851               "Received inbound tunnel from `%s'\n",
1852               GNUNET_i2s (initiator));
1853   s->tunnel = tunnel;
1854   return s;
1855 }
1856
1857
1858 /**
1859  * Function called by mesh whenever an inbound tunnel is destroyed.
1860  * Should clean up any associated state.
1861  *
1862  * @param cls closure (set from GNUNET_MESH_connect)
1863  * @param tunnel connection to the other end (henceforth invalid)
1864  * @param tunnel_ctx place where local state associated
1865  *                   with the tunnel is stored
1866  */
1867 static void
1868 clean_tunnel (void *cls GNUNET_UNUSED, const struct GNUNET_MESH_Tunnel *tunnel,
1869               void *tunnel_ctx)
1870 {
1871   struct TunnelState *s = tunnel_ctx;
1872   struct TunnelMessageQueue *tnq;
1873
1874   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1875               "Tunnel destroyed\n");
1876   while (NULL != (tnq = s->head))
1877   {
1878     GNUNET_CONTAINER_DLL_remove (s->head,
1879                                  s->tail,
1880                                  tnq);
1881     GNUNET_free (tnq);
1882   }
1883   if (s->heap_node != NULL)
1884   {
1885     GNUNET_assert (GNUNET_YES ==
1886                    GNUNET_CONTAINER_multihashmap_remove (connections_map,
1887                                                          &s->state_key,
1888                                                          s));
1889     GNUNET_CONTAINER_heap_remove_node (s->heap_node);
1890     s->heap_node = NULL;
1891   }
1892   if (NULL != s->th)
1893   {
1894     GNUNET_MESH_notify_transmit_ready_cancel (s->th);
1895     s->th = NULL;
1896   }
1897   GNUNET_free (s);
1898 }
1899
1900
1901 /**
1902  * Function that frees everything from a hashmap
1903  *
1904  * @param cls unused
1905  * @param hash key
1906  * @param value value to free
1907  */
1908 static int
1909 free_iterate (void *cls GNUNET_UNUSED,
1910               const GNUNET_HashCode * hash GNUNET_UNUSED, void *value)
1911 {
1912   GNUNET_free (value);
1913   return GNUNET_YES;
1914 }
1915
1916
1917 /**
1918  * Function scheduled as very last function, cleans up after us
1919  */
1920 static void
1921 cleanup (void *cls GNUNET_UNUSED,
1922          const struct GNUNET_SCHEDULER_TaskContext *tskctx)
1923 {
1924   unsigned int i;
1925
1926   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1927               "Exit service is shutting down now\n");
1928   if (helper_handle != NULL)
1929   {
1930     GNUNET_HELPER_stop (helper_handle);
1931     helper_handle = NULL;
1932   }
1933   if (mesh_handle != NULL)
1934   {
1935     GNUNET_MESH_disconnect (mesh_handle);
1936     mesh_handle = NULL;
1937   }
1938   if (NULL != connections_map)
1939   {
1940     GNUNET_CONTAINER_multihashmap_iterate (connections_map, &free_iterate, NULL);
1941     GNUNET_CONTAINER_multihashmap_destroy (connections_map);
1942     connections_map = NULL;
1943   }
1944   if (NULL != connections_heap)
1945   {
1946     GNUNET_CONTAINER_heap_destroy (connections_heap);
1947     connections_heap = NULL;
1948   }
1949   if (NULL != tcp_services)
1950   {
1951     GNUNET_CONTAINER_multihashmap_iterate (tcp_services, &free_service_record, NULL);
1952     GNUNET_CONTAINER_multihashmap_destroy (tcp_services);
1953     tcp_services = NULL;
1954   }
1955   if (NULL != udp_services)
1956   {
1957     GNUNET_CONTAINER_multihashmap_iterate (udp_services, &free_service_record, NULL);
1958     GNUNET_CONTAINER_multihashmap_destroy (udp_services);
1959     udp_services = NULL;
1960   }
1961   if (stats != NULL)
1962   {
1963     GNUNET_STATISTICS_destroy (stats, GNUNET_YES);
1964     stats = NULL;
1965   }
1966   for (i=0;i<5;i++)
1967     GNUNET_free_non_null (exit_argv[i]);
1968 }
1969
1970
1971 /**
1972  * Add services to the service map.
1973  *
1974  * @param proto IPPROTO_TCP or IPPROTO_UDP
1975  * @param cpy copy of the service descriptor (can be mutilated)
1976  * @param name DNS name of the service
1977  */
1978 static void
1979 add_services (int proto,
1980               char *cpy,
1981               const char *name)
1982 {
1983   char *redirect;
1984   char *hostname;
1985   char *hostport;
1986   struct LocalService *serv;
1987
1988   for (redirect = strtok (cpy, " "); redirect != NULL;
1989        redirect = strtok (NULL, " "))
1990   {
1991     if (NULL == (hostname = strstr (redirect, ":")))
1992     {
1993       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1994                   "option `%s' for domain `%s' is not formatted correctly!\n",
1995                   redirect,
1996                   name);
1997       continue;
1998     }
1999     hostname[0] = '\0';
2000     hostname++;
2001     if (NULL == (hostport = strstr (hostname, ":")))
2002     {
2003       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2004                   "option `%s' for domain `%s' is not formatted correctly!\n",
2005                   redirect,
2006                   name);
2007       continue;
2008     }
2009     hostport[0] = '\0';
2010     hostport++;
2011     
2012     int local_port = atoi (redirect);
2013     int remote_port = atoi (hostport);
2014     
2015     if (!((local_port > 0) && (local_port < 65536)))
2016     {
2017       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2018                   "`%s' is not a valid port number (for domain `%s')!", redirect,
2019                   name);
2020       continue;
2021     }
2022     if (!((remote_port > 0) && (remote_port < 65536)))
2023     {
2024       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2025                   "`%s' is not a valid port number (for domain `%s')!", hostport,
2026                   name);
2027       continue;
2028     }
2029
2030     serv = GNUNET_malloc (sizeof (struct LocalService));
2031     serv->my_port = (uint16_t) local_port;
2032     serv->address.port = remote_port;
2033     if (0 == strcmp ("localhost4", hostname))
2034     {
2035       const char *ip4addr = exit_argv[4];
2036
2037       serv->address.af = AF_INET;      
2038       GNUNET_assert (1 != inet_pton (AF_INET, ip4addr, &serv->address.address.ipv4));
2039     }
2040     else if (0 == strcmp ("localhost6", hostname))
2041     {
2042       const char *ip6addr = exit_argv[2];
2043
2044       serv->address.af = AF_INET6;
2045       GNUNET_assert (1 == inet_pton (AF_INET6, ip6addr, &serv->address.address.ipv6));
2046     }
2047     else
2048     {
2049       struct addrinfo *res;      
2050       int ret;
2051
2052       ret = getaddrinfo (hostname, NULL, NULL, &res);      
2053       if ( (ret != 0) || (res == NULL) )
2054       {
2055         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2056                     _("No addresses found for hostname `%s' of service `%s'!\n"),
2057                     hostname,
2058                     name);
2059         GNUNET_free (serv);
2060         continue;
2061       }
2062       
2063       serv->address.af = res->ai_family;
2064       switch (res->ai_family)
2065       {
2066       case AF_INET:
2067         if (! ipv4_enabled)
2068         {
2069           GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2070                       _("Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
2071                       name);
2072           freeaddrinfo (res);
2073           GNUNET_free (serv);
2074           continue;
2075         }
2076         serv->address.address.ipv4 = ((struct sockaddr_in *) res->ai_addr)->sin_addr;
2077         break;
2078       case AF_INET6:
2079         if (! ipv6_enabled)
2080         {
2081           GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2082                       _("Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
2083                       name);
2084           freeaddrinfo (res);
2085           GNUNET_free (serv);
2086           continue;
2087         }       
2088         serv->address.address.ipv6 = ((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
2089         break;
2090       default:
2091         freeaddrinfo (res);
2092         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2093                     _("No IP addresses found for hostname `%s' of service `%s'!\n"),
2094                     hostname,
2095                     name);
2096         GNUNET_free (serv);
2097         continue;
2098       }
2099       freeaddrinfo (res);
2100     }
2101     store_service ((IPPROTO_UDP == proto) ? udp_services : tcp_services,
2102                    name,
2103                    local_port,
2104                    serv);
2105   }
2106 }
2107
2108
2109 /**
2110  * Reads the configuration servicecfg and populates udp_services
2111  *
2112  * @param cls unused
2113  * @param section name of section in config, equal to hostname
2114  */
2115 static void
2116 read_service_conf (void *cls GNUNET_UNUSED, const char *section)
2117 {
2118   char *cpy;
2119
2120   if ((strlen (section) < 8) ||
2121       (0 != strcmp (".gnunet.", section + (strlen (section) - 8))))
2122     return;
2123   if (GNUNET_OK ==
2124       GNUNET_CONFIGURATION_get_value_string (cfg, section, "UDP_REDIRECTS",
2125                                              &cpy))
2126   {
2127     add_services (IPPROTO_UDP, cpy, section);
2128     GNUNET_free (cpy);
2129   }
2130   if (GNUNET_OK ==
2131       GNUNET_CONFIGURATION_get_value_string (cfg, section, "TCP_REDIRECTS",
2132                                              &cpy))
2133   {
2134     add_services (IPPROTO_TCP, cpy, section);
2135     GNUNET_free (cpy);
2136   }
2137 }
2138
2139
2140 /**
2141  * @brief Main function that will be run by the scheduler.
2142  *
2143  * @param cls closure
2144  * @param args remaining command-line arguments
2145  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
2146  * @param cfg_ configuration
2147  */
2148 static void
2149 run (void *cls, char *const *args GNUNET_UNUSED,
2150      const char *cfgfile GNUNET_UNUSED,
2151      const struct GNUNET_CONFIGURATION_Handle *cfg_)
2152 {
2153   static struct GNUNET_MESH_MessageHandler handlers[] = {
2154     {&receive_udp_service, GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE, 0},
2155     {&receive_udp_remote, GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET, 0},
2156     {&receive_tcp_service, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START, 0},
2157     {&receive_tcp_remote, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START, 0},
2158     {&receive_tcp_data, GNUNET_MESSAGE_TYPE_VPN_TCP_DATA, 0},
2159     {NULL, 0, 0}
2160   };
2161
2162   static GNUNET_MESH_ApplicationType apptypes[] = {
2163     GNUNET_APPLICATION_TYPE_END,
2164     GNUNET_APPLICATION_TYPE_END,
2165     GNUNET_APPLICATION_TYPE_END
2166   };
2167   unsigned int app_idx;
2168   char *exit_ifname;
2169   char *tun_ifname;
2170   char *ipv6addr;
2171   char *ipv6prefix_s;
2172   char *ipv4addr;
2173   char *ipv4mask;
2174   struct in_addr v4;
2175   struct in6_addr v6;
2176
2177   cfg = cfg_;
2178   stats = GNUNET_STATISTICS_create ("exit", cfg);
2179   ipv4_exit = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "EXIT_IPV4");
2180   ipv6_exit = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "EXIT_IPV6"); 
2181   ipv4_enabled = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_IPV4");
2182   ipv6_enabled = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_IPV6"); 
2183   if (ipv4_exit && (! ipv4_enabled))
2184   {
2185     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2186                 _("Cannot enable IPv4 exit but disable IPv4 on TUN interface, will use ENABLE_IPv4=YES\n"));
2187     ipv4_enabled = GNUNET_YES;
2188   }
2189   if (ipv6_exit && (! ipv6_enabled))
2190   {
2191     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2192                 _("Cannot enable IPv6 exit but disable IPv6 on TUN interface, will use ENABLE_IPv6=YES\n"));
2193     ipv6_enabled = GNUNET_YES;
2194   }
2195   if (! (ipv4_enabled || ipv6_enabled))
2196   {
2197     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2198                 _("No useful service enabled.  Exiting.\n"));
2199     GNUNET_SCHEDULER_shutdown ();
2200     return;    
2201   }
2202   app_idx = 0;
2203   if (GNUNET_YES == ipv4_exit)    
2204   {
2205     apptypes[app_idx] = GNUNET_APPLICATION_TYPE_IPV4_GATEWAY;
2206     app_idx++;
2207   }
2208   if (GNUNET_YES == ipv6_exit)    
2209   {
2210     apptypes[app_idx] = GNUNET_APPLICATION_TYPE_IPV6_GATEWAY;
2211     app_idx++;
2212   }
2213
2214   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls);
2215
2216   if (GNUNET_OK !=
2217       GNUNET_CONFIGURATION_get_value_number (cfg, "exit", "MAX_CONNECTIONS",
2218                                              &max_connections))
2219     max_connections = 1024;
2220   exit_argv[0] = GNUNET_strdup ("exit-gnunet");
2221   if (GNUNET_SYSERR ==
2222       GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "TUN_IFNAME", &tun_ifname))
2223   {
2224     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2225                 "No entry 'TUN_IFNAME' in configuration!\n");
2226     GNUNET_SCHEDULER_shutdown ();
2227     return;
2228   }
2229   exit_argv[1] = tun_ifname;
2230   if (ipv4_enabled)
2231   {
2232     if (GNUNET_SYSERR ==
2233         GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "EXIT_IFNAME", &exit_ifname))
2234     {
2235       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2236                   "No entry 'EXIT_IFNAME' in configuration!\n");
2237       GNUNET_SCHEDULER_shutdown ();
2238       return;
2239     }
2240     exit_argv[2] = exit_ifname;
2241   }
2242   else
2243   {
2244     exit_argv[2] = GNUNET_strdup ("%");
2245   }
2246   if (GNUNET_YES == ipv6_enabled)
2247   {
2248     if ( (GNUNET_SYSERR ==
2249           GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6ADDR",
2250                                                  &ipv6addr) ||
2251           (1 != inet_pton (AF_INET6, ipv6addr, &v6))) )
2252     {
2253       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2254                   "No valid entry 'IPV6ADDR' in configuration!\n");
2255       GNUNET_SCHEDULER_shutdown ();
2256       return;
2257     }
2258     exit_argv[3] = ipv6addr;
2259     if (GNUNET_SYSERR ==
2260         GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6PREFIX",
2261                                                &ipv6prefix_s))
2262     {
2263       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2264                   "No entry 'IPV6PREFIX' in configuration!\n");
2265       GNUNET_SCHEDULER_shutdown ();
2266       return;
2267     }
2268     exit_argv[4] = ipv6prefix_s;
2269     if ( (GNUNET_OK !=
2270           GNUNET_CONFIGURATION_get_value_number (cfg, "exit",
2271                                                  "IPV6PREFIX",
2272                                                  &ipv6prefix)) ||
2273          (ipv6prefix >= 127) )
2274     {
2275       GNUNET_SCHEDULER_shutdown ();
2276       return;
2277     }
2278   } 
2279   else
2280   {
2281     /* IPv6 explicitly disabled */
2282     exit_argv[3] = GNUNET_strdup ("-");
2283     exit_argv[4] = GNUNET_strdup ("-");
2284   }
2285   if (GNUNET_YES == ipv4_enabled)
2286   {
2287     if ( (GNUNET_SYSERR ==
2288           GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4ADDR",
2289                                                  &ipv4addr) ||
2290           (1 != inet_pton (AF_INET, ipv4addr, &v4))) )
2291       {
2292         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2293                     "No valid entry for 'IPV4ADDR' in configuration!\n");
2294         GNUNET_SCHEDULER_shutdown ();
2295         return;
2296       }
2297     exit_argv[5] = ipv4addr;
2298     if ( (GNUNET_SYSERR ==
2299           GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4MASK",
2300                                                  &ipv4mask) ||
2301           (1 != inet_pton (AF_INET, ipv4mask, &v4))) )
2302     {
2303       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2304                   "No valid entry 'IPV4MASK' in configuration!\n");
2305       GNUNET_SCHEDULER_shutdown ();
2306       return;
2307     }
2308     exit_argv[6] = ipv4mask;
2309   }
2310   else
2311   {
2312     /* IPv4 explicitly disabled */
2313     exit_argv[5] = GNUNET_strdup ("-");
2314     exit_argv[6] = GNUNET_strdup ("-");
2315   }
2316   exit_argv[7] = NULL;
2317
2318   udp_services = GNUNET_CONTAINER_multihashmap_create (65536);
2319   tcp_services = GNUNET_CONTAINER_multihashmap_create (65536);
2320   GNUNET_CONFIGURATION_iterate_sections (cfg, &read_service_conf, NULL);
2321
2322   connections_map = GNUNET_CONTAINER_multihashmap_create (65536);
2323   connections_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
2324   mesh_handle 
2325     = GNUNET_MESH_connect (cfg, 42 /* queue size */, NULL, 
2326                            &new_tunnel, 
2327                            &clean_tunnel, handlers,
2328                            apptypes);
2329   if (NULL == mesh_handle)
2330   {
2331     GNUNET_SCHEDULER_shutdown ();
2332     return;
2333   }
2334   helper_handle = GNUNET_HELPER_start ("gnunet-helper-exit", 
2335                                        exit_argv,
2336                                        &message_token, NULL);
2337 }
2338
2339
2340 /**
2341  * The main function
2342  *
2343  * @param argc number of arguments from the command line
2344  * @param argv command line arguments
2345  * @return 0 ok, 1 on error
2346  */
2347 int
2348 main (int argc, char *const *argv)
2349 {
2350   static const struct GNUNET_GETOPT_CommandLineOption options[] = {
2351     GNUNET_GETOPT_OPTION_END
2352   };
2353
2354   return (GNUNET_OK ==
2355           GNUNET_PROGRAM_run (argc, argv, "gnunet-daemon-exit",
2356                               gettext_noop
2357                               ("Daemon to run to provide an IP exit node for the VPN"),
2358                               options, &run, NULL)) ? 0 : 1;
2359 }
2360
2361
2362 /* end of gnunet-daemon-exit.c */