mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-23 14:40:51 +01:00
infrastructure for the 'bootstrap status event' feature, so we can
tell the controller how we're doing at bootstrapping, and it can tell the user. svn:r15008
This commit is contained in:
parent
9b626988a6
commit
5aeb89447e
7 changed files with 155 additions and 0 deletions
|
@ -373,6 +373,8 @@ circuit_handle_first_hop(origin_circuit_t *circ)
|
|||
circ->_base.n_port = firsthop->extend_info->port;
|
||||
|
||||
if (!n_conn || n_conn->_base.or_is_obsolete) { /* launch the connection */
|
||||
if (circ->build_state->onehop_tunnel)
|
||||
control_event_bootstrap(BOOTSTRAP_STATUS_CONN_DIR, 0);
|
||||
n_conn = connection_or_connect(firsthop->extend_info->addr,
|
||||
firsthop->extend_info->port,
|
||||
firsthop->extend_info->identity_digest);
|
||||
|
@ -590,6 +592,10 @@ circuit_send_next_onion_skin(origin_circuit_t *circ)
|
|||
int fast;
|
||||
uint8_t cell_type;
|
||||
log_debug(LD_CIRC,"First skin; sending create cell.");
|
||||
if (circ->build_state->onehop_tunnel)
|
||||
control_event_bootstrap(BOOTSTRAP_STATUS_ONEHOP_CREATE, 0);
|
||||
else
|
||||
control_event_bootstrap(BOOTSTRAP_STATUS_CIRCUIT_CREATE, 0);
|
||||
|
||||
router = router_get_by_digest(circ->_base.n_conn->identity_digest);
|
||||
fast = should_use_create_fast_for_router(router, circ);
|
||||
|
@ -641,6 +647,8 @@ circuit_send_next_onion_skin(origin_circuit_t *circ)
|
|||
circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_OPEN);
|
||||
log_info(LD_CIRC,"circuit built!");
|
||||
circuit_reset_failure_count(0);
|
||||
if (circ->build_state->onehop_tunnel)
|
||||
control_event_bootstrap(BOOTSTRAP_STATUS_REQUESTING_STATUS, 0);
|
||||
if (!has_completed_circuit && !circ->build_state->onehop_tunnel) {
|
||||
or_options_t *options = get_options();
|
||||
has_completed_circuit=1;
|
||||
|
@ -648,6 +656,7 @@ circuit_send_next_onion_skin(origin_circuit_t *circ)
|
|||
log(LOG_NOTICE, LD_GENERAL,
|
||||
"Tor has successfully opened a circuit. "
|
||||
"Looks like client functionality is working.");
|
||||
control_event_bootstrap(BOOTSTRAP_STATUS_DONE, 0);
|
||||
control_event_client_status(LOG_NOTICE, "CIRCUIT_ESTABLISHED");
|
||||
if (server_mode(options) && !check_whether_orport_reachable()) {
|
||||
inform_testing_reachability();
|
||||
|
|
|
@ -344,6 +344,7 @@ connection_or_finished_connecting(or_connection_t *or_conn)
|
|||
|
||||
log_debug(LD_OR,"OR connect() to router at %s:%u finished.",
|
||||
conn->address,conn->port);
|
||||
control_event_bootstrap(BOOTSTRAP_STATUS_HANDSHAKE, 0);
|
||||
|
||||
if (get_options()->HttpsProxy) {
|
||||
char buf[1024];
|
||||
|
|
|
@ -3823,3 +3823,94 @@ init_cookie_authentication(int enabled)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/** Convert the name of a bootstrapping phase <b>s</b> into a string
|
||||
* suitable for display by the controller. */
|
||||
static const char *
|
||||
bootstrap_status_to_string(bootstrap_status_t s)
|
||||
{
|
||||
switch (s) {
|
||||
case BOOTSTRAP_STATUS_STARTING:
|
||||
return "Starting";
|
||||
case BOOTSTRAP_STATUS_CONN_DIR:
|
||||
return "Connecting to directory mirror";
|
||||
case BOOTSTRAP_STATUS_HANDSHAKE:
|
||||
return "Finishing handshake";
|
||||
case BOOTSTRAP_STATUS_HANDSHAKE_DIR:
|
||||
return "Finishing handshake with directory mirror";
|
||||
case BOOTSTRAP_STATUS_ONEHOP_CREATE:
|
||||
return "Establishing one-hop circuit for dir info";
|
||||
case BOOTSTRAP_STATUS_REQUESTING_STATUS:
|
||||
return "Asking for networkstatus consensus";
|
||||
case BOOTSTRAP_STATUS_LOADING_STATUS:
|
||||
return "Loading networkstatus consensus";
|
||||
case BOOTSTRAP_STATUS_LOADING_KEYS:
|
||||
return "Loading authority key certs";
|
||||
case BOOTSTRAP_STATUS_REQUESTING_DESCRIPTORS:
|
||||
return "Asking for relay descriptors";
|
||||
case BOOTSTRAP_STATUS_LOADING_DESCRIPTORS:
|
||||
return "Loading relay descriptors";
|
||||
case BOOTSTRAP_STATUS_CONN_OR:
|
||||
return "Connecting to entry guard";
|
||||
case BOOTSTRAP_STATUS_HANDSHAKE_OR:
|
||||
return "Finishing handshake with entry guard";
|
||||
case BOOTSTRAP_STATUS_CIRCUIT_CREATE:
|
||||
return "Establishing circuits";
|
||||
case BOOTSTRAP_STATUS_DONE:
|
||||
return "Done!";
|
||||
default:
|
||||
log_warn(LD_BUG, "Unrecognized bootstrap status code %d", s);
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
/** Called when Tor has made progress at bootstrapping its directory
|
||||
* information and initial circuits. <b>status</b> is the new status,
|
||||
* that is, what task we will be doing next. <b>percent</b> is zero if
|
||||
* we just started this task, else it represents progress on the task.
|
||||
*/
|
||||
int
|
||||
control_event_bootstrap(bootstrap_status_t status, int percent)
|
||||
{
|
||||
static int last_percent = 0;
|
||||
|
||||
if (last_percent == 100)
|
||||
return 0; /* already bootstrapped; nothing to be done here. */
|
||||
|
||||
/* special case for handshaking status, since our tls handshaking code
|
||||
* can't distinguish what the connection is going to be for. */
|
||||
if (status == BOOTSTRAP_STATUS_HANDSHAKE) {
|
||||
if (last_percent < BOOTSTRAP_STATUS_HANDSHAKE_OR) {
|
||||
status = BOOTSTRAP_STATUS_HANDSHAKE_DIR;
|
||||
} else {
|
||||
status = BOOTSTRAP_STATUS_HANDSHAKE_OR;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (status <= last_percent)
|
||||
switch (status) {
|
||||
case BOOTSTRAP_STATUS_CONN_DIR:
|
||||
case BOOTSTRAP_STATUS_ONEHOP_CREATE:
|
||||
case BOOTSTRAP_STATUS_HANDSHAKE_DIR:
|
||||
case BOOTSTRAP_STATUS_REQUESTING_STATUS:
|
||||
case BOOTSTRAP_STATUS_REQUESTING_DESCRIPTORS:
|
||||
boring = 1;
|
||||
break;
|
||||
default: ;
|
||||
}
|
||||
|
||||
if (!boring)
|
||||
#endif
|
||||
if (status > last_percent || (percent && percent > last_percent))
|
||||
log_notice(LD_CONTROL, "Bootstrapped %d%% (last %d): %s.",
|
||||
status, last_percent, bootstrap_status_to_string(status));
|
||||
|
||||
/* ... This is where we tell the controller ... */
|
||||
|
||||
if (percent > last_percent) /* incremental progress within a milestone */
|
||||
last_percent = percent;
|
||||
if (status > last_percent) /* new milestone reached */
|
||||
last_percent = status ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1196,6 +1196,14 @@ update_certificate_downloads(time_t now)
|
|||
authority_certs_fetch_missing(current_consensus, now);
|
||||
}
|
||||
|
||||
/** Return 1 if we have a consensus but we don't have enough certificates
|
||||
* to start using it yet. */
|
||||
int
|
||||
consensus_is_waiting_for_certs(void)
|
||||
{
|
||||
return consensus_waiting_for_certs ? 1 : 0;
|
||||
}
|
||||
|
||||
/** Return the network status with a given identity digest. */
|
||||
networkstatus_v2_t *
|
||||
networkstatus_v2_get_by_digest(const char *digest)
|
||||
|
|
22
src/or/or.h
22
src/or/or.h
|
@ -3016,6 +3016,27 @@ smartlist_t *decode_hashed_passwords(config_line_t *passwords);
|
|||
void disable_control_logging(void);
|
||||
void enable_control_logging(void);
|
||||
|
||||
/** Enum describing various stages of bootstrapping, for use with controller
|
||||
* bootstrap status events. The values range from 0 to 100. */
|
||||
typedef enum {
|
||||
BOOTSTRAP_STATUS_STARTING=0,
|
||||
BOOTSTRAP_STATUS_CONN_DIR=5,
|
||||
BOOTSTRAP_STATUS_HANDSHAKE=-1,
|
||||
BOOTSTRAP_STATUS_HANDSHAKE_DIR=10,
|
||||
BOOTSTRAP_STATUS_ONEHOP_CREATE=15,
|
||||
BOOTSTRAP_STATUS_REQUESTING_STATUS=20,
|
||||
BOOTSTRAP_STATUS_LOADING_STATUS=25,
|
||||
BOOTSTRAP_STATUS_LOADING_KEYS=40,
|
||||
BOOTSTRAP_STATUS_REQUESTING_DESCRIPTORS=45,
|
||||
BOOTSTRAP_STATUS_LOADING_DESCRIPTORS=50,
|
||||
BOOTSTRAP_STATUS_CONN_OR=80,
|
||||
BOOTSTRAP_STATUS_HANDSHAKE_OR=85,
|
||||
BOOTSTRAP_STATUS_CIRCUIT_CREATE=90,
|
||||
BOOTSTRAP_STATUS_DONE=100
|
||||
} bootstrap_status_t;
|
||||
|
||||
int control_event_bootstrap(bootstrap_status_t status, int percent);
|
||||
|
||||
#ifdef CONTROL_PRIVATE
|
||||
/* Used only by control.c and test.c */
|
||||
size_t write_escaped_data(const char *data, size_t len, char **out);
|
||||
|
@ -3442,6 +3463,7 @@ void update_consensus_networkstatus_fetch_time(time_t now);
|
|||
int should_delay_dir_fetches(or_options_t *options);
|
||||
void update_networkstatus_downloads(time_t now);
|
||||
void update_certificate_downloads(time_t now);
|
||||
int consensus_is_waiting_for_certs(void);
|
||||
networkstatus_v2_t *networkstatus_v2_get_by_digest(const char *digest);
|
||||
networkstatus_t *networkstatus_get_latest_consensus(void);
|
||||
networkstatus_t *networkstatus_get_live_consensus(time_t now);
|
||||
|
|
|
@ -932,6 +932,28 @@ connection_edge_process_relay_cell_not_open(
|
|||
/* don't send a socks reply to transparent conns */
|
||||
if (!conn->socks_request->has_finished)
|
||||
connection_ap_handshake_socks_reply(conn, NULL, 0, 0);
|
||||
|
||||
/* Was it a linked dir conn? If so, a dir request just started to
|
||||
* fetch something; this could be a bootstrap status milestone. */
|
||||
log_debug(LD_APP, "considering");
|
||||
if (TO_CONN(conn)->linked_conn &&
|
||||
TO_CONN(conn)->linked_conn->type == CONN_TYPE_DIR) {
|
||||
connection_t *dirconn = TO_CONN(conn)->linked_conn;
|
||||
log_debug(LD_APP, "it is! %d", dirconn->purpose);
|
||||
switch (dirconn->purpose) {
|
||||
case DIR_PURPOSE_FETCH_CERTIFICATE:
|
||||
if (consensus_is_waiting_for_certs())
|
||||
control_event_bootstrap(BOOTSTRAP_STATUS_LOADING_KEYS, 0);
|
||||
break;
|
||||
case DIR_PURPOSE_FETCH_CONSENSUS:
|
||||
control_event_bootstrap(BOOTSTRAP_STATUS_LOADING_STATUS, 0);
|
||||
break;
|
||||
case DIR_PURPOSE_FETCH_SERVERDESC:
|
||||
control_event_bootstrap(BOOTSTRAP_STATUS_LOADING_DESCRIPTORS, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* handle anything that might have queued */
|
||||
if (connection_edge_package_raw_inbuf(conn, 1) < 0) {
|
||||
/* (We already sent an end cell if possible) */
|
||||
|
|
|
@ -4217,6 +4217,7 @@ update_router_have_minimum_dir_info(void)
|
|||
tor_snprintf(dir_info_status, sizeof(dir_info_status),
|
||||
"We have only %d/%d usable descriptors.", num_present, num_usable);
|
||||
res = 0;
|
||||
control_event_bootstrap(BOOTSTRAP_STATUS_REQUESTING_DESCRIPTORS, 0);
|
||||
} else if (num_present < 2) {
|
||||
tor_snprintf(dir_info_status, sizeof(dir_info_status),
|
||||
"Only %d descriptor%s here and believed reachable!",
|
||||
|
@ -4231,6 +4232,7 @@ update_router_have_minimum_dir_info(void)
|
|||
log(LOG_NOTICE, LD_DIR,
|
||||
"We now have enough directory information to build circuits.");
|
||||
control_event_client_status(LOG_NOTICE, "ENOUGH_DIR_INFO");
|
||||
control_event_bootstrap(BOOTSTRAP_STATUS_CONN_OR, 0);
|
||||
}
|
||||
if (!res && have_min_dir_info) {
|
||||
log(LOG_NOTICE, LD_DIR,"Our directory information is no longer up-to-date "
|
||||
|
|
Loading…
Add table
Reference in a new issue