aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-01-05 18:51:02 +0100
committerChristian Grothoff <christian@grothoff.org>2017-01-05 18:51:02 +0100
commit8c1ee5dd1319bcd9ddb6c55d2104c286b61b2e99 (patch)
tree704449a28ae0249ca3a3bd2789c2cbadb8171230 /src
parent3c31d74877c1243b98e7b31a0d5acab91fc5795e (diff)
downloadgnunet-8c1ee5dd1319bcd9ddb6c55d2104c286b61b2e99.tar.gz
gnunet-8c1ee5dd1319bcd9ddb6c55d2104c286b61b2e99.zip
move external IP logic to separate file
Diffstat (limited to 'src')
-rw-r--r--src/nat/Makefile.am3
-rw-r--r--src/nat/gnunet-service-nat.c211
-rw-r--r--src/nat/gnunet-service-nat.h35
-rw-r--r--src/nat/gnunet-service-nat_externalip.c314
-rw-r--r--src/nat/gnunet-service-nat_externalip.h92
5 files changed, 466 insertions, 189 deletions
diff --git a/src/nat/Makefile.am b/src/nat/Makefile.am
index 767cf8d82..b2b9c4f50 100644
--- a/src/nat/Makefile.am
+++ b/src/nat/Makefile.am
@@ -97,7 +97,8 @@ libgnunetnatnew_la_LDFLAGS = \
97 -version-info 2:0:0 97 -version-info 2:0:0
98 98
99gnunet_service_nat_SOURCES = \ 99gnunet_service_nat_SOURCES = \
100 gnunet-service-nat.c \ 100 gnunet-service-nat.c gnunet-service-nat.h \
101 gnunet-service-nat_externalip.c gnunet-service-nat_externalip.h \
101 gnunet-service-nat_stun.c gnunet-service-nat_stun.h \ 102 gnunet-service-nat_stun.c gnunet-service-nat_stun.h \
102 gnunet-service-nat_mini.c gnunet-service-nat_mini.h \ 103 gnunet-service-nat_mini.c gnunet-service-nat_mini.h \
103 gnunet-service-nat_helper.c gnunet-service-nat_helper.h 104 gnunet-service-nat_helper.c gnunet-service-nat_helper.h
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);
diff --git a/src/nat/gnunet-service-nat.h b/src/nat/gnunet-service-nat.h
new file mode 100644
index 000000000..96eb9f78b
--- /dev/null
+++ b/src/nat/gnunet-service-nat.h
@@ -0,0 +1,35 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2016, 2017 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19 */
20
21/**
22 * @file nat/gnunet-service-nat.h
23 * @brief network address translation traversal service
24 * @author Christian Grothoff
25 */
26#ifndef GNUNET_SERVICE_NAT_H
27#define GNUNET_SERVICE_NAT_H
28
29/**
30 * Is UPnP enabled? #GNUNET_YES if enabled, #GNUNET_NO if disabled,
31 * #GNUNET_SYSERR if configuration enabled but binary is unavailable.
32 */
33extern int enable_upnp;
34
35#endif
diff --git a/src/nat/gnunet-service-nat_externalip.c b/src/nat/gnunet-service-nat_externalip.c
new file mode 100644
index 000000000..979d2f0f5
--- /dev/null
+++ b/src/nat/gnunet-service-nat_externalip.c
@@ -0,0 +1,314 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009, 2015, 2016, 2017 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20/**
21 * Code to figure out what our external IPv4 address(es) might
22 * be (external IPv4s are what is seen on the rest of the Internet).
23 *
24 * This can be implemented using different methods, and we allow
25 * the main service to be notified about changes to what we believe
26 * is our external IPv4 address.
27 *
28 * Note that this is explicitly only about NATed systems; if one
29 * of our network interfaces has a global IP address this does
30 * not count as "external".
31 *
32 * TODO:
33 * - implement NEW logic for external IP detection based on traceroute!
34 *
35 * @file nat/gnunet-service-nat_externalip.c
36 * @brief Functions for monitoring external IPv4 addresses
37 * @author Christian Grothoff
38 */
39#include "platform.h"
40#include <math.h>
41#include "gnunet_util_lib.h"
42#include "gnunet_protocols.h"
43#include "gnunet_signatures.h"
44#include "gnunet_statistics_service.h"
45#include "gnunet_resolver_service.h"
46#include "gnunet_nat_service.h"
47#include "gnunet-service-nat.h"
48#include "gnunet-service-nat_externalip.h"
49#include "gnunet-service-nat_stun.h"
50#include "gnunet-service-nat_mini.h"
51#include "gnunet-service-nat_helper.h"
52#include "nat.h"
53#include <gcrypt.h>
54
55
56/**
57 * How long do we wait until we re-try running `external-ip` if the
58 * command failed to terminate nicely?
59 */
60#define EXTERN_IP_RETRY_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)
61
62/**
63 * How long do we wait until we re-try running `external-ip` if the
64 * command failed (but terminated)?
65 */
66#define EXTERN_IP_RETRY_FAILURE GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 30)
67
68/**
69 * How long do we wait until we re-try running `external-ip` if the
70 * command succeeded?
71 */
72#define EXTERN_IP_RETRY_SUCCESS GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
73
74
75/**
76 * Handle to monitor for external IP changes.
77 */
78struct GN_ExternalIPMonitor
79{
80 /**
81 * Kept in DLL.
82 */
83 struct GN_ExternalIPMonitor *next;
84
85 /**
86 * Kept in DLL.
87 */
88 struct GN_ExternalIPMonitor *prev;
89
90 /**
91 * Function to call when we believe our external IPv4 address changed.
92 */
93 GN_NotifyExternalIPv4Change cb;
94
95 /**
96 * Closure for @e cb.
97 */
98 void *cb_cls;
99
100};
101
102
103/**
104 * List of monitors, kept in DLL.
105 */
106static struct GN_ExternalIPMonitor *mon_head;
107
108/**
109 * List of monitors, kept in DLL.
110 */
111static struct GN_ExternalIPMonitor *mon_tail;
112
113/**
114 * Task run to obtain our external IP (if #enable_upnp is set
115 * and if we find we have a NATed IP address).
116 */
117static struct GNUNET_SCHEDULER_Task *probe_external_ip_task;
118
119/**
120 * Handle to our operation to run `external-ip`.
121 */
122static struct GNUNET_NAT_ExternalHandle *probe_external_ip_op;
123
124/**
125 * What is our external IP address as claimed by `external-ip`?
126 * 0 for unknown.
127 */
128static struct in_addr mini_external_ipv4;
129
130
131/**
132 * Tell relevant clients about a change in our external
133 * IPv4 address.
134 *
135 * @param add #GNUNET_YES to add, #GNUNET_NO to remove
136 * @param v4 the external address that changed
137 */
138static void
139notify_monitors_external_ipv4_change (int add,
140 const struct in_addr *v4)
141{
142 for (struct GN_ExternalIPMonitor *mon = mon_head;
143 NULL != mon;
144 mon = mon->next)
145 mon->cb (mon->cb_cls,
146 v4,
147 add);
148}
149
150
151/**
152 * Task used to run `external-ip` to get our external IPv4
153 * address and pass it to NATed clients if possible.
154 *
155 * @param cls NULL
156 */
157static void
158run_external_ip (void *cls);
159
160
161/**
162 * We learn our current external IP address. If it changed,
163 * notify all of our applicable clients. Also re-schedule
164 * #run_external_ip with an appropriate timeout.
165 *
166 * @param cls NULL
167 * @param addr the address, NULL on errors
168 * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
169 */
170static void
171handle_external_ip (void *cls,
172 const struct in_addr *addr,
173 enum GNUNET_NAT_StatusCode result)
174{
175 char buf[INET_ADDRSTRLEN];
176
177 probe_external_ip_op = NULL;
178 GNUNET_SCHEDULER_cancel (probe_external_ip_task);
179 probe_external_ip_task
180 = GNUNET_SCHEDULER_add_delayed ((NULL == addr)
181 ? EXTERN_IP_RETRY_FAILURE
182 : EXTERN_IP_RETRY_SUCCESS,
183 &run_external_ip,
184 NULL);
185 switch (result)
186 {
187 case GNUNET_NAT_ERROR_SUCCESS:
188 if (addr->s_addr == mini_external_ipv4.s_addr)
189 return; /* not change */
190 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
191 "Our external IP is now %s\n",
192 inet_ntop (AF_INET,
193 addr,
194 buf,
195 sizeof (buf)));
196 if (0 != mini_external_ipv4.s_addr)
197 notify_monitors_external_ipv4_change (GNUNET_NO,
198 &mini_external_ipv4);
199 mini_external_ipv4 = *addr;
200 notify_monitors_external_ipv4_change (GNUNET_YES,
201 &mini_external_ipv4);
202 break;
203 default:
204 if (0 != mini_external_ipv4.s_addr)
205 notify_monitors_external_ipv4_change (GNUNET_NO,
206 &mini_external_ipv4);
207 mini_external_ipv4.s_addr = 0;
208 break;
209 }
210}
211
212
213/**
214 * Task used to run `external-ip` to get our external IPv4
215 * address and pass it to NATed clients if possible.
216 *
217 * @param cls NULL
218 */
219static void
220run_external_ip (void *cls)
221{
222 probe_external_ip_task
223 = GNUNET_SCHEDULER_add_delayed (EXTERN_IP_RETRY_TIMEOUT,
224 &run_external_ip,
225 NULL);
226 if (NULL != probe_external_ip_op)
227 {
228 GNUNET_NAT_mini_get_external_ipv4_cancel_ (probe_external_ip_op);
229 probe_external_ip_op = NULL;
230 }
231 probe_external_ip_op
232 = GNUNET_NAT_mini_get_external_ipv4_ (&handle_external_ip,
233 NULL);
234}
235
236
237/**
238 * We have changed our opinion about being NATed in the first
239 * place. Adapt our probing.
240 *
241 * @param have_nat #GNUNET_YES if we believe we are behind NAT
242 */
243void
244GN_nat_status_changed (int have_nat)
245{
246 if (GNUNET_YES != enable_upnp)
247 return;
248 if ( (GNUNET_YES == have_nat) &&
249 (NULL == probe_external_ip_task) &&
250 (NULL == probe_external_ip_op) )
251 {
252 probe_external_ip_task
253 = GNUNET_SCHEDULER_add_now (&run_external_ip,
254 NULL);
255 return;
256 }
257 if (GNUNET_NO == have_nat)
258 {
259 if (NULL != probe_external_ip_task)
260 {
261 GNUNET_SCHEDULER_cancel (probe_external_ip_task);
262 probe_external_ip_task = NULL;
263 }
264 if (NULL != probe_external_ip_op)
265 {
266 GNUNET_NAT_mini_get_external_ipv4_cancel_ (probe_external_ip_op);
267 probe_external_ip_op = NULL;
268 }
269 }
270}
271
272
273/**
274 * Start monitoring external IPv4 addresses.
275 *
276 * @param cb function to call on changes
277 * @param cb_cls closure for @a cb
278 * @return handle to cancel
279 */
280struct GN_ExternalIPMonitor *
281GN_external_ipv4_monitor_start (GN_NotifyExternalIPv4Change cb,
282 void *cb_cls)
283{
284 struct GN_ExternalIPMonitor *mon;
285
286 mon = GNUNET_new (struct GN_ExternalIPMonitor);
287 mon->cb = cb;
288 mon->cb_cls = cb_cls;
289 GNUNET_CONTAINER_DLL_insert (mon_head,
290 mon_tail,
291 mon);
292 if (0 != mini_external_ipv4.s_addr)
293 cb (cb_cls,
294 &mini_external_ipv4,
295 GNUNET_YES);
296 return mon;
297}
298
299
300/**
301 * Stop calling monitor.
302 *
303 * @param mon monitor to call
304 */
305void
306GN_external_ipv4_monitor_stop (struct GN_ExternalIPMonitor *mon)
307{
308 GNUNET_CONTAINER_DLL_remove (mon_head,
309 mon_tail,
310 mon);
311 GNUNET_free (mon);
312}
313
314/* end of gnunet-service-nat_externalip.c */
diff --git a/src/nat/gnunet-service-nat_externalip.h b/src/nat/gnunet-service-nat_externalip.h
new file mode 100644
index 000000000..31910555d
--- /dev/null
+++ b/src/nat/gnunet-service-nat_externalip.h
@@ -0,0 +1,92 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009, 2015, 2016, 2017 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20/**
21 * Code to figure out what our external IPv4 address(es) might
22 * be (external IPv4s are what is seen on the rest of the Internet).
23 *
24 * This can be implemented using different methods, and we allow
25 * the main service to be notified about changes to what we believe
26 * is our external IPv4 address.
27 *
28 * Note that this is explicitly only about NATed systems; if one
29 * of our network interfaces has a global IP address this does
30 * not count as "external".
31 *
32 * @file nat/gnunet-service-nat_externalip.h
33 * @brief Functions for monitoring external IPv4 addresses
34 * @author Christian Grothoff
35 */
36#ifndef GNUNET_SERVICE_NAT_EXTERNALIP_H
37#define GNUNET_SERVICE_NAT_EXTERNALIP_H
38
39#include "platform.h"
40
41
42/**
43 * We have changed our opinion about being NATed in the first
44 * place. Adapt our probing.
45 *
46 * @param have_nat #GNUNET_YES if we believe we are behind NAT
47 */
48void
49GN_nat_status_changed (int have_nat);
50
51
52/**
53 * Function we call when we believe our external IPv4 address changed.
54 *
55 * @param cls closure
56 * @param ip address to add/remove
57 * @param add_remove #GNUNET_YES to add, #GNUNET_NO to remove
58 */
59typedef void
60(*GN_NotifyExternalIPv4Change)(void *cls,
61 const struct in_addr *ip,
62 int add_remove);
63
64
65/**
66 * Handle to monitor for external IP changes.
67 */
68struct GN_ExternalIPMonitor;
69
70
71/**
72 * Start monitoring external IPv4 addresses.
73 *
74 * @param cb function to call on changes
75 * @param cb_cls closure for @a cb
76 * @return handle to cancel
77 */
78struct GN_ExternalIPMonitor *
79GN_external_ipv4_monitor_start (GN_NotifyExternalIPv4Change cb,
80 void *cb_cls);
81
82
83/**
84 * Stop calling monitor.
85 *
86 * @param mon monitor to call
87 */
88void
89GN_external_ipv4_monitor_stop (struct GN_ExternalIPMonitor *mon);
90
91
92#endif