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