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