diff --git a/doc/spec/control-spec.txt b/doc/spec/control-spec.txt index 883c78f407..86bdf84052 100644 --- a/doc/spec/control-spec.txt +++ b/doc/spec/control-spec.txt @@ -1556,7 +1556,13 @@ $Id$ 4.1.12. Network status has changed Syntax: - "650" "+" "NS" CRLF 1*NetworkStatus "." CRLF "650" SP "OK" CRLF + "650" "+" "NS" CRLF 1*NetworkStatus "." CRLF "650" SP "OK" CRLF + + The event is used whenever our local view of a relay status changes. + This happens when we get a new v3 consensus (in which case the entries + we see are a duplicate of what we see in the NEWCONSENSUS event, + below), but it also happens when we decide to mark a relay as up or + down in our local status, for example based on connection attempts. [First added in 0.1.2.3-alpha] @@ -1596,6 +1602,20 @@ $Id$ set of "countrycode=count" pairs. For example, 650-CLIENTS_SEEN TimeStarted="Thu Dec 25 23:50:43 EST 2008" 650 CountrySummary=us=16,de=8,uk=8 +[XXX Matt Edman informs me that the time format above is wrong. -RD] + +4.1.15. New consensus networkstatus has arrived. + + The syntax is: + "650" "+" "NEWCONSENSUS" CRLF 1*NetworkStatus "." CRLF "650" SP + "OK" CRLF + + A new consensus networkstatus has arrived. We include NS-style lines for + every relay in the consensus. NEWCONSENSUS is a separate event from the + NS event, because the list here represents every usable relay: so any + relay *not* mentioned in this list is implicitly no longer recommended. + + [First added in 0.2.1.13-alpha] 5. Implementation notes diff --git a/src/or/control.c b/src/or/control.c index f435251751..222a6e0762 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -42,7 +42,8 @@ #define EVENT_GUARD 0x0013 #define EVENT_STREAM_BANDWIDTH_USED 0x0014 #define EVENT_CLIENTS_SEEN 0x0015 -#define _EVENT_MAX 0x0015 +#define EVENT_NEWCONSENSUS 0x0016 +#define _EVENT_MAX 0x0016 /* If _EVENT_MAX ever hits 0x0020, we need to make the mask wider. */ /** Bitfield: The bit 1<<e is set if any open control @@ -999,6 +1000,8 @@ handle_control_setevents(control_connection_t *conn, uint32_t len, event_code = EVENT_STREAM_BANDWIDTH_USED; else if (!strcasecmp(ev, "CLIENTS_SEEN")) event_code = EVENT_CLIENTS_SEEN; + else if (!strcasecmp(ev, "NEWCONSENSUS")) + event_code = EVENT_NEWCONSENSUS; else { connection_printf_to_buf(conn, "552 Unrecognized event \"%s\"\r\n", ev); @@ -3516,16 +3519,20 @@ control_event_or_authdir_new_descriptor(const char *action, /** Called when the routerstatus_ts statuses have changed: sends * an NS event to any controller that cares. */ -int -control_event_networkstatus_changed(smartlist_t *statuses) +static int +control_event_networkstatus_changed_helper(smartlist_t *statuses, + uint16_t event, + const char *event_string) { smartlist_t *strs; char *s, *esc = NULL; - if (!EVENT_IS_INTERESTING(EVENT_NS) || !smartlist_len(statuses)) + if (!EVENT_IS_INTERESTING(event) || !smartlist_len(statuses)) return 0; strs = smartlist_create(); - smartlist_add(strs, tor_strdup("650+NS\r\n")); + smartlist_add(strs, tor_strdup("650+")); + smartlist_add(strs, tor_strdup(event_string)); + smartlist_add(strs, tor_strdup("\r\n")); SMARTLIST_FOREACH(statuses, routerstatus_t *, rs, { s = networkstatus_getinfo_helper_single(rs); @@ -3538,14 +3545,27 @@ control_event_networkstatus_changed(smartlist_t *statuses) SMARTLIST_FOREACH(strs, char *, cp, tor_free(cp)); smartlist_free(strs); tor_free(s); - send_control_event_string(EVENT_NS, ALL_NAMES|ALL_FORMATS, esc); - send_control_event_string(EVENT_NS, ALL_NAMES|ALL_FORMATS, + send_control_event_string(event, ALL_NAMES|ALL_FORMATS, esc); + send_control_event_string(event, ALL_NAMES|ALL_FORMATS, "650 OK\r\n"); tor_free(esc); return 0; } +int +control_event_networkstatus_changed(smartlist_t *statuses) +{ + return control_event_networkstatus_changed_helper(statuses, EVENT_NS, "NS"); +} + +int +control_event_newconsensus(const networkstatus_t *consensus) +{ + return control_event_networkstatus_changed_helper( + consensus->routerstatus_list, EVENT_NEWCONSENSUS, "NEWCONSENSUS"); +} + /** Called when a single local_routerstatus_t has changed: Sends an NS event * to any countroller that cares. */ int diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c index 306ecb4278..81b1d07115 100644 --- a/src/or/networkstatus.c +++ b/src/or/networkstatus.c @@ -1317,6 +1317,9 @@ notify_control_networkstatus_changed(const networkstatus_t *old_c, smartlist_t *changed; if (old_c == new_c) return; + + control_event_newconsensus(new_c); + if (!old_c) { control_event_networkstatus_changed(new_c->routerstatus_list); return; diff --git a/src/or/or.h b/src/or/or.h index d8122dbbc3..7c191eeaf3 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -3236,6 +3236,7 @@ int control_event_or_authdir_new_descriptor(const char *action, const char *msg); int control_event_my_descriptor_changed(void); int control_event_networkstatus_changed(smartlist_t *statuses); +int control_event_newconsensus(const networkstatus_t *consensus); int control_event_networkstatus_changed_single(routerstatus_t *rs); int control_event_general_status(int severity, const char *format, ...) CHECK_PRINTF(2,3);