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