last XDG change: use GNUNET_RUNTIME_DIR instead of /tmp for UNIXPATHs by default
[oweals/gnunet.git] / src / exit / gnunet-daemon-exit.c
1 /*
2      This file is part of GNUnet.
3      (C) 2010-2013 Christian Grothoff
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file exit/gnunet-daemon-exit.c
23  * @brief tool to allow IP traffic exit from the GNUnet mesh to the Internet
24  * @author Philipp Toelke
25  * @author Christian Grothoff
26  *
27  * TODO:
28  * - test
29  *
30  * Design:
31  * - which code should advertise services? the service model is right
32  *   now a bit odd, especially as this code DOES the exit and knows
33  *   the DNS "name", but OTOH this is clearly NOT the place to advertise
34  *   the service's existence; maybe the daemon should turn into a
35  *   service with an API to add local-exit services dynamically?
36  */
37 #include "platform.h"
38 #include "gnunet_util_lib.h"
39 #include "gnunet_protocols.h"
40 #include "gnunet_applications.h"
41 #include "gnunet_dht_service.h"
42 #include "gnunet_mesh_service.h"
43 #include "gnunet_dnsparser_lib.h"
44 #include "gnunet_dnsstub_lib.h"
45 #include "gnunet_statistics_service.h"
46 #include "gnunet_constants.h"
47 #include "gnunet_signatures.h"
48 #include "gnunet_tun_lib.h"
49 #include "gnunet_regex_service.h"
50 #include "exit.h"
51 #include "block_dns.h"
52
53
54 /**
55  * Maximum path compression length for mesh regex announcing for IPv4 address
56  * based regex.
57  */
58 #define REGEX_MAX_PATH_LEN_IPV4 4
59
60 /**
61  * Maximum path compression length for mesh regex announcing for IPv6 address
62  * based regex.
63  */
64 #define REGEX_MAX_PATH_LEN_IPV6 8
65
66 /**
67  * How frequently do we re-announce the regex for the exit?
68  */
69 #define REGEX_REFRESH_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 30)
70
71 /**
72  * How frequently do we re-announce the DNS exit in the DHT?
73  */
74 #define DHT_PUT_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)
75
76 /**
77  * How long do we typically sign the DNS exit advertisement for?
78  */
79 #define DNS_ADVERTISEMENT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 3)
80
81
82 /**
83  * Generic logging shorthand
84  */
85 #define LOG(kind, ...)                          \
86   GNUNET_log_from (kind, "exit", __VA_ARGS__);
87
88
89 /**
90  * Information about an address.
91  */
92 struct SocketAddress
93 {
94   /**
95    * AF_INET or AF_INET6.
96    */
97   int af;
98
99   /**
100    * Remote address information.
101    */
102   union
103   {
104     /**
105      * Address, if af is AF_INET.
106      */
107     struct in_addr ipv4;
108
109     /**
110      * Address, if af is AF_INET6.
111      */
112     struct in6_addr ipv6;
113   } address;
114
115   /**
116    * IPPROTO_TCP or IPPROTO_UDP;
117    */
118   uint8_t proto;
119
120   /**
121    * Remote port, in host byte order!
122    */
123   uint16_t port;
124
125 };
126
127 /**
128  * This struct is saved into the services-hashmap to represent
129  * a service this peer is specifically offering an exit for
130  * (for a specific domain name).
131  */
132 struct LocalService
133 {
134
135   /**
136    * Remote address to use for the service.
137    */
138   struct SocketAddress address;
139
140   /**
141    * DNS name of the service.
142    */
143   char *name;
144
145   /**
146    * Port I am listening on within GNUnet for this service, in host
147    * byte order.  (as we may redirect ports).
148    */
149   uint16_t my_port;
150
151 };
152
153 /**
154  * Information we use to track a connection (the classical 6-tuple of
155  * IP-version, protocol, source-IP, destination-IP, source-port and
156  * destinatin-port.
157  */
158 struct RedirectInformation
159 {
160
161   /**
162    * Address information for the other party (equivalent of the
163    * arguments one would give to "connect").
164    */
165   struct SocketAddress remote_address;
166
167   /**
168    * Address information we used locally (AF and proto must match
169    * "remote_address").  Equivalent of the arguments one would give to
170    * "bind".
171    */
172   struct SocketAddress local_address;
173
174   /*
175      Note 1: additional information might be added here in the
176      future to support protocols that require special handling,
177      such as ftp/tftp
178
179      Note 2: we might also sometimes not match on all components
180      of the tuple, to support protocols where things do not always
181      fully map.
182   */
183 };
184
185
186 /**
187  * Queue of messages to a tunnel.
188  */
189 struct TunnelMessageQueue
190 {
191   /**
192    * This is a doubly-linked list.
193    */
194   struct TunnelMessageQueue *next;
195
196   /**
197    * This is a doubly-linked list.
198    */
199   struct TunnelMessageQueue *prev;
200
201   /**
202    * Payload to send via the tunnel.
203    */
204   const void *payload;
205
206   /**
207    * Number of bytes in 'payload'.
208    */
209   size_t len;
210 };
211
212
213 /**
214  * This struct is saved into connections_map to allow finding the
215  * right tunnel given an IP packet from TUN.  It is also associated
216  * with the tunnel's closure so we can find it again for the next
217  * message from the tunnel.
218  */
219 struct TunnelState
220 {
221   /**
222    * Mesh tunnel that is used for this connection.
223    */
224   struct GNUNET_MESH_Tunnel *tunnel;
225
226   /**
227    * Who is the other end of this tunnel.
228    * FIXME is this needed? Only used for debugging messages
229    */
230   struct GNUNET_PeerIdentity peer;
231
232   /**
233    * Active tunnel transmission request (or NULL).
234    */
235   struct GNUNET_MESH_TransmitHandle *th;
236
237   /**
238    * #GNUNET_NO if this is a tunnel for TCP/UDP,
239    * #GNUNET_YES if this is a tunnel for DNS,
240    * #GNUNET_SYSERR if the tunnel is not yet initialized.
241    */
242   int is_dns;
243
244   union
245   {
246     struct
247     {
248
249       /**
250        * Heap node for this state in the connections_heap.
251        */
252       struct GNUNET_CONTAINER_HeapNode *heap_node;
253
254       /**
255        * Key this state has in the connections_map.
256        */
257       struct GNUNET_HashCode state_key;
258
259       /**
260        * Associated service record, or NULL for no service.
261        */
262       struct LocalService *serv;
263
264       /**
265        * Head of DLL of messages for this tunnel.
266        */
267       struct TunnelMessageQueue *head;
268
269       /**
270        * Tail of DLL of messages for this tunnel.
271        */
272       struct TunnelMessageQueue *tail;
273
274       /**
275        * Primary redirection information for this connection.
276        */
277       struct RedirectInformation ri;
278     } tcp_udp;
279
280     struct
281     {
282
283       /**
284        * DNS reply ready for transmission.
285        */
286       char *reply;
287
288       /**
289        * Socket we are using to transmit this request (must match if we receive
290        * a response).
291        */
292       struct GNUNET_DNSSTUB_RequestSocket *rs;
293
294       /**
295        * Number of bytes in 'reply'.
296        */
297       size_t reply_length;
298
299       /**
300        * Original DNS request ID as used by the client.
301        */
302       uint16_t original_id;
303
304       /**
305        * DNS request ID that we used for forwarding.
306        */
307       uint16_t my_id;
308
309     } dns;
310
311   } specifics;
312
313 };
314
315
316 /**
317  * Return value from 'main'.
318  */
319 static int global_ret;
320
321 /**
322  * Handle to our regex announcement for IPv4.
323  */
324 static struct GNUNET_REGEX_Announcement *regex4;
325
326 /**
327  * Handle to our regex announcement for IPv4.
328  */
329 static struct GNUNET_REGEX_Announcement *regex6;
330
331 /**
332  * The handle to the configuration used throughout the process
333  */
334 static const struct GNUNET_CONFIGURATION_Handle *cfg;
335
336 /**
337  * The handle to the helper
338  */
339 static struct GNUNET_HELPER_Handle *helper_handle;
340
341 /**
342  * Arguments to the exit helper.
343  */
344 static char *exit_argv[8];
345
346 /**
347  * IPv6 address of our TUN interface.
348  */
349 static struct in6_addr exit_ipv6addr;
350
351 /**
352  * IPv6 prefix (0..127) from configuration file.
353  */
354 static unsigned long long ipv6prefix;
355
356 /**
357  * IPv4 address of our TUN interface.
358  */
359 static struct in_addr exit_ipv4addr;
360
361 /**
362  * IPv4 netmask of our TUN interface.
363  */
364 static struct in_addr exit_ipv4mask;
365
366 /**
367  * Statistics.
368  */
369 static struct GNUNET_STATISTICS_Handle *stats;
370
371 /**
372  * The handle to mesh
373  */
374 static struct GNUNET_MESH_Handle *mesh_handle;
375
376 /**
377  * This hashmaps contains the mapping from peer, service-descriptor,
378  * source-port and destination-port to a struct TunnelState
379  */
380 static struct GNUNET_CONTAINER_MultiHashMap *connections_map;
381
382 /**
383  * Heap so we can quickly find "old" connections.
384  */
385 static struct GNUNET_CONTAINER_Heap *connections_heap;
386
387 /**
388  * If there are at least this many connections, old ones will be removed
389  */
390 static unsigned long long max_connections;
391
392 /**
393  * This hashmaps saves interesting things about the configured UDP services
394  */
395 static struct GNUNET_CONTAINER_MultiHashMap *udp_services;
396
397 /**
398  * This hashmaps saves interesting things about the configured TCP services
399  */
400 static struct GNUNET_CONTAINER_MultiHashMap *tcp_services;
401
402 /**
403  * Array of all open DNS requests from tunnels.
404  */
405 static struct TunnelState *tunnels[UINT16_MAX + 1];
406
407 /**
408  * Handle to the DNS Stub resolver.
409  */
410 static struct GNUNET_DNSSTUB_Context *dnsstub;
411
412 /**
413  * Handle for ongoing DHT PUT operations to advertise exit service.
414  */
415 static struct GNUNET_DHT_PutHandle *dht_put;
416
417 /**
418  * Handle to the DHT.
419  */
420 static struct GNUNET_DHT_Handle *dht;
421
422 /**
423  * Task for doing DHT PUTs to advertise exit service.
424  */
425 static GNUNET_SCHEDULER_TaskIdentifier dht_task;
426
427 /**
428  * Advertisement message we put into the DHT to advertise us
429  * as a DNS exit.
430  */
431 static struct GNUNET_DNS_Advertisement dns_advertisement;
432
433 /**
434  * Key we store the DNS advertismenet under.
435  */
436 static struct GNUNET_HashCode dht_put_key;
437
438 /**
439  * Private key for this peer.
440  */
441 static struct GNUNET_CRYPTO_EccPrivateKey *peer_key;
442
443 /**
444  * Are we an IPv4-exit?
445  */
446 static int ipv4_exit;
447
448 /**
449  * Are we an IPv6-exit?
450  */
451 static int ipv6_exit;
452
453 /**
454  * Do we support IPv4 at all on the TUN interface?
455  */
456 static int ipv4_enabled;
457
458 /**
459  * Do we support IPv6 at all on the TUN interface?
460  */
461 static int ipv6_enabled;
462
463
464 /**
465  * We got a reply from DNS for a request of a MESH tunnel.  Send it
466  * via the tunnel (after changing the request ID back).
467  *
468  * @param cls the 'struct TunnelState'
469  * @param size number of bytes available in buf
470  * @param buf where to copy the reply
471  * @return number of bytes written to buf
472  */
473 static size_t
474 transmit_reply_to_mesh (void *cls,
475                         size_t size,
476                         void *buf)
477 {
478   struct TunnelState *ts = cls;
479   size_t off;
480   size_t ret;
481   char *cbuf = buf;
482   struct GNUNET_MessageHeader hdr;
483   struct GNUNET_TUN_DnsHeader dns;
484
485   GNUNET_assert (GNUNET_YES == ts->is_dns);
486   ts->th = NULL;
487   GNUNET_assert (ts->specifics.dns.reply != NULL);
488   if (size == 0)
489     return 0;
490   ret = sizeof (struct GNUNET_MessageHeader) + ts->specifics.dns.reply_length;
491   GNUNET_assert (ret <= size);
492   hdr.size = htons (ret);
493   hdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET);
494   memcpy (&dns, ts->specifics.dns.reply, sizeof (dns));
495   dns.id = ts->specifics.dns.original_id;
496   off = 0;
497   memcpy (&cbuf[off], &hdr, sizeof (hdr));
498   off += sizeof (hdr);
499   memcpy (&cbuf[off], &dns, sizeof (dns));
500   off += sizeof (dns);
501   memcpy (&cbuf[off], &ts->specifics.dns.reply[sizeof (dns)], ts->specifics.dns.reply_length - sizeof (dns));
502   off += ts->specifics.dns.reply_length - sizeof (dns);
503   GNUNET_free (ts->specifics.dns.reply);
504   ts->specifics.dns.reply = NULL;
505   ts->specifics.dns.reply_length = 0;
506   GNUNET_assert (ret == off);
507   return ret;
508 }
509
510
511 /**
512  * Callback called from DNSSTUB resolver when a resolution
513  * succeeded.
514  *
515  * @param cls NULL
516  * @param rs the socket that received the response
517  * @param dns the response itself
518  * @param r number of bytes in dns
519  */
520 static void
521 process_dns_result (void *cls,
522                     struct GNUNET_DNSSTUB_RequestSocket *rs,
523                     const struct GNUNET_TUN_DnsHeader *dns,
524                     size_t r)
525 {
526   struct TunnelState *ts;
527
528   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
529               "Processing DNS result from stub resolver\n");
530   GNUNET_assert (NULL == cls);
531   /* Handle case that this is a reply to a request from a MESH DNS tunnel */
532   ts = tunnels[dns->id];
533   if ( (NULL == ts) ||
534        (ts->specifics.dns.rs != rs) )
535     return;
536   LOG (GNUNET_ERROR_TYPE_DEBUG,
537        "Got a response from the stub resolver for DNS request received via MESH!\n");
538   tunnels[dns->id] = NULL;
539   GNUNET_free_non_null (ts->specifics.dns.reply);
540   ts->specifics.dns.reply = GNUNET_malloc (r);
541   ts->specifics.dns.reply_length = r;
542   memcpy (ts->specifics.dns.reply, dns, r);
543   if (NULL != ts->th)
544     GNUNET_MESH_notify_transmit_ready_cancel (ts->th);
545   ts->th = GNUNET_MESH_notify_transmit_ready (ts->tunnel,
546                                               GNUNET_NO,
547                                               GNUNET_TIME_UNIT_FOREVER_REL,
548                                               sizeof (struct GNUNET_MessageHeader) + r,
549                                               &transmit_reply_to_mesh,
550                                               ts);
551 }
552
553
554 /**
555  * Process a request via mesh to perform a DNS query.
556  *
557  * @param cls closure, NULL
558  * @param tunnel connection to the other end
559  * @param tunnel_ctx pointer to our `struct TunnelState *`
560  * @param message the actual message
561  *
562  * @return #GNUNET_OK to keep the connection open,
563  *         #GNUNET_SYSERR to close it (signal serious error)
564  */
565 static int
566 receive_dns_request (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
567                      void **tunnel_ctx,
568                      const struct GNUNET_MessageHeader *message)
569 {
570   struct TunnelState *ts = *tunnel_ctx;
571   const struct GNUNET_TUN_DnsHeader *dns;
572   size_t mlen = ntohs (message->size);
573   size_t dlen = mlen - sizeof (struct GNUNET_MessageHeader);
574   char buf[dlen] GNUNET_ALIGN;
575   struct GNUNET_TUN_DnsHeader *dout;
576
577   if (NULL == dnsstub)
578     return GNUNET_SYSERR;
579   if (GNUNET_NO == ts->is_dns)
580   {
581     GNUNET_break_op (0);
582     return GNUNET_SYSERR;
583   }
584   if (GNUNET_SYSERR == ts->is_dns)
585   {
586     /* tunnel is DNS from now on */
587     ts->is_dns = GNUNET_YES;
588   }
589   if (dlen < sizeof (struct GNUNET_TUN_DnsHeader))
590   {
591     GNUNET_break_op (0);
592     return GNUNET_SYSERR;
593   }
594   dns = (const struct GNUNET_TUN_DnsHeader *) &message[1];
595   ts->specifics.dns.original_id = dns->id;
596   if (tunnels[ts->specifics.dns.my_id] == ts)
597     tunnels[ts->specifics.dns.my_id] = NULL;
598   ts->specifics.dns.my_id = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
599                                                    UINT16_MAX + 1);
600   tunnels[ts->specifics.dns.my_id] = ts;
601   memcpy (buf, dns, dlen);
602   dout = (struct GNUNET_TUN_DnsHeader *) buf;
603   dout->id = ts->specifics.dns.my_id;
604   ts->specifics.dns.rs = GNUNET_DNSSTUB_resolve2 (dnsstub,
605                                                   buf, dlen,
606                                                   &process_dns_result,
607                                                   NULL);
608   if (NULL == ts->specifics.dns.rs)
609     return GNUNET_SYSERR;
610   return GNUNET_OK;
611 }
612
613
614 /**
615  * Given IP information about a connection, calculate the respective
616  * hash we would use for the 'connections_map'.
617  *
618  * @param hash resulting hash
619  * @param ri information about the connection
620  */
621 static void
622 hash_redirect_info (struct GNUNET_HashCode *hash,
623                     const struct RedirectInformation *ri)
624 {
625   char *off;
626
627   memset (hash, 0, sizeof (struct GNUNET_HashCode));
628   /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
629      so we put the IP address in there (and hope for few collisions) */
630   off = (char*) hash;
631   switch (ri->remote_address.af)
632   {
633   case AF_INET:
634     memcpy (off, &ri->remote_address.address.ipv4, sizeof (struct in_addr));
635     off += sizeof (struct in_addr);
636     break;
637   case AF_INET6:
638     memcpy (off, &ri->remote_address.address.ipv6, sizeof (struct in6_addr));
639     off += sizeof (struct in_addr);
640     break;
641   default:
642     GNUNET_assert (0);
643   }
644   memcpy (off, &ri->remote_address.port, sizeof (uint16_t));
645   off += sizeof (uint16_t);
646   switch (ri->local_address.af)
647   {
648   case AF_INET:
649     memcpy (off, &ri->local_address.address.ipv4, sizeof (struct in_addr));
650     off += sizeof (struct in_addr);
651     break;
652   case AF_INET6:
653     memcpy (off, &ri->local_address.address.ipv6, sizeof (struct in6_addr));
654     off += sizeof (struct in_addr);
655     break;
656   default:
657     GNUNET_assert (0);
658   }
659   memcpy (off, &ri->local_address.port, sizeof (uint16_t));
660   off += sizeof (uint16_t);
661   memcpy (off, &ri->remote_address.proto, sizeof (uint8_t));
662   /* off += sizeof (uint8_t); */
663 }
664
665
666 /**
667  * Get our connection tracking state.  Warns if it does not exists,
668  * refreshes the timestamp if it does exist.
669  *
670  * @param af address family
671  * @param protocol IPPROTO_UDP or IPPROTO_TCP
672  * @param destination_ip target IP
673  * @param destination_port target port
674  * @param local_ip local IP
675  * @param local_port local port
676  * @param state_key set to hash's state if non-NULL
677  * @return NULL if we have no tracking information for this tuple
678  */
679 static struct TunnelState *
680 get_redirect_state (int af,
681                     int protocol,               
682                     const void *destination_ip,
683                     uint16_t destination_port,
684                     const void *local_ip,
685                     uint16_t local_port,
686                     struct GNUNET_HashCode *state_key)
687 {
688   struct RedirectInformation ri;
689   struct GNUNET_HashCode key;
690   struct TunnelState *state;
691
692   if ( ( (af == AF_INET) && (protocol == IPPROTO_ICMP) ) ||
693        ( (af == AF_INET6) && (protocol == IPPROTO_ICMPV6) ) )
694   {
695     /* ignore ports */
696     destination_port = 0;
697     local_port = 0;
698   }
699   ri.remote_address.af = af;
700   if (af == AF_INET)
701     ri.remote_address.address.ipv4 = *((struct in_addr*) destination_ip);
702   else
703     ri.remote_address.address.ipv6 = * ((struct in6_addr*) destination_ip);
704   ri.remote_address.port = destination_port;
705   ri.remote_address.proto = protocol;
706   ri.local_address.af = af;
707   if (af == AF_INET)
708     ri.local_address.address.ipv4 = *((struct in_addr*) local_ip);
709   else
710     ri.local_address.address.ipv6 = * ((struct in6_addr*) local_ip);
711   ri.local_address.port = local_port;
712   ri.local_address.proto = protocol;
713   hash_redirect_info (&key, &ri);
714   if (NULL != state_key)
715     *state_key = key;
716   state = GNUNET_CONTAINER_multihashmap_get (connections_map, &key);
717   if (NULL == state)
718     return NULL;
719   /* Mark this connection as freshly used */
720   if (NULL == state_key)
721     GNUNET_CONTAINER_heap_update_cost (connections_heap,
722                                        state->specifics.tcp_udp.heap_node,
723                                        GNUNET_TIME_absolute_get ().abs_value_us);
724   return state;
725 }
726
727
728 /**
729  * Given a service descriptor and a destination port, find the
730  * respective service entry.
731  *
732  * @param service_map map of services (TCP or UDP)
733  * @param desc service descriptor
734  * @param destination_port destination port
735  * @return NULL if we are not aware of such a service
736  */
737 static struct LocalService *
738 find_service (struct GNUNET_CONTAINER_MultiHashMap *service_map,
739               const struct GNUNET_HashCode *desc,
740               uint16_t destination_port)
741 {
742   char key[sizeof (struct GNUNET_HashCode) + sizeof (uint16_t)];
743
744   memcpy (&key[0], &destination_port, sizeof (uint16_t));
745   memcpy (&key[sizeof(uint16_t)], desc, sizeof (struct GNUNET_HashCode));
746   return GNUNET_CONTAINER_multihashmap_get (service_map,
747                                             (struct GNUNET_HashCode *) key);
748 }
749
750
751 /**
752  * Free memory associated with a service record.
753  *
754  * @param cls unused
755  * @param key service descriptor
756  * @param value service record to free
757  * @return GNUNET_OK
758  */
759 static int
760 free_service_record (void *cls,
761                      const struct GNUNET_HashCode *key,
762                      void *value)
763 {
764   struct LocalService *service = value;
765
766   GNUNET_free_non_null (service->name);
767   GNUNET_free (service);
768   return GNUNET_OK;
769 }
770
771
772 /**
773  * Given a service descriptor and a destination port, find the
774  * respective service entry.
775  *
776  * @param service_map map of services (TCP or UDP)
777  * @param name name of the service
778  * @param destination_port destination port
779  * @param service service information record to store (service->name will be set).
780  */
781 static void
782 store_service (struct GNUNET_CONTAINER_MultiHashMap *service_map,
783                const char *name,
784                uint16_t destination_port,
785                struct LocalService *service)
786 {
787   char key[sizeof (struct GNUNET_HashCode) + sizeof (uint16_t)];
788   struct GNUNET_HashCode desc;
789
790   GNUNET_CRYPTO_hash (name, strlen (name) + 1, &desc);
791   service->name = GNUNET_strdup (name);
792   memcpy (&key[0], &destination_port, sizeof (uint16_t));
793   memcpy (&key[sizeof(uint16_t)], &desc, sizeof (struct GNUNET_HashCode));
794   if (GNUNET_OK !=
795       GNUNET_CONTAINER_multihashmap_put (service_map,
796                                          (struct GNUNET_HashCode *) key,
797                                          service,
798                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
799   {
800     free_service_record (NULL, (struct GNUNET_HashCode *) key, service);
801     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
802                 _("Got duplicate service records for `%s:%u'\n"),
803                 name,
804                 (unsigned int) destination_port);
805   }
806 }
807
808
809 /**
810  * MESH is ready to receive a message for the tunnel.  Transmit it.
811  *
812  * @param cls the 'struct TunnelState'.
813  * @param size number of bytes available in buf
814  * @param buf where to copy the message
815  * @return number of bytes copied to buf
816  */
817 static size_t
818 send_to_peer_notify_callback (void *cls, size_t size, void *buf)
819 {
820   struct TunnelState *s = cls;
821   struct GNUNET_MESH_Tunnel *tunnel = s->tunnel;
822   struct TunnelMessageQueue *tnq;
823
824   s->th = NULL;
825   tnq = s->specifics.tcp_udp.head;
826   if (NULL == tnq)
827     return 0;
828   if (0 == size)
829   {
830     s->th = GNUNET_MESH_notify_transmit_ready (tunnel,
831                                                GNUNET_NO /* corking */,
832                                                GNUNET_TIME_UNIT_FOREVER_REL,
833                                                tnq->len,
834                                                &send_to_peer_notify_callback,
835                                                s);
836     return 0;
837   }
838   GNUNET_assert (size >= tnq->len);
839   memcpy (buf, tnq->payload, tnq->len);
840   size = tnq->len;
841   GNUNET_CONTAINER_DLL_remove (s->specifics.tcp_udp.head,
842                                s->specifics.tcp_udp.tail,
843                                tnq);
844   GNUNET_free (tnq);
845   if (NULL != (tnq = s->specifics.tcp_udp.head))
846     s->th = GNUNET_MESH_notify_transmit_ready (tunnel,
847                                                GNUNET_NO /* corking */,
848                                                GNUNET_TIME_UNIT_FOREVER_REL,
849                                                tnq->len,
850                                                &send_to_peer_notify_callback,
851                                                s);
852   GNUNET_STATISTICS_update (stats,
853                             gettext_noop ("# Bytes transmitted via mesh tunnels"),
854                             size, GNUNET_NO);
855   return size;
856 }
857
858
859 /**
860  * Send the given packet via the mesh tunnel.
861  *
862  * @param s tunnel destination
863  * @param tnq message to queue
864  */
865 static void
866 send_packet_to_mesh_tunnel (struct TunnelState *s,
867                             struct TunnelMessageQueue *tnq)
868 {
869   struct GNUNET_MESH_Tunnel *mesh_tunnel;
870
871   mesh_tunnel = s->tunnel;
872   GNUNET_assert (NULL != s);
873   GNUNET_CONTAINER_DLL_insert_tail (s->specifics.tcp_udp.head, s->specifics.tcp_udp.tail, tnq);
874   if (NULL == s->th)
875     s->th = GNUNET_MESH_notify_transmit_ready (mesh_tunnel,
876                                                GNUNET_NO /* cork */,
877                                                GNUNET_TIME_UNIT_FOREVER_REL,
878                                                tnq->len,
879                                                &send_to_peer_notify_callback,
880                                                s);
881 }
882
883
884 /**
885  * @brief Handles an ICMP packet received from the helper.
886  *
887  * @param icmp A pointer to the Packet
888  * @param pktlen number of bytes in 'icmp'
889  * @param af address family (AFINET or AF_INET6)
890  * @param destination_ip destination IP-address of the IP packet (should
891  *                       be our local address)
892  * @param source_ip original source IP-address of the IP packet (should
893  *                       be the original destination address)
894  */
895 static void
896 icmp_from_helper (const struct GNUNET_TUN_IcmpHeader *icmp,
897                   size_t pktlen,
898                   int af,
899                   const void *destination_ip,
900                   const void *source_ip)
901 {
902   struct TunnelState *state;
903   struct TunnelMessageQueue *tnq;
904   struct GNUNET_EXIT_IcmpToVPNMessage *i2v;
905   const struct GNUNET_TUN_IPv4Header *ipv4;
906   const struct GNUNET_TUN_IPv6Header *ipv6;
907   const struct GNUNET_TUN_UdpHeader *udp;
908   size_t mlen;
909   uint16_t source_port;
910   uint16_t destination_port;
911   uint8_t protocol;
912
913   {
914     char sbuf[INET6_ADDRSTRLEN];
915     char dbuf[INET6_ADDRSTRLEN];
916     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
917                 "Received ICMP packet going from %s to %s\n",
918                 inet_ntop (af,
919                            source_ip,
920                            sbuf, sizeof (sbuf)),
921                 inet_ntop (af,
922                            destination_ip,
923                            dbuf, sizeof (dbuf)));
924   }
925   if (pktlen < sizeof (struct GNUNET_TUN_IcmpHeader))
926   {
927     /* blame kernel */
928     GNUNET_break (0);
929     return;
930   }
931
932   /* Find out if this is an ICMP packet in response to an existing
933      TCP/UDP packet and if so, figure out ports / protocol of the
934      existing session from the IP data in the ICMP payload */
935   source_port = 0;
936   destination_port = 0;
937   switch (af)
938   {
939   case AF_INET:
940     protocol = IPPROTO_ICMP;
941     switch (icmp->type)
942       {
943       case GNUNET_TUN_ICMPTYPE_ECHO_REPLY:
944       case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST:
945         break;
946       case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE:
947       case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH:
948       case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED:
949         if (pktlen <
950             sizeof (struct GNUNET_TUN_IcmpHeader) +
951             sizeof (struct GNUNET_TUN_IPv4Header) + 8)
952         {
953           /* blame kernel */
954           GNUNET_break (0);
955           return;
956         }
957         ipv4 = (const struct GNUNET_TUN_IPv4Header *) &icmp[1];
958         protocol = ipv4->protocol;
959         /* could be TCP or UDP, but both have the ports in the right
960            place, so that doesn't matter here */
961         udp = (const struct GNUNET_TUN_UdpHeader *) &ipv4[1];
962         /* swap ports, as they are from the original message */
963         destination_port = ntohs (udp->source_port);
964         source_port = ntohs (udp->destination_port);
965         /* throw away ICMP payload, won't be useful for the other side anyway */
966         pktlen = sizeof (struct GNUNET_TUN_IcmpHeader);
967         break;
968       default:
969         GNUNET_STATISTICS_update (stats,
970                                   gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
971                                   1, GNUNET_NO);
972         return;
973       }
974     break;
975   case AF_INET6:
976     protocol = IPPROTO_ICMPV6;
977     switch (icmp->type)
978       {
979       case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
980       case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
981       case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
982       case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM:
983         if (pktlen <
984             sizeof (struct GNUNET_TUN_IcmpHeader) +
985             sizeof (struct GNUNET_TUN_IPv6Header) + 8)
986         {
987           /* blame kernel */
988           GNUNET_break (0);
989           return;
990         }
991         ipv6 = (const struct GNUNET_TUN_IPv6Header *) &icmp[1];
992         protocol = ipv6->next_header;
993         /* could be TCP or UDP, but both have the ports in the right
994            place, so that doesn't matter here */
995         udp = (const struct GNUNET_TUN_UdpHeader *) &ipv6[1];
996         /* swap ports, as they are from the original message */
997         destination_port = ntohs (udp->source_port);
998         source_port = ntohs (udp->destination_port);
999         /* throw away ICMP payload, won't be useful for the other side anyway */
1000         pktlen = sizeof (struct GNUNET_TUN_IcmpHeader);
1001         break;
1002       case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
1003       case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY:
1004         break;
1005       default:
1006         GNUNET_STATISTICS_update (stats,
1007                                   gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
1008                                   1, GNUNET_NO);
1009         return;
1010       }
1011     break;
1012   default:
1013     GNUNET_assert (0);
1014   }
1015   switch (protocol)
1016   {
1017   case IPPROTO_ICMP:
1018     state = get_redirect_state (af, IPPROTO_ICMP,
1019                                 source_ip, 0,
1020                                 destination_ip, 0,
1021                                 NULL);
1022     break;
1023   case IPPROTO_ICMPV6:
1024     state = get_redirect_state (af, IPPROTO_ICMPV6,
1025                                 source_ip, 0,
1026                                 destination_ip, 0,
1027                                 NULL);
1028     break;
1029   case IPPROTO_UDP:
1030     state = get_redirect_state (af, IPPROTO_UDP,
1031                                 source_ip,
1032                                 source_port,
1033                                 destination_ip,
1034                                 destination_port,
1035                                 NULL);
1036     break;
1037   case IPPROTO_TCP:
1038     state = get_redirect_state (af, IPPROTO_TCP,
1039                                 source_ip,
1040                                 source_port,
1041                                 destination_ip,
1042                                 destination_port,
1043                                 NULL);
1044     break;
1045   default:
1046     GNUNET_STATISTICS_update (stats,
1047                               gettext_noop ("# ICMP packets dropped (not allowed)"),
1048                               1, GNUNET_NO);
1049     return;
1050   }
1051   if (NULL == state)
1052   {
1053     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1054                 _("ICMP Packet dropped, have no matching connection information\n"));
1055     return;
1056   }
1057   mlen = sizeof (struct GNUNET_EXIT_IcmpToVPNMessage) + pktlen - sizeof (struct GNUNET_TUN_IcmpHeader);
1058   tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueue) + mlen);
1059   tnq->payload = &tnq[1];
1060   tnq->len = mlen;
1061   i2v = (struct GNUNET_EXIT_IcmpToVPNMessage *) &tnq[1];
1062   i2v->header.size = htons ((uint16_t) mlen);
1063   i2v->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN);
1064   i2v->af = htonl (af);
1065   memcpy (&i2v->icmp_header,
1066           icmp,
1067           pktlen);
1068   send_packet_to_mesh_tunnel (state, tnq);
1069 }
1070
1071
1072 /**
1073  * @brief Handles an UDP packet received from the helper.
1074  *
1075  * @param udp A pointer to the Packet
1076  * @param pktlen number of bytes in 'udp'
1077  * @param af address family (AFINET or AF_INET6)
1078  * @param destination_ip destination IP-address of the IP packet (should
1079  *                       be our local address)
1080  * @param source_ip original source IP-address of the IP packet (should
1081  *                       be the original destination address)
1082  */
1083 static void
1084 udp_from_helper (const struct GNUNET_TUN_UdpHeader *udp,
1085                  size_t pktlen,
1086                  int af,
1087                  const void *destination_ip,
1088                  const void *source_ip)
1089 {
1090   struct TunnelState *state;
1091   struct TunnelMessageQueue *tnq;
1092   struct GNUNET_EXIT_UdpReplyMessage *urm;
1093   size_t mlen;
1094
1095   {
1096     char sbuf[INET6_ADDRSTRLEN];
1097     char dbuf[INET6_ADDRSTRLEN];
1098     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1099                 "Received UDP packet going from %s:%u to %s:%u\n",
1100                 inet_ntop (af,
1101                            source_ip,
1102                            sbuf, sizeof (sbuf)),
1103                 (unsigned int) ntohs (udp->source_port),
1104                 inet_ntop (af,
1105                            destination_ip,
1106                            dbuf, sizeof (dbuf)),
1107                 (unsigned int) ntohs (udp->destination_port));
1108   }
1109   if (pktlen < sizeof (struct GNUNET_TUN_UdpHeader))
1110   {
1111     /* blame kernel */
1112     GNUNET_break (0);
1113     return;
1114   }
1115   if (pktlen != ntohs (udp->len))
1116   {
1117     /* blame kernel */
1118     GNUNET_break (0);
1119     return;
1120   }
1121   state = get_redirect_state (af, IPPROTO_UDP,
1122                               source_ip,
1123                               ntohs (udp->source_port),
1124                               destination_ip,
1125                               ntohs (udp->destination_port),
1126                               NULL);
1127   if (NULL == state)
1128   {
1129     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1130                 _("UDP Packet dropped, have no matching connection information\n"));
1131     return;
1132   }
1133   mlen = sizeof (struct GNUNET_EXIT_UdpReplyMessage) + pktlen - sizeof (struct GNUNET_TUN_UdpHeader);
1134   tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueue) + mlen);
1135   tnq->payload = &tnq[1];
1136   tnq->len = mlen;
1137   urm = (struct GNUNET_EXIT_UdpReplyMessage *) &tnq[1];
1138   urm->header.size = htons ((uint16_t) mlen);
1139   urm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY);
1140   urm->source_port = htons (0);
1141   urm->destination_port = htons (0);
1142   memcpy (&urm[1],
1143           &udp[1],
1144           pktlen - sizeof (struct GNUNET_TUN_UdpHeader));
1145   send_packet_to_mesh_tunnel (state, tnq);
1146 }
1147
1148
1149 /**
1150  * @brief Handles a TCP packet received from the helper.
1151  *
1152  * @param tcp A pointer to the Packet
1153  * @param pktlen the length of the packet, including its TCP header
1154  * @param af address family (AFINET or AF_INET6)
1155  * @param destination_ip destination IP-address of the IP packet (should
1156  *                       be our local address)
1157  * @param source_ip original source IP-address of the IP packet (should
1158  *                       be the original destination address)
1159  */
1160 static void
1161 tcp_from_helper (const struct GNUNET_TUN_TcpHeader *tcp,
1162                  size_t pktlen,
1163                  int af,
1164                  const void *destination_ip,
1165                  const void *source_ip)
1166 {
1167   struct TunnelState *state;
1168   char buf[pktlen] GNUNET_ALIGN;
1169   struct GNUNET_TUN_TcpHeader *mtcp;
1170   struct GNUNET_EXIT_TcpDataMessage *tdm;
1171   struct TunnelMessageQueue *tnq;
1172   size_t mlen;
1173
1174   {
1175     char sbuf[INET6_ADDRSTRLEN];
1176     char dbuf[INET6_ADDRSTRLEN];
1177     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1178                 "Received TCP packet with %u bytes going from %s:%u to %s:%u\n",
1179                 pktlen - sizeof (struct GNUNET_TUN_TcpHeader),
1180                 inet_ntop (af,
1181                            source_ip,
1182                            sbuf, sizeof (sbuf)),
1183                 (unsigned int) ntohs (tcp->source_port),
1184                 inet_ntop (af,
1185                            destination_ip,
1186                            dbuf, sizeof (dbuf)),
1187                 (unsigned int) ntohs (tcp->destination_port));
1188   }
1189   if (pktlen < sizeof (struct GNUNET_TUN_TcpHeader))
1190   {
1191     /* blame kernel */
1192     GNUNET_break (0);
1193     return;
1194   }
1195   state = get_redirect_state (af, IPPROTO_TCP,
1196                               source_ip,
1197                               ntohs (tcp->source_port),
1198                               destination_ip,
1199                               ntohs (tcp->destination_port),
1200                               NULL);
1201   if (NULL == state)
1202   {
1203     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1204                 _("TCP Packet dropped, have no matching connection information\n"));
1205
1206     return;
1207   }
1208   /* mug port numbers and crc to avoid information leakage;
1209      sender will need to lookup the correct values anyway */
1210   memcpy (buf, tcp, pktlen);
1211   mtcp = (struct GNUNET_TUN_TcpHeader *) buf;
1212   mtcp->source_port = 0;
1213   mtcp->destination_port = 0;
1214   mtcp->crc = 0;
1215
1216   mlen = sizeof (struct GNUNET_EXIT_TcpDataMessage) + (pktlen - sizeof (struct GNUNET_TUN_TcpHeader));
1217   if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1218   {
1219     GNUNET_break (0);
1220     return;
1221   }
1222
1223   tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueue) + mlen);
1224   tnq->payload = &tnq[1];
1225   tnq->len = mlen;
1226   tdm = (struct GNUNET_EXIT_TcpDataMessage *) &tnq[1];
1227   tdm->header.size = htons ((uint16_t) mlen);
1228   tdm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN);
1229   tdm->reserved = htonl (0);
1230   memcpy (&tdm->tcp_header,
1231           buf,
1232           pktlen);
1233   send_packet_to_mesh_tunnel (state, tnq);
1234 }
1235
1236
1237 /**
1238  * Receive packets from the helper-process
1239  *
1240  * @param cls unused
1241  * @param client unsued
1242  * @param message message received from helper
1243  */
1244 static int
1245 message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED,
1246                const struct GNUNET_MessageHeader *message)
1247 {
1248   const struct GNUNET_TUN_Layer2PacketHeader *pkt_tun;
1249   size_t size;
1250
1251   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1252               "Got %u-byte message of type %u from gnunet-helper-exit\n",
1253               ntohs (message->size),
1254               ntohs (message->type));
1255   GNUNET_STATISTICS_update (stats,
1256                             gettext_noop ("# Packets received from TUN"),
1257                             1, GNUNET_NO);
1258   if (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER)
1259   {
1260     GNUNET_break (0);
1261     return GNUNET_OK;
1262   }
1263   size = ntohs (message->size);
1264   if (size < sizeof (struct GNUNET_TUN_Layer2PacketHeader) + sizeof (struct GNUNET_MessageHeader))
1265   {
1266     GNUNET_break (0);
1267     return GNUNET_OK;
1268   }
1269   GNUNET_STATISTICS_update (stats,
1270                             gettext_noop ("# Bytes received from TUN"),
1271                             size, GNUNET_NO);
1272   pkt_tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1];
1273   size -= sizeof (struct GNUNET_TUN_Layer2PacketHeader) + sizeof (struct GNUNET_MessageHeader);
1274   switch (ntohs (pkt_tun->proto))
1275   {
1276   case ETH_P_IPV4:
1277     {
1278       const struct GNUNET_TUN_IPv4Header *pkt4;
1279
1280       if (size < sizeof (struct GNUNET_TUN_IPv4Header))
1281       {
1282         /* Kernel to blame? */
1283         GNUNET_break (0);
1284         return GNUNET_OK;
1285       }
1286       pkt4 = (const struct GNUNET_TUN_IPv4Header *) &pkt_tun[1];
1287       if (size != ntohs (pkt4->total_length))
1288       {
1289         /* Kernel to blame? */
1290         GNUNET_break (0);
1291         return GNUNET_OK;
1292       }
1293       if (pkt4->header_length * 4 != sizeof (struct GNUNET_TUN_IPv4Header))
1294       {
1295         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1296                     _("IPv4 packet options received.  Ignored.\n"));
1297         return GNUNET_OK;
1298       }
1299
1300       size -= sizeof (struct GNUNET_TUN_IPv4Header);
1301       switch (pkt4->protocol)
1302       {
1303       case IPPROTO_UDP:
1304         udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt4[1], size,
1305                          AF_INET,
1306                          &pkt4->destination_address,
1307                          &pkt4->source_address);
1308         break;
1309       case IPPROTO_TCP:
1310         tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt4[1], size,
1311                          AF_INET,
1312                          &pkt4->destination_address,
1313                          &pkt4->source_address);
1314         break;
1315       case IPPROTO_ICMP:
1316         icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt4[1], size,
1317                           AF_INET,
1318                           &pkt4->destination_address,
1319                           &pkt4->source_address);
1320         break;
1321       default:
1322         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1323                     _("IPv4 packet with unsupported next header %u received.  Ignored.\n"),
1324                     (int) pkt4->protocol);
1325         return GNUNET_OK;
1326       }
1327     }
1328     break;
1329   case ETH_P_IPV6:
1330     {
1331       const struct GNUNET_TUN_IPv6Header *pkt6;
1332
1333       if (size < sizeof (struct GNUNET_TUN_IPv6Header))
1334       {
1335         /* Kernel to blame? */
1336         GNUNET_break (0);
1337         return GNUNET_OK;
1338       }
1339       pkt6 = (struct GNUNET_TUN_IPv6Header *) &pkt_tun[1];
1340       if (size != ntohs (pkt6->payload_length) + sizeof (struct GNUNET_TUN_IPv6Header))
1341       {
1342         /* Kernel to blame? */
1343         GNUNET_break (0);
1344         return GNUNET_OK;
1345       }
1346       size -= sizeof (struct GNUNET_TUN_IPv6Header);
1347       switch (pkt6->next_header)
1348       {
1349       case IPPROTO_UDP:
1350         udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt6[1], size,
1351                          AF_INET6,
1352                          &pkt6->destination_address,
1353                          &pkt6->source_address);
1354         break;
1355       case IPPROTO_TCP:
1356         tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt6[1], size,
1357                          AF_INET6,
1358                          &pkt6->destination_address,
1359                          &pkt6->source_address);
1360         break;
1361       case IPPROTO_ICMPV6:
1362         icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt6[1], size,
1363                           AF_INET6,
1364                           &pkt6->destination_address,
1365                           &pkt6->source_address);
1366         break;
1367       default:
1368         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1369                     _("IPv6 packet with unsupported next header %d received.  Ignored.\n"),
1370                     pkt6->next_header);
1371         return GNUNET_OK;
1372       }
1373     }
1374     break;
1375   default:
1376     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1377                 _("Packet from unknown protocol %u received.  Ignored.\n"),
1378                 ntohs (pkt_tun->proto));
1379     break;
1380   }
1381   return GNUNET_OK;
1382 }
1383
1384
1385 /**
1386  * We need to create a (unique) fresh local address (IP+port).
1387  * Fill one in.
1388  *
1389  * @param af desired address family
1390  * @param proto desired protocol (IPPROTO_UDP or IPPROTO_TCP)
1391  * @param local_address address to initialize
1392  */
1393 static void
1394 setup_fresh_address (int af,
1395                      uint8_t proto,
1396                      struct SocketAddress *local_address)
1397 {
1398   local_address->af = af;
1399   local_address->proto = (uint8_t) proto;
1400   /* default "local" port range is often 32768--61000,
1401      so we pick a random value in that range */ 
1402   if ( ( (af == AF_INET) && (proto == IPPROTO_ICMP) ) ||
1403        ( (af == AF_INET6) && (proto == IPPROTO_ICMPV6) ) )
1404     local_address->port = 0;
1405   else
1406     local_address->port
1407       = (uint16_t) 32768 + GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
1408                                                      28232);
1409   switch (af)
1410   {
1411   case AF_INET:
1412     {
1413       struct in_addr addr;
1414       struct in_addr mask;
1415       struct in_addr rnd;
1416
1417       addr = exit_ipv4addr;
1418       mask = exit_ipv4mask;
1419       if (0 == ~mask.s_addr)
1420       {
1421         /* only one valid IP anyway */
1422         local_address->address.ipv4 = addr;
1423         return;
1424       }
1425       /* Given 192.168.0.1/255.255.0.0, we want a mask
1426          of '192.168.255.255', thus:  */
1427       mask.s_addr = addr.s_addr | ~mask.s_addr;
1428       /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
1429       do
1430         {
1431           rnd.s_addr = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
1432                                                  UINT32_MAX);   
1433           local_address->address.ipv4.s_addr = (addr.s_addr | rnd.s_addr) & mask.s_addr;
1434         }
1435       while ( (local_address->address.ipv4.s_addr == addr.s_addr) ||
1436               (local_address->address.ipv4.s_addr == mask.s_addr) );
1437     }
1438     break;
1439   case AF_INET6:
1440     {
1441       struct in6_addr addr;
1442       struct in6_addr mask;
1443       struct in6_addr rnd;
1444       int i;
1445
1446       addr = exit_ipv6addr;
1447       GNUNET_assert (ipv6prefix < 128);
1448       if (ipv6prefix == 127)
1449       {
1450         /* only one valid IP anyway */
1451         local_address->address.ipv6 = addr;
1452         return;
1453       }
1454       /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
1455          thus: */
1456       mask = addr;
1457       for (i=127;i>=ipv6prefix;i--)
1458         mask.s6_addr[i / 8] |= (1 << (i % 8));
1459
1460       /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */
1461       do
1462         {
1463           for (i=0;i<16;i++)
1464           {
1465             rnd.s6_addr[i] = (unsigned char) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
1466                                                                        256);
1467             local_address->address.ipv6.s6_addr[i]
1468               = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
1469           }
1470         }
1471       while ( (0 == memcmp (&local_address->address.ipv6,
1472                             &addr,
1473                             sizeof (struct in6_addr))) ||
1474               (0 == memcmp (&local_address->address.ipv6,
1475                             &mask,
1476                             sizeof (struct in6_addr))) );
1477     }
1478     break;
1479   default:
1480     GNUNET_assert (0);
1481   }
1482 }
1483
1484
1485 /**
1486  * We are starting a fresh connection (TCP or UDP) and need
1487  * to pick a source port and IP address (within the correct
1488  * range and address family) to associate replies with the
1489  * connection / correct mesh tunnel.  This function generates
1490  * a "fresh" source IP and source port number for a connection
1491  * After picking a good source address, this function sets up
1492  * the state in the 'connections_map' and 'connections_heap'
1493  * to allow finding the state when needed later.  The function
1494  * also makes sure that we remain within memory limits by
1495  * cleaning up 'old' states.
1496  *
1497  * @param state skeleton state to setup a record for; should
1498  *              'state->specifics.tcp_udp.ri.remote_address' filled in so that
1499  *              this code can determine which AF/protocol is
1500  *              going to be used (the 'tunnel' should also
1501  *              already be set); after calling this function,
1502  *              heap_node and the local_address will be
1503  *              also initialized (heap_node != NULL can be
1504  *              used to test if a state has been fully setup).
1505  */
1506 static void
1507 setup_state_record (struct TunnelState *state)
1508 {
1509   struct GNUNET_HashCode key;
1510   struct TunnelState *s;
1511
1512   /* generate fresh, unique address */
1513   do
1514   {
1515     if (NULL == state->specifics.tcp_udp.serv)
1516       setup_fresh_address (state->specifics.tcp_udp.ri.remote_address.af,
1517                            state->specifics.tcp_udp.ri.remote_address.proto,
1518                            &state->specifics.tcp_udp.ri.local_address);
1519     else
1520       setup_fresh_address (state->specifics.tcp_udp.serv->address.af,
1521                            state->specifics.tcp_udp.serv->address.proto,
1522                            &state->specifics.tcp_udp.ri.local_address);
1523   } while (NULL != get_redirect_state (state->specifics.tcp_udp.ri.remote_address.af,
1524                                        state->specifics.tcp_udp.ri.remote_address.proto,
1525                                        &state->specifics.tcp_udp.ri.remote_address.address,
1526                                        state->specifics.tcp_udp.ri.remote_address.port,
1527                                        &state->specifics.tcp_udp.ri.local_address.address,
1528                                        state->specifics.tcp_udp.ri.local_address.port,
1529                                        &key));
1530   {
1531     char buf[INET6_ADDRSTRLEN];
1532     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1533                 "Picked local address %s:%u for new connection\n",
1534                 inet_ntop (state->specifics.tcp_udp.ri.local_address.af,
1535                            &state->specifics.tcp_udp.ri.local_address.address,
1536                            buf, sizeof (buf)),
1537                 (unsigned int) state->specifics.tcp_udp.ri.local_address.port);
1538   }
1539   state->specifics.tcp_udp.state_key = key;
1540   GNUNET_assert (GNUNET_OK ==
1541                  GNUNET_CONTAINER_multihashmap_put (connections_map,
1542                                                     &key, state,
1543                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1544   state->specifics.tcp_udp.heap_node = GNUNET_CONTAINER_heap_insert (connections_heap,
1545                                                    state,
1546                                                    GNUNET_TIME_absolute_get ().abs_value_us);
1547   while (GNUNET_CONTAINER_heap_get_size (connections_heap) > max_connections)
1548   {
1549     s = GNUNET_CONTAINER_heap_remove_root (connections_heap);
1550     GNUNET_assert (state != s);
1551     s->specifics.tcp_udp.heap_node = NULL;
1552     GNUNET_MESH_tunnel_destroy (s->tunnel);
1553     GNUNET_assert (GNUNET_OK ==
1554                    GNUNET_CONTAINER_multihashmap_remove (connections_map,
1555                                                          &s->specifics.tcp_udp.state_key,
1556                                                          s));
1557     GNUNET_free (s);
1558   }
1559 }
1560
1561
1562 /**
1563  * Prepare an IPv4 packet for transmission via the TUN interface.
1564  * Initializes the IP header and calculates checksums (IP+UDP/TCP).
1565  * For UDP, the UDP header will be fully created, whereas for TCP
1566  * only the ports and checksum will be filled in.  So for TCP,
1567  * a skeleton TCP header must be part of the provided payload.
1568  *
1569  * @param payload payload of the packet (starting with UDP payload or
1570  *                TCP header, depending on protocol)
1571  * @param payload_length number of bytes in 'payload'
1572  * @param protocol IPPROTO_UDP or IPPROTO_TCP
1573  * @param tcp_header skeleton of the TCP header, NULL for UDP
1574  * @param src_address source address to use (IP and port)
1575  * @param dst_address destination address to use (IP and port)
1576  * @param pkt4 where to write the assembled packet; must
1577  *        contain enough space for the IP header, UDP/TCP header
1578  *        AND the payload
1579  */
1580 static void
1581 prepare_ipv4_packet (const void *payload, size_t payload_length,
1582                      int protocol,
1583                      const struct GNUNET_TUN_TcpHeader *tcp_header,
1584                      const struct SocketAddress *src_address,
1585                      const struct SocketAddress *dst_address,
1586                      struct GNUNET_TUN_IPv4Header *pkt4)
1587 {
1588   size_t len;
1589
1590   len = payload_length;
1591   switch (protocol)
1592   {
1593   case IPPROTO_UDP:
1594     len += sizeof (struct GNUNET_TUN_UdpHeader);
1595     break;
1596   case IPPROTO_TCP:
1597     len += sizeof (struct GNUNET_TUN_TcpHeader);
1598     GNUNET_assert (NULL != tcp_header);
1599     break;
1600   default:
1601     GNUNET_break (0);
1602     return;
1603   }
1604   if (len + sizeof (struct GNUNET_TUN_IPv4Header) > UINT16_MAX)
1605   {
1606     GNUNET_break (0);
1607     return;
1608   }
1609
1610   GNUNET_TUN_initialize_ipv4_header (pkt4,
1611                                      protocol,
1612                                      len,
1613                                      &src_address->address.ipv4,
1614                                      &dst_address->address.ipv4);
1615   switch (protocol)
1616   {
1617   case IPPROTO_UDP:
1618     {
1619       struct GNUNET_TUN_UdpHeader *pkt4_udp = (struct GNUNET_TUN_UdpHeader *) &pkt4[1];
1620
1621       pkt4_udp->source_port = htons (src_address->port);
1622       pkt4_udp->destination_port = htons (dst_address->port);
1623       pkt4_udp->len = htons ((uint16_t) payload_length);
1624       GNUNET_TUN_calculate_udp4_checksum (pkt4,
1625                                           pkt4_udp,
1626                                           payload, payload_length);
1627       memcpy (&pkt4_udp[1], payload, payload_length);
1628     }
1629     break;
1630   case IPPROTO_TCP:
1631     {
1632       struct GNUNET_TUN_TcpHeader *pkt4_tcp = (struct GNUNET_TUN_TcpHeader *) &pkt4[1];
1633
1634       *pkt4_tcp = *tcp_header;
1635       pkt4_tcp->source_port = htons (src_address->port);
1636       pkt4_tcp->destination_port = htons (dst_address->port);
1637       GNUNET_TUN_calculate_tcp4_checksum (pkt4,
1638                                           pkt4_tcp,
1639                                           payload,
1640                                           payload_length);
1641       memcpy (&pkt4_tcp[1], payload, payload_length);
1642     }
1643     break;
1644   default:
1645     GNUNET_assert (0);
1646   }
1647 }
1648
1649
1650 /**
1651  * Prepare an IPv6 packet for transmission via the TUN interface.
1652  * Initializes the IP header and calculates checksums (IP+UDP/TCP).
1653  * For UDP, the UDP header will be fully created, whereas for TCP
1654  * only the ports and checksum will be filled in.  So for TCP,
1655  * a skeleton TCP header must be part of the provided payload.
1656  *
1657  * @param payload payload of the packet (starting with UDP payload or
1658  *                TCP header, depending on protocol)
1659  * @param payload_length number of bytes in 'payload'
1660  * @param protocol IPPROTO_UDP or IPPROTO_TCP
1661  * @param tcp_header skeleton TCP header data to send, NULL for UDP
1662  * @param src_address source address to use (IP and port)
1663  * @param dst_address destination address to use (IP and port)
1664  * @param pkt6 where to write the assembled packet; must
1665  *        contain enough space for the IP header, UDP/TCP header
1666  *        AND the payload
1667  */
1668 static void
1669 prepare_ipv6_packet (const void *payload, size_t payload_length,
1670                      int protocol,
1671                      const struct GNUNET_TUN_TcpHeader *tcp_header,
1672                      const struct SocketAddress *src_address,
1673                      const struct SocketAddress *dst_address,
1674                      struct GNUNET_TUN_IPv6Header *pkt6)
1675 {
1676   size_t len;
1677
1678   len = payload_length;
1679   switch (protocol)
1680   {
1681   case IPPROTO_UDP:
1682     len += sizeof (struct GNUNET_TUN_UdpHeader);
1683     break;
1684   case IPPROTO_TCP:
1685     len += sizeof (struct GNUNET_TUN_TcpHeader);
1686     break;
1687   default:
1688     GNUNET_break (0);
1689     return;
1690   }
1691   if (len > UINT16_MAX)
1692   {
1693     GNUNET_break (0);
1694     return;
1695   }
1696
1697   GNUNET_TUN_initialize_ipv6_header (pkt6,
1698                                      protocol,
1699                                      len,                               
1700                                      &src_address->address.ipv6,
1701                                      &dst_address->address.ipv6);
1702
1703   switch (protocol)
1704   {
1705   case IPPROTO_UDP:
1706     {
1707       struct GNUNET_TUN_UdpHeader *pkt6_udp = (struct GNUNET_TUN_UdpHeader *) &pkt6[1];
1708
1709       pkt6_udp->source_port = htons (src_address->port);
1710       pkt6_udp->destination_port = htons (dst_address->port);
1711       pkt6_udp->len = htons ((uint16_t) payload_length);
1712       GNUNET_TUN_calculate_udp6_checksum (pkt6,
1713                                           pkt6_udp,
1714                                           payload,
1715                                           payload_length);
1716       memcpy (&pkt6_udp[1], payload, payload_length);
1717     }
1718     break;
1719   case IPPROTO_TCP:
1720     {
1721       struct GNUNET_TUN_TcpHeader *pkt6_tcp = (struct GNUNET_TUN_TcpHeader *) &pkt6[1];
1722
1723       /* memcpy first here as some TCP header fields are initialized this way! */
1724       *pkt6_tcp = *tcp_header;
1725       pkt6_tcp->source_port = htons (src_address->port);
1726       pkt6_tcp->destination_port = htons (dst_address->port);
1727       GNUNET_TUN_calculate_tcp6_checksum (pkt6,
1728                                           pkt6_tcp,
1729                                           payload,
1730                                           payload_length);
1731       memcpy (&pkt6_tcp[1], payload, payload_length);
1732     }
1733     break;
1734   default:
1735     GNUNET_assert (0);
1736     break;
1737   }
1738 }
1739
1740
1741 /**
1742  * Send a TCP packet via the TUN interface.
1743  *
1744  * @param destination_address IP and port to use for the TCP packet's destination
1745  * @param source_address IP and port to use for the TCP packet's source
1746  * @param tcp_header header template to use
1747  * @param payload payload of the TCP packet
1748  * @param payload_length number of bytes in 'payload'
1749  */
1750 static void
1751 send_tcp_packet_via_tun (const struct SocketAddress *destination_address,
1752                          const struct SocketAddress *source_address,
1753                          const struct GNUNET_TUN_TcpHeader *tcp_header,
1754                          const void *payload, size_t payload_length)
1755 {
1756   size_t len;
1757
1758   GNUNET_STATISTICS_update (stats,
1759                             gettext_noop ("# TCP packets sent via TUN"),
1760                             1, GNUNET_NO);
1761   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1762               "Sending packet with %u bytes TCP payload via TUN\n",
1763               (unsigned int) payload_length);
1764   len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader);
1765   switch (source_address->af)
1766   {
1767   case AF_INET:
1768     len += sizeof (struct GNUNET_TUN_IPv4Header);
1769     break;
1770   case AF_INET6:
1771     len += sizeof (struct GNUNET_TUN_IPv6Header);
1772     break;
1773   default:
1774     GNUNET_break (0);
1775     return;
1776   }
1777   len += sizeof (struct GNUNET_TUN_TcpHeader);
1778   len += payload_length;
1779   if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1780   {
1781     GNUNET_break (0);
1782     return;
1783   }
1784   {
1785     char buf[len] GNUNET_ALIGN;
1786     struct GNUNET_MessageHeader *hdr;
1787     struct GNUNET_TUN_Layer2PacketHeader *tun;
1788
1789     hdr = (struct GNUNET_MessageHeader *) buf;
1790     hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1791     hdr->size = htons (len);
1792     tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1793     tun->flags = htons (0);
1794     switch (source_address->af)
1795     {
1796     case AF_INET:
1797       {
1798         struct GNUNET_TUN_IPv4Header * ipv4 = (struct GNUNET_TUN_IPv4Header*) &tun[1];
1799         
1800         tun->proto = htons (ETH_P_IPV4);
1801         prepare_ipv4_packet (payload, payload_length,
1802                              IPPROTO_TCP,
1803                              tcp_header,
1804                              source_address,
1805                              destination_address,
1806                              ipv4);
1807       }
1808       break;
1809     case AF_INET6:
1810       {
1811         struct GNUNET_TUN_IPv6Header * ipv6 = (struct GNUNET_TUN_IPv6Header*) &tun[1];
1812         
1813         tun->proto = htons (ETH_P_IPV6);
1814         prepare_ipv6_packet (payload, payload_length,
1815                              IPPROTO_TCP,
1816                              tcp_header,
1817                              source_address,
1818                              destination_address,
1819                              ipv6);
1820       }
1821       break;    
1822     default:
1823       GNUNET_assert (0);
1824       break;
1825     }
1826     if (NULL != helper_handle)
1827       (void) GNUNET_HELPER_send (helper_handle,
1828                                  (const struct GNUNET_MessageHeader*) buf,
1829                                  GNUNET_YES,
1830                                  NULL, NULL);
1831   }
1832 }
1833
1834
1835 /**
1836  * Process a request via mesh to send a request to a TCP service
1837  * offered by this system.
1838  *
1839  * @param cls closure, NULL
1840  * @param tunnel connection to the other end
1841  * @param tunnel_ctx pointer to our 'struct TunnelState *'
1842  * @param message the actual message
1843  *
1844  * @return GNUNET_OK to keep the connection open,
1845  *         GNUNET_SYSERR to close it (signal serious error)
1846  */
1847 static int
1848 receive_tcp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1849                      void **tunnel_ctx GNUNET_UNUSED,
1850                      const struct GNUNET_MessageHeader *message)
1851 {
1852   struct TunnelState *state = *tunnel_ctx;
1853   const struct GNUNET_EXIT_TcpServiceStartMessage *start;
1854   uint16_t pkt_len = ntohs (message->size);
1855
1856   if (NULL == state)
1857   {
1858     GNUNET_break_op (0);
1859     return GNUNET_SYSERR;
1860   }
1861   if (GNUNET_YES == state->is_dns)
1862   {
1863     GNUNET_break_op (0);
1864     return GNUNET_SYSERR;
1865   }
1866   if (GNUNET_SYSERR == state->is_dns)
1867   {
1868     /* tunnel is UDP/TCP from now on */
1869     state->is_dns = GNUNET_NO;
1870   }
1871   GNUNET_STATISTICS_update (stats,
1872                             gettext_noop ("# TCP service creation requests received via mesh"),
1873                             1, GNUNET_NO);
1874   GNUNET_STATISTICS_update (stats,
1875                             gettext_noop ("# Bytes received from MESH"),
1876                             pkt_len, GNUNET_NO);
1877   /* check that we got at least a valid header */
1878   if (pkt_len < sizeof (struct GNUNET_EXIT_TcpServiceStartMessage))
1879   {
1880     GNUNET_break_op (0);
1881     return GNUNET_SYSERR;
1882   }
1883   start = (const struct GNUNET_EXIT_TcpServiceStartMessage*) message;
1884   pkt_len -= sizeof (struct GNUNET_EXIT_TcpServiceStartMessage);
1885   if ( (NULL != state->specifics.tcp_udp.serv) ||
1886        (NULL != state->specifics.tcp_udp.heap_node) )
1887   {
1888     GNUNET_break_op (0);
1889     return GNUNET_SYSERR;
1890   }
1891   if (start->tcp_header.off * 4 < sizeof (struct GNUNET_TUN_TcpHeader))
1892   {
1893     GNUNET_break_op (0);
1894     return GNUNET_SYSERR;
1895   }
1896   GNUNET_break_op (ntohl (start->reserved) == 0);
1897   /* setup fresh connection */
1898   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1899               "Received data from %s for forwarding to TCP service %s on port %u\n",
1900               GNUNET_i2s (&state->peer),
1901               GNUNET_h2s (&start->service_descriptor),
1902               (unsigned int) ntohs (start->tcp_header.destination_port));
1903   if (NULL == (state->specifics.tcp_udp.serv = find_service (tcp_services, &start->service_descriptor,
1904                                                              ntohs (start->tcp_header.destination_port))))
1905   {
1906     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1907                 _("No service found for %s on port %d!\n"),
1908                 "TCP",
1909                 ntohs (start->tcp_header.destination_port));
1910     GNUNET_STATISTICS_update (stats,
1911                               gettext_noop ("# TCP requests dropped (no such service)"),
1912                               1, GNUNET_NO);
1913     return GNUNET_SYSERR;
1914   }
1915   state->specifics.tcp_udp.ri.remote_address = state->specifics.tcp_udp.serv->address;
1916   setup_state_record (state);
1917   send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1918                            &state->specifics.tcp_udp.ri.local_address,
1919                            &start->tcp_header,
1920                            &start[1], pkt_len);
1921   return GNUNET_YES;
1922 }
1923
1924
1925 /**
1926  * Process a request to forward TCP data to the Internet via this peer.
1927  *
1928  * @param cls closure, NULL
1929  * @param tunnel connection to the other end
1930  * @param tunnel_ctx pointer to our 'struct TunnelState *'
1931  * @param message the actual message
1932  *
1933  * @return GNUNET_OK to keep the connection open,
1934  *         GNUNET_SYSERR to close it (signal serious error)
1935  */
1936 static int
1937 receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1938                     void **tunnel_ctx GNUNET_UNUSED,
1939                     const struct GNUNET_MessageHeader *message)
1940 {
1941   struct TunnelState *state = *tunnel_ctx;
1942   const struct GNUNET_EXIT_TcpInternetStartMessage *start;
1943   uint16_t pkt_len = ntohs (message->size);
1944   const struct in_addr *v4;
1945   const struct in6_addr *v6;
1946   const void *payload;
1947   int af;
1948
1949   if (NULL == state)
1950   {
1951     GNUNET_break_op (0);
1952     return GNUNET_SYSERR;
1953   }
1954   if (GNUNET_YES == state->is_dns)
1955   {
1956     GNUNET_break_op (0);
1957     return GNUNET_SYSERR;
1958   }
1959   if (GNUNET_SYSERR == state->is_dns)
1960   {
1961     /* tunnel is UDP/TCP from now on */
1962     state->is_dns = GNUNET_NO;
1963   }
1964   GNUNET_STATISTICS_update (stats,
1965                             gettext_noop ("# Bytes received from MESH"),
1966                             pkt_len, GNUNET_NO);
1967   GNUNET_STATISTICS_update (stats,
1968                             gettext_noop ("# TCP IP-exit creation requests received via mesh"),
1969                             1, GNUNET_NO);
1970   if (pkt_len < sizeof (struct GNUNET_EXIT_TcpInternetStartMessage))
1971   {
1972     GNUNET_break_op (0);
1973     return GNUNET_SYSERR;
1974   }
1975   start = (const struct GNUNET_EXIT_TcpInternetStartMessage*) message;
1976   pkt_len -= sizeof (struct GNUNET_EXIT_TcpInternetStartMessage);
1977   if ( (NULL != state->specifics.tcp_udp.serv) ||
1978        (NULL != state->specifics.tcp_udp.heap_node) )
1979   {
1980     GNUNET_break_op (0);
1981     return GNUNET_SYSERR;
1982   }
1983   if (start->tcp_header.off * 4 < sizeof (struct GNUNET_TUN_TcpHeader))
1984   {
1985     GNUNET_break_op (0);
1986     return GNUNET_SYSERR;
1987   }
1988   af = (int) ntohl (start->af);
1989   state->specifics.tcp_udp.ri.remote_address.af = af;
1990   switch (af)
1991   {
1992   case AF_INET:
1993     if (pkt_len < sizeof (struct in_addr))
1994     {
1995       GNUNET_break_op (0);
1996       return GNUNET_SYSERR;
1997     }
1998     if (! ipv4_exit)
1999     {
2000       GNUNET_break_op (0);
2001       return GNUNET_SYSERR;
2002     }
2003     v4 = (const struct in_addr*) &start[1];
2004     payload = &v4[1];
2005     pkt_len -= sizeof (struct in_addr);
2006     state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
2007     break;
2008   case AF_INET6:
2009     if (pkt_len < sizeof (struct in6_addr))
2010     {
2011       GNUNET_break_op (0);
2012       return GNUNET_SYSERR;
2013     }
2014     if (! ipv6_exit)
2015     {
2016       GNUNET_break_op (0);
2017       return GNUNET_SYSERR;
2018     }
2019     v6 = (const struct in6_addr*) &start[1];
2020     payload = &v6[1];
2021     pkt_len -= sizeof (struct in6_addr);
2022     state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
2023     break;
2024   default:
2025     GNUNET_break_op (0);
2026     return GNUNET_SYSERR;
2027   }
2028   {
2029     char buf[INET6_ADDRSTRLEN];
2030     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2031                 "Received data from %s for starting TCP stream to %s:%u\n",
2032                 GNUNET_i2s (&state->peer),
2033                 inet_ntop (af,
2034                            &state->specifics.tcp_udp.ri.remote_address.address,
2035                            buf, sizeof (buf)),
2036                 (unsigned int) ntohs (start->tcp_header.destination_port));
2037   }
2038   state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_TCP;
2039   state->specifics.tcp_udp.ri.remote_address.port = ntohs (start->tcp_header.destination_port);
2040   setup_state_record (state);
2041   send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2042                            &state->specifics.tcp_udp.ri.local_address,
2043                            &start->tcp_header,
2044                            payload, pkt_len);
2045   return GNUNET_YES;
2046 }
2047
2048
2049 /**
2050  * Process a request to forward TCP data on an established
2051  * connection via this peer.
2052  *
2053  * @param cls closure, NULL
2054  * @param tunnel connection to the other end
2055  * @param tunnel_ctx pointer to our 'struct TunnelState *'
2056  * @param message the actual message
2057  *
2058  * @return GNUNET_OK to keep the connection open,
2059  *         GNUNET_SYSERR to close it (signal serious error)
2060  */
2061 static int
2062 receive_tcp_data (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
2063                   void **tunnel_ctx GNUNET_UNUSED,
2064                   const struct GNUNET_MessageHeader *message)
2065 {
2066   struct TunnelState *state = *tunnel_ctx;
2067   const struct GNUNET_EXIT_TcpDataMessage *data;
2068   uint16_t pkt_len = ntohs (message->size);
2069
2070   if (GNUNET_YES == state->is_dns)
2071   {
2072     GNUNET_break_op (0);
2073     return GNUNET_SYSERR;
2074   }
2075   if (GNUNET_SYSERR == state->is_dns)
2076   {
2077     /* tunnel is UDP/TCP from now on */
2078     state->is_dns = GNUNET_NO;
2079   }
2080   GNUNET_STATISTICS_update (stats,
2081                             gettext_noop ("# Bytes received from MESH"),
2082                             pkt_len, GNUNET_NO);
2083   GNUNET_STATISTICS_update (stats,
2084                             gettext_noop ("# TCP data requests received via mesh"),
2085                             1, GNUNET_NO);
2086   if (pkt_len < sizeof (struct GNUNET_EXIT_TcpDataMessage))
2087   {
2088     GNUNET_break_op (0);
2089     return GNUNET_SYSERR;
2090   }
2091   data = (const struct GNUNET_EXIT_TcpDataMessage*) message;
2092   pkt_len -= sizeof (struct GNUNET_EXIT_TcpDataMessage);
2093   if ( (NULL == state) ||
2094        (NULL == state->specifics.tcp_udp.heap_node) )
2095   {
2096     /* connection should have been up! */
2097     GNUNET_STATISTICS_update (stats,
2098                               gettext_noop ("# TCP DATA requests dropped (no session)"),
2099                               1, GNUNET_NO);
2100     return GNUNET_SYSERR;
2101   }
2102   if (data->tcp_header.off * 4 < sizeof (struct GNUNET_TUN_TcpHeader))
2103   {
2104     GNUNET_break_op (0);
2105     return GNUNET_SYSERR;
2106   }
2107
2108   GNUNET_break_op (ntohl (data->reserved) == 0);
2109   {
2110     char buf[INET6_ADDRSTRLEN];
2111     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2112                 "Received additional %u bytes of data from %s for TCP stream to %s:%u\n",
2113                 pkt_len,
2114                 GNUNET_i2s (&state->peer),
2115                 inet_ntop (state->specifics.tcp_udp.ri.remote_address.af,
2116                            &state->specifics.tcp_udp.ri.remote_address.address,
2117                            buf, sizeof (buf)),
2118                 (unsigned int) state->specifics.tcp_udp.ri.remote_address.port);
2119   }
2120
2121   send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2122                            &state->specifics.tcp_udp.ri.local_address,
2123                            &data->tcp_header,
2124                            &data[1], pkt_len);
2125   return GNUNET_YES;
2126 }
2127
2128
2129 /**
2130  * Send an ICMP packet via the TUN interface.
2131  *
2132  * @param destination_address IP to use for the ICMP packet's destination
2133  * @param source_address IP to use for the ICMP packet's source
2134  * @param icmp_header ICMP header to send
2135  * @param payload payload of the ICMP packet (does NOT include ICMP header)
2136  * @param payload_length number of bytes of data in payload
2137  */
2138 static void
2139 send_icmp_packet_via_tun (const struct SocketAddress *destination_address,
2140                           const struct SocketAddress *source_address,
2141                           const struct GNUNET_TUN_IcmpHeader *icmp_header,
2142                           const void *payload, size_t payload_length)
2143 {
2144   size_t len;
2145   struct GNUNET_TUN_IcmpHeader *icmp;
2146
2147   GNUNET_STATISTICS_update (stats,
2148                             gettext_noop ("# ICMP packets sent via TUN"),
2149                             1, GNUNET_NO);
2150   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2151               "Sending packet with %u bytes ICMP payload via TUN\n",
2152               (unsigned int) payload_length);
2153   len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader);
2154   switch (destination_address->af)
2155   {
2156   case AF_INET:
2157     len += sizeof (struct GNUNET_TUN_IPv4Header);
2158     break;
2159   case AF_INET6:
2160     len += sizeof (struct GNUNET_TUN_IPv6Header);
2161     break;
2162   default:
2163     GNUNET_break (0);
2164     return;
2165   }
2166   len += sizeof (struct GNUNET_TUN_IcmpHeader);
2167   len += payload_length;
2168   if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
2169   {
2170     GNUNET_break (0);
2171     return;
2172   }
2173   {
2174     char buf[len] GNUNET_ALIGN;
2175     struct GNUNET_MessageHeader *hdr;
2176     struct GNUNET_TUN_Layer2PacketHeader *tun;
2177
2178     hdr= (struct GNUNET_MessageHeader *) buf;
2179     hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
2180     hdr->size = htons (len);
2181     tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
2182     tun->flags = htons (0);
2183     switch (source_address->af)
2184     {
2185     case AF_INET:
2186       {
2187         struct GNUNET_TUN_IPv4Header * ipv4 = (struct GNUNET_TUN_IPv4Header*) &tun[1];
2188         
2189         tun->proto = htons (ETH_P_IPV4);
2190         GNUNET_TUN_initialize_ipv4_header (ipv4,
2191                                            IPPROTO_ICMP,
2192                                            sizeof (struct GNUNET_TUN_IcmpHeader) + payload_length,
2193                                            &source_address->address.ipv4,
2194                                            &destination_address->address.ipv4);
2195         icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv4[1];
2196       }
2197       break;
2198     case AF_INET6:
2199       {
2200         struct GNUNET_TUN_IPv6Header * ipv6 = (struct GNUNET_TUN_IPv6Header*) &tun[1];
2201         
2202         tun->proto = htons (ETH_P_IPV6);
2203         GNUNET_TUN_initialize_ipv6_header (ipv6,
2204                                            IPPROTO_ICMPV6,
2205                                            sizeof (struct GNUNET_TUN_IcmpHeader) + payload_length,
2206                                            &source_address->address.ipv6,
2207                                            &destination_address->address.ipv6);
2208         icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv6[1];
2209       }
2210       break;    
2211     default:
2212       GNUNET_assert (0);
2213       break;
2214     }
2215     *icmp = *icmp_header;
2216     memcpy (&icmp[1],
2217             payload,
2218             payload_length);
2219     GNUNET_TUN_calculate_icmp_checksum (icmp,
2220                                         payload,
2221                                         payload_length);
2222     if (NULL != helper_handle)
2223       (void) GNUNET_HELPER_send (helper_handle,
2224                                  (const struct GNUNET_MessageHeader*) buf,
2225                                  GNUNET_YES,
2226                                  NULL, NULL);
2227   }
2228 }
2229
2230
2231 /**
2232  * Synthesize a plausible ICMP payload for an ICMPv4 error
2233  * response on the given tunnel.
2234  *
2235  * @param state tunnel information
2236  * @param ipp IPv6 header to fill in (ICMP payload)
2237  * @param udp "UDP" header to fill in (ICMP payload); might actually
2238  *            also be the first 8 bytes of the TCP header
2239  */
2240 static void
2241 make_up_icmpv4_payload (struct TunnelState *state,
2242                         struct GNUNET_TUN_IPv4Header *ipp,
2243                         struct GNUNET_TUN_UdpHeader *udp)
2244 {
2245   GNUNET_TUN_initialize_ipv4_header (ipp,
2246                                      state->specifics.tcp_udp.ri.remote_address.proto,
2247                                      sizeof (struct GNUNET_TUN_TcpHeader),
2248                                      &state->specifics.tcp_udp.ri.remote_address.address.ipv4,
2249                                      &state->specifics.tcp_udp.ri.local_address.address.ipv4);
2250   udp->source_port = htons (state->specifics.tcp_udp.ri.remote_address.port);
2251   udp->destination_port = htons (state->specifics.tcp_udp.ri.local_address.port);
2252   udp->len = htons (0);
2253   udp->crc = htons (0);
2254 }
2255
2256
2257 /**
2258  * Synthesize a plausible ICMP payload for an ICMPv6 error
2259  * response on the given tunnel.
2260  *
2261  * @param state tunnel information
2262  * @param ipp IPv6 header to fill in (ICMP payload)
2263  * @param udp "UDP" header to fill in (ICMP payload); might actually
2264  *            also be the first 8 bytes of the TCP header
2265  */
2266 static void
2267 make_up_icmpv6_payload (struct TunnelState *state,
2268                         struct GNUNET_TUN_IPv6Header *ipp,
2269                         struct GNUNET_TUN_UdpHeader *udp)
2270 {
2271   GNUNET_TUN_initialize_ipv6_header (ipp,
2272                                      state->specifics.tcp_udp.ri.remote_address.proto,
2273                                      sizeof (struct GNUNET_TUN_TcpHeader),
2274                                      &state->specifics.tcp_udp.ri.remote_address.address.ipv6,
2275                                      &state->specifics.tcp_udp.ri.local_address.address.ipv6);
2276   udp->source_port = htons (state->specifics.tcp_udp.ri.remote_address.port);
2277   udp->destination_port = htons (state->specifics.tcp_udp.ri.local_address.port);
2278   udp->len = htons (0);
2279   udp->crc = htons (0);
2280 }
2281
2282
2283 /**
2284  * Process a request to forward ICMP data to the Internet via this peer.
2285  *
2286  * @param cls closure, NULL
2287  * @param tunnel connection to the other end
2288  * @param tunnel_ctx pointer to our 'struct TunnelState *'
2289  * @param message the actual message
2290  *
2291  * @return GNUNET_OK to keep the connection open,
2292  *         GNUNET_SYSERR to close it (signal serious error)
2293  */
2294 static int
2295 receive_icmp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
2296                      void **tunnel_ctx GNUNET_UNUSED,
2297                      const struct GNUNET_MessageHeader *message)
2298 {
2299   struct TunnelState *state = *tunnel_ctx;
2300   const struct GNUNET_EXIT_IcmpInternetMessage *msg;
2301   uint16_t pkt_len = ntohs (message->size);
2302   const struct in_addr *v4;
2303   const struct in6_addr *v6;
2304   const void *payload;
2305   char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
2306   int af;
2307
2308   if (GNUNET_YES == state->is_dns)
2309   {
2310     GNUNET_break_op (0);
2311     return GNUNET_SYSERR;
2312   }
2313   if (GNUNET_SYSERR == state->is_dns)
2314   {
2315     /* tunnel is UDP/TCP from now on */
2316     state->is_dns = GNUNET_NO;
2317   }
2318   GNUNET_STATISTICS_update (stats,
2319                             gettext_noop ("# Bytes received from MESH"),
2320                             pkt_len, GNUNET_NO);
2321   GNUNET_STATISTICS_update (stats,
2322                             gettext_noop ("# ICMP IP-exit requests received via mesh"),
2323                             1, GNUNET_NO);
2324   if (pkt_len < sizeof (struct GNUNET_EXIT_IcmpInternetMessage))
2325   {
2326     GNUNET_break_op (0);
2327     return GNUNET_SYSERR;
2328   }
2329   msg = (const struct GNUNET_EXIT_IcmpInternetMessage*) message;
2330   pkt_len -= sizeof (struct GNUNET_EXIT_IcmpInternetMessage);
2331
2332   af = (int) ntohl (msg->af);
2333   if ( (NULL != state->specifics.tcp_udp.heap_node) &&
2334        (af != state->specifics.tcp_udp.ri.remote_address.af) )
2335   {
2336     /* other peer switched AF on this tunnel; not allowed */
2337     GNUNET_break_op (0);
2338     return GNUNET_SYSERR;
2339   }
2340
2341   switch (af)
2342   {
2343   case AF_INET:
2344     if (pkt_len < sizeof (struct in_addr))
2345     {
2346       GNUNET_break_op (0);
2347       return GNUNET_SYSERR;
2348     }
2349     if (! ipv4_exit)
2350     {
2351       GNUNET_break_op (0);
2352       return GNUNET_SYSERR;
2353     }
2354     v4 = (const struct in_addr*) &msg[1];
2355     payload = &v4[1];
2356     pkt_len -= sizeof (struct in_addr);
2357     state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
2358     if (NULL == state->specifics.tcp_udp.heap_node)
2359     {
2360       state->specifics.tcp_udp.ri.remote_address.af = af;
2361       state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMP;
2362       setup_state_record (state);
2363     }
2364     /* check that ICMP type is something we want to support
2365        and possibly make up payload! */
2366     switch (msg->icmp_header.type)
2367     {
2368     case GNUNET_TUN_ICMPTYPE_ECHO_REPLY:
2369     case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST:
2370       break;
2371     case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE:
2372     case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH:
2373     case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED:
2374       if (0 != pkt_len)
2375       {
2376         GNUNET_break_op (0);
2377         return GNUNET_SYSERR;
2378       }
2379       /* make up payload */
2380       {
2381         struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header *) buf;
2382         struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1];
2383
2384         GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
2385         pkt_len = sizeof (struct GNUNET_TUN_IPv4Header) + 8;
2386         make_up_icmpv4_payload (state,
2387                                 ipp,
2388                                 udp);
2389         payload = ipp;
2390       }
2391       break;
2392     default:
2393       GNUNET_break_op (0);
2394       GNUNET_STATISTICS_update (stats,
2395                                 gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
2396                                 1, GNUNET_NO);
2397       return GNUNET_SYSERR;
2398     }
2399     /* end AF_INET */
2400     break;
2401   case AF_INET6:
2402     if (pkt_len < sizeof (struct in6_addr))
2403     {
2404       GNUNET_break_op (0);
2405       return GNUNET_SYSERR;
2406     }
2407     if (! ipv6_exit)
2408     {
2409       GNUNET_break_op (0);
2410       return GNUNET_SYSERR;
2411     }
2412     v6 = (const struct in6_addr*) &msg[1];
2413     payload = &v6[1];
2414     pkt_len -= sizeof (struct in6_addr);
2415     state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
2416     if (NULL == state->specifics.tcp_udp.heap_node)
2417     {
2418       state->specifics.tcp_udp.ri.remote_address.af = af;
2419       state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMPV6;
2420       setup_state_record (state);
2421     }
2422     /* check that ICMP type is something we want to support
2423        and possibly make up payload! */
2424     switch (msg->icmp_header.type)
2425     {
2426     case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY:
2427     case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
2428       break;
2429     case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
2430     case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
2431     case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
2432     case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM:
2433       if (0 != pkt_len)
2434       {
2435         GNUNET_break_op (0);
2436         return GNUNET_SYSERR;
2437       }
2438       /* make up payload */
2439       {
2440         struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header *) buf;
2441         struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1];
2442
2443         GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
2444         pkt_len = sizeof (struct GNUNET_TUN_IPv6Header) + 8;
2445         make_up_icmpv6_payload (state,
2446                                 ipp,
2447                                 udp);
2448         payload = ipp;
2449       }
2450       break;
2451     default:
2452       GNUNET_break_op (0);
2453       GNUNET_STATISTICS_update (stats,
2454                                 gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
2455                                 1, GNUNET_NO);
2456       return GNUNET_SYSERR;
2457     }
2458     /* end AF_INET6 */
2459     break;
2460   default:
2461     /* bad AF */
2462     GNUNET_break_op (0);
2463     return GNUNET_SYSERR;
2464   }
2465
2466   {
2467     char buf[INET6_ADDRSTRLEN];
2468     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2469                 "Received ICMP data from %s for forwarding to %s\n",
2470                 GNUNET_i2s (&state->peer),
2471                 inet_ntop (af,
2472                            &state->specifics.tcp_udp.ri.remote_address.address,
2473                            buf, sizeof (buf)));
2474   }
2475   send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2476                             &state->specifics.tcp_udp.ri.local_address,
2477                             &msg->icmp_header,
2478                             payload, pkt_len);
2479   return GNUNET_YES;
2480 }
2481
2482
2483 /**
2484  * Setup ICMP payload for ICMP error messages. Called
2485  * for both IPv4 and IPv6 addresses.
2486  *
2487  * @param state context for creating the IP Packet
2488  * @param buf where to create the payload, has at least
2489  *       sizeof (struct GNUNET_TUN_IPv6Header) + 8 bytes
2490  * @return number of bytes of payload we created in buf
2491  */
2492 static uint16_t
2493 make_up_icmp_service_payload (struct TunnelState *state,
2494                               char *buf)
2495 {
2496   switch (state->specifics.tcp_udp.serv->address.af)
2497   {
2498   case AF_INET:
2499     {
2500       struct GNUNET_TUN_IPv4Header *ipv4;
2501       struct GNUNET_TUN_UdpHeader *udp;
2502
2503       ipv4 = (struct GNUNET_TUN_IPv4Header *)buf;
2504       udp = (struct GNUNET_TUN_UdpHeader *) &ipv4[1];
2505       make_up_icmpv4_payload (state,
2506                               ipv4,
2507                               udp);
2508       GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
2509       return sizeof (struct GNUNET_TUN_IPv4Header) + 8;
2510     }
2511     break;
2512   case AF_INET6:
2513     {
2514       struct GNUNET_TUN_IPv6Header *ipv6;
2515       struct GNUNET_TUN_UdpHeader *udp;
2516
2517       ipv6 = (struct GNUNET_TUN_IPv6Header *)buf;
2518       udp = (struct GNUNET_TUN_UdpHeader *) &ipv6[1];
2519       make_up_icmpv6_payload (state,
2520                               ipv6,
2521                               udp);
2522       GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
2523       return sizeof (struct GNUNET_TUN_IPv6Header) + 8;
2524     }
2525     break;
2526   default:
2527     GNUNET_break (0);
2528   }
2529   return 0;
2530 }
2531
2532
2533 /**
2534  * Process a request via mesh to send ICMP data to a service
2535  * offered by this system.
2536  *
2537  * @param cls closure, NULL
2538  * @param tunnel connection to the other end
2539  * @param tunnel_ctx pointer to our 'struct TunnelState *'
2540  * @param message the actual message
2541  *
2542  * @return GNUNET_OK to keep the connection open,
2543  *         GNUNET_SYSERR to close it (signal serious error)
2544  */
2545 static int
2546 receive_icmp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
2547                       void **tunnel_ctx,
2548                       const struct GNUNET_MessageHeader *message)
2549 {
2550   struct TunnelState *state = *tunnel_ctx;
2551   const struct GNUNET_EXIT_IcmpServiceMessage *msg;
2552   uint16_t pkt_len = ntohs (message->size);
2553   struct GNUNET_TUN_IcmpHeader icmp;
2554   char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
2555   const void *payload;
2556
2557   if (GNUNET_YES == state->is_dns)
2558   {
2559     GNUNET_break_op (0);
2560     return GNUNET_SYSERR;
2561   }
2562   if (GNUNET_SYSERR == state->is_dns)
2563   {
2564     /* tunnel is UDP/TCP from now on */
2565     state->is_dns = GNUNET_NO;
2566   }
2567   GNUNET_STATISTICS_update (stats,
2568                             gettext_noop ("# Bytes received from MESH"),
2569                             pkt_len, GNUNET_NO);
2570   GNUNET_STATISTICS_update (stats,
2571                             gettext_noop ("# ICMP service requests received via mesh"),
2572                             1, GNUNET_NO);
2573   /* check that we got at least a valid header */
2574   if (pkt_len < sizeof (struct GNUNET_EXIT_IcmpServiceMessage))
2575   {
2576     GNUNET_break_op (0);
2577     return GNUNET_SYSERR;
2578   }
2579   msg = (const struct GNUNET_EXIT_IcmpServiceMessage*) message;
2580   pkt_len -= sizeof (struct GNUNET_EXIT_IcmpServiceMessage);
2581   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2582               "Received data from %s for forwarding to ICMP service %s\n",
2583               GNUNET_i2s (&state->peer),
2584               GNUNET_h2s (&msg->service_descriptor));
2585   if (NULL == state->specifics.tcp_udp.serv)
2586   {
2587     /* first packet to service must not be ICMP (cannot determine service!) */
2588     GNUNET_break_op (0);
2589     return GNUNET_SYSERR;
2590   }
2591   icmp = msg->icmp_header;
2592   payload = &msg[1];
2593   state->specifics.tcp_udp.ri.remote_address = state->specifics.tcp_udp.serv->address;
2594   setup_state_record (state);
2595
2596   /* check that ICMP type is something we want to support,
2597      perform ICMP PT if needed ans possibly make up payload */
2598   switch (msg->af)
2599   {
2600   case AF_INET:
2601     switch (msg->icmp_header.type)
2602     {
2603     case GNUNET_TUN_ICMPTYPE_ECHO_REPLY:
2604       if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2605         icmp.type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY;
2606       break;
2607     case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST:
2608       if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2609         icmp.type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST;
2610       break;
2611     case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE:
2612       if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2613         icmp.type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE;
2614       if (0 != pkt_len)
2615       {
2616         GNUNET_break_op (0);
2617         return GNUNET_SYSERR;
2618       }
2619       payload = buf;
2620       pkt_len = make_up_icmp_service_payload (state, buf);
2621       break;
2622     case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED:
2623       if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2624         icmp.type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED;
2625       if (0 != pkt_len)
2626       {
2627         GNUNET_break_op (0);
2628         return GNUNET_SYSERR;
2629       }
2630       payload = buf;
2631       pkt_len = make_up_icmp_service_payload (state, buf);
2632       break;
2633     case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH:
2634       if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2635       {
2636         GNUNET_STATISTICS_update (stats,
2637                                   gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"),
2638                                   1, GNUNET_NO);
2639         return GNUNET_OK;
2640       }
2641       if (0 != pkt_len)
2642       {
2643         GNUNET_break_op (0);
2644         return GNUNET_SYSERR;
2645       }
2646       payload = buf;
2647       pkt_len = make_up_icmp_service_payload (state, buf);
2648       break;
2649     default:
2650       GNUNET_break_op (0);
2651       GNUNET_STATISTICS_update (stats,
2652                                 gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
2653                                 1, GNUNET_NO);
2654       return GNUNET_SYSERR;
2655     }
2656     /* end of AF_INET */
2657     break;
2658   case AF_INET6:
2659     switch (msg->icmp_header.type)
2660     {
2661     case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY:
2662       if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2663         icmp.type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY;
2664       break;
2665     case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
2666       if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2667         icmp.type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST;
2668       break;
2669     case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
2670       if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2671         icmp.type = GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE;
2672       if (0 != pkt_len)
2673       {
2674         GNUNET_break_op (0);
2675         return GNUNET_SYSERR;
2676       }
2677       payload = buf;
2678       pkt_len = make_up_icmp_service_payload (state, buf);
2679       break;
2680     case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
2681       if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2682         icmp.type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED;
2683       if (0 != pkt_len)
2684       {
2685         GNUNET_break_op (0);
2686         return GNUNET_SYSERR;
2687       }
2688       payload = buf;
2689       pkt_len = make_up_icmp_service_payload (state, buf);
2690       break;
2691     case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
2692     case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM:
2693       if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2694       {
2695         GNUNET_STATISTICS_update (stats,
2696                                   gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"),
2697                                   1, GNUNET_NO);
2698         return GNUNET_OK;
2699       }
2700       if (0 != pkt_len)
2701       {
2702         GNUNET_break_op (0);
2703         return GNUNET_SYSERR;
2704       }
2705       payload = buf;
2706       pkt_len = make_up_icmp_service_payload (state, buf);
2707       break;
2708     default:
2709       GNUNET_break_op (0);
2710       GNUNET_STATISTICS_update (stats,
2711                                 gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
2712                                 1, GNUNET_NO);
2713       return GNUNET_SYSERR;
2714     }
2715     /* end of AF_INET6 */
2716     break;
2717   default:
2718     GNUNET_break_op (0);
2719     return GNUNET_SYSERR;
2720   }
2721
2722   send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2723                             &state->specifics.tcp_udp.ri.local_address,
2724                             &icmp,
2725                             payload, pkt_len);
2726   return GNUNET_YES;
2727 }
2728
2729
2730 /**
2731  * Send a UDP packet via the TUN interface.
2732  *
2733  * @param destination_address IP and port to use for the UDP packet's destination
2734  * @param source_address IP and port to use for the UDP packet's source
2735  * @param payload payload of the UDP packet (does NOT include UDP header)
2736  * @param payload_length number of bytes of data in payload
2737  */
2738 static void
2739 send_udp_packet_via_tun (const struct SocketAddress *destination_address,
2740                          const struct SocketAddress *source_address,
2741                          const void *payload, size_t payload_length)
2742 {
2743   size_t len;
2744
2745   GNUNET_STATISTICS_update (stats,
2746                             gettext_noop ("# UDP packets sent via TUN"),
2747                             1, GNUNET_NO);
2748   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2749               "Sending packet with %u bytes UDP payload via TUN\n",
2750               (unsigned int) payload_length);
2751   len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader);
2752   switch (source_address->af)
2753   {
2754   case AF_INET:
2755     len += sizeof (struct GNUNET_TUN_IPv4Header);
2756     break;
2757   case AF_INET6:
2758     len += sizeof (struct GNUNET_TUN_IPv6Header);
2759     break;
2760   default:
2761     GNUNET_break (0);
2762     return;
2763   }
2764   len += sizeof (struct GNUNET_TUN_UdpHeader);
2765   len += payload_length;
2766   if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
2767   {
2768     GNUNET_break (0);
2769     return;
2770   }
2771   {
2772     char buf[len] GNUNET_ALIGN;
2773     struct GNUNET_MessageHeader *hdr;
2774     struct GNUNET_TUN_Layer2PacketHeader *tun;
2775
2776     hdr= (struct GNUNET_MessageHeader *) buf;
2777     hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
2778     hdr->size = htons (len);
2779     tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
2780     tun->flags = htons (0);
2781     switch (source_address->af)
2782     {
2783     case AF_INET:
2784       {
2785         struct GNUNET_TUN_IPv4Header * ipv4 = (struct GNUNET_TUN_IPv4Header*) &tun[1];
2786         
2787         tun->proto = htons (ETH_P_IPV4);
2788         prepare_ipv4_packet (payload, payload_length,
2789                              IPPROTO_UDP,
2790                              NULL,
2791                              source_address,
2792                              destination_address,
2793                              ipv4);
2794       }
2795       break;
2796     case AF_INET6:
2797       {
2798         struct GNUNET_TUN_IPv6Header * ipv6 = (struct GNUNET_TUN_IPv6Header*) &tun[1];
2799         
2800         tun->proto = htons (ETH_P_IPV6);
2801         prepare_ipv6_packet (payload, payload_length,
2802                              IPPROTO_UDP,
2803                              NULL,
2804                              source_address,
2805                              destination_address,
2806                              ipv6);
2807       }
2808       break;    
2809     default:
2810       GNUNET_assert (0);
2811       break;
2812     }
2813     if (NULL != helper_handle)
2814       (void) GNUNET_HELPER_send (helper_handle,
2815                                  (const struct GNUNET_MessageHeader*) buf,
2816                                  GNUNET_YES,
2817                                  NULL, NULL);
2818   }
2819 }
2820
2821
2822 /**
2823  * Process a request to forward UDP data to the Internet via this peer.
2824  *
2825  * @param cls closure, NULL
2826  * @param tunnel connection to the other end
2827  * @param tunnel_ctx pointer to our 'struct TunnelState *'
2828  * @param message the actual message
2829  *
2830  * @return GNUNET_OK to keep the connection open,
2831  *         GNUNET_SYSERR to close it (signal serious error)
2832  */
2833 static int
2834 receive_udp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
2835                     void **tunnel_ctx GNUNET_UNUSED,
2836                     const struct GNUNET_MessageHeader *message)
2837 {
2838   struct TunnelState *state = *tunnel_ctx;
2839   const struct GNUNET_EXIT_UdpInternetMessage *msg;
2840   uint16_t pkt_len = ntohs (message->size);
2841   const struct in_addr *v4;
2842   const struct in6_addr *v6;
2843   const void *payload;
2844   int af;
2845
2846   if (GNUNET_YES == state->is_dns)
2847   {
2848     GNUNET_break_op (0);
2849     return GNUNET_SYSERR;
2850   }
2851   if (GNUNET_SYSERR == state->is_dns)
2852   {
2853     /* tunnel is UDP/TCP from now on */
2854     state->is_dns = GNUNET_NO;
2855   }
2856   GNUNET_STATISTICS_update (stats,
2857                             gettext_noop ("# Bytes received from MESH"),
2858                             pkt_len, GNUNET_NO);
2859   GNUNET_STATISTICS_update (stats,
2860                             gettext_noop ("# UDP IP-exit requests received via mesh"),
2861                             1, GNUNET_NO);
2862   if (pkt_len < sizeof (struct GNUNET_EXIT_UdpInternetMessage))
2863   {
2864     GNUNET_break_op (0);
2865     return GNUNET_SYSERR;
2866   }
2867   msg = (const struct GNUNET_EXIT_UdpInternetMessage*) message;
2868   pkt_len -= sizeof (struct GNUNET_EXIT_UdpInternetMessage);
2869   af = (int) ntohl (msg->af);
2870   state->specifics.tcp_udp.ri.remote_address.af = af;
2871   switch (af)
2872   {
2873   case AF_INET:
2874     if (pkt_len < sizeof (struct in_addr))
2875     {
2876       GNUNET_break_op (0);
2877       return GNUNET_SYSERR;
2878     }
2879     if (! ipv4_exit)
2880     {
2881       GNUNET_break_op (0);
2882       return GNUNET_SYSERR;
2883     }
2884     v4 = (const struct in_addr*) &msg[1];
2885     payload = &v4[1];
2886     pkt_len -= sizeof (struct in_addr);
2887     state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
2888     break;
2889   case AF_INET6:
2890     if (pkt_len < sizeof (struct in6_addr))
2891     {
2892       GNUNET_break_op (0);
2893       return GNUNET_SYSERR;
2894     }
2895     if (! ipv6_exit)
2896     {
2897       GNUNET_break_op (0);
2898       return GNUNET_SYSERR;
2899     }
2900     v6 = (const struct in6_addr*) &msg[1];
2901     payload = &v6[1];
2902     pkt_len -= sizeof (struct in6_addr);
2903     state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
2904     break;
2905   default:
2906     GNUNET_break_op (0);
2907     return GNUNET_SYSERR;
2908   }
2909   {
2910     char buf[INET6_ADDRSTRLEN];
2911     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2912                 "Received data from %s for forwarding to UDP %s:%u\n",
2913                 GNUNET_i2s (&state->peer),
2914                 inet_ntop (af,
2915                            &state->specifics.tcp_udp.ri.remote_address.address,
2916                            buf, sizeof (buf)),
2917                 (unsigned int) ntohs (msg->destination_port));
2918   }
2919   state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_UDP;
2920   state->specifics.tcp_udp.ri.remote_address.port = msg->destination_port;
2921   if (NULL == state->specifics.tcp_udp.heap_node)
2922     setup_state_record (state);
2923   if (0 != ntohs (msg->source_port))
2924     state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
2925   send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2926                            &state->specifics.tcp_udp.ri.local_address,
2927                            payload, pkt_len);
2928   return GNUNET_YES;
2929 }
2930
2931
2932 /**
2933  * Process a request via mesh to send a request to a UDP service
2934  * offered by this system.
2935  *
2936  * @param cls closure, NULL
2937  * @param tunnel connection to the other end
2938  * @param tunnel_ctx pointer to our 'struct TunnelState *'
2939  * @param message the actual message
2940  *
2941  * @return GNUNET_OK to keep the connection open,
2942  *         GNUNET_SYSERR to close it (signal serious error)
2943  */
2944 static int
2945 receive_udp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
2946                      void **tunnel_ctx,
2947                      const struct GNUNET_MessageHeader *message)
2948 {
2949   struct TunnelState *state = *tunnel_ctx;
2950   const struct GNUNET_EXIT_UdpServiceMessage *msg;
2951   uint16_t pkt_len = ntohs (message->size);
2952
2953   if (GNUNET_YES == state->is_dns)
2954   {
2955     GNUNET_break_op (0);
2956     return GNUNET_SYSERR;
2957   }
2958   if (GNUNET_SYSERR == state->is_dns)
2959   {
2960     /* tunnel is UDP/TCP from now on */
2961     state->is_dns = GNUNET_NO;
2962   }
2963   GNUNET_STATISTICS_update (stats,
2964                             gettext_noop ("# Bytes received from MESH"),
2965                             pkt_len, GNUNET_NO);
2966   GNUNET_STATISTICS_update (stats,
2967                             gettext_noop ("# UDP service requests received via mesh"),
2968                             1, GNUNET_NO);
2969   /* check that we got at least a valid header */
2970   if (pkt_len < sizeof (struct GNUNET_EXIT_UdpServiceMessage))
2971   {
2972     GNUNET_break_op (0);
2973     return GNUNET_SYSERR;
2974   }
2975   msg = (const struct GNUNET_EXIT_UdpServiceMessage*) message;
2976   pkt_len -= sizeof (struct GNUNET_EXIT_UdpServiceMessage);
2977   LOG (GNUNET_ERROR_TYPE_DEBUG,
2978        "Received data from %s for forwarding to UDP service %s on port %u\n",
2979        GNUNET_i2s (&state->peer),
2980        GNUNET_h2s (&msg->service_descriptor),
2981        (unsigned int) ntohs (msg->destination_port));
2982   if (NULL == (state->specifics.tcp_udp.serv = find_service (udp_services, &msg->service_descriptor,
2983                                                              ntohs (msg->destination_port))))
2984   {
2985     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2986                 _("No service found for %s on port %d!\n"),
2987                 "UDP",
2988                 ntohs (msg->destination_port));
2989     GNUNET_STATISTICS_update (stats,
2990                               gettext_noop ("# UDP requests dropped (no such service)"),
2991                               1, GNUNET_NO);
2992     return GNUNET_SYSERR;
2993   }
2994   state->specifics.tcp_udp.ri.remote_address = state->specifics.tcp_udp.serv->address;
2995   setup_state_record (state);
2996   if (0 != ntohs (msg->source_port))
2997     state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
2998   send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2999                            &state->specifics.tcp_udp.ri.local_address,
3000                            &msg[1], pkt_len);
3001   return GNUNET_YES;
3002 }
3003
3004
3005 /**
3006  * Callback from GNUNET_MESH for new tunnels.
3007  *
3008  * @param cls closure
3009  * @param tunnel new handle to the tunnel
3010  * @param initiator peer that started the tunnel
3011  * @param port destination port
3012  * @return initial tunnel context for the tunnel
3013  */
3014 static void *
3015 new_tunnel (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
3016             const struct GNUNET_PeerIdentity *initiator, uint32_t port)
3017 {
3018   struct TunnelState *s = GNUNET_new (struct TunnelState);
3019
3020   s->is_dns = GNUNET_SYSERR;
3021   s->peer = *initiator;
3022   GNUNET_STATISTICS_update (stats,
3023                             gettext_noop ("# Inbound MESH tunnels created"),
3024                             1, GNUNET_NO);
3025   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3026               "Received inbound tunnel from `%s'\n",
3027               GNUNET_i2s (initiator));
3028   s->tunnel = tunnel;
3029   return s;
3030 }
3031
3032
3033 /**
3034  * Function called by mesh whenever an inbound tunnel is destroyed.
3035  * Should clean up any associated state.
3036  *
3037  * @param cls closure (set from GNUNET_MESH_connect)
3038  * @param tunnel connection to the other end (henceforth invalid)
3039  * @param tunnel_ctx place where local state associated
3040  *                   with the tunnel is stored
3041  */
3042 static void
3043 clean_tunnel (void *cls GNUNET_UNUSED, const struct GNUNET_MESH_Tunnel *tunnel,
3044               void *tunnel_ctx)
3045 {
3046   struct TunnelState *s = tunnel_ctx;
3047   struct TunnelMessageQueue *tnq;
3048
3049   LOG (GNUNET_ERROR_TYPE_DEBUG,
3050        "Tunnel destroyed\n");
3051   if (GNUNET_SYSERR == s->is_dns)
3052   {
3053     GNUNET_free (s);
3054     return;
3055   }
3056   if (GNUNET_YES == s->is_dns)
3057   {
3058     if (tunnels[s->specifics.dns.my_id] == s)
3059       tunnels[s->specifics.dns.my_id] = NULL;
3060     GNUNET_free_non_null (s->specifics.dns.reply);
3061   }
3062   else
3063   {
3064     while (NULL != (tnq = s->specifics.tcp_udp.head))
3065     {
3066       GNUNET_CONTAINER_DLL_remove (s->specifics.tcp_udp.head,
3067                                    s->specifics.tcp_udp.tail,
3068                                    tnq);
3069       GNUNET_free (tnq);
3070     }
3071     if (NULL != s->specifics.tcp_udp.heap_node)
3072     {
3073       GNUNET_assert (GNUNET_YES ==
3074                      GNUNET_CONTAINER_multihashmap_remove (connections_map,
3075                                                            &s->specifics.tcp_udp.state_key,
3076                                                            s));
3077       GNUNET_CONTAINER_heap_remove_node (s->specifics.tcp_udp.heap_node);
3078       s->specifics.tcp_udp.heap_node = NULL;
3079     }
3080   }
3081   if (NULL != s->th)
3082   {
3083     GNUNET_MESH_notify_transmit_ready_cancel (s->th);
3084     s->th = NULL;
3085   }
3086   GNUNET_free (s);
3087 }
3088
3089
3090 /**
3091  * Function that frees everything from a hashmap
3092  *
3093  * @param cls unused
3094  * @param hash key
3095  * @param value value to free
3096  */
3097 static int
3098 free_iterate (void *cls GNUNET_UNUSED,
3099               const struct GNUNET_HashCode * hash GNUNET_UNUSED, void *value)
3100 {
3101   GNUNET_free (value);
3102   return GNUNET_YES;
3103 }
3104
3105
3106 /**
3107  * Function scheduled as very last function, cleans up after us
3108  */
3109 static void
3110 cleanup (void *cls GNUNET_UNUSED,
3111          const struct GNUNET_SCHEDULER_TaskContext *tskctx)
3112 {
3113   unsigned int i;
3114
3115   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3116               "Exit service is shutting down now\n");
3117
3118   if (NULL != helper_handle)
3119   {
3120     GNUNET_HELPER_stop (helper_handle, GNUNET_NO);
3121     helper_handle = NULL;
3122   }
3123   if (NULL != regex4)
3124   {
3125     GNUNET_REGEX_announce_cancel (regex4);
3126     regex4 = NULL;
3127   }
3128   if (NULL != regex6)
3129   {
3130     GNUNET_REGEX_announce_cancel (regex6);
3131     regex6 = NULL;
3132   }
3133   if (NULL != mesh_handle)
3134   {
3135     GNUNET_MESH_disconnect (mesh_handle);
3136     mesh_handle = NULL;
3137   }
3138   if (NULL != connections_map)
3139   {
3140     GNUNET_CONTAINER_multihashmap_iterate (connections_map, &free_iterate, NULL);
3141     GNUNET_CONTAINER_multihashmap_destroy (connections_map);
3142     connections_map = NULL;
3143   }
3144   if (NULL != connections_heap)
3145   {
3146     GNUNET_CONTAINER_heap_destroy (connections_heap);
3147     connections_heap = NULL;
3148   }
3149   if (NULL != tcp_services)
3150   {
3151     GNUNET_CONTAINER_multihashmap_iterate (tcp_services, &free_service_record, NULL);
3152     GNUNET_CONTAINER_multihashmap_destroy (tcp_services);
3153     tcp_services = NULL;
3154   }
3155   if (NULL != udp_services)
3156   {
3157     GNUNET_CONTAINER_multihashmap_iterate (udp_services, &free_service_record, NULL);
3158     GNUNET_CONTAINER_multihashmap_destroy (udp_services);
3159     udp_services = NULL;
3160   }
3161   if (NULL != dnsstub)
3162   {
3163     GNUNET_DNSSTUB_stop (dnsstub);
3164     dnsstub = NULL;
3165   }
3166   if (NULL != peer_key)
3167   {
3168     GNUNET_free (peer_key);
3169     peer_key = NULL;
3170   }
3171   if (GNUNET_SCHEDULER_NO_TASK != dht_task)
3172   {
3173     GNUNET_SCHEDULER_cancel (dht_task);
3174     dht_task = GNUNET_SCHEDULER_NO_TASK;
3175   }
3176   if (NULL != dht_put)
3177   {
3178     GNUNET_DHT_put_cancel (dht_put);
3179     dht_put = NULL;
3180   }
3181   if (NULL != dht)
3182   {
3183     GNUNET_DHT_disconnect (dht);
3184     dht = NULL;
3185   }
3186   if (NULL != stats)
3187   {
3188     GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
3189     stats = NULL;
3190   }
3191   for (i=0;i<8;i++)
3192     GNUNET_free_non_null (exit_argv[i]);
3193 }
3194
3195
3196 /**
3197  * Add services to the service map.
3198  *
3199  * @param proto IPPROTO_TCP or IPPROTO_UDP
3200  * @param cpy copy of the service descriptor (can be mutilated)
3201  * @param name DNS name of the service
3202  */
3203 static void
3204 add_services (int proto,
3205               char *cpy,
3206               const char *name)
3207 {
3208   char *redirect;
3209   char *hostname;
3210   char *hostport;
3211   struct LocalService *serv;
3212
3213   for (redirect = strtok (cpy, " "); redirect != NULL;
3214        redirect = strtok (NULL, " "))
3215   {
3216     if (NULL == (hostname = strstr (redirect, ":")))
3217     {
3218       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3219                   "option `%s' for domain `%s' is not formatted correctly!\n",
3220                   redirect,
3221                   name);
3222       continue;
3223     }
3224     hostname[0] = '\0';
3225     hostname++;
3226     if (NULL == (hostport = strstr (hostname, ":")))
3227     {
3228       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3229                   "option `%s' for domain `%s' is not formatted correctly!\n",
3230                   redirect,
3231                   name);
3232       continue;
3233     }
3234     hostport[0] = '\0';
3235     hostport++;
3236
3237     int local_port = atoi (redirect);
3238     int remote_port = atoi (hostport);
3239
3240     if (!((local_port > 0) && (local_port < 65536)))
3241     {
3242       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3243                   "`%s' is not a valid port number (for domain `%s')!", redirect,
3244                   name);
3245       continue;
3246     }
3247     if (!((remote_port > 0) && (remote_port < 65536)))
3248     {
3249       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3250                   "`%s' is not a valid port number (for domain `%s')!", hostport,
3251                   name);
3252       continue;
3253     }
3254
3255     serv = GNUNET_new (struct LocalService);
3256     serv->address.proto = proto;
3257     serv->my_port = (uint16_t) local_port;
3258     serv->address.port = remote_port;
3259     if (0 == strcmp ("localhost4", hostname))
3260     {
3261       const char *ip4addr = exit_argv[5];
3262
3263       serv->address.af = AF_INET;
3264       GNUNET_assert (1 == inet_pton (AF_INET, ip4addr, &serv->address.address.ipv4));
3265     }
3266     else if (0 == strcmp ("localhost6", hostname))
3267     {
3268       const char *ip6addr = exit_argv[3];
3269
3270       serv->address.af = AF_INET6;
3271       GNUNET_assert (1 == inet_pton (AF_INET6, ip6addr, &serv->address.address.ipv6));
3272     }
3273     else
3274     {
3275       struct addrinfo *res;
3276       int ret;
3277
3278       ret = getaddrinfo (hostname, NULL, NULL, &res);
3279       if ( (ret != 0) || (res == NULL) )
3280       {
3281         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3282                     _("No addresses found for hostname `%s' of service `%s'!\n"),
3283                     hostname,
3284                     name);
3285         GNUNET_free (serv);
3286         continue;
3287       }
3288
3289       serv->address.af = res->ai_family;
3290       switch (res->ai_family)
3291       {
3292       case AF_INET:
3293         if (! ipv4_enabled)
3294         {
3295           GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3296                       _("Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
3297                       name);
3298           freeaddrinfo (res);
3299           GNUNET_free (serv);
3300           continue;
3301         }
3302         serv->address.address.ipv4 = ((struct sockaddr_in *) res->ai_addr)->sin_addr;
3303         break;
3304       case AF_INET6:
3305         if (! ipv6_enabled)
3306         {
3307           GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3308                       _("Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
3309                       name);
3310           freeaddrinfo (res);
3311           GNUNET_free (serv);
3312           continue;
3313         }       
3314         serv->address.address.ipv6 = ((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
3315         break;
3316       default:
3317         freeaddrinfo (res);
3318         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3319                     _("No IP addresses found for hostname `%s' of service `%s'!\n"),
3320                     hostname,
3321                     name);
3322         GNUNET_free (serv);
3323         continue;
3324       }
3325       freeaddrinfo (res);
3326     }
3327     store_service ((IPPROTO_UDP == proto) ? udp_services : tcp_services,
3328                    name,
3329                    local_port,
3330                    serv);
3331   }
3332 }
3333
3334
3335 /**
3336  * Reads the configuration servicecfg and populates udp_services
3337  *
3338  * @param cls unused
3339  * @param section name of section in config, equal to hostname
3340  */
3341 static void
3342 read_service_conf (void *cls GNUNET_UNUSED, const char *section)
3343 {
3344   char *cpy;
3345
3346   if ((strlen (section) < 8) ||
3347       (0 != strcmp (".gnunet.", section + (strlen (section) - 8))))
3348     return;
3349   if (GNUNET_OK ==
3350       GNUNET_CONFIGURATION_get_value_string (cfg, section, "UDP_REDIRECTS",
3351                                              &cpy))
3352   {
3353     add_services (IPPROTO_UDP, cpy, section);
3354     GNUNET_free (cpy);
3355   }
3356   if (GNUNET_OK ==
3357       GNUNET_CONFIGURATION_get_value_string (cfg, section, "TCP_REDIRECTS",
3358                                              &cpy))
3359   {
3360     add_services (IPPROTO_TCP, cpy, section);
3361     GNUNET_free (cpy);
3362   }
3363 }
3364
3365
3366 /**
3367  * We are running a DNS exit service, advertise it in the
3368  * DHT.  This task is run periodically to do the DHT PUT.
3369  *
3370  * @param cls closure
3371  * @param tc scheduler context
3372  */
3373 static void
3374 do_dht_put (void *cls,
3375             const struct GNUNET_SCHEDULER_TaskContext *tc);
3376
3377
3378 /**
3379  * Function called when the DHT PUT operation is complete.
3380  * Schedules the next PUT.
3381  *
3382  * @param cls closure, NULL
3383  * @param success #GNUNET_OK if the operation worked (unused)
3384  */
3385 static void
3386 dht_put_cont (void *cls,
3387               int success)
3388 {
3389   dht_put = NULL;
3390   dht_task = GNUNET_SCHEDULER_add_delayed (DHT_PUT_FREQUENCY,
3391                                            &do_dht_put,
3392                                            NULL);
3393 }
3394
3395
3396 /**
3397  * We are running a DNS exit service, advertise it in the
3398  * DHT.  This task is run periodically to do the DHT PUT.
3399  *
3400  * @param cls closure
3401  * @param tc scheduler context
3402  */
3403 static void
3404 do_dht_put (void *cls,
3405             const struct GNUNET_SCHEDULER_TaskContext *tc)
3406 {
3407   struct GNUNET_TIME_Absolute expiration;
3408
3409   dht_task = GNUNET_SCHEDULER_NO_TASK;
3410   expiration = GNUNET_TIME_absolute_ntoh (dns_advertisement.expiration_time);
3411   if (GNUNET_TIME_absolute_get_remaining (expiration).rel_value_us <
3412       GNUNET_TIME_UNIT_HOURS.rel_value_us)
3413   {
3414     /* refresh advertisement */
3415     expiration = GNUNET_TIME_relative_to_absolute (DNS_ADVERTISEMENT_TIMEOUT);
3416     dns_advertisement.expiration_time = GNUNET_TIME_absolute_hton (expiration);
3417     GNUNET_assert (GNUNET_OK ==
3418                    GNUNET_CRYPTO_ecc_sign (peer_key,
3419                                            &dns_advertisement.purpose,
3420                                            &dns_advertisement.signature));
3421   }
3422   dht_put = GNUNET_DHT_put (dht,
3423                             &dht_put_key,
3424                             1 /* replication */,
3425                             GNUNET_DHT_RO_NONE,
3426                             GNUNET_BLOCK_TYPE_DNS,
3427                             sizeof (struct GNUNET_DNS_Advertisement),
3428                             &dns_advertisement,
3429                             expiration,
3430                             GNUNET_TIME_UNIT_FOREVER_REL,
3431                             &dht_put_cont, NULL);
3432 }
3433
3434
3435 /**
3436  * @brief Main function that will be run by the scheduler.
3437  *
3438  * @param cls closure
3439  * @param args remaining command-line arguments
3440  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
3441  * @param cfg_ configuration
3442  */
3443 static void
3444 run (void *cls, char *const *args GNUNET_UNUSED,
3445      const char *cfgfile GNUNET_UNUSED,
3446      const struct GNUNET_CONFIGURATION_Handle *cfg_)
3447 {
3448   static struct GNUNET_MESH_MessageHandler handlers[] = {
3449     {&receive_icmp_service, GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE, 0},
3450     {&receive_icmp_remote, GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET, 0},
3451     {&receive_udp_service, GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE, 0},
3452     {&receive_udp_remote, GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET, 0},
3453     {&receive_tcp_service, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START, 0},
3454     {&receive_tcp_remote, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START, 0},
3455     {&receive_tcp_data, GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT, 0},
3456     {&receive_dns_request, GNUNET_MESSAGE_TYPE_VPN_DNS_TO_INTERNET, 0},
3457     {NULL, 0, 0}
3458   };
3459
3460   static uint32_t apptypes[] = {
3461     GNUNET_APPLICATION_TYPE_END,
3462     GNUNET_APPLICATION_TYPE_END,
3463     GNUNET_APPLICATION_TYPE_END,
3464     GNUNET_APPLICATION_TYPE_END
3465   };
3466   unsigned int app_idx;
3467   char *exit_ifname;
3468   char *tun_ifname;
3469   char *policy;
3470   char *ipv6addr;
3471   char *ipv6prefix_s;
3472   char *ipv4addr;
3473   char *ipv4mask;
3474   char *binary;
3475   char *regex;
3476   char *prefixed_regex;
3477   struct in_addr dns_exit4;
3478   struct in6_addr dns_exit6;
3479   char *dns_exit;
3480
3481   cfg = cfg_;
3482   ipv4_exit = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "EXIT_IPV4");
3483   ipv6_exit = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "EXIT_IPV6");
3484   ipv4_enabled = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_IPV4");
3485   ipv6_enabled = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_IPV6");
3486   if ( (ipv4_exit) || (ipv6_exit) )
3487   {
3488     binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-exit");
3489     if (GNUNET_YES !=
3490         GNUNET_OS_check_helper_binary (binary, GNUNET_YES, "-d gnunet-vpn - - - 169.1.3.3.7 255.255.255.0")) //no nat, ipv4 only
3491     {
3492       GNUNET_free (binary);
3493       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3494                   _("`%s' must be installed SUID, refusing to run\n"),
3495                   "gnunet-helper-exit");
3496       global_ret = 1;
3497       return;
3498     }
3499     GNUNET_free (binary);
3500   }
3501   stats = GNUNET_STATISTICS_create ("exit", cfg);
3502
3503   if ( (ipv4_exit || ipv4_enabled) &&
3504        GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET))
3505   {
3506     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3507                 _("This system does not support IPv4, will disable IPv4 functions despite them being enabled in the configuration\n"));
3508     ipv4_exit = GNUNET_NO;
3509     ipv4_enabled = GNUNET_NO;
3510   }
3511   if ( (ipv6_exit || ipv6_enabled) &&
3512        GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET6))
3513   {
3514     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3515                 _("This system does not support IPv6, will disable IPv6 functions despite them being enabled in the configuration\n"));
3516     ipv6_exit = GNUNET_NO;
3517     ipv6_enabled = GNUNET_NO;
3518   }
3519   if (ipv4_exit && (! ipv4_enabled))
3520   {
3521     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3522                 _("Cannot enable IPv4 exit but disable IPv4 on TUN interface, will use ENABLE_IPv4=YES\n"));
3523     ipv4_enabled = GNUNET_YES;
3524   }
3525   if (ipv6_exit && (! ipv6_enabled))
3526   {
3527     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3528                 _("Cannot enable IPv6 exit but disable IPv6 on TUN interface, will use ENABLE_IPv6=YES\n"));
3529     ipv6_enabled = GNUNET_YES;
3530   }
3531   if (! (ipv4_enabled || ipv6_enabled))
3532   {
3533     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3534                 _("No useful service enabled.  Exiting.\n"));
3535     GNUNET_SCHEDULER_shutdown ();
3536     return;
3537   }
3538
3539   dns_exit = NULL;
3540   if ( (GNUNET_YES ==
3541         GNUNET_CONFIGURATION_get_value_yesno (cfg_, "exit", "ENABLE_DNS")) &&
3542        ( (GNUNET_OK !=
3543           GNUNET_CONFIGURATION_get_value_string (cfg, "exit",
3544                                                  "DNS_RESOLVER",
3545                                                  &dns_exit)) ||
3546          ( (1 != inet_pton (AF_INET, dns_exit, &dns_exit4)) &&
3547            (1 != inet_pton (AF_INET6, dns_exit, &dns_exit6)) ) ) )
3548   {
3549     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
3550                                "dns", "DNS_RESOLVER",
3551                                _("need a valid IPv4 or IPv6 address\n"));
3552     GNUNET_free_non_null (dns_exit);
3553     dns_exit = NULL;
3554   }
3555   if (NULL != dns_exit)
3556     dnsstub = GNUNET_DNSSTUB_start (dns_exit);
3557
3558
3559   app_idx = 0;
3560   if (GNUNET_YES == ipv4_exit)
3561   {
3562     // FIXME use regex to put info
3563     apptypes[app_idx] = GNUNET_APPLICATION_TYPE_IPV4_GATEWAY;
3564     app_idx++;
3565   }
3566   if (GNUNET_YES == ipv6_exit)
3567   {
3568     // FIXME use regex to put info
3569     apptypes[app_idx] = GNUNET_APPLICATION_TYPE_IPV6_GATEWAY;
3570     app_idx++;
3571   }
3572   if (NULL != dns_exit)
3573   {
3574     dht = GNUNET_DHT_connect (cfg, 1);
3575     peer_key = GNUNET_CRYPTO_ecc_key_create_from_configuration (cfg);
3576     GNUNET_CRYPTO_ecc_key_get_public_for_signature (peer_key,
3577                                                     &dns_advertisement.peer.public_key);
3578     dns_advertisement.purpose.size = htonl (sizeof (struct GNUNET_DNS_Advertisement) -
3579                                             sizeof (struct GNUNET_CRYPTO_EccSignature));
3580     dns_advertisement.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DNS_RECORD);
3581     GNUNET_CRYPTO_hash ("dns",
3582                         strlen ("dns"),
3583                         &dht_put_key);
3584     dht_task = GNUNET_SCHEDULER_add_now (&do_dht_put,
3585                                          NULL);
3586     apptypes[app_idx] = GNUNET_APPLICATION_TYPE_INTERNET_RESOLVER;
3587     app_idx++;
3588   }
3589
3590   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls);
3591
3592   if (GNUNET_OK !=
3593       GNUNET_CONFIGURATION_get_value_number (cfg, "exit", "MAX_CONNECTIONS",
3594                                              &max_connections))
3595     max_connections = 1024;
3596   exit_argv[0] = GNUNET_strdup ("exit-gnunet");
3597   if (GNUNET_SYSERR ==
3598       GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "TUN_IFNAME", &tun_ifname))
3599   {
3600     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "EXIT", "TUN_IFNAME");
3601     GNUNET_SCHEDULER_shutdown ();
3602     return;
3603   }
3604   exit_argv[1] = tun_ifname;
3605   if (ipv4_enabled)
3606   {
3607     if (GNUNET_SYSERR ==
3608         GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "EXIT_IFNAME", &exit_ifname))
3609     {
3610       GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "EXIT", "EXIT_IFNAME");
3611       GNUNET_SCHEDULER_shutdown ();
3612       return;
3613     }
3614     exit_argv[2] = exit_ifname;
3615   }
3616   else
3617   {
3618     exit_argv[2] = GNUNET_strdup ("-");
3619   }
3620
3621
3622   if (GNUNET_YES == ipv6_enabled)
3623   {
3624     if ( (GNUNET_SYSERR ==
3625           GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6ADDR",
3626                                                  &ipv6addr) ||
3627           (1 != inet_pton (AF_INET6, ipv6addr, &exit_ipv6addr))) )
3628     {
3629       GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "EXIT", "IPV6ADDR");
3630       GNUNET_SCHEDULER_shutdown ();
3631       return;
3632     }
3633     exit_argv[3] = ipv6addr;
3634     if (GNUNET_SYSERR ==
3635         GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6PREFIX",
3636                                                &ipv6prefix_s))
3637     {
3638       GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "EXIT", "IPV6PREFIX");
3639       GNUNET_SCHEDULER_shutdown ();
3640       return;
3641     }
3642     exit_argv[4] = ipv6prefix_s;
3643     if ( (GNUNET_OK !=
3644           GNUNET_CONFIGURATION_get_value_number (cfg, "exit",
3645                                                  "IPV6PREFIX",
3646                                                  &ipv6prefix)) ||
3647          (ipv6prefix >= 127) )
3648     {
3649       GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "EXIT", "IPV6PREFIX",
3650                                  _("Must be a number"));
3651       GNUNET_SCHEDULER_shutdown ();
3652       return;
3653     }
3654   }
3655   else
3656   {
3657     /* IPv6 explicitly disabled */
3658     exit_argv[3] = GNUNET_strdup ("-");
3659     exit_argv[4] = GNUNET_strdup ("-");
3660   }
3661   if (GNUNET_YES == ipv4_enabled)
3662   {
3663     if ( (GNUNET_SYSERR ==
3664           GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4ADDR",
3665                                                  &ipv4addr) ||
3666           (1 != inet_pton (AF_INET, ipv4addr, &exit_ipv4addr))) )
3667       {
3668         GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "EXIT", "IPV4ADDR");
3669         GNUNET_SCHEDULER_shutdown ();
3670         return;
3671       }
3672     exit_argv[5] = ipv4addr;
3673     if ( (GNUNET_SYSERR ==
3674           GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4MASK",
3675                                                  &ipv4mask) ||
3676           (1 != inet_pton (AF_INET, ipv4mask, &exit_ipv4mask))) )
3677     {
3678       GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "EXIT", "IPV4MASK");
3679       GNUNET_SCHEDULER_shutdown ();
3680       return;
3681     }
3682     exit_argv[6] = ipv4mask;
3683   }
3684   else
3685   {
3686     /* IPv4 explicitly disabled */
3687     exit_argv[5] = GNUNET_strdup ("-");
3688     exit_argv[6] = GNUNET_strdup ("-");
3689   }
3690   exit_argv[7] = NULL;
3691
3692   udp_services = GNUNET_CONTAINER_multihashmap_create (65536, GNUNET_NO);
3693   tcp_services = GNUNET_CONTAINER_multihashmap_create (65536, GNUNET_NO);
3694   GNUNET_CONFIGURATION_iterate_sections (cfg, &read_service_conf, NULL);
3695
3696   connections_map = GNUNET_CONTAINER_multihashmap_create (65536, GNUNET_NO);
3697   connections_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
3698   mesh_handle
3699     = GNUNET_MESH_connect (cfg, NULL,
3700                            &new_tunnel,
3701                            &clean_tunnel, handlers,
3702                            apptypes); // FIXME use ports
3703   if (NULL == mesh_handle)
3704   {
3705     GNUNET_SCHEDULER_shutdown ();
3706     return;
3707   }
3708
3709   /* Mesh handle acquired, now announce regular expressions matching our exit */
3710   if ( (GNUNET_YES == ipv4_enabled) && (GNUNET_YES == ipv4_exit) )
3711   {
3712     policy = NULL;
3713     if (GNUNET_OK !=
3714         GNUNET_CONFIGURATION_get_value_string (cfg,
3715                                                "exit",
3716                                                "EXIT_RANGE_IPV4_REGEX",
3717                                                &policy))
3718       regex = NULL;
3719     else
3720       regex = GNUNET_TUN_ipv4policy2regex (policy);
3721     GNUNET_free_non_null (policy);
3722     if (NULL != regex)
3723     {
3724       (void) GNUNET_asprintf (&prefixed_regex, "%s%s%s",
3725                               GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX,
3726                               "4", regex);
3727       regex4 = GNUNET_REGEX_announce (cfg,                      
3728                                       prefixed_regex,
3729                                       REGEX_REFRESH_FREQUENCY,
3730                                       REGEX_MAX_PATH_LEN_IPV4);
3731       GNUNET_free (regex);
3732       GNUNET_free (prefixed_regex);
3733     }
3734   }
3735
3736   if (GNUNET_YES == ipv6_enabled && GNUNET_YES == ipv6_exit)
3737   {
3738     policy = NULL;
3739     if (GNUNET_OK !=
3740         GNUNET_CONFIGURATION_get_value_string (cfg,
3741                                                "exit",
3742                                                "EXIT_RANGE_IPV6_REGEX",
3743                                                &policy))
3744       regex = NULL;
3745     else
3746       regex = GNUNET_TUN_ipv6policy2regex (policy);
3747     GNUNET_free_non_null (policy);
3748     if (NULL != regex)
3749     {
3750       (void) GNUNET_asprintf (&prefixed_regex, "%s%s%s",
3751                               GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX,
3752                               "6", regex);
3753       regex6 = GNUNET_REGEX_announce (cfg,
3754                                       prefixed_regex,
3755                                       REGEX_REFRESH_FREQUENCY,
3756                                       REGEX_MAX_PATH_LEN_IPV6);
3757       GNUNET_free (regex);
3758       GNUNET_free (prefixed_regex);
3759     }
3760   }
3761   if ((ipv4_exit) || (ipv6_exit))
3762     helper_handle = GNUNET_HELPER_start (GNUNET_NO,
3763                                          "gnunet-helper-exit",
3764                                          exit_argv,
3765                                          &message_token,
3766                                          NULL, NULL);
3767 }
3768
3769
3770 /**
3771  * The main function
3772  *
3773  * @param argc number of arguments from the command line
3774  * @param argv command line arguments
3775  * @return 0 ok, 1 on error
3776  */
3777 int
3778 main (int argc, char *const *argv)
3779 {
3780   static const struct GNUNET_GETOPT_CommandLineOption options[] = {
3781     GNUNET_GETOPT_OPTION_END
3782   };
3783
3784   if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
3785     return 2;
3786
3787   return (GNUNET_OK ==
3788           GNUNET_PROGRAM_run (argc, argv, "gnunet-daemon-exit",
3789                               gettext_noop
3790                               ("Daemon to run to provide an IP exit node for the VPN"),
3791                               options, &run, NULL)) ? global_ret : 1;
3792 }
3793
3794
3795 /* end of gnunet-daemon-exit.c */