aboutsummaryrefslogtreecommitdiff
path: root/src/nat/gnunet-service-nat.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nat/gnunet-service-nat.c')
-rw-r--r--src/nat/gnunet-service-nat.c211
1 files changed, 23 insertions, 188 deletions
diff --git a/src/nat/gnunet-service-nat.c b/src/nat/gnunet-service-nat.c
index ffc0f6742..7edee9f5b 100644
--- a/src/nat/gnunet-service-nat.c
+++ b/src/nat/gnunet-service-nat.c
@@ -29,9 +29,6 @@
29 * 29 *
30 * TODO: 30 * TODO:
31 * - test and document (!) ICMP based NAT traversal 31 * - test and document (!) ICMP based NAT traversal
32 * - implement NEW logic for external IP detection;
33 * => introduce higher-level abstraction for external-IPs
34 * for subsystems to hook into!
35 * - implement manual hole punching support (AUTO missing) 32 * - implement manual hole punching support (AUTO missing)
36 * - test manual hole punching support 33 * - test manual hole punching support
37 * - implement "more" autoconfig: 34 * - implement "more" autoconfig:
@@ -49,6 +46,8 @@
49#include "gnunet_statistics_service.h" 46#include "gnunet_statistics_service.h"
50#include "gnunet_resolver_service.h" 47#include "gnunet_resolver_service.h"
51#include "gnunet_nat_service.h" 48#include "gnunet_nat_service.h"
49#include "gnunet-service-nat.h"
50#include "gnunet-service-nat_externalip.h"
52#include "gnunet-service-nat_stun.h" 51#include "gnunet-service-nat_stun.h"
53#include "gnunet-service-nat_mini.h" 52#include "gnunet-service-nat_mini.h"
54#include "gnunet-service-nat_helper.h" 53#include "gnunet-service-nat_helper.h"
@@ -68,24 +67,6 @@
68#define AUTOCONFIG_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) 67#define AUTOCONFIG_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
69 68
70/** 69/**
71 * How long do we wait until we re-try running `external-ip` if the
72 * command failed to terminate nicely?
73 */
74#define EXTERN_IP_RETRY_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)
75
76/**
77 * How long do we wait until we re-try running `external-ip` if the
78 * command failed (but terminated)?
79 */
80#define EXTERN_IP_RETRY_FAILURE GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 30)
81
82/**
83 * How long do we wait until we re-try running `external-ip` if the
84 * command succeeded?
85 */
86#define EXTERN_IP_RETRY_SUCCESS GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
87
88/**
89 * How often do we scan for changes in how our external (dyndns) hostname resolves? 70 * How often do we scan for changes in how our external (dyndns) hostname resolves?
90 */ 71 */
91#define DYNDNS_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 7) 72#define DYNDNS_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 7)
@@ -211,6 +192,11 @@ struct ClientHandle
211 struct GNUNET_RESOLVER_RequestHandle *ext_dns; 192 struct GNUNET_RESOLVER_RequestHandle *ext_dns;
212 193
213 /** 194 /**
195 * Handle for monitoring external IP changes.
196 */
197 struct GN_ExternalIPMonitor *external_monitor;
198
199 /**
214 * DLL of external IP addresses as given in @e hole_external. 200 * DLL of external IP addresses as given in @e hole_external.
215 */ 201 */
216 struct LocalAddressList *ext_addr_head; 202 struct LocalAddressList *ext_addr_head;
@@ -422,24 +408,7 @@ static struct StunExternalIP *se_tail;
422 * Is UPnP enabled? #GNUNET_YES if enabled, #GNUNET_NO if disabled, 408 * Is UPnP enabled? #GNUNET_YES if enabled, #GNUNET_NO if disabled,
423 * #GNUNET_SYSERR if configuration enabled but binary is unavailable. 409 * #GNUNET_SYSERR if configuration enabled but binary is unavailable.
424 */ 410 */
425static int enable_upnp; 411int enable_upnp;
426
427/**
428 * Task run to obtain our external IP (if #enable_upnp is set
429 * and if we find we have a NATed IP address).
430 */
431static struct GNUNET_SCHEDULER_Task *probe_external_ip_task;
432
433/**
434 * Handle to our operation to run `external-ip`.
435 */
436static struct GNUNET_NAT_ExternalHandle *probe_external_ip_op;
437
438/**
439 * What is our external IP address as claimed by `external-ip`?
440 * 0 for unknown.
441 */
442static struct in_addr mini_external_ipv4;
443 412
444 413
445/** 414/**
@@ -936,15 +905,16 @@ notify_clients (struct LocalAddressList *delta,
936 * Tell relevant client about a change in our external 905 * Tell relevant client about a change in our external
937 * IPv4 address. 906 * IPv4 address.
938 * 907 *
908 * @param cls client to check if it cares and possibly notify
939 * @param v4 the external address that changed 909 * @param v4 the external address that changed
940 * @param ch client to check if it cares and possibly notify
941 * @param add #GNUNET_YES to add, #GNUNET_NO to remove 910 * @param add #GNUNET_YES to add, #GNUNET_NO to remove
942 */ 911 */
943static void 912static void
944check_notify_client_external_ipv4_change (const struct in_addr *v4, 913notify_client_external_ipv4_change (void *cls,
945 struct ClientHandle *ch, 914 const struct in_addr *v4,
946 int add) 915 int add)
947{ 916{
917 struct ClientHandle *ch = cls;
948 struct sockaddr_in sa; 918 struct sockaddr_in sa;
949 int have_v4; 919 int have_v4;
950 920
@@ -986,112 +956,6 @@ check_notify_client_external_ipv4_change (const struct in_addr *v4,
986 956
987 957
988/** 958/**
989 * Tell relevant clients about a change in our external
990 * IPv4 address.
991 *
992 * @param add #GNUNET_YES to add, #GNUNET_NO to remove
993 * @param v4 the external address that changed
994 */
995static void
996notify_clients_external_ipv4_change (int add,
997 const struct in_addr *v4)
998{
999 for (struct ClientHandle *ch = ch_head;
1000 NULL != ch;
1001 ch = ch->next)
1002 check_notify_client_external_ipv4_change (v4,
1003 ch,
1004 add);
1005}
1006
1007
1008/**
1009 * Task used to run `external-ip` to get our external IPv4
1010 * address and pass it to NATed clients if possible.
1011 *
1012 * @param cls NULL
1013 */
1014static void
1015run_external_ip (void *cls);
1016
1017
1018/**
1019 * We learn our current external IP address. If it changed,
1020 * notify all of our applicable clients. Also re-schedule
1021 * #run_external_ip with an appropriate timeout.
1022 *
1023 * @param cls NULL
1024 * @param addr the address, NULL on errors
1025 * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
1026 */
1027static void
1028handle_external_ip (void *cls,
1029 const struct in_addr *addr,
1030 enum GNUNET_NAT_StatusCode result)
1031{
1032 char buf[INET_ADDRSTRLEN];
1033
1034 probe_external_ip_op = NULL;
1035 GNUNET_SCHEDULER_cancel (probe_external_ip_task);
1036 probe_external_ip_task
1037 = GNUNET_SCHEDULER_add_delayed ((NULL == addr)
1038 ? EXTERN_IP_RETRY_FAILURE
1039 : EXTERN_IP_RETRY_SUCCESS,
1040 &run_external_ip,
1041 NULL);
1042 switch (result)
1043 {
1044 case GNUNET_NAT_ERROR_SUCCESS:
1045 if (addr->s_addr == mini_external_ipv4.s_addr)
1046 return; /* not change */
1047 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1048 "Our external IP is now %s\n",
1049 inet_ntop (AF_INET,
1050 addr,
1051 buf,
1052 sizeof (buf)));
1053 if (0 != mini_external_ipv4.s_addr)
1054 notify_clients_external_ipv4_change (GNUNET_NO,
1055 &mini_external_ipv4);
1056 mini_external_ipv4 = *addr;
1057 notify_clients_external_ipv4_change (GNUNET_YES,
1058 &mini_external_ipv4);
1059 break;
1060 default:
1061 if (0 != mini_external_ipv4.s_addr)
1062 notify_clients_external_ipv4_change (GNUNET_NO,
1063 &mini_external_ipv4);
1064 mini_external_ipv4.s_addr = 0;
1065 break;
1066 }
1067}
1068
1069
1070/**
1071 * Task used to run `external-ip` to get our external IPv4
1072 * address and pass it to NATed clients if possible.
1073 *
1074 * @param cls NULL
1075 */
1076static void
1077run_external_ip (void *cls)
1078{
1079 probe_external_ip_task
1080 = GNUNET_SCHEDULER_add_delayed (EXTERN_IP_RETRY_TIMEOUT,
1081 &run_external_ip,
1082 NULL);
1083 if (NULL != probe_external_ip_op)
1084 {
1085 GNUNET_NAT_mini_get_external_ipv4_cancel_ (probe_external_ip_op);
1086 probe_external_ip_op = NULL;
1087 }
1088 probe_external_ip_op
1089 = GNUNET_NAT_mini_get_external_ipv4_ (&handle_external_ip,
1090 NULL);
1091}
1092
1093
1094/**
1095 * We got a connection reversal request from another peer. 959 * We got a connection reversal request from another peer.
1096 * Notify applicable clients. 960 * Notify applicable clients.
1097 * 961 *
@@ -1251,29 +1115,7 @@ run_scan (void *cls)
1251 } 1115 }
1252 } 1116 }
1253 } 1117 }
1254 if ( (GNUNET_YES == have_nat) && 1118 GN_nat_status_changed (have_nat);
1255 (GNUNET_YES == enable_upnp) &&
1256 (NULL == probe_external_ip_task) &&
1257 (NULL == probe_external_ip_op) )
1258 {
1259 probe_external_ip_task
1260 = GNUNET_SCHEDULER_add_now (&run_external_ip,
1261 NULL);
1262 }
1263 if ( (GNUNET_NO == have_nat) &&
1264 (GNUNET_YES == enable_upnp) )
1265 {
1266 if (NULL != probe_external_ip_task)
1267 {
1268 GNUNET_SCHEDULER_cancel (probe_external_ip_task);
1269 probe_external_ip_task = NULL;
1270 }
1271 if (NULL != probe_external_ip_op)
1272 {
1273 GNUNET_NAT_mini_get_external_ipv4_cancel_ (probe_external_ip_op);
1274 probe_external_ip_op = NULL;
1275 }
1276 }
1277} 1119}
1278 1120
1279 1121
@@ -1727,12 +1569,9 @@ handle_register (void *cls,
1727 GNUNET_YES); 1569 GNUNET_YES);
1728 } 1570 }
1729 /* Also consider IPv4 determined by `external-ip` */ 1571 /* Also consider IPv4 determined by `external-ip` */
1730 if (0 != mini_external_ipv4.s_addr) 1572 ch->external_monitor
1731 { 1573 = GN_external_ipv4_monitor_start (&notify_client_external_ipv4_change,
1732 check_notify_client_external_ipv4_change (&mini_external_ipv4, 1574 ch);
1733 ch,
1734 GNUNET_YES);
1735 }
1736 GNUNET_SERVICE_client_continue (ch->client); 1575 GNUNET_SERVICE_client_continue (ch->client);
1737} 1576}
1738 1577
@@ -2346,16 +2185,7 @@ shutdown_task (void *cls)
2346 GNUNET_SCHEDULER_cancel (se->timeout_task); 2185 GNUNET_SCHEDULER_cancel (se->timeout_task);
2347 GNUNET_free (se); 2186 GNUNET_free (se);
2348 } 2187 }
2349 if (NULL != probe_external_ip_task) 2188 GN_nat_status_changed (GNUNET_NO);
2350 {
2351 GNUNET_SCHEDULER_cancel (probe_external_ip_task);
2352 probe_external_ip_task = NULL;
2353 }
2354 if (NULL != probe_external_ip_op)
2355 {
2356 GNUNET_NAT_mini_get_external_ipv4_cancel_ (probe_external_ip_op);
2357 probe_external_ip_op = NULL;
2358 }
2359 if (NULL != scan_task) 2189 if (NULL != scan_task)
2360 { 2190 {
2361 GNUNET_SCHEDULER_cancel (scan_task); 2191 GNUNET_SCHEDULER_cancel (scan_task);
@@ -2489,6 +2319,11 @@ client_disconnect_cb (void *cls,
2489 GNUNET_SCHEDULER_cancel (ch->ext_dns_task); 2319 GNUNET_SCHEDULER_cancel (ch->ext_dns_task);
2490 ch->ext_dns_task = NULL; 2320 ch->ext_dns_task = NULL;
2491 } 2321 }
2322 if (NULL != ch->external_monitor)
2323 {
2324 GN_external_ipv4_monitor_stop (ch->external_monitor);
2325 ch->external_monitor = NULL;
2326 }
2492 if (NULL != ch->ext_dns) 2327 if (NULL != ch->ext_dns)
2493 { 2328 {
2494 GNUNET_RESOLVER_request_cancel (ch->ext_dns); 2329 GNUNET_RESOLVER_request_cancel (ch->ext_dns);