include postgres db url in error message
[oweals/gnunet.git] / src / nat / gnunet-service-nat.c
1 /*
2   This file is part of GNUnet.
3   Copyright (C) 2016 GNUnet e.V.
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., 51 Franklin Street, Fifth Floor,
18   Boston, MA 02110-1301, USA.
19  */
20
21 /**
22  * @file nat/gnunet-service-nat.c
23  * @brief network address translation traversal service
24  * @author Christian Grothoff
25  *
26  * The purpose of this service is to enable transports to 
27  * traverse NAT routers, by providing traversal options and
28  * knowledge about the local network topology.
29  */
30 #include "platform.h"
31 #include <math.h>
32 #include "gnunet_util_lib.h"
33 #include "gnunet_protocols.h"
34 #include "gnunet_signatures.h"
35 #include "gnunet_statistics_service.h"
36 #include "gnunet_nat_service.h"
37 #include "nat.h"
38 #include <gcrypt.h>
39
40
41 /**
42  * How often should we ask the OS about a list of active
43  * network interfaces?
44  */
45 #define SCAN_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15)
46
47
48 /**
49  * Internal data structure we track for each of our clients.
50  */
51 struct ClientHandle
52 {
53
54   /**
55    * Kept in a DLL.
56    */
57   struct ClientHandle *next;
58   
59   /**
60    * Kept in a DLL.
61    */
62   struct ClientHandle *prev;
63
64   /**
65    * Underlying handle for this client with the service.
66    */ 
67   struct GNUNET_SERVICE_Client *client;
68
69   /**
70    * Message queue for communicating with the client.
71    */
72   struct GNUNET_MQ_Handle *mq;
73
74   /**
75    * Array of addresses used by the service.
76    */
77   struct sockaddr **addrs;
78   
79   /**
80    * What does this client care about?
81    */
82   enum GNUNET_NAT_RegisterFlags flags;
83
84   /**
85    * Port we would like as we are configured to use this one for
86    * advertising (in addition to the one we are binding to).
87    */
88   uint16_t adv_port;
89
90   /**
91    * Number of addresses that this service is bound to.
92    */
93   uint16_t num_addrs;
94   
95   /**
96    * Client's IPPROTO, e.g. IPPROTO_UDP or IPPROTO_TCP.
97    */
98   uint8_t proto;
99
100 };
101
102
103 /**
104  * List of local addresses this system has.
105  */
106 struct LocalAddressList
107 {
108   /**
109    * This is a linked list.
110    */
111   struct LocalAddressList *next;
112
113   /**
114    * Previous entry.
115    */
116   struct LocalAddressList *prev;
117
118   /**
119    * The address itself (i.e. `struct in_addr` or `struct in6_addr`,
120    * in the respective byte order).  Allocated at the end of this
121    * struct.
122    */
123   const void *addr;
124
125   /**
126    * Address family.
127    */
128   int af;
129
130 };
131
132
133
134
135 /**
136  * Handle to our current configuration.
137  */
138 static const struct GNUNET_CONFIGURATION_Handle *cfg;
139
140 /**
141  * Handle to the statistics service.
142  */
143 static struct GNUNET_STATISTICS_Handle *stats;
144
145 /**
146  * Task scheduled to periodically scan our network interfaces.
147  */
148 static struct GNUNET_SCHEDULER_Task *scan_task;
149
150 /**
151  * Head of client DLL.
152  */
153 static struct ClientHandle *ch_head;
154   
155 /**
156  * Tail of client DLL.
157  */
158 static struct ClientHandle *ch_tail;
159
160 /**
161  * Head of DLL of local addresses.
162  */
163 static struct LocalAddressList *lal_head;
164
165 /**
166  * Tail of DLL of local addresses.
167  */
168 static struct LocalAddressList *lal_tail;
169
170
171 /**
172  * Free the DLL starting at #lal_head.
173  */ 
174 static void
175 destroy_lal ()
176 {
177   struct LocalAddressList *lal;
178
179   while (NULL != (lal = lal_head))
180   {
181     GNUNET_CONTAINER_DLL_remove (lal_head,
182                                  lal_tail,
183                                  lal);
184     GNUNET_free (lal);
185   }
186 }
187
188
189 /**
190  * Check validity of #GNUNET_MESSAGE_TYPE_NAT_REGISTER message from
191  * client.
192  *
193  * @param cls client who sent the message
194  * @param message the message received
195  * @return #GNUNET_OK if message is well-formed
196  */
197 static int
198 check_register (void *cls,
199                 const struct GNUNET_NAT_RegisterMessage *message)
200 {
201   uint16_t num_addrs = ntohs (message->num_addrs);
202   const char *off = (const char *) &message[1];
203   size_t left = ntohs (message->header.size) - sizeof (*message);
204
205   for (unsigned int i=0;i<num_addrs;i++)
206   {
207     size_t alen;
208     const struct sockaddr *sa = (const struct sockaddr *) off;
209
210     if (sizeof (sa_family_t) > left)
211     {
212       GNUNET_break (0);
213       return GNUNET_SYSERR;
214     }
215     switch (sa->sa_family)
216     {
217     case AF_INET:
218       alen = sizeof (struct sockaddr_in);
219       break;
220     case AF_INET6:
221       alen = sizeof (struct sockaddr_in6);
222       break;
223 #if AF_UNIX
224     case AF_UNIX:
225       alen = sizeof (struct sockaddr_un);
226       break;
227 #endif
228     default:
229       GNUNET_break (0);
230       return GNUNET_SYSERR;      
231     }
232     if (alen > left)
233     {
234       GNUNET_break (0);
235       return GNUNET_SYSERR;      
236     }
237   }  
238   return GNUNET_OK; 
239 }
240
241
242 /**
243  * Handler for #GNUNET_MESSAGE_TYPE_NAT_REGISTER message from client.
244  * We remember the client for updates upon future NAT events.
245  *
246  * @param cls client who sent the message
247  * @param message the message received
248  */
249 static void
250 handle_register (void *cls,
251                  const struct GNUNET_NAT_RegisterMessage *message)
252 {
253   struct ClientHandle *ch = cls;
254   const char *off;
255   size_t left;
256
257   if ( (0 != ch->proto) ||
258        (NULL != ch->addrs) )
259   {
260     /* double registration not allowed */
261     GNUNET_break (0);
262     GNUNET_SERVICE_client_drop (ch->client);
263     return;
264   }
265   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
266               "Received REGISTER message from client\n");
267   ch->flags = message->flags;
268   ch->proto = message->proto;
269   ch->adv_port = ntohs (message->adv_port);
270   ch->num_addrs = ntohs (message->adv_port);
271   ch->addrs = GNUNET_new_array (ch->num_addrs,
272                                 struct sockaddr *);
273   left = ntohs (message->header.size) - sizeof (*message);
274   off = (const char *) &message[1];
275   for (unsigned int i=0;i<ch->num_addrs;i++)
276   {
277     size_t alen;
278     const struct sockaddr *sa = (const struct sockaddr *) off;
279
280     if (sizeof (sa_family_t) > left)
281     {
282       GNUNET_break (0);
283       GNUNET_SERVICE_client_drop (ch->client);
284       return;
285     }
286     switch (sa->sa_family)
287     {
288     case AF_INET:
289       alen = sizeof (struct sockaddr_in);
290       break;
291     case AF_INET6:
292       alen = sizeof (struct sockaddr_in6);
293       break;
294 #if AF_UNIX
295     case AF_UNIX:
296       alen = sizeof (struct sockaddr_un);
297       break;
298 #endif
299     default:
300       GNUNET_break (0);
301       GNUNET_SERVICE_client_drop (ch->client);
302       return;      
303     }
304     GNUNET_assert (alen <= left);
305     ch->addrs[i] = GNUNET_malloc (alen);
306     GNUNET_memcpy (ch->addrs[i],
307                    sa,
308                    alen);    
309     off += alen;
310   }  
311   GNUNET_SERVICE_client_continue (ch->client);
312 }
313
314
315 /**
316  * Check validity of #GNUNET_MESSAGE_TYPE_NAT_HANDLE_STUN message from
317  * client.
318  *
319  * @param cls client who sent the message
320  * @param message the message received
321  * @return #GNUNET_OK if message is well-formed
322  */
323 static int
324 check_stun (void *cls,
325             const struct GNUNET_NAT_HandleStunMessage *message)
326 {
327   size_t sa_len = ntohs (message->sender_addr_size);
328   size_t expect = sa_len + ntohs (message->payload_size);
329   
330   if (ntohs (message->header.size) - sizeof (*message) != expect)
331   {
332     GNUNET_break (0);
333     return GNUNET_SYSERR;
334   }
335   if (sa_len < sizeof (sa_family_t))
336   {
337     GNUNET_break (0);
338     return GNUNET_SYSERR;
339   }
340   return GNUNET_OK;
341 }
342
343
344 /**
345  * Handler for #GNUNET_MESSAGE_TYPE_NAT_HANDLE_STUN message from
346  * client.
347  *
348  * @param cls client who sent the message
349  * @param message the message received
350  */
351 static void
352 handle_stun (void *cls,
353              const struct GNUNET_NAT_HandleStunMessage *message)
354 {
355   struct ClientHandle *ch = cls;
356   const char *buf = (const char *) &message[1];
357   const struct sockaddr *sa;
358   const void *payload;
359   size_t sa_len;
360   size_t payload_size;
361
362   sa_len = ntohs (message->sender_addr_size);
363   payload_size = ntohs (message->payload_size);
364   sa = (const struct sockaddr *) &buf[0];
365   payload = (const struct sockaddr *) &buf[sa_len];
366   switch (sa->sa_family)
367   {
368   case AF_INET:
369     if (sa_len != sizeof (struct sockaddr_in))
370     {
371       GNUNET_break (0);
372       GNUNET_SERVICE_client_drop (ch->client);
373       return;
374     }
375     break;
376   case AF_INET6:
377     if (sa_len != sizeof (struct sockaddr_in6))
378     {
379       GNUNET_break (0);
380       GNUNET_SERVICE_client_drop (ch->client);
381       return;
382     }
383     break;
384   }
385   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
386               "Received HANDLE_STUN message from client\n");
387   // FIXME: actually handle STUN request!
388   GNUNET_SERVICE_client_continue (ch->client);
389 }
390
391
392 /**
393  * Check validity of
394  * #GNUNET_MESSAGE_TYPE_NAT_REQUEST_CONNECTION_REVERSAL message from
395  * client.
396  *
397  * @param cls client who sent the message
398  * @param message the message received
399  * @return #GNUNET_OK if message is well-formed
400  */
401 static int
402 check_request_connection_reversal (void *cls,
403                                    const struct GNUNET_NAT_RequestConnectionReversalMessage *message)
404 {
405   size_t expect;
406
407   expect = ntohs (message->local_addr_size)
408     + ntohs (message->remote_addr_size);
409   if (ntohs (message->header.size) - sizeof (*message) != expect)
410   {
411     GNUNET_break (0);
412     return GNUNET_SYSERR;
413   }
414   return GNUNET_OK;
415 }
416
417
418 /**
419  * Handler for #GNUNET_MESSAGE_TYPE_NAT_REQUEST_CONNECTION_REVERSAL
420  * message from client.
421  *
422  * @param cls client who sent the message
423  * @param message the message received
424  */
425 static void
426 handle_request_connection_reversal (void *cls,
427                                     const struct GNUNET_NAT_RequestConnectionReversalMessage *message)
428 {
429   struct ClientHandle *ch = cls;
430   const char *buf = (const char *) &message[1];
431   size_t local_sa_len = ntohs (message->local_addr_size);
432   size_t remote_sa_len = ntohs (message->remote_addr_size);
433   const struct sockaddr *local_sa = (const struct sockaddr *) &buf[0];
434   const struct sockaddr *remote_sa = (const struct sockaddr *) &buf[local_sa_len];
435   
436   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
437               "Received REQUEST CONNECTION REVERSAL message from client\n");
438   switch (local_sa->sa_family)
439   {
440   case AF_INET:
441     if (local_sa_len != sizeof (struct sockaddr_in))
442     {
443       GNUNET_break (0);
444       GNUNET_SERVICE_client_drop (ch->client);
445       return;
446     }
447     break;
448   case AF_INET6:
449     if (local_sa_len != sizeof (struct sockaddr_in6))
450     {
451       GNUNET_break (0);
452       GNUNET_SERVICE_client_drop (ch->client);
453       return;
454     }
455     break;
456   default:
457     GNUNET_break (0);
458     GNUNET_SERVICE_client_drop (ch->client);
459     return;
460   }
461   switch (remote_sa->sa_family)
462   {
463   case AF_INET:
464     if (remote_sa_len != sizeof (struct sockaddr_in))
465     {
466       GNUNET_break (0);
467       GNUNET_SERVICE_client_drop (ch->client);
468       return;
469     }
470     break;
471   case AF_INET6:
472     if (remote_sa_len != sizeof (struct sockaddr_in6))
473     {
474       GNUNET_break (0);
475       GNUNET_SERVICE_client_drop (ch->client);
476       return;
477     }
478     break;
479   default:
480     GNUNET_break (0);
481     GNUNET_SERVICE_client_drop (ch->client);
482     return;
483   }
484   /* FIXME: actually run the logic! */
485   
486   GNUNET_SERVICE_client_continue (ch->client);
487 }
488
489
490 /**
491  * Handler for #GNUNET_MESSAGE_TYPE_NAT_REQUEST_TEST message from
492  * client.
493  *
494  * @param cls client who sent the message
495  * @param message the message received
496  */
497 static void
498 handle_test (void *cls,
499              const struct GNUNET_NAT_RequestTestMessage *message)
500 {
501   struct ClientHandle *ch = cls;
502
503   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
504               "Received REQUEST_TEST message from client\n");
505   GNUNET_SERVICE_client_continue (ch->client);
506 }
507
508
509 /**
510  * Check validity of #GNUNET_MESSAGE_TYPE_NAT_REQUEST_AUTO_CFG message
511  * from client.
512  *
513  * @param cls client who sent the message
514  * @param message the message received
515  * @return #GNUNET_OK if message is well-formed
516  */
517 static int
518 check_autoconfig_request (void *cls,
519                           const struct GNUNET_NAT_AutoconfigRequestMessage *message)
520 {
521   return GNUNET_OK;  /* checked later */
522 }
523
524
525 /**
526  * Handler for #GNUNET_MESSAGE_TYPE_NAT_REQUEST_AUTO_CFG message from
527  * client.
528  *
529  * @param cls client who sent the message
530  * @param message the message received
531  */
532 static void
533 handle_autoconfig_request (void *cls,
534                            const struct GNUNET_NAT_AutoconfigRequestMessage *message)
535 {
536   struct ClientHandle *ch = cls;
537   size_t left = ntohs (message->header.size);
538   struct GNUNET_CONFIGURATION_Handle *c;
539
540   c = GNUNET_CONFIGURATION_create ();
541   if (GNUNET_OK !=
542       GNUNET_CONFIGURATION_deserialize (c,
543                                         (const char *) &message[1],
544                                         left,
545                                         GNUNET_NO))
546   {
547     GNUNET_break (0);
548     GNUNET_SERVICE_client_drop (ch->client);
549     return;
550   }
551   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
552               "Received REQUEST_AUTO_CONFIG message from client\n");
553   // FIXME: actually handle request...
554   GNUNET_CONFIGURATION_destroy (c);
555   GNUNET_SERVICE_client_continue (ch->client);
556 }
557
558
559 /**
560  * Task run during shutdown.
561  *
562  * @param cls unused
563  */
564 static void
565 shutdown_task (void *cls)
566 {
567   if (NULL != scan_task)
568   {
569     GNUNET_SCHEDULER_cancel (scan_task);
570     scan_task = NULL;
571   }
572   if (NULL != stats)
573   {
574     GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
575     stats = NULL;
576   }
577   destroy_lal ();
578 }
579
580
581 /**
582  * Closure for #ifc_proc.
583  */
584 struct IfcProcContext
585 {
586
587   /** 
588    * Head of DLL of local addresses.
589    */
590   struct LocalAddressList *lal_head;
591
592   /**
593    * Tail of DLL of local addresses.
594    */
595   struct LocalAddressList *lal_tail;
596
597 };
598
599
600 /**
601  * Callback function invoked for each interface found.  Adds them
602  * to our new address list.
603  *
604  * @param cls a `struct IfcProcContext *`
605  * @param name name of the interface (can be NULL for unknown)
606  * @param isDefault is this presumably the default interface
607  * @param addr address of this interface (can be NULL for unknown or unassigned)
608  * @param broadcast_addr the broadcast address (can be NULL for unknown or unassigned)
609  * @param netmask the network mask (can be NULL for unknown or unassigned)
610  * @param addrlen length of the address
611  * @return #GNUNET_OK to continue iteration, #GNUNET_SYSERR to abort
612  */
613 static int
614 ifc_proc (void *cls,
615           const char *name,
616           int isDefault,
617           const struct sockaddr *addr,
618           const struct sockaddr *broadcast_addr,
619           const struct sockaddr *netmask,
620           socklen_t addrlen)
621 {
622   struct IfcProcContext *ifc_ctx = cls;
623   struct LocalAddressList *lal;
624   size_t alen;
625   const void *ip;
626
627   switch (addr->sa_family)
628   {
629   case AF_INET:
630     alen = sizeof (struct in_addr);
631     ip = &((const struct sockaddr_in *) addr)->sin_addr;
632     break;
633   case AF_INET6:
634     alen = sizeof (struct in6_addr);
635     ip = &((const struct sockaddr_in6 *) addr)->sin6_addr;
636     break;
637 #if AF_UNIX
638   case AF_UNIX:
639     GNUNET_break (0);
640     return GNUNET_OK;
641 #endif
642   default:
643     GNUNET_break (0);
644     return GNUNET_OK;
645   }
646   lal = GNUNET_malloc (sizeof (*lal) + alen);
647   lal->af = addr->sa_family;
648   lal->addr = &lal[1];
649   GNUNET_memcpy (&lal[1],
650                  ip,
651                  alen);
652   GNUNET_CONTAINER_DLL_insert (ifc_ctx->lal_head,
653                                ifc_ctx->lal_tail,
654                                lal);
655   return GNUNET_OK;
656 }
657
658
659 /**
660  * Task we run periodically to scan for network interfaces.
661  *
662  * @param cls NULL
663  */ 
664 static void
665 run_scan (void *cls)
666 {
667   struct IfcProcContext ifc_ctx;
668   
669   scan_task = GNUNET_SCHEDULER_add_delayed (SCAN_FREQ,
670                                             &run_scan,
671                                             NULL);
672   memset (&ifc_ctx,
673           0,
674           sizeof (ifc_ctx));
675   GNUNET_OS_network_interfaces_list (&ifc_proc,
676                                      &ifc_ctx);
677   /* FIXME: notify clients of changes in lal-DLL */
678   destroy_lal ();
679   lal_head = ifc_ctx.lal_head;
680   lal_tail = ifc_ctx.lal_tail;
681 }
682
683
684 /**
685  * Handle network size estimate clients.
686  *
687  * @param cls closure
688  * @param c configuration to use
689  * @param service the initialized service
690  */
691 static void
692 run (void *cls,
693      const struct GNUNET_CONFIGURATION_Handle *c,
694      struct GNUNET_SERVICE_Handle *service)
695 {
696   cfg = c;
697   GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
698                                  NULL);
699   stats = GNUNET_STATISTICS_create ("nat",
700                                     cfg);
701   scan_task = GNUNET_SCHEDULER_add_now (&run_scan,
702                                         NULL);
703 }
704
705
706 /**
707  * Callback called when a client connects to the service.
708  *
709  * @param cls closure for the service
710  * @param c the new client that connected to the service
711  * @param mq the message queue used to send messages to the client
712  * @return a `struct ClientHandle`
713  */
714 static void *
715 client_connect_cb (void *cls,
716                    struct GNUNET_SERVICE_Client *c,
717                    struct GNUNET_MQ_Handle *mq)
718 {
719   struct ClientHandle *ch;
720
721   ch = GNUNET_new (struct ClientHandle);
722   ch->mq = mq;
723   ch->client = c;
724   GNUNET_CONTAINER_DLL_insert (ch_head,
725                                ch_tail,
726                                ch);
727   return ch;
728 }
729
730
731 /**
732  * Callback called when a client disconnected from the service
733  *
734  * @param cls closure for the service
735  * @param c the client that disconnected
736  * @param internal_cls a `struct ClientHandle *`
737  */
738 static void
739 client_disconnect_cb (void *cls,
740                       struct GNUNET_SERVICE_Client *c,
741                       void *internal_cls)
742 {
743   struct ClientHandle *ch = internal_cls;
744
745   GNUNET_CONTAINER_DLL_remove (ch_head,
746                                ch_tail,
747                                ch);
748   for (unsigned int i=0;i<ch->num_addrs;i++)
749     GNUNET_free_non_null (ch->addrs[i]);
750   GNUNET_free_non_null (ch->addrs);
751   GNUNET_free (ch);
752 }
753
754
755 /**
756  * Define "main" method using service macro.
757  */
758 GNUNET_SERVICE_MAIN
759 ("nat",
760  GNUNET_SERVICE_OPTION_NONE,
761  &run,
762  &client_connect_cb,
763  &client_disconnect_cb,
764  NULL,
765  GNUNET_MQ_hd_var_size (register,
766                         GNUNET_MESSAGE_TYPE_NAT_REGISTER,
767                         struct GNUNET_NAT_RegisterMessage,
768                         NULL),
769  GNUNET_MQ_hd_var_size (stun,
770                         GNUNET_MESSAGE_TYPE_NAT_HANDLE_STUN,
771                         struct GNUNET_NAT_HandleStunMessage,
772                         NULL),
773  GNUNET_MQ_hd_var_size (request_connection_reversal,
774                         GNUNET_MESSAGE_TYPE_NAT_REQUEST_CONNECTION_REVERSAL,
775                         struct GNUNET_NAT_RequestConnectionReversalMessage,
776                         NULL),
777  GNUNET_MQ_hd_fixed_size (test,
778                           GNUNET_MESSAGE_TYPE_NAT_REQUEST_TEST,
779                           struct GNUNET_NAT_RequestTestMessage,
780                           NULL),
781  GNUNET_MQ_hd_var_size (autoconfig_request,
782                         GNUNET_MESSAGE_TYPE_NAT_REQUEST_AUTO_CFG,
783                         struct GNUNET_NAT_AutoconfigRequestMessage,
784                         NULL),
785  GNUNET_MQ_handler_end ());
786
787
788 #if defined(LINUX) && defined(__GLIBC__)
789 #include <malloc.h>
790
791 /**
792  * MINIMIZE heap size (way below 128k) since this process doesn't need much.
793  */
794 void __attribute__ ((constructor))
795 GNUNET_ARM_memory_init ()
796 {
797   mallopt (M_TRIM_THRESHOLD, 4 * 1024);
798   mallopt (M_TOP_PAD, 1 * 1024);
799   malloc_trim (0);
800 }
801 #endif
802
803 /* end of gnunet-service-nat.c */