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