9ab2738e64ff3ab0e7d90431b0dfe7922a4109a9
[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 payload message to transmit
548  * @param payload_length number of bytes in payload
549  * @param desc descriptor to add before payload (optional)
550  * @param mtype message type to use
551  */
552 static void
553 send_packet_to_mesh_tunnel (struct GNUNET_MESH_Tunnel *mesh_tunnel,
554                             const void *payload,
555                             size_t payload_length,
556                             const GNUNET_HashCode *desc,
557                             uint16_t mtype)
558 {
559   struct TunnelState *s;
560   struct TunnelMessageQueue *tnq;
561   struct GNUNET_MessageHeader *msg;
562   size_t len;
563   GNUNET_HashCode *dp;
564
565   len = sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + payload_length;
566   if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
567   {
568     GNUNET_break (0);
569     return;
570   }
571   tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueue) + len);
572   tnq->payload = &tnq[1];
573   tnq->len = len;
574   msg = (struct GNUNET_MessageHeader *) &tnq[1];
575   msg->size = htons ((uint16_t) len);
576   msg->type = htons (mtype);
577   if (NULL != desc)
578   {
579     dp = (GNUNET_HashCode *) &msg[1];
580     *dp = *desc;  
581     memcpy (&dp[1], payload, payload_length);
582   }
583   else
584   {
585     memcpy (&msg[1], payload, payload_length);
586   }
587   s = GNUNET_MESH_tunnel_get_data (mesh_tunnel);
588   GNUNET_assert (NULL != s);
589   GNUNET_CONTAINER_DLL_insert_tail (s->head, s->tail, tnq);
590   if (NULL == s->th)
591     s->th = GNUNET_MESH_notify_transmit_ready (mesh_tunnel, GNUNET_NO /* cork */, 0 /* priority */,
592                                                GNUNET_TIME_UNIT_FOREVER_REL,
593                                                NULL, len,
594                                                &send_to_peer_notify_callback,
595                                                s);
596 }
597
598
599 /**
600  * @brief Handles an UDP packet received from the helper.
601  *
602  * @param udp A pointer to the Packet
603  * @param pktlen number of bytes in 'udp'
604  * @param af address family (AFINET or AF_INET6)
605  * @param destination_ip destination IP-address of the IP packet (should 
606  *                       be our local address)
607  * @param source_ip original source IP-address of the IP packet (should
608  *                       be the original destination address)
609  */
610 static void
611 udp_from_helper (const struct GNUNET_TUN_UdpHeader *udp, 
612                  size_t pktlen,
613                  int af,
614                  const void *destination_ip, 
615                  const void *source_ip)
616 {
617   struct TunnelState *state;
618
619   {
620     char sbuf[INET6_ADDRSTRLEN];
621     char dbuf[INET6_ADDRSTRLEN];
622     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
623                 "Received UDP packet going from %s:%u to %s:%u\n",
624                 inet_ntop (af,
625                            source_ip,
626                            sbuf, sizeof (sbuf)),
627                 (unsigned int) ntohs (udp->spt),
628                 inet_ntop (af,
629                            source_ip,
630                            dbuf, sizeof (dbuf)),
631                 (unsigned int) ntohs (udp->dpt));
632   }
633   if (pktlen < sizeof (struct GNUNET_TUN_UdpHeader))
634   {
635     /* blame kernel */
636     GNUNET_break (0);
637     return;
638   }
639   if (pktlen != ntohs (udp->len))
640   {
641     /* blame kernel */
642     GNUNET_break (0);
643     return;
644   }
645   state = get_redirect_state (af, IPPROTO_UDP,
646                               source_ip,
647                               ntohs (udp->spt),
648                               destination_ip,
649                               ntohs (udp->dpt),
650                               NULL);
651   if (NULL == state)
652   {
653     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
654                 _("Packet dropped, have no matching connection information\n"));
655     return;
656   }
657   send_packet_to_mesh_tunnel (state->tunnel,
658                               &udp[1], pktlen - sizeof (struct GNUNET_TUN_UdpHeader),
659                               NULL,
660                               GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY);
661 }
662
663
664 /**
665  * @brief Handles a TCP packet received from the helper.
666  *
667  * @param tcp A pointer to the Packet
668  * @param pktlen the length of the packet, including its header
669  * @param af address family (AFINET or AF_INET6)
670  * @param destination_ip destination IP-address of the IP packet (should 
671  *                       be our local address)
672  * @param source_ip original source IP-address of the IP packet (should
673  *                       be the original destination address)
674  */
675 static void
676 tcp_from_helper (const struct GNUNET_TUN_TcpHeader *tcp, 
677                  size_t pktlen,
678                  int af,
679                  const void *destination_ip,
680                  const void *source_ip)
681 {
682   struct TunnelState *state;
683   char buf[pktlen];
684   struct GNUNET_TUN_TcpHeader *mtcp;
685
686   {
687     char sbuf[INET6_ADDRSTRLEN];
688     char dbuf[INET6_ADDRSTRLEN];
689     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
690                 "Received TCP packet going from %s:%u to %s:%u\n",
691                 inet_ntop (af,
692                            source_ip,
693                            sbuf, sizeof (sbuf)),
694                 (unsigned int) ntohs (tcp->spt),
695                 inet_ntop (af,
696                            source_ip,
697                            dbuf, sizeof (dbuf)),
698                 (unsigned int) ntohs (tcp->dpt));
699   }
700   if (pktlen < sizeof (struct GNUNET_TUN_TcpHeader))
701   {
702     /* blame kernel */
703     GNUNET_break (0);
704     return;
705   }
706   state = get_redirect_state (af, IPPROTO_TCP,
707                               source_ip, 
708                               ntohs (tcp->spt),
709                               destination_ip,
710                               ntohs (tcp->dpt),
711                               NULL);
712   if (NULL == state)
713   {
714     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
715                 _("Packet dropped, have no matching connection information\n"));
716     
717     return;
718   }
719   /* mug port numbers and crc to avoid information leakage;
720      sender will need to lookup the correct values anyway */
721   memcpy (buf, tcp, pktlen);  
722   mtcp = (struct GNUNET_TUN_TcpHeader *) buf;
723   mtcp->spt = 0;
724   mtcp->dpt = 0;
725   mtcp->crc = 0;
726   send_packet_to_mesh_tunnel (state->tunnel,
727                               mtcp, pktlen,
728                               NULL,
729                               GNUNET_MESSAGE_TYPE_VPN_TCP_DATA);
730 }
731
732
733 /**
734  * Receive packets from the helper-process
735  *
736  * @param cls unused
737  * @param client unsued
738  * @param message message received from helper
739  */
740 static void
741 message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED,
742                const struct GNUNET_MessageHeader *message)
743 {
744   const struct GNUNET_TUN_Layer2PacketHeader *pkt_tun;
745   size_t size;
746
747   GNUNET_STATISTICS_update (stats,
748                             gettext_noop ("# Packets received from TUN"),
749                             1, GNUNET_NO);
750   if (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER)
751   {
752     GNUNET_break (0);
753     return;
754   }
755   size = ntohs (message->size);
756   if (size < sizeof (struct GNUNET_TUN_Layer2PacketHeader) + sizeof (struct GNUNET_MessageHeader))
757   {
758     GNUNET_break (0);
759     return;
760   }
761   GNUNET_STATISTICS_update (stats,
762                             gettext_noop ("# Bytes received from TUN"),
763                             size, GNUNET_NO);
764   pkt_tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1];
765   size -= sizeof (struct GNUNET_TUN_Layer2PacketHeader) + sizeof (struct GNUNET_MessageHeader);
766   switch (ntohs (pkt_tun->proto))
767   {
768   case ETH_P_IPV6:
769     {
770       const struct GNUNET_TUN_IPv6Header *pkt6;
771
772       if (size < sizeof (struct GNUNET_TUN_IPv6Header))
773       {
774         /* Kernel to blame? */
775         GNUNET_break (0);
776         return;
777       }
778       pkt6 = (struct GNUNET_TUN_IPv6Header *) &pkt_tun[1];
779       if (size != ntohs (pkt6->payload_length))
780       {
781         /* Kernel to blame? */
782         GNUNET_break (0);
783         return;
784       }
785       size -= sizeof (struct GNUNET_TUN_IPv6Header);
786       switch (pkt6->next_header)
787       {
788       case IPPROTO_UDP:
789         udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt6[1], size,
790                          AF_INET6,
791                          &pkt6->destination_address, 
792                          &pkt6->source_address);
793         break;
794       case IPPROTO_TCP:
795         tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt6[1], size,
796                          AF_INET6,
797                          &pkt6->destination_address, 
798                          &pkt6->source_address);
799         break;
800       default:
801         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
802                     _("IPv6 packet with unsupported next header received.  Ignored.\n"));
803         return;
804       }
805     }
806     break;
807   case ETH_P_IPV4:
808     {
809       const struct GNUNET_TUN_IPv4Header *pkt4;
810
811       if (size < sizeof (struct GNUNET_TUN_IPv4Header))
812       {
813         /* Kernel to blame? */
814         GNUNET_break (0);
815         return;
816       }
817       pkt4 = (const struct GNUNET_TUN_IPv4Header *) &pkt_tun[1];
818       if (size != ntohs (pkt4->total_length))
819       {
820         /* Kernel to blame? */
821         GNUNET_break (0);
822         return;
823       }
824       if (pkt4->header_length * 4 != sizeof (struct GNUNET_TUN_IPv4Header))
825       {
826         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
827                     _("IPv4 packet options received.  Ignored.\n"));
828         return;
829       }
830       size -= sizeof (struct GNUNET_TUN_IPv4Header);
831       switch (pkt4->protocol)
832       {
833       case IPPROTO_UDP:
834         udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt4[1], size,
835                          AF_INET,
836                          &pkt4->destination_address, 
837                          &pkt4->source_address);
838       case IPPROTO_TCP:
839         tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt4[1], size,
840                          AF_INET,
841                          &pkt4->destination_address, 
842                          &pkt4->source_address);
843         break;
844       default:
845         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
846                     _("IPv4 packet with unsupported next header received.  Ignored.\n"));
847         return;
848       }
849     }
850     break;
851   default:
852     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
853                 _("Packet from unknown protocol %u received.  Ignored.\n"),
854                 ntohs (pkt_tun->proto));
855     break;
856   }
857 }
858
859
860 /**
861  * We need to create a (unique) fresh local address (IP+port).
862  * Fill one in.
863  *
864  * @param af desired address family
865  * @param proto desired protocol (IPPROTO_UDP or IPPROTO_TCP)
866  * @param local_address address to initialize
867  */
868 static void
869 setup_fresh_address (int af,
870                      uint8_t proto,
871                      struct SocketAddress *local_address)
872 {
873   local_address->af = af;
874   local_address->proto = (uint8_t) proto;
875   /* default "local" port range is often 32768--61000,
876      so we pick a random value in that range */  
877   local_address->port 
878     = (uint16_t) 32768 + GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 
879                                                    28232);      
880   switch (af)
881   {
882   case AF_INET:
883     {
884       struct in_addr addr;
885       struct in_addr mask;
886       struct in_addr rnd;
887
888       addr = exit_ipv4addr;
889       mask = exit_ipv4mask;
890       if (0 == ~mask.s_addr)
891       {
892         /* only one valid IP anyway */
893         local_address->address.ipv4 = addr;
894         return;
895       }
896       /* Given 192.168.0.1/255.255.0.0, we want a mask 
897          of '192.168.255.255', thus:  */
898       mask.s_addr = addr.s_addr | ~mask.s_addr;
899       /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
900       do
901         {
902           rnd.s_addr = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 
903                                                  UINT32_MAX);   
904           local_address->address.ipv4.s_addr = (addr.s_addr | rnd.s_addr) & mask.s_addr;
905         }
906       while ( (local_address->address.ipv4.s_addr == addr.s_addr) ||
907               (local_address->address.ipv4.s_addr == mask.s_addr) );
908     }
909     break;
910   case AF_INET6:
911     {
912       struct in6_addr addr;
913       struct in6_addr mask;
914       struct in6_addr rnd;
915       int i;
916       
917       addr = exit_ipv6addr;
918       GNUNET_assert (ipv6prefix < 128);
919       if (ipv6prefix == 127)
920       {
921         /* only one valid IP anyway */
922         local_address->address.ipv6 = addr;
923         return;
924       }
925       /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
926          thus: */
927       mask = addr;
928       for (i=127;i>=128-ipv6prefix;i--)
929         mask.s6_addr[i / 8] |= (1 << (i % 8));
930       
931       /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */
932       do
933         {
934           for (i=0;i<16;i++)
935           {
936             rnd.s6_addr[i] = (unsigned char) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 
937                                                                        256);
938             local_address->address.ipv6.s6_addr[i]
939               = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
940           }
941         }
942       while ( (0 == memcmp (&local_address->address.ipv6,
943                             &addr,
944                             sizeof (struct in6_addr))) ||
945               (0 == memcmp (&local_address->address.ipv6,
946                             &mask,
947                             sizeof (struct in6_addr))) );
948     }
949     break;
950   default:
951     GNUNET_assert (0);
952   }  
953 }
954
955
956 /**
957  * We are starting a fresh connection (TCP or UDP) and need
958  * to pick a source port and IP address (within the correct
959  * range and address family) to associate replies with the
960  * connection / correct mesh tunnel.  This function generates
961  * a "fresh" source IP and source port number for a connection
962  * After picking a good source address, this function sets up
963  * the state in the 'connections_map' and 'connections_heap'
964  * to allow finding the state when needed later.  The function
965  * also makes sure that we remain within memory limits by
966  * cleaning up 'old' states.
967  *
968  * @param state skeleton state to setup a record for; should
969  *              'state->ri.remote_address' filled in so that
970  *              this code can determine which AF/protocol is
971  *              going to be used (the 'tunnel' should also
972  *              already be set); after calling this function,
973  *              heap_node and the local_address will be
974  *              also initialized (heap_node != NULL can be
975  *              used to test if a state has been fully setup).
976  */
977 static void
978 setup_state_record (struct TunnelState *state)
979 {
980   GNUNET_HashCode key;
981   struct TunnelState *s;
982
983   /* generate fresh, unique address */
984   do
985   {
986     if (NULL == state->serv)
987       setup_fresh_address (state->ri.remote_address.af,
988                            state->ri.remote_address.proto,
989                            &state->ri.local_address);
990     else
991       setup_fresh_address (state->serv->address.af,
992                            state->serv->address.proto,
993                            &state->ri.local_address);
994   } while (NULL != get_redirect_state (state->ri.remote_address.af,
995                                        state->ri.remote_address.proto,
996                                        &state->ri.remote_address.address,
997                                        state->ri.remote_address.port,
998                                        &state->ri.local_address.address,
999                                        state->ri.local_address.port,
1000                                        &key));
1001   {
1002     char buf[INET6_ADDRSTRLEN];
1003     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1004                 "Picked local address %s:%u for new connection\n",
1005                 inet_ntop (state->ri.local_address.af, 
1006                            &state->ri.local_address.address,
1007                            buf, sizeof (buf)),
1008                 (unsigned int) state->ri.local_address.port);  
1009   }
1010   state->state_key = key;
1011   GNUNET_assert (GNUNET_OK ==
1012                  GNUNET_CONTAINER_multihashmap_put (connections_map, 
1013                                                     &key, state,
1014                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1015   state->heap_node = GNUNET_CONTAINER_heap_insert (connections_heap,
1016                                                    state,
1017                                                    GNUNET_TIME_absolute_get ().abs_value);   
1018   while (GNUNET_CONTAINER_heap_get_size (connections_heap) > max_connections)
1019   {
1020     s = GNUNET_CONTAINER_heap_remove_root (connections_heap);
1021     GNUNET_assert (state != s);
1022     s->heap_node = NULL;
1023     GNUNET_MESH_tunnel_destroy (s->tunnel);
1024     GNUNET_assert (GNUNET_OK ==
1025                    GNUNET_CONTAINER_multihashmap_remove (connections_map,
1026                                                          &s->state_key, 
1027                                                          s));
1028     GNUNET_free (s);
1029   }
1030 }
1031
1032
1033 /**
1034  * Prepare an IPv4 packet for transmission via the TUN interface.
1035  * Initializes the IP header and calculates checksums (IP+UDP/TCP).
1036  * For UDP, the UDP header will be fully created, whereas for TCP
1037  * only the ports and checksum will be filled in.  So for TCP,
1038  * a skeleton TCP header must be part of the provided payload.
1039  *
1040  * @param payload payload of the packet (starting with UDP payload or
1041  *                TCP header, depending on protocol)
1042  * @param payload_length number of bytes in 'payload'
1043  * @param protocol IPPROTO_UDP or IPPROTO_TCP
1044  * @param src_address source address to use (IP and port)
1045  * @param dst_address destination address to use (IP and port)
1046  * @param pkt6 where to write the assembled packet; must
1047  *        contain enough space for the IP header, UDP/TCP header
1048  *        AND the payload
1049  */
1050 static void
1051 prepare_ipv4_packet (const void *payload, size_t payload_length,
1052                      int protocol,
1053                      const struct GNUNET_TUN_TcpHeader *tcp_header,
1054                      const struct SocketAddress *src_address,
1055                      const struct SocketAddress *dst_address,
1056                      struct GNUNET_TUN_IPv4Header *pkt4)
1057 {
1058   size_t len;
1059
1060   len = payload_length;
1061   switch (protocol)
1062   {
1063   case IPPROTO_UDP:
1064     len += sizeof (struct GNUNET_TUN_UdpHeader);
1065     break;
1066   case IPPROTO_TCP:
1067     len += sizeof (struct GNUNET_TUN_TcpHeader);
1068     GNUNET_assert (NULL != tcp_header);
1069     break;
1070   default:
1071     GNUNET_break (0);
1072     return;
1073   }
1074   if (len + sizeof (struct GNUNET_TUN_IPv4Header) > UINT16_MAX)
1075   {
1076     GNUNET_break (0);
1077     return;
1078   }
1079
1080   GNUNET_TUN_initialize_ipv4_header (pkt4,
1081                                      protocol,
1082                                      len,
1083                                      &src_address->address.ipv4,
1084                                      &dst_address->address.ipv4);
1085   switch (protocol)
1086   {
1087   case IPPROTO_UDP:
1088     {
1089       struct GNUNET_TUN_UdpHeader *pkt4_udp = (struct GNUNET_TUN_UdpHeader *) &pkt4[1];
1090
1091       pkt4_udp->spt = htons (src_address->port);
1092       pkt4_udp->dpt = htons (dst_address->port);
1093       pkt4_udp->len = htons ((uint16_t) payload_length);
1094       GNUNET_TUN_calculate_udp4_checksum (pkt4,
1095                                           pkt4_udp,
1096                                           payload, payload_length);
1097       memcpy (&pkt4_udp[1], payload, payload_length);
1098     }
1099     break;
1100   case IPPROTO_TCP:
1101     {
1102       struct GNUNET_TUN_TcpHeader *pkt4_tcp = (struct GNUNET_TUN_TcpHeader *) &pkt4[1];
1103       
1104       memcpy (pkt4_tcp, tcp_header, sizeof (struct GNUNET_TUN_TcpHeader));
1105       pkt4_tcp->spt = htons (src_address->port);
1106       pkt4_tcp->dpt = htons (dst_address->port);
1107       GNUNET_TUN_calculate_tcp4_checksum (pkt4,
1108                                           pkt4_tcp,
1109                                           payload,
1110                                           payload_length);
1111       memcpy (&pkt4_tcp[1], payload, payload_length);
1112     }
1113     break;
1114   default:
1115     GNUNET_assert (0);
1116   }
1117 }
1118
1119
1120 /**
1121  * Prepare an IPv6 packet for transmission via the TUN interface.
1122  * Initializes the IP header and calculates checksums (IP+UDP/TCP).
1123  * For UDP, the UDP header will be fully created, whereas for TCP
1124  * only the ports and checksum will be filled in.  So for TCP,
1125  * a skeleton TCP header must be part of the provided payload.
1126  *
1127  * @param payload payload of the packet (starting with UDP payload or
1128  *                TCP header, depending on protocol)
1129  * @param payload_length number of bytes in 'payload'
1130  * @param protocol IPPROTO_UDP or IPPROTO_TCP
1131  * @param src_address source address to use (IP and port)
1132  * @param dst_address destination address to use (IP and port)
1133  * @param pkt6 where to write the assembled packet; must
1134  *        contain enough space for the IP header, UDP/TCP header
1135  *        AND the payload
1136  */
1137 static void
1138 prepare_ipv6_packet (const void *payload, size_t payload_length,
1139                      int protocol,
1140                      const struct GNUNET_TUN_TcpHeader *tcp_header,
1141                      const struct SocketAddress *src_address,
1142                      const struct SocketAddress *dst_address,
1143                      struct GNUNET_TUN_IPv6Header *pkt6)
1144 {
1145   size_t len;
1146
1147   len = payload_length;
1148   switch (protocol)
1149   {
1150   case IPPROTO_UDP:
1151     len += sizeof (struct GNUNET_TUN_UdpHeader);
1152     break;
1153   case IPPROTO_TCP:
1154     /* tcp_header (with port/crc not set) must be part of payload! */
1155     if (len < sizeof (struct GNUNET_TUN_TcpHeader))
1156     {
1157       GNUNET_break (0);
1158       return;
1159     }
1160     break;
1161   default:
1162     GNUNET_break (0);
1163     return;
1164   }
1165   if (len > UINT16_MAX)
1166   {
1167     GNUNET_break (0);
1168     return;
1169   }
1170
1171   GNUNET_TUN_initialize_ipv6_header (pkt6,
1172                                      protocol,
1173                                      len,
1174                                      &dst_address->address.ipv6,
1175                                      &src_address->address.ipv6);
1176
1177   switch (protocol)
1178   {
1179   case IPPROTO_UDP:
1180     {
1181       struct GNUNET_TUN_UdpHeader *pkt6_udp = (struct GNUNET_TUN_UdpHeader *) &pkt6[1];
1182
1183       pkt6_udp->spt = htons (src_address->port);
1184       pkt6_udp->dpt = htons (dst_address->port);
1185       pkt6_udp->len = htons ((uint16_t) payload_length);
1186       pkt6_udp->crc = 0;
1187       GNUNET_TUN_calculate_udp6_checksum (pkt6,
1188                                           pkt6_udp,
1189                                           payload,
1190                                           payload_length);
1191       memcpy (&pkt6[1], payload, payload_length);
1192     }
1193     break;
1194   case IPPROTO_TCP:
1195     {
1196       struct GNUNET_TUN_TcpHeader *pkt6_tcp = (struct GNUNET_TUN_TcpHeader *) pkt6;
1197
1198       /* memcpy first here as some TCP header fields are initialized this way! */
1199       memcpy (pkt6_tcp, payload, payload_length);
1200       pkt6_tcp->spt = htons (src_address->port);
1201       pkt6_tcp->dpt = htons (dst_address->port);
1202       GNUNET_TUN_calculate_tcp6_checksum (pkt6,
1203                                           pkt6_tcp,
1204                                           payload,
1205                                           payload_length);
1206     }
1207     break;
1208   default:
1209     GNUNET_assert (0);
1210     break;
1211   }
1212 }
1213
1214
1215 /**
1216  * Send a TCP packet via the TUN interface.
1217  *
1218  * @param destination_address IP and port to use for the TCP packet's destination
1219  * @param source_address IP and port to use for the TCP packet's source
1220  * @param tcp header template to use
1221  * @param payload payload of the TCP packet
1222  * @param payload_length number of bytes in 'payload'
1223  */
1224 static void
1225 send_tcp_packet_via_tun (const struct SocketAddress *destination_address,
1226                          const struct SocketAddress *source_address,
1227                          const struct GNUNET_TUN_TcpHeader *tcp_header,
1228                          const void *payload, size_t payload_length)
1229 {
1230   size_t len;
1231
1232   GNUNET_STATISTICS_update (stats,
1233                             gettext_noop ("# TCP packets sent via TUN"),
1234                             1, GNUNET_NO);
1235   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1236               "Sending packet with %u bytes TCP payload via TUN\n",
1237               (unsigned int) payload_length);
1238   len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader);
1239   switch (source_address->af)
1240   {
1241   case AF_INET:
1242     len += sizeof (struct GNUNET_TUN_IPv4Header);
1243     break;
1244   case AF_INET6:
1245     len += sizeof (struct GNUNET_TUN_IPv6Header);
1246     break;
1247   default:
1248     GNUNET_break (0);
1249     return;
1250   }
1251   len += payload_length;
1252   if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1253   {
1254     GNUNET_break (0);
1255     return;
1256   }
1257   {
1258     char buf[len];
1259     struct GNUNET_MessageHeader *hdr;
1260     struct GNUNET_TUN_Layer2PacketHeader *tun;
1261     
1262     hdr= (struct GNUNET_MessageHeader *) buf;
1263     hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1264     hdr->size = htons (len);
1265     tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1266     tun->flags = htons (0);
1267     switch (source_address->af)
1268     {
1269     case AF_INET:
1270       {
1271         struct GNUNET_TUN_IPv4Header * ipv4 = (struct GNUNET_TUN_IPv4Header*) &tun[1];
1272         
1273         tun->proto = htons (ETH_P_IPV4);
1274         prepare_ipv4_packet (payload, payload_length,
1275                              IPPROTO_TCP,
1276                              tcp_header, 
1277                              source_address,
1278                              destination_address,
1279                              ipv4);
1280       }
1281       break;
1282     case AF_INET6:
1283       {
1284         struct GNUNET_TUN_IPv6Header * ipv6 = (struct GNUNET_TUN_IPv6Header*) &tun[1];
1285         
1286         tun->proto = htons (ETH_P_IPV6);
1287         prepare_ipv6_packet (payload, payload_length, 
1288                              IPPROTO_TCP,
1289                              tcp_header, 
1290                              source_address,
1291                              destination_address,
1292                              ipv6);
1293       }
1294       break;    
1295     default:
1296       GNUNET_assert (0);
1297       break;
1298     }
1299     (void) GNUNET_HELPER_send (helper_handle,
1300                                (const struct GNUNET_MessageHeader*) buf,
1301                                GNUNET_YES,
1302                                NULL, NULL);
1303   }
1304 }
1305
1306
1307 /**
1308  * Process a request via mesh to send a request to a TCP service
1309  * offered by this system.
1310  *
1311  * @param cls closure, NULL
1312  * @param tunnel connection to the other end
1313  * @param tunnel_ctx pointer to our 'struct TunnelState *'
1314  * @param sender who sent the message
1315  * @param message the actual message
1316  * @param atsi performance data for the connection
1317  * @return GNUNET_OK to keep the connection open,
1318  *         GNUNET_SYSERR to close it (signal serious error)
1319  */
1320 static int
1321 receive_tcp_service (void *unused GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1322                      void **tunnel_ctx GNUNET_UNUSED,
1323                      const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1324                      const struct GNUNET_MessageHeader *message,
1325                      const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1326 {
1327   struct TunnelState *state = *tunnel_ctx;
1328   const struct GNUNET_EXIT_TcpServiceStartMessage *start;
1329   uint16_t pkt_len = ntohs (message->size);
1330
1331   GNUNET_STATISTICS_update (stats,
1332                             gettext_noop ("# TCP service creation requests received via mesh"),
1333                             1, GNUNET_NO);
1334   GNUNET_STATISTICS_update (stats,
1335                             gettext_noop ("# Bytes received from MESH"),
1336                             pkt_len, GNUNET_NO);
1337   /* check that we got at least a valid header */
1338   if (pkt_len < sizeof (struct GNUNET_EXIT_TcpServiceStartMessage))
1339   {
1340     GNUNET_break_op (0);
1341     return GNUNET_SYSERR;
1342   }
1343   start = (const struct GNUNET_EXIT_TcpServiceStartMessage*) message;
1344   pkt_len -= sizeof (struct GNUNET_EXIT_TcpServiceStartMessage);
1345   if ( (NULL == state) ||
1346        (NULL != state->serv) ||
1347        (NULL != state->heap_node) )
1348   {
1349     GNUNET_break_op (0);
1350     return GNUNET_SYSERR;
1351   }
1352   GNUNET_break_op (ntohl (start->reserved) == 0);
1353   /* setup fresh connection */
1354   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1355               "Received data from %s for forwarding to TCP service %s on port %u\n",
1356               GNUNET_i2s (sender),
1357               GNUNET_h2s (&start->service_descriptor),
1358               (unsigned int) ntohs (start->tcp_header.dpt));  
1359   if (NULL == (state->serv = find_service (tcp_services, &start->service_descriptor, 
1360                                            ntohs (start->tcp_header.dpt))))
1361   {
1362     GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
1363                 _("No service found for %s on port %d!\n"),
1364                 "TCP",
1365                 ntohs (start->tcp_header.dpt));
1366     GNUNET_STATISTICS_update (stats,
1367                               gettext_noop ("# TCP requests dropped (no such service)"),
1368                               1, GNUNET_NO);
1369     return GNUNET_SYSERR;
1370   }
1371   state->ri.remote_address = state->serv->address;    
1372   setup_state_record (state);
1373   send_tcp_packet_via_tun (&state->ri.remote_address,
1374                            &state->ri.local_address,
1375                            &start->tcp_header,
1376                            &start[1], pkt_len);
1377   return GNUNET_YES;
1378 }
1379
1380
1381 /**
1382  * Process a request to forward TCP data to the Internet via this peer.
1383  *
1384  * @param cls closure, NULL
1385  * @param tunnel connection to the other end
1386  * @param tunnel_ctx pointer to our 'struct TunnelState *'
1387  * @param sender who sent the message
1388  * @param message the actual message
1389  * @param atsi performance data for the connection
1390  * @return GNUNET_OK to keep the connection open,
1391  *         GNUNET_SYSERR to close it (signal serious error)
1392  */
1393 static int
1394 receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1395                     void **tunnel_ctx GNUNET_UNUSED,
1396                     const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1397                     const struct GNUNET_MessageHeader *message,
1398                     const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1399 {
1400   struct TunnelState *state = *tunnel_ctx;
1401   const struct GNUNET_EXIT_TcpInternetStartMessage *start;
1402   uint16_t pkt_len = ntohs (message->size);
1403   const struct in_addr *v4;
1404   const struct in6_addr *v6;
1405   const void *payload;
1406   int af;
1407
1408   GNUNET_STATISTICS_update (stats,
1409                             gettext_noop ("# Bytes received from MESH"),
1410                             pkt_len, GNUNET_NO);
1411   GNUNET_STATISTICS_update (stats,
1412                             gettext_noop ("# TCP IP-exit creation requests received via mesh"),
1413                             1, GNUNET_NO);
1414   if (pkt_len < sizeof (struct GNUNET_EXIT_TcpInternetStartMessage))
1415   {
1416     GNUNET_break_op (0);
1417     return GNUNET_SYSERR;
1418   }
1419   start = (const struct GNUNET_EXIT_TcpInternetStartMessage*) message;
1420   pkt_len -= sizeof (struct GNUNET_EXIT_TcpInternetStartMessage);  
1421   if ( (NULL == state) ||
1422        (NULL != state->serv) ||
1423        (NULL != state->heap_node) )
1424   {
1425     GNUNET_break_op (0);
1426     return GNUNET_SYSERR;
1427   }
1428   af = (int) ntohl (start->af);
1429   state->ri.remote_address.af = af;
1430   switch (af)
1431   {
1432   case AF_INET:
1433     if (pkt_len < sizeof (struct in_addr))
1434     {
1435       GNUNET_break_op (0);
1436       return GNUNET_SYSERR;
1437     }
1438     if (! ipv4_exit)
1439     {
1440       GNUNET_break_op (0);
1441       return GNUNET_SYSERR;
1442     }
1443     v4 = (const struct in_addr*) &start[1];
1444     payload = &v4[1];
1445     pkt_len -= sizeof (struct in_addr);
1446     state->ri.remote_address.address.ipv4 = *v4;
1447     break;
1448   case AF_INET6:
1449     if (pkt_len < sizeof (struct in6_addr))
1450     {
1451       GNUNET_break_op (0);
1452       return GNUNET_SYSERR;
1453     }
1454     if (! ipv6_exit)
1455     {
1456       GNUNET_break_op (0);
1457       return GNUNET_SYSERR;
1458     }
1459     v6 = (const struct in6_addr*) &start[1];
1460     payload = &v6[1];
1461     pkt_len -= sizeof (struct in_addr);
1462     state->ri.remote_address.address.ipv6 = *v6;
1463     break;
1464   default:
1465     GNUNET_break_op (0);
1466     return GNUNET_SYSERR;
1467   }
1468   {
1469     char buf[INET6_ADDRSTRLEN];
1470     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1471                 "Received data from %s for starting TCP stream to %s:%u\n",
1472                 GNUNET_i2s (sender),
1473                 inet_ntop (af, 
1474                            &state->ri.remote_address.address,
1475                            buf, sizeof (buf)),
1476                 (unsigned int) ntohs (start->tcp_header.dpt));  
1477   }
1478
1479   state->ri.remote_address.proto = IPPROTO_TCP;
1480   state->ri.remote_address.port = ntohs (start->tcp_header.dpt);
1481   setup_state_record (state);
1482   send_tcp_packet_via_tun (&state->ri.remote_address,
1483                            &state->ri.local_address,
1484                            &start->tcp_header,
1485                            payload, pkt_len);
1486   return GNUNET_YES;
1487 }
1488
1489
1490 /**
1491  * Process a request to forward TCP data on an established 
1492  * connection via this peer.
1493  *
1494  * @param cls closure, NULL
1495  * @param tunnel connection to the other end
1496  * @param tunnel_ctx pointer to our 'struct TunnelState *'
1497  * @param sender who sent the message
1498  * @param message the actual message
1499  * @param atsi performance data for the connection
1500  * @return GNUNET_OK to keep the connection open,
1501  *         GNUNET_SYSERR to close it (signal serious error)
1502  */
1503 static int
1504 receive_tcp_data (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1505                   void **tunnel_ctx GNUNET_UNUSED,
1506                   const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1507                   const struct GNUNET_MessageHeader *message,
1508                   const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1509 {
1510   struct TunnelState *state = *tunnel_ctx;
1511   const struct GNUNET_EXIT_TcpDataMessage *data;
1512   uint16_t pkt_len = ntohs (message->size);
1513
1514   GNUNET_STATISTICS_update (stats,
1515                             gettext_noop ("# Bytes received from MESH"),
1516                             pkt_len, GNUNET_NO);
1517   GNUNET_STATISTICS_update (stats,
1518                             gettext_noop ("# TCP data requests received via mesh"),
1519                             1, GNUNET_NO);
1520   if (pkt_len < sizeof (struct GNUNET_EXIT_TcpDataMessage))
1521   {
1522     GNUNET_break_op (0);
1523     return GNUNET_SYSERR;
1524   }
1525   data = (const struct GNUNET_EXIT_TcpDataMessage*) message;
1526   pkt_len -= sizeof (struct GNUNET_EXIT_TcpDataMessage);  
1527   if ( (NULL == state) ||
1528        (NULL == state->heap_node) )
1529   {
1530     /* connection should have been up! */
1531     GNUNET_STATISTICS_update (stats,
1532                               gettext_noop ("# TCP DATA requests dropped (no session)"),
1533                               1, GNUNET_NO);
1534     return GNUNET_SYSERR;
1535   }
1536   GNUNET_break_op (ntohl (data->reserved) == 0);
1537   {
1538     char buf[INET6_ADDRSTRLEN];
1539     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1540                 "Received additional data from %s for TCP stream to %s:%u\n",
1541                 GNUNET_i2s (sender),
1542                 inet_ntop (state->ri.remote_address.af, 
1543                            &state->ri.remote_address.address,
1544                            buf, sizeof (buf)),
1545                 (unsigned int) state->ri.remote_address.port);
1546   }
1547
1548   send_tcp_packet_via_tun (&state->ri.remote_address,
1549                            &state->ri.local_address,
1550                            &data->tcp_header,
1551                            &data[1], pkt_len);
1552   return GNUNET_YES;
1553 }
1554
1555
1556 /**
1557  * Send a UDP packet via the TUN interface.
1558  *
1559  * @param destination_address IP and port to use for the UDP packet's destination
1560  * @param source_address IP and port to use for the UDP packet's source
1561  * @param payload payload of the UDP packet (does NOT include UDP header)
1562  * @param payload_length number of bytes of data in payload
1563  */
1564 static void
1565 send_udp_packet_via_tun (const struct SocketAddress *destination_address,
1566                          const struct SocketAddress *source_address,
1567                          const void *payload, size_t payload_length)
1568 {
1569   size_t len;
1570
1571   GNUNET_STATISTICS_update (stats,
1572                             gettext_noop ("# UDP packets sent via TUN"),
1573                             1, GNUNET_NO);
1574   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1575               "Sending packet with %u bytes UDP payload via TUN\n",
1576               (unsigned int) payload_length);
1577   len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader);
1578   switch (source_address->af)
1579   {
1580   case AF_INET:
1581     len += sizeof (struct GNUNET_TUN_IPv4Header);
1582     break;
1583   case AF_INET6:
1584     len += sizeof (struct GNUNET_TUN_IPv6Header);
1585     break;
1586   default:
1587     GNUNET_break (0);
1588     return;
1589   }
1590   len += sizeof (struct GNUNET_TUN_UdpHeader);
1591   len += payload_length;
1592   if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1593   {
1594     GNUNET_break (0);
1595     return;
1596   }
1597   {
1598     char buf[len];
1599     struct GNUNET_MessageHeader *hdr;
1600     struct GNUNET_TUN_Layer2PacketHeader *tun;
1601     
1602     hdr= (struct GNUNET_MessageHeader *) buf;
1603     hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1604     hdr->size = htons (len);
1605     tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1606     tun->flags = htons (0);
1607     switch (source_address->af)
1608     {
1609     case AF_INET:
1610       {
1611         struct GNUNET_TUN_IPv4Header * ipv4 = (struct GNUNET_TUN_IPv4Header*) &tun[1];
1612         
1613         tun->proto = htons (ETH_P_IPV4);
1614         prepare_ipv4_packet (payload, payload_length,
1615                              IPPROTO_UDP,
1616                              NULL,
1617                              source_address,
1618                              destination_address,
1619                              ipv4);
1620       }
1621       break;
1622     case AF_INET6:
1623       {
1624         struct GNUNET_TUN_IPv6Header * ipv6 = (struct GNUNET_TUN_IPv6Header*) &tun[1];
1625         
1626         tun->proto = htons (ETH_P_IPV6);
1627         prepare_ipv6_packet (payload, payload_length, 
1628                              IPPROTO_UDP,
1629                              NULL,
1630                              source_address,
1631                              destination_address,
1632                              ipv6);
1633       }
1634       break;    
1635     default:
1636       GNUNET_assert (0);
1637       break;
1638     }
1639     (void) GNUNET_HELPER_send (helper_handle,
1640                                (const struct GNUNET_MessageHeader*) buf,
1641                                GNUNET_YES,
1642                                NULL, NULL);
1643   }
1644 }
1645
1646
1647 /**
1648  * Process a request to forward UDP data to the Internet via this peer.
1649  *
1650  * @param cls closure, NULL
1651  * @param tunnel connection to the other end
1652  * @param tunnel_ctx pointer to our 'struct TunnelState *'
1653  * @param sender who sent the message
1654  * @param message the actual message
1655  * @param atsi performance data for the connection
1656  * @return GNUNET_OK to keep the connection open,
1657  *         GNUNET_SYSERR to close it (signal serious error)
1658  */
1659 static int
1660 receive_udp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1661                     void **tunnel_ctx GNUNET_UNUSED,
1662                     const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1663                     const struct GNUNET_MessageHeader *message,
1664                     const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1665 {
1666   struct TunnelState *state = *tunnel_ctx;
1667   const struct GNUNET_EXIT_UdpInternetMessage *msg;
1668   uint16_t pkt_len = ntohs (message->size);
1669   const struct in_addr *v4;
1670   const struct in6_addr *v6;
1671   const void *payload;
1672   int af;
1673
1674   GNUNET_STATISTICS_update (stats,
1675                             gettext_noop ("# Bytes received from MESH"),
1676                             pkt_len, GNUNET_NO);
1677   GNUNET_STATISTICS_update (stats,
1678                             gettext_noop ("# UDP IP-exit requests received via mesh"),
1679                             1, GNUNET_NO);
1680   if (pkt_len < sizeof (struct GNUNET_EXIT_UdpInternetMessage))
1681   {
1682     GNUNET_break_op (0);
1683     return GNUNET_SYSERR;
1684   }
1685   msg = (const struct GNUNET_EXIT_UdpInternetMessage*) message;
1686   pkt_len -= sizeof (struct GNUNET_EXIT_UdpInternetMessage);  
1687   af = (int) ntohl (msg->af);
1688   state->ri.remote_address.af = af;
1689   switch (af)
1690   {
1691   case AF_INET:
1692     if (pkt_len < sizeof (struct in_addr))
1693     {
1694       GNUNET_break_op (0);
1695       return GNUNET_SYSERR;
1696     }
1697     if (! ipv4_exit)
1698     {
1699       GNUNET_break_op (0);
1700       return GNUNET_SYSERR;
1701     }
1702     v4 = (const struct in_addr*) &msg[1];
1703     payload = &v4[1];
1704     pkt_len -= sizeof (struct in_addr);
1705     state->ri.remote_address.address.ipv4 = *v4;
1706     break;
1707   case AF_INET6:
1708     if (pkt_len < sizeof (struct in6_addr))
1709     {
1710       GNUNET_break_op (0);
1711       return GNUNET_SYSERR;
1712     }
1713     if (! ipv6_exit)
1714     {
1715       GNUNET_break_op (0);
1716       return GNUNET_SYSERR;
1717     }
1718     v6 = (const struct in6_addr*) &msg[1];
1719     payload = &v6[1];
1720     pkt_len -= sizeof (struct in_addr);
1721     state->ri.remote_address.address.ipv6 = *v6;
1722     break;
1723   default:
1724     GNUNET_break_op (0);
1725     return GNUNET_SYSERR;
1726   }
1727   {
1728     char buf[INET6_ADDRSTRLEN];
1729     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1730                 "Received data from %s for forwarding to UDP %s:%u\n",
1731                 GNUNET_i2s (sender),
1732                 inet_ntop (af, 
1733                            &state->ri.remote_address.address,
1734                            buf, sizeof (buf)),
1735                 (unsigned int) ntohs (msg->destination_port));  
1736   }
1737   state->ri.remote_address.proto = IPPROTO_UDP;
1738   state->ri.remote_address.port = msg->destination_port;
1739   if (NULL == state->heap_node)
1740     setup_state_record (state);
1741   if (0 != ntohs (msg->source_port))
1742     state->ri.local_address.port = msg->source_port;
1743   send_udp_packet_via_tun (&state->ri.remote_address,
1744                            &state->ri.local_address,
1745                            payload, pkt_len);
1746   return GNUNET_YES;
1747 }
1748
1749
1750 /**
1751  * Process a request via mesh to send a request to a UDP service
1752  * offered by this system.
1753  *
1754  * @param cls closure, NULL
1755  * @param tunnel connection to the other end
1756  * @param tunnel_ctx pointer to our 'struct TunnelState *'
1757  * @param sender who sent the message
1758  * @param message the actual message
1759  * @param atsi performance data for the connection
1760  * @return GNUNET_OK to keep the connection open,
1761  *         GNUNET_SYSERR to close it (signal serious error)
1762  */
1763 static int
1764 receive_udp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1765                      void **tunnel_ctx,
1766                      const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1767                      const struct GNUNET_MessageHeader *message,
1768                      const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1769 {
1770   struct TunnelState *state = *tunnel_ctx;
1771   const struct GNUNET_EXIT_UdpServiceMessage *msg;
1772   uint16_t pkt_len = ntohs (message->size);
1773
1774   GNUNET_STATISTICS_update (stats,
1775                             gettext_noop ("# Bytes received from MESH"),
1776                             pkt_len, GNUNET_NO);
1777   GNUNET_STATISTICS_update (stats,
1778                             gettext_noop ("# UDP service requests received via mesh"),
1779                             1, GNUNET_NO);
1780   /* check that we got at least a valid header */
1781   if (pkt_len < sizeof (struct GNUNET_EXIT_UdpServiceMessage))
1782   {
1783     GNUNET_break_op (0);
1784     return GNUNET_SYSERR;
1785   }
1786   msg = (const struct GNUNET_EXIT_UdpServiceMessage*) message;
1787   pkt_len -= sizeof (struct GNUNET_EXIT_UdpServiceMessage);
1788   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1789               "Received data from %s for forwarding to UDP service %s on port %u\n",
1790               GNUNET_i2s (sender),
1791               GNUNET_h2s (&msg->service_descriptor),
1792               (unsigned int) ntohs (msg->destination_port));  
1793   if (NULL == (state->serv = find_service (udp_services, &msg->service_descriptor, 
1794                                            ntohs (msg->destination_port))))
1795   {
1796     GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
1797                 _("No service found for %s on port %d!\n"),
1798                 "UDP",
1799                 ntohs (msg->destination_port));
1800     GNUNET_STATISTICS_update (stats,
1801                               gettext_noop ("# UDP requests dropped (no such service)"),
1802                               1, GNUNET_NO);
1803     return GNUNET_SYSERR;
1804   }
1805   state->ri.remote_address = state->serv->address;    
1806   setup_state_record (state);
1807   if (0 != ntohs (msg->source_port))
1808     state->ri.local_address.port = msg->source_port;
1809   send_udp_packet_via_tun (&state->ri.remote_address,
1810                            &state->ri.local_address,
1811                            &msg[1], pkt_len);
1812   return GNUNET_YES;
1813 }
1814
1815
1816 /**
1817  * Callback from GNUNET_MESH for new tunnels.
1818  *
1819  * @param cls closure
1820  * @param tunnel new handle to the tunnel
1821  * @param initiator peer that started the tunnel
1822  * @param atsi performance information for the tunnel
1823  * @return initial tunnel context for the tunnel
1824  */
1825 static void *
1826 new_tunnel (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1827             const struct GNUNET_PeerIdentity *initiator GNUNET_UNUSED,
1828             const struct GNUNET_ATS_Information *ats GNUNET_UNUSED)
1829 {
1830   struct TunnelState *s = GNUNET_malloc (sizeof (struct TunnelState));
1831
1832   GNUNET_STATISTICS_update (stats,
1833                             gettext_noop ("# Inbound MESH tunnels created"),
1834                             1, GNUNET_NO);
1835   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1836               "Received inbound tunnel from `%s'\n",
1837               GNUNET_i2s (initiator));
1838   s->tunnel = tunnel;
1839   return s;
1840 }
1841
1842
1843 /**
1844  * Function called by mesh whenever an inbound tunnel is destroyed.
1845  * Should clean up any associated state.
1846  *
1847  * @param cls closure (set from GNUNET_MESH_connect)
1848  * @param tunnel connection to the other end (henceforth invalid)
1849  * @param tunnel_ctx place where local state associated
1850  *                   with the tunnel is stored
1851  */
1852 static void
1853 clean_tunnel (void *cls GNUNET_UNUSED, const struct GNUNET_MESH_Tunnel *tunnel,
1854               void *tunnel_ctx)
1855 {
1856   struct TunnelState *s = tunnel_ctx;
1857   struct TunnelMessageQueue *tnq;
1858
1859   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1860               "Tunnel destroyed\n");
1861   while (NULL != (tnq = s->head))
1862   {
1863     GNUNET_CONTAINER_DLL_remove (s->head,
1864                                  s->tail,
1865                                  tnq);
1866     GNUNET_free (tnq);
1867   }
1868   if (s->heap_node != NULL)
1869   {
1870     GNUNET_assert (GNUNET_YES ==
1871                    GNUNET_CONTAINER_multihashmap_remove (connections_map,
1872                                                          &s->state_key,
1873                                                          s));
1874     GNUNET_CONTAINER_heap_remove_node (s->heap_node);
1875     s->heap_node = NULL;
1876   }
1877   if (NULL != s->th)
1878   {
1879     GNUNET_MESH_notify_transmit_ready_cancel (s->th);
1880     s->th = NULL;
1881   }
1882   GNUNET_free (s);
1883 }
1884
1885
1886 /**
1887  * Function that frees everything from a hashmap
1888  *
1889  * @param cls unused
1890  * @param hash key
1891  * @param value value to free
1892  */
1893 static int
1894 free_iterate (void *cls GNUNET_UNUSED,
1895               const GNUNET_HashCode * hash GNUNET_UNUSED, void *value)
1896 {
1897   GNUNET_free (value);
1898   return GNUNET_YES;
1899 }
1900
1901
1902 /**
1903  * Function scheduled as very last function, cleans up after us
1904  */
1905 static void
1906 cleanup (void *cls GNUNET_UNUSED,
1907          const struct GNUNET_SCHEDULER_TaskContext *tskctx)
1908 {
1909   unsigned int i;
1910
1911   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1912               "Exit service is shutting down now\n");
1913   if (helper_handle != NULL)
1914   {
1915     GNUNET_HELPER_stop (helper_handle);
1916     helper_handle = NULL;
1917   }
1918   if (mesh_handle != NULL)
1919   {
1920     GNUNET_MESH_disconnect (mesh_handle);
1921     mesh_handle = NULL;
1922   }
1923   if (NULL != connections_map)
1924   {
1925     GNUNET_CONTAINER_multihashmap_iterate (connections_map, &free_iterate, NULL);
1926     GNUNET_CONTAINER_multihashmap_destroy (connections_map);
1927     connections_map = NULL;
1928   }
1929   if (NULL != connections_heap)
1930   {
1931     GNUNET_CONTAINER_heap_destroy (connections_heap);
1932     connections_heap = NULL;
1933   }
1934   if (NULL != tcp_services)
1935   {
1936     GNUNET_CONTAINER_multihashmap_iterate (tcp_services, &free_service_record, NULL);
1937     GNUNET_CONTAINER_multihashmap_destroy (tcp_services);
1938     tcp_services = NULL;
1939   }
1940   if (NULL != udp_services)
1941   {
1942     GNUNET_CONTAINER_multihashmap_iterate (udp_services, &free_service_record, NULL);
1943     GNUNET_CONTAINER_multihashmap_destroy (udp_services);
1944     udp_services = NULL;
1945   }
1946   if (stats != NULL)
1947   {
1948     GNUNET_STATISTICS_destroy (stats, GNUNET_YES);
1949     stats = NULL;
1950   }
1951   for (i=0;i<5;i++)
1952     GNUNET_free_non_null (exit_argv[i]);
1953 }
1954
1955
1956 /**
1957  * Add services to the service map.
1958  *
1959  * @param proto IPPROTO_TCP or IPPROTO_UDP
1960  * @param cpy copy of the service descriptor (can be mutilated)
1961  * @param name DNS name of the service
1962  */
1963 static void
1964 add_services (int proto,
1965               char *cpy,
1966               const char *name)
1967 {
1968   char *redirect;
1969   char *hostname;
1970   char *hostport;
1971   struct LocalService *serv;
1972
1973   for (redirect = strtok (cpy, " "); redirect != NULL;
1974        redirect = strtok (NULL, " "))
1975   {
1976     if (NULL == (hostname = strstr (redirect, ":")))
1977     {
1978       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1979                   "option `%s' for domain `%s' is not formatted correctly!\n",
1980                   redirect,
1981                   name);
1982       continue;
1983     }
1984     hostname[0] = '\0';
1985     hostname++;
1986     if (NULL == (hostport = strstr (hostname, ":")))
1987     {
1988       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1989                   "option `%s' for domain `%s' is not formatted correctly!\n",
1990                   redirect,
1991                   name);
1992       continue;
1993     }
1994     hostport[0] = '\0';
1995     hostport++;
1996     
1997     int local_port = atoi (redirect);
1998     int remote_port = atoi (hostport);
1999     
2000     if (!((local_port > 0) && (local_port < 65536)))
2001     {
2002       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2003                   "`%s' is not a valid port number (for domain `%s')!", redirect,
2004                   name);
2005       continue;
2006     }
2007     if (!((remote_port > 0) && (remote_port < 65536)))
2008     {
2009       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2010                   "`%s' is not a valid port number (for domain `%s')!", hostport,
2011                   name);
2012       continue;
2013     }
2014
2015     serv = GNUNET_malloc (sizeof (struct LocalService));
2016     serv->my_port = (uint16_t) local_port;
2017     serv->address.port = remote_port;
2018     if (0 == strcmp ("localhost4", hostname))
2019     {
2020       const char *ip4addr = exit_argv[4];
2021
2022       serv->address.af = AF_INET;      
2023       GNUNET_assert (1 != inet_pton (AF_INET, ip4addr, &serv->address.address.ipv4));
2024     }
2025     else if (0 == strcmp ("localhost6", hostname))
2026     {
2027       const char *ip6addr = exit_argv[2];
2028
2029       serv->address.af = AF_INET6;
2030       GNUNET_assert (1 == inet_pton (AF_INET6, ip6addr, &serv->address.address.ipv6));
2031     }
2032     else
2033     {
2034       struct addrinfo *res;      
2035       int ret;
2036
2037       ret = getaddrinfo (hostname, NULL, NULL, &res);      
2038       if ( (ret != 0) || (res == NULL) )
2039       {
2040         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2041                     _("No addresses found for hostname `%s' of service `%s'!\n"),
2042                     hostname,
2043                     name);
2044         GNUNET_free (serv);
2045         continue;
2046       }
2047       
2048       serv->address.af = res->ai_family;
2049       switch (res->ai_family)
2050       {
2051       case AF_INET:
2052         if (! ipv4_enabled)
2053         {
2054           GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2055                       _("Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
2056                       name);
2057           freeaddrinfo (res);
2058           GNUNET_free (serv);
2059           continue;
2060         }
2061         serv->address.address.ipv4 = ((struct sockaddr_in *) res->ai_addr)->sin_addr;
2062         break;
2063       case AF_INET6:
2064         if (! ipv6_enabled)
2065         {
2066           GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2067                       _("Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
2068                       name);
2069           freeaddrinfo (res);
2070           GNUNET_free (serv);
2071           continue;
2072         }       
2073         serv->address.address.ipv6 = ((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
2074         break;
2075       default:
2076         freeaddrinfo (res);
2077         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2078                     _("No IP addresses found for hostname `%s' of service `%s'!\n"),
2079                     hostname,
2080                     name);
2081         GNUNET_free (serv);
2082         continue;
2083       }
2084       freeaddrinfo (res);
2085     }
2086     store_service ((IPPROTO_UDP == proto) ? udp_services : tcp_services,
2087                    name,
2088                    local_port,
2089                    serv);
2090   }
2091 }
2092
2093
2094 /**
2095  * Reads the configuration servicecfg and populates udp_services
2096  *
2097  * @param cls unused
2098  * @param section name of section in config, equal to hostname
2099  */
2100 static void
2101 read_service_conf (void *cls GNUNET_UNUSED, const char *section)
2102 {
2103   char *cpy;
2104
2105   if ((strlen (section) < 8) ||
2106       (0 != strcmp (".gnunet.", section + (strlen (section) - 8))))
2107     return;
2108   if (GNUNET_OK ==
2109       GNUNET_CONFIGURATION_get_value_string (cfg, section, "UDP_REDIRECTS",
2110                                              &cpy))
2111   {
2112     add_services (IPPROTO_UDP, cpy, section);
2113     GNUNET_free (cpy);
2114   }
2115   if (GNUNET_OK ==
2116       GNUNET_CONFIGURATION_get_value_string (cfg, section, "TCP_REDIRECTS",
2117                                              &cpy))
2118   {
2119     add_services (IPPROTO_TCP, cpy, section);
2120     GNUNET_free (cpy);
2121   }
2122 }
2123
2124
2125 /**
2126  * @brief Main function that will be run by the scheduler.
2127  *
2128  * @param cls closure
2129  * @param args remaining command-line arguments
2130  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
2131  * @param cfg_ configuration
2132  */
2133 static void
2134 run (void *cls, char *const *args GNUNET_UNUSED,
2135      const char *cfgfile GNUNET_UNUSED,
2136      const struct GNUNET_CONFIGURATION_Handle *cfg_)
2137 {
2138   static struct GNUNET_MESH_MessageHandler handlers[] = {
2139     {&receive_udp_service, GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE, 0},
2140     {&receive_udp_remote, GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET, 0},
2141     {&receive_tcp_service, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START, 0},
2142     {&receive_tcp_remote, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START, 0},
2143     {&receive_tcp_data, GNUNET_MESSAGE_TYPE_VPN_TCP_DATA, 0},
2144     {NULL, 0, 0}
2145   };
2146
2147   static GNUNET_MESH_ApplicationType apptypes[] = {
2148     GNUNET_APPLICATION_TYPE_END,
2149     GNUNET_APPLICATION_TYPE_END,
2150     GNUNET_APPLICATION_TYPE_END
2151   };
2152   unsigned int app_idx;
2153   char *exit_ifname;
2154   char *tun_ifname;
2155   char *ipv6addr;
2156   char *ipv6prefix_s;
2157   char *ipv4addr;
2158   char *ipv4mask;
2159
2160   cfg = cfg_;
2161   stats = GNUNET_STATISTICS_create ("exit", cfg);
2162   ipv4_exit = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "EXIT_IPV4");
2163   ipv6_exit = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "EXIT_IPV6"); 
2164   ipv4_enabled = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_IPV4");
2165   ipv6_enabled = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_IPV6"); 
2166   if (ipv4_exit && (! ipv4_enabled))
2167   {
2168     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2169                 _("Cannot enable IPv4 exit but disable IPv4 on TUN interface, will use ENABLE_IPv4=YES\n"));
2170     ipv4_enabled = GNUNET_YES;
2171   }
2172   if (ipv6_exit && (! ipv6_enabled))
2173   {
2174     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2175                 _("Cannot enable IPv6 exit but disable IPv6 on TUN interface, will use ENABLE_IPv6=YES\n"));
2176     ipv6_enabled = GNUNET_YES;
2177   }
2178   if (! (ipv4_enabled || ipv6_enabled))
2179   {
2180     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2181                 _("No useful service enabled.  Exiting.\n"));
2182     GNUNET_SCHEDULER_shutdown ();
2183     return;    
2184   }
2185   app_idx = 0;
2186   if (GNUNET_YES == ipv4_exit)    
2187   {
2188     apptypes[app_idx] = GNUNET_APPLICATION_TYPE_IPV4_GATEWAY;
2189     app_idx++;
2190   }
2191   if (GNUNET_YES == ipv6_exit)    
2192   {
2193     apptypes[app_idx] = GNUNET_APPLICATION_TYPE_IPV6_GATEWAY;
2194     app_idx++;
2195   }
2196
2197   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls);
2198
2199   if (GNUNET_OK !=
2200       GNUNET_CONFIGURATION_get_value_number (cfg, "exit", "MAX_CONNECTIONS",
2201                                              &max_connections))
2202     max_connections = 1024;
2203   exit_argv[0] = GNUNET_strdup ("exit-gnunet");
2204   if (GNUNET_SYSERR ==
2205       GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "TUN_IFNAME", &tun_ifname))
2206   {
2207     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2208                 "No entry 'TUN_IFNAME' in configuration!\n");
2209     GNUNET_SCHEDULER_shutdown ();
2210     return;
2211   }
2212   exit_argv[1] = tun_ifname;
2213   if (ipv4_enabled)
2214   {
2215     if (GNUNET_SYSERR ==
2216         GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "EXIT_IFNAME", &exit_ifname))
2217     {
2218       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2219                   "No entry 'EXIT_IFNAME' in configuration!\n");
2220       GNUNET_SCHEDULER_shutdown ();
2221       return;
2222     }
2223     exit_argv[2] = exit_ifname;
2224   }
2225   else
2226   {
2227     exit_argv[2] = GNUNET_strdup ("%");
2228   }
2229   if (GNUNET_YES == ipv6_enabled)
2230   {
2231     if ( (GNUNET_SYSERR ==
2232           GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6ADDR",
2233                                                  &ipv6addr) ||
2234           (1 != inet_pton (AF_INET6, ipv6addr, &exit_ipv6addr))) )
2235     {
2236       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2237                   "No valid entry 'IPV6ADDR' in configuration!\n");
2238       GNUNET_SCHEDULER_shutdown ();
2239       return;
2240     }
2241     exit_argv[3] = ipv6addr;
2242     if (GNUNET_SYSERR ==
2243         GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6PREFIX",
2244                                                &ipv6prefix_s))
2245     {
2246       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2247                   "No entry 'IPV6PREFIX' in configuration!\n");
2248       GNUNET_SCHEDULER_shutdown ();
2249       return;
2250     }
2251     exit_argv[4] = ipv6prefix_s;
2252     if ( (GNUNET_OK !=
2253           GNUNET_CONFIGURATION_get_value_number (cfg, "exit",
2254                                                  "IPV6PREFIX",
2255                                                  &ipv6prefix)) ||
2256          (ipv6prefix >= 127) )
2257     {
2258       GNUNET_SCHEDULER_shutdown ();
2259       return;
2260     }
2261   } 
2262   else
2263   {
2264     /* IPv6 explicitly disabled */
2265     exit_argv[3] = GNUNET_strdup ("-");
2266     exit_argv[4] = GNUNET_strdup ("-");
2267   }
2268   if (GNUNET_YES == ipv4_enabled)
2269   {
2270     if ( (GNUNET_SYSERR ==
2271           GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4ADDR",
2272                                                  &ipv4addr) ||
2273           (1 != inet_pton (AF_INET, ipv4addr, &exit_ipv4addr))) )
2274       {
2275         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2276                     "No valid entry for 'IPV4ADDR' in configuration!\n");
2277         GNUNET_SCHEDULER_shutdown ();
2278         return;
2279       }
2280     exit_argv[5] = ipv4addr;
2281     if ( (GNUNET_SYSERR ==
2282           GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4MASK",
2283                                                  &ipv4mask) ||
2284           (1 != inet_pton (AF_INET, ipv4mask, &exit_ipv4mask))) )
2285     {
2286       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2287                   "No valid entry 'IPV4MASK' in configuration!\n");
2288       GNUNET_SCHEDULER_shutdown ();
2289       return;
2290     }
2291     exit_argv[6] = ipv4mask;
2292   }
2293   else
2294   {
2295     /* IPv4 explicitly disabled */
2296     exit_argv[5] = GNUNET_strdup ("-");
2297     exit_argv[6] = GNUNET_strdup ("-");
2298   }
2299   exit_argv[7] = NULL;
2300
2301   udp_services = GNUNET_CONTAINER_multihashmap_create (65536);
2302   tcp_services = GNUNET_CONTAINER_multihashmap_create (65536);
2303   GNUNET_CONFIGURATION_iterate_sections (cfg, &read_service_conf, NULL);
2304
2305   connections_map = GNUNET_CONTAINER_multihashmap_create (65536);
2306   connections_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
2307   mesh_handle 
2308     = GNUNET_MESH_connect (cfg, 42 /* queue size */, NULL, 
2309                            &new_tunnel, 
2310                            &clean_tunnel, handlers,
2311                            apptypes);
2312   if (NULL == mesh_handle)
2313   {
2314     GNUNET_SCHEDULER_shutdown ();
2315     return;
2316   }
2317   helper_handle = GNUNET_HELPER_start ("gnunet-helper-exit", 
2318                                        exit_argv,
2319                                        &message_token, NULL);
2320 }
2321
2322
2323 /**
2324  * The main function
2325  *
2326  * @param argc number of arguments from the command line
2327  * @param argv command line arguments
2328  * @return 0 ok, 1 on error
2329  */
2330 int
2331 main (int argc, char *const *argv)
2332 {
2333   static const struct GNUNET_GETOPT_CommandLineOption options[] = {
2334     GNUNET_GETOPT_OPTION_END
2335   };
2336
2337   return (GNUNET_OK ==
2338           GNUNET_PROGRAM_run (argc, argv, "gnunet-daemon-exit",
2339                               gettext_noop
2340                               ("Daemon to run to provide an IP exit node for the VPN"),
2341                               options, &run, NULL)) ? 0 : 1;
2342 }
2343
2344
2345 /* end of gnunet-daemon-exit.c */