diff --git a/doc/TODO b/doc/TODO index b07340d940..2395fe348a 100644 --- a/doc/TODO +++ b/doc/TODO @@ -66,11 +66,16 @@ N . Implement pending controller features. o Way to handle overlong messages o Specify fragmented format o Implement fragmented format - - Event for "new descriptors" + o Event for "new descriptors" o Better stream IDs + o Stream status changed: "new" state. - EXTENDCIRCUIT - - ATTACHSTREAM - - Stream status changed: "new" state. + - ATTACHSTREAM + - Make streams have an 'unattached and unattachable' state. + - Add support to put new streams into this state rather than try to + attach them automatically. ("Hidden" config option.) + - Time out never-attached streams. + - Implement 'attach stream X to circuit Y' logic. - Tests for new controller features R . HTTPS proxy for OR CONNECT stuff. (For outgoing SSL connections to other ORs.) diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 4d7f9d020a..7aea8ce2dc 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -812,6 +812,7 @@ static int connection_ap_handshake_process_socks(connection_t *conn) { } rep_hist_note_used_port(socks->port, time(NULL)); /* help predict this next time */ } + control_event_stream_status(conn, STREAM_EVENT_NEW); conn->state = AP_CONN_STATE_CIRCUIT_WAIT; return connection_ap_handshake_attach_circuit(conn); } else { diff --git a/src/or/control.c b/src/or/control.c index a23c54bc4f..4024fd4274 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -871,6 +871,31 @@ control_event_logmsg(int severity, const char *msg) send_control_event(EVENT_WARNING, (uint32_t)(len+1), msg); } +/** DOCDOC */ +int control_event_descriptors_changed(smartlist_t *routers) +{ + size_t len; + char *msg; + smartlist_t *identities; + char buf[HEX_DIGEST_LEN+1]; + + if (!EVENT_IS_INTERESTING(EVENT_NEW_DESC)) + return 0; + identities = smartlist_create(); + SMARTLIST_FOREACH(routers, routerinfo_t *, r, + { + base16_encode(buf,sizeof(buf),r->identity_digest,DIGEST_LEN); + smartlist_add(identities, tor_strdup(buf)); + }); + msg = smartlist_join_strings(identities, ",", 1, &len); + send_control_event(EVENT_NEW_DESC, len+1, msg); + + SMARTLIST_FOREACH(identities, char *, cp, tor_free(cp)); + smartlist_free(identities); + tor_free(msg); + return 0; +} + /** Choose a random authentication cookie and write it to disk. * Anybody who can read the cookie from disk will be considered * authorized to use the control connection. */ diff --git a/src/or/or.h b/src/or/or.h index 9b86307c56..4622cfb196 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1362,7 +1362,8 @@ typedef enum stream_status_event_t { STREAM_EVENT_SENT_RESOLVE = 1, STREAM_EVENT_SUCCEEDED = 2, STREAM_EVENT_FAILED = 3, - STREAM_EVENT_CLOSED = 4 + STREAM_EVENT_CLOSED = 4, + STREAM_EVENT_NEW = 5 } stream_status_event_t; typedef enum or_conn_status_event_t { @@ -1381,6 +1382,7 @@ int control_event_stream_status(connection_t *conn, stream_status_event_t e); int control_event_or_conn_status(connection_t *conn, or_conn_status_event_t e); int control_event_bandwidth_used(uint32_t n_read, uint32_t n_written); void control_event_logmsg(int severity, const char *msg); +int control_event_descriptors_changed(smartlist_t *routers); int init_cookie_authentication(int enabled); int decode_hashed_password(char *buf, const char *hashed); diff --git a/src/or/routerlist.c b/src/or/routerlist.c index e521cae011..5c8a46a743 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -886,6 +886,11 @@ router_load_single_router(const char *s) if (router_add_to_routerlist(ri)<0) { log_fn(LOG_WARN, "Couldn't add router to list; dropping."); return -1; + } else { + smartlist_t *changed = smartlist_create(); + smartlist_add(changed, ri); + control_event_descriptors_changed(changed); + smartlist_free(changed); } log_fn(LOG_DEBUG, "Added router to list"); return 0; @@ -914,16 +919,23 @@ int router_load_routerlist_from_directory(const char *s, return -1; } if (routerlist) { + smartlist_t *changed = smartlist_create(); SMARTLIST_FOREACH(new_list->routers, routerinfo_t *, r, - router_add_to_routerlist(r)); + { + if (router_add_to_routerlist(r)==0) + smartlist_add(changed, r); + }); smartlist_clear(new_list->routers); routerlist->published_on = new_list->published_on; tor_free(routerlist->software_versions); routerlist->software_versions = new_list->software_versions; new_list->software_versions = NULL; routerlist_free(new_list); + control_event_descriptors_changed(changed); + smartlist_free(changed); } else { routerlist = new_list; + control_event_descriptors_changed(routerlist->routers); } if (router_resolve_routerlist(routerlist)) { log_fn(LOG_WARN, "Error resolving routerlist");