aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/or/main.c6
-rw-r--r--src/or/or.h1
-rw-r--r--src/or/router.c49
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.