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