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