summaryrefslogtreecommitdiff
path: root/src/feature
diff options
context:
space:
mode:
Diffstat (limited to 'src/feature')
-rw-r--r--src/feature/client/circpathbias.c63
-rw-r--r--src/feature/client/circpathbias.h1
-rw-r--r--src/feature/control/control.c139
-rw-r--r--src/feature/control/control.h4
-rw-r--r--src/feature/dircache/directory.c8
-rw-r--r--src/feature/hs/hs_client.c7
-rw-r--r--src/feature/hs/hs_service.c7
-rw-r--r--src/feature/nodelist/nodelist.c9
8 files changed, 176 insertions, 62 deletions
diff --git a/src/feature/client/circpathbias.c b/src/feature/client/circpathbias.c
index 1ee29c639d..9f2ed9347c 100644
--- a/src/feature/client/circpathbias.c
+++ b/src/feature/client/circpathbias.c
@@ -901,6 +901,7 @@ pathbias_check_probe_response(circuit_t *circ, const cell_t *cell)
/* Check nonce */
if (ipv4_host == ocirc->pathbias_probe_nonce) {
pathbias_mark_use_success(ocirc);
+ circuit_read_valid_data(ocirc, rh.length);
circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
log_info(LD_CIRC,
"Got valid path bias probe back for circ %d, stream %d.",
@@ -922,6 +923,68 @@ pathbias_check_probe_response(circuit_t *circ, const cell_t *cell)
}
/**
+ * Check if a cell is counts as valid data for a circuit,
+ * and if so, count it as valid.
+ */
+void
+pathbias_count_valid_cells(circuit_t *circ, const cell_t *cell)
+{
+ origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
+ relay_header_t rh;
+
+ relay_header_unpack(&rh, cell->payload);
+
+ /* Check to see if this is a cell from a previous connection,
+ * or is a request to close the circuit. */
+ switch (rh.command) {
+ case RELAY_COMMAND_TRUNCATED:
+ /* Truncated cells can arrive on path bias circs. When they do,
+ * just process them. This closes the circ, but it was junk anyway.
+ * No reason to wait for the probe. */
+ circuit_read_valid_data(ocirc, rh.length);
+ circuit_truncated(TO_ORIGIN_CIRCUIT(circ),
+ get_uint8(cell->payload + RELAY_HEADER_SIZE));
+
+ break;
+
+ case RELAY_COMMAND_END:
+ if (connection_half_edge_is_valid_end(ocirc->half_streams,
+ rh.stream_id)) {
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh.length);
+ }
+ break;
+
+ case RELAY_COMMAND_DATA:
+ if (connection_half_edge_is_valid_data(ocirc->half_streams,
+ rh.stream_id)) {
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh.length);
+ }
+ break;
+
+ case RELAY_COMMAND_SENDME:
+ if (connection_half_edge_is_valid_sendme(ocirc->half_streams,
+ rh.stream_id)) {
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh.length);
+ }
+ break;
+
+ case RELAY_COMMAND_CONNECTED:
+ if (connection_half_edge_is_valid_connected(ocirc->half_streams,
+ rh.stream_id)) {
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh.length);
+ }
+ break;
+
+ case RELAY_COMMAND_RESOLVED:
+ if (connection_half_edge_is_valid_resolved(ocirc->half_streams,
+ rh.stream_id)) {
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh.length);
+ }
+ break;
+ }
+}
+
+/**
* Check if a circuit was used and/or closed successfully.
*
* If we attempted to use the circuit to carry a stream but failed
diff --git a/src/feature/client/circpathbias.h b/src/feature/client/circpathbias.h
index c99d1277bb..9ce4a6b23a 100644
--- a/src/feature/client/circpathbias.h
+++ b/src/feature/client/circpathbias.h
@@ -20,6 +20,7 @@ void pathbias_count_build_success(origin_circuit_t *circ);
int pathbias_count_build_attempt(origin_circuit_t *circ);
int pathbias_check_close(origin_circuit_t *circ, int reason);
int pathbias_check_probe_response(circuit_t *circ, const cell_t *cell);
+void pathbias_count_valid_cells(circuit_t *circ, const cell_t *cell);
void pathbias_count_use_attempt(origin_circuit_t *circ);
void pathbias_mark_use_success(origin_circuit_t *circ);
void pathbias_mark_use_rollback(origin_circuit_t *circ);
diff --git a/src/feature/control/control.c b/src/feature/control/control.c
index 9e7d21308e..2fac3bd6de 100644
--- a/src/feature/control/control.c
+++ b/src/feature/control/control.c
@@ -7073,6 +7073,11 @@ bootstrap_status_to_string(bootstrap_status_t s, const char **tag,
* Tor initializes. */
static int bootstrap_percent = BOOTSTRAP_STATUS_UNDEF;
+/** Like bootstrap_percent, but only takes on the enumerated values in
+ * bootstrap_status_t.
+ */
+static int bootstrap_phase = BOOTSTRAP_STATUS_UNDEF;
+
/** As bootstrap_percent, but holds the bootstrapping level at which we last
* logged a NOTICE-level message. We use this, plus BOOTSTRAP_PCT_INCREMENT,
* to avoid flooding the log with a new message every time we get a few more
@@ -7095,23 +7100,46 @@ static int bootstrap_problems = 0;
*/
#define BOOTSTRAP_PCT_INCREMENT 5
+/** Do the actual logging and notifications for
+ * control_event_bootstrap(). Doesn't change any state beyond that.
+ */
+static void
+control_event_bootstrap_core(int loglevel, bootstrap_status_t status,
+ int progress)
+{
+ char buf[BOOTSTRAP_MSG_LEN];
+ const char *tag, *summary;
+
+ bootstrap_status_to_string(status, &tag, &summary);
+ /* Locally reset status if there's incremental progress */
+ if (progress)
+ status = progress;
+
+ tor_log(loglevel, LD_CONTROL,
+ "Bootstrapped %d%%: %s", status, summary);
+ tor_snprintf(buf, sizeof(buf),
+ "BOOTSTRAP PROGRESS=%d TAG=%s SUMMARY=\"%s\"",
+ status, tag, summary);
+ tor_snprintf(last_sent_bootstrap_message,
+ sizeof(last_sent_bootstrap_message),
+ "NOTICE %s", buf);
+ control_event_client_status(LOG_NOTICE, "%s", buf);
+}
+
/** 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>progress</b> is zero if we just started this task, else it
* represents progress on the task.
- *
- * Return true if we logged a message at level NOTICE, and false otherwise.
*/
-int
+void
control_event_bootstrap(bootstrap_status_t status, int progress)
{
- const char *tag, *summary;
- char buf[BOOTSTRAP_MSG_LEN];
+ int loglevel = LOG_NOTICE;
if (bootstrap_percent == BOOTSTRAP_STATUS_DONE)
- return 0; /* already bootstrapped; nothing to be done here. */
+ return; /* 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. */
@@ -7123,45 +7151,70 @@ control_event_bootstrap(bootstrap_status_t status, int progress)
}
}
- if (status > bootstrap_percent ||
- (progress && progress > bootstrap_percent)) {
- int loglevel = LOG_NOTICE;
- bootstrap_status_to_string(status, &tag, &summary);
-
- if (status <= bootstrap_percent &&
- (progress < notice_bootstrap_percent + BOOTSTRAP_PCT_INCREMENT)) {
- /* We log the message at info if the status hasn't advanced, and if less
- * than BOOTSTRAP_PCT_INCREMENT progress has been made.
- */
+ if (status <= bootstrap_percent) {
+ /* If there's no new progress, return early. */
+ if (!progress || progress <= bootstrap_percent)
+ return;
+ /* Log at INFO if not enough progress happened. */
+ if (progress < notice_bootstrap_percent + BOOTSTRAP_PCT_INCREMENT)
loglevel = LOG_INFO;
- }
+ }
- tor_log(loglevel, LD_CONTROL,
- "Bootstrapped %d%%: %s", progress ? progress : status, summary);
- tor_snprintf(buf, sizeof(buf),
- "BOOTSTRAP PROGRESS=%d TAG=%s SUMMARY=\"%s\"",
- progress ? progress : status, tag, summary);
- tor_snprintf(last_sent_bootstrap_message,
- sizeof(last_sent_bootstrap_message),
- "NOTICE %s", buf);
- control_event_client_status(LOG_NOTICE, "%s", buf);
- if (status > bootstrap_percent) {
- bootstrap_percent = status; /* new milestone reached */
- }
- if (progress > bootstrap_percent) {
- /* incremental progress within a milestone */
- bootstrap_percent = progress;
- bootstrap_problems = 0; /* Progress! Reset our problem counter. */
- }
- if (loglevel == LOG_NOTICE &&
- bootstrap_percent > notice_bootstrap_percent) {
- /* Remember that we gave a notice at this level. */
- notice_bootstrap_percent = bootstrap_percent;
- }
- return loglevel == LOG_NOTICE;
+ control_event_bootstrap_core(loglevel, status, progress);
+
+ if (status > bootstrap_percent) {
+ bootstrap_phase = status; /* new milestone reached */
+ bootstrap_percent = status;
+ }
+ if (progress > bootstrap_percent) {
+ /* incremental progress within a milestone */
+ bootstrap_percent = progress;
+ bootstrap_problems = 0; /* Progress! Reset our problem counter. */
}
+ if (loglevel == LOG_NOTICE &&
+ bootstrap_percent > notice_bootstrap_percent) {
+ /* Remember that we gave a notice at this level. */
+ notice_bootstrap_percent = bootstrap_percent;
+ }
+}
- return 0;
+/** Flag whether we've opened an OR_CONN yet */
+static int bootstrap_first_orconn = 0;
+
+/** Like bootstrap_phase, but for (possibly deferred) directory progress */
+static int bootstrap_dir_phase = BOOTSTRAP_STATUS_UNDEF;
+
+/** Like bootstrap_problems, but for (possibly deferred) directory progress */
+static int bootstrap_dir_progress = BOOTSTRAP_STATUS_UNDEF;
+
+/** Defer directory info bootstrap events until we have successfully
+ * completed our first connection to a router. */
+void
+control_event_boot_dir(bootstrap_status_t status, int progress)
+{
+ if (status > bootstrap_dir_progress) {
+ bootstrap_dir_progress = status;
+ bootstrap_dir_phase = status;
+ }
+ if (progress && progress >= bootstrap_dir_progress) {
+ bootstrap_dir_progress = progress;
+ }
+
+ /* Don't report unless we have successfully opened at least one OR_CONN */
+ if (!bootstrap_first_orconn)
+ return;
+
+ control_event_bootstrap(status, progress);
+}
+
+/** Set a flag to allow reporting of directory bootstrap progress.
+ * (Code that reports completion of an OR_CONN calls this.) Also,
+ * report directory progress so far. */
+void
+control_event_boot_first_orconn(void)
+{
+ bootstrap_first_orconn = 1;
+ control_event_bootstrap(bootstrap_dir_phase, bootstrap_dir_progress);
}
/** Called when Tor has failed to make bootstrapping progress in a way
@@ -7198,9 +7251,7 @@ control_event_bootstrap_problem(const char *warn, const char *reason,
if (we_are_hibernating())
dowarn = 0;
- while (status>=0 && bootstrap_status_to_string(status, &tag, &summary) < 0)
- status--; /* find a recognized status string based on current progress */
- status = bootstrap_percent; /* set status back to the actual number */
+ tor_assert(bootstrap_status_to_string(bootstrap_phase, &tag, &summary) == 0);
severity = dowarn ? LOG_WARN : LOG_INFO;
diff --git a/src/feature/control/control.h b/src/feature/control/control.h
index 5c5fe8a917..3445eb0a9d 100644
--- a/src/feature/control/control.h
+++ b/src/feature/control/control.h
@@ -191,10 +191,12 @@ void enable_control_logging(void);
void monitor_owning_controller_process(const char *process_spec);
-int control_event_bootstrap(bootstrap_status_t status, int progress);
+void control_event_bootstrap(bootstrap_status_t status, int progress);
MOCK_DECL(void, control_event_bootstrap_prob_or,(const char *warn,
int reason,
or_connection_t *or_conn));
+void control_event_boot_dir(bootstrap_status_t status, int progress);
+void control_event_boot_first_orconn(void);
void control_event_bootstrap_problem(const char *warn, const char *reason,
const connection_t *conn, int dowarn);
diff --git a/src/feature/dircache/directory.c b/src/feature/dircache/directory.c
index de0bcdbfa7..b94c5317af 100644
--- a/src/feature/dircache/directory.c
+++ b/src/feature/dircache/directory.c
@@ -2226,8 +2226,8 @@ load_downloaded_routers(const char *body, smartlist_t *which,
added = router_load_routers_from_string(body, NULL, SAVED_NOWHERE, which,
descriptor_digests, buf);
if (added && general)
- control_event_bootstrap(BOOTSTRAP_STATUS_LOADING_DESCRIPTORS,
- count_loading_descriptors_progress());
+ control_event_boot_dir(BOOTSTRAP_STATUS_LOADING_DESCRIPTORS,
+ count_loading_descriptors_progress());
return added;
}
@@ -2949,8 +2949,8 @@ handle_response_fetch_microdesc(dir_connection_t *conn,
dir_microdesc_download_failed(which, status_code, conn->identity_digest);
}
if (mds && smartlist_len(mds)) {
- control_event_bootstrap(BOOTSTRAP_STATUS_LOADING_DESCRIPTORS,
- count_loading_descriptors_progress());
+ control_event_boot_dir(BOOTSTRAP_STATUS_LOADING_DESCRIPTORS,
+ count_loading_descriptors_progress());
directory_info_has_arrived(now, 0, 1);
}
SMARTLIST_FOREACH(which, char *, cp, tor_free(cp));
diff --git a/src/feature/hs/hs_client.c b/src/feature/hs/hs_client.c
index 6f031eb3b9..a6384b87a3 100644
--- a/src/feature/hs/hs_client.c
+++ b/src/feature/hs/hs_client.c
@@ -1524,10 +1524,9 @@ parse_auth_file_content(const char *client_key_str)
if (seckey_b32) {
memwipe(seckey_b32, 0, strlen(seckey_b32));
}
- if (fields) {
- SMARTLIST_FOREACH(fields, char *, s, tor_free(s));
- smartlist_free(fields);
- }
+ tor_assert(fields);
+ SMARTLIST_FOREACH(fields, char *, s, tor_free(s));
+ smartlist_free(fields);
return auth;
}
diff --git a/src/feature/hs/hs_service.c b/src/feature/hs/hs_service.c
index 15f3478596..b01f9f0adf 100644
--- a/src/feature/hs/hs_service.c
+++ b/src/feature/hs/hs_service.c
@@ -1193,10 +1193,9 @@ parse_authorized_client(const char *client_key_str)
if (pubkey_b32) {
memwipe(pubkey_b32, 0, strlen(pubkey_b32));
}
- if (fields) {
- SMARTLIST_FOREACH(fields, char *, s, tor_free(s));
- smartlist_free(fields);
- }
+ tor_assert(fields);
+ SMARTLIST_FOREACH(fields, char *, s, tor_free(s));
+ smartlist_free(fields);
return client;
}
diff --git a/src/feature/nodelist/nodelist.c b/src/feature/nodelist/nodelist.c
index e62e87ea70..50dc8f7d3c 100644
--- a/src/feature/nodelist/nodelist.c
+++ b/src/feature/nodelist/nodelist.c
@@ -2528,7 +2528,7 @@ update_router_have_minimum_dir_info(void)
(int)(paths*100), status);
tor_free(status);
res = 0;
- control_event_bootstrap(BOOTSTRAP_STATUS_REQUESTING_DESCRIPTORS, 0);
+ control_event_boot_dir(BOOTSTRAP_STATUS_REQUESTING_DESCRIPTORS, 0);
goto done;
}
@@ -2553,10 +2553,9 @@ update_router_have_minimum_dir_info(void)
/* If paths have just become available in this update. */
if (res && !have_min_dir_info) {
control_event_client_status(LOG_NOTICE, "ENOUGH_DIR_INFO");
- if (control_event_bootstrap(BOOTSTRAP_STATUS_CONN_OR, 0) == 0) {
- log_notice(LD_DIR,
- "We now have enough directory information to build circuits.");
- }
+ control_event_boot_dir(BOOTSTRAP_STATUS_CONN_OR, 0);
+ log_info(LD_DIR,
+ "We now have enough directory information to build circuits.");
}
/* If paths have just become unavailable in this update. */