GNUnet debian-0.24.3-29-g453fda2cf
 
Loading...
Searching...
No Matches
gnunet-service-nat-auto_legacy.c File Reference
#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_resolver_service.h"
#include "gnunet_nat_lib.h"
#include "nat.h"
Include dependency graph for gnunet-service-nat-auto_legacy.c:

Go to the source code of this file.

Data Structures

struct  GNUNET_NAT_AutoHandle
 Handle to auto-configuration in progress. More...
 

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "nat", __VA_ARGS__)
 
#define TIMEOUT   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15)
 How long do we wait for the NAT test to report success?
 
#define NAT_SERVER_TIMEOUT
 

Enumerations

enum  AutoPhase {
  AUTO_INIT = 0 , AUTO_EXTERNAL_IP , AUTO_STUN , AUTO_LOCAL_IP ,
  AUTO_NAT_PUNCHED , AUTO_UPNPC , AUTO_ICMP_SERVER , AUTO_ICMP_CLIENT ,
  AUTO_DONE
}
 Phases of the auto configuration. More...
 

Functions

static void next_phase (struct GNUNET_NAT_AutoHandle *ah)
 Run the next phase of the auto test.
 
static void process_stun_reply (struct sockaddr_in *answer, struct GNUNET_NAT_AutoHandle *ah)
 
static void stop_stun ()
 Function that terminates the test.
 
static void do_udp_read (void *cls)
 Activity on our incoming socket.
 
static struct GNUNET_NETWORK_Handlebind_v4 ()
 Create an IPv4 listen socket bound to our port.
 
static void request_callback (void *cls, enum GNUNET_NAT_StatusCode result)
 
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 reversal_test (void *cls)
 Main function for the connection reversal test.
 
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 void test_external_ip (struct GNUNET_NAT_AutoHandle *ah)
 Determine our external IPv4 address.
 
static void test_stun (struct GNUNET_NAT_AutoHandle *ah)
 Determine our external IPv4 address and port using an external STUN server.
 
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 void test_local_ip (struct GNUNET_NAT_AutoHandle *ah)
 Determine our local IP addresses; detect internal IP & IPv6-support.
 
static void mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
 We got disconnected from the NAT server.
 
static void test_nat_punched (struct GNUNET_NAT_AutoHandle *ah)
 Test if NAT has been punched.
 
static void test_upnpc (struct GNUNET_NAT_AutoHandle *ah)
 Test if UPnPC works.
 
static void test_icmp_server (struct GNUNET_NAT_AutoHandle *ah)
 Test if ICMP server is working.
 
static void test_icmp_client (struct GNUNET_NAT_AutoHandle *ah)
 Test if ICMP client is working.
 
struct GNUNET_NAT_AutoHandleGNUNET_NAT_autoconfig_start (const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_NAT_AutoResultCallback cb, void *cb_cls)
 Start auto-configuration routine.
 
void GNUNET_NAT_autoconfig_cancel (struct GNUNET_NAT_AutoHandle *ah)
 Abort autoconfiguration.
 

Variables

static struct GNUNET_NETWORK_Handlelsock4
 The listen socket of the service for IPv4.
 
static struct GNUNET_SCHEDULER_Taskltask4
 The listen task ID for IPv4.
 
static unsigned long long port = 7895
 The port the test service is running on (default 7895)
 
static char * stun_server = "stun.ekiga.net"
 
static unsigned int stun_port = 3478
 

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "nat", __VA_ARGS__)

Definition at line 33 of file gnunet-service-nat-auto_legacy.c.

◆ TIMEOUT

How long do we wait for the NAT test to report success?

Definition at line 39 of file gnunet-service-nat-auto_legacy.c.

◆ NAT_SERVER_TIMEOUT

#define NAT_SERVER_TIMEOUT
Value:
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition time.c:486

Definition at line 41 of file gnunet-service-nat-auto_legacy.c.

47{
51 AUTO_INIT = 0,
52
57
62
67
72
77
82
87
92};
93
94
99{
103 struct GNUNET_NAT_Test *tst;
104
108 GNUNET_NAT_AutoResultCallback fin_cb;
109
113 void *fin_cb_cls;
114
119
124
129
134
138 struct GNUNET_MQ_Handle *mq;
139
143 enum AutoPhase phase;
144
149
153 int have_v6;
154
159
163 int connected_back;
164
168 char *stun_ip;
169
170 unsigned int stun_port;
171
176
181};
182
183
187static struct GNUNET_NETWORK_Handle *lsock4;
188
192static struct GNUNET_SCHEDULER_Task *ltask4;
193
197static unsigned long long port = 7895;
198
199static char *stun_server = "stun.ekiga.net";
200
201static unsigned int stun_port = 3478;
202
203
209static void
211
212
213static void
214process_stun_reply (struct sockaddr_in *answer,
216{
217 ah->stun_ip = inet_ntoa (answer->sin_addr);
218 ah->stun_port = ntohs (answer->sin_port);
220 "External IP is: %s , with port %u\n",
221 ah->stun_ip,
222 ah->stun_port);
223 next_phase (ah);
224}
225
226
230static void
231stop_stun ()
232{
234 "Stopping STUN and quitting...\n");
235 /* Clean task */
236 if (NULL != ltask4)
237 {
239 ltask4 = NULL;
240 }
241 /* Clean socket */
242 if (NULL != lsock4)
243 {
245 lsock4 = NULL;
246 }
247}
248
249
256static void
257do_udp_read (void *cls)
258{
259 struct GNUNET_NAT_AutoHandle *ah = cls;
260 unsigned char reply_buf[1024];
261 ssize_t rlen;
262 struct sockaddr_in answer;
263 const struct GNUNET_SCHEDULER_TaskContext *tc;
264
268 lsock4)))
269 {
271 reply_buf,
272 sizeof(reply_buf));
273
274 // Lets handle the packet
275 memset (&answer, 0, sizeof(struct sockaddr_in));
276 if (ah->phase == AUTO_NAT_PUNCHED)
277 {
278 // Destroy the connection
281 "The external server was able to connect back");
282 ah->connected_back = GNUNET_YES;
283 next_phase (ah);
284 }
285 else
286 {
287 if (GNUNET_OK ==
288 GNUNET_NAT_stun_handle_packet (reply_buf, rlen, &answer))
289 {
290 // Process the answer
291 process_stun_reply (&answer, ah);
292 }
293 else
294 {
295 next_phase (ah);
296 }
297 }
298 }
299 else
300 {
302 "TIMEOUT while waiting for an answer\n");
303 if (ah->phase == AUTO_NAT_PUNCHED)
304 {
305 stop_stun ();
306 }
307
308 next_phase (ah);
309 }
310}
311
312
318static struct GNUNET_NETWORK_Handle *
319bind_v4 ()
320{
322 struct sockaddr_in sa4;
323 int eno;
324
325 memset (&sa4, 0, sizeof(sa4));
326 sa4.sin_family = AF_INET;
327 sa4.sin_port = htons (port);
328#if HAVE_SOCKADDR_IN_SIN_LEN
329 sa4.sin_len = sizeof(sa4);
330#endif
332 SOCK_DGRAM,
333 0);
334 if (NULL == ls)
335 return NULL;
336 if (GNUNET_OK !=
337 GNUNET_NETWORK_socket_bind (ls, (const struct sockaddr *) &sa4,
338 sizeof(sa4)))
339 {
340 eno = errno;
342 errno = eno;
343 return NULL;
344 }
345 return ls;
346}
347
348
349static void
350request_callback (void *cls,
352{
353 // struct GNUNET_NAT_AutoHandle *ah = cls;
354
356 "Request callback: stop and quit\n");
357 stop_stun ();
358
359 // next_phase (ah); FIXME this always will be NULL, as called in test_stun()
360}
361
362
371static void
372result_callback (void *cls,
374{
375 struct GNUNET_NAT_AutoHandle *ah = cls;
376
379 ah->tst = NULL;
380 ah->ret = ret;
383 ? _ ("NAT traversal with ICMP Server succeeded.\n")
384 : _ ("NAT traversal with ICMP Server failed.\n"));
385 GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "ENABLE_ICMP_SERVER",
387 "NO" : "YES");
388 next_phase (ah);
389}
390
391
397static void
398reversal_test (void *cls)
399{
400 struct GNUNET_NAT_AutoHandle *ah = cls;
401
402 ah->task = NULL;
404 _ ("Testing connection reversal with ICMP server.\n"));
408}
409
410
419static void
420set_external_ipv4 (void *cls,
421 const struct in_addr *addr,
423{
424 struct GNUNET_NAT_AutoHandle *ah = cls;
425 char buf[INET_ADDRSTRLEN];
426
427 ah->eh = NULL;
428 ah->ret = ret;
430 {
431 next_phase (ah);
432 return;
433 }
434 /* enable 'behind nat' */
436 _ ("Detected external IP `%s'\n"),
437 inet_ntop (AF_INET,
438 addr,
439 buf,
440 sizeof(buf)));
441 GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "BEHIND_NAT", "YES");
442
443 /* set external IP address */
444 if (NULL == inet_ntop (AF_INET, addr, buf, sizeof(buf)))
445 {
446 GNUNET_break (0);
447 /* actually, this should never happen, as the caller already executed just
448 * this check, but for consistency (eg: future changes in the caller)
449 * we still need to report this error...
450 */
452 next_phase (ah);
453 return;
454 }
455 GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "EXTERNAL_ADDRESS",
456 buf);
457 ah->upnp_set_external_address = GNUNET_YES;
458 next_phase (ah);
459}
460
461
467static void
469{
470 if (GNUNET_NAT_ERROR_SUCCESS != ah->ret)
471 next_phase (ah);
472
473 // FIXME: CPS?
474 /* try to detect external IP */
475 ah->eh = GNUNET_NAT_mini_get_external_ipv4 (TIMEOUT,
477}
478
479
485static void
487{
488 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Running STUN test\n");
489
490 /* Get port from the configuration */
491 if (GNUNET_OK !=
493 "transport-udp",
494 "PORT",
495 &port))
496 {
497 port = 2086;
498 }
499
500 // Lets create the socket
501 lsock4 = bind_v4 ();
502 if (NULL == lsock4)
503 {
505 next_phase (ah);
506 return;
507 }
508 else
509 {
510 // Lets call our function now when it accepts
512 lsock4,
514 ah);
515 }
516
517
519 "STUN service listens on port %u\n",
520 (unsigned int) port);
521 if (GNUNET_NO ==
523 stun_port,
524 lsock4,
526 NULL))
527 {
528 /*An error happened*/
529 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "STUN error, stopping\n");
530 stop_stun ();
531 next_phase (ah);
532 }
533}
534
535
549static int
550process_if (void *cls,
551 const char *name,
552 int isDefault,
553 const struct sockaddr *addr,
554 const struct sockaddr *broadcast_addr,
555 const struct sockaddr *netmask,
556 socklen_t addrlen)
557{
558 struct GNUNET_NAT_AutoHandle *ah = cls;
559 const struct sockaddr_in *in;
560 char buf[INET_ADDRSTRLEN];
561
562
563 if ((sizeof(struct sockaddr_in6) == addrlen) &&
564 (0 != GNUNET_memcmp (&in6addr_loopback, &((const struct
565 sockaddr_in6 *) addr)->
566 sin6_addr)) &&
567 (! IN6_IS_ADDR_LINKLOCAL (&((const struct
568 sockaddr_in6 *) addr)->sin6_addr)))
569 {
570 ah->have_v6 = GNUNET_YES;
572 _ (
573 "This system has a global IPv6 address, setting IPv6 to supported.\n"));
574
575 return GNUNET_OK;
576 }
577 if (addrlen != sizeof(struct sockaddr_in))
578 return GNUNET_OK;
579 in = (const struct sockaddr_in *) addr;
580
581
582 /* set internal IP address */
583 if (NULL == inet_ntop (AF_INET, &in->sin_addr, buf, sizeof(buf)))
584 {
585 GNUNET_break (0);
586 return GNUNET_OK;
587 }
588 GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "INTERNAL_ADDRESS",
589 buf);
591 _ ("Detected internal network address `%s'.\n"),
592 buf);
593
594
596
597 /* Check if our internal IP is the same as the External detect by STUN*/
598 if (ah->stun_ip && (strcmp (buf, ah->stun_ip) == 0))
599 {
600 ah->internal_ip_is_public = GNUNET_YES;
602 "A internal IP is the sameas the external");
603 /* No need to continue*/
604 return GNUNET_SYSERR;
605 }
606
607 /* no need to continue iteration if we found the default */
608 if (! isDefault)
609 return GNUNET_OK;
610 else
611 return GNUNET_SYSERR;
612}
613
614
620static void
622{
623 ah->have_v6 = GNUNET_NO;
624 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
626
627 GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "DISABLEV6",
628 (GNUNET_YES == ah->have_v6) ? "NO" :
629 "YES");
630 next_phase (ah);
631}
632
633
641static void
642mq_error_handler (void *cls,
643 enum GNUNET_MQ_Error error)
644{
645 struct GNUNET_NAT_AutoHandle *ah = cls;
646
648 ah->mq = NULL;
649 /* wait a bit first? */
650 next_phase (ah);
651}
652
653
659static void
661{
663 struct GNUNET_MQ_Envelope *env;
664
665 if (! ah->stun_ip)
666 {
668 "We don't have a STUN IP");
669 next_phase (ah);
670 return;
671 }
672
674 "Asking gnunet-nat-server to connect to `%s'\n",
675 ah->stun_ip);
677 "gnunet-nat-server",
678 NULL,
680 ah);
681 if (NULL == ah->mq)
682 {
684 _ ("Failed to connect to `gnunet-nat-server'\n"));
685 next_phase (ah);
686 return;
687 }
690 msg->dst_ipv4 = inet_addr (ah->stun_ip);
691 msg->dport = htons (ah->stun_port);
692 msg->data = port;
693 msg->is_tcp = htonl ((uint32_t) GNUNET_NO);
695 env);
696 if (NULL != ltask4)
697 {
700 lsock4,
702 ah);
703 }
704}
705
706
712static void
714{
715 int have_upnpc;
716
717 if (GNUNET_NAT_ERROR_SUCCESS != ah->ret)
718 next_phase (ah);
719
720 // test if upnpc is available
721 have_upnpc = (GNUNET_SYSERR !=
723 // FIXME: test if upnpc is actually working, that is, if transports start to work once we use UPnP
725 (have_upnpc)
726 ? _ ("upnpc found, enabling its use\n")
727 : _ ("upnpc not found\n"));
728 GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "ENABLE_UPNP",
729 (GNUNET_YES == have_upnpc) ? "YES" :
730 "NO");
731 next_phase (ah);
732}
733
734
740static void
742{
743 int ext_ip;
744 int nated;
745 int binary;
746 char *tmp;
747 char *helper;
748
749 ext_ip = GNUNET_NO;
750 nated = GNUNET_NO;
751 binary = GNUNET_NO;
752
753 tmp = NULL;
754 helper = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-nat-server");
755 if ((GNUNET_OK ==
757 "nat",
758 "EXTERNAL_ADDRESS",
759 &tmp)) &&
760 (0 < strlen (tmp)))
761 {
762 ext_ip = GNUNET_OK;
764 _ (
765 "test_icmp_server not possible, as we have no public IPv4 address\n"));
766 }
767 else
768 goto err;
769
770 if (GNUNET_YES ==
772 "nat",
773 "BEHIND_NAT"))
774 {
775 nated = GNUNET_YES;
777 _ (
778 "test_icmp_server not possible, as we are not behind NAT\n"));
779 }
780 else
781 goto err;
782
783 if (GNUNET_YES ==
786 "-d 127.0.0.1"))
787 {
788 binary = GNUNET_OK; // use localhost as source for that one udp-port, ok for testing
790 _ ("No working gnunet-helper-nat-server found\n"));
791 }
792err:
793 GNUNET_free (tmp);
794 GNUNET_free (helper);
795
796 if ((GNUNET_OK == ext_ip) &&
797 (GNUNET_YES == nated) &&
798 (GNUNET_OK == binary))
800 ah);
801 else
802 next_phase (ah);
803}
804
805
811static void
813{
814 char *tmp;
815 char *helper;
816
817 tmp = NULL;
818 helper = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-nat-client");
819 if ((GNUNET_OK ==
821 "nat",
822 "INTERNAL_ADDRESS",
823 &tmp)) &&
824 (0 < strlen (tmp)))
825 {
827 _ (
828 "test_icmp_client not possible, as we have no internal IPv4 address\n"));
829 }
830 else
831 goto err;
832
833 if (GNUNET_YES !=
835 "nat",
836 "BEHIND_NAT"))
837 {
839 _ (
840 "test_icmp_server not possible, as we are not behind NAT\n"));
841 }
842 else
843 goto err;
844
845 if (GNUNET_YES ==
848 "-d 127.0.0.1 127.0.0.2 42"))
849 {
850 // none of these parameters are actually used in privilege testing mode
852 _ ("No working gnunet-helper-nat-server found\n"));
853 }
854err:
855 GNUNET_free (tmp);
856 GNUNET_free (helper);
857
858 next_phase (ah);
859}
860
861
865static void
867{
868 struct GNUNET_CONFIGURATION_Handle *diff;
869
870 ah->phase++;
871 switch (ah->phase)
872 {
873 case AUTO_INIT:
874 GNUNET_assert (0);
875 break;
876
877 case AUTO_EXTERNAL_IP:
879 "Will run AUTO_EXTERNAL_IP\n");
881 break;
882
883 case AUTO_STUN:
885 "Will run AUTO_STUN\n");
886 test_stun (ah);
887 break;
888
889 case AUTO_LOCAL_IP:
891 "Will run AUTO_LOCAL_IP\n");
893 break;
894
895 case AUTO_NAT_PUNCHED:
897 "Will run AUTO_NAT_PUNCHED\n");
899 break;
900
901 case AUTO_UPNPC:
903 "Will run AUTO_UPNPC\n");
904 test_upnpc (ah);
905 break;
906
907 case AUTO_ICMP_SERVER:
909 "Will run AUTO_ICMP_SERVER\n");
911 break;
912
913 case AUTO_ICMP_CLIENT:
915 "Will run AUTO_ICMP_CLIENT\n");
917 break;
918
919 case AUTO_DONE:
921 "Done with tests\n");
922 if (! ah->internal_ip_is_public)
923 {
925 "nat",
926 "BEHIND_NAT",
927 "YES");
928
929 if (ah->connected_back)
930 {
932 "nat",
933 "PUNCHED_NAT",
934 "YES");
935 }
936 else
937 {
939 "nat",
940 "PUNCHED_NAT",
941 "NO");
942 }
943
944 if (ah->stun_ip)
945 {
947 "nat",
948 "EXTERNAL_ADDRESS",
949 ah->stun_ip);
950 if (ah->connected_back)
951 {
954 "nat",
955 "USE_STUN",
956 "YES");
957 }
958 else
959 {
962 "nat",
963 "USE_STUN",
964 "NO");
965 }
966 }
967 if (0 != ah->stun_port)
968 {
970 "transport-udp",
971 "ADVERTISED_PORT",
972 ah->stun_port);
973 }
974 }
975 else
976 {
977 // The internal IP is the same as public, but we didn't got a incoming connection
978 if (ah->connected_back)
979 {
982 "nat",
983 "BEHIND_NAT",
984 "NO");
985 }
986 else
987 {
989 "nat",
990 "BEHIND_NAT",
991 "YES");
993 if (ah->stun_ip)
994 {
996 "nat",
997 "EXTERNAL_ADDRESS",
998 ah->stun_ip);
999 }
1000 if (0 != ah->stun_port)
1001 {
1003 "transport-udp",
1004 "ADVERTISED_PORT",
1005 ah->stun_port);
1006 }
1007 }
1008 }
1009
1010 diff = GNUNET_CONFIGURATION_get_diff (ah->initial_cfg,
1011 ah->cfg);
1012
1013
1014 ah->fin_cb (ah->fin_cb_cls,
1015 diff,
1016 ah->ret,
1017 ah->type);
1020 }
1021}
1022
1023
1033struct GNUNET_NAT_AutoHandle *
1035 GNUNET_NAT_AutoResultCallback cb,
1036 void *cb_cls)
1037{
1038 struct GNUNET_NAT_AutoHandle *ah;
1039
1041 ah->fin_cb = cb;
1042 ah->fin_cb_cls = cb_cls;
1045 ah->initial_cfg = GNUNET_CONFIGURATION_dup (cfg);
1046
1047 /* never use loopback addresses if user wanted autoconfiguration */
1049 "nat",
1050 "USE_LOCALADDR",
1051 "NO");
1052
1053 next_phase (ah);
1054 return ah;
1055}
1056
1057
1063void
1065{
1066 if (NULL != ah->tst)
1067 {
1068 GNUNET_NAT_test_stop (ah->tst);
1069 ah->tst = NULL;
1070 }
1071 if (NULL != ah->eh)
1072 {
1073 GNUNET_NAT_mini_get_external_ipv4_cancel (ah->eh);
1074 ah->eh = NULL;
1075 }
1076 if (NULL != ah->mq)
1077 {
1079 ah->mq = NULL;
1080 }
1081 if (NULL != ah->task)
1082 {
1084 ah->task = NULL;
1085 }
1087 GNUNET_CONFIGURATION_destroy (ah->initial_cfg);
1088 GNUNET_free (ah);
1089}
1090
1091
1092/* end of nat_auto.c */
struct GNUNET_MessageHeader * msg
Definition 005.c:2
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
static int ret
Final status code.
Definition gnunet-arm.c:93
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition gnunet-arm.c:108
static char * name
Name (label) of the records to list.
static struct GNUNET_NAT_AUTO_AutoHandle * ah
Handle to ongoing autoconfiguration.
void GNUNET_NAT_test_stop(struct GNUNET_NAT_Test *tst)
Stop an active NAT test.
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).
static struct GNUNET_NETWORK_Handle * ls
Listen socket for STUN processing.
Definition gnunet-nat.c:85
static int result
Global testing status.
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 struct GNUNET_NETWORK_Handle * bind_v4()
Create an IPv4 listen socket bound to our port.
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.
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 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.
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:1060
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.
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_dup(const struct GNUNET_CONFIGURATION_Handle *cfg)
Duplicate an existing configuration object.
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.
#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:305
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition mq.c:700
GNUNET_NAT_StatusCode
Error Types for the NAT subsystem (which can then later be converted/resolved to a string)
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.
GNUNET_NAT_Type
What the situation of the NAT connectivity.
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:601
@ 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:717
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition network.c:833
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:950
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.
char * GNUNET_OS_get_libexec_binary_path(const struct GNUNET_OS_ProjectData *pd, const char *progname)
Given the name of a gnunet-helper, gnunet-service or gnunet-daemon binary, try to prefix it with the ...
#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.
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:1511
const struct GNUNET_SCHEDULER_TaskContext * GNUNET_SCHEDULER_get_task_context(void)
Obtain the reasoning why the current task was started.
Definition scheduler.c:758
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:980
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:1304
@ GNUNET_SCHEDULER_REASON_READ_READY
The reading socket is ready.
#define _(String)
GNU gettext support macro.
Definition platform.h:179
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.
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we use.
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

Enumeration Type Documentation

◆ AutoPhase

enum AutoPhase

Phases of the auto configuration.

Enumerator
AUTO_INIT 

Initial start value.

AUTO_EXTERNAL_IP 

Test our external IP.

AUTO_STUN 

Test our external IP.

AUTO_LOCAL_IP 

Test our internal IP.

AUTO_NAT_PUNCHED 

Test if NAT was punched.

AUTO_UPNPC 

Test if UPnP is working.

AUTO_ICMP_SERVER 

Test if ICMP server works.

AUTO_ICMP_CLIENT 

Test if ICMP client works.

AUTO_DONE 

Last phase, we're done.

Definition at line 47 of file gnunet-service-nat-auto_legacy.c.

48{
52 AUTO_INIT = 0,
53
58
63
68
73
78
83
88
93};

Function Documentation

◆ next_phase()

static void next_phase ( struct GNUNET_NAT_AutoHandle ah)
static

Run the next phase of the auto test.

Parameters
ahauto test handle

Definition at line 867 of file gnunet-service-nat-auto_legacy.c.

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");
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 {
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}

References ah, AUTO_DONE, AUTO_EXTERNAL_IP, AUTO_ICMP_CLIENT, AUTO_ICMP_SERVER, AUTO_INIT, AUTO_LOCAL_IP, AUTO_NAT_PUNCHED, AUTO_STUN, AUTO_UPNPC, GNUNET_NAT_AUTO_AutoHandle::cfg, GNUNET_assert, GNUNET_CONFIGURATION_destroy(), GNUNET_CONFIGURATION_get_diff(), GNUNET_CONFIGURATION_set_value_number(), GNUNET_CONFIGURATION_set_value_string(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NAT_autoconfig_cancel(), GNUNET_NAT_TYPE_NO_NAT, GNUNET_NAT_TYPE_STUN_PUNCHED_NAT, GNUNET_NAT_TYPE_UNREACHABLE_NAT, test_external_ip(), test_icmp_client(), test_icmp_server(), test_local_ip(), test_nat_punched(), test_stun(), and test_upnpc().

Referenced by do_udp_read(), GNUNET_NAT_autoconfig_start(), mq_error_handler(), process_stun_reply(), result_callback(), set_external_ipv4(), test_external_ip(), test_icmp_client(), test_icmp_server(), test_local_ip(), test_nat_punched(), test_stun(), and test_upnpc().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_stun_reply()

static void process_stun_reply ( struct sockaddr_in *  answer,
struct GNUNET_NAT_AutoHandle ah 
)
static

Definition at line 215 of file gnunet-service-nat-auto_legacy.c.

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}

References ah, GNUNET_ERROR_TYPE_INFO, GNUNET_log, and next_phase().

Referenced by do_udp_read().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ stop_stun()

static void stop_stun ( )
static

Function that terminates the test.

Definition at line 232 of file gnunet-service-nat-auto_legacy.c.

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}

References GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_NETWORK_socket_close(), GNUNET_SCHEDULER_cancel(), lsock4, and ltask4.

Referenced by do_udp_read(), request_callback(), and test_stun().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_udp_read()

static void do_udp_read ( void *  cls)
static

Activity on our incoming socket.

Read data from the incoming connection.

Parameters
cls

Definition at line 258 of file gnunet-service-nat-auto_legacy.c.

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
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}

References ah, AUTO_NAT_PUNCHED, GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_NAT_stun_handle_packet(), GNUNET_NETWORK_fdset_isset(), GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_recv(), GNUNET_OK, GNUNET_SCHEDULER_get_task_context(), GNUNET_SCHEDULER_REASON_READ_READY, GNUNET_YES, lsock4, next_phase(), process_stun_reply(), GNUNET_SCHEDULER_TaskContext::read_ready, GNUNET_SCHEDULER_TaskContext::reason, stop_stun(), and tc.

Referenced by test_nat_punched(), and test_stun().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ bind_v4()

static struct GNUNET_NETWORK_Handle * bind_v4 ( )
static

Create an IPv4 listen socket bound to our port.

Returns
NULL on error

Definition at line 320 of file gnunet-service-nat-auto_legacy.c.

321{
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
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}

References GNUNET_NETWORK_socket_bind(), GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_create(), GNUNET_OK, ls, and port.

Referenced by test_stun().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ request_callback()

static void request_callback ( void *  cls,
enum GNUNET_NAT_StatusCode  result 
)
static

Definition at line 351 of file gnunet-service-nat-auto_legacy.c.

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}

References GNUNET_ERROR_TYPE_INFO, GNUNET_log, and stop_stun().

Referenced by test_stun().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ result_callback()

static void result_callback ( void *  cls,
enum GNUNET_NAT_StatusCode  ret 
)
static

Function called by NAT to report the outcome of the nat-test.

Clean up and update GUI.

Parameters
clsthe auto handle
successcurrently always GNUNET_OK
emsgNULL on success, otherwise an error message

Definition at line 373 of file gnunet-service-nat-auto_legacy.c.

375{
376 struct GNUNET_NAT_AutoHandle *ah = cls;
377
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}

References _, ah, GNUNET_NAT_AUTO_AutoHandle::cfg, GNUNET_CONFIGURATION_set_value_string(), GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_NAT_ERROR_SUCCESS, GNUNET_NAT_test_stop(), next_phase(), and ret.

Referenced by reversal_test().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ reversal_test()

static void reversal_test ( void *  cls)
static

Main function for the connection reversal test.

Parameters
clsthe struct GNUNET_NAT_AutoHandle

Definition at line 399 of file gnunet-service-nat-auto_legacy.c.

400{
401 struct GNUNET_NAT_AutoHandle *ah = cls;
402
403 ah->task = NULL;
405 _ ("Testing connection reversal with ICMP server.\n"));
409}

References _, ah, GNUNET_NAT_AUTO_AutoHandle::cfg, GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_NAT_test_start(), GNUNET_RESOLVER_connect(), GNUNET_YES, result_callback(), and TIMEOUT.

Referenced by test_icmp_server().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_external_ipv4()

static void set_external_ipv4 ( void *  cls,
const struct in_addr *  addr,
enum GNUNET_NAT_StatusCode  ret 
)
static

Set our external IPv4 address based on the UPnP.

Parameters
clsclosure with our setup context
addrthe address, NULL on errors
emsgNULL on success, otherwise an error message

Definition at line 421 of file gnunet-service-nat-auto_legacy.c.

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}

References _, ah, GNUNET_NAT_AUTO_AutoHandle::cfg, GNUNET_break, GNUNET_CONFIGURATION_set_value_string(), GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_NAT_ERROR_EXTERNAL_IP_ADDRESS_INVALID, GNUNET_NAT_ERROR_SUCCESS, GNUNET_YES, next_phase(), and ret.

Referenced by test_external_ip().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ test_external_ip()

static void test_external_ip ( struct GNUNET_NAT_AutoHandle ah)
static

Determine our external IPv4 address.

Parameters
ahauto setup context

Definition at line 469 of file gnunet-service-nat-auto_legacy.c.

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}

References ah, GNUNET_NAT_ERROR_SUCCESS, next_phase(), set_external_ipv4(), and TIMEOUT.

Referenced by next_phase().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ test_stun()

static void test_stun ( struct GNUNET_NAT_AutoHandle ah)
static

Determine our external IPv4 address and port using an external STUN server.

Parameters
ahauto setup context

Definition at line 487 of file gnunet-service-nat-auto_legacy.c.

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,
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}

References ah, bind_v4(), GNUNET_NAT_AUTO_AutoHandle::cfg, do_udp_read(), GNUNET_CONFIGURATION_get_value_number(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_log_strerror, GNUNET_NAT_stun_make_request(), GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_read_net(), lsock4, ltask4, NAT_SERVER_TIMEOUT, next_phase(), port, request_callback(), stop_stun(), stun_port, and stun_server.

Referenced by next_phase().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_if()

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 
)
static

Process list of local IP addresses.

Find and set the one of the default interface.

Parameters
clsour struct GNUNET_NAT_AutoHandle
namename of the interface (can be NULL for unknown)
isDefaultis this presumably the default interface
addraddress of this interface (can be NULL for unknown or unassigned)
broadcast_addrthe broadcast address (can be NULL for unknown or unassigned)
netmaskthe network mask (can be NULL for unknown or unassigned))
addrlenlength of the addr and broadcast_addr
Returns
GNUNET_OK to continue iteration, GNUNET_SYSERR to abort

Definition at line 551 of file gnunet-service-nat-auto_legacy.c.

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}

References _, ah, GNUNET_NAT_AUTO_AutoHandle::cfg, GNUNET_break, GNUNET_CONFIGURATION_set_value_string(), GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_memcmp, GNUNET_NAT_ERROR_SUCCESS, GNUNET_OK, GNUNET_SYSERR, and GNUNET_YES.

Referenced by test_local_ip().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ test_local_ip()

static void test_local_ip ( struct GNUNET_NAT_AutoHandle ah)
static

Determine our local IP addresses; detect internal IP & IPv6-support.

Parameters
ahauto setup context

Definition at line 622 of file gnunet-service-nat-auto_legacy.c.

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}

References ah, GNUNET_NAT_AUTO_AutoHandle::cfg, GNUNET_CONFIGURATION_set_value_string(), GNUNET_NAT_ERROR_NO_VALID_IF_IP_COMBO, GNUNET_NO, GNUNET_OS_network_interfaces_list(), GNUNET_YES, next_phase(), and process_if().

Referenced by next_phase().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mq_error_handler()

static void mq_error_handler ( void *  cls,
enum GNUNET_MQ_Error  error 
)
static

We got disconnected from the NAT server.

Stop waiting for a reply.

Parameters
clsthe struct GNUNET_NAT_AutoHandle
errorerror code

Definition at line 643 of file gnunet-service-nat-auto_legacy.c.

645{
646 struct GNUNET_NAT_AutoHandle *ah = cls;
647
649 ah->mq = NULL;
650 /* wait a bit first? */
651 next_phase (ah);
652}

References ah, GNUNET_MQ_destroy(), GNUNET_NAT_AUTO_AutoHandle::mq, and next_phase().

Referenced by test_nat_punched().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ test_nat_punched()

static void test_nat_punched ( struct GNUNET_NAT_AutoHandle ah)
static

Test if NAT has been punched.

Parameters
ahauto setup context

Definition at line 661 of file gnunet-service-nat-auto_legacy.c.

662{
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 }
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);
696 env);
697 if (NULL != ltask4)
698 {
701 lsock4,
703 ah);
704 }
705}

References _, ah, GNUNET_NAT_AUTO_AutoHandle::cfg, do_udp_read(), env, GNUNET_CLIENT_connect(), GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_MESSAGE_TYPE_NAT_TEST, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_NO, GNUNET_SCHEDULER_add_read_net(), GNUNET_SCHEDULER_cancel(), LOG, lsock4, ltask4, GNUNET_NAT_AUTO_AutoHandle::mq, mq_error_handler(), msg, NAT_SERVER_TIMEOUT, next_phase(), and port.

Referenced by next_phase().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ test_upnpc()

static void test_upnpc ( struct GNUNET_NAT_AutoHandle ah)
static

Test if UPnPC works.

Parameters
ahauto setup context

Definition at line 714 of file gnunet-service-nat-auto_legacy.c.

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 !=
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}

References _, ah, GNUNET_NAT_AUTO_AutoHandle::cfg, GNUNET_CONFIGURATION_set_value_string(), GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_NAT_ERROR_SUCCESS, GNUNET_NO, GNUNET_OS_check_helper_binary(), GNUNET_SYSERR, GNUNET_YES, and next_phase().

Referenced by next_phase().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ test_icmp_server()

static void test_icmp_server ( struct GNUNET_NAT_AutoHandle ah)
static

Test if ICMP server is working.

Parameters
ahauto setup context

Definition at line 742 of file gnunet-service-nat-auto_legacy.c.

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 ==
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 }
793err:
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}

References _, ah, GNUNET_NAT_AUTO_AutoHandle::cfg, GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_log, GNUNET_NO, GNUNET_OK, GNUNET_OS_check_helper_binary(), GNUNET_OS_get_libexec_binary_path(), GNUNET_SCHEDULER_add_now(), GNUNET_YES, next_phase(), and reversal_test().

Referenced by next_phase().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ test_icmp_client()

static void test_icmp_client ( struct GNUNET_NAT_AutoHandle ah)
static

Test if ICMP client is working.

Parameters
ahauto setup context

Definition at line 813 of file gnunet-service-nat-auto_legacy.c.

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 ==
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 }
855err:
856 GNUNET_free (tmp);
857 GNUNET_free (helper);
858
859 next_phase (ah);
860}

References _, ah, GNUNET_NAT_AUTO_AutoHandle::cfg, GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_log, GNUNET_OK, GNUNET_OS_check_helper_binary(), GNUNET_OS_get_libexec_binary_path(), GNUNET_YES, and next_phase().

Referenced by next_phase().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_NAT_autoconfig_start()

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.

The resolver service should be available when this function is called.

Parameters
cfginitial configuration
cbfunction to call with autoconfiguration result
cb_clsclosure for cb
Returns
handle to cancel operation

Definition at line 1035 of file gnunet-service-nat-auto_legacy.c.

1038{
1039 struct GNUNET_NAT_AutoHandle *ah;
1040
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}

References ah, cfg, GNUNET_NAT_AUTO_AutoHandle::cfg, GNUNET_CONFIGURATION_dup(), GNUNET_CONFIGURATION_set_value_string(), GNUNET_NAT_ERROR_SUCCESS, GNUNET_new, and next_phase().

Here is the call graph for this function:

◆ GNUNET_NAT_autoconfig_cancel()

void GNUNET_NAT_autoconfig_cancel ( struct GNUNET_NAT_AutoHandle ah)

Abort autoconfiguration.

Parameters
ahhandle for operation to abort

Definition at line 1065 of file gnunet-service-nat-auto_legacy.c.

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 {
1080 ah->mq = NULL;
1081 }
1082 if (NULL != ah->task)
1083 {
1085 ah->task = NULL;
1086 }
1088 GNUNET_CONFIGURATION_destroy (ah->initial_cfg);
1089 GNUNET_free (ah);
1090}

References ah, GNUNET_NAT_AUTO_AutoHandle::cfg, GNUNET_CONFIGURATION_destroy(), GNUNET_free, GNUNET_MQ_destroy(), GNUNET_NAT_test_stop(), GNUNET_SCHEDULER_cancel(), and GNUNET_NAT_AUTO_AutoHandle::mq.

Referenced by next_phase().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ lsock4

struct GNUNET_NETWORK_Handle* lsock4
static

The listen socket of the service for IPv4.

Definition at line 188 of file gnunet-service-nat-auto_legacy.c.

Referenced by do_udp_read(), stop_stun(), test_nat_punched(), and test_stun().

◆ ltask4

struct GNUNET_SCHEDULER_Task* ltask4
static

The listen task ID for IPv4.

Definition at line 193 of file gnunet-service-nat-auto_legacy.c.

Referenced by stop_stun(), test_nat_punched(), and test_stun().

◆ port

unsigned long long port = 7895
static

The port the test service is running on (default 7895)

Definition at line 198 of file gnunet-service-nat-auto_legacy.c.

Referenced by bind_v4(), test_nat_punched(), and test_stun().

◆ stun_server

char* stun_server = "stun.ekiga.net"
static

Definition at line 200 of file gnunet-service-nat-auto_legacy.c.

Referenced by test_stun().

◆ stun_port

unsigned int stun_port = 3478
static

Definition at line 202 of file gnunet-service-nat-auto_legacy.c.

Referenced by test_stun().