GNUnet  0.10.x
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(GNUNET_TIME_UNIT_SECONDS, 10)
42 
46 enum AutoPhase {
50  AUTO_INIT = 0,
51 
56 
61 
66 
71 
76 
81 
86 
91 };
92 
93 
102 
106  GNUNET_NAT_AutoResultCallback fin_cb;
107 
111  void *fin_cb_cls;
112 
117 
122 
127 
132 
137 
142 
147 
151  int have_v6;
152 
157 
162 
166  char *stun_ip;
167 
168  unsigned int stun_port;
169 
174 
179 };
180 
181 
186 
191 
195 static unsigned long long port = 7895;
196 
197 static char *stun_server = "stun.ekiga.net";
198 
199 static unsigned int stun_port = 3478;
200 
201 
207 static void
209 
210 
211 static void
212 process_stun_reply(struct sockaddr_in *answer,
213  struct GNUNET_NAT_AutoHandle *ah)
214 {
215  ah->stun_ip = inet_ntoa(answer->sin_addr);
216  ah->stun_port = ntohs(answer->sin_port);
218  "External IP is: %s , with port %u\n",
219  ah->stun_ip,
220  ah->stun_port);
221  next_phase(ah);
222 }
223 
224 
228 static void
230 {
232  "Stopping STUN and quitting...\n");
233  /* Clean task */
234  if (NULL != ltask4)
235  {
236  GNUNET_SCHEDULER_cancel(ltask4);
237  ltask4 = NULL;
238  }
239  /* Clean socket */
240  if (NULL != lsock4)
241  {
243  lsock4 = NULL;
244  }
245 }
246 
247 
254 static void
255 do_udp_read(void *cls)
256 {
257  struct GNUNET_NAT_AutoHandle *ah = cls;
258  unsigned char reply_buf[1024];
259  ssize_t rlen;
260  struct sockaddr_in answer;
261  const struct GNUNET_SCHEDULER_TaskContext *tc;
262 
264  if ((0 != (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) &&
266  lsock4)))
267  {
268  rlen = GNUNET_NETWORK_socket_recv(lsock4,
269  reply_buf,
270  sizeof(reply_buf));
271 
272  //Lets handle the packet
273  memset(&answer, 0, sizeof(struct sockaddr_in));
274  if (ah->phase == AUTO_NAT_PUNCHED)
275  {
276  //Destroy the connection
279  "The external server was able to connect back");
281  next_phase(ah);
282  }
283  else
284  {
285  if (GNUNET_OK ==
286  GNUNET_NAT_stun_handle_packet(reply_buf, rlen, &answer))
287  {
288  //Process the answer
289  process_stun_reply(&answer, ah);
290  }
291  else
292  {
293  next_phase(ah);
294  }
295  }
296  }
297  else
298  {
300  "TIMEOUT while waiting for an answer\n");
301  if (ah->phase == AUTO_NAT_PUNCHED)
302  {
303  stop_stun();
304  }
305 
306  next_phase(ah);
307  }
308 }
309 
310 
316 static struct GNUNET_NETWORK_Handle *
318 {
319  struct GNUNET_NETWORK_Handle *ls;
320  struct sockaddr_in sa4;
321  int eno;
322 
323  memset(&sa4, 0, sizeof(sa4));
324  sa4.sin_family = AF_INET;
325  sa4.sin_port = htons(port);
326 #if HAVE_SOCKADDR_IN_SIN_LEN
327  sa4.sin_len = sizeof(sa4);
328 #endif
329  ls = GNUNET_NETWORK_socket_create(AF_INET,
330  SOCK_DGRAM,
331  0);
332  if (NULL == ls)
333  return NULL;
334  if (GNUNET_OK !=
335  GNUNET_NETWORK_socket_bind(ls, (const struct sockaddr *)&sa4,
336  sizeof(sa4)))
337  {
338  eno = errno;
340  errno = eno;
341  return NULL;
342  }
343  return ls;
344 }
345 
346 
347 static void
350 {
351  // struct GNUNET_NAT_AutoHandle *ah = cls;
352 
354  "Request callback: stop and quit\n");
355  stop_stun();
356 
357  // next_phase (ah); FIXME this always will be NULL, as called in test_stun()
358 }
359 
360 
369 static void
370 result_callback(void *cls,
372 {
373  struct GNUNET_NAT_AutoHandle *ah = cls;
374 
375  if (GNUNET_NAT_ERROR_SUCCESS == ret)
377  ah->tst = NULL;
378  ah->ret = ret;
381  ? _("NAT traversal with ICMP Server succeeded.\n")
382  : _("NAT traversal with ICMP Server failed.\n"));
383  GNUNET_CONFIGURATION_set_value_string(ah->cfg, "nat", "ENABLE_ICMP_SERVER",
384  GNUNET_NAT_ERROR_SUCCESS == ret ? "NO" : "YES");
385  next_phase(ah);
386 }
387 
388 
394 static void
395 reversal_test(void *cls)
396 {
397  struct GNUNET_NAT_AutoHandle *ah = cls;
398 
399  ah->task = NULL;
401  _("Testing connection reversal with ICMP server.\n"));
403  ah->tst = GNUNET_NAT_test_start(ah->cfg, GNUNET_YES, 0, 0, TIMEOUT,
404  &result_callback, ah);
405 }
406 
407 
416 static void
418  const struct in_addr *addr,
420 {
421  struct GNUNET_NAT_AutoHandle *ah = cls;
422  char buf[INET_ADDRSTRLEN];
423 
424  ah->eh = NULL;
425  ah->ret = ret;
426  if (GNUNET_NAT_ERROR_SUCCESS != ret)
427  {
428  next_phase(ah);
429  return;
430  }
431  /* enable 'behind nat' */
433  _("Detected external IP `%s'\n"),
434  inet_ntop(AF_INET,
435  addr,
436  buf,
437  sizeof(buf)));
438  GNUNET_CONFIGURATION_set_value_string(ah->cfg, "nat", "BEHIND_NAT", "YES");
439 
440  /* set external IP address */
441  if (NULL == inet_ntop(AF_INET, addr, buf, sizeof(buf)))
442  {
443  GNUNET_break(0);
444  /* actually, this should never happen, as the caller already executed just
445  * this check, but for consistency (eg: future changes in the caller)
446  * we still need to report this error...
447  */
449  next_phase(ah);
450  return;
451  }
452  GNUNET_CONFIGURATION_set_value_string(ah->cfg, "nat", "EXTERNAL_ADDRESS",
453  buf);
455  next_phase(ah);
456 }
457 
458 
464 static void
466 {
467  if (GNUNET_NAT_ERROR_SUCCESS != ah->ret)
468  next_phase(ah);
469 
470  // FIXME: CPS?
471  /* try to detect external IP */
472  ah->eh = GNUNET_NAT_mini_get_external_ipv4(TIMEOUT,
473  &set_external_ipv4, ah);
474 }
475 
476 
482 static void
484 {
485  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Running STUN test\n");
486 
487  /* Get port from the configuration */
488  if (GNUNET_OK !=
490  "transport-udp",
491  "PORT",
492  &port))
493  {
494  port = 2086;
495  }
496 
497  //Lets create the socket
498  lsock4 = bind_v4();
499  if (NULL == lsock4)
500  {
502  next_phase(ah);
503  return;
504  }
505  else
506  {
507  //Lets call our function now when it accepts
509  lsock4,
510  &do_udp_read,
511  ah);
512  }
513 
514 
516  "STUN service listens on port %u\n",
517  (unsigned int)port);
518  if (GNUNET_NO ==
520  stun_port,
521  lsock4,
523  NULL))
524  {
525  /*An error happened*/
526  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "STUN error, stopping\n");
527  stop_stun();
528  next_phase(ah);
529  }
530 }
531 
532 
546 static int
547 process_if(void *cls,
548  const char *name,
549  int isDefault,
550  const struct sockaddr *addr,
551  const struct sockaddr *broadcast_addr,
552  const struct sockaddr *netmask,
553  socklen_t addrlen)
554 {
555  struct GNUNET_NAT_AutoHandle *ah = cls;
556  const struct sockaddr_in *in;
557  char buf[INET_ADDRSTRLEN];
558 
559 
560  if ((sizeof(struct sockaddr_in6) == addrlen) &&
561  (0 != GNUNET_memcmp(&in6addr_loopback, &((const struct sockaddr_in6 *)addr)->sin6_addr)) &&
562  (!IN6_IS_ADDR_LINKLOCAL(&((const struct sockaddr_in6 *)addr)->sin6_addr)))
563  {
564  ah->have_v6 = GNUNET_YES;
566  _("This system has a global IPv6 address, setting IPv6 to supported.\n"));
567 
568  return GNUNET_OK;
569  }
570  if (addrlen != sizeof(struct sockaddr_in))
571  return GNUNET_OK;
572  in = (const struct sockaddr_in *)addr;
573 
574 
575  /* set internal IP address */
576  if (NULL == inet_ntop(AF_INET, &in->sin_addr, buf, sizeof(buf)))
577  {
578  GNUNET_break(0);
579  return GNUNET_OK;
580  }
581  GNUNET_CONFIGURATION_set_value_string(ah->cfg, "nat", "INTERNAL_ADDRESS",
582  buf);
584  _("Detected internal network address `%s'.\n"),
585  buf);
586 
587 
589 
590  /* Check if our internal IP is the same as the External detect by STUN*/
591  if (ah->stun_ip && (strcmp(buf, ah->stun_ip) == 0))
592  {
594  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "A internal IP is the sameas the external");
595  /* No need to continue*/
596  return GNUNET_SYSERR;
597  }
598 
599  /* no need to continue iteration if we found the default */
600  if (!isDefault)
601  return GNUNET_OK;
602  else
603  return GNUNET_SYSERR;
604 }
605 
606 
612 static void
614 {
615  ah->have_v6 = GNUNET_NO;
616  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
618 
619  GNUNET_CONFIGURATION_set_value_string(ah->cfg, "nat", "DISABLEV6",
620  (GNUNET_YES == ah->have_v6) ? "NO" : "YES");
621  next_phase(ah);
622 }
623 
624 
632 static void
634  enum GNUNET_MQ_Error error)
635 {
636  struct GNUNET_NAT_AutoHandle *ah = cls;
637 
638  GNUNET_MQ_destroy(ah->mq);
639  ah->mq = NULL;
640  /* wait a bit first? */
641  next_phase(ah);
642 }
643 
644 
650 static void
652 {
653  struct GNUNET_NAT_TestMessage *msg;
654  struct GNUNET_MQ_Envelope *env;
655 
656  if (!ah->stun_ip)
657  {
659  "We don't have a STUN IP");
660  next_phase(ah);
661  return;
662  }
663 
665  "Asking gnunet-nat-server to connect to `%s'\n",
666  ah->stun_ip);
667  ah->mq = GNUNET_CLIENT_connect(ah->cfg,
668  "gnunet-nat-server",
669  NULL,
671  ah);
672  if (NULL == ah->mq)
673  {
675  _("Failed to connect to `gnunet-nat-server'\n"));
676  next_phase(ah);
677  return;
678  }
679  env = GNUNET_MQ_msg(msg,
681  msg->dst_ipv4 = inet_addr(ah->stun_ip);
682  msg->dport = htons(ah->stun_port);
683  msg->data = port;
684  msg->is_tcp = htonl((uint32_t)GNUNET_NO);
685  GNUNET_MQ_send(ah->mq,
686  env);
687  if (NULL != ltask4)
688  {
689  GNUNET_SCHEDULER_cancel(ltask4);
691  lsock4,
692  &do_udp_read,
693  ah);
694  }
695 }
696 
697 
703 static void
705 {
706  int have_upnpc;
707 
708  if (GNUNET_NAT_ERROR_SUCCESS != ah->ret)
709  next_phase(ah);
710 
711  // test if upnpc is available
712  have_upnpc = (GNUNET_SYSERR !=
713  GNUNET_OS_check_helper_binary("upnpc", GNUNET_NO, NULL));
714  //FIXME: test if upnpc is actually working, that is, if transports start to work once we use UPnP
716  (have_upnpc)
717  ? _("upnpc found, enabling its use\n")
718  : _("upnpc not found\n"));
719  GNUNET_CONFIGURATION_set_value_string(ah->cfg, "nat", "ENABLE_UPNP",
720  (GNUNET_YES == have_upnpc) ? "YES" : "NO");
721  next_phase(ah);
722 }
723 
724 
730 static void
732 {
733  int ext_ip;
734  int nated;
735  int binary;
736  char *tmp;
737  char *helper;
738 
739  ext_ip = GNUNET_NO;
740  nated = GNUNET_NO;
741  binary = GNUNET_NO;
742 
743  tmp = NULL;
744  helper = GNUNET_OS_get_libexec_binary_path("gnunet-helper-nat-server");
745  if ((GNUNET_OK ==
747  "nat",
748  "EXTERNAL_ADDRESS",
749  &tmp)) &&
750  (0 < strlen(tmp)))
751  {
752  ext_ip = GNUNET_OK;
754  _("test_icmp_server not possible, as we have no public IPv4 address\n"));
755  }
756  else
757  goto err;
758 
759  if (GNUNET_YES ==
761  "nat",
762  "BEHIND_NAT"))
763  {
764  nated = GNUNET_YES;
766  _("test_icmp_server not possible, as we are not behind NAT\n"));
767  }
768  else
769  goto err;
770 
771  if (GNUNET_YES ==
773  GNUNET_YES,
774  "-d 127.0.0.1"))
775  {
776  binary = GNUNET_OK; // use localhost as source for that one udp-port, ok for testing
778  _("No working gnunet-helper-nat-server found\n"));
779  }
780 err:
782  GNUNET_free(helper);
783 
784  if ((GNUNET_OK == ext_ip) &&
785  (GNUNET_YES == nated) &&
786  (GNUNET_OK == binary))
788  ah);
789  else
790  next_phase(ah);
791 }
792 
793 
799 static void
801 {
802  char *tmp;
803  char *helper;
804 
805  tmp = NULL;
806  helper = GNUNET_OS_get_libexec_binary_path("gnunet-helper-nat-client");
807  if ((GNUNET_OK ==
809  "nat",
810  "INTERNAL_ADDRESS",
811  &tmp)) &&
812  (0 < strlen(tmp)))
813  {
815  _("test_icmp_client not possible, as we have no internal IPv4 address\n"));
816  }
817  else
818  goto err;
819 
820  if (GNUNET_YES !=
822  "nat",
823  "BEHIND_NAT"))
824  {
826  _("test_icmp_server not possible, as we are not behind NAT\n"));
827  }
828  else
829  goto err;
830 
831  if (GNUNET_YES ==
833  GNUNET_YES,
834  "-d 127.0.0.1 127.0.0.2 42"))
835  {
836  // none of these parameters are actually used in privilege testing mode
838  _("No working gnunet-helper-nat-server found\n"));
839  }
840 err:
842  GNUNET_free(helper);
843 
844  next_phase(ah);
845 }
846 
847 
851 static void
853 {
854  struct GNUNET_CONFIGURATION_Handle *diff;
855 
856  ah->phase++;
857  switch (ah->phase)
858  {
859  case AUTO_INIT:
860  GNUNET_assert(0);
861  break;
862 
863  case AUTO_EXTERNAL_IP:
865  "Will run AUTO_EXTERNAL_IP\n");
866  test_external_ip(ah);
867  break;
868 
869  case AUTO_STUN:
871  "Will run AUTO_STUN\n");
872  test_stun(ah);
873  break;
874 
875  case AUTO_LOCAL_IP:
877  "Will run AUTO_LOCAL_IP\n");
878  test_local_ip(ah);
879  break;
880 
881  case AUTO_NAT_PUNCHED:
883  "Will run AUTO_NAT_PUNCHED\n");
884  test_nat_punched(ah);
885  break;
886 
887  case AUTO_UPNPC:
889  "Will run AUTO_UPNPC\n");
890  test_upnpc(ah);
891  break;
892 
893  case AUTO_ICMP_SERVER:
895  "Will run AUTO_ICMP_SERVER\n");
896  test_icmp_server(ah);
897  break;
898 
899  case AUTO_ICMP_CLIENT:
901  "Will run AUTO_ICMP_CLIENT\n");
902  test_icmp_client(ah);
903  break;
904 
905  case AUTO_DONE:
907  "Done with tests\n");
908  if (!ah->internal_ip_is_public)
909  {
911  "nat",
912  "BEHIND_NAT",
913  "YES");
914 
915  if (ah->connected_back)
916  {
918  "nat",
919  "PUNCHED_NAT",
920  "YES");
921  }
922  else
923  {
925  "nat",
926  "PUNCHED_NAT",
927  "NO");
928  }
929 
930  if (ah->stun_ip)
931  {
933  "nat",
934  "EXTERNAL_ADDRESS",
935  ah->stun_ip);
936  if (ah->connected_back)
937  {
940  "nat",
941  "USE_STUN",
942  "YES");
943  }
944  else
945  {
948  "nat",
949  "USE_STUN",
950  "NO");
951  }
952  }
953  if (0 != ah->stun_port)
954  {
956  "transport-udp",
957  "ADVERTISED_PORT",
958  ah->stun_port);
959  }
960  }
961  else
962  {
963  //The internal IP is the same as public, but we didn't got a incoming connection
964  if (ah->connected_back)
965  {
968  "nat",
969  "BEHIND_NAT",
970  "NO");
971  }
972  else
973  {
975  "nat",
976  "BEHIND_NAT",
977  "YES");
979  if (ah->stun_ip)
980  {
982  "nat",
983  "EXTERNAL_ADDRESS",
984  ah->stun_ip);
985  }
986  if (0 != ah->stun_port)
987  {
989  "transport-udp",
990  "ADVERTISED_PORT",
991  ah->stun_port);
992  }
993  }
994  }
995 
997  ah->cfg);
998 
999 
1000  ah->fin_cb(ah->fin_cb_cls,
1001  diff,
1002  ah->ret,
1003  ah->type);
1006  }
1007 }
1008 
1009 
1019 struct GNUNET_NAT_AutoHandle *
1021  GNUNET_NAT_AutoResultCallback cb,
1022  void *cb_cls)
1023 {
1024  struct GNUNET_NAT_AutoHandle *ah;
1025 
1026  ah = GNUNET_new(struct GNUNET_NAT_AutoHandle);
1027  ah->fin_cb = cb;
1028  ah->fin_cb_cls = cb_cls;
1030  ah->cfg = GNUNET_CONFIGURATION_dup(cfg);
1032 
1033  /* never use loopback addresses if user wanted autoconfiguration */
1035  "nat",
1036  "USE_LOCALADDR",
1037  "NO");
1038 
1039  next_phase(ah);
1040  return ah;
1041 }
1042 
1043 
1049 void
1051 {
1052  if (NULL != ah->tst)
1053  {
1055  ah->tst = NULL;
1056  }
1057  if (NULL != ah->eh)
1058  {
1059  GNUNET_NAT_mini_get_external_ipv4_cancel(ah->eh);
1060  ah->eh = NULL;
1061  }
1062  if (NULL != ah->mq)
1063  {
1064  GNUNET_MQ_destroy(ah->mq);
1065  ah->mq = NULL;
1066  }
1067  if (NULL != ah->task)
1068  {
1070  ah->task = NULL;
1071  }
1074  GNUNET_free(ah);
1075 }
1076 
1077 
1078 /* end of nat_auto.c */
Test if ICMP client works.
const struct GNUNET_SCHEDULER_TaskContext * GNUNET_SCHEDULER_get_task_context(void)
Obtain the reasoning why the current task was started.
Definition: scheduler.c:737
Last phase, we&#39;re done.
Initial start value.
static void test_stun(struct GNUNET_NAT_AutoHandle *ah)
Determine our external IPv4 address and port using an external STUN server.
#define LOG(kind,...)
Test if ICMP server works.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
enum GNUNET_NAT_StatusCode ret
Error code for better debugging and user feedback.
static struct GNUNET_SCHEDULER_Task * ltask4
The listen task ID for IPv4.
int 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.
Opaque handle to cancel "GNUNET_NAT_mini_get_external_ipv4" operation.
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:209
uint32_t dst_ipv4
IPv4 target IP address.
Definition: nat.h:48
struct GNUNET_SCHEDULER_Task * task
Task identifier for the timeout.
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:900
The reading socket is ready.
Context information passed to each scheduler task.
GNUNET_MQ_Error
Error codes for the queue.
static void do_udp_read(void *cls)
Activity on our incoming socket.
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:775
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
int32_t is_tcp
GNUNET_YES for TCP, GNUNET_NO for UDP.
Definition: nat.h:63
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition: scheduler.c:410
int 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:474
static void test_nat_punched(struct GNUNET_NAT_AutoHandle *ah)
Test if NAT has been punched.
struct GNUNET_NAT_ExternalHandle * eh
Handle for active &#39;GNUNET_NAT_mini_get_external_ipv4&#39;-operation.
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.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
#define GNUNET_MESSAGE_TYPE_NAT_TEST
Message to ask NAT server to perform traversal test.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
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 ...
int GNUNET_OS_check_helper_binary(const char *binary, int check_suid, const char *params)
Check whether an executable exists and possibly if the suid bit is set on the file.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
void GNUNET_OS_network_interfaces_list(GNUNET_OS_NetworkInterfaceProcessor proc, void *proc_cls)
Enumerate all network interfaces.
Definition: os_network.c:388
enum GNUNET_NAT_Type type
Situation of the NAT.
static void reversal_test(void *cls)
Main function for the connection reversal test.
We are under a NAT but cannot traverse it.
enum GNUNET_SCHEDULER_Reason reason
Reason why the task is run now.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
uint16_t dport
Port to use, 0 to send dummy ICMP response.
Definition: nat.h:53
Handle to auto-configuration in progress.
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).
Could not determine interface with internal/local network address.
void * fin_cb_cls
Closure for fin_cb.
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
static void mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
We got disconnected from the NAT server.
static struct GNUNET_NETWORK_Handle * bind_v4()
Create an IPv4 listen socket bound to our port.
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.
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:581
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:1264
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.
int internal_ip_is_public
Internal IP is the same as the public one ?
GNUNET_NAT_StatusCode
Error Types for the NAT subsystem (which can then later be converted/resolved to a string) ...
void GNUNET_CONFIGURATION_destroy(struct GNUNET_CONFIGURATION_Handle *cfg)
Destroy configuration object.
static char buf[2048]
static int result
Global testing status.
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.
char * stun_ip
Address detected by STUN.
static unsigned long long port
The port the test service is running on (default 7895)
AutoPhase
Phases of the auto configuration.
static void next_phase(struct GNUNET_NAT_AutoHandle *ah)
Run the next phase of the auto test.
Test our external IP.
static void test_icmp_server(struct GNUNET_NAT_AutoHandle *ah)
Test if ICMP server is working.
static char * stun_server
int 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_NAT_test_stop(struct GNUNET_NAT_Test *tst)
Stop an active NAT test.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
int connected_back
Did the external server connected back ?
static void test_local_ip(struct GNUNET_NAT_AutoHandle *ah)
Determine our local IP addresses; detect internal IP & IPv6-support.
struct GNUNET_MQ_Handle * mq
Message queue to the gnunet-nat-server.
const char * name
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.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static void stop_stun()
Function that terminates the test.
struct GNUNET_NAT_Test * tst
Handle to the active NAT test.
static struct GNUNET_NETWORK_Handle * ls
Listen socket for STUN processing.
Definition: gnunet-nat.c:85
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
Handle to a NAT test.
#define NAT_SERVER_TIMEOUT
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_dup(const struct GNUNET_CONFIGURATION_Handle *cfg)
Duplicate an existing configuration object.
static void result_callback(void *cls, enum GNUNET_NAT_StatusCode ret)
Function called by NAT to report the outcome of the nat-test.
Request to test NAT traversal, sent to the gnunet-nat-server (not the service!).
Definition: nat.h:39
static void test_external_ip(struct GNUNET_NAT_AutoHandle *ah)
Determine our external IPv4 address.
Handle to a message queue.
Definition: mq.c:84
Test if NAT was punched.
static struct GNUNET_NAT_AUTO_AutoHandle * ah
Handle to ongoing autoconfiguration.
Messages for interaction with gnunet-nat-server and gnunet-nat-service.
static void process_stun_reply(struct sockaddr_in *answer, struct GNUNET_NAT_AutoHandle *ah)
static void test_icmp_client(struct GNUNET_NAT_AutoHandle *ah)
Test if ICMP client is working.
configuration data
Definition: configuration.c:83
Test if UPnP is working.
struct GNUNET_CONFIGURATION_Handle * initial_cfg
Original configuration (used to calculate differences)
#define GNUNET_log(kind,...)
We have a direct connection.
Entry in list of pending tasks.
Definition: scheduler.c:131
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 ...
handle to a socket
Definition: network.c:46
GNUNET_NAT_AutoResultCallback fin_cb
Function to call when done.
"no valid address was returned by `external-ip&#39;"
enum AutoPhase phase
Where are we in the test?
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:821
#define GNUNET_YES
Definition: gnunet_common.h:77
#define TIMEOUT
How long do we wait for the NAT test to report success?
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:1467
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:351
static void request_callback(void *cls, enum GNUNET_NAT_StatusCode result)
GNUNET_NAT_Type
What the situation of the NAT connectivity.
int upnp_set_external_address
UPnP already set the external ip address ?
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:1017
int 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".
Test our external IP.
static void test_upnpc(struct GNUNET_NAT_AutoHandle *ah)
Test if UPnPC works.
We can traverse using STUN.
Test our internal IP.
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.
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:548
static struct GNUNET_NETWORK_Handle * lsock4
The listen socket of the service for IPv4.
void GNUNET_RESOLVER_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Create the connection to the resolver service.
Definition: resolver_api.c:252
void GNUNET_NAT_autoconfig_cancel(struct GNUNET_NAT_AutoHandle *ah)
Abort autoconfiguration.
struct GNUNET_CONFIGURATION_Handle * cfg
Current configuration (with updates from previous phases)
#define GNUNET_free(ptr)
Wrapper around free.
uint16_t data
Data to send OR advertised-port (in NBO) to use for dummy ICMP.
Definition: nat.h:58
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:900
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956