mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-27 22:03:31 +01:00
Merge remote-tracking branch 'dgoulet/bug14391_026_v2'
This commit is contained in:
commit
8837cc266e
@ -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'",
|
log_info(LD_REND,"Got a hidden service request for ID '%s'",
|
||||||
safe_str_client(rend_data->onion_address));
|
safe_str_client(rend_data->onion_address));
|
||||||
|
|
||||||
/* see if we already have a hidden service descriptor cached for this
|
/* Lookup the given onion address. If invalid, stop right now else we
|
||||||
* address. */
|
* 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;
|
rend_cache_entry_t *entry = NULL;
|
||||||
const int rend_cache_lookup_result =
|
const int rend_cache_lookup_result =
|
||||||
rend_cache_lookup_entry(rend_data->onion_address, -1, &entry);
|
rend_cache_lookup_entry(rend_data->onion_address, -1, &entry);
|
||||||
if (rend_cache_lookup_result < 0) {
|
if (rend_cache_lookup_result < 0) {
|
||||||
|
switch (-rend_cache_lookup_result) {
|
||||||
|
case EINVAL:
|
||||||
/* We should already have rejected this address! */
|
/* We should already have rejected this address! */
|
||||||
log_warn(LD_BUG,"Invalid service name '%s'",
|
log_warn(LD_BUG,"Invalid service name '%s'",
|
||||||
safe_str_client(rend_data->onion_address));
|
safe_str_client(rend_data->onion_address));
|
||||||
connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
|
connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
|
||||||
return -1;
|
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
|
/* Help predict this next time. We're not sure if it will need
|
||||||
* a stable circuit yet, but we know we'll need *something*. */
|
* a stable circuit yet, but we know we'll need *something*. */
|
||||||
rep_hist_note_used_internal(now, 0, 1);
|
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
|
/* Look up if we have client authorization configured for this hidden
|
||||||
* service. If we do, associate it with the rend_data. */
|
* service. If we do, associate it with the rend_data. */
|
||||||
rend_service_authorization_t *client_auth =
|
rend_service_authorization_t *client_auth =
|
||||||
@ -1538,15 +1560,7 @@ connection_ap_handshake_rewrite_and_attach(entry_connection_t *conn,
|
|||||||
rend_data->auth_type = client_auth->auth_type;
|
rend_data->auth_type = client_auth->auth_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now, we either launch an attempt to connect to the hidden service,
|
/* We have the descriptor so launch a connection to the HS. */
|
||||||
* 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;
|
base_conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
|
||||||
log_info(LD_REND, "Descriptor is here. Great.");
|
log_info(LD_REND, "Descriptor is here. Great.");
|
||||||
if (connection_ap_handshake_attach_circuit(conn) < 0) {
|
if (connection_ap_handshake_attach_circuit(conn) < 0) {
|
||||||
@ -1554,7 +1568,6 @@ connection_ap_handshake_rewrite_and_attach(entry_connection_t *conn,
|
|||||||
connection_mark_unattached_ap(conn, END_STREAM_REASON_CANT_ATTACH);
|
connection_mark_unattached_ap(conn, END_STREAM_REASON_CANT_ATTACH);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ rend_client_send_introduction(origin_circuit_t *introcirc,
|
|||||||
int r, v3_shift = 0;
|
int r, v3_shift = 0;
|
||||||
char payload[RELAY_PAYLOAD_SIZE];
|
char payload[RELAY_PAYLOAD_SIZE];
|
||||||
char tmp[RELAY_PAYLOAD_SIZE];
|
char tmp[RELAY_PAYLOAD_SIZE];
|
||||||
rend_cache_entry_t *entry;
|
rend_cache_entry_t *entry = NULL;
|
||||||
crypt_path_t *cpath;
|
crypt_path_t *cpath;
|
||||||
off_t dh_offset;
|
off_t dh_offset;
|
||||||
crypto_pk_t *intro_key = NULL;
|
crypto_pk_t *intro_key = NULL;
|
||||||
@ -158,8 +158,13 @@ rend_client_send_introduction(origin_circuit_t *introcirc,
|
|||||||
tor_assert(!(rendcirc->build_state->onehop_tunnel));
|
tor_assert(!(rendcirc->build_state->onehop_tunnel));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (rend_cache_lookup_entry(introcirc->rend_data->onion_address, -1,
|
r = rend_cache_lookup_entry(introcirc->rend_data->onion_address, -1,
|
||||||
&entry) < 1) {
|
&entry);
|
||||||
|
/* An invalid onion address is not possible else we have a big issue. */
|
||||||
|
tor_assert(r != -EINVAL);
|
||||||
|
if (r < 0 || !rend_client_any_intro_points_usable(entry)) {
|
||||||
|
/* If the descriptor is not found or the intro points are not usable
|
||||||
|
* anymore, trigger a fetch. */
|
||||||
log_info(LD_REND,
|
log_info(LD_REND,
|
||||||
"query %s didn't have valid rend desc in cache. "
|
"query %s didn't have valid rend desc in cache. "
|
||||||
"Refetching descriptor.",
|
"Refetching descriptor.",
|
||||||
@ -739,7 +744,7 @@ rend_client_refetch_v2_renddesc(const rend_data_t *rend_query)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Before fetching, check if we already have a usable descriptor here. */
|
/* Before fetching, check if we already have a usable descriptor here. */
|
||||||
if (rend_cache_lookup_entry(rend_query->onion_address, -1, &e) > 0 &&
|
if (rend_cache_lookup_entry(rend_query->onion_address, -1, &e) == 0 &&
|
||||||
rend_client_any_intro_points_usable(e)) {
|
rend_client_any_intro_points_usable(e)) {
|
||||||
log_info(LD_REND, "We would fetch a v2 rendezvous descriptor, but we "
|
log_info(LD_REND, "We would fetch a v2 rendezvous descriptor, but we "
|
||||||
"already have a usable descriptor here. Not fetching.");
|
"already have a usable descriptor here. Not fetching.");
|
||||||
@ -853,17 +858,26 @@ rend_client_report_intro_point_failure(extend_info_t *failed_intro,
|
|||||||
connection_t *conn;
|
connection_t *conn;
|
||||||
|
|
||||||
r = rend_cache_lookup_entry(rend_query->onion_address, -1, &ent);
|
r = rend_cache_lookup_entry(rend_query->onion_address, -1, &ent);
|
||||||
if (r<0) {
|
if (r < 0) {
|
||||||
|
/* Either invalid onion address or cache entry not found. */
|
||||||
|
switch (-r) {
|
||||||
|
case EINVAL:
|
||||||
log_warn(LD_BUG, "Malformed service ID %s.",
|
log_warn(LD_BUG, "Malformed service ID %s.",
|
||||||
escaped_safe_str_client(rend_query->onion_address));
|
escaped_safe_str_client(rend_query->onion_address));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
case ENOENT:
|
||||||
if (r==0) {
|
|
||||||
log_info(LD_REND, "Unknown service %s. Re-fetching descriptor.",
|
log_info(LD_REND, "Unknown service %s. Re-fetching descriptor.",
|
||||||
escaped_safe_str_client(rend_query->onion_address));
|
escaped_safe_str_client(rend_query->onion_address));
|
||||||
rend_client_refetch_v2_renddesc(rend_query);
|
rend_client_refetch_v2_renddesc(rend_query);
|
||||||
return 0;
|
return 0;
|
||||||
|
default:
|
||||||
|
log_warn(LD_BUG, "Unknown cache lookup returned code: %d", r);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
/* The intro points are not checked here if they are usable or not because
|
||||||
|
* this is called when an intro point circuit is closed thus there must be
|
||||||
|
* at least one intro point that is usable and is about to be flagged. */
|
||||||
|
|
||||||
for (i = 0; i < smartlist_len(ent->parsed->intro_nodes); i++) {
|
for (i = 0; i < smartlist_len(ent->parsed->intro_nodes); i++) {
|
||||||
rend_intro_point_t *intro = smartlist_get(ent->parsed->intro_nodes, i);
|
rend_intro_point_t *intro = smartlist_get(ent->parsed->intro_nodes, i);
|
||||||
@ -1062,7 +1076,7 @@ rend_client_desc_trynow(const char *query)
|
|||||||
continue;
|
continue;
|
||||||
assert_connection_ok(base_conn, now);
|
assert_connection_ok(base_conn, now);
|
||||||
if (rend_cache_lookup_entry(rend_data->onion_address, -1,
|
if (rend_cache_lookup_entry(rend_data->onion_address, -1,
|
||||||
&entry) == 1 &&
|
&entry) == 0 &&
|
||||||
rend_client_any_intro_points_usable(entry)) {
|
rend_client_any_intro_points_usable(entry)) {
|
||||||
/* either this fetch worked, or it failed but there was a
|
/* either this fetch worked, or it failed but there was a
|
||||||
* valid entry from before which we should reuse */
|
* valid entry from before which we should reuse */
|
||||||
@ -1126,13 +1140,17 @@ rend_client_note_connection_attempt_ended(const char *onion_address)
|
|||||||
extend_info_t *
|
extend_info_t *
|
||||||
rend_client_get_random_intro(const rend_data_t *rend_query)
|
rend_client_get_random_intro(const rend_data_t *rend_query)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
extend_info_t *result;
|
extend_info_t *result;
|
||||||
rend_cache_entry_t *entry;
|
rend_cache_entry_t *entry;
|
||||||
|
|
||||||
if (rend_cache_lookup_entry(rend_query->onion_address, -1, &entry) < 1) {
|
ret = rend_cache_lookup_entry(rend_query->onion_address, -1, &entry);
|
||||||
|
if (ret < 0 || !rend_client_any_intro_points_usable(entry)) {
|
||||||
log_warn(LD_REND,
|
log_warn(LD_REND,
|
||||||
"Query '%s' didn't have valid rend desc in cache. Failing.",
|
"Query '%s' didn't have valid rend desc in cache. Failing.",
|
||||||
safe_str_client(rend_query->onion_address));
|
safe_str_client(rend_query->onion_address));
|
||||||
|
/* XXX: Should we refetch the descriptor here if the IPs are not usable
|
||||||
|
* anymore ?. */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -919,36 +919,52 @@ rend_valid_service_id(const char *query)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** If we have a cached rend_cache_entry_t for the service ID <b>query</b>
|
/** Lookup in the client cache the given service ID <b>query</b> for
|
||||||
* with <b>version</b>, set *<b>e</b> to that entry and return 1.
|
* <b>version</b>.
|
||||||
* Else return 0. If <b>version</b> is nonnegative, only return an entry
|
*
|
||||||
* in that descriptor format version. Otherwise (if <b>version</b> is
|
* Return 0 if found and if <b>e</b> is non NULL, set it with the entry
|
||||||
* negative), return the most recent format we have.
|
* found. Else, a negative value is returned and <b>e</b> is untouched.
|
||||||
*/
|
* -EINVAL means that <b>query</b> is not a valid service id.
|
||||||
|
* -ENOENT means that no entry in the cache was found. */
|
||||||
int
|
int
|
||||||
rend_cache_lookup_entry(const char *query, int version, rend_cache_entry_t **e)
|
rend_cache_lookup_entry(const char *query, int version, rend_cache_entry_t **e)
|
||||||
{
|
{
|
||||||
char key[REND_SERVICE_ID_LEN_BASE32+2]; /* <version><query>\0 */
|
int ret = 0;
|
||||||
|
char key[REND_SERVICE_ID_LEN_BASE32 + 2]; /* <version><query>\0 */
|
||||||
|
rend_cache_entry_t *entry = NULL;
|
||||||
|
static const int default_version = 2;
|
||||||
|
|
||||||
tor_assert(rend_cache);
|
tor_assert(rend_cache);
|
||||||
if (!rend_valid_service_id(query))
|
tor_assert(query);
|
||||||
return -1;
|
|
||||||
*e = NULL;
|
if (!rend_valid_service_id(query)) {
|
||||||
if (version != 0) {
|
ret = -EINVAL;
|
||||||
tor_snprintf(key, sizeof(key), "2%s", query);
|
goto end;
|
||||||
*e = strmap_get_lc(rend_cache, key);
|
|
||||||
}
|
}
|
||||||
if (!*e && version != 2) {
|
|
||||||
tor_snprintf(key, sizeof(key), "0%s", query);
|
switch (version) {
|
||||||
*e = strmap_get_lc(rend_cache, key);
|
case 0:
|
||||||
|
log_warn(LD_REND, "Cache lookup of a v0 renddesc is deprecated.");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
/* Default is version 2. */
|
||||||
|
default:
|
||||||
|
tor_snprintf(key, sizeof(key), "%d%s", default_version, query);
|
||||||
|
entry = strmap_get_lc(rend_cache, key);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (!*e)
|
if (!entry) {
|
||||||
return 0;
|
ret = -ENOENT;
|
||||||
tor_assert((*e)->parsed && (*e)->parsed->intro_nodes);
|
goto end;
|
||||||
/* XXX023 hack for now, to return "not found" if there are no intro
|
}
|
||||||
* points remaining. See bug 997. */
|
tor_assert(entry->parsed && entry->parsed->intro_nodes);
|
||||||
if (! rend_client_any_intro_points_usable(*e))
|
|
||||||
return 0;
|
if (e) {
|
||||||
return 1;
|
*e = entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Lookup the v2 service descriptor with base32-encoded <b>desc_id</b> and
|
/** Lookup the v2 service descriptor with base32-encoded <b>desc_id</b> and
|
||||||
|
Loading…
Reference in New Issue
Block a user