GNUnet 0.22.0
gnunet-service-nat_externalip.c
Go to the documentation of this file.
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 it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
36#include "platform.h"
37#include <math.h>
38#include "gnunet_util_lib.h"
39#include "gnunet_protocols.h"
40#include "gnunet_signatures.h"
43#include "gnunet_nat_service.h"
44#include "gnunet-service-nat.h"
49#include "nat.h"
50#include <gcrypt.h>
51
52
57#define EXTERN_IP_RETRY_TIMEOUT GNUNET_TIME_relative_multiply ( \
58 GNUNET_TIME_UNIT_MINUTES, 15)
59
64#define EXTERN_IP_RETRY_FAILURE GNUNET_TIME_relative_multiply ( \
65 GNUNET_TIME_UNIT_MINUTES, 30)
66
71#define EXTERN_IP_RETRY_SUCCESS GNUNET_TIME_relative_multiply ( \
72 GNUNET_TIME_UNIT_MINUTES, 5)
73
74
79{
84
89
94
98 void *cb_cls;
99};
100
101
106
111
117
122
127static struct in_addr mini_external_ipv4;
128
129
137static void
139 const struct in_addr *v4)
140{
141 for (struct GN_ExternalIPMonitor *mon = mon_head;
142 NULL != mon;
143 mon = mon->next)
144 mon->cb (mon->cb_cls,
145 v4,
146 add);
147}
148
149
156static void
157run_external_ip (void *cls);
158
159
169static void
171 const struct in_addr *addr,
173{
174 char buf[INET_ADDRSTRLEN];
175
179 = GNUNET_SCHEDULER_add_delayed ((NULL == addr)
183 NULL);
184 switch (result)
185 {
187 GNUNET_assert (NULL != addr);
188 if (addr->s_addr == mini_external_ipv4.s_addr)
189 return; /* not change */
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)
199 mini_external_ipv4 = *addr;
202 break;
203
204 default:
205 if (0 != mini_external_ipv4.s_addr)
208 mini_external_ipv4.s_addr = 0;
209 break;
210 }
211}
212
213
220static void
222{
226 NULL);
227 if (NULL != probe_external_ip_op)
228 {
231 }
234 NULL);
235}
236
237
244void
246{
247 if (GNUNET_YES != enable_upnp)
248 return;
249 if ((GNUNET_YES == have_nat) &&
250 (NULL == probe_external_ip_task) &&
251 (NULL == probe_external_ip_op))
252 {
255 NULL);
256 return;
257 }
258 if (GNUNET_NO == have_nat)
259 {
260 if (NULL != probe_external_ip_task)
261 {
264 }
265 if (NULL != probe_external_ip_op)
266 {
269 }
270 }
271}
272
273
283 void *cb_cls)
284{
285 struct GN_ExternalIPMonitor *mon;
286
287 mon = GNUNET_new (struct GN_ExternalIPMonitor);
288 mon->cb = cb;
289 mon->cb_cls = cb_cls;
291 mon_tail,
292 mon);
293 if (0 != mini_external_ipv4.s_addr)
294 cb (cb_cls,
296 GNUNET_YES);
297 return mon;
298}
299
300
306void
308{
310 mon_tail,
311 mon);
312 GNUNET_free (mon);
313}
314
315
316/* end of gnunet-service-nat_externalip.c */
static int add
Desired action is to add a record.
static int result
Global testing status.
int enable_upnp
Is UPnP enabled? GNUNET_YES if enabled, GNUNET_NO if disabled, GNUNET_SYSERR if configuration enabled...
network address translation traversal service
static struct GNUNET_NAT_ExternalHandle * probe_external_ip_op
Handle to our operation to run external-ip.
void GN_external_ipv4_monitor_stop(struct GN_ExternalIPMonitor *mon)
Stop calling monitor.
void GN_nat_status_changed(int have_nat)
We have changed our opinion about being NATed in the first place.
static struct GNUNET_SCHEDULER_Task * probe_external_ip_task
Task run to obtain our external IP (if enable_upnp is set and if we find we have a NATed IP address).
static struct GN_ExternalIPMonitor * mon_tail
List of monitors, kept in DLL.
#define EXTERN_IP_RETRY_TIMEOUT
How long do we wait until we re-try running external-ip if the command failed to terminate nicely?
static struct in_addr mini_external_ipv4
What is our external IP address as claimed by external-ip? 0 for unknown.
#define EXTERN_IP_RETRY_FAILURE
How long do we wait until we re-try running external-ip if the command failed (but terminated)?
static void run_external_ip(void *cls)
Task used to run external-ip to get our external IPv4 address and pass it to NATed clients if possibl...
static void handle_external_ip(void *cls, const struct in_addr *addr, enum GNUNET_NAT_StatusCode result)
We learn our current external IP address.
struct GN_ExternalIPMonitor * GN_external_ipv4_monitor_start(GN_NotifyExternalIPv4Change cb, void *cb_cls)
Start monitoring external IPv4 addresses.
static struct GN_ExternalIPMonitor * mon_head
List of monitors, kept in DLL.
static void notify_monitors_external_ipv4_change(int add, const struct in_addr *v4)
Tell relevant clients about a change in our external IPv4 address.
#define EXTERN_IP_RETRY_SUCCESS
How long do we wait until we re-try running external-ip if the command succeeded?
Code to figure out what our external IPv4 address(es) might be (external IPv4s are what is seen on th...
void(* GN_NotifyExternalIPv4Change)(void *cls, const struct in_addr *ip, int add_remove)
Function we call when we believe our external IPv4 address changed.
runs the gnunet-helper-nat-server
void GNUNET_NAT_mini_get_external_ipv4_cancel_(struct GNUNET_NAT_ExternalHandle *eh)
Cancel operation.
struct GNUNET_NAT_ExternalHandle * GNUNET_NAT_mini_get_external_ipv4_(GNUNET_NAT_IPCallback cb, void *cb_cls)
Try to get the external IPv4 address of this peer.
This code provides some support for doing STUN transactions.
Constants for network protocols.
Functions related to doing DNS lookups.
API to create, modify and access statistics.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_log(kind,...)
@ GNUNET_YES
@ GNUNET_NO
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
GNUNET_NAT_StatusCode
Error Types for the NAT subsystem (which can then later be converted/resolved to a string)
@ GNUNET_NAT_ERROR_SUCCESS
Just the default.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:979
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:1303
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1276
Opaque handle to cancel "GNUNET_NAT_mini_get_external_ipv4" operation.
Entry in list of pending tasks.
Definition: scheduler.c:135
Handle to monitor for external IP changes.
struct GN_ExternalIPMonitor * prev
Kept in DLL.
GN_NotifyExternalIPv4Change cb
Function to call when we believe our external IPv4 address changed.
struct GN_ExternalIPMonitor * next
Kept in DLL.