aboutsummaryrefslogtreecommitdiff
path: root/src/or
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2007-12-31 21:12:16 +0000
committerNick Mathewson <nickm@torproject.org>2007-12-31 21:12:16 +0000
commit48d7adca8a3c0f58fef0fc76da95f2f18af69e88 (patch)
tree96f1453a312605afb625dcfe596024c54cf0d3e0 /src/or
parent71e117e444af3cfc01f417c40c55c77fcf9ca48c (diff)
downloadtor-48d7adca8a3c0f58fef0fc76da95f2f18af69e88.tar.gz
tor-48d7adca8a3c0f58fef0fc76da95f2f18af69e88.zip
r15768@tombo: nickm | 2007-12-31 16:12:09 -0500
Patch from Tup: make NS events work again. svn:r13009
Diffstat (limited to 'src/or')
-rw-r--r--src/or/control.c2
-rw-r--r--src/or/networkstatus.c74
-rw-r--r--src/or/or.h1
3 files changed, 76 insertions, 1 deletions
diff --git a/src/or/control.c b/src/or/control.c
index 39deb8d266..f3ff86ecaa 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -38,7 +38,7 @@ const char control_c_id[] =
#define EVENT_ADDRMAP 0x000C
// #define EVENT_AUTHDIR_NEWDESCS 0x000D
#define EVENT_DESCCHANGED 0x000E
-#define EVENT_NS 0x000F
+// #define EVENT_NS 0x000F
#define EVENT_STATUS_CLIENT 0x0010
#define EVENT_STATUS_SERVER 0x0011
#define EVENT_STATUS_GENERAL 0x0012
diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c
index 85728273d4..76ba5c1b68 100644
--- a/src/or/networkstatus.c
+++ b/src/or/networkstatus.c
@@ -1199,6 +1199,77 @@ networkstatus_get_reasonably_live_consensus(time_t now)
return NULL;
}
+/** Given two router status entries for the same router identity, return 1 if
+ * if the contents have changed between them. Otherwise, return 0. */
+static int
+routerstatus_has_changed(const routerstatus_t *a, const routerstatus_t *b)
+{
+ tor_assert(!memcmp(a->identity_digest, b->identity_digest, DIGEST_LEN));
+
+ return strcmp(a->nickname, b->nickname) ||
+ memcmp(a->descriptor_digest, b->descriptor_digest, DIGEST_LEN) ||
+ a->addr != b->addr ||
+ a->or_port != b->or_port ||
+ a->dir_port != b->dir_port ||
+ a->is_authority != b->is_authority ||
+ a->is_exit != b->is_exit ||
+ a->is_stable != b->is_stable ||
+ a->is_fast != b->is_fast ||
+ a->is_running != b->is_running ||
+ a->is_named != b->is_named ||
+ a->is_unnamed != b->is_unnamed ||
+ a->is_valid != b->is_valid ||
+ a->is_v2_dir != b->is_v2_dir ||
+ a->is_possible_guard != b->is_possible_guard ||
+ a->is_bad_exit != b->is_bad_exit ||
+ a->is_bad_directory != b->is_bad_directory ||
+ a->is_hs_dir != b->is_hs_dir ||
+ a->version_known != b->version_known ||
+ a->version_supports_begindir != b->version_supports_begindir ||
+ a->version_supports_extrainfo_upload !=
+ b->version_supports_extrainfo_upload ||
+ a->version_supports_v3_dir != b->version_supports_v3_dir;
+}
+
+/** Notify controllers of any router status entries that changed between
+ * <b>old_c</b> and <b>new_c</b>. */
+static void
+notify_control_networkstatus_changed(const networkstatus_vote_t *old_c,
+ const networkstatus_vote_t *new_c)
+{
+ int idx = 0;
+ int old_remain = old_c && smartlist_len(old_c->routerstatus_list);
+ const routerstatus_t *rs_old = NULL;
+ smartlist_t *changed;
+ if (old_c == new_c)
+ return;
+ changed = smartlist_create();
+ if (old_remain)
+ rs_old = smartlist_get(old_c->routerstatus_list, idx);
+
+ SMARTLIST_FOREACH(new_c->routerstatus_list, routerstatus_t *, rs_new,
+ {
+ if (!old_remain) {
+ smartlist_add(changed, rs_new);
+ } else {
+ int r;
+ while ((r = memcmp(rs_old->identity_digest, rs_new->identity_digest,
+ DIGEST_LEN)) < 0) {
+ if (++idx == smartlist_len(old_c->routerstatus_list)) {
+ old_remain = 0;
+ break;
+ }
+ rs_old = smartlist_get(old_c->routerstatus_list, idx);
+ }
+ if (r || (!r && routerstatus_has_changed(rs_old, rs_new)))
+ smartlist_add(changed, rs_new);
+ }
+ });
+
+ control_event_networkstatus_changed(changed);
+ smartlist_free(changed);
+}
+
/** Copy all the ancillary information (like router download status and so on)
* from <b>old_c</b> to <b>new_c</b>. */
static void
@@ -1337,6 +1408,9 @@ networkstatus_set_current_consensus(const char *consensus, int from_cache,
if (r != 1)
authority_certs_fetch_missing(c, now);
+ if (control_event_is_interesting(EVENT_NS))
+ notify_control_networkstatus_changed(current_consensus, c);
+
if (current_consensus) {
networkstatus_copy_old_consensus_info(c, current_consensus);
networkstatus_vote_free(current_consensus);
diff --git a/src/or/or.h b/src/or/or.h
index 1979d7638f..fa4a4d0538 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -2930,6 +2930,7 @@ int connection_control_reached_eof(control_connection_t *conn);
int connection_control_process_inbuf(control_connection_t *conn);
#define EVENT_AUTHDIR_NEWDESCS 0x000D
+#define EVENT_NS 0x000F
int control_event_is_interesting(int event);
int control_event_circuit_status(origin_circuit_t *circ,