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