aboutsummaryrefslogtreecommitdiff
path: root/src/feature
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2019-01-11 18:53:24 -0500
committerNick Mathewson <nickm@torproject.org>2019-01-11 18:53:24 -0500
commitd21fa48cac0f41bd52306e269796559f75855323 (patch)
tree3f58bbe71874b15b205f47e7d7f7620388abbfbc /src/feature
parent5dd926caa670002c6d2f15ac78e2282c00c352b6 (diff)
parentefd765a94816bb216e81a4962c94bac385947719 (diff)
downloadtor-d21fa48cac0f41bd52306e269796559f75855323.tar.gz
tor-d21fa48cac0f41bd52306e269796559f75855323.zip
Merge branch 'maint-0.3.5'
Diffstat (limited to 'src/feature')
-rw-r--r--src/feature/hs/hs_client.c56
-rw-r--r--src/feature/rend/rendclient.c6
2 files changed, 39 insertions, 23 deletions
diff --git a/src/feature/hs/hs_client.c b/src/feature/hs/hs_client.c
index dfad216abb..5fded92fe3 100644
--- a/src/feature/hs/hs_client.c
+++ b/src/feature/hs/hs_client.c
@@ -142,8 +142,7 @@ flag_all_conn_wait_desc(const ed25519_public_key_t *service_identity_pk)
if (edge_conn->hs_ident &&
ed25519_pubkey_eq(&edge_conn->hs_ident->identity_pk,
service_identity_pk)) {
- connection_ap_mark_as_non_pending_circuit(TO_ENTRY_CONN(conn));
- conn->state = AP_CONN_STATE_RENDDESC_WAIT;
+ connection_ap_mark_as_waiting_for_renddesc(TO_ENTRY_CONN(conn));
}
} SMARTLIST_FOREACH_END(conn);
@@ -201,6 +200,26 @@ directory_request_is_pending(const ed25519_public_key_t *identity_pk)
return ret;
}
+/* Helper function that changes the state of an entry connection to waiting
+ * for a circuit. For this to work properly, the connection timestamps are set
+ * to now and the connection is then marked as pending for a circuit. */
+static void
+mark_conn_as_waiting_for_circuit(connection_t *conn, time_t now)
+{
+ tor_assert(conn);
+
+ /* Because the connection can now proceed to opening circuit and ultimately
+ * connect to the service, reset those timestamp so the connection is
+ * considered "fresh" and can continue without being closed too early. */
+ conn->timestamp_created = now;
+ conn->timestamp_last_read_allowed = now;
+ conn->timestamp_last_write_allowed = now;
+ /* Change connection's state into waiting for a circuit. */
+ conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
+
+ connection_ap_mark_as_pending_circuit(TO_ENTRY_CONN(conn));
+}
+
/* We failed to fetch a descriptor for the service with <b>identity_pk</b>
* because of <b>status</b>. Find all pending SOCKS connections for this
* service that are waiting on the descriptor and close them with
@@ -277,12 +296,19 @@ retry_all_socks_conn_waiting_for_desc(void)
/* Order a refetch in case it works this time. */
status = hs_client_refetch_hsdesc(&edge_conn->hs_ident->identity_pk);
- if (BUG(status == HS_CLIENT_FETCH_HAVE_DESC)) {
- /* This case is unique because it can NOT happen in theory. Once we get
- * a new descriptor, the HS client subsystem is notified immediately and
- * the connections waiting for it are handled which means the state will
- * change from renddesc wait state. Log this and continue to next
- * connection. */
+ if (status == HS_CLIENT_FETCH_HAVE_DESC) {
+ /* This is a rare case where a SOCKS connection is in state waiting for
+ * a descriptor but we do have it in the cache.
+ *
+ * This can happen is tor comes back from suspend where it previously
+ * had the descriptor but the intro points were not usuable. Once it
+ * came back to life, the intro point failure cache was cleaned up and
+ * thus the descriptor became usable again leaving us in this code path.
+ *
+ * We'll mark the connection as waiting for a circuit so the descriptor
+ * can be retried. This is safe because a connection in state waiting
+ * for a descriptor can not be in the entry connection pending list. */
+ mark_conn_as_waiting_for_circuit(base_conn, approx_time());
continue;
}
/* In the case of an error, either all SOCKS connections have been
@@ -1701,17 +1727,9 @@ hs_client_desc_has_arrived(const hs_ident_dir_conn_t *ident)
log_info(LD_REND, "Descriptor has arrived. Launching circuits.");
- /* Because the connection can now proceed to opening circuit and
- * ultimately connect to the service, reset those timestamp so the
- * connection is considered "fresh" and can continue without being closed
- * too early. */
- base_conn->timestamp_created = now;
- base_conn->timestamp_last_read_allowed = now;
- base_conn->timestamp_last_write_allowed = now;
- /* Change connection's state into waiting for a circuit. */
- base_conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
-
- connection_ap_mark_as_pending_circuit(entry_conn);
+ /* Mark connection as waiting for a circuit since we do have a usable
+ * descriptor now. */
+ mark_conn_as_waiting_for_circuit(base_conn, now);
} SMARTLIST_FOREACH_END(base_conn);
end:
diff --git a/src/feature/rend/rendclient.c b/src/feature/rend/rendclient.c
index 10b67ceda9..6ecb3eb3c6 100644
--- a/src/feature/rend/rendclient.c
+++ b/src/feature/rend/rendclient.c
@@ -150,8 +150,7 @@ rend_client_send_introduction(origin_circuit_t *introcirc,
while ((conn = connection_get_by_type_state_rendquery(CONN_TYPE_AP,
AP_CONN_STATE_CIRCUIT_WAIT, onion_address))) {
- connection_ap_mark_as_non_pending_circuit(TO_ENTRY_CONN(conn));
- conn->state = AP_CONN_STATE_RENDDESC_WAIT;
+ connection_ap_mark_as_waiting_for_renddesc(TO_ENTRY_CONN(conn));
}
}
@@ -864,8 +863,7 @@ rend_client_report_intro_point_failure(extend_info_t *failed_intro,
while ((conn = connection_get_by_type_state_rendquery(CONN_TYPE_AP,
AP_CONN_STATE_CIRCUIT_WAIT,
onion_address))) {
- connection_ap_mark_as_non_pending_circuit(TO_ENTRY_CONN(conn));
- conn->state = AP_CONN_STATE_RENDDESC_WAIT;
+ connection_ap_mark_as_waiting_for_renddesc(TO_ENTRY_CONN(conn));
}
return 0;