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