summaryrefslogtreecommitdiff
path: root/src/or/hs_client.c
diff options
context:
space:
mode:
authorDavid Goulet <dgoulet@torproject.org>2017-07-21 14:32:47 -0400
committerDavid Goulet <dgoulet@torproject.org>2017-08-24 13:03:28 -0400
commitc38144bb0f1a38cd4d72b60efd038aab63182b8b (patch)
tree79b37f66edd1d2e1d785ddbb240bc0a1e5b37d0a /src/or/hs_client.c
parent89eb96c19a091b1e892e4a7c05f06e188131aed0 (diff)
downloadtor-c38144bb0f1a38cd4d72b60efd038aab63182b8b.tar.gz
tor-c38144bb0f1a38cd4d72b60efd038aab63182b8b.zip
prop224: Client callback when descriptor has arrived
When a descriptor fetch has completed and it has been successfully stored in the client cache, this callback will take appropriate actions to attach streams and/or launch neede circuits to connect to the service. Signed-off-by: David Goulet <dgoulet@torproject.org>
Diffstat (limited to 'src/or/hs_client.c')
-rw-r--r--src/or/hs_client.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/or/hs_client.c b/src/or/hs_client.c
index 2674e2c1e7..cf9bdba5a4 100644
--- a/src/or/hs_client.c
+++ b/src/or/hs_client.c
@@ -24,6 +24,7 @@
#include "circuituse.h"
#include "connection.h"
#include "circpathbias.h"
+#include "connection.h"
/* Get all connections that are waiting on a circuit and flag them back to
* waiting for a hidden service descriptor for the given service key
@@ -580,3 +581,65 @@ hs_client_receive_rendezvous_acked(origin_circuit_t *circ,
return -1;
}
+/* This is called when a descriptor has arrived following a fetch request and
+ * has been stored in the client cache. Every entry connection that matches
+ * the service identity key in the ident will get attached to the hidden
+ * service circuit. */
+void
+hs_client_desc_has_arrived(const hs_ident_dir_conn_t *ident)
+{
+ time_t now = time(NULL);
+ smartlist_t *conns = NULL;
+
+ tor_assert(ident);
+
+ conns = connection_list_by_type_state(CONN_TYPE_AP,
+ AP_CONN_STATE_RENDDESC_WAIT);
+ SMARTLIST_FOREACH_BEGIN(conns, connection_t *, base_conn) {
+ const hs_descriptor_t *desc;
+ entry_connection_t *entry_conn = TO_ENTRY_CONN(base_conn);
+ const edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(entry_conn);
+
+ /* Only consider the entry connections that matches the service for which
+ * we just fetched its descriptor. */
+ if (!edge_conn->hs_ident ||
+ !ed25519_pubkey_eq(&ident->identity_pk,
+ &edge_conn->hs_ident->identity_pk)) {
+ continue;
+ }
+ assert_connection_ok(base_conn, now);
+
+ /* We were just called because we stored the descriptor for this service
+ * so not finding a descriptor means we have a bigger problem. */
+ desc = hs_cache_lookup_as_client(&ident->identity_pk);
+ if (BUG(desc == NULL)) {
+ goto end;
+ }
+
+ if (!hs_client_any_intro_points_usable(desc)) {
+ log_info(LD_REND, "Hidden service descriptor is unusable. "
+ "Closing streams.");
+ connection_mark_unattached_ap(entry_conn,
+ END_STREAM_REASON_RESOLVEFAILED);
+ /* XXX: Note the connection attempt. */
+ goto end;
+ }
+
+ log_info(LD_REND, "Descriptor has arrived. Launching circuits.");
+
+ /* Restart their timeout values, so they get a fair shake at connecting to
+ * the hidden service. XXX: Improve comment on why this is needed. */
+ base_conn->timestamp_created = now;
+ base_conn->timestamp_lastread = now;
+ base_conn->timestamp_lastwritten = 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);
+ } SMARTLIST_FOREACH_END(base_conn);
+
+ end:
+ /* We don't have ownership of the objects in this list. */
+ smartlist_free(conns);
+}
+