ca6ec75442fe6533741ab09ed4453ab68c1705f7
[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  * FIXME: document!
1224  *
1225  * @param payload payload of the IP header (includes TCP header)
1226  */
1227 static void
1228 send_tcp_packet_via_tun (const struct SocketAddress *destination_address,
1229                          const struct SocketAddress *source_address,
1230                          const void *payload, size_t payload_length)
1231 {
1232   size_t len;
1233
1234   len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct tun_header);
1235   switch (source_address->af)
1236   {
1237   case AF_INET:
1238     len += sizeof (struct ip4_header);
1239     break;
1240   case AF_INET6:
1241     len += sizeof (struct ip6_header);
1242     break;
1243   default:
1244     GNUNET_break (0);
1245     return;
1246   }
1247   len += payload_length;
1248   if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1249   {
1250     GNUNET_break (0);
1251     return;
1252   }
1253   {
1254     char buf[len];
1255     struct GNUNET_MessageHeader *hdr;
1256     struct tun_header *tun;
1257     
1258     hdr= (struct GNUNET_MessageHeader *) buf;
1259     hdr->type = htons (42);
1260     hdr->size = htons (len);
1261     tun = (struct tun_header*) &hdr[1];
1262     tun->flags = htons (0);
1263     switch (source_address->af)
1264     {
1265     case AF_INET:
1266       {
1267         struct ip4_header * ipv4 = (struct ip4_header*) &tun[1];
1268         
1269         tun->proto = htons (ETH_P_IPV4);
1270         prepare_ipv4_packet (payload, payload_length, IPPROTO_TCP,
1271                              source_address,
1272                              destination_address,
1273                              ipv4);
1274       }
1275       break;
1276     case AF_INET6:
1277       {
1278         struct ip6_header * ipv6 = (struct ip6_header*) &tun[1];
1279         
1280         tun->proto = htons (ETH_P_IPV6);
1281         prepare_ipv6_packet (payload, payload_length, IPPROTO_TCP,
1282                              source_address,
1283                              destination_address,
1284                              ipv6);
1285       }
1286       break;    
1287     default:
1288       GNUNET_assert (0);
1289       break;
1290     }
1291     (void) GNUNET_HELPER_send (helper_handle,
1292                                (const struct GNUNET_MessageHeader*) buf,
1293                                GNUNET_YES,
1294                                NULL, NULL);
1295   }
1296 }
1297
1298
1299 /**
1300  * The messages are one GNUNET_HashCode for the service followed by a struct tcp_packet
1301  * FIXME: document!
1302  */
1303 static int
1304 receive_tcp_service (void *unused GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1305                      void **tunnel_ctx GNUNET_UNUSED,
1306                      const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1307                      const struct GNUNET_MessageHeader *message,
1308                      const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1309 {
1310   struct TunnelState *state = *tunnel_ctx;
1311   // FIXME: write proper request struct (we don't need the descriptor EACH time here!)
1312   const GNUNET_HashCode *desc = (const GNUNET_HashCode *) &message[1];
1313   const struct tcp_packet *pkt = (const struct tcp_packet *) &desc[1];
1314   uint16_t pkt_len = ntohs (message->size);
1315
1316
1317   /* check that we got at least a valid header */
1318   if (pkt_len < sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + sizeof (struct tcp_packet))
1319   {
1320     GNUNET_break_op (0);
1321     return GNUNET_YES;
1322   }
1323   pkt_len -= (sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode));
1324
1325   if (NULL == state->serv) 
1326   {
1327     /* setup fresh connection */
1328     GNUNET_assert (NULL == state->heap_node);
1329     if (NULL == (state->serv = find_service (tcp_services, desc, ntohs (pkt->dpt))))
1330     {
1331       GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
1332                   _("No service found for %s on port %d!\n"),
1333                   "TCP",
1334                   ntohs (pkt->dpt));
1335       GNUNET_MESH_tunnel_destroy (state->tunnel);
1336       return GNUNET_YES;
1337     }
1338     state->ri.remote_address = state->serv->address;    
1339     setup_state_record (state);
1340   }
1341   send_tcp_packet_via_tun (&state->ri.remote_address,
1342                            &state->ri.local_address,
1343                            pkt, pkt_len);
1344   return GNUNET_YES;
1345 }
1346
1347
1348 /**
1349  * FIXME: document!
1350  */
1351 static int
1352 receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1353                     void **tunnel_ctx GNUNET_UNUSED,
1354                     const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1355                     const struct GNUNET_MessageHeader *message,
1356                     const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1357 {
1358   struct TunnelState *state = *tunnel_ctx;
1359   // FIXME: write proper request struct (!)
1360   const GNUNET_HashCode *desc = (const GNUNET_HashCode *) &message[1];
1361   const struct tcp_packet *pkt = (const struct tcp_packet *) &desc[1];
1362   const struct SocketAddress *s = (const struct SocketAddress *) desc;
1363   uint16_t pkt_len = ntohs (message->size);
1364
1365   if (pkt_len < sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + sizeof (struct tcp_packet))
1366   {
1367     GNUNET_break_op (0);
1368     return GNUNET_YES;
1369   }
1370   pkt_len -= (sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode));
1371
1372   if (NULL == state->heap_node)
1373   {
1374     /* first packet, setup record */
1375     state->ri.remote_address = *s;
1376     setup_state_record (state);
1377   }
1378
1379   send_tcp_packet_via_tun (&state->ri.remote_address,
1380                            &state->ri.local_address,
1381                            pkt, pkt_len);
1382   return GNUNET_YES;
1383 }
1384
1385
1386 /**
1387  * FIXME: document!
1388  * @param payload payload of the UDP packet (does NOT include UDP header)
1389  */
1390 static void
1391 send_udp_packet_via_tun (const struct SocketAddress *destination_address,
1392                          const struct SocketAddress *source_address,
1393                          const void *payload, size_t payload_length)
1394 {
1395   size_t len;
1396
1397   len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct tun_header);
1398   switch (source_address->af)
1399   {
1400   case AF_INET:
1401     len += sizeof (struct ip4_header);
1402     break;
1403   case AF_INET6:
1404     len += sizeof (struct ip6_header);
1405     break;
1406   default:
1407     GNUNET_break (0);
1408     return;
1409   }
1410   len += sizeof (struct udp_packet);
1411   len += payload_length;
1412   if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1413   {
1414     GNUNET_break (0);
1415     return;
1416   }
1417   {
1418     char buf[len];
1419     struct GNUNET_MessageHeader *hdr;
1420     struct tun_header *tun;
1421     
1422     hdr= (struct GNUNET_MessageHeader *) buf;
1423     hdr->type = htons (42);
1424     hdr->size = htons (len);
1425     tun = (struct tun_header*) &hdr[1];
1426     tun->flags = htons (0);
1427     switch (source_address->af)
1428     {
1429     case AF_INET:
1430       {
1431         struct ip4_header * ipv4 = (struct ip4_header*) &tun[1];
1432         
1433         tun->proto = htons (ETH_P_IPV4);
1434         prepare_ipv4_packet (payload, payload_length, IPPROTO_UDP,
1435                              source_address,
1436                              destination_address,
1437                              ipv4);
1438       }
1439       break;
1440     case AF_INET6:
1441       {
1442         struct ip6_header * ipv6 = (struct ip6_header*) &tun[1];
1443         
1444         tun->proto = htons (ETH_P_IPV6);
1445         prepare_ipv6_packet (payload, payload_length, IPPROTO_UDP,
1446                              source_address,
1447                              destination_address,
1448                              ipv6);
1449       }
1450       break;    
1451     default:
1452       GNUNET_assert (0);
1453       break;
1454     }
1455     (void) GNUNET_HELPER_send (helper_handle,
1456                                (const struct GNUNET_MessageHeader*) buf,
1457                                GNUNET_YES,
1458                                NULL, NULL);
1459   }
1460 }
1461
1462
1463 /**
1464  * FIXME: document!
1465  */
1466 static int
1467 receive_udp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1468                     void **tunnel_ctx GNUNET_UNUSED,
1469                     const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1470                     const struct GNUNET_MessageHeader *message,
1471                     const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1472 {
1473   struct TunnelState *state = *tunnel_ctx;
1474   // FIXME: write proper request struct (!)
1475   const GNUNET_HashCode *desc = (const GNUNET_HashCode *) &message[1];
1476   const struct udp_packet *pkt = (const struct udp_packet *) &desc[1];
1477   const struct SocketAddress *s = (const struct SocketAddress *) desc;
1478   uint16_t pkt_len = ntohs (message->size);
1479
1480   if (pkt_len < sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + sizeof (struct udp_packet))
1481   {
1482     GNUNET_break_op (0);
1483     return GNUNET_YES;
1484   }
1485   pkt_len -= (sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode));
1486
1487   if (NULL == state->heap_node)
1488   {
1489     /* first packet, setup record */
1490     state->ri.remote_address = *s;
1491     setup_state_record (state);
1492   }
1493
1494   send_udp_packet_via_tun (&state->ri.remote_address,
1495                            &state->ri.local_address,
1496                            &pkt[1], pkt_len - sizeof (struct udp_packet));
1497   return GNUNET_YES;
1498 }
1499
1500
1501 /**
1502  * FIXME: document!
1503  */
1504 static int
1505 receive_udp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1506                      void **tunnel_ctx,
1507                      const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1508                      const struct GNUNET_MessageHeader *message,
1509                      const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1510 {
1511   struct TunnelState *state = *tunnel_ctx;
1512   // FIXME: write proper request struct (we don't need UDP except dpt either!)
1513   const GNUNET_HashCode *desc = (const GNUNET_HashCode *) &message[1];
1514   const struct udp_packet *pkt = (const struct udp_packet *) &desc[1];
1515   uint16_t pkt_len = ntohs (message->size);
1516
1517
1518   /* check that we got at least a valid header */
1519   if (pkt_len < sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + sizeof (struct udp_packet))
1520   {
1521     GNUNET_break_op (0);
1522     return GNUNET_YES;
1523   }
1524   pkt_len -= (sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode));
1525
1526   GNUNET_assert (ntohs (pkt->len) ==
1527                  ntohs (message->size) - sizeof (struct GNUNET_MessageHeader) -
1528                  sizeof (GNUNET_HashCode));
1529
1530   if (NULL == state->serv) 
1531   {
1532     /* setup fresh connection */
1533     GNUNET_assert (NULL == state->heap_node);
1534     if (NULL == (state->serv = find_service (udp_services, desc, ntohs (pkt->dpt))))
1535     {
1536       GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
1537                   _("No service found for %s on port %d!\n"),
1538                   "UDP",
1539                   ntohs (pkt->dpt));
1540       GNUNET_MESH_tunnel_destroy (state->tunnel);
1541       return GNUNET_YES;
1542     }
1543     state->ri.remote_address = state->serv->address;    
1544     setup_state_record (state);
1545   }
1546   send_udp_packet_via_tun (&state->ri.remote_address,
1547                            &state->ri.local_address,
1548                            &pkt[1], pkt_len - sizeof (struct udp_packet));
1549   return GNUNET_YES;
1550 }
1551
1552
1553 /**
1554  * Callback from GNUNET_MESH for new tunnels.
1555  *
1556  * @param cls closure
1557  * @param tunnel new handle to the tunnel
1558  * @param initiator peer that started the tunnel
1559  * @param atsi performance information for the tunnel
1560  * @return initial tunnel context for the tunnel
1561  */
1562 static void *
1563 new_tunnel (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1564             const struct GNUNET_PeerIdentity *initiator GNUNET_UNUSED,
1565             const struct GNUNET_ATS_Information *ats GNUNET_UNUSED)
1566 {
1567   struct TunnelState *s = GNUNET_malloc (sizeof (struct TunnelState));
1568   
1569   s->tunnel = tunnel;
1570   return s;
1571 }
1572
1573
1574 /**
1575  * Function called by mesh whenever an inbound tunnel is destroyed.
1576  * Should clean up any associated state.
1577  *
1578  * @param cls closure (set from GNUNET_MESH_connect)
1579  * @param tunnel connection to the other end (henceforth invalid)
1580  * @param tunnel_ctx place where local state associated
1581  *                   with the tunnel is stored
1582  */
1583 static void
1584 clean_tunnel (void *cls GNUNET_UNUSED, const struct GNUNET_MESH_Tunnel *tunnel,
1585               void *tunnel_ctx)
1586 {
1587   struct TunnelState *s = tunnel_ctx;
1588   struct TunnelMessageQueue *tnq;
1589
1590   while (NULL != (tnq = s->head))
1591   {
1592     GNUNET_CONTAINER_DLL_remove (s->head,
1593                                  s->tail,
1594                                  tnq);
1595     GNUNET_free (tnq);
1596   }
1597   if (s->heap_node != NULL)
1598   {
1599     GNUNET_assert (GNUNET_YES ==
1600                    GNUNET_CONTAINER_multihashmap_remove (connections_map,
1601                                                          &s->state_key,
1602                                                          s));
1603     GNUNET_CONTAINER_heap_remove_node (s->heap_node);
1604     s->heap_node = NULL;
1605   }
1606   if (NULL != s->th)
1607   {
1608     GNUNET_MESH_notify_transmit_ready_cancel (s->th);
1609     s->th = NULL;
1610   }
1611   GNUNET_free (s);
1612 }
1613
1614
1615 /**
1616  * Function that frees everything from a hashmap
1617  *
1618  * @param cls unused
1619  * @param hash key
1620  * @param value value to free
1621  */
1622 static int
1623 free_iterate (void *cls GNUNET_UNUSED,
1624               const GNUNET_HashCode * hash GNUNET_UNUSED, void *value)
1625 {
1626   GNUNET_free (value);
1627   return GNUNET_YES;
1628 }
1629
1630
1631 /**
1632  * Function scheduled as very last function, cleans up after us
1633  */
1634 static void
1635 cleanup (void *cls GNUNET_UNUSED,
1636          const struct GNUNET_SCHEDULER_TaskContext *tskctx)
1637 {
1638   unsigned int i;
1639
1640   if (helper_handle != NULL)
1641   {
1642     GNUNET_HELPER_stop (helper_handle);
1643     helper_handle = NULL;
1644   }
1645   if (mesh_handle != NULL)
1646   {
1647     GNUNET_MESH_disconnect (mesh_handle);
1648     mesh_handle = NULL;
1649   }
1650   if (NULL != connections_map)
1651   {
1652     GNUNET_CONTAINER_multihashmap_iterate (connections_map, &free_iterate, NULL);
1653     GNUNET_CONTAINER_multihashmap_destroy (connections_map);
1654     connections_map = NULL;
1655   }
1656   if (NULL != connections_heap)
1657   {
1658     GNUNET_CONTAINER_heap_destroy (connections_heap);
1659     connections_heap = NULL;
1660   }
1661   if (NULL != tcp_services)
1662   {
1663     GNUNET_CONTAINER_multihashmap_iterate (tcp_services, &free_service_record, NULL);
1664     GNUNET_CONTAINER_multihashmap_destroy (tcp_services);
1665     tcp_services = NULL;
1666   }
1667   if (NULL != udp_services)
1668   {
1669     GNUNET_CONTAINER_multihashmap_iterate (udp_services, &free_service_record, NULL);
1670     GNUNET_CONTAINER_multihashmap_destroy (udp_services);
1671     udp_services = NULL;
1672   }
1673   for (i=0;i<5;i++)
1674     GNUNET_free_non_null (exit_argv[i]);
1675 }
1676
1677
1678 /**
1679  * Add services to the service map.
1680  *
1681  * @param proto IPPROTO_TCP or IPPROTO_UDP
1682  * @param cpy copy of the service descriptor (can be mutilated)
1683  * @param name DNS name of the service
1684  */
1685 static void
1686 add_services (int proto,
1687               char *cpy,
1688               const char *name)
1689 {
1690   char *redirect;
1691   char *hostname;
1692   char *hostport;
1693   struct LocalService *serv;
1694
1695   for (redirect = strtok (cpy, " "); redirect != NULL;
1696        redirect = strtok (NULL, " "))
1697   {
1698     if (NULL == (hostname = strstr (redirect, ":")))
1699     {
1700       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1701                   "option `%s' for domain `%s' is not formatted correctly!\n",
1702                   redirect,
1703                   name);
1704       continue;
1705     }
1706     hostname[0] = '\0';
1707     hostname++;
1708     if (NULL == (hostport = strstr (hostname, ":")))
1709     {
1710       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1711                   "option `%s' for domain `%s' is not formatted correctly!\n",
1712                   redirect,
1713                   name);
1714       continue;
1715     }
1716     hostport[0] = '\0';
1717     hostport++;
1718     
1719     int local_port = atoi (redirect);
1720     int remote_port = atoi (hostport);
1721     
1722     if (!((local_port > 0) && (local_port < 65536)))
1723     {
1724       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1725                   "`%s' is not a valid port number (for domain `%s')!", redirect,
1726                   name);
1727       continue;
1728     }
1729     if (!((remote_port > 0) && (remote_port < 65536)))
1730     {
1731       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1732                   "`%s' is not a valid port number (for domain `%s')!", hostport,
1733                   name);
1734       continue;
1735     }
1736
1737     serv = GNUNET_malloc (sizeof (struct LocalService));
1738     serv->my_port = (uint16_t) local_port;
1739     serv->address.port = remote_port;
1740     if (0 == strcmp ("localhost4", hostname))
1741     {
1742       const char *ip4addr = exit_argv[4];
1743
1744       serv->address.af = AF_INET;      
1745       GNUNET_assert (1 != inet_pton (AF_INET, ip4addr, &serv->address.address.ipv4));
1746     }
1747     else if (0 == strcmp ("localhost6", hostname))
1748     {
1749       const char *ip6addr = exit_argv[2];
1750
1751       serv->address.af = AF_INET6;
1752       GNUNET_assert (1 == inet_pton (AF_INET6, ip6addr, &serv->address.address.ipv6));
1753     }
1754     else
1755     {
1756       struct addrinfo *res;      
1757       int ret;
1758
1759       ret = getaddrinfo (hostname, NULL, NULL, &res);      
1760       if ( (ret != 0) || (res == NULL) )
1761       {
1762         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1763                     _("No addresses found for hostname `%s' of service `%s'!\n"),
1764                     hostname,
1765                     name);
1766         GNUNET_free (serv);
1767         continue;
1768       }
1769       
1770       serv->address.af = res->ai_family;
1771       switch (res->ai_family)
1772       {
1773         case AF_INET:
1774           serv->address.address.ipv4 = ((struct sockaddr_in *) res->ai_addr)->sin_addr;
1775           break;
1776         case AF_INET6:
1777           serv->address.address.ipv6 = ((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
1778           break;
1779       default:
1780         freeaddrinfo (res);
1781         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1782                     _("No IP addresses found for hostname `%s' of service `%s'!\n"),
1783                     hostname,
1784                     name);
1785         GNUNET_free (serv);
1786         continue;
1787       }
1788       freeaddrinfo (res);
1789     }
1790     store_service ((IPPROTO_UDP == proto) ? udp_services : tcp_services,
1791                    name,
1792                    local_port,
1793                    serv);
1794   }
1795 }
1796
1797
1798 /**
1799  * Reads the configuration servicecfg and populates udp_services
1800  *
1801  * @param cls unused
1802  * @param section name of section in config, equal to hostname
1803  */
1804 static void
1805 read_service_conf (void *cls GNUNET_UNUSED, const char *section)
1806 {
1807   char *cpy;
1808
1809   if ((strlen (section) < 8) ||
1810       (0 != strcmp (".gnunet.", section + (strlen (section) - 8))))
1811     return;
1812   if (GNUNET_OK ==
1813       GNUNET_CONFIGURATION_get_value_string (cfg, section, "UDP_REDIRECTS",
1814                                              &cpy))
1815   {
1816     add_services (IPPROTO_UDP, cpy, section);
1817     GNUNET_free (cpy);
1818   }
1819   if (GNUNET_OK ==
1820       GNUNET_CONFIGURATION_get_value_string (cfg, section, "TCP_REDIRECTS",
1821                                              &cpy))
1822   {
1823     add_services (IPPROTO_TCP, cpy, section);
1824     GNUNET_free (cpy);
1825   }
1826 }
1827
1828
1829 /**
1830  * @brief Main function that will be run by the scheduler.
1831  *
1832  * @param cls closure
1833  * @param args remaining command-line arguments
1834  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
1835  * @param cfg_ configuration
1836  */
1837 static void
1838 run (void *cls, char *const *args GNUNET_UNUSED,
1839      const char *cfgfile GNUNET_UNUSED,
1840      const struct GNUNET_CONFIGURATION_Handle *cfg_)
1841 {
1842   static struct GNUNET_MESH_MessageHandler handlers[] = {
1843     {&receive_udp_service, GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP, 0},
1844     {&receive_tcp_service, GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP, 0},
1845     {NULL, 0, 0},
1846     {NULL, 0, 0},
1847     {NULL, 0, 0}
1848   };
1849
1850   static GNUNET_MESH_ApplicationType apptypes[] = {
1851     GNUNET_APPLICATION_TYPE_END,
1852     GNUNET_APPLICATION_TYPE_END,
1853     GNUNET_APPLICATION_TYPE_END
1854   };
1855   unsigned int handler_idx;
1856   unsigned int app_idx;
1857   int udp;
1858   int tcp;
1859   char *ifname;
1860   char *ipv6addr;
1861   char *ipv6prefix_s;
1862   char *ipv4addr;
1863   char *ipv4mask;
1864   struct in_addr v4;
1865   struct in6_addr v6;
1866
1867   cfg = cfg_;
1868   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls);
1869   if (GNUNET_OK !=
1870       GNUNET_CONFIGURATION_get_value_number (cfg, "exit", "MAX_CONNECTIONS",
1871                                              &max_connections))
1872     max_connections = 1024;
1873   exit_argv[0] = GNUNET_strdup ("exit-gnunet");
1874   if (GNUNET_SYSERR ==
1875       GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IFNAME", &ifname))
1876   {
1877     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1878                 "No entry 'IFNAME' in configuration!\n");
1879     GNUNET_SCHEDULER_shutdown ();
1880     return;
1881   }
1882   exit_argv[1] = ifname;
1883   if ( (GNUNET_SYSERR ==
1884         GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6ADDR",
1885                                                &ipv6addr) ||
1886         (1 != inet_pton (AF_INET6, ipv6addr, &v6))) )
1887   {
1888     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1889                 "No valid entry 'IPV6ADDR' in configuration!\n");
1890     GNUNET_SCHEDULER_shutdown ();
1891     return;
1892   }
1893   exit_argv[2] = ipv6addr;
1894   if (GNUNET_SYSERR ==
1895       GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6PREFIX",
1896                                              &ipv6prefix_s))
1897   {
1898     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1899                 "No entry 'IPV6PREFIX' in configuration!\n");
1900     GNUNET_SCHEDULER_shutdown ();
1901     return;
1902   }
1903   exit_argv[3] = ipv6prefix_s;
1904   if ( (GNUNET_OK !=
1905         GNUNET_CONFIGURATION_get_value_number (cfg, "exit",
1906                                                "IPV6PREFIX",
1907                                                &ipv6prefix)) ||
1908        (ipv6prefix >= 127) )
1909   {
1910     GNUNET_SCHEDULER_shutdown ();
1911     return;
1912   }
1913
1914   if ( (GNUNET_SYSERR ==
1915         GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4ADDR",
1916                                                &ipv4addr) ||
1917         (1 != inet_pton (AF_INET, ipv4addr, &v4))) )
1918   {
1919     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1920                 "No valid entry for 'IPV4ADDR' in configuration!\n");
1921     GNUNET_SCHEDULER_shutdown ();
1922     return;
1923   }
1924   exit_argv[4] = ipv4addr;
1925   if ( (GNUNET_SYSERR ==
1926         GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4MASK",
1927                                                &ipv4mask) ||
1928         (1 != inet_pton (AF_INET, ipv4mask, &v4))) )
1929   {
1930     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1931                 "No valid entry 'IPV4MASK' in configuration!\n");
1932     GNUNET_SCHEDULER_shutdown ();
1933     return;
1934   }
1935   exit_argv[5] = ipv4mask;
1936   exit_argv[6] = NULL;
1937
1938   app_idx = 0;
1939   handler_idx = 2;
1940   udp = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_UDP");
1941   tcp = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_TCP");
1942   if (GNUNET_YES == udp)
1943   {
1944     handlers[handler_idx].callback = &receive_udp_remote;
1945     handlers[handler_idx].expected_size = 0;
1946     handlers[handler_idx].type = GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP;
1947     apptypes[app_idx] = GNUNET_APPLICATION_TYPE_INTERNET_UDP_GATEWAY;
1948     handler_idx++;
1949     app_idx++;
1950   }
1951
1952   if (GNUNET_YES == tcp)
1953   {
1954     handlers[handler_idx].callback = &receive_tcp_remote;
1955     handlers[handler_idx].expected_size = 0;
1956     handlers[handler_idx].type = GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP;
1957     apptypes[app_idx] = GNUNET_APPLICATION_TYPE_INTERNET_TCP_GATEWAY;
1958     handler_idx++;
1959     app_idx++;
1960   }
1961   udp_services = GNUNET_CONTAINER_multihashmap_create (65536);
1962   tcp_services = GNUNET_CONTAINER_multihashmap_create (65536);
1963   GNUNET_CONFIGURATION_iterate_sections (cfg, &read_service_conf, NULL);
1964
1965   connections_map = GNUNET_CONTAINER_multihashmap_create (65536);
1966   connections_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
1967   mesh_handle 
1968     = GNUNET_MESH_connect (cfg, 42 /* queue size */, NULL, 
1969                            &new_tunnel, 
1970                            &clean_tunnel, handlers,
1971                            apptypes);
1972   if (NULL == mesh_handle)
1973   {
1974     GNUNET_SCHEDULER_shutdown ();
1975     return;
1976   }
1977   helper_handle = GNUNET_HELPER_start ("gnunet-helper-vpn", 
1978                                        exit_argv,
1979                                        &message_token, NULL);
1980 }
1981
1982
1983 /**
1984  * The main function
1985  *
1986  * @param argc number of arguments from the command line
1987  * @param argv command line arguments
1988  * @return 0 ok, 1 on error
1989  */
1990 int
1991 main (int argc, char *const *argv)
1992 {
1993   static const struct GNUNET_GETOPT_CommandLineOption options[] = {
1994     GNUNET_GETOPT_OPTION_END
1995   };
1996
1997   return (GNUNET_OK ==
1998           GNUNET_PROGRAM_run (argc, argv, "gnunet-daemon-exit",
1999                               gettext_noop
2000                               ("Daemon to run to provide an IP exit node for the VPN"),
2001                               options, &run, NULL)) ? 0 : 1;
2002 }
2003
2004
2005 /* end of gnunet-daemon-exit.c */