77830020e2662afb99346d5f3dffd0d0764845cf
[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 #include <platform.h>
28 #include <gnunet_common.h>
29 #include <gnunet_program_lib.h>
30 #include <gnunet_protocols.h>
31 #include <gnunet_applications.h>
32 #include <gnunet_mesh_service.h>
33 #include <gnunet_constants.h>
34 #include <string.h>
35
36
37 /* see http://www.iana.org/assignments/ethernet-numbers */
38 #ifndef ETH_P_IPV4
39 #define ETH_P_IPV4 0x0800
40 #endif
41
42 #ifndef ETH_P_IPV6
43 #define ETH_P_IPV6 0x86DD
44 #endif
45
46
47 GNUNET_NETWORK_STRUCT_BEGIN
48 /**
49  * Header from Linux TUN interface.
50  */ 
51 struct tun_header
52 {
53   /**
54    * Some flags (unused).
55    */ 
56   uint16_t flags;
57
58   /**
59    * Here we get an ETH_P_-number.
60    */
61   uint16_t proto;
62 };
63
64 /**
65  * Standard IPv4 header.
66  */
67 struct ip4_header
68 {
69   unsigned header_length:4 GNUNET_PACKED;
70   unsigned version:4 GNUNET_PACKED;
71   uint8_t diff_serv;
72   uint16_t total_length GNUNET_PACKED;
73   uint16_t identification GNUNET_PACKED;
74   unsigned flags:3 GNUNET_PACKED;
75   unsigned fragmentation_offset:13 GNUNET_PACKED;
76   uint8_t ttl;
77   uint8_t protocol;
78   uint16_t checksum GNUNET_PACKED;
79   struct in_addr source_address GNUNET_PACKED;
80   struct in_addr destination_address GNUNET_PACKED;
81 };
82
83 /**
84  * Standard IPv6 header.
85  */
86 struct ip6_header
87 {
88   unsigned traffic_class_h:4 GNUNET_PACKED;
89   unsigned version:4 GNUNET_PACKED;
90   unsigned traffic_class_l:4 GNUNET_PACKED;
91   unsigned flow_label:20 GNUNET_PACKED;
92   uint16_t payload_length GNUNET_PACKED;
93   uint8_t next_header;
94   uint8_t hop_limit;
95   struct in6_addr source_address GNUNET_PACKED;
96   struct in6_addr destination_address GNUNET_PACKED;
97 };
98
99 #define TCP_FLAG_SYN 2
100
101 struct tcp_packet
102 {
103   unsigned spt:16 GNUNET_PACKED;
104   unsigned dpt:16 GNUNET_PACKED;
105   unsigned seq:32 GNUNET_PACKED;
106   unsigned ack:32 GNUNET_PACKED;
107   unsigned off:4 GNUNET_PACKED;
108   unsigned rsv:4 GNUNET_PACKED;
109   unsigned flg:8 GNUNET_PACKED;
110   unsigned wsz:16 GNUNET_PACKED;
111   unsigned crc:16 GNUNET_PACKED;
112   unsigned urg:16 GNUNET_PACKED;
113 };
114
115 /**
116  * UDP packet header.
117  */
118 struct udp_packet
119 {
120   uint16_t spt GNUNET_PACKED;
121   uint16_t dpt GNUNET_PACKED;
122   uint16_t len GNUNET_PACKED;
123   uint16_t crc GNUNET_PACKED;
124 };
125
126 /**
127  * DNS header.
128  */
129 struct dns_header
130 {
131   uint16_t id GNUNET_PACKED;
132   uint16_t flags GNUNET_PACKED;
133   uint16_t qdcount GNUNET_PACKED;
134   uint16_t ancount GNUNET_PACKED;
135   uint16_t nscount GNUNET_PACKED;
136   uint16_t arcount GNUNET_PACKED;
137 };
138 GNUNET_NETWORK_STRUCT_END
139
140 /**
141  * Information about an address.
142  */
143 struct SocketAddress
144 {
145   /**
146    * AF_INET or AF_INET6.
147    */
148   int af;
149
150   /**
151    * Remote address information.
152    */
153   union
154   {
155     /**
156      * Address, if af is AF_INET.
157      */
158     struct in_addr ipv4;
159
160     /**
161      * Address, if af is AF_INET6.
162      */
163     struct in6_addr ipv6;
164   } address;
165   
166   /**
167    * IPPROTO_TCP or IPPROTO_UDP;
168    */
169   uint8_t proto;
170
171   /**
172    * Remote port, in host byte order!
173    */
174   uint16_t port;
175
176 };
177
178 /**
179  * This struct is saved into the services-hashmap to represent
180  * a service this peer is specifically offering an exit for
181  * (for a specific domain name).
182  */
183 struct LocalService
184 {
185
186   /**
187    * Remote address to use for the service.
188    */
189   struct SocketAddress address;
190
191   /**
192    * DNS name of the service.
193    */
194   char *name;
195
196   /**
197    * Port I am listening on within GNUnet for this service, in host
198    * byte order.  (as we may redirect ports).
199    */
200   uint16_t my_port;
201
202 };
203
204 /**
205  * Information we use to track a connection (the classical 6-tuple of
206  * IP-version, protocol, source-IP, destination-IP, source-port and
207  * destinatin-port.
208  */
209 struct RedirectInformation 
210 {
211
212   /**
213    * Address information for the other party (equivalent of the
214    * arguments one would give to "connect").
215    */
216   struct SocketAddress remote_address;
217
218   /**
219    * Address information we used locally (AF and proto must match
220    * "remote_address").  Equivalent of the arguments one would give to
221    * "bind".
222    */
223   struct SocketAddress local_address;
224
225   /* 
226      Note 1: additional information might be added here in the
227      future to support protocols that require special handling,
228      such as ftp/tftp 
229
230      Note 2: we might also sometimes not match on all components
231      of the tuple, to support protocols where things do not always
232      fully map.
233   */
234 };
235
236
237 /**
238  * Queue of messages to a tunnel.
239  */
240 struct TunnelMessageQueue
241 {
242   /**
243    * This is a doubly-linked list.
244    */
245   struct TunnelMessageQueue *next;
246
247   /**
248    * This is a doubly-linked list.
249    */
250   struct TunnelMessageQueue *prev;
251
252   /**
253    * Payload to send via the tunnel.
254    */
255   const void *payload;
256
257   /**
258    * Number of bytes in 'payload'.
259    */
260   size_t len;
261 };
262
263
264 /**
265  * This struct is saved into connections_map to allow finding the
266  * right tunnel given an IP packet from TUN.  It is also associated
267  * with the tunnel's closure so we can find it again for the next
268  * message from the tunnel.
269  */
270 struct TunnelState
271 {
272   /**
273    * Mesh tunnel that is used for this connection.
274    */
275   struct GNUNET_MESH_Tunnel *tunnel;
276
277   /**
278    * Heap node for this state in the connections_heap.
279    */
280   struct GNUNET_CONTAINER_HeapNode *heap_node;
281
282   /**
283    * Key this state has in the connections_map.
284    */
285   GNUNET_HashCode state_key;
286
287   /**
288    * Associated service record, or NULL for no service.
289    */
290   struct LocalService *serv;
291
292   /**
293    * Head of DLL of messages for this tunnel.
294    */
295   struct TunnelMessageQueue *head;
296
297   /**
298    * Tail of DLL of messages for this tunnel.
299    */
300   struct TunnelMessageQueue *tail;
301
302   /**
303    * Active tunnel transmission request (or NULL).
304    */
305   struct GNUNET_MESH_TransmitHandle *th;
306
307   /**
308    * Primary redirection information for this connection.
309    */
310   struct RedirectInformation ri;
311
312 };
313
314
315 /**
316  * The handle to the configuration used throughout the process
317  */
318 static const struct GNUNET_CONFIGURATION_Handle *cfg;
319
320 /**
321  * The handle to the helper
322  */
323 static struct GNUNET_HELPER_Handle *helper_handle;
324
325 /**
326  * Arguments to the exit helper.
327  */
328 static char *exit_argv[7];
329
330 /**
331  * IPv6 prefix (0..127) from configuration file.
332  */
333 static unsigned long long ipv6prefix;
334
335 /**
336  * The handle to mesh
337  */
338 static struct GNUNET_MESH_Handle *mesh_handle;
339
340 /**
341  * This hashmaps contains the mapping from peer, service-descriptor,
342  * source-port and destination-port to a struct TunnelState
343  */
344 static struct GNUNET_CONTAINER_MultiHashMap *connections_map;
345
346 /**
347  * Heap so we can quickly find "old" connections.
348  */
349 static struct GNUNET_CONTAINER_Heap *connections_heap;
350
351 /**
352  * If there are at least this many connections, old ones will be removed
353  */
354 static long long unsigned int max_connections = 200;
355
356 /**
357  * This hashmaps saves interesting things about the configured UDP services
358  */
359 static struct GNUNET_CONTAINER_MultiHashMap *udp_services;
360
361 /**
362  * This hashmaps saves interesting things about the configured TCP services
363  */
364 static struct GNUNET_CONTAINER_MultiHashMap *tcp_services;
365
366
367 /**
368  * Given IP information about a connection, calculate the respective
369  * hash we would use for the 'connections_map'.
370  *
371  * @param hash resulting hash
372  * @param ri information about the connection
373  */
374 static void
375 hash_redirect_info (GNUNET_HashCode *hash, 
376                     const struct RedirectInformation *ri)
377 {
378   char *off;
379
380   memset (hash, 0, sizeof (GNUNET_HashCode));
381   /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
382      so we put the IP address in there (and hope for few collisions) */
383   off = (char*) hash;
384   switch (ri->remote_address.af)
385   {
386   case AF_INET:
387     memcpy (off, &ri->remote_address.address.ipv4, sizeof (struct in_addr));
388     off += sizeof (struct in_addr);
389     break;
390   case AF_INET6:
391     memcpy (off, &ri->remote_address.address.ipv6, sizeof (struct in6_addr));
392     off += sizeof (struct in_addr);
393     break;
394   default:
395     GNUNET_assert (0);
396   }
397   memcpy (off, &ri->remote_address.port, sizeof (uint16_t));
398   off += sizeof (uint16_t);
399   switch (ri->local_address.af)
400   {
401   case AF_INET:
402     memcpy (off, &ri->local_address.address.ipv4, sizeof (struct in_addr));
403     off += sizeof (struct in_addr);
404     break;
405   case AF_INET6:
406     memcpy (off, &ri->local_address.address.ipv6, sizeof (struct in6_addr));
407     off += sizeof (struct in_addr);
408     break;
409   default:
410     GNUNET_assert (0);
411   }
412   memcpy (off, &ri->local_address.port, sizeof (uint16_t));
413   off += sizeof (uint16_t);
414   memcpy (off, &ri->remote_address.proto, sizeof (uint8_t));
415   off += sizeof (uint8_t);
416 }
417
418
419 /**
420  * Get our connection tracking state.  Warns if it does not exists,
421  * refreshes the timestamp if it does exist.
422  *
423  * @param af address family
424  * @param protocol IPPROTO_UDP or IPPROTO_TCP
425  * @param destination_ip target IP
426  * @param destination_port target port
427  * @param local_ip local IP
428  * @param local_port local port
429  * @param state_key set to hash's state if non-NULL
430  * @return NULL if we have no tracking information for this tuple
431  */
432 static struct TunnelState *
433 get_redirect_state (int af,
434                     int protocol,                   
435                     const void *destination_ip,
436                     uint16_t destination_port,
437                     const void *local_ip,
438                     uint16_t local_port,
439                     GNUNET_HashCode *state_key)
440 {
441   struct RedirectInformation ri;
442   GNUNET_HashCode key;
443   struct TunnelState *state;
444
445   ri.remote_address.af = af;
446   if (af == AF_INET)
447     ri.remote_address.address.ipv4 = *((struct in_addr*) destination_ip);
448   else
449     ri.remote_address.address.ipv6 = * ((struct in6_addr*) destination_ip);
450   ri.remote_address.port = destination_port;
451   ri.remote_address.proto = protocol;
452   ri.local_address.af = af;
453   if (af == AF_INET)
454     ri.local_address.address.ipv4 = *((struct in_addr*) local_ip);
455   else
456     ri.local_address.address.ipv6 = * ((struct in6_addr*) local_ip);
457   ri.local_address.port = local_port;
458   ri.local_address.proto = protocol;
459   hash_redirect_info (&key, &ri);
460   if (NULL != state_key)
461     *state_key = key;
462   state = GNUNET_CONTAINER_multihashmap_get (connections_map, &key);
463   if (NULL == state)
464     return NULL;
465   /* Mark this connection as freshly used */
466   if (NULL == state_key)
467     GNUNET_CONTAINER_heap_update_cost (connections_heap, 
468                                        state->heap_node,
469                                        GNUNET_TIME_absolute_get ().abs_value);
470   return state;
471 }
472
473
474 /**
475  * Given a service descriptor and a destination port, find the
476  * respective service entry.
477  *
478  * @param service_map map of services (TCP or UDP)
479  * @param desc service descriptor
480  * @param dpt destination port
481  * @return NULL if we are not aware of such a service
482  */
483 static struct LocalService *
484 find_service (struct GNUNET_CONTAINER_MultiHashMap *service_map,
485               const GNUNET_HashCode *desc,
486               uint16_t dpt)
487 {
488   char key[sizeof (GNUNET_HashCode) + sizeof (uint16_t)];
489
490   memcpy (&key[0], &dpt, sizeof (uint16_t));
491   memcpy (&key[sizeof(uint16_t)], desc, sizeof (GNUNET_HashCode));
492   return GNUNET_CONTAINER_multihashmap_get (service_map,
493                                             (GNUNET_HashCode *) key);
494 }
495
496
497 /**
498  * Free memory associated with a service record.
499  *
500  * @param cls unused
501  * @param key service descriptor
502  * @param value service record to free
503  * @return GNUNET_OK
504  */
505 static int
506 free_service_record (void *cls,
507                      const GNUNET_HashCode *key,
508                      void *value)
509 {
510   struct LocalService *service = value;
511
512   GNUNET_free_non_null (service->name);
513   GNUNET_free (service);
514   return GNUNET_OK;
515 }
516
517
518 /**
519  * Given a service descriptor and a destination port, find the
520  * respective service entry.
521  *
522  * @param service_map map of services (TCP or UDP)
523  * @param name name of the service 
524  * @param dpt destination port
525  * @param service service information record to store (service->name will be set).
526  */
527 static void
528 store_service (struct GNUNET_CONTAINER_MultiHashMap *service_map,
529                const char *name,
530                uint16_t dpt,
531                struct LocalService *service)
532 {
533   char key[sizeof (GNUNET_HashCode) + sizeof (uint16_t)];
534   GNUNET_HashCode desc;
535
536   GNUNET_CRYPTO_hash (name, strlen (name) + 1, &desc);
537   service->name = GNUNET_strdup (name);
538   memcpy (&key[0], &dpt, sizeof (uint16_t));
539   memcpy (&key[sizeof(uint16_t)], &desc, sizeof (GNUNET_HashCode));
540   if (GNUNET_OK !=
541       GNUNET_CONTAINER_multihashmap_put (service_map,
542                                          (GNUNET_HashCode *) key,
543                                          service,
544                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
545   {
546     free_service_record (NULL, (GNUNET_HashCode *) key, service);
547     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
548                 _("Got duplicate service records for `%s:%u'\n"),
549                 name,
550                 (unsigned int) dpt);
551   }
552 }
553
554
555 /**
556  * MESH is ready to receive a message for the tunnel.  Transmit it.
557  *
558  * @param cls the 'struct TunnelState'.
559  * @param size number of bytes available in buf
560  * @param buf where to copy the message
561  * @return number of bytes copied to buf
562  */
563 static size_t
564 send_to_peer_notify_callback (void *cls, size_t size, void *buf)
565 {
566   struct TunnelState *s = cls;
567   struct GNUNET_MESH_Tunnel *tunnel = s->tunnel;
568   struct TunnelMessageQueue *tnq;
569
570   s->th = NULL;
571   tnq = s->head;
572   GNUNET_assert (size >= tnq->len);
573   memcpy (buf, tnq->payload, tnq->len);
574   size = tnq->len;
575   GNUNET_CONTAINER_DLL_remove (s->head, 
576                                s->tail,
577                                tnq);  
578   GNUNET_free (tnq);
579   if (NULL != (tnq = s->head))
580     s->th = GNUNET_MESH_notify_transmit_ready (tunnel, 
581                                                GNUNET_NO /* corking */, 
582                                                0 /* priority */,
583                                                GNUNET_TIME_UNIT_FOREVER_REL,
584                                                NULL,
585                                                tnq->len,
586                                                &send_to_peer_notify_callback,
587                                                s);
588   return size;
589 }
590
591
592 /**
593  * Send the given packet via the mesh tunnel.
594  *
595  * @param mesh_tunnel destination
596  * @param payload message to transmit
597  * @param payload_length number of bytes in payload
598  * @param desc descriptor to add before payload (optional)
599  * @param mtype message type to use
600  */
601 static void
602 send_packet_to_mesh_tunnel (struct GNUNET_MESH_Tunnel *mesh_tunnel,
603                             const void *payload,
604                             size_t payload_length,
605                             const GNUNET_HashCode *desc,
606                             uint16_t mtype)
607 {
608   struct TunnelState *s;
609   struct TunnelMessageQueue *tnq;
610   struct GNUNET_MessageHeader *msg;
611   size_t len;
612   GNUNET_HashCode *dp;
613
614   len = sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + payload_length;
615   if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
616   {
617     GNUNET_break (0);
618     return;
619   }
620   tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueue) + len);
621   tnq->payload = &tnq[1];
622   tnq->len = len;
623   msg = (struct GNUNET_MessageHeader *) &tnq[1];
624   msg->size = htons ((uint16_t) len);
625   msg->type = htons (mtype);
626   if (NULL != desc)
627   {
628     dp = (GNUNET_HashCode *) &msg[1];
629     *dp = *desc;  
630     memcpy (&dp[1], payload, payload_length);
631   }
632   else
633   {
634     memcpy (&msg[1], payload, payload_length);
635   }
636   s = GNUNET_MESH_tunnel_get_data (mesh_tunnel);
637   GNUNET_assert (NULL != s);
638   GNUNET_CONTAINER_DLL_insert_tail (s->head, s->tail, tnq);
639   if (NULL == s->th)
640     s->th = GNUNET_MESH_notify_transmit_ready (mesh_tunnel, GNUNET_NO /* cork */, 0 /* priority */,
641                                                GNUNET_TIME_UNIT_FOREVER_REL,
642                                                NULL, len,
643                                                &send_to_peer_notify_callback,
644                                                s);
645 }
646
647
648 /**
649  * @brief Handles an UDP packet received from the helper.
650  *
651  * @param udp A pointer to the Packet
652  * @param pktlen number of bytes in 'udp'
653  * @param af address family (AFINET or AF_INET6)
654  * @param destination_ip destination IP-address of the IP packet (should 
655  *                       be our local address)
656  * @param source_ip original source IP-address of the IP packet (should
657  *                       be the original destination address)
658  */
659 static void
660 udp_from_helper (const struct udp_packet *udp, 
661                  size_t pktlen,
662                  int af,
663                  const void *destination_ip, 
664                  const void *source_ip)
665 {
666   struct TunnelState *state;
667
668   if (pktlen < sizeof (struct udp_packet))
669   {
670     /* blame kernel */
671     GNUNET_break (0);
672     return;
673   }
674   if (pktlen != ntohs (udp->len))
675   {
676     /* blame kernel */
677     GNUNET_break (0);
678     return;
679   }
680   state = get_redirect_state (af, IPPROTO_UDP,
681                               source_ip,
682                               ntohs (udp->spt),
683                               destination_ip,
684                               ntohs (udp->dpt),
685                               NULL);
686   if (NULL == state)
687   {
688     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
689                 _("Packet dropped, have no matching connection information\n"));
690     return;
691   }
692   send_packet_to_mesh_tunnel (state->tunnel,
693                               &udp[1], pktlen - sizeof (struct udp_packet),
694                               NULL,
695                               state->serv != NULL
696                               ? GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK 
697                               : GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP_BACK);
698 }
699
700
701 /**
702  * @brief Handles a TCP packet received from the helper.
703  *
704  * @param tcp A pointer to the Packet
705  * @param pktlen the length of the packet, including its header
706  * @param af address family (AFINET or AF_INET6)
707  * @param destination_ip destination IP-address of the IP packet (should 
708  *                       be our local address)
709  * @param source_ip original source IP-address of the IP packet (should
710  *                       be the original destination address)
711  */
712 static void
713 tcp_from_helper (const struct tcp_packet *tcp, 
714                  size_t pktlen,
715                  int af,
716                  const void *destination_ip,
717                  const void *source_ip)
718 {
719   struct TunnelState *state;
720   char buf[pktlen];
721   struct tcp_packet *mtcp;
722
723   if (pktlen < sizeof (struct tcp_packet))
724   {
725     /* blame kernel */
726     GNUNET_break (0);
727     return;
728   }
729   state = get_redirect_state (af, IPPROTO_TCP,
730                               source_ip, 
731                               ntohs (tcp->spt),
732                               destination_ip,
733                               ntohs (tcp->dpt),
734                               NULL);
735   if (NULL == state)
736   {
737     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
738                 _("Packet dropped, have no matching connection information\n"));
739     
740     return;
741   }
742   /* mug port numbers and crc to avoid information leakage;
743      sender will need to lookup the correct values anyway */
744   memcpy (buf, tcp, pktlen);  
745   mtcp = (struct tcp_packet *) buf;
746   mtcp->spt = 0;
747   mtcp->dpt = 0;
748   mtcp->crc = 0;
749   send_packet_to_mesh_tunnel (state->tunnel,
750                               mtcp, pktlen,
751                               NULL,
752                               state->serv != NULL
753                               ? GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP_BACK 
754                               : GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP_BACK);
755 }
756
757
758 /**
759  * Receive packets from the helper-process
760  *
761  * @param cls unused
762  * @param client unsued
763  * @param message message received from helper
764  */
765 static void
766 message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED,
767                const struct GNUNET_MessageHeader *message)
768 {
769   const struct tun_header *pkt_tun;
770   size_t size;
771
772   if (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER)
773   {
774     GNUNET_break (0);
775     return;
776   }
777   size = ntohs (message->size);
778   if (size < sizeof (struct tun_header) + sizeof (struct GNUNET_MessageHeader))
779   {
780     GNUNET_break (0);
781     return;
782   }
783   pkt_tun = (const struct tun_header *) &message[1];
784   size -= sizeof (struct tun_header) + sizeof (struct GNUNET_MessageHeader);
785   switch (ntohs (pkt_tun->proto))
786   {
787   case ETH_P_IPV6:
788     {
789       const struct ip6_header *pkt6;
790
791       if (size < sizeof (struct ip6_header))
792       {
793         /* Kernel to blame? */
794         GNUNET_break (0);
795         return;
796       }
797       pkt6 = (struct ip6_header *) &pkt_tun[1];
798       if (size != ntohs (pkt6->payload_length))
799       {
800         /* Kernel to blame? */
801         GNUNET_break (0);
802         return;
803       }
804       size -= sizeof (struct ip6_header);
805       switch (pkt6->next_header)
806       {
807       case IPPROTO_UDP:
808         udp_from_helper ((const struct udp_packet *) &pkt6[1], size,
809                          AF_INET6,
810                          &pkt6->destination_address, 
811                          &pkt6->source_address);
812         break;
813       case IPPROTO_TCP:
814         tcp_from_helper ((const struct tcp_packet *) &pkt6[1], size,
815                          AF_INET6,
816                          &pkt6->destination_address, 
817                          &pkt6->source_address);
818         break;
819       default:
820         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
821                     _("IPv6 packet with unsupported next header received.  Ignored.\n"));
822         return;
823       }
824     }
825     break;
826   case ETH_P_IPV4:
827     {
828       const struct ip4_header *pkt4;
829
830       if (size < sizeof (struct ip4_header))
831       {
832         /* Kernel to blame? */
833         GNUNET_break (0);
834         return;
835       }
836       pkt4 = (const struct ip4_header *) &pkt_tun[1];
837       if (size != ntohs (pkt4->total_length))
838       {
839         /* Kernel to blame? */
840         GNUNET_break (0);
841         return;
842       }
843       if (pkt4->header_length * 4 != sizeof (struct ip4_header))
844       {
845         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
846                     _("IPv4 packet options received.  Ignored.\n"));
847         return;
848       }
849       size -= sizeof (struct ip4_header);
850       switch (pkt4->protocol)
851       {
852       case IPPROTO_UDP:
853         udp_from_helper ((const struct udp_packet *) &pkt4[1], size,
854                          AF_INET,
855                          &pkt4->destination_address, 
856                          &pkt4->source_address);
857       case IPPROTO_TCP:
858         tcp_from_helper ((const struct tcp_packet *) &pkt4[1], size,
859                          AF_INET,
860                          &pkt4->destination_address, 
861                          &pkt4->source_address);
862         break;
863       default:
864         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
865                     _("IPv4 packet with unsupported next header received.  Ignored.\n"));
866         return;
867       }
868     }
869     break;
870   default:
871     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
872                 _("Packet from unknown protocol %u received.  Ignored.\n"),
873                 ntohs (pkt_tun->proto));
874     break;
875   }
876 }
877
878
879 /**
880  * We need to create a (unique) fresh local address (IP+port).
881  * Fill one in.
882  *
883  * @param af desired address family
884  * @param proto desired protocol (IPPROTO_UDP or IPPROTO_TCP)
885  * @param local_address address to initialize
886  */
887 static void
888 setup_fresh_address (int af,
889                      int proto,
890                      struct SocketAddress *local_address)
891 {
892   switch (af)
893   {
894   case AF_INET:
895     {
896       const char *ipv4addr = exit_argv[4];
897       const char *ipv4mask = exit_argv[5];
898       uint32_t tmp;
899       uint32_t tmp2;
900       
901       GNUNET_assert (1 == inet_pton (AF_INET, ipv4addr, &tmp));
902       GNUNET_assert (1 == inet_pton (AF_INET, ipv4mask, &tmp2));
903       // FIXME
904       /* This should be a noop */
905       tmp = tmp & tmp2;
906       tmp |= ntohl (*((uint32_t *) /*tunnel*/ 42)) & (~tmp2);
907       
908       // pkt4->source_address.s_addr = tmp;
909     }
910     break;
911   case AF_INET6:
912     {
913       const char *ipv6addr = exit_argv[2];
914       /* Generate a new src-address
915        * This takes as much from the address of the tunnel as fits into
916        * the host-mask*/
917       unsigned long long ipv6prefix_r = (ipv6prefix + 7) / 8;
918       inet_pton (AF_INET6, ipv6addr, &local_address->address.ipv6);
919       if (ipv6prefix_r < (16 - sizeof (void *)))
920         ipv6prefix_r = 16 - sizeof (void *);
921       
922       unsigned int offset = ipv6prefix_r - (16 - sizeof (void *));
923       // memcpy ((((char *) &pkt6->source_address)) + ipv6prefix_r, ((char *) &tunnel) + offset, 16 - ipv6prefix_r);
924       offset++;
925     }
926     break;
927   default:
928     GNUNET_assert (0);
929   }  
930 }
931
932
933 /**
934  * FIXME: document!
935  */
936 static void
937 setup_state_record (struct TunnelState *state)
938 {
939   GNUNET_HashCode key;
940   struct TunnelState *s;
941
942   /* generate fresh, unique address */
943   do
944   {
945     setup_fresh_address (state->serv->address.af,
946                          state->serv->address.proto,
947                          &state->ri.local_address);
948   } while (NULL != get_redirect_state (state->serv->address.af,
949                                        IPPROTO_UDP,
950                                        &state->ri.remote_address.address,
951                                        state->ri.remote_address.port,
952                                        &state->ri.local_address.address,
953                                        state->ri.local_address.port,
954                                        &key));
955   GNUNET_assert (GNUNET_OK ==
956                  GNUNET_CONTAINER_multihashmap_put (connections_map, 
957                                                     &key, state,
958                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
959   state->heap_node = GNUNET_CONTAINER_heap_insert (connections_heap,
960                                                    state,
961                                                    GNUNET_TIME_absolute_get ().abs_value);   
962   while (GNUNET_CONTAINER_heap_get_size (connections_heap) > max_connections)
963   {
964     s = GNUNET_CONTAINER_heap_remove_root (connections_heap);
965     GNUNET_assert (state != s);
966     s->heap_node = NULL;
967     GNUNET_MESH_tunnel_destroy (s->tunnel);
968     GNUNET_assert (GNUNET_OK ==
969                    GNUNET_CONTAINER_multihashmap_remove (connections_map,
970                                                          &s->state_key, 
971                                                          s));
972     GNUNET_free (s);
973   }
974 }
975
976
977 /**
978  * FIXME: document
979  */
980 static void
981 prepare_ipv4_packet (const void *payload, size_t payload_length,
982                      int protocol,
983                      const struct SocketAddress *src_address,
984                      const struct SocketAddress *dst_address,
985                      struct ip4_header *pkt4)
986 {
987   size_t len;
988
989   len = payload_length;
990   switch (protocol)
991   {
992   case IPPROTO_UDP:
993     len += sizeof (struct udp_packet);
994     break;
995   case IPPROTO_TCP:
996     /* tcp_header (with port/crc not set) must be part of payload! */
997     if (len < sizeof (struct tcp_packet))
998     {
999       GNUNET_break (0);
1000       return;
1001     }
1002     break;
1003   default:
1004     GNUNET_break (0);
1005     return;
1006   }
1007   if (len + sizeof (struct ip4_header) > UINT16_MAX)
1008   {
1009     GNUNET_break (0);
1010     return;
1011   }
1012
1013   pkt4->version = 4;
1014   pkt4->header_length = sizeof (struct ip4_header) / 4;
1015   pkt4->diff_serv = 0;
1016   pkt4->total_length = htons ((uint16_t) (sizeof (struct ip4_header) + len));
1017   pkt4->identification = 0; // FIXME: pick at random!
1018   pkt4->flags = 0;
1019   pkt4->fragmentation_offset = 0;
1020   pkt4->ttl = 255;
1021   pkt4->protocol = protocol;
1022   pkt4->checksum = 0;
1023   pkt4->destination_address = dst_address->address.ipv4;
1024   pkt4->source_address = src_address->address.ipv4;
1025   pkt4->checksum = GNUNET_CRYPTO_crc16_n (pkt4, sizeof (struct ip4_header));
1026
1027   switch (protocol)
1028   {
1029   case IPPROTO_UDP:
1030     {
1031       struct udp_packet *pkt4_udp = (struct udp_packet *) &pkt4[1];
1032
1033       pkt4_udp->spt = htons (src_address->port);
1034       pkt4_udp->dpt = htons (dst_address->port);
1035       pkt4_udp->crc = 0;  /* Optional for IPv4 */
1036       pkt4_udp->len = htons ((uint16_t) payload_length);
1037       memcpy (&pkt4_udp[1], payload, payload_length);
1038     }
1039     break;
1040   case IPPROTO_TCP:
1041     {
1042       struct tcp_packet *pkt4_tcp = (struct tcp_packet *) &pkt4[1];
1043       
1044       memcpy (pkt4_tcp, payload, payload_length);
1045       pkt4_tcp->spt = htons (src_address->port);
1046       pkt4_tcp->dpt = htons (dst_address->port);
1047       pkt4_tcp->crc = 0;
1048       uint32_t sum = 0;
1049       sum = GNUNET_CRYPTO_crc16_step (sum, 
1050                                       &pkt4->source_address,
1051                                       sizeof (struct in_addr) * 2);
1052       uint32_t tmp = htonl ((protocol << 16) | (0xffff & len));
1053       sum = GNUNET_CRYPTO_crc16_step (sum, & tmp, sizeof (uint32_t));
1054       sum = GNUNET_CRYPTO_crc16_step (sum, & pkt4_tcp, len);
1055       pkt4_tcp->crc = GNUNET_CRYPTO_crc16_finish (sum);
1056     }
1057     break;
1058   default:
1059     GNUNET_assert (0);
1060   }
1061 }
1062
1063
1064 /**
1065  * FIXME: document
1066  */
1067 static void
1068 prepare_ipv6_packet (const void *payload, size_t payload_length,
1069                      int protocol,
1070                      const struct SocketAddress *src_address,
1071                      const struct SocketAddress *dst_address,
1072                      struct ip6_header *pkt6)
1073 {
1074   size_t len;
1075
1076   len = payload_length;
1077   switch (protocol)
1078   {
1079   case IPPROTO_UDP:
1080     len += sizeof (struct udp_packet);
1081     break;
1082   case IPPROTO_TCP:
1083     /* tcp_header (with port/crc not set) must be part of payload! */
1084     if (len < sizeof (struct tcp_packet))
1085     {
1086       GNUNET_break (0);
1087       return;
1088     }
1089     break;
1090   default:
1091     GNUNET_break (0);
1092     return;
1093   }
1094   if (len > UINT16_MAX)
1095   {
1096     GNUNET_break (0);
1097     return;
1098   }
1099
1100   pkt6->version = 6;
1101   pkt6->next_header = protocol;
1102   pkt6->payload_length = htons ((uint16_t) (len + sizeof (struct ip6_header)));
1103   pkt6->hop_limit = 255;
1104   pkt6->destination_address = dst_address->address.ipv6;
1105   pkt6->source_address = src_address->address.ipv6;
1106
1107   switch (protocol)
1108   {
1109   case IPPROTO_UDP:
1110     {
1111       struct udp_packet *pkt6_udp = (struct udp_packet *) &pkt6[1];
1112
1113       memcpy (&pkt6[1], payload, payload_length);
1114       pkt6_udp->crc = 0;
1115       pkt6_udp->spt = htons (src_address->port);
1116       pkt6_udp->dpt = htons (dst_address->port);
1117       pkt6_udp->len = htons ((uint16_t) payload_length);
1118
1119       uint32_t sum = 0;
1120       sum = GNUNET_CRYPTO_crc16_step (sum,
1121                                       &pkt6->source_address,
1122                                       sizeof (struct in6_addr) * 2);
1123       uint32_t tmp = htons (len);
1124       sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
1125       tmp = htonl (pkt6->next_header);
1126       sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
1127       sum = GNUNET_CRYPTO_crc16_step (sum, pkt6_udp, len);
1128       pkt6_udp->crc = GNUNET_CRYPTO_crc16_finish (sum);
1129     }
1130     break;
1131   case IPPROTO_TCP:
1132     {
1133       struct tcp_packet *pkt6_tcp = (struct tcp_packet *) pkt6;
1134       
1135       memcpy (pkt6_tcp, payload, payload_length);
1136       pkt6_tcp->crc = 0;
1137       pkt6_tcp->spt = htons (src_address->port);
1138       pkt6_tcp->dpt = htons (dst_address->port);
1139
1140       uint32_t sum = 0;
1141       sum = GNUNET_CRYPTO_crc16_step (sum, &pkt6->source_address, 
1142                                       sizeof (struct in6_addr) * 2);
1143       uint32_t tmp = htonl (len);
1144       sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
1145       tmp = htonl (pkt6->next_header);
1146       sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));      
1147       sum = GNUNET_CRYPTO_crc16_step (sum,  pkt6_tcp, len);
1148       pkt6_tcp->crc = GNUNET_CRYPTO_crc16_finish (sum);
1149     }
1150     break;
1151   default:
1152     GNUNET_assert (0);
1153     break;
1154   }
1155 }
1156
1157
1158 /**
1159  * We've just experienced a connection in use.  Track it, or if it is
1160  * already tracked, update the tracking.
1161  *
1162  * @param u_i IP-level connection tracking state
1163  * @param tunnel associated mesh tunnel
1164  * @param desc service descriptor (or NULL)
1165  * @param serv service information
1166  */
1167 void
1168 update_state_map (const struct RedirectInformation *ri,
1169                   struct GNUNET_MESH_Tunnel *tunnel,
1170                   const GNUNET_HashCode *desc,
1171                   struct LocalService *serv)
1172 {
1173   struct TunnelState *state;
1174   GNUNET_HashCode state_key;
1175
1176   hash_redirect_info (&state_key,
1177                       ri);
1178   state = GNUNET_CONTAINER_multihashmap_get (connections_map, &state_key);
1179   if (NULL == state)
1180   {
1181     state = GNUNET_malloc (sizeof (struct TunnelState));
1182     state->tunnel = tunnel;
1183     state->state_key = state_key;
1184     state->serv = serv;
1185     // FIXME? if (NULL != desc) state->desc = *desc;
1186     // FIXME? state->redirect_info = *ri;
1187     GNUNET_assert (GNUNET_OK ==
1188                    GNUNET_CONTAINER_multihashmap_put (connections_map, &state_key, state,
1189                                                       GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1190     state->heap_node =
1191       GNUNET_CONTAINER_heap_insert (connections_heap,
1192                                     state,
1193                                     GNUNET_TIME_absolute_get ().abs_value);
1194   }
1195   else
1196   {
1197     if (state->tunnel != tunnel) 
1198     {
1199       /* Stats / warning: two tunnels got exactly the same connection state!? */
1200       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1201                   _("Two different mesh tunnels got the same connection state. Oops.\n"));
1202       return;
1203     }
1204     GNUNET_CONTAINER_heap_update_cost (connections_heap,
1205                                        state->heap_node,
1206                                        GNUNET_TIME_absolute_get ().abs_value);
1207   }
1208   while (GNUNET_CONTAINER_heap_get_size (connections_heap) > max_connections)
1209   {
1210     state = GNUNET_CONTAINER_heap_remove_root (connections_heap);
1211     state->heap_node = NULL;
1212     GNUNET_MESH_tunnel_destroy (state->tunnel);
1213     GNUNET_assert (GNUNET_OK ==
1214                    GNUNET_CONTAINER_multihashmap_remove (connections_map,
1215                                                          &state->state_key, 
1216                                                          state));
1217     GNUNET_free (state);
1218   }
1219 }
1220
1221                   
1222
1223
1224 /**
1225  * The messages are one GNUNET_HashCode for the service followed by a struct tcp_packet
1226  */
1227 static int
1228 receive_tcp_service (void *unused GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1229                      void **tunnel_ctx GNUNET_UNUSED,
1230                      const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1231                      const struct GNUNET_MessageHeader *message,
1232                      const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1233 {
1234 #if 0
1235   const GNUNET_HashCode *desc = (const GNUNET_HashCode *) &message[1];
1236   const struct tcp_packet *pkt = (const struct tcp_packet *) &desc[1];
1237   uint16_t pkt_len = ntohs (message->size);
1238   struct LocalService *serv;
1239   struct RedirectInformation u_i;
1240   GNUNET_HashCode state_key;
1241
1242   /* check that we got at least a valid header */
1243   if (pkt_len < sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + sizeof (struct tcp_packet))
1244   {
1245     GNUNET_break_op (0);
1246     return GNUNET_YES;
1247   }
1248   pkt_len -= (sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode));
1249
1250   if (NULL == (serv = find_service (tcp_services, desc, ntohs (pkt->dpt))))
1251   {
1252     GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
1253                 _("No service found for %s on port %d!\n"),
1254                 "TCP",
1255                 ntohs (pkt->dpt));
1256     return GNUNET_YES;
1257   }
1258   pkt->dpt = htons (serv->remote_port);
1259
1260   /* At this point it would be possible to check against some kind of ACL. */
1261
1262   switch (serv->version)
1263     {
1264     case 4:
1265       {
1266         size_t len =
1267           sizeof (struct GNUNET_MessageHeader) + sizeof (struct tun_header) +
1268           sizeof (struct ip4_header) + pkt_len;       
1269         char buf[len];
1270         struct tun_header *hdr;
1271         struct GNUNET_MessageHeader *mhdr;
1272         
1273         memset (buf, 0, len);
1274         mhdr = (struct GNUNET_MessageHeader*) buf;
1275         hdr = (struct tun_header *) &mhdr[1];
1276         mhdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1277         mhdr->size = htons (len);
1278         hdr->flags = 0;
1279         hdr->proto = htons (0x0800);
1280         prepare_ipv4_packet (len, pkt_len, pkt, IPPROTO_TCP, &serv->v4.ip4address,
1281                              tunnel, &u_i, (struct ip4_header *) &hdr[1]);
1282         /* FIXME: here, flow-control with mesh would be nice to have... */
1283         (void) GNUNET_HELPER_send (helper_handle,
1284                                    mhdr,
1285                                    GNUNET_YES,
1286                                    NULL, NULL);
1287         break;
1288       }
1289     case 6:
1290       {
1291         size_t len =
1292           sizeof (struct GNUNET_MessageHeader) + sizeof (struct tun_header) +
1293           sizeof (struct ip6_header) + pkt_len;
1294         char buf[len];
1295         struct tun_header *hdr;
1296         struct GNUNET_MessageHeader *mhdr;
1297         
1298         memset (buf, 0, len);
1299         mhdr = (struct GNUNET_MessageHeader*) buf;
1300         hdr = (struct tun_header *) &mhdr[1];
1301         mhdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1302         mhdr->size = htons (len);
1303         hdr->flags = 0;
1304         hdr->proto = htons (0x86dd);
1305         prepare_ipv6_packet (len, pkt_len, pkt, IPPROTO_TCP, &serv->v6.ip6address,
1306                              tunnel, &u_i, (struct ip6_header *) buf);
1307             /* FIXME: here, flow-control with mesh would be nice to have... */
1308         (void) GNUNET_HELPER_send (helper_handle,
1309                                    (const struct GNUNET_MessageHeader*) buf,
1310                                    GNUNET_YES,
1311                                    NULL, NULL);
1312
1313         break;
1314       }
1315     default:
1316       GNUNET_assert (0);
1317       break;
1318     }
1319
1320
1321   update_state_map (&u_i, desc, tunnel, serv);
1322 #endif
1323   return GNUNET_YES;
1324 }
1325
1326
1327 static int
1328 receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1329                     void **tunnel_ctx GNUNET_UNUSED,
1330                     const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1331                     const struct GNUNET_MessageHeader *message,
1332                     const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1333 {
1334   // FIXME
1335 #if 0
1336   GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1);
1337   struct tcp_packet *pkt = (struct tcp_packet *) (desc + 1);
1338   struct remote_addr *s = (struct remote_addr *) desc;
1339   char *buf;
1340   size_t len;
1341   uint16_t pkt_len =
1342       ntohs (message->size) - sizeof (struct GNUNET_MessageHeader) -
1343       sizeof (GNUNET_HashCode);
1344
1345   struct TunnelState *state = GNUNET_malloc (sizeof (struct TunnelState));
1346
1347   state->tunnel = tunnel;
1348   state->type = REMOTE;
1349   state->hashmap = tcp_connections;
1350   memcpy (&state->remote, s, sizeof (struct remote_addr));
1351
1352   hash_redirect_info (&state->hash, &state->redirect_info, s->addrlen);
1353
1354   if (GNUNET_NO ==
1355       GNUNET_CONTAINER_multihashmap_contains (tcp_connections, &state->hash))
1356   {
1357     GNUNET_CONTAINER_multihashmap_put (tcp_connections, &state->hash, state,
1358                                        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1359
1360     state->heap_node =
1361         GNUNET_CONTAINER_heap_insert (tcp_connections_heap, state,
1362                                       GNUNET_TIME_absolute_get ().abs_value);
1363
1364     if (GNUNET_CONTAINER_heap_get_size (tcp_connections_heap) >
1365         max_tcp_connections)
1366       GNUNET_SCHEDULER_add_now (collect_connections, tcp_connections_heap);
1367   }
1368   else
1369     GNUNET_free (state);
1370
1371
1372
1373   len =
1374       sizeof (struct GNUNET_MessageHeader) + sizeof (struct pkt_tun) +
1375       sizeof (struct ip6_hdr) + pkt_len;
1376   buf = alloca (len);
1377
1378   memset (buf, 0, len);
1379
1380   switch (s->addrlen)
1381   {
1382   case 4:
1383     prepare_ipv4_packet (len, pkt_len, pkt, IPPROTO_TCP, &s->addr, tunnel,
1384                          state, (struct ip4_header *) buf);
1385     break;
1386   case 16:
1387     prepare_ipv6_packet (len, pkt_len, pkt, IPPROTO_TCP, &s->addr, tunnel,
1388                          state, (struct ip6_header *) buf);
1389     break;
1390   default:
1391     GNUNET_free (state);
1392     return GNUNET_SYSERR;
1393   }
1394
1395   /* FIXME: here, flow-control with mesh would be nice to have... */
1396   (void) GNUNET_HELPER_send (helper_handle,
1397                              (const struct GNUNET_MessageHeader*) buf,
1398                              GNUNET_YES,
1399                              NULL, NULL);
1400
1401 #endif
1402   return GNUNET_YES;
1403 }
1404
1405
1406
1407
1408 /**
1409  * FIXME: document!
1410  */
1411 static void
1412 send_udp_packet_via_tun (const struct SocketAddress *destination_address,
1413                          const struct SocketAddress *source_address,
1414                          const void *payload, size_t payload_length)
1415 {
1416   size_t len;
1417
1418   len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct tun_header);
1419   switch (source_address->af)
1420   {
1421   case AF_INET:
1422     len += sizeof (struct ip4_header);
1423     break;
1424   case AF_INET6:
1425     len += sizeof (struct ip6_header);
1426     break;
1427   default:
1428     GNUNET_break (0);
1429     return;
1430   }
1431   len += sizeof (struct udp_packet);
1432   len += payload_length;
1433   if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1434   {
1435     GNUNET_break (0);
1436     return;
1437   }
1438   {
1439     char buf[len];
1440     struct GNUNET_MessageHeader *hdr;
1441     struct tun_header *tun;
1442     
1443     hdr= (struct GNUNET_MessageHeader *) buf;
1444     hdr->type = htons (42);
1445     hdr->size = htons (len);
1446     tun = (struct tun_header*) &hdr[1];
1447     tun->flags = htons (0);
1448     switch (source_address->af)
1449     {
1450     case AF_INET:
1451       {
1452         struct ip4_header * ipv4 = (struct ip4_header*) &tun[1];
1453         
1454         tun->proto = htons (ETH_P_IPV4);
1455         prepare_ipv4_packet (payload, payload_length, IPPROTO_UDP,
1456                              source_address,
1457                              destination_address,
1458                              ipv4);
1459       }
1460       break;
1461     case AF_INET6:
1462       {
1463         struct ip6_header * ipv6 = (struct ip6_header*) &tun[1];
1464         
1465         tun->proto = htons (ETH_P_IPV6);
1466         prepare_ipv6_packet (payload, payload_length, IPPROTO_UDP,
1467                              source_address,
1468                              destination_address,
1469                              ipv6);
1470       }
1471       break;    
1472     default:
1473       GNUNET_assert (0);
1474       break;
1475     }
1476     (void) GNUNET_HELPER_send (helper_handle,
1477                                (const struct GNUNET_MessageHeader*) buf,
1478                                GNUNET_YES,
1479                                NULL, NULL);
1480   }
1481 }
1482
1483
1484
1485
1486 /**
1487  * FIXME: document!
1488  */
1489 static int
1490 receive_udp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1491                     void **tunnel_ctx GNUNET_UNUSED,
1492                     const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1493                     const struct GNUNET_MessageHeader *message,
1494                     const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1495 {
1496   struct TunnelState *state = *tunnel_ctx;
1497   // FIXME: write proper request struct (!)
1498   const GNUNET_HashCode *desc = (const GNUNET_HashCode *) &message[1];
1499   const struct udp_packet *pkt = (const struct udp_packet *) &desc[1];
1500   const struct SocketAddress *s = (const struct SocketAddress *) desc;
1501   uint16_t pkt_len = ntohs (message->size);
1502
1503   if (pkt_len != ntohs (message->size) - sizeof (struct GNUNET_MessageHeader) - sizeof (GNUNET_HashCode))
1504   {
1505     GNUNET_break_op (0);
1506     return GNUNET_YES;
1507   }
1508   pkt_len -= (sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode));
1509
1510   if (NULL == state->heap_node)
1511   {
1512     /* first packet, setup record */
1513     state->ri.remote_address = *s;
1514     setup_state_record (state);
1515   }
1516
1517   send_udp_packet_via_tun (&state->ri.remote_address,
1518                            &state->ri.local_address,
1519                            &pkt[1], pkt_len - sizeof (struct udp_packet));
1520   return GNUNET_YES;
1521 }
1522
1523
1524 /**
1525  * FIXME: document!
1526  */
1527 static int
1528 receive_udp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1529                      void **tunnel_ctx,
1530                      const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1531                      const struct GNUNET_MessageHeader *message,
1532                      const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1533 {
1534   struct TunnelState *state = *tunnel_ctx;
1535   // FIXME: write proper request struct (we don't need UDP except dpt either!)
1536   const GNUNET_HashCode *desc = (const GNUNET_HashCode *) &message[1];
1537   const struct udp_packet *pkt = (const struct udp_packet *) &desc[1];
1538   uint16_t pkt_len = ntohs (message->size);
1539
1540
1541   /* check that we got at least a valid header */
1542   if (pkt_len < sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + sizeof (struct udp_packet))
1543   {
1544     GNUNET_break_op (0);
1545     return GNUNET_YES;
1546   }
1547   pkt_len -= (sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode));
1548
1549   GNUNET_assert (ntohs (pkt->len) ==
1550                  ntohs (message->size) - sizeof (struct GNUNET_MessageHeader) -
1551                  sizeof (GNUNET_HashCode));
1552
1553   if (NULL == state->serv) 
1554   {
1555     /* setup fresh connection */
1556     GNUNET_assert (NULL == state->heap_node);
1557     if (NULL == (state->serv = find_service (udp_services, desc, ntohs (pkt->dpt))))
1558     {
1559       GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
1560                   _("No service found for %s on port %d!\n"),
1561                   "UDP",
1562                   ntohs (pkt->dpt));
1563       GNUNET_MESH_tunnel_destroy (state->tunnel);
1564       return GNUNET_YES;
1565     }
1566     state->ri.remote_address = state->serv->address;    
1567     setup_state_record (state);
1568   }
1569   send_udp_packet_via_tun (&state->ri.remote_address,
1570                            &state->ri.local_address,
1571                            &pkt[1], pkt_len - sizeof (struct udp_packet));
1572   return GNUNET_YES;
1573 }
1574
1575
1576 /**
1577  * Callback from GNUNET_MESH for new tunnels.
1578  *
1579  * @param cls closure
1580  * @param tunnel new handle to the tunnel
1581  * @param initiator peer that started the tunnel
1582  * @param atsi performance information for the tunnel
1583  * @return initial tunnel context for the tunnel
1584  */
1585 static void *
1586 new_tunnel (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1587             const struct GNUNET_PeerIdentity *initiator GNUNET_UNUSED,
1588             const struct GNUNET_ATS_Information *ats GNUNET_UNUSED)
1589 {
1590   struct TunnelState *s = GNUNET_malloc (sizeof (struct TunnelState));
1591   
1592   s->tunnel = tunnel;
1593   return s;
1594 }
1595
1596
1597 /**
1598  * Function called by mesh whenever an inbound tunnel is destroyed.
1599  * Should clean up any associated state.
1600  *
1601  * @param cls closure (set from GNUNET_MESH_connect)
1602  * @param tunnel connection to the other end (henceforth invalid)
1603  * @param tunnel_ctx place where local state associated
1604  *                   with the tunnel is stored
1605  */
1606 static void
1607 clean_tunnel (void *cls GNUNET_UNUSED, const struct GNUNET_MESH_Tunnel *tunnel,
1608               void *tunnel_ctx)
1609 {
1610   struct TunnelState *s = tunnel_ctx;
1611   struct TunnelMessageQueue *tnq;
1612
1613   while (NULL != (tnq = s->head))
1614   {
1615     GNUNET_CONTAINER_DLL_remove (s->head,
1616                                  s->tail,
1617                                  tnq);
1618     GNUNET_free (tnq);
1619   }
1620   if (s->heap_node != NULL)
1621   {
1622     GNUNET_assert (GNUNET_YES ==
1623                    GNUNET_CONTAINER_multihashmap_remove (connections_map,
1624                                                          &s->state_key,
1625                                                          s));
1626     GNUNET_CONTAINER_heap_remove_node (s->heap_node);
1627     s->heap_node = NULL;
1628   }
1629   if (NULL != s->th)
1630   {
1631     GNUNET_MESH_notify_transmit_ready_cancel (s->th);
1632     s->th = NULL;
1633   }
1634   GNUNET_free (s);
1635 }
1636
1637
1638 /**
1639  * Function that frees everything from a hashmap
1640  *
1641  * @param cls unused
1642  * @param hash key
1643  * @param value value to free
1644  */
1645 static int
1646 free_iterate (void *cls GNUNET_UNUSED,
1647               const GNUNET_HashCode * hash GNUNET_UNUSED, void *value)
1648 {
1649   GNUNET_free (value);
1650   return GNUNET_YES;
1651 }
1652
1653
1654 /**
1655  * Function scheduled as very last function, cleans up after us
1656  */
1657 static void
1658 cleanup (void *cls GNUNET_UNUSED,
1659          const struct GNUNET_SCHEDULER_TaskContext *tskctx)
1660 {
1661   unsigned int i;
1662
1663   if (helper_handle != NULL)
1664   {
1665     GNUNET_HELPER_stop (helper_handle);
1666     helper_handle = NULL;
1667   }
1668   if (mesh_handle != NULL)
1669   {
1670     GNUNET_MESH_disconnect (mesh_handle);
1671     mesh_handle = NULL;
1672   }
1673   if (NULL != connections_map)
1674   {
1675     GNUNET_CONTAINER_multihashmap_iterate (connections_map, &free_iterate, NULL);
1676     GNUNET_CONTAINER_multihashmap_destroy (connections_map);
1677     connections_map = NULL;
1678   }
1679   if (NULL != connections_heap)
1680   {
1681     GNUNET_CONTAINER_heap_destroy (connections_heap);
1682     connections_heap = NULL;
1683   }
1684   if (NULL != tcp_services)
1685   {
1686     GNUNET_CONTAINER_multihashmap_iterate (tcp_services, &free_service_record, NULL);
1687     GNUNET_CONTAINER_multihashmap_destroy (tcp_services);
1688     tcp_services = NULL;
1689   }
1690   if (NULL != udp_services)
1691   {
1692     GNUNET_CONTAINER_multihashmap_iterate (udp_services, &free_service_record, NULL);
1693     GNUNET_CONTAINER_multihashmap_destroy (udp_services);
1694     udp_services = NULL;
1695   }
1696   for (i=0;i<5;i++)
1697     GNUNET_free_non_null (exit_argv[i]);
1698 }
1699
1700
1701 /**
1702  * Add services to the service map.
1703  *
1704  * @param proto IPPROTO_TCP or IPPROTO_UDP
1705  * @param cpy copy of the service descriptor (can be mutilated)
1706  * @param name DNS name of the service
1707  */
1708 static void
1709 add_services (int proto,
1710               char *cpy,
1711               const char *name)
1712 {
1713   char *redirect;
1714   char *hostname;
1715   char *hostport;
1716   struct LocalService *serv;
1717
1718   for (redirect = strtok (cpy, " "); redirect != NULL;
1719        redirect = strtok (NULL, " "))
1720   {
1721     if (NULL == (hostname = strstr (redirect, ":")))
1722     {
1723       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1724                   "option `%s' for domain `%s' is not formatted correctly!\n",
1725                   redirect,
1726                   name);
1727       continue;
1728     }
1729     hostname[0] = '\0';
1730     hostname++;
1731     if (NULL == (hostport = strstr (hostname, ":")))
1732     {
1733       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1734                   "option `%s' for domain `%s' is not formatted correctly!\n",
1735                   redirect,
1736                   name);
1737       continue;
1738     }
1739     hostport[0] = '\0';
1740     hostport++;
1741     
1742     int local_port = atoi (redirect);
1743     int remote_port = atoi (hostport);
1744     
1745     if (!((local_port > 0) && (local_port < 65536)))
1746     {
1747       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1748                   "`%s' is not a valid port number (for domain `%s')!", redirect,
1749                   name);
1750       continue;
1751     }
1752     if (!((remote_port > 0) && (remote_port < 65536)))
1753     {
1754       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1755                   "`%s' is not a valid port number (for domain `%s')!", hostport,
1756                   name);
1757       continue;
1758     }
1759
1760     serv = GNUNET_malloc (sizeof (struct LocalService));
1761     serv->my_port = (uint16_t) local_port;
1762     serv->address.port = remote_port;
1763     if (0 == strcmp ("localhost4", hostname))
1764     {
1765       const char *ip4addr = exit_argv[4];
1766
1767       serv->address.af = AF_INET;      
1768       GNUNET_assert (1 != inet_pton (AF_INET, ip4addr, &serv->address.address.ipv4));
1769     }
1770     else if (0 == strcmp ("localhost6", hostname))
1771     {
1772       const char *ip6addr = exit_argv[2];
1773
1774       serv->address.af = AF_INET6;
1775       GNUNET_assert (1 == inet_pton (AF_INET6, ip6addr, &serv->address.address.ipv6));
1776     }
1777     else
1778     {
1779       struct addrinfo *res;      
1780       int ret;
1781
1782       ret = getaddrinfo (hostname, NULL, NULL, &res);      
1783       if ( (ret != 0) || (res == NULL) )
1784       {
1785         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1786                     _("No addresses found for hostname `%s' of service `%s'!\n"),
1787                     hostname,
1788                     name);
1789         GNUNET_free (serv);
1790         continue;
1791       }
1792       
1793       serv->address.af = res->ai_family;
1794       switch (res->ai_family)
1795       {
1796         case AF_INET:
1797           serv->address.address.ipv4 = ((struct sockaddr_in *) res->ai_addr)->sin_addr;
1798           break;
1799         case AF_INET6:
1800           serv->address.address.ipv6 = ((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
1801           break;
1802       default:
1803         freeaddrinfo (res);
1804         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1805                     _("No IP addresses found for hostname `%s' of service `%s'!\n"),
1806                     hostname,
1807                     name);
1808         GNUNET_free (serv);
1809         continue;
1810       }
1811       freeaddrinfo (res);
1812     }
1813     store_service ((IPPROTO_UDP == proto) ? udp_services : tcp_services,
1814                    name,
1815                    local_port,
1816                    serv);
1817   }
1818 }
1819
1820
1821 /**
1822  * Reads the configuration servicecfg and populates udp_services
1823  *
1824  * @param cls unused
1825  * @param section name of section in config, equal to hostname
1826  */
1827 static void
1828 read_service_conf (void *cls GNUNET_UNUSED, const char *section)
1829 {
1830   char *cpy;
1831
1832   if ((strlen (section) < 8) ||
1833       (0 != strcmp (".gnunet.", section + (strlen (section) - 8))))
1834     return;
1835   if (GNUNET_OK ==
1836       GNUNET_CONFIGURATION_get_value_string (cfg, section, "UDP_REDIRECTS",
1837                                              &cpy))
1838   {
1839     add_services (IPPROTO_UDP, cpy, section);
1840     GNUNET_free (cpy);
1841   }
1842   if (GNUNET_OK ==
1843       GNUNET_CONFIGURATION_get_value_string (cfg, section, "TCP_REDIRECTS",
1844                                              &cpy))
1845   {
1846     add_services (IPPROTO_TCP, cpy, section);
1847     GNUNET_free (cpy);
1848   }
1849 }
1850
1851
1852 /**
1853  * @brief Main function that will be run by the scheduler.
1854  *
1855  * @param cls closure
1856  * @param args remaining command-line arguments
1857  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
1858  * @param cfg_ configuration
1859  */
1860 static void
1861 run (void *cls, char *const *args GNUNET_UNUSED,
1862      const char *cfgfile GNUNET_UNUSED,
1863      const struct GNUNET_CONFIGURATION_Handle *cfg_)
1864 {
1865   static struct GNUNET_MESH_MessageHandler handlers[] = {
1866     {&receive_udp_service, GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP, 0},
1867     {&receive_tcp_service, GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP, 0},
1868     {NULL, 0, 0},
1869     {NULL, 0, 0},
1870     {NULL, 0, 0}
1871   };
1872
1873   static GNUNET_MESH_ApplicationType apptypes[] = {
1874     GNUNET_APPLICATION_TYPE_END,
1875     GNUNET_APPLICATION_TYPE_END,
1876     GNUNET_APPLICATION_TYPE_END
1877   };
1878   unsigned int handler_idx;
1879   unsigned int app_idx;
1880   int udp;
1881   int tcp;
1882   char *ifname;
1883   char *ipv6addr;
1884   char *ipv6prefix_s;
1885   char *ipv4addr;
1886   char *ipv4mask;
1887   struct in_addr v4;
1888   struct in6_addr v6;
1889
1890   cfg = cfg_;
1891   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls);
1892   if (GNUNET_OK !=
1893       GNUNET_CONFIGURATION_get_value_number (cfg, "exit", "MAX_CONNECTIONS",
1894                                              &max_connections))
1895     max_connections = 1024;
1896   exit_argv[0] = GNUNET_strdup ("exit-gnunet");
1897   if (GNUNET_SYSERR ==
1898       GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IFNAME", &ifname))
1899   {
1900     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1901                 "No entry 'IFNAME' in configuration!\n");
1902     GNUNET_SCHEDULER_shutdown ();
1903     return;
1904   }
1905   exit_argv[1] = ifname;
1906   if ( (GNUNET_SYSERR ==
1907         GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6ADDR",
1908                                                &ipv6addr) ||
1909         (1 != inet_pton (AF_INET6, ipv6addr, &v6))) )
1910   {
1911     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1912                 "No valid entry 'IPV6ADDR' in configuration!\n");
1913     GNUNET_SCHEDULER_shutdown ();
1914     return;
1915   }
1916   exit_argv[2] = ipv6addr;
1917   if (GNUNET_SYSERR ==
1918       GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6PREFIX",
1919                                              &ipv6prefix_s))
1920   {
1921     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1922                 "No entry 'IPV6PREFIX' in configuration!\n");
1923     GNUNET_SCHEDULER_shutdown ();
1924     return;
1925   }
1926   exit_argv[3] = ipv6prefix_s;
1927   if ( (GNUNET_OK !=
1928         GNUNET_CONFIGURATION_get_value_number (cfg, "exit",
1929                                                "IPV6PREFIX",
1930                                                &ipv6prefix)) ||
1931        (ipv6prefix >= 127) )
1932   {
1933     GNUNET_SCHEDULER_shutdown ();
1934     return;
1935   }
1936
1937   if ( (GNUNET_SYSERR ==
1938         GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4ADDR",
1939                                                &ipv4addr) ||
1940         (1 != inet_pton (AF_INET, ipv4addr, &v4))) )
1941   {
1942     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1943                 "No valid entry for 'IPV4ADDR' in configuration!\n");
1944     GNUNET_SCHEDULER_shutdown ();
1945     return;
1946   }
1947   exit_argv[4] = ipv4addr;
1948   if ( (GNUNET_SYSERR ==
1949         GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4MASK",
1950                                                &ipv4mask) ||
1951         (1 != inet_pton (AF_INET, ipv4mask, &v4))) )
1952   {
1953     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1954                 "No valid entry 'IPV4MASK' in configuration!\n");
1955     GNUNET_SCHEDULER_shutdown ();
1956     return;
1957   }
1958   exit_argv[5] = ipv4mask;
1959   exit_argv[6] = NULL;
1960
1961   app_idx = 0;
1962   handler_idx = 2;
1963   udp = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_UDP");
1964   tcp = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_TCP");
1965   if (GNUNET_YES == udp)
1966   {
1967     handlers[handler_idx].callback = &receive_udp_remote;
1968     handlers[handler_idx].expected_size = 0;
1969     handlers[handler_idx].type = GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP;
1970     apptypes[app_idx] = GNUNET_APPLICATION_TYPE_INTERNET_UDP_GATEWAY;
1971     handler_idx++;
1972     app_idx++;
1973   }
1974
1975   if (GNUNET_YES == tcp)
1976   {
1977     handlers[handler_idx].callback = &receive_tcp_remote;
1978     handlers[handler_idx].expected_size = 0;
1979     handlers[handler_idx].type = GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP;
1980     apptypes[app_idx] = GNUNET_APPLICATION_TYPE_INTERNET_TCP_GATEWAY;
1981     handler_idx++;
1982     app_idx++;
1983   }
1984   udp_services = GNUNET_CONTAINER_multihashmap_create (65536);
1985   tcp_services = GNUNET_CONTAINER_multihashmap_create (65536);
1986   GNUNET_CONFIGURATION_iterate_sections (cfg, &read_service_conf, NULL);
1987
1988   connections_map = GNUNET_CONTAINER_multihashmap_create (65536);
1989   connections_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
1990   mesh_handle 
1991     = GNUNET_MESH_connect (cfg, 42 /* queue size */, NULL, 
1992                            &new_tunnel, 
1993                            &clean_tunnel, handlers,
1994                            apptypes);
1995   if (NULL == mesh_handle)
1996   {
1997     GNUNET_SCHEDULER_shutdown ();
1998     return;
1999   }
2000   helper_handle = GNUNET_HELPER_start ("gnunet-helper-vpn", 
2001                                        exit_argv,
2002                                        &message_token, NULL);
2003 }
2004
2005
2006 /**
2007  * The main function
2008  *
2009  * @param argc number of arguments from the command line
2010  * @param argv command line arguments
2011  * @return 0 ok, 1 on error
2012  */
2013 int
2014 main (int argc, char *const *argv)
2015 {
2016   static const struct GNUNET_GETOPT_CommandLineOption options[] = {
2017     GNUNET_GETOPT_OPTION_END
2018   };
2019
2020   return (GNUNET_OK ==
2021           GNUNET_PROGRAM_run (argc, argv, "gnunet-daemon-exit",
2022                               gettext_noop
2023                               ("Daemon to run to provide an IP exit node for the VPN"),
2024                               options, &run, NULL)) ? 0 : 1;
2025 }
2026
2027
2028 /* end of gnunet-daemon-exit.c */