-updating todo notes
[oweals/gnunet.git] / src / vpn / gnunet-service-vpn.c
1 /*
2      This file is part of GNUnet.
3      (C) 2010, 2011, 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 vpn/gnunet-service-vpn.c
23  * @brief service that opens a virtual interface and allows its clients
24  *        to allocate IPs on the virtual interface and to then redirect
25  *        IP traffic received on those IPs via the GNUnet mesh 
26  * @author Philipp Toelke
27  * @author Christian Grothoff
28  *
29  * TODO:
30  * - fully implement shutdown code
31  * - create secondary mesh tunnels if needed / check overall tunnel creation/management code!
32  * => test!
33  * - better message queue management (bounded state, drop oldest/RED?)
34  * - improve support for deciding which tunnels to keep and which ones to destroy
35  * - add back ICMP support (especially needed for IPv6)
36  * - consider moving IP-header building / checksumming code into shared library
37  *   with dns/exit/vpn (libgnunettun_tcpip?)
38  */
39 #include "platform.h"
40 #include "gnunet_util_lib.h"
41 #include "gnunet_common.h"
42 #include "gnunet_protocols.h"
43 #include "gnunet_applications.h"
44 #include "gnunet_mesh_service.h"
45 #include "gnunet_constants.h"
46 #include "tcpip_tun.h"
47 #include "vpn.h"
48 #include "exit.h"
49
50 /**
51  * Information we track for each IP address to determine which tunnel
52  * to send the traffic over to the destination.
53  */
54 struct DestinationEntry
55 {
56   /**
57    * Information about the tunnel to use, NULL if no tunnel
58    * is available right now.
59    */
60   struct GNUNET_MESH_Tunnel *tunnel;
61
62   /**
63    * Entry for this entry in the destination_heap.
64    */
65   struct GNUNET_CONTAINER_HeapNode *heap_node;
66
67   /**
68    * GNUNET_NO if this is a tunnel to an Internet-exit,
69    * GNUNET_YES if this tunnel is to a service.
70    */
71   int is_service;
72
73   /**
74    * Details about the connection (depending on is_service).
75    */
76   union
77   {
78
79     struct
80     {
81       /**
82        * The description of the service (only used for service tunnels).
83        */
84       GNUNET_HashCode service_descriptor;
85
86       /**
87        * Peer offering the service.
88        */
89       struct GNUNET_PeerIdentity target;
90
91     } service_destination;
92
93     struct 
94     {
95   
96       /**
97        * Address family used (AF_INET or AF_INET6).
98        */
99       int af;
100       
101       /**
102        * IP address of the ultimate destination (only used for exit tunnels).
103        */
104       union
105       {
106         /**
107          * Address if af is AF_INET.
108          */
109         struct in_addr v4;
110         
111         /**
112          * Address if af is AF_INET6.
113          */
114         struct in6_addr v6;
115       } ip;
116
117     } exit_destination;
118
119   } details;
120     
121 };
122
123
124 /**
125  * A messages we have in queue for a particular tunnel.
126  */
127 struct TunnelMessageQueueEntry
128 {
129   /**
130    * This is a doubly-linked list.
131    */
132   struct TunnelMessageQueueEntry *next;
133
134   /**
135    * This is a doubly-linked list.
136    */
137   struct TunnelMessageQueueEntry *prev;
138   
139   /**
140    * Number of bytes in 'msg'.
141    */
142   size_t len;
143
144   /**
145    * Message to transmit, allocated at the end of this struct.
146    */
147   const void *msg;
148 };
149
150
151 /**
152  * State we keep for each of our tunnels.
153  */
154 struct TunnelState
155 {
156   /**
157    * Active transmission handle, NULL for none.
158    */
159   struct GNUNET_MESH_TransmitHandle *th;
160
161   /**
162    * Entry for this entry in the tunnel_heap, NULL as long as this
163    * tunnel state is not fully bound.
164    */
165   struct GNUNET_CONTAINER_HeapNode *heap_node;
166
167   /**
168    * Head of list of messages scheduled for transmission.
169    */
170   struct TunnelMessageQueueEntry *head;
171
172   /**
173    * Tail of list of messages scheduled for transmission.
174    */
175   struct TunnelMessageQueueEntry *tail;
176
177   /**
178    * Client that needs to be notified about the tunnel being
179    * up as soon as a peer is connected; NULL for none.
180    */
181   struct GNUNET_SERVER_Client *client;
182
183   /**
184    * ID of the client request that caused us to setup this entry.
185    */ 
186   uint64_t request_id;
187
188   /**
189    * Destination to which this tunnel leads.  Note that
190    * this struct is NOT in the destination_map (but a
191    * local copy) and that the 'heap_node' should always
192    * be NULL.
193    */
194   struct DestinationEntry destination;
195
196   /**
197    * GNUNET_NO if this is a tunnel to an Internet-exit,
198    * GNUNET_YES if this tunnel is to a service.
199    */
200   int is_service;
201
202   /**
203    * Addess family used for this tunnel on the local TUN interface.
204    */
205   int af;
206
207   /**
208    * IP address of the source on our end, initially uninitialized.
209    */
210   union
211   {
212     /**
213      * Address if af is AF_INET.
214      */
215     struct in_addr v4;
216     
217     /**
218      * Address if af is AF_INET6.
219      */
220     struct in6_addr v6;
221
222   } source_ip;
223
224   /**
225    * Destination IP address used by the source on our end (this is the IP
226    * that we pick freely within the VPN's tunnel IP range).
227    */
228   union
229   {
230     /**
231      * Address if af is AF_INET.
232      */
233     struct in_addr v4;
234     
235     /**
236      * Address if af is AF_INET6.
237      */
238     struct in6_addr v6;
239
240   } destination_ip;
241
242   /**
243    * Source port used by the sender on our end; 0 for uninitialized.
244    */
245   uint16_t source_port;
246
247   /**
248    * Destination port used by the sender on our end; 0 for uninitialized.
249    */
250   uint16_t destination_port;
251
252 };
253
254
255 /**
256  * Configuration we use.
257  */
258 static const struct GNUNET_CONFIGURATION_Handle *cfg;
259
260 /**
261  * Handle to the mesh service.
262  */
263 static struct GNUNET_MESH_Handle *mesh_handle;
264
265 /**
266  * Map from IP address to destination information (possibly with a
267  * MESH tunnel handle for fast setup).
268  */
269 static struct GNUNET_CONTAINER_MultiHashMap *destination_map;
270
271 /**
272  * Min-Heap sorted by activity time to expire old mappings.
273  */
274 static struct GNUNET_CONTAINER_Heap *destination_heap;
275
276 /**
277  * Map from source and destination address (IP+port) to connection
278  * information (mostly with the respective MESH tunnel handle).
279  */
280 static struct GNUNET_CONTAINER_MultiHashMap *tunnel_map;
281
282 /**
283  * Min-Heap sorted by activity time to expire old mappings.
284  */
285 static struct GNUNET_CONTAINER_Heap *tunnel_heap;
286
287 /**
288  * The handle to the VPN helper process "gnunet-helper-vpn".
289  */
290 static struct GNUNET_HELPER_Handle *helper_handle;
291
292 /**
293  * Arguments to the vpn helper.
294  */
295 static char *vpn_argv[7];
296
297 /**
298  * Length of the prefix of the VPN's IPv6 network.
299  */
300 static unsigned long long ipv6prefix;
301
302 /**
303  * Notification context for sending replies to clients.
304  */
305 static struct GNUNET_SERVER_NotificationContext *nc;
306
307 /**
308  * If there are more than this number of address-mappings, old ones
309  * will be removed
310  */
311 static unsigned long long max_destination_mappings;
312
313 /**
314  * If there are more than this number of open tunnels, old ones
315  * will be removed
316  */
317 static unsigned long long max_tunnel_mappings;
318
319
320 /**
321  * Compute the key under which we would store an entry in the
322  * destination_map for the given IP address.
323  *
324  * @param af address family (AF_INET or AF_INET6)
325  * @param address IP address, struct in_addr or struct in6_addr
326  * @param key where to store the key
327  */
328 static void
329 get_destination_key_from_ip (int af,
330                              const void *address,
331                              GNUNET_HashCode *key)
332 {
333   switch (af)
334   {
335   case AF_INET:
336     GNUNET_CRYPTO_hash (address,
337                         sizeof (struct in_addr),
338                         key);
339     break;
340   case AF_INET6:
341     GNUNET_CRYPTO_hash (address,
342                         sizeof (struct in6_addr),
343                         key);
344     break;
345   default:
346     GNUNET_assert (0);
347     break;
348   }
349 }
350
351
352 /**
353  * Compute the key under which we would store an entry in the
354  * tunnel_map for the given socket address pair.
355  *
356  * @param af address family (AF_INET or AF_INET6)
357  * @param protocol IPPROTO_TCP or IPPROTO_UDP
358  * @param source_ip sender's source IP, struct in_addr or struct in6_addr
359  * @param source_port sender's source port
360  * @param destination_ip sender's destination IP, struct in_addr or struct in6_addr
361  * @param destination_port sender's destination port
362  * @param key where to store the key
363  */
364 static void
365 get_tunnel_key_from_ips (int af,
366                          uint8_t protocol,
367                          const void *source_ip,
368                          uint16_t source_port,
369                          const void *destination_ip,
370                          uint16_t destination_port,
371                          GNUNET_HashCode *key)
372 {
373   char *off;
374
375   memset (key, 0, sizeof (GNUNET_HashCode));
376   /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
377      so we put the ports in there (and hope for few collisions) */
378   off = (char*) key;
379   memcpy (off, &source_port, sizeof (uint16_t));
380   off += sizeof (uint16_t);
381   memcpy (off, &destination_port, sizeof (uint16_t));
382   off += sizeof (uint16_t);
383   switch (af)
384   {
385   case AF_INET:
386     memcpy (off, source_ip, sizeof (struct in_addr));
387     off += sizeof (struct in_addr);
388     memcpy (off, destination_ip, sizeof (struct in_addr));
389     off += sizeof (struct in_addr);
390     break;
391   case AF_INET6:
392     memcpy (off, source_ip, sizeof (struct in6_addr));
393     off += sizeof (struct in6_addr);
394     memcpy (off, destination_ip, sizeof (struct in6_addr));
395     off += sizeof (struct in6_addr);
396     break;
397   default:
398     GNUNET_assert (0);
399     break;
400   }
401   memcpy (off, &protocol, sizeof (uint8_t));
402   off += sizeof (uint8_t);  
403 }
404
405
406 /**
407  * Notify the client about the result of its request.
408  *
409  * @param client client to notify
410  * @param request_id original request ID to include in response
411  * @param result_af resulting address family
412  * @param addr resulting IP address
413  */
414 static void
415 send_client_reply (struct GNUNET_SERVER_Client *client,
416                    uint64_t request_id,
417                    int result_af,
418                    const void *addr)
419 {
420   char buf[sizeof (struct RedirectToIpResponseMessage) + sizeof (struct in6_addr)];
421   struct RedirectToIpResponseMessage *res;
422   size_t rlen;
423
424   switch (result_af)
425   {
426   case AF_INET:
427     rlen = sizeof (struct in_addr);    
428     break;
429   case AF_INET6:
430     rlen = sizeof (struct in6_addr);
431     break;
432   case AF_UNSPEC:
433     rlen = 0;
434     break;
435   default:
436     GNUNET_assert (0);
437     return;
438   }
439   res = (struct RedirectToIpResponseMessage *) buf;
440   res->header.size = htons (sizeof (struct RedirectToIpResponseMessage) + rlen);
441   res->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP);
442   res->result_af = htonl (result_af);
443   res->request_id = request_id;
444   memcpy (&res[1], addr, rlen);
445   GNUNET_SERVER_notification_context_add (nc, client);
446   GNUNET_SERVER_notification_context_unicast (nc,
447                                               client,
448                                               &res->header,
449                                               GNUNET_NO);
450 }
451
452
453 /**
454  * Method called whenever a peer has disconnected from the tunnel.
455  *
456  * @param cls closure
457  * @param peer peer identity the tunnel stopped working with
458  */
459 static void
460 tunnel_peer_disconnect_handler (void *cls,
461                                 const struct
462                                 GNUNET_PeerIdentity * peer)
463 {
464   /* FIXME: should we do anything here? 
465    - stop transmitting to the tunnel (start queueing?)
466    - possibly destroy the tunnel entirely (unless service tunnel?) 
467   */
468 }
469
470
471 /**
472  * Method called whenever a peer has connected to the tunnel.  Notifies
473  * the waiting client that the tunnel is now up.
474  *
475  * @param cls closure
476  * @param peer peer identity the tunnel was created to, NULL on timeout
477  * @param atsi performance data for the connection
478  */
479 static void
480 tunnel_peer_connect_handler (void *cls,
481                              const struct GNUNET_PeerIdentity
482                              * peer,
483                              const struct
484                              GNUNET_ATS_Information * atsi)
485 {
486   struct TunnelState *ts = cls;
487
488   if (NULL == ts->client)
489     return; /* nothing to do */
490   send_client_reply (ts->client,
491                      ts->request_id,
492                      ts->af,
493                      &ts->destination_ip);
494   GNUNET_SERVER_client_drop (ts->client);
495   ts->client = NULL;
496 }
497
498
499 /**
500  * Send a message from the message queue via mesh.
501  *
502  * @param cls the 'struct TunnelState' with the message queue
503  * @param size number of bytes available in buf
504  * @param buf where to copy the message
505  * @return number of bytes copied to buf
506  */
507 static size_t
508 send_to_peer_notify_callback (void *cls, size_t size, void *buf)
509 {
510   struct TunnelState *ts = cls;
511   struct TunnelMessageQueueEntry *tnq;
512   size_t ret;
513
514   ts->th = NULL;
515   if (NULL == buf)
516     return 0;
517   tnq = ts->head;
518   GNUNET_assert (NULL != tnq);
519   GNUNET_assert (size >= tnq->len);
520   GNUNET_CONTAINER_DLL_remove (ts->head,
521                                ts->tail,
522                                tnq);
523   memcpy (buf, tnq->msg, tnq->len);
524   ret = tnq->len;
525   GNUNET_free (tnq);
526   if (NULL != (tnq = ts->head))
527     ts->th = GNUNET_MESH_notify_transmit_ready (ts->destination.tunnel, 
528                                                 GNUNET_NO /* cork */, 
529                                                 42 /* priority */,
530                                                 GNUNET_TIME_UNIT_FOREVER_REL,
531                                                 NULL, 
532                                                 tnq->len,
533                                                 &send_to_peer_notify_callback,
534                                                 ts);
535   return ret;
536 }
537
538
539 /**
540  * Add the given message to the given tunnel and
541  * trigger the transmission process.
542  *
543  * @param tnq message to queue
544  * @param ts tunnel to queue the message for
545  */
546 static void
547 send_to_tunnel (struct TunnelMessageQueueEntry *tnq,
548                 struct TunnelState *ts)
549 {
550   GNUNET_CONTAINER_DLL_insert_tail (ts->head,
551                                     ts->tail,
552                                     tnq);
553   if (NULL == ts->th)
554     ts->th = GNUNET_MESH_notify_transmit_ready (ts->destination.tunnel, 
555                                                 GNUNET_NO /* cork */,
556                                                 42 /* priority */,
557                                                 GNUNET_TIME_UNIT_FOREVER_REL,
558                                                 NULL, 
559                                                 tnq->len,
560                                                 &send_to_peer_notify_callback,
561                                                 ts);
562 }
563
564
565 /**
566  * Route a packet via mesh to the given destination.  
567  *
568  * @param destination description of the destination
569  * @param af address family on this end (AF_INET or AF_INET6)
570  * @param protocol IPPROTO_TCP or IPPROTO_UDP
571  * @param source_ip source IP used by the sender (struct in_addr or struct in6_addr)
572  * @param destination_ip destination IP used by the sender (struct in_addr or struct in6_addr)
573  * @param payload payload of the packet after the IP header
574  * @param payload_length number of bytes in payload
575  */
576 static void
577 route_packet (struct DestinationEntry *destination,
578               int af,
579               uint8_t protocol,
580               const void *source_ip,
581               const void *destination_ip,
582               const void *payload,
583               size_t payload_length)
584 {
585   GNUNET_HashCode key;
586   struct TunnelState *ts;
587   struct TunnelMessageQueueEntry *tnq;
588   size_t alen;
589   size_t mlen;
590   GNUNET_MESH_ApplicationType app_type;
591   int is_new;
592   const struct udp_packet *udp;
593   const struct tcp_packet *tcp;
594     
595   switch (protocol)
596   {
597   case IPPROTO_UDP:
598     {
599       if (payload_length < sizeof (struct udp_packet))
600       {
601         /* blame kernel? */
602         GNUNET_break (0);
603         return;
604       }
605       udp = payload;
606       get_tunnel_key_from_ips (af,
607                                IPPROTO_UDP,
608                                source_ip,
609                                ntohs (udp->spt),
610                                destination_ip,
611                                ntohs (udp->dpt),
612                                &key);
613     }
614     break;
615   case IPPROTO_TCP:
616     {
617       if (payload_length < sizeof (struct tcp_packet))
618       {
619         /* blame kernel? */
620         GNUNET_break (0);
621         return;
622       }
623       tcp = payload;
624       get_tunnel_key_from_ips (af,
625                                IPPROTO_TCP,
626                                source_ip,
627                                ntohs (tcp->spt),
628                                destination_ip,
629                                ntohs (tcp->dpt),
630                                &key);
631     }
632     break;
633   default:
634     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
635                 _("Protocol %u not supported, dropping\n"),
636                 (unsigned int) protocol);
637     return;
638   }
639
640   if (! destination->is_service)
641   {  
642     switch (destination->details.exit_destination.af)
643     {
644     case AF_INET:
645       alen = sizeof (struct in_addr);
646       app_type = GNUNET_APPLICATION_TYPE_IPV4_GATEWAY; 
647      break;
648     case AF_INET6:
649       alen = sizeof (struct in6_addr);
650       app_type = GNUNET_APPLICATION_TYPE_IPV6_GATEWAY; 
651       break;
652     default:
653       alen = 0;
654       GNUNET_assert (0);
655     }
656   }
657   else
658   {
659     /* make compiler happy */
660     alen = 0;
661     app_type = 0;
662   }
663
664   // FIXME: something is horrifically wrong here about
665   // how we lookup 'ts', match it and how we decide about
666   // creating new tunnels!
667   /* find tunnel */
668   is_new = GNUNET_NO;
669   ts = GNUNET_CONTAINER_multihashmap_get (tunnel_map,
670                                           &key);
671   if (NULL == ts)
672   {
673     /* create new tunnel */
674     is_new = GNUNET_YES;
675     ts = GNUNET_malloc (sizeof (struct TunnelState));
676     ts->destination.tunnel = GNUNET_MESH_tunnel_create (mesh_handle,
677                                                         ts,
678                                                         &tunnel_peer_connect_handler,
679                                                         &tunnel_peer_disconnect_handler, 
680                                                         ts);
681     if (destination->is_service)
682       GNUNET_MESH_peer_request_connect_add (ts->destination.tunnel,
683                                             &destination->details.service_destination.target);
684     else
685       GNUNET_MESH_peer_request_connect_by_type (ts->destination.tunnel,
686                                                 app_type);
687   }
688   
689   /* send via tunnel */
690   switch (protocol)
691   {
692   case IPPROTO_UDP:
693     if (destination->is_service)
694     {
695       struct GNUNET_EXIT_UdpServiceMessage *usm;
696
697       mlen = sizeof (struct GNUNET_EXIT_UdpServiceMessage) + 
698         payload_length - sizeof (struct udp_packet);
699       if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
700       {
701         GNUNET_break (0);
702         return;
703       }
704       tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + mlen);
705       usm = (struct GNUNET_EXIT_UdpServiceMessage *) &tnq[1];
706       usm->header.size = htons ((uint16_t) mlen);
707       usm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE);
708       /* if the source port is below 32000, we assume it has a special
709          meaning; if not, we pick a random port (this is a heuristic) */
710       usm->source_port = (ntohs (udp->spt) < 32000) ? udp->spt : 0;
711       usm->destination_port = udp->dpt;
712       usm->service_descriptor = destination->details.service_destination.service_descriptor;
713       memcpy (&usm[1],
714               &udp[1],
715               payload_length - sizeof (struct udp_packet));
716     }
717     else
718     {
719       struct GNUNET_EXIT_UdpInternetMessage *uim;
720       struct in_addr *ip4dst;
721       struct in6_addr *ip6dst;
722       void *payload;
723
724       mlen = sizeof (struct GNUNET_EXIT_UdpInternetMessage) + 
725         alen + payload_length - sizeof (struct udp_packet);
726       if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
727       {
728         GNUNET_break (0);
729         return;
730       }
731       tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + 
732                            mlen);
733       uim = (struct GNUNET_EXIT_UdpInternetMessage *) &tnq[1];
734       uim->header.size = htons ((uint16_t) mlen);
735       uim->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET); 
736       uim->af = htonl (destination->details.exit_destination.af);
737       uim->source_port = (ntohs (udp->spt) < 32000) ? udp->spt : 0;
738       uim->destination_port = udp->dpt;
739       switch (destination->details.exit_destination.af)
740       {
741       case AF_INET:
742         ip4dst = (struct in_addr *) &uim[1];
743         *ip4dst = destination->details.exit_destination.ip.v4;
744         payload = &ip4dst[1];
745         break;
746       case AF_INET6:
747         ip6dst = (struct in6_addr *) &uim[1];
748         *ip6dst = destination->details.exit_destination.ip.v6;
749         payload = &ip6dst[1];
750         break;
751       default:
752         GNUNET_assert (0);
753       }
754       memcpy (payload,
755               &udp[1],
756               payload_length - sizeof (struct udp_packet));
757     }
758     break;
759   case IPPROTO_TCP:
760     if (is_new)
761     {
762       if (destination->is_service)
763       {
764         struct GNUNET_EXIT_TcpServiceStartMessage *tsm;
765
766         mlen = sizeof (struct GNUNET_EXIT_TcpServiceStartMessage) + 
767           payload_length - sizeof (struct tcp_packet);
768         if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
769         {
770           GNUNET_break (0);
771           return;
772         }
773         tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + mlen);
774         tsm = (struct  GNUNET_EXIT_TcpServiceStartMessage *) &tnq[1];
775         tsm->header.size = htons ((uint16_t) mlen);
776         tsm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START);
777         tsm->reserved = htonl (0);
778         tsm->service_descriptor = destination->details.service_destination.service_descriptor;
779         tsm->tcp_header = *tcp;
780         memcpy (&tsm[1],
781                 &tcp[1],
782                 payload_length - sizeof (struct tcp_packet));
783       }
784       else
785       {
786         struct GNUNET_EXIT_TcpInternetStartMessage *tim;
787         struct in_addr *ip4dst;
788         struct in6_addr *ip6dst;
789         void *payload;
790
791         mlen = sizeof (struct GNUNET_EXIT_TcpInternetStartMessage) + 
792           alen + payload_length - sizeof (struct tcp_packet);
793         if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
794         {
795           GNUNET_break (0);
796           return;
797         }
798         tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + mlen);
799         tim = (struct  GNUNET_EXIT_TcpInternetStartMessage *) &tnq[1];
800         tim->header.size = htons ((uint16_t) mlen);
801         tim->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START);
802         tim->af = htonl (destination->details.exit_destination.af);     
803         tim->tcp_header = *tcp;
804         switch (destination->details.exit_destination.af)
805         {
806         case AF_INET:
807           ip4dst = (struct in_addr *) &tim[1];
808           *ip4dst = destination->details.exit_destination.ip.v4;
809           payload = &ip4dst[1];
810           break;
811         case AF_INET6:
812           ip6dst = (struct in6_addr *) &tim[1];
813           *ip6dst = destination->details.exit_destination.ip.v6;
814           payload = &ip6dst[1];
815           break;
816         default:
817           GNUNET_assert (0);
818         }
819         memcpy (payload,
820                 &tcp[1],
821                 payload_length - sizeof (struct tcp_packet));
822       }
823     }
824     else
825     {
826       struct GNUNET_EXIT_TcpDataMessage *tdm;
827
828       mlen = sizeof (struct GNUNET_EXIT_TcpDataMessage) + 
829         alen + payload_length - sizeof (struct tcp_packet);
830       if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
831       {
832         GNUNET_break (0);
833         return;
834       }
835       tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + mlen);
836       tdm = (struct  GNUNET_EXIT_TcpDataMessage *) &tnq[1];
837       tdm->header.size = htons ((uint16_t) mlen);
838       tdm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_TCP_DATA);
839       tdm->reserved = htonl (0);
840       tdm->tcp_header = *tcp;
841       memcpy (&tdm[1],
842               &tcp[1],
843               payload_length - sizeof (struct tcp_packet));
844      }
845     break;
846   default:
847     /* not supported above, how can we get here !? */
848     GNUNET_assert (0);
849     break;
850   }
851   send_to_tunnel (tnq, ts);
852 }
853
854
855 /**
856  * Receive packets from the helper-process (someone send to the local
857  * virtual tunnel interface).  Find the destination mapping, and if it
858  * exists, identify the correct MESH tunnel (or possibly create it)
859  * and forward the packet.
860  *
861  * @param cls closure, NULL
862  * @param client NULL
863  * @param message message we got from the client (VPN tunnel interface)
864  */
865 static void
866 message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED,
867                const struct GNUNET_MessageHeader *message)
868 {
869   const struct tun_header *tun;
870   size_t mlen;
871   GNUNET_HashCode key;
872   struct DestinationEntry *de;
873
874   mlen = ntohs (message->size);
875   if ( (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) ||
876        (mlen < sizeof (struct GNUNET_MessageHeader) + sizeof (struct tun_header)) )
877   {
878     GNUNET_break (0);
879     return;
880   }
881   tun = (const struct tun_header *) &message[1];
882   mlen -= (sizeof (struct GNUNET_MessageHeader) + sizeof (struct tun_header));
883   switch (ntohs (tun->proto))
884   {
885   case ETH_P_IPV6:
886     {
887       const struct ip6_header *pkt6;
888       
889       if (mlen < sizeof (struct ip6_header))
890       {
891         /* blame kernel */
892         GNUNET_break (0);
893         return;
894       }
895       pkt6 = (const struct ip6_header *) &tun[1];
896       get_destination_key_from_ip (AF_INET6,
897                                    &pkt6->destination_address,
898                                    &key);
899       de = GNUNET_CONTAINER_multihashmap_get (destination_map, &key);
900       /* FIXME: do we need to guard against hash collision? */
901       if (NULL == de)
902       {
903         char buf[INET6_ADDRSTRLEN];
904         
905         GNUNET_log (GNUNET_ERROR_TYPE_INFO,
906                     _("Packet received for unmapped destination `%s' (dropping it)\n"),
907                     inet_ntop (AF_INET6,
908                                &pkt6->destination_address,
909                                buf,
910                                sizeof (buf)));
911         return;
912       }
913       route_packet (de,
914                     AF_INET6,
915                     pkt6->next_header,
916                     &pkt6->source_address,                  
917                     &pkt6->destination_address,             
918                     &pkt6[1],
919                     mlen - sizeof (struct ip6_header));
920     }
921     break;
922   case ETH_P_IPV4:
923     {
924       struct ip4_header *pkt4;
925
926       if (mlen < sizeof (struct ip4_header))
927       {
928         /* blame kernel */
929         GNUNET_break (0);
930         return;
931       }
932       pkt4 = (struct ip4_header *) &tun[1];
933       get_destination_key_from_ip (AF_INET,
934                                    &pkt4->destination_address,
935                                    &key);
936       de = GNUNET_CONTAINER_multihashmap_get (destination_map, &key);
937       /* FIXME: do we need to guard against hash collision? */
938       if (NULL == de)
939       {
940         char buf[INET_ADDRSTRLEN];
941         
942         GNUNET_log (GNUNET_ERROR_TYPE_INFO,
943                     _("Packet received for unmapped destination `%s' (dropping it)\n"),
944                     inet_ntop (AF_INET,
945                                &pkt4->destination_address,
946                                buf,
947                                sizeof (buf)));
948         return;
949       }
950       if (pkt4->header_length * 4 != sizeof (struct ip4_header))
951       {
952         GNUNET_log (GNUNET_ERROR_TYPE_INFO,
953                     _("Received IPv4 packet with options (dropping it)\n"));                
954         return;
955       }
956       route_packet (de,
957                     AF_INET,
958                     pkt4->protocol,
959                     &pkt4->source_address,                  
960                     &pkt4->destination_address,             
961                     &pkt4[1],
962                     mlen - sizeof (struct ip4_header));
963     }
964     break;
965   default:
966     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
967                 _("Received packet of unknown protocol %d from TUN (dropping it)\n"),
968                 (unsigned int) ntohs (tun->proto));
969     break;
970   }
971 }
972
973
974 /**
975  * We got a UDP packet back from the MESH tunnel.  Pass it on to the
976  * local virtual interface via the helper.
977  *
978  * @param cls closure, NULL
979  * @param tunnel connection to the other end
980  * @param tunnel_ctx pointer to our 'struct TunnelState *'
981  * @param sender who sent the message
982  * @param message the actual message
983  * @param atsi performance data for the connection
984  * @return GNUNET_OK to keep the connection open,
985  *         GNUNET_SYSERR to close it (signal serious error)
986  */ 
987 static int
988 receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
989                   void **tunnel_ctx, const struct GNUNET_PeerIdentity *sender,
990                   const struct GNUNET_MessageHeader *message,
991                   const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
992 {
993   struct TunnelState *ts = *tunnel_ctx;
994   const struct GNUNET_EXIT_UdpReplyMessage *reply;
995   size_t mlen;
996
997   mlen = ntohs (message->size);
998   if (mlen < sizeof (struct GNUNET_EXIT_UdpReplyMessage))
999   {
1000     GNUNET_break_op (0);
1001     return GNUNET_SYSERR;
1002   }
1003   if (NULL == ts->heap_node)
1004   {
1005     GNUNET_break_op (0);
1006     return GNUNET_SYSERR;
1007   }
1008   reply = (const struct GNUNET_EXIT_UdpReplyMessage *) message;
1009   mlen -= sizeof (struct GNUNET_EXIT_UdpReplyMessage);
1010   switch (ts->af)
1011   {
1012   case AF_INET:
1013     {
1014       size_t size = sizeof (struct ip4_header) 
1015         + sizeof (struct udp_packet) 
1016         + sizeof (struct GNUNET_MessageHeader) +
1017         sizeof (struct tun_header) +
1018         mlen;
1019       {
1020         char buf[size];
1021         struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
1022         struct tun_header *tun = (struct tun_header*) &msg[1];
1023         struct ip4_header *ipv4 = (struct ip4_header *) &tun[1];
1024         struct udp_packet *udp = (struct udp_packet *) &ipv4[1];
1025         msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1026         msg->size = htons (size);
1027         tun->flags = htons (0);
1028         tun->proto = htons (ETH_P_IPV4);
1029         ipv4->version = 4;
1030         ipv4->header_length = sizeof (struct ip4_header) / 4;
1031         ipv4->diff_serv = 0;
1032         ipv4->total_length = htons (sizeof (struct ip4_header) +
1033                                     sizeof (struct udp_packet) +
1034                                     mlen);
1035         ipv4->identification = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 
1036                                                                     UINT16_MAX + 1);
1037         ipv4->flags = 0;
1038         ipv4->fragmentation_offset = 0;
1039         ipv4->ttl = 255;
1040         ipv4->protocol = IPPROTO_UDP;
1041         ipv4->checksum = 0; 
1042         ipv4->source_address = ts->destination_ip.v4;
1043         ipv4->destination_address = ts->source_ip.v4;
1044         ipv4->checksum =
1045           GNUNET_CRYPTO_crc16_n (ipv4, sizeof (struct ip4_header));
1046         if (0 == ntohs (reply->source_port))
1047           udp->spt = htons (ts->destination_port);
1048         else
1049           udp->spt = reply->source_port;
1050         if (0 == ntohs (reply->destination_port))
1051           udp->dpt = htons (ts->source_port);
1052         else
1053           udp->dpt = reply->destination_port;
1054         udp->len = htons (mlen + sizeof (struct udp_packet));
1055         udp->crc = 0; // FIXME: optional, but we might want to calculate this one anyway
1056         memcpy (&udp[1],
1057                 &reply[1],
1058                 mlen);
1059         (void) GNUNET_HELPER_send (helper_handle,
1060                                    msg,
1061                                    GNUNET_YES,
1062                                    NULL, NULL);
1063       }
1064     }
1065     break;
1066   case AF_INET6:
1067     {
1068       size_t size = sizeof (struct ip6_header) 
1069         + sizeof (struct udp_packet) 
1070         + sizeof (struct GNUNET_MessageHeader) +
1071         sizeof (struct tun_header) +
1072         mlen;
1073       {
1074         char buf[size];
1075         struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
1076         struct tun_header *tun = (struct tun_header*) &msg[1];
1077         struct ip6_header *ipv6 = (struct ip6_header *) &tun[1];
1078         struct udp_packet *udp = (struct udp_packet *) &ipv6[1];
1079         msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1080         msg->size = htons (size);
1081         tun->flags = htons (0);
1082         tun->proto = htons (ETH_P_IPV6);
1083         ipv6->traffic_class_h = 0;
1084         ipv6->version = 6;
1085         ipv6->traffic_class_l = 0;
1086         ipv6->flow_label = 0;
1087         ipv6->payload_length = htons (sizeof (struct udp_packet) + sizeof (struct ip6_header) + mlen);
1088         ipv6->next_header = IPPROTO_UDP;
1089         ipv6->hop_limit = 255;
1090         ipv6->source_address = ts->destination_ip.v6;
1091         ipv6->destination_address = ts->source_ip.v6;
1092         if (0 == ntohs (reply->source_port))
1093           udp->spt = htons (ts->destination_port);
1094         else
1095           udp->spt = reply->source_port;
1096         if (0 == ntohs (reply->destination_port))
1097           udp->dpt = htons (ts->source_port);
1098         else
1099           udp->dpt = reply->destination_port;
1100         udp->len = htons (mlen + sizeof (struct udp_packet));
1101         udp->crc = 0;
1102         memcpy (&udp[1],
1103                 &reply[1],
1104                 mlen);
1105         {
1106           uint32_t sum = 0;
1107           sum =
1108             GNUNET_CRYPTO_crc16_step (sum, &ipv6->source_address, 
1109                                       sizeof (struct in6_addr) * 2);
1110           uint32_t tmp = udp->len;
1111           sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
1112           tmp = htons (IPPROTO_UDP);
1113           sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
1114           sum = GNUNET_CRYPTO_crc16_step (sum, 
1115                                           udp,
1116                                           ntohs (udp->len));
1117           udp->crc = GNUNET_CRYPTO_crc16_finish (sum);
1118         }
1119         (void) GNUNET_HELPER_send (helper_handle,
1120                                    msg,
1121                                    GNUNET_YES,
1122                                    NULL, NULL);
1123       }
1124     }
1125     break;
1126   default:
1127     GNUNET_assert (0);
1128   }
1129 #if 0
1130   // FIXME: refresh entry to avoid expiration...
1131   struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
1132   
1133   GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node,
1134                                      GNUNET_TIME_absolute_get ().abs_value);
1135   
1136 #endif
1137   return GNUNET_OK;
1138 }
1139
1140
1141 /**
1142  * We got a TCP packet back from the MESH tunnel.  Pass it on to the
1143  * local virtual interface via the helper.
1144  *
1145  * @param cls closure, NULL
1146  * @param tunnel connection to the other end
1147  * @param tunnel_ctx pointer to our 'struct TunnelState *'
1148  * @param sender who sent the message
1149  * @param message the actual message
1150  * @param atsi performance data for the connection
1151  * @return GNUNET_OK to keep the connection open,
1152  *         GNUNET_SYSERR to close it (signal serious error)
1153  */ 
1154 static int
1155 receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1156                   void **tunnel_ctx,
1157                   const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
1158                   const struct GNUNET_MessageHeader *message,
1159                   const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
1160 {
1161   struct TunnelState *ts = *tunnel_ctx;
1162   const struct GNUNET_EXIT_TcpDataMessage *data;
1163   size_t mlen;
1164
1165   mlen = ntohs (message->size);
1166   if (mlen < sizeof (struct GNUNET_EXIT_TcpDataMessage))
1167   {
1168     GNUNET_break_op (0);
1169     return GNUNET_SYSERR;
1170   }
1171   if (NULL == ts->heap_node)
1172   {
1173     GNUNET_break_op (0);
1174     return GNUNET_SYSERR;
1175   }
1176   data = (const struct GNUNET_EXIT_TcpDataMessage *) message;
1177   mlen -= sizeof (struct GNUNET_EXIT_TcpDataMessage);
1178   switch (ts->af)
1179   {
1180   case AF_INET:
1181     {
1182       size_t size = sizeof (struct ip4_header) 
1183         + sizeof (struct tcp_packet) 
1184         + sizeof (struct GNUNET_MessageHeader) +
1185         sizeof (struct tun_header) +
1186         mlen;
1187       {
1188         char buf[size];
1189         struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
1190         struct tun_header *tun = (struct tun_header*) &msg[1];
1191         struct ip4_header *ipv4 = (struct ip4_header *) &tun[1];
1192         struct tcp_packet *tcp = (struct tcp_packet *) &ipv4[1];
1193         msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1194         msg->size = htons (size);
1195         tun->flags = htons (0);
1196         tun->proto = htons (ETH_P_IPV4);
1197         ipv4->version = 4;
1198         ipv4->header_length = sizeof (struct ip4_header) / 4;
1199         ipv4->diff_serv = 0;
1200         ipv4->total_length = htons (sizeof (struct ip4_header) +
1201                                     sizeof (struct tcp_packet) +
1202                                     mlen);
1203         ipv4->identification = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 
1204                                                                     UINT16_MAX + 1);
1205         ipv4->flags = 0;
1206         ipv4->fragmentation_offset = 0;
1207         ipv4->ttl = 255;
1208         ipv4->protocol = IPPROTO_TCP;
1209         ipv4->checksum = 0; 
1210         ipv4->source_address = ts->destination_ip.v4;
1211         ipv4->destination_address = ts->source_ip.v4;
1212         ipv4->checksum =
1213           GNUNET_CRYPTO_crc16_n (ipv4, sizeof (struct ip4_header));
1214         *tcp = data->tcp_header;
1215         tcp->spt = htons (ts->destination_port);
1216         tcp->dpt = htons (ts->source_port);
1217         tcp->crc = 0;
1218         memcpy (&tcp[1],
1219                 &data[1],
1220                 mlen);
1221         {
1222           uint32_t sum = 0;
1223           uint32_t tmp;
1224           
1225           sum = GNUNET_CRYPTO_crc16_step (sum, 
1226                                           &ipv4->source_address,
1227                                           2 * sizeof (struct in_addr));   
1228           tmp = htonl ((IPPROTO_TCP << 16) | (mlen + sizeof (struct tcp_packet)));
1229           sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
1230           sum = GNUNET_CRYPTO_crc16_step (sum, tcp, mlen + sizeof (struct tcp_packet));
1231           tcp->crc = GNUNET_CRYPTO_crc16_finish (sum);
1232         }
1233         (void) GNUNET_HELPER_send (helper_handle,
1234                                    msg,
1235                                    GNUNET_YES,
1236                                    NULL, NULL);
1237       }
1238     }
1239     break;
1240   case AF_INET6:
1241     {
1242       size_t size = sizeof (struct ip6_header) 
1243         + sizeof (struct tcp_packet) 
1244         + sizeof (struct GNUNET_MessageHeader) +
1245         sizeof (struct tun_header) +
1246         mlen;
1247       {
1248         char buf[size];
1249         struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
1250         struct tun_header *tun = (struct tun_header*) &msg[1];
1251         struct ip6_header *ipv6 = (struct ip6_header *) &tun[1];
1252         struct tcp_packet *tcp = (struct tcp_packet *) &ipv6[1];
1253         msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1254         msg->size = htons (size);
1255         tun->flags = htons (0);
1256         tun->proto = htons (ETH_P_IPV6);
1257         ipv6->traffic_class_h = 0;
1258         ipv6->version = 6;
1259         ipv6->traffic_class_l = 0;
1260         ipv6->flow_label = 0;
1261         ipv6->payload_length = htons (sizeof (struct tcp_packet) + sizeof (struct ip6_header) + mlen);
1262         ipv6->next_header = IPPROTO_TCP;
1263         ipv6->hop_limit = 255;
1264         ipv6->source_address = ts->destination_ip.v6;
1265         ipv6->destination_address = ts->source_ip.v6;
1266         tcp->spt = htons (ts->destination_port);
1267         tcp->dpt = htons (ts->source_port);
1268         tcp->crc = 0;
1269         {
1270           uint32_t sum = 0;
1271           uint32_t tmp;
1272
1273           sum = GNUNET_CRYPTO_crc16_step (sum, &ipv6->source_address, 2 * sizeof (struct in6_addr));
1274           tmp = htonl (sizeof (struct tcp_packet) + mlen);
1275           sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
1276           tmp = htonl (IPPROTO_TCP);
1277           sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t));
1278           sum = GNUNET_CRYPTO_crc16_step (sum, tcp,
1279                                           sizeof (struct tcp_packet) + mlen);
1280           tcp->crc = GNUNET_CRYPTO_crc16_finish (sum);
1281         }
1282         (void) GNUNET_HELPER_send (helper_handle,
1283                                    msg,
1284                                    GNUNET_YES,
1285                                    NULL, NULL);
1286       }
1287     }
1288     break;
1289   }
1290
1291 #if 0
1292   // FIXME: refresh entry to avoid expiration...
1293   struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key);
1294   
1295   GNUNET_CONTAINER_heap_update_cost (heap, me->heap_node,
1296                                      GNUNET_TIME_absolute_get ().abs_value);
1297   
1298 #endif
1299   return GNUNET_OK;
1300 }
1301
1302
1303 /**
1304  * Allocate an IPv4 address from the range of the tunnel
1305  * for a new redirection.
1306  *
1307  * @param v4 where to store the address
1308  * @return GNUNET_OK on success,
1309  *         GNUNET_SYSERR on error
1310  */
1311 static int
1312 allocate_v4_address (struct in_addr *v4)
1313 {
1314   const char *ipv4addr = vpn_argv[4];
1315   const char *ipv4mask = vpn_argv[5];
1316   struct in_addr addr;
1317   struct in_addr mask;
1318   struct in_addr rnd;
1319   GNUNET_HashCode key;
1320   unsigned int tries;
1321
1322   GNUNET_assert (1 == inet_pton (AF_INET, ipv4addr, &addr));
1323   GNUNET_assert (1 == inet_pton (AF_INET, ipv4mask, &mask));           
1324   /* Given 192.168.0.1/255.255.0.0, we want a mask 
1325      of '192.168.255.255', thus:  */
1326   mask.s_addr = addr.s_addr | ~mask.s_addr;  
1327   tries = 0;
1328   do
1329     {
1330       tries++;
1331       if (tries > 16)
1332       {
1333         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1334                     _("Failed to find unallocated IPv4 address in VPN's range\n"));
1335         return GNUNET_SYSERR;
1336       }
1337       /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
1338       rnd.s_addr = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 
1339                                              UINT32_MAX);       
1340       v4->s_addr = (addr.s_addr | rnd.s_addr) & mask.s_addr;          
1341       get_destination_key_from_ip (AF_INET,
1342                                    v4,
1343                                    &key);
1344     }
1345   while ( (GNUNET_YES ==
1346            GNUNET_CONTAINER_multihashmap_contains (destination_map,
1347                                                    &key)) ||
1348           (v4->s_addr == addr.s_addr) ||
1349           (v4->s_addr == mask.s_addr) );
1350   return GNUNET_OK;
1351 }
1352
1353
1354 /**
1355  * Allocate an IPv6 address from the range of the tunnel
1356  * for a new redirection.
1357  *
1358  * @param v6 where to store the address
1359  * @return GNUNET_OK on success,
1360  *         GNUNET_SYSERR on error
1361  */
1362 static int
1363 allocate_v6_address (struct in6_addr *v6)
1364 {
1365   const char *ipv6addr = vpn_argv[2];
1366   struct in6_addr addr;
1367   struct in6_addr mask;
1368   struct in6_addr rnd;
1369   int i;
1370   GNUNET_HashCode key;
1371   unsigned int tries;
1372
1373   GNUNET_assert (1 == inet_pton (AF_INET6, ipv6addr, &addr));
1374   GNUNET_assert (ipv6prefix < 128);
1375   /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
1376      thus: */
1377   mask = addr;
1378   for (i=127;i>=128-ipv6prefix;i--)
1379     mask.s6_addr[i / 8] |= (1 << (i % 8));
1380   
1381   /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */
1382   tries = 0;
1383   do
1384     {
1385       tries++;
1386       if (tries > 16)
1387         {
1388           GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1389                       _("Failed to find unallocated IPv6 address in VPN's range\n"));
1390           return GNUNET_SYSERR;
1391
1392         }
1393       for (i=0;i<16;i++)
1394         {
1395           rnd.s6_addr[i] = (unsigned char) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 
1396                                                                      256);
1397           v6->s6_addr[i]
1398             = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
1399         }
1400       get_destination_key_from_ip (AF_INET6,
1401                                    v6,
1402                                    &key);
1403     }
1404   while ( (GNUNET_YES ==
1405            GNUNET_CONTAINER_multihashmap_contains (destination_map,
1406                                                    &key)) ||
1407           (0 == memcmp (v6,
1408                         &addr,
1409                         sizeof (struct in6_addr))) ||
1410           (0 == memcmp (v6,
1411                         &mask,
1412                         sizeof (struct in6_addr))) );
1413   return GNUNET_OK;
1414 }
1415
1416
1417 /**
1418  * A client asks us to setup a redirection via some exit
1419  * node to a particular IP.  Setup the redirection and
1420  * give the client the allocated IP.
1421  *
1422  * @param cls unused
1423  * @param client requesting client
1424  * @param message redirection request (a 'struct RedirectToIpRequestMessage')
1425  */
1426 static void
1427 service_redirect_to_ip (void *cls GNUNET_UNUSED, struct GNUNET_SERVER_Client *client,
1428                         const struct GNUNET_MessageHeader *message)
1429 {
1430   size_t mlen;
1431   size_t alen;
1432   const struct RedirectToIpRequestMessage *msg;
1433   int addr_af;
1434   int result_af;
1435   struct in_addr v4;
1436   struct in6_addr v6;
1437   void *addr;
1438   struct DestinationEntry *de;
1439   GNUNET_HashCode key;
1440   struct TunnelState *ts;
1441   GNUNET_MESH_ApplicationType app_type;
1442   
1443   /* validate and parse request */
1444   mlen = ntohs (message->size);
1445   if (mlen < sizeof (struct RedirectToIpRequestMessage))
1446   {
1447     GNUNET_break (0);
1448     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1449     return;
1450   }
1451   alen = mlen - sizeof (struct RedirectToIpRequestMessage);
1452   msg = (const struct RedirectToIpRequestMessage *) message;
1453   addr_af = (int) htonl (msg->addr_af);
1454   switch (addr_af)
1455   {
1456   case AF_INET:
1457     if (alen != sizeof (struct in_addr))
1458     {
1459       GNUNET_break (0);
1460       GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1461       return;      
1462     }
1463     app_type = GNUNET_APPLICATION_TYPE_IPV4_GATEWAY; 
1464     break;
1465   case AF_INET6:
1466     if (alen != sizeof (struct in6_addr))
1467     {
1468       GNUNET_break (0);
1469       GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1470       return;      
1471     }
1472     app_type = GNUNET_APPLICATION_TYPE_IPV6_GATEWAY; 
1473     break;
1474   default:
1475     GNUNET_break (0);
1476     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1477     return;      
1478   }
1479
1480   /* allocate response IP */
1481   addr = NULL;
1482   result_af = (int) htonl (msg->result_af);
1483   switch (result_af)
1484   {
1485   case AF_INET:
1486     if (GNUNET_OK !=
1487         allocate_v4_address (&v4))
1488       result_af = AF_UNSPEC;
1489     else
1490       addr = &v4;
1491     break;
1492   case AF_INET6:
1493     if (GNUNET_OK !=
1494         allocate_v6_address (&v6))
1495       result_af = AF_UNSPEC;
1496     else
1497       addr = &v6;
1498     break;
1499   case AF_UNSPEC:
1500     if (GNUNET_OK ==
1501         allocate_v4_address (&v4))
1502     {
1503       addr = &v4;
1504       result_af = AF_INET;
1505     }
1506     else if (GNUNET_OK ==
1507         allocate_v6_address (&v6))
1508     {
1509       addr = &v6;
1510       result_af = AF_INET6;
1511     }
1512     break;
1513   default:
1514     GNUNET_break (0);
1515     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1516     return;      
1517   }
1518   if ( (result_af == AF_UNSPEC) ||
1519        (GNUNET_NO == ntohl (msg->nac)) )
1520   {
1521     /* send reply "instantly" */
1522     send_client_reply (client,
1523                        msg->request_id,
1524                        result_af,
1525                        addr);
1526   }
1527   if (result_af == AF_UNSPEC)
1528   {
1529     /* failure, we're done */
1530     GNUNET_SERVER_receive_done (client, GNUNET_OK);
1531     return;
1532   }
1533   
1534   /* setup destination record */
1535   de = GNUNET_malloc (sizeof (struct DestinationEntry));
1536   de->is_service = GNUNET_NO;
1537   de->details.exit_destination.af = addr_af;
1538   memcpy (&de->details.exit_destination.ip,
1539           &msg[1],
1540           alen);
1541   get_destination_key_from_ip (result_af,
1542                                addr,
1543                                &key);
1544   GNUNET_assert (GNUNET_OK ==
1545                  GNUNET_CONTAINER_multihashmap_put (destination_map,
1546                                                     &key,
1547                                                     de,
1548                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
1549   de->heap_node = GNUNET_CONTAINER_heap_insert (destination_heap,
1550                                                 de,
1551                                                 GNUNET_TIME_absolute_ntoh (msg->expiration_time).abs_value);
1552   /* setup tunnel to destination */
1553   ts = GNUNET_malloc (sizeof (struct TunnelState));
1554   if (GNUNET_NO != ntohl (msg->nac))
1555   {
1556     ts->request_id = msg->request_id;
1557     ts->client = client;
1558     GNUNET_SERVER_client_keep (client);
1559   }
1560   ts->destination = *de;
1561   ts->destination.heap_node = NULL;
1562   ts->is_service = GNUNET_NO;
1563   ts->af = result_af;
1564   if (result_af == AF_INET) 
1565     ts->destination_ip.v4 = v4;
1566   else
1567     ts->destination_ip.v6 = v6;
1568   de->tunnel = GNUNET_MESH_tunnel_create (mesh_handle,
1569                                           ts,
1570                                           &tunnel_peer_connect_handler,
1571                                           &tunnel_peer_disconnect_handler,
1572                                           ts);
1573   GNUNET_MESH_peer_request_connect_by_type (de->tunnel,
1574                                             app_type);  
1575   /* we're done */
1576   GNUNET_SERVER_receive_done (client, GNUNET_OK);
1577 }
1578
1579
1580 /**
1581  * A client asks us to setup a redirection to a particular peer
1582  * offering a service.  Setup the redirection and give the client the
1583  * allocated IP.
1584  *
1585  * @param cls unused
1586  * @param client requesting client
1587  * @param message redirection request (a 'struct RedirectToPeerRequestMessage')
1588  */
1589 static void
1590 service_redirect_to_service (void *cls GNUNET_UNUSED, struct GNUNET_SERVER_Client *client,
1591                              const struct GNUNET_MessageHeader *message)
1592 {
1593   const struct RedirectToServiceRequestMessage *msg;
1594   int result_af;
1595   struct in_addr v4;
1596   struct in6_addr v6;
1597   void *addr;
1598   struct DestinationEntry *de;
1599   GNUNET_HashCode key;
1600   struct TunnelState *ts;
1601   
1602   /*  parse request */
1603   msg = (const struct RedirectToServiceRequestMessage *) message;
1604
1605   /* allocate response IP */
1606   addr = NULL;
1607   result_af = (int) htonl (msg->result_af);
1608   switch (result_af)
1609   {
1610   case AF_INET:
1611     if (GNUNET_OK !=
1612         allocate_v4_address (&v4))
1613       result_af = AF_UNSPEC;
1614     else
1615       addr = &v4;
1616     break;
1617   case AF_INET6:
1618     if (GNUNET_OK !=
1619         allocate_v6_address (&v6))
1620       result_af = AF_UNSPEC;
1621     else
1622       addr = &v6;
1623     break;
1624   case AF_UNSPEC:
1625     if (GNUNET_OK ==
1626         allocate_v4_address (&v4))
1627     {
1628       addr = &v4;
1629       result_af = AF_INET;
1630     }
1631     else if (GNUNET_OK ==
1632         allocate_v6_address (&v6))
1633     {
1634       addr = &v6;
1635       result_af = AF_INET6;
1636     }
1637     break;
1638   default:
1639     GNUNET_break (0);
1640     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1641     return;      
1642   }
1643   if ( (result_af == AF_UNSPEC) ||
1644        (GNUNET_NO == ntohl (msg->nac)) )
1645   {
1646     /* send reply "instantly" */
1647     send_client_reply (client,
1648                        msg->request_id,
1649                        result_af,
1650                        addr);
1651   }
1652   if (result_af == AF_UNSPEC)
1653   {
1654     /* failure, we're done */
1655     GNUNET_SERVER_receive_done (client, GNUNET_OK);
1656     return;
1657   }
1658   
1659   /* setup destination record */
1660   de = GNUNET_malloc (sizeof (struct DestinationEntry));
1661   de->is_service = GNUNET_YES;
1662   de->details.service_destination.service_descriptor = msg->service_descriptor;
1663   de->details.service_destination.target = msg->target;
1664   get_destination_key_from_ip (result_af,
1665                                addr,
1666                                &key);
1667   GNUNET_assert (GNUNET_OK ==
1668                  GNUNET_CONTAINER_multihashmap_put (destination_map,
1669                                                     &key,
1670                                                     de,
1671                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
1672   de->heap_node = GNUNET_CONTAINER_heap_insert (destination_heap,
1673                                                 de,
1674                                                 GNUNET_TIME_absolute_ntoh (msg->expiration_time).abs_value);
1675
1676   /* setup tunnel to destination */
1677   ts = GNUNET_malloc (sizeof (struct TunnelState));
1678   if (GNUNET_NO != ntohl (msg->nac))
1679   {
1680     ts->request_id = msg->request_id;
1681     ts->client = client;
1682     GNUNET_SERVER_client_keep (client);
1683   }
1684   ts->destination = *de;
1685   ts->destination.heap_node = NULL;
1686   ts->is_service = GNUNET_YES;
1687   ts->af = result_af;
1688   if (result_af == AF_INET) 
1689     ts->destination_ip.v4 = v4;
1690   else
1691     ts->destination_ip.v6 = v6;
1692   de->tunnel = GNUNET_MESH_tunnel_create (mesh_handle,
1693                                           ts,
1694                                           &tunnel_peer_connect_handler,
1695                                           &tunnel_peer_disconnect_handler,
1696                                           ts);
1697   GNUNET_MESH_peer_request_connect_add (de->tunnel,
1698                                         &msg->target);  
1699   /* we're done */
1700   GNUNET_SERVER_receive_done (client, GNUNET_OK);
1701 }
1702
1703
1704
1705 /**
1706  * Function called for inbound tunnels.  As we don't offer
1707  * any mesh services, this function should never be called.
1708  *
1709  * @param cls closure
1710  * @param tunnel new handle to the tunnel
1711  * @param initiator peer that started the tunnel
1712  * @param atsi performance information for the tunnel
1713  * @return initial tunnel context for the tunnel
1714  *         (can be NULL -- that's not an error)
1715  */ 
1716 static void *
1717 inbound_tunnel_cb (void *cls, struct GNUNET_MESH_Tunnel *tunnel,
1718                    const struct GNUNET_PeerIdentity *initiator,
1719                    const struct GNUNET_ATS_Information *atsi)
1720 {
1721   /* Why should anyone open an inbound tunnel to vpn? */
1722   GNUNET_break (0);
1723   return NULL;
1724 }
1725
1726
1727 /**
1728  * Function called whenever an inbound tunnel is destroyed.  Should clean up
1729  * any associated state.
1730  *
1731  * @param cls closure (set from GNUNET_MESH_connect)
1732  * @param tunnel connection to the other end (henceforth invalid)
1733  * @param tunnel_ctx place where local state associated
1734  *                   with the tunnel is stored
1735  */ 
1736 static void
1737 tunnel_cleaner (void *cls, const struct GNUNET_MESH_Tunnel *tunnel, void *tunnel_ctx)
1738 {
1739   /* FIXME: is this function called for outbound tunnels that go down?
1740      Should we clean up something here? */
1741   GNUNET_break (0);
1742 }
1743
1744
1745 /**
1746  * Function scheduled as very last function, cleans up after us
1747  */
1748 static void
1749 cleanup (void *cls GNUNET_UNUSED,
1750          const struct GNUNET_SCHEDULER_TaskContext *tskctx)
1751 {
1752   unsigned int i;
1753
1754   // FIXME: clean up heaps and maps!
1755   if (NULL != mesh_handle)
1756   {
1757     GNUNET_MESH_disconnect (mesh_handle);
1758     mesh_handle = NULL;
1759   }
1760   if (NULL != helper_handle)
1761     {
1762     GNUNET_HELPER_stop (helper_handle);
1763     helper_handle = NULL;
1764   }
1765   if (NULL != nc)
1766   {
1767     GNUNET_SERVER_notification_context_destroy (nc);
1768     nc = NULL;
1769   }
1770   for (i=0;i<5;i++)
1771     GNUNET_free_non_null (vpn_argv[i]);
1772 }
1773
1774
1775 /**
1776  * A client has disconnected from us.  If we are currently building
1777  * a tunnel for it, cancel the operation.
1778  *
1779  * @param cls unused
1780  * @param client handle to the client that disconnected
1781  */
1782 static void
1783 client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
1784 {
1785   // FIXME: find all TunnelState's and check if they point
1786   // to the client and if so, clean the reference up!
1787 }
1788
1789
1790 /**
1791  * Main function that will be run by the scheduler.
1792  *
1793  * @param cls closure
1794  * @param server the initialized server
1795  * @param cfg_ configuration
1796  */
1797 static void
1798 run (void *cls,
1799      struct GNUNET_SERVER_Handle *server,
1800      const struct GNUNET_CONFIGURATION_Handle *cfg_)
1801 {
1802   static const struct GNUNET_SERVER_MessageHandler service_handlers[] = {
1803     /* callback, cls, type, size */
1804     {&service_redirect_to_ip, NULL, GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP, 0},
1805     {&service_redirect_to_service, NULL, 
1806      GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_SERVICE, 
1807      sizeof (struct RedirectToServiceRequestMessage) },
1808     {NULL, NULL, 0, 0}
1809   };
1810   static const struct GNUNET_MESH_MessageHandler mesh_handlers[] = {
1811     {receive_udp_back, GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK, 0},
1812     {receive_tcp_back, GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP_BACK, 0},
1813     {receive_udp_back, GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP_BACK, 0},
1814     {receive_tcp_back, GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP_BACK, 0},
1815     {NULL, 0, 0}
1816   };
1817   static const GNUNET_MESH_ApplicationType types[] = {
1818     GNUNET_APPLICATION_TYPE_END
1819   };
1820   char *ifname;
1821   char *ipv6addr;
1822   char *ipv6prefix_s;
1823   char *ipv4addr;
1824   char *ipv4mask;
1825   struct in_addr v4;
1826   struct in6_addr v6;
1827
1828   cfg = cfg_;
1829   if (GNUNET_OK !=
1830       GNUNET_CONFIGURATION_get_value_number (cfg, "vpn", "MAX_MAPPING",
1831                                              &max_destination_mappings))
1832     max_destination_mappings = 200;
1833   if (GNUNET_OK !=
1834       GNUNET_CONFIGURATION_get_value_number (cfg, "vpn", "MAX_TUNNELS",
1835                                              &max_tunnel_mappings))
1836     max_tunnel_mappings = 200;
1837
1838   destination_map = GNUNET_CONTAINER_multihashmap_create (max_destination_mappings * 2);
1839   destination_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
1840   tunnel_map = GNUNET_CONTAINER_multihashmap_create (max_tunnel_mappings * 2);
1841   tunnel_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
1842
1843
1844   vpn_argv[0] = GNUNET_strdup ("vpn-gnunet");
1845   if (GNUNET_SYSERR ==
1846       GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IFNAME", &ifname))
1847   {
1848     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1849                 "No entry 'IFNAME' in configuration!\n");
1850     GNUNET_SCHEDULER_shutdown ();
1851     return;
1852   }
1853   vpn_argv[1] = ifname;
1854   if ( (GNUNET_SYSERR ==
1855         GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR",
1856                                                &ipv6addr) ||
1857         (1 != inet_pton (AF_INET6, ipv6addr, &v6))) )
1858   {
1859     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1860                 "No valid entry 'IPV6ADDR' in configuration!\n");
1861     GNUNET_SCHEDULER_shutdown ();
1862     return;
1863   }
1864   vpn_argv[2] = ipv6addr;
1865   if (GNUNET_SYSERR ==
1866       GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6PREFIX",
1867                                              &ipv6prefix_s))
1868   {
1869     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1870                 "No entry 'IPV6PREFIX' in configuration!\n");
1871     GNUNET_SCHEDULER_shutdown ();
1872     return;
1873   }
1874   vpn_argv[3] = ipv6prefix_s;
1875   if ( (GNUNET_OK !=
1876         GNUNET_CONFIGURATION_get_value_number (cfg, "vpn",
1877                                                "IPV6PREFIX",
1878                                                &ipv6prefix)) ||
1879        (ipv6prefix >= 127) )
1880   {
1881     GNUNET_SCHEDULER_shutdown ();
1882     return;
1883   }
1884
1885   if ( (GNUNET_SYSERR ==
1886         GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4ADDR",
1887                                                &ipv4addr) ||
1888         (1 != inet_pton (AF_INET, ipv4addr, &v4))) )
1889   {
1890     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1891                 "No valid entry for 'IPV4ADDR' in configuration!\n");
1892     GNUNET_SCHEDULER_shutdown ();
1893     return;
1894   }
1895   vpn_argv[4] = ipv4addr;
1896   if ( (GNUNET_SYSERR ==
1897         GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4MASK",
1898                                                &ipv4mask) ||
1899         (1 != inet_pton (AF_INET, ipv4mask, &v4))) )
1900   {
1901     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1902                 "No valid entry 'IPV4MASK' in configuration!\n");
1903     GNUNET_SCHEDULER_shutdown ();
1904     return;
1905   }
1906   vpn_argv[5] = ipv4mask;
1907   vpn_argv[6] = NULL;
1908
1909   mesh_handle =
1910     GNUNET_MESH_connect (cfg_, 42 /* queue length */, NULL, 
1911                          &inbound_tunnel_cb, 
1912                          &tunnel_cleaner, 
1913                          mesh_handlers,
1914                          types);
1915   helper_handle = GNUNET_HELPER_start ("gnunet-helper-vpn", vpn_argv,
1916                                        &message_token, NULL);
1917   nc = GNUNET_SERVER_notification_context_create (server, 1);
1918   GNUNET_SERVER_add_handlers (server, service_handlers);
1919   GNUNET_SERVER_disconnect_notify (server, &client_disconnect, NULL);
1920   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls);
1921 }
1922
1923
1924 /**
1925  * The main function of the VPN service.
1926  *
1927  * @param argc number of arguments from the command line
1928  * @param argv command line arguments
1929  * @return 0 ok, 1 on error
1930  */
1931 int
1932 main (int argc, char *const *argv)
1933 {
1934   return (GNUNET_OK ==
1935           GNUNET_SERVICE_run (argc, argv, "vpn", 
1936                               GNUNET_SERVICE_OPTION_NONE,
1937                               &run, NULL)) ? 0 : 1;
1938 }
1939
1940 /* end of gnunet-service-vpn.c */