aboutsummaryrefslogtreecommitdiff
path: root/src/nat/nat.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-06-29 21:18:25 +0000
committerChristian Grothoff <christian@grothoff.org>2011-06-29 21:18:25 +0000
commit503dbc5515ca5d4a590ab9378deb712236dd7a90 (patch)
treea7576b24d591eb02519d951c23d9c0f7987f4838 /src/nat/nat.c
parent3fab372fcc5ed667a11f05c3897ea4d1d7f3456d (diff)
downloadgnunet-503dbc5515ca5d4a590ab9378deb712236dd7a90.tar.gz
gnunet-503dbc5515ca5d4a590ab9378deb712236dd7a90.zip
improving NAT code
Diffstat (limited to 'src/nat/nat.c')
-rw-r--r--src/nat/nat.c169
1 files changed, 147 insertions, 22 deletions
diff --git a/src/nat/nat.c b/src/nat/nat.c
index c4a4c75cb..e5a3e0e0f 100644
--- a/src/nat/nat.c
+++ b/src/nat/nat.c
@@ -27,13 +27,32 @@
27 * 27 *
28 * TODO: 28 * TODO:
29 * - implement UPnP/PMP support 29 * - implement UPnP/PMP support
30 * - repeatedly perform certain checks again to notice changes 30 * - make frequency of checks configurable
31 */ 31 */
32#include "platform.h" 32#include "platform.h"
33#include "gnunet_util_lib.h" 33#include "gnunet_util_lib.h"
34#include "gnunet_resolver_service.h" 34#include "gnunet_resolver_service.h"
35#include "gnunet_nat_lib.h" 35#include "gnunet_nat_lib.h"
36 36
37/**
38 * How often do we scan for changes in our IP address from our local
39 * interfaces?
40 * FIXME: make this configurable...
41 */
42#define IFC_SCAN_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)
43
44/**
45 * How often do we scan for changes in how our hostname resolves?
46 * FIXME: make this configurable...
47 */
48#define HOSTNAME_DNS_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 20)
49
50
51/**
52 * How often do we scan for changes in how our external (dyndns) hostname resolves?
53 * FIXME: make this configurable...
54 */
55#define DYNDNS_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 7)
37 56
38/** 57/**
39 * How long until we give up on transmitting the welcome message? 58 * How long until we give up on transmitting the welcome message?
@@ -52,20 +71,17 @@ enum LocalAddressSource
52 /** 71 /**
53 * Address was obtained by DNS resolution of the external hostname 72 * Address was obtained by DNS resolution of the external hostname
54 * given in the configuration (i.e. hole-punched DynDNS setup). 73 * given in the configuration (i.e. hole-punched DynDNS setup).
55 * FIXME: repeatedly do the lookup to notice changes!
56 */ 74 */
57 LAL_EXTERNAL_IP, 75 LAL_EXTERNAL_IP,
58 76
59 /** 77 /**
60 * Address was obtained by looking up our own hostname in DNS. 78 * Address was obtained by looking up our own hostname in DNS.
61 * FIXME: repeatedly do the lookup to notice changes!
62 */ 79 */
63 LAL_HOSTNAME_DNS, 80 LAL_HOSTNAME_DNS,
64 81
65 /** 82 /**
66 * Address was obtained by scanning our hosts's network interfaces 83 * Address was obtained by scanning our hosts's network interfaces
67 * and taking their address (no DNS involved). 84 * and taking their address (no DNS involved).
68 * FIXME: repeatedly do the lookup to notice changes!
69 */ 85 */
70 LAL_INTERFACE_ADDRESS, 86 LAL_INTERFACE_ADDRESS,
71 87
@@ -183,6 +199,16 @@ struct GNUNET_NAT_Handle
183 GNUNET_SCHEDULER_TaskIdentifier ifc_task; 199 GNUNET_SCHEDULER_TaskIdentifier ifc_task;
184 200
185 /** 201 /**
202 * ID of hostname DNS lookup task
203 */
204 GNUNET_SCHEDULER_TaskIdentifier hostname_task;
205
206 /**
207 * ID of DynDNS lookup task
208 */
209 GNUNET_SCHEDULER_TaskIdentifier dns_task;
210
211 /**
186 * The process id of the server process (if behind NAT) 212 * The process id of the server process (if behind NAT)
187 */ 213 */
188 struct GNUNET_OS_Process *server_proc; 214 struct GNUNET_OS_Process *server_proc;
@@ -271,6 +297,38 @@ start_gnunet_nat_server (struct GNUNET_NAT_Handle *h);
271 297
272 298
273/** 299/**
300 * Remove all addresses from the list of 'local' addresses
301 * that originated from the given source.
302 *
303 * @param plugin the plugin
304 * @param src source that identifies addresses to remove
305 */
306static void
307remove_from_address_list_by_source (struct GNUNET_NAT_Handle *h,
308 enum LocalAddressSource src)
309{
310 struct LocalAddressList *pos;
311 struct LocalAddressList *next;
312
313 next = h->lal_head;
314 while (NULL != (pos = next))
315 {
316 next = pos->next;
317 if (pos->source != src)
318 continue;
319 GNUNET_CONTAINER_DLL_remove (h->lal_head,
320 h->lal_tail,
321 pos);
322 h->address_callback (h->callback_cls,
323 GNUNET_NO,
324 (const struct sockaddr* ) &pos[1],
325 pos->addrlen);
326 GNUNET_free (pos);
327 }
328}
329
330
331/**
274 * Add the given address to the list of 'local' addresses, thereby 332 * Add the given address to the list of 'local' addresses, thereby
275 * making it a 'legal' address for this peer to have. 333 * making it a 'legal' address for this peer to have.
276 * 334 *
@@ -438,6 +496,18 @@ add_ip_to_address_list (struct GNUNET_NAT_Handle *h,
438 496
439 497
440/** 498/**
499 * Task to do DNS lookup on our external hostname to
500 * get DynDNS-IP addresses.
501 *
502 * @param cls the NAT handle
503 * @param tc scheduler context
504 */
505static void
506resolve_dns (void *cls,
507 const struct GNUNET_SCHEDULER_TaskContext *tc);
508
509
510/**
441 * Our (external) hostname was resolved and the configuration says that 511 * Our (external) hostname was resolved and the configuration says that
442 * the NAT was hole-punched. 512 * the NAT was hole-punched.
443 * 513 *
@@ -455,9 +525,8 @@ process_external_ip (void *cls,
455 if (addr == NULL) 525 if (addr == NULL)
456 { 526 {
457 h->ext_dns = NULL; 527 h->ext_dns = NULL;
458 /* FIXME: schedule task to resolve IP again in the 528 h->dns_task = GNUNET_SCHEDULER_add_delayed (DYNDNS_FREQUENCY,
459 future, and if the result changes, update the 529 &resolve_dns, h);
460 local address list accordingly */
461 return; 530 return;
462 } 531 }
463 add_to_address_list (h, LAL_EXTERNAL_IP, addr, addrlen); 532 add_to_address_list (h, LAL_EXTERNAL_IP, addr, addrlen);
@@ -465,6 +534,17 @@ process_external_ip (void *cls,
465 534
466 535
467/** 536/**
537 * Task to do a lookup on our hostname for IP addresses.
538 *
539 * @param cls the NAT handle
540 * @param tc scheduler context
541 */
542static void
543resolve_hostname (void *cls,
544 const struct GNUNET_SCHEDULER_TaskContext *tc);
545
546
547/**
468 * Function called by the resolver for each address obtained from DNS 548 * Function called by the resolver for each address obtained from DNS
469 * for our own hostname. Add the addresses to the list of our IP 549 * for our own hostname. Add the addresses to the list of our IP
470 * addresses. 550 * addresses.
@@ -482,9 +562,8 @@ process_hostname_ip (void *cls,
482 if (addr == NULL) 562 if (addr == NULL)
483 { 563 {
484 h->hostname_dns = NULL; 564 h->hostname_dns = NULL;
485 /* FIXME: schedule task to resolve IP again in the 565 h->hostname_task = GNUNET_SCHEDULER_add_delayed (HOSTNAME_DNS_FREQUENCY,
486 future, and if the result changes, update the 566 &resolve_hostname, h);
487 address list accordingly */
488 return; 567 return;
489 } 568 }
490 add_to_address_list (h, LAL_HOSTNAME_DNS, addr, addrlen); 569 add_to_address_list (h, LAL_HOSTNAME_DNS, addr, addrlen);
@@ -874,11 +953,54 @@ list_interfaces (void *cls,
874 struct GNUNET_NAT_Handle *h = cls; 953 struct GNUNET_NAT_Handle *h = cls;
875 954
876 h->ifc_task = GNUNET_SCHEDULER_NO_TASK; 955 h->ifc_task = GNUNET_SCHEDULER_NO_TASK;
956 remove_from_address_list_by_source (h, LAL_INTERFACE_ADDRESS);
877 GNUNET_OS_network_interfaces_list (&process_interfaces, h); 957 GNUNET_OS_network_interfaces_list (&process_interfaces, h);
878#if 0 958 h->ifc_task = GNUNET_SCHEDULER_add_delayed (IFC_SCAN_FREQUENCY,
879 h->ifc_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FIXME,
880 &list_interfaces, h); 959 &list_interfaces, h);
881#endif 960}
961
962
963/**
964 * Task to do a lookup on our hostname for IP addresses.
965 *
966 * @param cls the NAT handle
967 * @param tc scheduler context
968 */
969static void
970resolve_hostname (void *cls,
971 const struct GNUNET_SCHEDULER_TaskContext *tc)
972{
973 struct GNUNET_NAT_Handle *h = cls;
974
975 h->hostname_task = GNUNET_SCHEDULER_NO_TASK;
976 remove_from_address_list_by_source (h, LAL_HOSTNAME_DNS);
977 h->hostname_dns = GNUNET_RESOLVER_hostname_resolve (AF_UNSPEC,
978 HOSTNAME_RESOLVE_TIMEOUT,
979 &process_hostname_ip,
980 h);
981}
982
983
984/**
985 * Task to do DNS lookup on our external hostname to
986 * get DynDNS-IP addresses.
987 *
988 * @param cls the NAT handle
989 * @param tc scheduler context
990 */
991static void
992resolve_dns (void *cls,
993 const struct GNUNET_SCHEDULER_TaskContext *tc)
994{
995 struct GNUNET_NAT_Handle *h = cls;
996
997 h->dns_task = GNUNET_SCHEDULER_NO_TASK;
998 remove_from_address_list_by_source (h, LAL_EXTERNAL_IP);
999 h->ext_dns = GNUNET_RESOLVER_ip_get (h->external_address,
1000 AF_INET,
1001 GNUNET_TIME_UNIT_MINUTES,
1002 &process_external_ip,
1003 h);
882} 1004}
883 1005
884 1006
@@ -1014,11 +1136,7 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg,
1014 (h->external_address != NULL) && 1136 (h->external_address != NULL) &&
1015 (h->nat_punched == GNUNET_YES) ) 1137 (h->nat_punched == GNUNET_YES) )
1016 { 1138 {
1017 h->ext_dns = GNUNET_RESOLVER_ip_get (h->external_address, 1139 h->dns_task = GNUNET_SCHEDULER_add_now (&resolve_dns, h);
1018 AF_INET,
1019 GNUNET_TIME_UNIT_MINUTES,
1020 &process_external_ip,
1021 h);
1022 h->enable_nat_server = GNUNET_NO; 1140 h->enable_nat_server = GNUNET_NO;
1023 h->enable_upnp = GNUNET_NO; 1141 h->enable_upnp = GNUNET_NO;
1024 } 1142 }
@@ -1049,10 +1167,7 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg,
1049 if (NULL != h->address_callback) 1167 if (NULL != h->address_callback)
1050 { 1168 {
1051 h->ifc_task = GNUNET_SCHEDULER_add_now (&list_interfaces, h); 1169 h->ifc_task = GNUNET_SCHEDULER_add_now (&list_interfaces, h);
1052 h->hostname_dns = GNUNET_RESOLVER_hostname_resolve (AF_UNSPEC, 1170 h->hostname_task = GNUNET_SCHEDULER_add_now (&resolve_hostname, h);
1053 HOSTNAME_RESOLVE_TIMEOUT,
1054 &process_hostname_ip,
1055 h);
1056 } 1171 }
1057 return h; 1172 return h;
1058} 1173}
@@ -1090,6 +1205,16 @@ GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h)
1090 GNUNET_SCHEDULER_cancel (h->ifc_task); 1205 GNUNET_SCHEDULER_cancel (h->ifc_task);
1091 h->ifc_task = GNUNET_SCHEDULER_NO_TASK; 1206 h->ifc_task = GNUNET_SCHEDULER_NO_TASK;
1092 } 1207 }
1208 if (GNUNET_SCHEDULER_NO_TASK != h->hostname_task)
1209 {
1210 GNUNET_SCHEDULER_cancel (h->hostname_task);
1211 h->hostname_task = GNUNET_SCHEDULER_NO_TASK;
1212 }
1213 if (GNUNET_SCHEDULER_NO_TASK != h->dns_task)
1214 {
1215 GNUNET_SCHEDULER_cancel (h->dns_task);
1216 h->dns_task = GNUNET_SCHEDULER_NO_TASK;
1217 }
1093 if (NULL != h->server_proc) 1218 if (NULL != h->server_proc)
1094 { 1219 {
1095 if (0 != GNUNET_OS_process_kill (h->server_proc, SIGTERM)) 1220 if (0 != GNUNET_OS_process_kill (h->server_proc, SIGTERM))