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