diff options
-rw-r--r-- | src/or/main.c | 6 | ||||
-rw-r--r-- | src/or/or.h | 1 | ||||
-rw-r--r-- | src/or/router.c | 49 |
3 files changed, 56 insertions, 0 deletions
diff --git a/src/or/main.c b/src/or/main.c index 28913e11b..81ce77216 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -94,6 +94,7 @@ static char* nt_strerror(uint32_t errnum); #define FORCE_REGENERATE_DESCRIPTOR_INTERVAL 18*60*60 /* 18 hours */ #define CHECK_DESCRIPTOR_INTERVAL 60 /* one minute */ +#define CHECK_IPADDRESS_INTERVAL (5*60) /* five minutes */ #define BUF_SHRINK_INTERVAL 60 /* one minute */ #define DESCRIPTOR_RETRY_INTERVAL 10 #define DESCRIPTOR_FAILURE_RESET_INTERVAL 60*60 @@ -637,6 +638,7 @@ run_scheduled_events(time_t now) static time_t last_rotated_certificate = 0; static time_t time_to_check_listeners = 0; static time_t time_to_check_descriptor = 0; + static time_t time_to_check_ipaddress = 0; static time_t time_to_shrink_buffers = 0; static time_t time_to_try_getting_descriptors = 0; static time_t time_to_reset_descriptor_failures = 0; @@ -744,6 +746,10 @@ run_scheduled_events(time_t now) if (time_to_check_descriptor < now) { time_to_check_descriptor = now + CHECK_DESCRIPTOR_INTERVAL; check_descriptor_bandwidth_changed(now); + if (time_to_check_ipaddress < now) { + time_to_check_ipaddress = now + CHECK_IPADDRESS_INTERVAL; + check_descriptor_ipaddress_changed(now); + } mark_my_descriptor_dirty_if_older_than( now - FORCE_REGENERATE_DESCRIPTOR_INTERVAL); consider_publishable_server(now, 0); diff --git a/src/or/or.h b/src/or/or.h index 59ee95954..df92d1db8 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2058,6 +2058,7 @@ void router_upload_dir_desc_to_dirservers(int force); void mark_my_descriptor_dirty_if_older_than(time_t when); void mark_my_descriptor_dirty(void); void check_descriptor_bandwidth_changed(time_t now); +void check_descriptor_ipaddress_changed(time_t now); int router_compare_to_my_exit_policy(connection_t *conn); routerinfo_t *router_get_my_routerinfo(void); const char *router_get_my_descriptor(void); diff --git a/src/or/router.c b/src/or/router.c index 75a10740a..48b47fa22 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -909,6 +909,55 @@ check_descriptor_bandwidth_changed(time_t now) } } +#define MAX_IPADDRESS_CHANGE_FREQ 60*60 +/** Check whether our own address as defined by the Address configuration + * has changed. This is for routers that get their address from a service + * like dyndns. If our address has changed, mark our descriptor dirty.*/ +void +check_descriptor_ipaddress_changed(time_t now) +{ + static time_t last_changed = 0; + static time_t last_warned_lastchangetime = 0; + uint32_t prev, cur; + or_options_t *options = get_options(); + + if (!desc_routerinfo) + return; + + prev = desc_routerinfo->addr; + if (resolve_my_address(options, &cur, NULL) < 0) { + log_fn(LOG_WARN,"options->Address didn't resolve into an IP."); + return; + } + + if (prev != cur) { + char addrbuf_prev[INET_NTOA_BUF_LEN]; + char addrbuf_cur[INET_NTOA_BUF_LEN]; + struct in_addr in_prev; + struct in_addr in_cur; + + in_prev.s_addr = htonl(prev); + tor_inet_ntoa(&in_prev, addrbuf_prev, sizeof(addrbuf_prev)); + + in_cur.s_addr = htonl(cur); + tor_inet_ntoa(&in_cur, addrbuf_cur, sizeof(addrbuf_cur)); + + if (last_changed+MAX_IPADDRESS_CHANGE_FREQ < now) { + log_fn(LOG_INFO,"Our IP Address has changed from %s to %s; rebuilding descriptor.", addrbuf_prev, addrbuf_cur); + mark_my_descriptor_dirty(); + last_changed = now; + last_warned_lastchangetime = 0; + } + else + { + if (last_warned_lastchangetime != last_changed) { + log_fn(LOG_WARN,"Our IP Address seems to be flapping. It has changed twice within one hour (from %s to %s this time). Ignoring for now.", addrbuf_prev, addrbuf_cur); + last_warned_lastchangetime = last_changed; + } + } + } +} + /** Set <b>platform</b> (max length <b>len</b>) to a NUL-terminated short * string describing the version of Tor and the operating system we're * currently running on. |