GNUnet  0.19.4
gnunet-service-nat-auto_legacy.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2015 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your 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  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
30 #include "gnunet_nat_lib.h"
31 #include "nat.h"
32 
33 #define LOG(kind, ...) GNUNET_log_from (kind, "nat", __VA_ARGS__)
34 
35 
39 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15)
40 
41 #define NAT_SERVER_TIMEOUT GNUNET_TIME_relative_multiply ( \
42  GNUNET_TIME_UNIT_SECONDS, 10)
43 
48 {
52  AUTO_INIT = 0,
53 
58 
63 
68 
73 
78 
83 
88 
92  AUTO_DONE
93 };
94 
95 
100 {
105 
109  GNUNET_NAT_AutoResultCallback fin_cb;
110 
114  void *fin_cb_cls;
115 
120 
125 
130 
135 
140 
144  enum AutoPhase phase;
145 
149  enum GNUNET_NAT_Type type;
150 
154  int have_v6;
155 
160 
165 
169  char *stun_ip;
170 
171  unsigned int stun_port;
172 
177 
182 };
183 
184 
189 
194 
198 static unsigned long long port = 7895;
199 
200 static char *stun_server = "stun.ekiga.net";
201 
202 static unsigned int stun_port = 3478;
203 
204 
210 static void
212 
213 
214 static void
215 process_stun_reply (struct sockaddr_in *answer,
216  struct GNUNET_NAT_AutoHandle *ah)
217 {
218  ah->stun_ip = inet_ntoa (answer->sin_addr);
219  ah->stun_port = ntohs (answer->sin_port);
221  "External IP is: %s , with port %u\n",
222  ah->stun_ip,
223  ah->stun_port);
224  next_phase (ah);
225 }
226 
227 
231 static void
233 {
235  "Stopping STUN and quitting...\n");
236  /* Clean task */
237  if (NULL != ltask4)
238  {
240  ltask4 = NULL;
241  }
242  /* Clean socket */
243  if (NULL != lsock4)
244  {
246  lsock4 = NULL;
247  }
248 }
249 
250 
257 static void
258 do_udp_read (void *cls)
259 {
260  struct GNUNET_NAT_AutoHandle *ah = cls;
261  unsigned char reply_buf[1024];
262  ssize_t rlen;
263  struct sockaddr_in answer;
264  const struct GNUNET_SCHEDULER_TaskContext *tc;
265 
267  if ((0 != (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) &&
269  lsock4)))
270  {
272  reply_buf,
273  sizeof(reply_buf));
274 
275  // Lets handle the packet
276  memset (&answer, 0, sizeof(struct sockaddr_in));
277  if (ah->phase == AUTO_NAT_PUNCHED)
278  {
279  // Destroy the connection
282  "The external server was able to connect back");
283  ah->connected_back = GNUNET_YES;
284  next_phase (ah);
285  }
286  else
287  {
288  if (GNUNET_OK ==
289  GNUNET_NAT_stun_handle_packet (reply_buf, rlen, &answer))
290  {
291  // Process the answer
292  process_stun_reply (&answer, ah);
293  }
294  else
295  {
296  next_phase (ah);
297  }
298  }
299  }
300  else
301  {
303  "TIMEOUT while waiting for an answer\n");
304  if (ah->phase == AUTO_NAT_PUNCHED)
305  {
306  stop_stun ();
307  }
308 
309  next_phase (ah);
310  }
311 }
312 
313 
319 static struct GNUNET_NETWORK_Handle *
321 {
322  struct GNUNET_NETWORK_Handle *ls;
323  struct sockaddr_in sa4;
324  int eno;
325 
326  memset (&sa4, 0, sizeof(sa4));
327  sa4.sin_family = AF_INET;
328  sa4.sin_port = htons (port);
329 #if HAVE_SOCKADDR_IN_SIN_LEN
330  sa4.sin_len = sizeof(sa4);
331 #endif
332  ls = GNUNET_NETWORK_socket_create (AF_INET,
333  SOCK_DGRAM,
334  0);
335  if (NULL == ls)
336  return NULL;
337  if (GNUNET_OK !=
338  GNUNET_NETWORK_socket_bind (ls, (const struct sockaddr *) &sa4,
339  sizeof(sa4)))
340  {
341  eno = errno;
343  errno = eno;
344  return NULL;
345  }
346  return ls;
347 }
348 
349 
350 static void
351 request_callback (void *cls,
353 {
354  // struct GNUNET_NAT_AutoHandle *ah = cls;
355 
357  "Request callback: stop and quit\n");
358  stop_stun ();
359 
360  // next_phase (ah); FIXME this always will be NULL, as called in test_stun()
361 }
362 
363 
372 static void
373 result_callback (void *cls,
375 {
376  struct GNUNET_NAT_AutoHandle *ah = cls;
377 
379  GNUNET_NAT_test_stop (ah->tst);
380  ah->tst = NULL;
381  ah->ret = ret;
384  ? _ ("NAT traversal with ICMP Server succeeded.\n")
385  : _ ("NAT traversal with ICMP Server failed.\n"));
386  GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "ENABLE_ICMP_SERVER",
388  "NO" : "YES");
389  next_phase (ah);
390 }
391 
392 
398 static void
399 reversal_test (void *cls)
400 {
401  struct GNUNET_NAT_AutoHandle *ah = cls;
402 
403  ah->task = NULL;
405  _ ("Testing connection reversal with ICMP server.\n"));
407  ah->tst = GNUNET_NAT_test_start (ah->cfg, GNUNET_YES, 0, 0, TIMEOUT,
408  &result_callback, ah);
409 }
410 
411 
420 static void
421 set_external_ipv4 (void *cls,
422  const struct in_addr *addr,
424 {
425  struct GNUNET_NAT_AutoHandle *ah = cls;
426  char buf[INET_ADDRSTRLEN];
427 
428  ah->eh = NULL;
429  ah->ret = ret;
431  {
432  next_phase (ah);
433  return;
434  }
435  /* enable 'behind nat' */
437  _ ("Detected external IP `%s'\n"),
438  inet_ntop (AF_INET,
439  addr,
440  buf,
441  sizeof(buf)));
442  GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "BEHIND_NAT", "YES");
443 
444  /* set external IP address */
445  if (NULL == inet_ntop (AF_INET, addr, buf, sizeof(buf)))
446  {
447  GNUNET_break (0);
448  /* actually, this should never happen, as the caller already executed just
449  * this check, but for consistency (eg: future changes in the caller)
450  * we still need to report this error...
451  */
453  next_phase (ah);
454  return;
455  }
456  GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "EXTERNAL_ADDRESS",
457  buf);
458  ah->upnp_set_external_address = GNUNET_YES;
459  next_phase (ah);
460 }
461 
462 
468 static void
470 {
471  if (GNUNET_NAT_ERROR_SUCCESS != ah->ret)
472  next_phase (ah);
473 
474  // FIXME: CPS?
475  /* try to detect external IP */
476  ah->eh = GNUNET_NAT_mini_get_external_ipv4 (TIMEOUT,
478 }
479 
480 
486 static void
488 {
489  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Running STUN test\n");
490 
491  /* Get port from the configuration */
492  if (GNUNET_OK !=
494  "transport-udp",
495  "PORT",
496  &port))
497  {
498  port = 2086;
499  }
500 
501  // Lets create the socket
502  lsock4 = bind_v4 ();
503  if (NULL == lsock4)
504  {
506  next_phase (ah);
507  return;
508  }
509  else
510  {
511  // Lets call our function now when it accepts
513  lsock4,
514  &do_udp_read,
515  ah);
516  }
517 
518 
520  "STUN service listens on port %u\n",
521  (unsigned int) port);
522  if (GNUNET_NO ==
524  stun_port,
525  lsock4,
527  NULL))
528  {
529  /*An error happened*/
530  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "STUN error, stopping\n");
531  stop_stun ();
532  next_phase (ah);
533  }
534 }
535 
536 
550 static int
551 process_if (void *cls,
552  const char *name,
553  int isDefault,
554  const struct sockaddr *addr,
555  const struct sockaddr *broadcast_addr,
556  const struct sockaddr *netmask,
557  socklen_t addrlen)
558 {
559  struct GNUNET_NAT_AutoHandle *ah = cls;
560  const struct sockaddr_in *in;
561  char buf[INET_ADDRSTRLEN];
562 
563 
564  if ((sizeof(struct sockaddr_in6) == addrlen) &&
565  (0 != GNUNET_memcmp (&in6addr_loopback, &((const struct
566  sockaddr_in6 *) addr)->
567  sin6_addr)) &&
568  (! IN6_IS_ADDR_LINKLOCAL (&((const struct
569  sockaddr_in6 *) addr)->sin6_addr)))
570  {
571  ah->have_v6 = GNUNET_YES;
573  _ (
574  "This system has a global IPv6 address, setting IPv6 to supported.\n"));
575 
576  return GNUNET_OK;
577  }
578  if (addrlen != sizeof(struct sockaddr_in))
579  return GNUNET_OK;
580  in = (const struct sockaddr_in *) addr;
581 
582 
583  /* set internal IP address */
584  if (NULL == inet_ntop (AF_INET, &in->sin_addr, buf, sizeof(buf)))
585  {
586  GNUNET_break (0);
587  return GNUNET_OK;
588  }
589  GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "INTERNAL_ADDRESS",
590  buf);
592  _ ("Detected internal network address `%s'.\n"),
593  buf);
594 
595 
597 
598  /* Check if our internal IP is the same as the External detect by STUN*/
599  if (ah->stun_ip && (strcmp (buf, ah->stun_ip) == 0))
600  {
601  ah->internal_ip_is_public = GNUNET_YES;
603  "A internal IP is the sameas the external");
604  /* No need to continue*/
605  return GNUNET_SYSERR;
606  }
607 
608  /* no need to continue iteration if we found the default */
609  if (! isDefault)
610  return GNUNET_OK;
611  else
612  return GNUNET_SYSERR;
613 }
614 
615 
621 static void
623 {
624  ah->have_v6 = GNUNET_NO;
625  ah->ret = GNUNET_NAT_ERROR_NO_VALID_IF_IP_COMBO; // reset to success if any of the IFs in below iterator has a valid IP
627 
628  GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "DISABLEV6",
629  (GNUNET_YES == ah->have_v6) ? "NO" :
630  "YES");
631  next_phase (ah);
632 }
633 
634 
642 static void
643 mq_error_handler (void *cls,
644  enum GNUNET_MQ_Error error)
645 {
646  struct GNUNET_NAT_AutoHandle *ah = cls;
647 
649  ah->mq = NULL;
650  /* wait a bit first? */
651  next_phase (ah);
652 }
653 
654 
660 static void
662 {
663  struct GNUNET_NAT_TestMessage *msg;
664  struct GNUNET_MQ_Envelope *env;
665 
666  if (! ah->stun_ip)
667  {
669  "We don't have a STUN IP");
670  next_phase (ah);
671  return;
672  }
673 
675  "Asking gnunet-nat-server to connect to `%s'\n",
676  ah->stun_ip);
678  "gnunet-nat-server",
679  NULL,
681  ah);
682  if (NULL == ah->mq)
683  {
685  _ ("Failed to connect to `gnunet-nat-server'\n"));
686  next_phase (ah);
687  return;
688  }
689  env = GNUNET_MQ_msg (msg,
691  msg->dst_ipv4 = inet_addr (ah->stun_ip);
692  msg->dport = htons (ah->stun_port);
693  msg->data = port;
694  msg->is_tcp = htonl ((uint32_t) GNUNET_NO);
695  GNUNET_MQ_send (ah->mq,
696  env);
697  if (NULL != ltask4)
698  {
701  lsock4,
702  &do_udp_read,
703  ah);
704  }
705 }
706 
707 
713 static void
715 {
716  int have_upnpc;
717 
718  if (GNUNET_NAT_ERROR_SUCCESS != ah->ret)
719  next_phase (ah);
720 
721  // test if upnpc is available
722  have_upnpc = (GNUNET_SYSERR !=
723  GNUNET_OS_check_helper_binary ("upnpc", GNUNET_NO, NULL));
724  // FIXME: test if upnpc is actually working, that is, if transports start to work once we use UPnP
726  (have_upnpc)
727  ? _ ("upnpc found, enabling its use\n")
728  : _ ("upnpc not found\n"));
729  GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "ENABLE_UPNP",
730  (GNUNET_YES == have_upnpc) ? "YES" :
731  "NO");
732  next_phase (ah);
733 }
734 
735 
741 static void
743 {
744  int ext_ip;
745  int nated;
746  int binary;
747  char *tmp;
748  char *helper;
749 
750  ext_ip = GNUNET_NO;
751  nated = GNUNET_NO;
752  binary = GNUNET_NO;
753 
754  tmp = NULL;
755  helper = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-nat-server");
756  if ((GNUNET_OK ==
758  "nat",
759  "EXTERNAL_ADDRESS",
760  &tmp)) &&
761  (0 < strlen (tmp)))
762  {
763  ext_ip = GNUNET_OK;
765  _ (
766  "test_icmp_server not possible, as we have no public IPv4 address\n"));
767  }
768  else
769  goto err;
770 
771  if (GNUNET_YES ==
773  "nat",
774  "BEHIND_NAT"))
775  {
776  nated = GNUNET_YES;
778  _ (
779  "test_icmp_server not possible, as we are not behind NAT\n"));
780  }
781  else
782  goto err;
783 
784  if (GNUNET_YES ==
786  GNUNET_YES,
787  "-d 127.0.0.1"))
788  {
789  binary = GNUNET_OK; // use localhost as source for that one udp-port, ok for testing
791  _ ("No working gnunet-helper-nat-server found\n"));
792  }
793 err:
794  GNUNET_free (tmp);
795  GNUNET_free (helper);
796 
797  if ((GNUNET_OK == ext_ip) &&
798  (GNUNET_YES == nated) &&
799  (GNUNET_OK == binary))
801  ah);
802  else
803  next_phase (ah);
804 }
805 
806 
812 static void
814 {
815  char *tmp;
816  char *helper;
817 
818  tmp = NULL;
819  helper = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-nat-client");
820  if ((GNUNET_OK ==
822  "nat",
823  "INTERNAL_ADDRESS",
824  &tmp)) &&
825  (0 < strlen (tmp)))
826  {
828  _ (
829  "test_icmp_client not possible, as we have no internal IPv4 address\n"));
830  }
831  else
832  goto err;
833 
834  if (GNUNET_YES !=
836  "nat",
837  "BEHIND_NAT"))
838  {
840  _ (
841  "test_icmp_server not possible, as we are not behind NAT\n"));
842  }
843  else
844  goto err;
845 
846  if (GNUNET_YES ==
848  GNUNET_YES,
849  "-d 127.0.0.1 127.0.0.2 42"))
850  {
851  // none of these parameters are actually used in privilege testing mode
853  _ ("No working gnunet-helper-nat-server found\n"));
854  }
855 err:
856  GNUNET_free (tmp);
857  GNUNET_free (helper);
858 
859  next_phase (ah);
860 }
861 
862 
866 static void
868 {
869  struct GNUNET_CONFIGURATION_Handle *diff;
870 
871  ah->phase++;
872  switch (ah->phase)
873  {
874  case AUTO_INIT:
875  GNUNET_assert (0);
876  break;
877 
878  case AUTO_EXTERNAL_IP:
880  "Will run AUTO_EXTERNAL_IP\n");
882  break;
883 
884  case AUTO_STUN:
886  "Will run AUTO_STUN\n");
887  test_stun (ah);
888  break;
889 
890  case AUTO_LOCAL_IP:
892  "Will run AUTO_LOCAL_IP\n");
893  test_local_ip (ah);
894  break;
895 
896  case AUTO_NAT_PUNCHED:
898  "Will run AUTO_NAT_PUNCHED\n");
900  break;
901 
902  case AUTO_UPNPC:
904  "Will run AUTO_UPNPC\n");
905  test_upnpc (ah);
906  break;
907 
908  case AUTO_ICMP_SERVER:
910  "Will run AUTO_ICMP_SERVER\n");
912  break;
913 
914  case AUTO_ICMP_CLIENT:
916  "Will run AUTO_ICMP_CLIENT\n");
918  break;
919 
920  case AUTO_DONE:
922  "Done with tests\n");
923  if (! ah->internal_ip_is_public)
924  {
926  "nat",
927  "BEHIND_NAT",
928  "YES");
929 
930  if (ah->connected_back)
931  {
933  "nat",
934  "PUNCHED_NAT",
935  "YES");
936  }
937  else
938  {
940  "nat",
941  "PUNCHED_NAT",
942  "NO");
943  }
944 
945  if (ah->stun_ip)
946  {
948  "nat",
949  "EXTERNAL_ADDRESS",
950  ah->stun_ip);
951  if (ah->connected_back)
952  {
955  "nat",
956  "USE_STUN",
957  "YES");
958  }
959  else
960  {
963  "nat",
964  "USE_STUN",
965  "NO");
966  }
967  }
968  if (0 != ah->stun_port)
969  {
971  "transport-udp",
972  "ADVERTISED_PORT",
973  ah->stun_port);
974  }
975  }
976  else
977  {
978  // The internal IP is the same as public, but we didn't got a incoming connection
979  if (ah->connected_back)
980  {
981  ah->type = GNUNET_NAT_TYPE_NO_NAT;
983  "nat",
984  "BEHIND_NAT",
985  "NO");
986  }
987  else
988  {
990  "nat",
991  "BEHIND_NAT",
992  "YES");
994  if (ah->stun_ip)
995  {
997  "nat",
998  "EXTERNAL_ADDRESS",
999  ah->stun_ip);
1000  }
1001  if (0 != ah->stun_port)
1002  {
1004  "transport-udp",
1005  "ADVERTISED_PORT",
1006  ah->stun_port);
1007  }
1008  }
1009  }
1010 
1011  diff = GNUNET_CONFIGURATION_get_diff (ah->initial_cfg,
1012  ah->cfg);
1013 
1014 
1015  ah->fin_cb (ah->fin_cb_cls,
1016  diff,
1017  ah->ret,
1018  ah->type);
1021  }
1022 }
1023 
1024 
1034 struct GNUNET_NAT_AutoHandle *
1036  GNUNET_NAT_AutoResultCallback cb,
1037  void *cb_cls)
1038 {
1039  struct GNUNET_NAT_AutoHandle *ah;
1040 
1041  ah = GNUNET_new (struct GNUNET_NAT_AutoHandle);
1042  ah->fin_cb = cb;
1043  ah->fin_cb_cls = cb_cls;
1046  ah->initial_cfg = GNUNET_CONFIGURATION_dup (cfg);
1047 
1048  /* never use loopback addresses if user wanted autoconfiguration */
1050  "nat",
1051  "USE_LOCALADDR",
1052  "NO");
1053 
1054  next_phase (ah);
1055  return ah;
1056 }
1057 
1058 
1064 void
1066 {
1067  if (NULL != ah->tst)
1068  {
1069  GNUNET_NAT_test_stop (ah->tst);
1070  ah->tst = NULL;
1071  }
1072  if (NULL != ah->eh)
1073  {
1074  GNUNET_NAT_mini_get_external_ipv4_cancel (ah->eh);
1075  ah->eh = NULL;
1076  }
1077  if (NULL != ah->mq)
1078  {
1079  GNUNET_MQ_destroy (ah->mq);
1080  ah->mq = NULL;
1081  }
1082  if (NULL != ah->task)
1083  {
1084  GNUNET_SCHEDULER_cancel (ah->task);
1085  ah->task = NULL;
1086  }
1088  GNUNET_CONFIGURATION_destroy (ah->initial_cfg);
1089  GNUNET_free (ah);
1090 }
1091 
1092 
1093 /* end of nat_auto.c */
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static struct GNUNET_NAT_AUTO_AutoHandle * ah
Handle to ongoing autoconfiguration.
struct GNUNET_NAT_Test * GNUNET_NAT_test_start(const struct GNUNET_CONFIGURATION_Handle *cfg, int is_tcp, uint16_t bnd_port, uint16_t adv_port, struct GNUNET_TIME_Relative timeout, GNUNET_NAT_TestCallback report, void *report_cls)
Start testing if NAT traversal works using the given configuration (IPv4-only).
void GNUNET_NAT_test_stop(struct GNUNET_NAT_Test *tst)
Stop an active NAT test.
static struct GNUNET_NETWORK_Handle * ls
Listen socket for STUN processing.
Definition: gnunet-nat.c:85
static int result
Global testing status.
struct GNUNET_NAT_AutoHandle * GNUNET_NAT_autoconfig_start(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_NAT_AutoResultCallback cb, void *cb_cls)
Start auto-configuration routine.
static void process_stun_reply(struct sockaddr_in *answer, struct GNUNET_NAT_AutoHandle *ah)
static void test_upnpc(struct GNUNET_NAT_AutoHandle *ah)
Test if UPnPC works.
static void set_external_ipv4(void *cls, const struct in_addr *addr, enum GNUNET_NAT_StatusCode ret)
Set our external IPv4 address based on the UPnP.
static char * stun_server
static void test_nat_punched(struct GNUNET_NAT_AutoHandle *ah)
Test if NAT has been punched.
static void next_phase(struct GNUNET_NAT_AutoHandle *ah)
Run the next phase of the auto test.
static void request_callback(void *cls, enum GNUNET_NAT_StatusCode result)
void GNUNET_NAT_autoconfig_cancel(struct GNUNET_NAT_AutoHandle *ah)
Abort autoconfiguration.
#define TIMEOUT
How long do we wait for the NAT test to report success?
static void test_stun(struct GNUNET_NAT_AutoHandle *ah)
Determine our external IPv4 address and port using an external STUN server.
#define NAT_SERVER_TIMEOUT
static void test_icmp_client(struct GNUNET_NAT_AutoHandle *ah)
Test if ICMP client is working.
static int process_if(void *cls, const char *name, int isDefault, const struct sockaddr *addr, const struct sockaddr *broadcast_addr, const struct sockaddr *netmask, socklen_t addrlen)
Process list of local IP addresses.
static struct GNUNET_NETWORK_Handle * lsock4
The listen socket of the service for IPv4.
static unsigned long long port
The port the test service is running on (default 7895)
static void stop_stun()
Function that terminates the test.
static unsigned int stun_port
static void test_icmp_server(struct GNUNET_NAT_AutoHandle *ah)
Test if ICMP server is working.
static void mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
We got disconnected from the NAT server.
static void test_local_ip(struct GNUNET_NAT_AutoHandle *ah)
Determine our local IP addresses; detect internal IP & IPv6-support.
static void reversal_test(void *cls)
Main function for the connection reversal test.
static void result_callback(void *cls, enum GNUNET_NAT_StatusCode ret)
Function called by NAT to report the outcome of the nat-test.
static void test_external_ip(struct GNUNET_NAT_AutoHandle *ah)
Determine our external IPv4 address.
static void do_udp_read(void *cls)
Activity on our incoming socket.
AutoPhase
Phases of the auto configuration.
@ AUTO_EXTERNAL_IP
Test our external IP.
@ AUTO_NAT_PUNCHED
Test if NAT was punched.
@ AUTO_LOCAL_IP
Test our internal IP.
@ AUTO_INIT
Initial start value.
@ AUTO_STUN
Test our external IP.
@ AUTO_ICMP_CLIENT
Test if ICMP client works.
@ AUTO_DONE
Last phase, we're done.
@ AUTO_ICMP_SERVER
Test if ICMP server works.
@ AUTO_UPNPC
Test if UPnP is working.
#define LOG(kind,...)
static struct GNUNET_SCHEDULER_Task * ltask4
The listen task ID for IPv4.
static struct GNUNET_NETWORK_Handle * bind_v4()
Create an IPv4 listen socket bound to our port.
static char buf[2048]
Functions related to doing DNS lookups.
struct GNUNET_MQ_Handle * GNUNET_CLIENT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *service_name, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *error_handler_cls)
Create a message queue to connect to a GNUnet service.
Definition: client.c:1057
void GNUNET_CONFIGURATION_set_value_string(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, const char *value)
Set a configuration value that should be a string.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
void GNUNET_CONFIGURATION_destroy(struct GNUNET_CONFIGURATION_Handle *cfg)
Destroy configuration object.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
void GNUNET_CONFIGURATION_set_value_number(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long number)
Set a configuration value that should be a number.
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_get_diff(const struct GNUNET_CONFIGURATION_Handle *cfg_default, const struct GNUNET_CONFIGURATION_Handle *cfg_new)
Compute configuration with only entries that have been changed.
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_dup(const struct GNUNET_CONFIGURATION_Handle *cfg)
Duplicate an existing configuration object.
#define GNUNET_log(kind,...)
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
GNUNET_MQ_Error
Error codes for the queue.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:304
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:77
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:683
GNUNET_NAT_StatusCode
Error Types for the NAT subsystem (which can then later be converted/resolved to a string)
GNUNET_NAT_Type
What the situation of the NAT connectivity.
struct GNUNET_NAT_STUN_Handle * GNUNET_NAT_stun_make_request(const char *server, uint16_t port, struct GNUNET_NETWORK_Handle *sock, GNUNET_NAT_TestCallback cb, void *cb_cls)
Make Generic STUN request.
Definition: nat_api_stun.c:211
int GNUNET_NAT_stun_handle_packet(struct GNUNET_NAT_Handle *nh, const struct sockaddr *sender_addr, size_t sender_addr_len, const void *data, size_t data_size)
Handle an incoming STUN message.
Definition: nat_api.c:572
@ GNUNET_NAT_ERROR_SUCCESS
Just the default.
@ GNUNET_NAT_ERROR_NO_VALID_IF_IP_COMBO
Could not determine interface with internal/local network address.
@ GNUNET_NAT_ERROR_EXTERNAL_IP_ADDRESS_INVALID
"no valid address was returned by `external-ip'"
@ GNUNET_NAT_TYPE_UNREACHABLE_NAT
We are under a NAT but cannot traverse it.
@ GNUNET_NAT_TYPE_NO_NAT
We have a direct connection.
@ GNUNET_NAT_TYPE_STUN_PUNCHED_NAT
We can traverse using STUN.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:508
ssize_t GNUNET_NETWORK_socket_recv(const struct GNUNET_NETWORK_Handle *desc, void *buffer, size_t length)
Read data from a connected socket (always non-blocking).
Definition: network.c:716
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:832
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_bind(struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Bind a socket to a particular address.
Definition: network.c:439
int GNUNET_NETWORK_fdset_isset(const struct GNUNET_NETWORK_FDSet *fds, const struct GNUNET_NETWORK_Handle *desc)
Check whether a socket is part of the fd set.
Definition: network.c:949
char * GNUNET_OS_get_libexec_binary_path(const char *progname)
Given the name of a gnunet-helper, gnunet-service or gnunet-daemon binary, try to prefix it with the ...
void GNUNET_OS_network_interfaces_list(GNUNET_OS_NetworkInterfaceProcessor proc, void *proc_cls)
Enumerate all network interfaces.
Definition: os_network.c:397
enum GNUNET_GenericReturnValue GNUNET_OS_check_helper_binary(const char *binary, bool check_suid, const char *params)
Check whether an executable exists and possibly if the suid bit is set on the file.
#define GNUNET_MESSAGE_TYPE_NAT_TEST
Message to ask NAT server to perform traversal test.
void GNUNET_RESOLVER_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Create the connection to the resolver service.
Definition: resolver_api.c:258
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1299
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition: scheduler.c:1506
const struct GNUNET_SCHEDULER_TaskContext * GNUNET_SCHEDULER_get_task_context(void)
Obtain the reasoning why the current task was started.
Definition: scheduler.c:752
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
@ GNUNET_SCHEDULER_REASON_READ_READY
The reading socket is ready.
Messages for interaction with gnunet-nat-server and gnunet-nat-service.
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
const char * name
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition: scheduler.c:431
Handle to a message queue.
Definition: mq.c:87
struct GNUNET_MQ_Handle * mq
Message queue for communicating with the NAT service.
Definition: nat_auto_api.c:47
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we use.
Definition: nat_auto_api.c:42
Handle to auto-configuration in progress.
int internal_ip_is_public
Internal IP is the same as the public one ?
enum GNUNET_NAT_StatusCode ret
Error code for better debugging and user feedback.
struct GNUNET_SCHEDULER_Task * task
Task identifier for the timeout.
int upnp_set_external_address
UPnP already set the external ip address ?
struct GNUNET_NAT_ExternalHandle * eh
Handle for active 'GNUNET_NAT_mini_get_external_ipv4'-operation.
int connected_back
Did the external server connected back ?
struct GNUNET_CONFIGURATION_Handle * cfg
Current configuration (with updates from previous phases)
enum AutoPhase phase
Where are we in the test?
struct GNUNET_NAT_Test * tst
Handle to the active NAT test.
char * stun_ip
Address detected by STUN.
void * fin_cb_cls
Closure for fin_cb.
struct GNUNET_MQ_Handle * mq
Message queue to the gnunet-nat-server.
enum GNUNET_NAT_Type type
Situation of the NAT.
GNUNET_NAT_AutoResultCallback fin_cb
Function to call when done.
struct GNUNET_CONFIGURATION_Handle * initial_cfg
Original configuration (used to calculate differences)
Opaque handle to cancel "GNUNET_NAT_mini_get_external_ipv4" operation.
Request to test NAT traversal, sent to the gnunet-nat-server (not the service!).
Definition: nat.h:39
Handle to a NAT test.
handle to a socket
Definition: network.c:53
Context information passed to each scheduler task.
const struct GNUNET_NETWORK_FDSet * read_ready
Set of file descriptors ready for reading; note that additional bits may be set that were not in the ...
enum GNUNET_SCHEDULER_Reason reason
Reason why the task is run now.
Entry in list of pending tasks.
Definition: scheduler.c:136