aboutsummaryrefslogtreecommitdiff
path: root/src/or/connection_edge.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2015-04-15 10:33:04 -0400
committerNick Mathewson <nickm@torproject.org>2015-04-15 10:33:04 -0400
commit8837cc266e44f8033f32a7d1a05020e585f034c7 (patch)
tree1b627b23567a717bad7355f4082f086b0831ae2e /src/or/connection_edge.c
parent7e6437babcea32c98cb028796bff1f81675b2c3b (diff)
parent91009dce971655f6b18b5eba5f0c0b48dbd8a737 (diff)
downloadtor-8837cc266e44f8033f32a7d1a05020e585f034c7.tar.gz
tor-8837cc266e44f8033f32a7d1a05020e585f034c7.zip
Merge remote-tracking branch 'dgoulet/bug14391_026_v2'
Diffstat (limited to 'src/or/connection_edge.c')
-rw-r--r--src/or/connection_edge.c59
1 files changed, 36 insertions, 23 deletions
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 2a1a2f0fd2..670905f136 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -1508,23 +1508,45 @@ connection_ap_handshake_rewrite_and_attach(entry_connection_t *conn,
log_info(LD_REND,"Got a hidden service request for ID '%s'",
safe_str_client(rend_data->onion_address));
- /* see if we already have a hidden service descriptor cached for this
- * address. */
+ /* Lookup the given onion address. If invalid, stop right now else we
+ * might have it in the cache or not, it will be tested later on. */
+ unsigned int refetch_desc = 0;
rend_cache_entry_t *entry = NULL;
const int rend_cache_lookup_result =
rend_cache_lookup_entry(rend_data->onion_address, -1, &entry);
if (rend_cache_lookup_result < 0) {
- /* We should already have rejected this address! */
- log_warn(LD_BUG,"Invalid service name '%s'",
- safe_str_client(rend_data->onion_address));
- connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
- return -1;
+ switch (-rend_cache_lookup_result) {
+ case EINVAL:
+ /* We should already have rejected this address! */
+ log_warn(LD_BUG,"Invalid service name '%s'",
+ safe_str_client(rend_data->onion_address));
+ connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
+ return -1;
+ case ENOENT:
+ refetch_desc = 1;
+ break;
+ default:
+ log_warn(LD_BUG, "Unknown cache lookup error %d",
+ rend_cache_lookup_result);
+ return -1;
+ }
}
/* Help predict this next time. We're not sure if it will need
* a stable circuit yet, but we know we'll need *something*. */
rep_hist_note_used_internal(now, 0, 1);
+ /* Now we have a descriptor but is it usable or not? If not, refetch.
+ * Also, a fetch could have been requested if the onion address was not
+ * found in the cache previously. */
+ if (refetch_desc || !rend_client_any_intro_points_usable(entry)) {
+ base_conn->state = AP_CONN_STATE_RENDDESC_WAIT;
+ log_info(LD_REND, "Unknown descriptor %s. Fetching.",
+ safe_str_client(rend_data->onion_address));
+ rend_client_refetch_v2_renddesc(rend_data);
+ return 0;
+ }
+
/* Look up if we have client authorization configured for this hidden
* service. If we do, associate it with the rend_data. */
rend_service_authorization_t *client_auth =
@@ -1538,22 +1560,13 @@ connection_ap_handshake_rewrite_and_attach(entry_connection_t *conn,
rend_data->auth_type = client_auth->auth_type;
}
- /* Now, we either launch an attempt to connect to the hidden service,
- * or we launch an attempt to look up its descriptor, depending on
- * whether we had the descriptor. */
- if (rend_cache_lookup_result == 0) {
- base_conn->state = AP_CONN_STATE_RENDDESC_WAIT;
- log_info(LD_REND, "Unknown descriptor %s. Fetching.",
- safe_str_client(rend_data->onion_address));
- rend_client_refetch_v2_renddesc(rend_data);
- } else { /* rend_cache_lookup_result > 0 */
- base_conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
- log_info(LD_REND, "Descriptor is here. Great.");
- if (connection_ap_handshake_attach_circuit(conn) < 0) {
- if (!base_conn->marked_for_close)
- connection_mark_unattached_ap(conn, END_STREAM_REASON_CANT_ATTACH);
- return -1;
- }
+ /* We have the descriptor so launch a connection to the HS. */
+ base_conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
+ log_info(LD_REND, "Descriptor is here. Great.");
+ if (connection_ap_handshake_attach_circuit(conn) < 0) {
+ if (!base_conn->marked_for_close)
+ connection_mark_unattached_ap(conn, END_STREAM_REASON_CANT_ATTACH);
+ return -1;
}
return 0;
}