session time out for http client/server
[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 channel.
188  */
189 struct ChannelMessageQueue
190 {
191   /**
192    * This is a doubly-linked list.
193    */
194   struct ChannelMessageQueue *next;
195
196   /**
197    * This is a doubly-linked list.
198    */
199   struct ChannelMessageQueue *prev;
200
201   /**
202    * Payload to send via the channel.
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 channel given an IP packet from TUN.  It is also associated
216  * with the channel's closure so we can find it again for the next
217  * message from the channel.
218  */
219 struct ChannelState
220 {
221   /**
222    * Mesh channel that is used for this connection.
223    */
224   struct GNUNET_MESH_Channel *channel;
225
226   /**
227    * Who is the other end of this channel.
228    * FIXME is this needed? Only used for debugging messages
229    */
230   struct GNUNET_PeerIdentity peer;
231
232   /**
233    * Active channel transmission request (or NULL).
234    */
235   struct GNUNET_MESH_TransmitHandle *th;
236
237   /**
238    * #GNUNET_NO if this is a channel for TCP/UDP,
239    * #GNUNET_YES if this is a channel for DNS,
240    * #GNUNET_SYSERR if the channel 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 channel.
266        */
267       struct ChannelMessageQueue *head;
268
269       /**
270        * Tail of DLL of messages for this channel.
271        */
272       struct ChannelMessageQueue *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 ChannelState
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 channels.
404  */
405 static struct ChannelState *channels[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_EddsaPrivateKey *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 channel.  Send it
466  * via the channel (after changing the request ID back).
467  *
468  * @param cls the 'struct ChannelState'
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 ChannelState *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 ChannelState *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 channel */
532   ts = channels[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   channels[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->channel,
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 channel connection to the other end
559  * @param channel_ctx pointer to our `struct ChannelState *`
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_Channel *channel,
567                      void **channel_ctx,
568                      const struct GNUNET_MessageHeader *message)
569 {
570   struct ChannelState *ts = *channel_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     /* channel 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 (channels[ts->specifics.dns.my_id] == ts)
597     channels[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   channels[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 ChannelState *
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 ChannelState *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 channel.  Transmit it.
811  *
812  * @param cls the 'struct ChannelState'.
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 ChannelState *s = cls;
821   struct GNUNET_MESH_Channel *channel = s->channel;
822   struct ChannelMessageQueue *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 (channel,
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 (channel,
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 channels"),
854                             size, GNUNET_NO);
855   return size;
856 }
857
858
859 /**
860  * Send the given packet via the mesh channel.
861  *
862  * @param s channel destination
863  * @param tnq message to queue
864  */
865 static void
866 send_packet_to_mesh_channel (struct ChannelState *s,
867                             struct ChannelMessageQueue *tnq)
868 {
869   struct GNUNET_MESH_Channel *mesh_channel;
870
871   mesh_channel = s->channel;
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_channel,
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 ChannelState *state;
903   struct ChannelMessageQueue *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 ChannelMessageQueue) + 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_channel (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 ChannelState *state;
1091   struct ChannelMessageQueue *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 ChannelMessageQueue) + 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_channel (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 ChannelState *state;
1168   char buf[pktlen] GNUNET_ALIGN;
1169   struct GNUNET_TUN_TcpHeader *mtcp;
1170   struct GNUNET_EXIT_TcpDataMessage *tdm;
1171   struct ChannelMessageQueue *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 ChannelMessageQueue) + 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_channel (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 channel.  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 'channel' 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 ChannelState *state)
1508 {
1509   struct GNUNET_HashCode key;
1510   struct ChannelState *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_channel_destroy (s->channel);
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 @a 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 channel connection to the other end
1841  * @param channel_ctx pointer to our `struct ChannelState *`
1842  * @param message the actual message
1843  * @return #GNUNET_OK to keep the connection open,
1844  *         #GNUNET_SYSERR to close it (signal serious error)
1845  */
1846 static int
1847 receive_tcp_service (void *cls,
1848                      struct GNUNET_MESH_Channel *channel,
1849                      void **channel_ctx,
1850                      const struct GNUNET_MessageHeader *message)
1851 {
1852   struct ChannelState *state = *channel_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     /* channel 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 channel connection to the other end
1930  * @param channel_ctx pointer to our 'struct ChannelState *'
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_Channel *channel,
1938                     void **channel_ctx GNUNET_UNUSED,
1939                     const struct GNUNET_MessageHeader *message)
1940 {
1941   struct ChannelState *state = *channel_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     /* channel 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 channel connection to the other end
2055  * @param channel_ctx pointer to our 'struct ChannelState *'
2056  * @param message the actual message
2057  * @return #GNUNET_OK to keep the connection open,
2058  *         #GNUNET_SYSERR to close it (signal serious error)
2059  */
2060 static int
2061 receive_tcp_data (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Channel *channel,
2062                   void **channel_ctx GNUNET_UNUSED,
2063                   const struct GNUNET_MessageHeader *message)
2064 {
2065   struct ChannelState *state = *channel_ctx;
2066   const struct GNUNET_EXIT_TcpDataMessage *data;
2067   uint16_t pkt_len = ntohs (message->size);
2068
2069   GNUNET_STATISTICS_update (stats,
2070                             gettext_noop ("# Bytes received from MESH"),
2071                             pkt_len, GNUNET_NO);
2072   GNUNET_STATISTICS_update (stats,
2073                             gettext_noop ("# TCP data requests received via mesh"),
2074                             1, GNUNET_NO);
2075   if (pkt_len < sizeof (struct GNUNET_EXIT_TcpDataMessage))
2076   {
2077     GNUNET_break_op (0);
2078     return GNUNET_SYSERR;
2079   }
2080   data = (const struct GNUNET_EXIT_TcpDataMessage*) message;
2081   pkt_len -= sizeof (struct GNUNET_EXIT_TcpDataMessage);
2082   if ( (NULL == state) ||
2083        (NULL == state->specifics.tcp_udp.heap_node) )
2084   {
2085     /* connection should have been up! */
2086     GNUNET_STATISTICS_update (stats,
2087                               gettext_noop ("# TCP DATA requests dropped (no session)"),
2088                               1, GNUNET_NO);
2089     return GNUNET_SYSERR;
2090   }
2091   if (data->tcp_header.off * 4 < sizeof (struct GNUNET_TUN_TcpHeader))
2092   {
2093     GNUNET_break_op (0);
2094     return GNUNET_SYSERR;
2095   }
2096   if (GNUNET_YES == state->is_dns)
2097   {
2098     GNUNET_break_op (0);
2099     return GNUNET_SYSERR;
2100   }
2101   if (GNUNET_SYSERR == state->is_dns)
2102   {
2103     /* channel is UDP/TCP from now on */
2104     state->is_dns = GNUNET_NO;
2105   }
2106
2107   GNUNET_break_op (ntohl (data->reserved) == 0);
2108   {
2109     char buf[INET6_ADDRSTRLEN];
2110     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2111                 "Received additional %u bytes of data from %s for TCP stream to %s:%u\n",
2112                 pkt_len,
2113                 GNUNET_i2s (&state->peer),
2114                 inet_ntop (state->specifics.tcp_udp.ri.remote_address.af,
2115                            &state->specifics.tcp_udp.ri.remote_address.address,
2116                            buf, sizeof (buf)),
2117                 (unsigned int) state->specifics.tcp_udp.ri.remote_address.port);
2118   }
2119
2120   send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2121                            &state->specifics.tcp_udp.ri.local_address,
2122                            &data->tcp_header,
2123                            &data[1], pkt_len);
2124   return GNUNET_YES;
2125 }
2126
2127
2128 /**
2129  * Send an ICMP packet via the TUN interface.
2130  *
2131  * @param destination_address IP to use for the ICMP packet's destination
2132  * @param source_address IP to use for the ICMP packet's source
2133  * @param icmp_header ICMP header to send
2134  * @param payload payload of the ICMP packet (does NOT include ICMP header)
2135  * @param payload_length number of bytes of data in @a payload
2136  */
2137 static void
2138 send_icmp_packet_via_tun (const struct SocketAddress *destination_address,
2139                           const struct SocketAddress *source_address,
2140                           const struct GNUNET_TUN_IcmpHeader *icmp_header,
2141                           const void *payload, size_t payload_length)
2142 {
2143   size_t len;
2144   struct GNUNET_TUN_IcmpHeader *icmp;
2145
2146   GNUNET_STATISTICS_update (stats,
2147                             gettext_noop ("# ICMP packets sent via TUN"),
2148                             1, GNUNET_NO);
2149   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2150               "Sending packet with %u bytes ICMP payload via TUN\n",
2151               (unsigned int) payload_length);
2152   len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader);
2153   switch (destination_address->af)
2154   {
2155   case AF_INET:
2156     len += sizeof (struct GNUNET_TUN_IPv4Header);
2157     break;
2158   case AF_INET6:
2159     len += sizeof (struct GNUNET_TUN_IPv6Header);
2160     break;
2161   default:
2162     GNUNET_break (0);
2163     return;
2164   }
2165   len += sizeof (struct GNUNET_TUN_IcmpHeader);
2166   len += payload_length;
2167   if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
2168   {
2169     GNUNET_break (0);
2170     return;
2171   }
2172   {
2173     char buf[len] GNUNET_ALIGN;
2174     struct GNUNET_MessageHeader *hdr;
2175     struct GNUNET_TUN_Layer2PacketHeader *tun;
2176
2177     hdr= (struct GNUNET_MessageHeader *) buf;
2178     hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
2179     hdr->size = htons (len);
2180     tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
2181     tun->flags = htons (0);
2182     switch (source_address->af)
2183     {
2184     case AF_INET:
2185       {
2186         struct GNUNET_TUN_IPv4Header * ipv4 = (struct GNUNET_TUN_IPv4Header*) &tun[1];
2187
2188         tun->proto = htons (ETH_P_IPV4);
2189         GNUNET_TUN_initialize_ipv4_header (ipv4,
2190                                            IPPROTO_ICMP,
2191                                            sizeof (struct GNUNET_TUN_IcmpHeader) + payload_length,
2192                                            &source_address->address.ipv4,
2193                                            &destination_address->address.ipv4);
2194         icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv4[1];
2195       }
2196       break;
2197     case AF_INET6:
2198       {
2199         struct GNUNET_TUN_IPv6Header * ipv6 = (struct GNUNET_TUN_IPv6Header*) &tun[1];
2200
2201         tun->proto = htons (ETH_P_IPV6);
2202         GNUNET_TUN_initialize_ipv6_header (ipv6,
2203                                            IPPROTO_ICMPV6,
2204                                            sizeof (struct GNUNET_TUN_IcmpHeader) + payload_length,
2205                                            &source_address->address.ipv6,
2206                                            &destination_address->address.ipv6);
2207         icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv6[1];
2208       }
2209       break;
2210     default:
2211       GNUNET_assert (0);
2212       break;
2213     }
2214     *icmp = *icmp_header;
2215     memcpy (&icmp[1],
2216             payload,
2217             payload_length);
2218     GNUNET_TUN_calculate_icmp_checksum (icmp,
2219                                         payload,
2220                                         payload_length);
2221     if (NULL != helper_handle)
2222       (void) GNUNET_HELPER_send (helper_handle,
2223                                  (const struct GNUNET_MessageHeader*) buf,
2224                                  GNUNET_YES,
2225                                  NULL, NULL);
2226   }
2227 }
2228
2229
2230 /**
2231  * Synthesize a plausible ICMP payload for an ICMPv4 error
2232  * response on the given channel.
2233  *
2234  * @param state channel information
2235  * @param ipp IPv6 header to fill in (ICMP payload)
2236  * @param udp "UDP" header to fill in (ICMP payload); might actually
2237  *            also be the first 8 bytes of the TCP header
2238  */
2239 static void
2240 make_up_icmpv4_payload (struct ChannelState *state,
2241                         struct GNUNET_TUN_IPv4Header *ipp,
2242                         struct GNUNET_TUN_UdpHeader *udp)
2243 {
2244   GNUNET_TUN_initialize_ipv4_header (ipp,
2245                                      state->specifics.tcp_udp.ri.remote_address.proto,
2246                                      sizeof (struct GNUNET_TUN_TcpHeader),
2247                                      &state->specifics.tcp_udp.ri.remote_address.address.ipv4,
2248                                      &state->specifics.tcp_udp.ri.local_address.address.ipv4);
2249   udp->source_port = htons (state->specifics.tcp_udp.ri.remote_address.port);
2250   udp->destination_port = htons (state->specifics.tcp_udp.ri.local_address.port);
2251   udp->len = htons (0);
2252   udp->crc = htons (0);
2253 }
2254
2255
2256 /**
2257  * Synthesize a plausible ICMP payload for an ICMPv6 error
2258  * response on the given channel.
2259  *
2260  * @param state channel information
2261  * @param ipp IPv6 header to fill in (ICMP payload)
2262  * @param udp "UDP" header to fill in (ICMP payload); might actually
2263  *            also be the first 8 bytes of the TCP header
2264  */
2265 static void
2266 make_up_icmpv6_payload (struct ChannelState *state,
2267                         struct GNUNET_TUN_IPv6Header *ipp,
2268                         struct GNUNET_TUN_UdpHeader *udp)
2269 {
2270   GNUNET_TUN_initialize_ipv6_header (ipp,
2271                                      state->specifics.tcp_udp.ri.remote_address.proto,
2272                                      sizeof (struct GNUNET_TUN_TcpHeader),
2273                                      &state->specifics.tcp_udp.ri.remote_address.address.ipv6,
2274                                      &state->specifics.tcp_udp.ri.local_address.address.ipv6);
2275   udp->source_port = htons (state->specifics.tcp_udp.ri.remote_address.port);
2276   udp->destination_port = htons (state->specifics.tcp_udp.ri.local_address.port);
2277   udp->len = htons (0);
2278   udp->crc = htons (0);
2279 }
2280
2281
2282 /**
2283  * Process a request to forward ICMP data to the Internet via this peer.
2284  *
2285  * @param cls closure, NULL
2286  * @param channel connection to the other end
2287  * @param channel_ctx pointer to our 'struct ChannelState *'
2288  * @param message the actual message
2289  * @return #GNUNET_OK to keep the connection open,
2290  *         #GNUNET_SYSERR to close it (signal serious error)
2291  */
2292 static int
2293 receive_icmp_remote (void *cls,
2294                      struct GNUNET_MESH_Channel *channel,
2295                      void **channel_ctx,
2296                      const struct GNUNET_MessageHeader *message)
2297 {
2298   struct ChannelState *state = *channel_ctx;
2299   const struct GNUNET_EXIT_IcmpInternetMessage *msg;
2300   uint16_t pkt_len = ntohs (message->size);
2301   const struct in_addr *v4;
2302   const struct in6_addr *v6;
2303   const void *payload;
2304   char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
2305   int af;
2306
2307   if (GNUNET_YES == state->is_dns)
2308   {
2309     GNUNET_break_op (0);
2310     return GNUNET_SYSERR;
2311   }
2312   if (GNUNET_SYSERR == state->is_dns)
2313   {
2314     /* channel is UDP/TCP from now on */
2315     state->is_dns = GNUNET_NO;
2316   }
2317   GNUNET_STATISTICS_update (stats,
2318                             gettext_noop ("# Bytes received from MESH"),
2319                             pkt_len, GNUNET_NO);
2320   GNUNET_STATISTICS_update (stats,
2321                             gettext_noop ("# ICMP IP-exit requests received via mesh"),
2322                             1, GNUNET_NO);
2323   if (pkt_len < sizeof (struct GNUNET_EXIT_IcmpInternetMessage))
2324   {
2325     GNUNET_break_op (0);
2326     return GNUNET_SYSERR;
2327   }
2328   msg = (const struct GNUNET_EXIT_IcmpInternetMessage*) message;
2329   pkt_len -= sizeof (struct GNUNET_EXIT_IcmpInternetMessage);
2330
2331   af = (int) ntohl (msg->af);
2332   if ( (NULL != state->specifics.tcp_udp.heap_node) &&
2333        (af != state->specifics.tcp_udp.ri.remote_address.af) )
2334   {
2335     /* other peer switched AF on this channel; not allowed */
2336     GNUNET_break_op (0);
2337     return GNUNET_SYSERR;
2338   }
2339
2340   switch (af)
2341   {
2342   case AF_INET:
2343     if (pkt_len < sizeof (struct in_addr))
2344     {
2345       GNUNET_break_op (0);
2346       return GNUNET_SYSERR;
2347     }
2348     if (! ipv4_exit)
2349     {
2350       GNUNET_break_op (0);
2351       return GNUNET_SYSERR;
2352     }
2353     v4 = (const struct in_addr*) &msg[1];
2354     payload = &v4[1];
2355     pkt_len -= sizeof (struct in_addr);
2356     state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
2357     if (NULL == state->specifics.tcp_udp.heap_node)
2358     {
2359       state->specifics.tcp_udp.ri.remote_address.af = af;
2360       state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMP;
2361       setup_state_record (state);
2362     }
2363     /* check that ICMP type is something we want to support
2364        and possibly make up payload! */
2365     switch (msg->icmp_header.type)
2366     {
2367     case GNUNET_TUN_ICMPTYPE_ECHO_REPLY:
2368     case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST:
2369       break;
2370     case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE:
2371     case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH:
2372     case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED:
2373       if (0 != pkt_len)
2374       {
2375         GNUNET_break_op (0);
2376         return GNUNET_SYSERR;
2377       }
2378       /* make up payload */
2379       {
2380         struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header *) buf;
2381         struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1];
2382
2383         GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
2384         pkt_len = sizeof (struct GNUNET_TUN_IPv4Header) + 8;
2385         make_up_icmpv4_payload (state,
2386                                 ipp,
2387                                 udp);
2388         payload = ipp;
2389       }
2390       break;
2391     default:
2392       GNUNET_break_op (0);
2393       GNUNET_STATISTICS_update (stats,
2394                                 gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
2395                                 1, GNUNET_NO);
2396       return GNUNET_SYSERR;
2397     }
2398     /* end AF_INET */
2399     break;
2400   case AF_INET6:
2401     if (pkt_len < sizeof (struct in6_addr))
2402     {
2403       GNUNET_break_op (0);
2404       return GNUNET_SYSERR;
2405     }
2406     if (! ipv6_exit)
2407     {
2408       GNUNET_break_op (0);
2409       return GNUNET_SYSERR;
2410     }
2411     v6 = (const struct in6_addr*) &msg[1];
2412     payload = &v6[1];
2413     pkt_len -= sizeof (struct in6_addr);
2414     state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
2415     if (NULL == state->specifics.tcp_udp.heap_node)
2416     {
2417       state->specifics.tcp_udp.ri.remote_address.af = af;
2418       state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMPV6;
2419       setup_state_record (state);
2420     }
2421     /* check that ICMP type is something we want to support
2422        and possibly make up payload! */
2423     switch (msg->icmp_header.type)
2424     {
2425     case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY:
2426     case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
2427       break;
2428     case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
2429     case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
2430     case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
2431     case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM:
2432       if (0 != pkt_len)
2433       {
2434         GNUNET_break_op (0);
2435         return GNUNET_SYSERR;
2436       }
2437       /* make up payload */
2438       {
2439         struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header *) buf;
2440         struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1];
2441
2442         GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
2443         pkt_len = sizeof (struct GNUNET_TUN_IPv6Header) + 8;
2444         make_up_icmpv6_payload (state,
2445                                 ipp,
2446                                 udp);
2447         payload = ipp;
2448       }
2449       break;
2450     default:
2451       GNUNET_break_op (0);
2452       GNUNET_STATISTICS_update (stats,
2453                                 gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
2454                                 1, GNUNET_NO);
2455       return GNUNET_SYSERR;
2456     }
2457     /* end AF_INET6 */
2458     break;
2459   default:
2460     /* bad AF */
2461     GNUNET_break_op (0);
2462     return GNUNET_SYSERR;
2463   }
2464
2465   {
2466     char buf[INET6_ADDRSTRLEN];
2467     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2468                 "Received ICMP data from %s for forwarding to %s\n",
2469                 GNUNET_i2s (&state->peer),
2470                 inet_ntop (af,
2471                            &state->specifics.tcp_udp.ri.remote_address.address,
2472                            buf, sizeof (buf)));
2473   }
2474   send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2475                             &state->specifics.tcp_udp.ri.local_address,
2476                             &msg->icmp_header,
2477                             payload, pkt_len);
2478   return GNUNET_YES;
2479 }
2480
2481
2482 /**
2483  * Setup ICMP payload for ICMP error messages. Called
2484  * for both IPv4 and IPv6 addresses.
2485  *
2486  * @param state context for creating the IP Packet
2487  * @param buf where to create the payload, has at least
2488  *       sizeof (struct GNUNET_TUN_IPv6Header) + 8 bytes
2489  * @return number of bytes of payload we created in buf
2490  */
2491 static uint16_t
2492 make_up_icmp_service_payload (struct ChannelState *state,
2493                               char *buf)
2494 {
2495   switch (state->specifics.tcp_udp.serv->address.af)
2496   {
2497   case AF_INET:
2498     {
2499       struct GNUNET_TUN_IPv4Header *ipv4;
2500       struct GNUNET_TUN_UdpHeader *udp;
2501
2502       ipv4 = (struct GNUNET_TUN_IPv4Header *)buf;
2503       udp = (struct GNUNET_TUN_UdpHeader *) &ipv4[1];
2504       make_up_icmpv4_payload (state,
2505                               ipv4,
2506                               udp);
2507       GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
2508       return sizeof (struct GNUNET_TUN_IPv4Header) + 8;
2509     }
2510     break;
2511   case AF_INET6:
2512     {
2513       struct GNUNET_TUN_IPv6Header *ipv6;
2514       struct GNUNET_TUN_UdpHeader *udp;
2515
2516       ipv6 = (struct GNUNET_TUN_IPv6Header *)buf;
2517       udp = (struct GNUNET_TUN_UdpHeader *) &ipv6[1];
2518       make_up_icmpv6_payload (state,
2519                               ipv6,
2520                               udp);
2521       GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
2522       return sizeof (struct GNUNET_TUN_IPv6Header) + 8;
2523     }
2524     break;
2525   default:
2526     GNUNET_break (0);
2527   }
2528   return 0;
2529 }
2530
2531
2532 /**
2533  * Process a request via mesh to send ICMP data to a service
2534  * offered by this system.
2535  *
2536  * @param cls closure, NULL
2537  * @param channel connection to the other end
2538  * @param channel_ctx pointer to our 'struct ChannelState *'
2539  * @param message the actual message
2540  * @return #GNUNET_OK to keep the connection open,
2541  *         #GNUNET_SYSERR to close it (signal serious error)
2542  */
2543 static int
2544 receive_icmp_service (void *cls,
2545                       struct GNUNET_MESH_Channel *channel,
2546                       void **channel_ctx,
2547                       const struct GNUNET_MessageHeader *message)
2548 {
2549   struct ChannelState *state = *channel_ctx;
2550   const struct GNUNET_EXIT_IcmpServiceMessage *msg;
2551   uint16_t pkt_len = ntohs (message->size);
2552   struct GNUNET_TUN_IcmpHeader icmp;
2553   char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
2554   const void *payload;
2555
2556   if (GNUNET_YES == state->is_dns)
2557   {
2558     GNUNET_break_op (0);
2559     return GNUNET_SYSERR;
2560   }
2561   if (GNUNET_SYSERR == state->is_dns)
2562   {
2563     /* channel is UDP/TCP from now on */
2564     state->is_dns = GNUNET_NO;
2565   }
2566   GNUNET_STATISTICS_update (stats,
2567                             gettext_noop ("# Bytes received from MESH"),
2568                             pkt_len, GNUNET_NO);
2569   GNUNET_STATISTICS_update (stats,
2570                             gettext_noop ("# ICMP service requests received via mesh"),
2571                             1, GNUNET_NO);
2572   /* check that we got at least a valid header */
2573   if (pkt_len < sizeof (struct GNUNET_EXIT_IcmpServiceMessage))
2574   {
2575     GNUNET_break_op (0);
2576     return GNUNET_SYSERR;
2577   }
2578   msg = (const struct GNUNET_EXIT_IcmpServiceMessage*) message;
2579   pkt_len -= sizeof (struct GNUNET_EXIT_IcmpServiceMessage);
2580   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2581               "Received data from %s for forwarding to ICMP service %s\n",
2582               GNUNET_i2s (&state->peer),
2583               GNUNET_h2s (&msg->service_descriptor));
2584   if (NULL == state->specifics.tcp_udp.serv)
2585   {
2586     /* first packet to service must not be ICMP (cannot determine service!) */
2587     GNUNET_break_op (0);
2588     return GNUNET_SYSERR;
2589   }
2590   icmp = msg->icmp_header;
2591   payload = &msg[1];
2592   state->specifics.tcp_udp.ri.remote_address = state->specifics.tcp_udp.serv->address;
2593   setup_state_record (state);
2594
2595   /* check that ICMP type is something we want to support,
2596      perform ICMP PT if needed ans possibly make up payload */
2597   switch (msg->af)
2598   {
2599   case AF_INET:
2600     switch (msg->icmp_header.type)
2601     {
2602     case GNUNET_TUN_ICMPTYPE_ECHO_REPLY:
2603       if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2604         icmp.type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY;
2605       break;
2606     case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST:
2607       if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2608         icmp.type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST;
2609       break;
2610     case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE:
2611       if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2612         icmp.type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE;
2613       if (0 != pkt_len)
2614       {
2615         GNUNET_break_op (0);
2616         return GNUNET_SYSERR;
2617       }
2618       payload = buf;
2619       pkt_len = make_up_icmp_service_payload (state, buf);
2620       break;
2621     case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED:
2622       if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2623         icmp.type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED;
2624       if (0 != pkt_len)
2625       {
2626         GNUNET_break_op (0);
2627         return GNUNET_SYSERR;
2628       }
2629       payload = buf;
2630       pkt_len = make_up_icmp_service_payload (state, buf);
2631       break;
2632     case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH:
2633       if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2634       {
2635         GNUNET_STATISTICS_update (stats,
2636                                   gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"),
2637                                   1, GNUNET_NO);
2638         return GNUNET_OK;
2639       }
2640       if (0 != pkt_len)
2641       {
2642         GNUNET_break_op (0);
2643         return GNUNET_SYSERR;
2644       }
2645       payload = buf;
2646       pkt_len = make_up_icmp_service_payload (state, buf);
2647       break;
2648     default:
2649       GNUNET_break_op (0);
2650       GNUNET_STATISTICS_update (stats,
2651                                 gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
2652                                 1, GNUNET_NO);
2653       return GNUNET_SYSERR;
2654     }
2655     /* end of AF_INET */
2656     break;
2657   case AF_INET6:
2658     switch (msg->icmp_header.type)
2659     {
2660     case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY:
2661       if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2662         icmp.type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY;
2663       break;
2664     case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
2665       if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2666         icmp.type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST;
2667       break;
2668     case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
2669       if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2670         icmp.type = GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE;
2671       if (0 != pkt_len)
2672       {
2673         GNUNET_break_op (0);
2674         return GNUNET_SYSERR;
2675       }
2676       payload = buf;
2677       pkt_len = make_up_icmp_service_payload (state, buf);
2678       break;
2679     case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
2680       if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2681         icmp.type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED;
2682       if (0 != pkt_len)
2683       {
2684         GNUNET_break_op (0);
2685         return GNUNET_SYSERR;
2686       }
2687       payload = buf;
2688       pkt_len = make_up_icmp_service_payload (state, buf);
2689       break;
2690     case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
2691     case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM:
2692       if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2693       {
2694         GNUNET_STATISTICS_update (stats,
2695                                   gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"),
2696                                   1, GNUNET_NO);
2697         return GNUNET_OK;
2698       }
2699       if (0 != pkt_len)
2700       {
2701         GNUNET_break_op (0);
2702         return GNUNET_SYSERR;
2703       }
2704       payload = buf;
2705       pkt_len = make_up_icmp_service_payload (state, buf);
2706       break;
2707     default:
2708       GNUNET_break_op (0);
2709       GNUNET_STATISTICS_update (stats,
2710                                 gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
2711                                 1, GNUNET_NO);
2712       return GNUNET_SYSERR;
2713     }
2714     /* end of AF_INET6 */
2715     break;
2716   default:
2717     GNUNET_break_op (0);
2718     return GNUNET_SYSERR;
2719   }
2720
2721   send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2722                             &state->specifics.tcp_udp.ri.local_address,
2723                             &icmp,
2724                             payload, pkt_len);
2725   return GNUNET_YES;
2726 }
2727
2728
2729 /**
2730  * Send a UDP packet via the TUN interface.
2731  *
2732  * @param destination_address IP and port to use for the UDP packet's destination
2733  * @param source_address IP and port to use for the UDP packet's source
2734  * @param payload payload of the UDP packet (does NOT include UDP header)
2735  * @param payload_length number of bytes of data in @a payload
2736  */
2737 static void
2738 send_udp_packet_via_tun (const struct SocketAddress *destination_address,
2739                          const struct SocketAddress *source_address,
2740                          const void *payload, size_t payload_length)
2741 {
2742   size_t len;
2743
2744   GNUNET_STATISTICS_update (stats,
2745                             gettext_noop ("# UDP packets sent via TUN"),
2746                             1, GNUNET_NO);
2747   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2748               "Sending packet with %u bytes UDP payload via TUN\n",
2749               (unsigned int) payload_length);
2750   len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader);
2751   switch (source_address->af)
2752   {
2753   case AF_INET:
2754     len += sizeof (struct GNUNET_TUN_IPv4Header);
2755     break;
2756   case AF_INET6:
2757     len += sizeof (struct GNUNET_TUN_IPv6Header);
2758     break;
2759   default:
2760     GNUNET_break (0);
2761     return;
2762   }
2763   len += sizeof (struct GNUNET_TUN_UdpHeader);
2764   len += payload_length;
2765   if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
2766   {
2767     GNUNET_break (0);
2768     return;
2769   }
2770   {
2771     char buf[len] GNUNET_ALIGN;
2772     struct GNUNET_MessageHeader *hdr;
2773     struct GNUNET_TUN_Layer2PacketHeader *tun;
2774
2775     hdr= (struct GNUNET_MessageHeader *) buf;
2776     hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
2777     hdr->size = htons (len);
2778     tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
2779     tun->flags = htons (0);
2780     switch (source_address->af)
2781     {
2782     case AF_INET:
2783       {
2784         struct GNUNET_TUN_IPv4Header * ipv4 = (struct GNUNET_TUN_IPv4Header*) &tun[1];
2785
2786         tun->proto = htons (ETH_P_IPV4);
2787         prepare_ipv4_packet (payload, payload_length,
2788                              IPPROTO_UDP,
2789                              NULL,
2790                              source_address,
2791                              destination_address,
2792                              ipv4);
2793       }
2794       break;
2795     case AF_INET6:
2796       {
2797         struct GNUNET_TUN_IPv6Header * ipv6 = (struct GNUNET_TUN_IPv6Header*) &tun[1];
2798
2799         tun->proto = htons (ETH_P_IPV6);
2800         prepare_ipv6_packet (payload, payload_length,
2801                              IPPROTO_UDP,
2802                              NULL,
2803                              source_address,
2804                              destination_address,
2805                              ipv6);
2806       }
2807       break;
2808     default:
2809       GNUNET_assert (0);
2810       break;
2811     }
2812     if (NULL != helper_handle)
2813       (void) GNUNET_HELPER_send (helper_handle,
2814                                  (const struct GNUNET_MessageHeader*) buf,
2815                                  GNUNET_YES,
2816                                  NULL, NULL);
2817   }
2818 }
2819
2820
2821 /**
2822  * Process a request to forward UDP data to the Internet via this peer.
2823  *
2824  * @param cls closure, NULL
2825  * @param channel connection to the other end
2826  * @param channel_ctx pointer to our 'struct ChannelState *'
2827  * @param message the actual message
2828  * @return #GNUNET_OK to keep the connection open,
2829  *         #GNUNET_SYSERR to close it (signal serious error)
2830  */
2831 static int
2832 receive_udp_remote (void *cls,
2833                     struct GNUNET_MESH_Channel *channel,
2834                     void **channel_ctx,
2835                     const struct GNUNET_MessageHeader *message)
2836 {
2837   struct ChannelState *state = *channel_ctx;
2838   const struct GNUNET_EXIT_UdpInternetMessage *msg;
2839   uint16_t pkt_len = ntohs (message->size);
2840   const struct in_addr *v4;
2841   const struct in6_addr *v6;
2842   const void *payload;
2843   int af;
2844
2845   if (GNUNET_YES == state->is_dns)
2846   {
2847     GNUNET_break_op (0);
2848     return GNUNET_SYSERR;
2849   }
2850   if (GNUNET_SYSERR == state->is_dns)
2851   {
2852     /* channel is UDP/TCP from now on */
2853     state->is_dns = GNUNET_NO;
2854   }
2855   GNUNET_STATISTICS_update (stats,
2856                             gettext_noop ("# Bytes received from MESH"),
2857                             pkt_len, GNUNET_NO);
2858   GNUNET_STATISTICS_update (stats,
2859                             gettext_noop ("# UDP IP-exit requests received via mesh"),
2860                             1, GNUNET_NO);
2861   if (pkt_len < sizeof (struct GNUNET_EXIT_UdpInternetMessage))
2862   {
2863     GNUNET_break_op (0);
2864     return GNUNET_SYSERR;
2865   }
2866   msg = (const struct GNUNET_EXIT_UdpInternetMessage*) message;
2867   pkt_len -= sizeof (struct GNUNET_EXIT_UdpInternetMessage);
2868   af = (int) ntohl (msg->af);
2869   state->specifics.tcp_udp.ri.remote_address.af = af;
2870   switch (af)
2871   {
2872   case AF_INET:
2873     if (pkt_len < sizeof (struct in_addr))
2874     {
2875       GNUNET_break_op (0);
2876       return GNUNET_SYSERR;
2877     }
2878     if (! ipv4_exit)
2879     {
2880       GNUNET_break_op (0);
2881       return GNUNET_SYSERR;
2882     }
2883     v4 = (const struct in_addr*) &msg[1];
2884     payload = &v4[1];
2885     pkt_len -= sizeof (struct in_addr);
2886     state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
2887     break;
2888   case AF_INET6:
2889     if (pkt_len < sizeof (struct in6_addr))
2890     {
2891       GNUNET_break_op (0);
2892       return GNUNET_SYSERR;
2893     }
2894     if (! ipv6_exit)
2895     {
2896       GNUNET_break_op (0);
2897       return GNUNET_SYSERR;
2898     }
2899     v6 = (const struct in6_addr*) &msg[1];
2900     payload = &v6[1];
2901     pkt_len -= sizeof (struct in6_addr);
2902     state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
2903     break;
2904   default:
2905     GNUNET_break_op (0);
2906     return GNUNET_SYSERR;
2907   }
2908   {
2909     char buf[INET6_ADDRSTRLEN];
2910     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2911                 "Received data from %s for forwarding to UDP %s:%u\n",
2912                 GNUNET_i2s (&state->peer),
2913                 inet_ntop (af,
2914                            &state->specifics.tcp_udp.ri.remote_address.address,
2915                            buf, sizeof (buf)),
2916                 (unsigned int) ntohs (msg->destination_port));
2917   }
2918   state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_UDP;
2919   state->specifics.tcp_udp.ri.remote_address.port = msg->destination_port;
2920   if (NULL == state->specifics.tcp_udp.heap_node)
2921     setup_state_record (state);
2922   if (0 != ntohs (msg->source_port))
2923     state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
2924   send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2925                            &state->specifics.tcp_udp.ri.local_address,
2926                            payload, pkt_len);
2927   return GNUNET_YES;
2928 }
2929
2930
2931 /**
2932  * Process a request via mesh to send a request to a UDP service
2933  * offered by this system.
2934  *
2935  * @param cls closure, NULL
2936  * @param channel connection to the other end
2937  * @param channel_ctx pointer to our 'struct ChannelState *'
2938  * @param message the actual message
2939  * @return #GNUNET_OK to keep the connection open,
2940  *         #GNUNET_SYSERR to close it (signal serious error)
2941  */
2942 static int
2943 receive_udp_service (void *cls,
2944                      struct GNUNET_MESH_Channel *channel,
2945                      void **channel_ctx,
2946                      const struct GNUNET_MessageHeader *message)
2947 {
2948   struct ChannelState *state = *channel_ctx;
2949   const struct GNUNET_EXIT_UdpServiceMessage *msg;
2950   uint16_t pkt_len = ntohs (message->size);
2951
2952   if (GNUNET_YES == state->is_dns)
2953   {
2954     GNUNET_break_op (0);
2955     return GNUNET_SYSERR;
2956   }
2957   if (GNUNET_SYSERR == state->is_dns)
2958   {
2959     /* channel is UDP/TCP from now on */
2960     state->is_dns = GNUNET_NO;
2961   }
2962   GNUNET_STATISTICS_update (stats,
2963                             gettext_noop ("# Bytes received from MESH"),
2964                             pkt_len, GNUNET_NO);
2965   GNUNET_STATISTICS_update (stats,
2966                             gettext_noop ("# UDP service requests received via mesh"),
2967                             1, GNUNET_NO);
2968   /* check that we got at least a valid header */
2969   if (pkt_len < sizeof (struct GNUNET_EXIT_UdpServiceMessage))
2970   {
2971     GNUNET_break_op (0);
2972     return GNUNET_SYSERR;
2973   }
2974   msg = (const struct GNUNET_EXIT_UdpServiceMessage*) message;
2975   pkt_len -= sizeof (struct GNUNET_EXIT_UdpServiceMessage);
2976   LOG (GNUNET_ERROR_TYPE_DEBUG,
2977        "Received data from %s for forwarding to UDP service %s on port %u\n",
2978        GNUNET_i2s (&state->peer),
2979        GNUNET_h2s (&msg->service_descriptor),
2980        (unsigned int) ntohs (msg->destination_port));
2981   if (NULL == (state->specifics.tcp_udp.serv = find_service (udp_services, &msg->service_descriptor,
2982                                                              ntohs (msg->destination_port))))
2983   {
2984     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2985                 _("No service found for %s on port %d!\n"),
2986                 "UDP",
2987                 ntohs (msg->destination_port));
2988     GNUNET_STATISTICS_update (stats,
2989                               gettext_noop ("# UDP requests dropped (no such service)"),
2990                               1, GNUNET_NO);
2991     return GNUNET_SYSERR;
2992   }
2993   state->specifics.tcp_udp.ri.remote_address = state->specifics.tcp_udp.serv->address;
2994   setup_state_record (state);
2995   if (0 != ntohs (msg->source_port))
2996     state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
2997   send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2998                            &state->specifics.tcp_udp.ri.local_address,
2999                            &msg[1], pkt_len);
3000   return GNUNET_YES;
3001 }
3002
3003
3004 /**
3005  * Callback from GNUNET_MESH for new channels.
3006  *
3007  * @param cls closure
3008  * @param channel new handle to the channel
3009  * @param initiator peer that started the channel
3010  * @param port destination port
3011  * @param options channel options flags
3012  * @return initial channel context for the channel
3013  */
3014 static void *
3015 new_channel (void *cls,
3016             struct GNUNET_MESH_Channel *channel,
3017             const struct GNUNET_PeerIdentity *initiator,
3018             uint32_t port, enum GNUNET_MESH_ChannelOption options)
3019 {
3020   struct ChannelState *s = GNUNET_new (struct ChannelState);
3021
3022   s->is_dns = GNUNET_SYSERR;
3023   s->peer = *initiator;
3024   GNUNET_STATISTICS_update (stats,
3025                             gettext_noop ("# Inbound MESH channels created"),
3026                             1, GNUNET_NO);
3027   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3028               "Received inbound channel from `%s'\n",
3029               GNUNET_i2s (initiator));
3030   s->channel = channel;
3031   return s;
3032 }
3033
3034
3035 /**
3036  * Function called by mesh whenever an inbound channel is destroyed.
3037  * Should clean up any associated state.
3038  *
3039  * @param cls closure (set from #GNUNET_MESH_connect)
3040  * @param channel connection to the other end (henceforth invalid)
3041  * @param channel_ctx place where local state associated
3042  *                   with the channel is stored
3043  */
3044 static void
3045 clean_channel (void *cls,
3046               const struct GNUNET_MESH_Channel *channel,
3047               void *channel_ctx)
3048 {
3049   struct ChannelState *s = channel_ctx;
3050   struct ChannelMessageQueue *tnq;
3051
3052   LOG (GNUNET_ERROR_TYPE_DEBUG,
3053        "Channel destroyed\n");
3054   if (GNUNET_SYSERR == s->is_dns)
3055   {
3056     GNUNET_free (s);
3057     return;
3058   }
3059   if (GNUNET_YES == s->is_dns)
3060   {
3061     if (channels[s->specifics.dns.my_id] == s)
3062       channels[s->specifics.dns.my_id] = NULL;
3063     GNUNET_free_non_null (s->specifics.dns.reply);
3064   }
3065   else
3066   {
3067     while (NULL != (tnq = s->specifics.tcp_udp.head))
3068     {
3069       GNUNET_CONTAINER_DLL_remove (s->specifics.tcp_udp.head,
3070                                    s->specifics.tcp_udp.tail,
3071                                    tnq);
3072       GNUNET_free (tnq);
3073     }
3074     if (NULL != s->specifics.tcp_udp.heap_node)
3075     {
3076       GNUNET_assert (GNUNET_YES ==
3077                      GNUNET_CONTAINER_multihashmap_remove (connections_map,
3078                                                            &s->specifics.tcp_udp.state_key,
3079                                                            s));
3080       GNUNET_CONTAINER_heap_remove_node (s->specifics.tcp_udp.heap_node);
3081       s->specifics.tcp_udp.heap_node = NULL;
3082     }
3083   }
3084   if (NULL != s->th)
3085   {
3086     GNUNET_MESH_notify_transmit_ready_cancel (s->th);
3087     s->th = NULL;
3088   }
3089   GNUNET_free (s);
3090 }
3091
3092
3093 /**
3094  * Function that frees everything from a hashmap
3095  *
3096  * @param cls unused
3097  * @param hash key
3098  * @param value value to free
3099  */
3100 static int
3101 free_iterate (void *cls,
3102               const struct GNUNET_HashCode * hash,
3103               void *value)
3104 {
3105   GNUNET_free (value);
3106   return GNUNET_YES;
3107 }
3108
3109
3110 /**
3111  * Function scheduled as very last function, cleans up after us
3112  */
3113 static void
3114 cleanup (void *cls,
3115          const struct GNUNET_SCHEDULER_TaskContext *tskctx)
3116 {
3117   unsigned int i;
3118
3119   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3120               "Exit service is shutting down now\n");
3121
3122   if (NULL != helper_handle)
3123   {
3124     GNUNET_HELPER_stop (helper_handle, GNUNET_NO);
3125     helper_handle = NULL;
3126   }
3127   if (NULL != regex4)
3128   {
3129     GNUNET_REGEX_announce_cancel (regex4);
3130     regex4 = NULL;
3131   }
3132   if (NULL != regex6)
3133   {
3134     GNUNET_REGEX_announce_cancel (regex6);
3135     regex6 = NULL;
3136   }
3137   if (NULL != mesh_handle)
3138   {
3139     GNUNET_MESH_disconnect (mesh_handle);
3140     mesh_handle = NULL;
3141   }
3142   if (NULL != connections_map)
3143   {
3144     GNUNET_CONTAINER_multihashmap_iterate (connections_map, &free_iterate, NULL);
3145     GNUNET_CONTAINER_multihashmap_destroy (connections_map);
3146     connections_map = NULL;
3147   }
3148   if (NULL != connections_heap)
3149   {
3150     GNUNET_CONTAINER_heap_destroy (connections_heap);
3151     connections_heap = NULL;
3152   }
3153   if (NULL != tcp_services)
3154   {
3155     GNUNET_CONTAINER_multihashmap_iterate (tcp_services, &free_service_record, NULL);
3156     GNUNET_CONTAINER_multihashmap_destroy (tcp_services);
3157     tcp_services = NULL;
3158   }
3159   if (NULL != udp_services)
3160   {
3161     GNUNET_CONTAINER_multihashmap_iterate (udp_services, &free_service_record, NULL);
3162     GNUNET_CONTAINER_multihashmap_destroy (udp_services);
3163     udp_services = NULL;
3164   }
3165   if (NULL != dnsstub)
3166   {
3167     GNUNET_DNSSTUB_stop (dnsstub);
3168     dnsstub = NULL;
3169   }
3170   if (NULL != peer_key)
3171   {
3172     GNUNET_free (peer_key);
3173     peer_key = NULL;
3174   }
3175   if (GNUNET_SCHEDULER_NO_TASK != dht_task)
3176   {
3177     GNUNET_SCHEDULER_cancel (dht_task);
3178     dht_task = GNUNET_SCHEDULER_NO_TASK;
3179   }
3180   if (NULL != dht_put)
3181   {
3182     GNUNET_DHT_put_cancel (dht_put);
3183     dht_put = NULL;
3184   }
3185   if (NULL != dht)
3186   {
3187     GNUNET_DHT_disconnect (dht);
3188     dht = NULL;
3189   }
3190   if (NULL != stats)
3191   {
3192     GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
3193     stats = NULL;
3194   }
3195   for (i=0;i<8;i++)
3196     GNUNET_free_non_null (exit_argv[i]);
3197 }
3198
3199
3200 /**
3201  * Add services to the service map.
3202  *
3203  * @param proto IPPROTO_TCP or IPPROTO_UDP
3204  * @param cpy copy of the service descriptor (can be mutilated)
3205  * @param name DNS name of the service
3206  */
3207 static void
3208 add_services (int proto,
3209               char *cpy,
3210               const char *name)
3211 {
3212   char *redirect;
3213   char *hostname;
3214   char *hostport;
3215   struct LocalService *serv;
3216
3217   for (redirect = strtok (cpy, " "); redirect != NULL;
3218        redirect = strtok (NULL, " "))
3219   {
3220     if (NULL == (hostname = strstr (redirect, ":")))
3221     {
3222       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3223                   "option `%s' for domain `%s' is not formatted correctly!\n",
3224                   redirect,
3225                   name);
3226       continue;
3227     }
3228     hostname[0] = '\0';
3229     hostname++;
3230     if (NULL == (hostport = strstr (hostname, ":")))
3231     {
3232       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3233                   "option `%s' for domain `%s' is not formatted correctly!\n",
3234                   redirect,
3235                   name);
3236       continue;
3237     }
3238     hostport[0] = '\0';
3239     hostport++;
3240
3241     int local_port = atoi (redirect);
3242     int remote_port = atoi (hostport);
3243
3244     if (!((local_port > 0) && (local_port < 65536)))
3245     {
3246       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3247                   "`%s' is not a valid port number (for domain `%s')!", redirect,
3248                   name);
3249       continue;
3250     }
3251     if (!((remote_port > 0) && (remote_port < 65536)))
3252     {
3253       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3254                   "`%s' is not a valid port number (for domain `%s')!", hostport,
3255                   name);
3256       continue;
3257     }
3258
3259     serv = GNUNET_new (struct LocalService);
3260     serv->address.proto = proto;
3261     serv->my_port = (uint16_t) local_port;
3262     serv->address.port = remote_port;
3263     if (0 == strcmp ("localhost4", hostname))
3264     {
3265       const char *ip4addr = exit_argv[5];
3266
3267       serv->address.af = AF_INET;
3268       GNUNET_assert (1 == inet_pton (AF_INET, ip4addr, &serv->address.address.ipv4));
3269     }
3270     else if (0 == strcmp ("localhost6", hostname))
3271     {
3272       const char *ip6addr = exit_argv[3];
3273
3274       serv->address.af = AF_INET6;
3275       GNUNET_assert (1 == inet_pton (AF_INET6, ip6addr, &serv->address.address.ipv6));
3276     }
3277     else
3278     {
3279       struct addrinfo *res;
3280       int ret;
3281
3282       ret = getaddrinfo (hostname, NULL, NULL, &res);
3283       if ( (ret != 0) || (res == NULL) )
3284       {
3285         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3286                     _("No addresses found for hostname `%s' of service `%s'!\n"),
3287                     hostname,
3288                     name);
3289         GNUNET_free (serv);
3290         continue;
3291       }
3292
3293       serv->address.af = res->ai_family;
3294       switch (res->ai_family)
3295       {
3296       case AF_INET:
3297         if (! ipv4_enabled)
3298         {
3299           GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3300                       _("Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
3301                       name);
3302           freeaddrinfo (res);
3303           GNUNET_free (serv);
3304           continue;
3305         }
3306         serv->address.address.ipv4 = ((struct sockaddr_in *) res->ai_addr)->sin_addr;
3307         break;
3308       case AF_INET6:
3309         if (! ipv6_enabled)
3310         {
3311           GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3312                       _("Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
3313                       name);
3314           freeaddrinfo (res);
3315           GNUNET_free (serv);
3316           continue;
3317         }
3318         serv->address.address.ipv6 = ((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
3319         break;
3320       default:
3321         freeaddrinfo (res);
3322         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3323                     _("No IP addresses found for hostname `%s' of service `%s'!\n"),
3324                     hostname,
3325                     name);
3326         GNUNET_free (serv);
3327         continue;
3328       }
3329       freeaddrinfo (res);
3330     }
3331     store_service ((IPPROTO_UDP == proto) ? udp_services : tcp_services,
3332                    name,
3333                    local_port,
3334                    serv);
3335   }
3336 }
3337
3338
3339 /**
3340  * Reads the configuration servicecfg and populates udp_services
3341  *
3342  * @param cls unused
3343  * @param section name of section in config, equal to hostname
3344  */
3345 static void
3346 read_service_conf (void *cls, const char *section)
3347 {
3348   char *cpy;
3349
3350   if ((strlen (section) < 8) ||
3351       (0 != strcmp (".gnunet.", section + (strlen (section) - 8))))
3352     return;
3353   if (GNUNET_OK ==
3354       GNUNET_CONFIGURATION_get_value_string (cfg, section, "UDP_REDIRECTS",
3355                                              &cpy))
3356   {
3357     add_services (IPPROTO_UDP, cpy, section);
3358     GNUNET_free (cpy);
3359   }
3360   if (GNUNET_OK ==
3361       GNUNET_CONFIGURATION_get_value_string (cfg, section, "TCP_REDIRECTS",
3362                                              &cpy))
3363   {
3364     add_services (IPPROTO_TCP, cpy, section);
3365     GNUNET_free (cpy);
3366   }
3367 }
3368
3369
3370 /**
3371  * We are running a DNS exit service, advertise it in the
3372  * DHT.  This task is run periodically to do the DHT PUT.
3373  *
3374  * @param cls closure
3375  * @param tc scheduler context
3376  */
3377 static void
3378 do_dht_put (void *cls,
3379             const struct GNUNET_SCHEDULER_TaskContext *tc);
3380
3381
3382 /**
3383  * Function called when the DHT PUT operation is complete.
3384  * Schedules the next PUT.
3385  *
3386  * @param cls closure, NULL
3387  * @param success #GNUNET_OK if the operation worked (unused)
3388  */
3389 static void
3390 dht_put_cont (void *cls,
3391               int success)
3392 {
3393   dht_put = NULL;
3394   dht_task = GNUNET_SCHEDULER_add_delayed (DHT_PUT_FREQUENCY,
3395                                            &do_dht_put,
3396                                            NULL);
3397 }
3398
3399
3400 /**
3401  * We are running a DNS exit service, advertise it in the
3402  * DHT.  This task is run periodically to do the DHT PUT.
3403  *
3404  * @param cls closure
3405  * @param tc scheduler context
3406  */
3407 static void
3408 do_dht_put (void *cls,
3409             const struct GNUNET_SCHEDULER_TaskContext *tc)
3410 {
3411   struct GNUNET_TIME_Absolute expiration;
3412
3413   dht_task = GNUNET_SCHEDULER_NO_TASK;
3414   expiration = GNUNET_TIME_absolute_ntoh (dns_advertisement.expiration_time);
3415   if (GNUNET_TIME_absolute_get_remaining (expiration).rel_value_us <
3416       GNUNET_TIME_UNIT_HOURS.rel_value_us)
3417   {
3418     /* refresh advertisement */
3419     expiration = GNUNET_TIME_relative_to_absolute (DNS_ADVERTISEMENT_TIMEOUT);
3420     dns_advertisement.expiration_time = GNUNET_TIME_absolute_hton (expiration);
3421     GNUNET_assert (GNUNET_OK ==
3422                    GNUNET_CRYPTO_eddsa_sign (peer_key,
3423                                            &dns_advertisement.purpose,
3424                                            &dns_advertisement.signature));
3425   }
3426   dht_put = GNUNET_DHT_put (dht,
3427                             &dht_put_key,
3428                             1 /* replication */,
3429                             GNUNET_DHT_RO_NONE,
3430                             GNUNET_BLOCK_TYPE_DNS,
3431                             sizeof (struct GNUNET_DNS_Advertisement),
3432                             &dns_advertisement,
3433                             expiration,
3434                             GNUNET_TIME_UNIT_FOREVER_REL,
3435                             &dht_put_cont, NULL);
3436 }
3437
3438
3439 /**
3440  * @brief Main function that will be run by the scheduler.
3441  *
3442  * @param cls closure
3443  * @param args remaining command-line arguments
3444  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
3445  * @param cfg_ configuration
3446  */
3447 static void
3448 run (void *cls,
3449      char *const *args,
3450      const char *cfgfile,
3451      const struct GNUNET_CONFIGURATION_Handle *cfg_)
3452 {
3453   static struct GNUNET_MESH_MessageHandler handlers[] = {
3454     {&receive_icmp_service, GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE, 0},
3455     {&receive_icmp_remote, GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET, 0},
3456     {&receive_udp_service, GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE, 0},
3457     {&receive_udp_remote, GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET, 0},
3458     {&receive_tcp_service, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START, 0},
3459     {&receive_tcp_remote, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START, 0},
3460     {&receive_tcp_data, GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT, 0},
3461     {&receive_dns_request, GNUNET_MESSAGE_TYPE_VPN_DNS_TO_INTERNET, 0},
3462     {NULL, 0, 0}
3463   };
3464
3465   static uint32_t apptypes[] = {
3466     GNUNET_APPLICATION_TYPE_END,
3467     GNUNET_APPLICATION_TYPE_END,
3468     GNUNET_APPLICATION_TYPE_END,
3469     GNUNET_APPLICATION_TYPE_END
3470   };
3471   unsigned int app_idx;
3472   char *exit_ifname;
3473   char *tun_ifname;
3474   char *policy;
3475   char *ipv6addr;
3476   char *ipv6prefix_s;
3477   char *ipv4addr;
3478   char *ipv4mask;
3479   char *binary;
3480   char *regex;
3481   char *prefixed_regex;
3482   struct in_addr dns_exit4;
3483   struct in6_addr dns_exit6;
3484   char *dns_exit;
3485
3486   cfg = cfg_;
3487   ipv4_exit = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "EXIT_IPV4");
3488   ipv6_exit = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "EXIT_IPV6");
3489   ipv4_enabled = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_IPV4");
3490   ipv6_enabled = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_IPV6");
3491   if ( (ipv4_exit) || (ipv6_exit) )
3492   {
3493     binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-exit");
3494     if (GNUNET_YES !=
3495         GNUNET_OS_check_helper_binary (binary, GNUNET_YES, "-d gnunet-vpn - - - 169.1.3.3.7 255.255.255.0")) //no nat, ipv4 only
3496     {
3497       GNUNET_free (binary);
3498       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3499                   _("`%s' must be installed SUID, refusing to run\n"),
3500                   "gnunet-helper-exit");
3501       global_ret = 1;
3502       return;
3503     }
3504     GNUNET_free (binary);
3505   }
3506   stats = GNUNET_STATISTICS_create ("exit", cfg);
3507
3508   if ( (ipv4_exit || ipv4_enabled) &&
3509        GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET))
3510   {
3511     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3512                 _("This system does not support IPv4, will disable IPv4 functions despite them being enabled in the configuration\n"));
3513     ipv4_exit = GNUNET_NO;
3514     ipv4_enabled = GNUNET_NO;
3515   }
3516   if ( (ipv6_exit || ipv6_enabled) &&
3517        GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET6))
3518   {
3519     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3520                 _("This system does not support IPv6, will disable IPv6 functions despite them being enabled in the configuration\n"));
3521     ipv6_exit = GNUNET_NO;
3522     ipv6_enabled = GNUNET_NO;
3523   }
3524   if (ipv4_exit && (! ipv4_enabled))
3525   {
3526     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3527                 _("Cannot enable IPv4 exit but disable IPv4 on TUN interface, will use ENABLE_IPv4=YES\n"));
3528     ipv4_enabled = GNUNET_YES;
3529   }
3530   if (ipv6_exit && (! ipv6_enabled))
3531   {
3532     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3533                 _("Cannot enable IPv6 exit but disable IPv6 on TUN interface, will use ENABLE_IPv6=YES\n"));
3534     ipv6_enabled = GNUNET_YES;
3535   }
3536   if (! (ipv4_enabled || ipv6_enabled))
3537   {
3538     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3539                 _("No useful service enabled.  Exiting.\n"));
3540     GNUNET_SCHEDULER_shutdown ();
3541     return;
3542   }
3543
3544   dns_exit = NULL;
3545   if ( (GNUNET_YES ==
3546         GNUNET_CONFIGURATION_get_value_yesno (cfg_, "exit", "ENABLE_DNS")) &&
3547        ( (GNUNET_OK !=
3548           GNUNET_CONFIGURATION_get_value_string (cfg, "exit",
3549                                                  "DNS_RESOLVER",
3550                                                  &dns_exit)) ||
3551          ( (1 != inet_pton (AF_INET, dns_exit, &dns_exit4)) &&
3552            (1 != inet_pton (AF_INET6, dns_exit, &dns_exit6)) ) ) )
3553   {
3554     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
3555                                "dns", "DNS_RESOLVER",
3556                                _("need a valid IPv4 or IPv6 address\n"));
3557     GNUNET_free_non_null (dns_exit);
3558     dns_exit = NULL;
3559   }
3560   if (NULL != dns_exit)
3561     dnsstub = GNUNET_DNSSTUB_start (dns_exit);
3562
3563
3564   app_idx = 0;
3565   if (GNUNET_YES == ipv4_exit)
3566   {
3567     // FIXME use regex to put info
3568     apptypes[app_idx] = GNUNET_APPLICATION_TYPE_IPV4_GATEWAY;
3569     app_idx++;
3570   }
3571   if (GNUNET_YES == ipv6_exit)
3572   {
3573     // FIXME use regex to put info
3574     apptypes[app_idx] = GNUNET_APPLICATION_TYPE_IPV6_GATEWAY;
3575     app_idx++;
3576   }
3577   if (NULL != dns_exit)
3578   {
3579     dht = GNUNET_DHT_connect (cfg, 1);
3580     peer_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg);
3581     GNUNET_CRYPTO_eddsa_key_get_public (peer_key,
3582                                                     &dns_advertisement.peer.public_key);
3583     dns_advertisement.purpose.size = htonl (sizeof (struct GNUNET_DNS_Advertisement) -
3584                                             sizeof (struct GNUNET_CRYPTO_EddsaSignature));
3585     dns_advertisement.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DNS_RECORD);
3586     GNUNET_CRYPTO_hash ("dns",
3587                         strlen ("dns"),
3588                         &dht_put_key);
3589     dht_task = GNUNET_SCHEDULER_add_now (&do_dht_put,
3590                                          NULL);
3591     apptypes[app_idx] = GNUNET_APPLICATION_TYPE_INTERNET_RESOLVER;
3592     app_idx++;
3593   }
3594   GNUNET_free_non_null (dns_exit);
3595   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls);
3596
3597   if (GNUNET_OK !=
3598       GNUNET_CONFIGURATION_get_value_number (cfg, "exit", "MAX_CONNECTIONS",
3599                                              &max_connections))
3600     max_connections = 1024;
3601   exit_argv[0] = GNUNET_strdup ("exit-gnunet");
3602   if (GNUNET_SYSERR ==
3603       GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "TUN_IFNAME", &tun_ifname))
3604   {
3605     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "EXIT", "TUN_IFNAME");
3606     GNUNET_SCHEDULER_shutdown ();
3607     return;
3608   }
3609   exit_argv[1] = tun_ifname;
3610   if (ipv4_enabled)
3611   {
3612     if (GNUNET_SYSERR ==
3613         GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "EXIT_IFNAME", &exit_ifname))
3614     {
3615       GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "EXIT", "EXIT_IFNAME");
3616       GNUNET_SCHEDULER_shutdown ();
3617       return;
3618     }
3619     exit_argv[2] = exit_ifname;
3620   }
3621   else
3622   {
3623     exit_argv[2] = GNUNET_strdup ("-");
3624   }
3625
3626
3627   if (GNUNET_YES == ipv6_enabled)
3628   {
3629     if ( (GNUNET_SYSERR ==
3630           GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6ADDR",
3631                                                  &ipv6addr) ||
3632           (1 != inet_pton (AF_INET6, ipv6addr, &exit_ipv6addr))) )
3633     {
3634       GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "EXIT", "IPV6ADDR");
3635       GNUNET_SCHEDULER_shutdown ();
3636       return;
3637     }
3638     exit_argv[3] = ipv6addr;
3639     if (GNUNET_SYSERR ==
3640         GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6PREFIX",
3641                                                &ipv6prefix_s))
3642     {
3643       GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "EXIT", "IPV6PREFIX");
3644       GNUNET_SCHEDULER_shutdown ();
3645       return;
3646     }
3647     exit_argv[4] = ipv6prefix_s;
3648     if ( (GNUNET_OK !=
3649           GNUNET_CONFIGURATION_get_value_number (cfg, "exit",
3650                                                  "IPV6PREFIX",
3651                                                  &ipv6prefix)) ||
3652          (ipv6prefix >= 127) )
3653     {
3654       GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "EXIT", "IPV6PREFIX",
3655                                  _("Must be a number"));
3656       GNUNET_SCHEDULER_shutdown ();
3657       return;
3658     }
3659   }
3660   else
3661   {
3662     /* IPv6 explicitly disabled */
3663     exit_argv[3] = GNUNET_strdup ("-");
3664     exit_argv[4] = GNUNET_strdup ("-");
3665   }
3666   if (GNUNET_YES == ipv4_enabled)
3667   {
3668     if ( (GNUNET_SYSERR ==
3669           GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4ADDR",
3670                                                  &ipv4addr) ||
3671           (1 != inet_pton (AF_INET, ipv4addr, &exit_ipv4addr))) )
3672       {
3673         GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "EXIT", "IPV4ADDR");
3674         GNUNET_SCHEDULER_shutdown ();
3675         return;
3676       }
3677     exit_argv[5] = ipv4addr;
3678     ipv4mask = NULL;
3679     if ( (GNUNET_SYSERR ==
3680           GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4MASK",
3681                                                  &ipv4mask) ||
3682           (1 != inet_pton (AF_INET, ipv4mask, &exit_ipv4mask))) )
3683     {
3684       GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "EXIT", "IPV4MASK");
3685       GNUNET_SCHEDULER_shutdown ();
3686       GNUNET_free_non_null (ipv4mask);
3687       return;
3688     }
3689     exit_argv[6] = ipv4mask;
3690   }
3691   else
3692   {
3693     /* IPv4 explicitly disabled */
3694     exit_argv[5] = GNUNET_strdup ("-");
3695     exit_argv[6] = GNUNET_strdup ("-");
3696   }
3697   exit_argv[7] = NULL;
3698
3699   udp_services = GNUNET_CONTAINER_multihashmap_create (65536, GNUNET_NO);
3700   tcp_services = GNUNET_CONTAINER_multihashmap_create (65536, GNUNET_NO);
3701   GNUNET_CONFIGURATION_iterate_sections (cfg, &read_service_conf, NULL);
3702
3703   connections_map = GNUNET_CONTAINER_multihashmap_create (65536, GNUNET_NO);
3704   connections_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
3705   mesh_handle
3706     = GNUNET_MESH_connect (cfg, NULL,
3707                            &new_channel,
3708                            &clean_channel, handlers,
3709                            apptypes); // FIXME use ports
3710   if (NULL == mesh_handle)
3711   {
3712     GNUNET_SCHEDULER_shutdown ();
3713     return;
3714   }
3715
3716   /* Mesh handle acquired, now announce regular expressions matching our exit */
3717   if ( (GNUNET_YES == ipv4_enabled) && (GNUNET_YES == ipv4_exit) )
3718   {
3719     policy = NULL;
3720     if (GNUNET_OK !=
3721         GNUNET_CONFIGURATION_get_value_string (cfg,
3722                                                "exit",
3723                                                "EXIT_RANGE_IPV4_POLICY",
3724                                                &policy))
3725       regex = NULL;
3726     else
3727       regex = GNUNET_TUN_ipv4policy2regex (policy);
3728     GNUNET_free_non_null (policy);
3729     if (NULL != regex)
3730     {
3731       (void) GNUNET_asprintf (&prefixed_regex, "%s%s%s",
3732                               GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX,
3733                               "4", regex);
3734       regex4 = GNUNET_REGEX_announce (cfg,
3735                                       prefixed_regex,
3736                                       REGEX_REFRESH_FREQUENCY,
3737                                       REGEX_MAX_PATH_LEN_IPV4);
3738       GNUNET_free (regex);
3739       GNUNET_free (prefixed_regex);
3740     }
3741   }
3742
3743   if (GNUNET_YES == ipv6_enabled && GNUNET_YES == ipv6_exit)
3744   {
3745     policy = NULL;
3746     if (GNUNET_OK !=
3747         GNUNET_CONFIGURATION_get_value_string (cfg,
3748                                                "exit",
3749                                                "EXIT_RANGE_IPV6_POLICY",
3750                                                &policy))
3751       regex = NULL;
3752     else
3753       regex = GNUNET_TUN_ipv6policy2regex (policy);
3754     GNUNET_free_non_null (policy);
3755     if (NULL != regex)
3756     {
3757       (void) GNUNET_asprintf (&prefixed_regex, "%s%s%s",
3758                               GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX,
3759                               "6", regex);
3760       regex6 = GNUNET_REGEX_announce (cfg,
3761                                       prefixed_regex,
3762                                       REGEX_REFRESH_FREQUENCY,
3763                                       REGEX_MAX_PATH_LEN_IPV6);
3764       GNUNET_free (regex);
3765       GNUNET_free (prefixed_regex);
3766     }
3767   }
3768   if ((ipv4_exit) || (ipv6_exit))
3769     helper_handle = GNUNET_HELPER_start (GNUNET_NO,
3770                                          "gnunet-helper-exit",
3771                                          exit_argv,
3772                                          &message_token,
3773                                          NULL, NULL);
3774 }
3775
3776
3777 /**
3778  * The main function
3779  *
3780  * @param argc number of arguments from the command line
3781  * @param argv command line arguments
3782  * @return 0 ok, 1 on error
3783  */
3784 int
3785 main (int argc, char *const *argv)
3786 {
3787   static const struct GNUNET_GETOPT_CommandLineOption options[] = {
3788     GNUNET_GETOPT_OPTION_END
3789   };
3790
3791   if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
3792     return 2;
3793
3794   return (GNUNET_OK ==
3795           GNUNET_PROGRAM_run (argc, argv, "gnunet-daemon-exit",
3796                               gettext_noop
3797                               ("Daemon to run to provide an IP exit node for the VPN"),
3798                               options, &run, NULL)) ? global_ret : 1;
3799 }
3800
3801
3802 /* end of gnunet-daemon-exit.c */