aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2004-11-13 16:53:48 +0000
committerNick Mathewson <nickm@torproject.org>2004-11-13 16:53:48 +0000
commit08627d5d87294ee86b252dac0a2f9f003d7e24bf (patch)
treeb55f42a35cf6c24d724c94aaf67b17866e38c377
parentec7d0d43f4d9808a849f2575ee30861c5d3da742 (diff)
downloadtor-08627d5d87294ee86b252dac0a2f9f003d7e24bf.tar
tor-08627d5d87294ee86b252dac0a2f9f003d7e24bf.tar.gz
Track whether descriptor is dirty/uploaded. When any options are set, mark it dirty. Once a minute, regenerate and upload the server descriptor if it is dirty.
svn:r2832
-rw-r--r--doc/TODO2
-rw-r--r--src/or/config.c6
-rw-r--r--src/or/connection.c12
-rw-r--r--src/or/main.c33
-rw-r--r--src/or/or.h5
-rw-r--r--src/or/router.c32
6 files changed, 68 insertions, 22 deletions
diff --git a/doc/TODO b/doc/TODO
index 05a9b39d0..6e07c5304 100644
--- a/doc/TODO
+++ b/doc/TODO
@@ -17,7 +17,7 @@ N - clients now have certs, which means we warn when their certs have
o clean up parse_*_policy code
o when you hup, they're not getting re-parsed
o stop calling a *_policy an exit_policy_t
-N - Regenerate our server descriptor when a relevant option is changed from
+ o Regenerate our server descriptor when a relevant option is changed from
control.c.
. Writing out the machine-readable torrc file
o Function to check whether an option has changed.
diff --git a/src/or/config.c b/src/or/config.c
index dc1816a0a..133dd8518 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -325,6 +325,12 @@ options_act(void) {
}
#endif
+ /* Since our options changed, we might need to regenerate and upload our
+ * server descriptor. (We could probably be more clever about only calling
+ * this when something significant changed.)
+ */
+ mark_my_descriptor_dirty();
+
return 0;
}
diff --git a/src/or/connection.c b/src/or/connection.c
index 47b796eab..d1dbf0cfc 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -871,11 +871,14 @@ static int connection_read_to_buf(connection_t *conn) {
result = read_to_buf_tls(conn->tls, at_most, conn->inbuf);
switch(result) {
- case TOR_TLS_ERROR:
case TOR_TLS_CLOSE:
+ log_fn(LOG_INFO,"TLS connection closed on read. Closing. (Nickname %s, address %s",
+ conn->nickname ? conn->nickname : "not set", conn->address);
+ return -1;
+ case TOR_TLS_ERROR:
log_fn(LOG_INFO,"tls error. breaking (nickname %s, address %s).",
conn->nickname ? conn->nickname : "not set", conn->address);
- return -1; /* XXX deal with close better */
+ return -1;
case TOR_TLS_WANTWRITE:
connection_start_writing(conn);
return 0;
@@ -993,10 +996,11 @@ int connection_handle_write(connection_t *conn) {
switch(result) {
case TOR_TLS_ERROR:
case TOR_TLS_CLOSE:
- log_fn(LOG_INFO,"tls error. breaking.");
+ log_fn(LOG_INFO,result==TOR_TLS_ERROR?
+ "tls error. breaking.":"TLS connection closed on flush");
connection_close_immediate(conn); /* Don't flush; connection is dead. */
connection_mark_for_close(conn);
- return -1; /* XXX deal with close better */
+ return -1;
case TOR_TLS_WANTWRITE:
log_fn(LOG_DEBUG,"wanted write.");
/* we're already writing */
diff --git a/src/or/main.c b/src/or/main.c
index 4654980e3..484461a50 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -66,6 +66,8 @@ SERVICE_STATUS service_status;
SERVICE_STATUS_HANDLE hStatus;
#endif
+#define CHECK_DESCRIPTOR_INTERVAL 60
+
/********* END VARIABLES ************/
/****************************************************************************
@@ -509,6 +511,7 @@ static void run_scheduled_events(time_t now) {
static time_t last_uploaded_services = 0;
static time_t last_rotated_certificate = 0;
static time_t time_to_check_listeners = 0;
+ static time_t time_to_check_descriptor = 0;
or_options_t *options = get_options();
int i;
@@ -527,11 +530,11 @@ static void run_scheduled_events(time_t now) {
log_fn(LOG_INFO,"Rotating onion key.");
rotate_onion_key();
cpuworkers_rotate();
- if (router_rebuild_descriptor()<0) {
+ if (router_rebuild_descriptor(1)<0) {
log_fn(LOG_WARN, "Couldn't rebuild router descriptor");
}
if(advertised_server_mode())
- router_upload_dir_desc_to_dirservers();
+ router_upload_dir_desc_to_dirservers(0);
}
/** 1b. Every MAX_SSL_KEY_LIFETIME seconds, we change our TLS context. */
@@ -553,14 +556,14 @@ static void run_scheduled_events(time_t now) {
if (options->AccountingMaxKB)
accounting_run_housekeeping(now);
- /** 2. Every DirFetchPostPeriod seconds, we get a new directory and upload
- * our descriptor (if we've passed our internal checks). */
+ /** 2. Every DirFetchPostPeriod seconds, we get a new directory and
+ * force-upload our descriptor (if we've passed our internal
+ * checks). */
if(time_to_fetch_directory < now) {
-
if(decide_if_publishable_server(now)) {
server_is_advertised = 1;
- router_rebuild_descriptor();
- router_upload_dir_desc_to_dirservers();
+ router_rebuild_descriptor(1);
+ router_upload_dir_desc_to_dirservers(1);
} else {
server_is_advertised = 0;
}
@@ -590,6 +593,18 @@ static void run_scheduled_events(time_t now) {
time_to_fetch_directory = now + options->DirFetchPostPeriod;
}
+ /* 2b. Once per minute, regenerate and upload the descriptor if it is wrong */
+ if (time_to_check_descriptor < now) {
+ time_to_check_descriptor = now + CHECK_DESCRIPTOR_INTERVAL;
+ if (decide_if_publishable_server(now)) {
+ server_is_advertised=1;
+ router_rebuild_descriptor(0);
+ router_upload_dir_desc_to_dirservers(0);
+ } else {
+ server_is_advertised=0;
+ }
+ }
+
/** 3a. Every second, we examine pending circuits and prune the
* ones which have been pending for more than a few seconds.
* We do this before step 3, so it can try building more if
@@ -726,8 +741,8 @@ static int do_hup(void) {
* configuration options. */
cpuworkers_rotate();
dnsworkers_rotate();
- /* Rebuild fresh descriptor as needed. */
- router_rebuild_descriptor();
+ /* Rebuild fresh descriptor. */
+ router_rebuild_descriptor(1);
tor_snprintf(keydir,sizeof(keydir),"%s/router.desc", options->DataDirectory);
log_fn(LOG_INFO,"Dumping descriptor to %s...",keydir);
if (write_str_to_file(keydir, router_get_my_descriptor(), 0)) {
diff --git a/src/or/or.h b/src/or/or.h
index 35a487921..f6ae58f72 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -1509,12 +1509,13 @@ int router_get_bandwidth_capacity(void);
void router_retry_connections(void);
int router_is_clique_mode(routerinfo_t *router);
-void router_upload_dir_desc_to_dirservers(void);
+void router_upload_dir_desc_to_dirservers(int force);
+void mark_my_descriptor_dirty(void);
int router_compare_to_my_exit_policy(connection_t *conn);
routerinfo_t *router_get_my_routerinfo(void);
const char *router_get_my_descriptor(void);
int router_is_me(routerinfo_t *router);
-int router_rebuild_descriptor(void);
+int router_rebuild_descriptor(int force);
int router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
crypto_pk_env_t *ident_key);
int is_legal_nickname(const char *s);
diff --git a/src/or/router.c b/src/or/router.c
index 1dad84ac5..e2c7fa7de 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -38,6 +38,7 @@ void set_onion_key(crypto_pk_env_t *k) {
onionkey = k;
onionkey_set_at = time(NULL);
tor_mutex_release(key_lock);
+ mark_my_descriptor_dirty();
}
/** Return the current onion key. Requires that the onion key has been
@@ -412,11 +413,15 @@ int router_is_clique_mode(routerinfo_t *router) {
static routerinfo_t *desc_routerinfo = NULL;
/** String representation of my descriptor, signed by me. */
static char descriptor[8192];
+/** Boolean: do we need to regenerate the above? */
+static int desc_is_dirty = 1;
+/** Boolean: do we need to regenerate the above? */
+static int desc_needs_upload = 0;
/** OR only: try to upload our signed descriptor to all the directory servers
- * we know about.
+ * we know about. DOCDOC force
*/
-void router_upload_dir_desc_to_dirservers(void) {
+void router_upload_dir_desc_to_dirservers(int force) {
const char *s;
s = router_get_my_descriptor();
@@ -424,6 +429,9 @@ void router_upload_dir_desc_to_dirservers(void) {
log_fn(LOG_WARN, "No descriptor; skipping upload");
return;
}
+ if (!force || !desc_needs_upload)
+ return;
+ desc_needs_upload = 0;
directory_post_to_dirservers(DIR_PURPOSE_UPLOAD_DIR, s, strlen(s));
}
@@ -489,7 +497,7 @@ routerinfo_t *router_get_my_routerinfo(void)
return NULL;
if (!desc_routerinfo) {
- if (router_rebuild_descriptor())
+ if (router_rebuild_descriptor(1))
return NULL;
}
return desc_routerinfo;
@@ -500,7 +508,7 @@ routerinfo_t *router_get_my_routerinfo(void)
*/
const char *router_get_my_descriptor(void) {
if (!desc_routerinfo) {
- if (router_rebuild_descriptor())
+ if (router_rebuild_descriptor(1))
return NULL;
}
log_fn(LOG_DEBUG,"my desc is '%s'",descriptor);
@@ -508,15 +516,18 @@ const char *router_get_my_descriptor(void) {
}
/** Rebuild a fresh routerinfo and signed server descriptor for this
- * OR. Return 0 on success, -1 on error.
+ * OR. Return 0 on success, -1 on error. DOCDOC force
*/
-int router_rebuild_descriptor(void) {
+int router_rebuild_descriptor(int force) {
routerinfo_t *ri;
uint32_t addr;
char platform[256];
struct in_addr in;
or_options_t *options = get_options();
+ if (!desc_is_dirty && !force)
+ return 0;
+
if(resolve_my_address(options->Address, &addr) < 0) {
log_fn(LOG_WARN,"options->Address didn't resolve into an IP.");
return -1;
@@ -558,9 +569,18 @@ int router_rebuild_descriptor(void) {
log_fn(LOG_WARN, "Couldn't dump router to string.");
return -1;
}
+ desc_is_dirty = 0;
+ desc_needs_upload = 1;
return 0;
}
+/** DOCDOC */
+void
+mark_my_descriptor_dirty(void)
+{
+ desc_is_dirty = 1;
+}
+
/** 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.