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