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