mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-30 23:53:32 +01:00
patch from karsten:
Resolved problems with (re-)fetching hidden service descriptors. Before, v0 descriptors were not fetched at all (fix on 0.2.0.18-alpha), re-fetching of v2 descriptors did not stop when a v0 descriptor was received (fix on 0.2.0.18-alpha), and re-fetching of v2 descriptors did not work in all cases (fix on 0.2.0.19-alpha). svn:r13540
This commit is contained in:
parent
6366dcd8ee
commit
bd959adcb7
@ -2436,11 +2436,13 @@ connection_get_by_type_state(int type, int state)
|
|||||||
|
|
||||||
/** Return a connection of type <b>type</b> that has rendquery equal
|
/** Return a connection of type <b>type</b> that has rendquery equal
|
||||||
* to <b>rendquery</b>, and that is not marked for close. If state
|
* to <b>rendquery</b>, and that is not marked for close. If state
|
||||||
* is non-zero, conn must be of that state too.
|
* is non-zero, conn must be of that state too. If rendversion is
|
||||||
|
* nonnegative, conn must fetch that rendversion, too.
|
||||||
*/
|
*/
|
||||||
connection_t *
|
connection_t *
|
||||||
connection_get_by_type_state_rendquery(int type, int state,
|
connection_get_by_type_state_rendquery(int type, int state,
|
||||||
const char *rendquery)
|
const char *rendquery,
|
||||||
|
int rendversion)
|
||||||
{
|
{
|
||||||
smartlist_t *conns = get_connection_array();
|
smartlist_t *conns = get_connection_array();
|
||||||
|
|
||||||
@ -2453,6 +2455,8 @@ connection_get_by_type_state_rendquery(int type, int state,
|
|||||||
!conn->marked_for_close &&
|
!conn->marked_for_close &&
|
||||||
(!state || state == conn->state)) {
|
(!state || state == conn->state)) {
|
||||||
if (type == CONN_TYPE_DIR &&
|
if (type == CONN_TYPE_DIR &&
|
||||||
|
(rendversion < 0 ||
|
||||||
|
rendversion == TO_DIR_CONN(conn)->rend_version) &&
|
||||||
!rend_cmp_service_ids(rendquery, TO_DIR_CONN(conn)->rend_query))
|
!rend_cmp_service_ids(rendquery, TO_DIR_CONN(conn)->rend_query))
|
||||||
return conn;
|
return conn;
|
||||||
else if (CONN_IS_EDGE(conn) &&
|
else if (CONN_IS_EDGE(conn) &&
|
||||||
|
@ -880,6 +880,7 @@ directory_send_command(dir_connection_t *conn,
|
|||||||
tor_assert(strlen(resource) <= REND_SERVICE_ID_LEN_BASE32);
|
tor_assert(strlen(resource) <= REND_SERVICE_ID_LEN_BASE32);
|
||||||
/* This breaks the function abstraction. */
|
/* This breaks the function abstraction. */
|
||||||
strlcpy(conn->rend_query, resource, sizeof(conn->rend_query));
|
strlcpy(conn->rend_query, resource, sizeof(conn->rend_query));
|
||||||
|
conn->rend_version = 0;
|
||||||
|
|
||||||
httpcommand = "GET";
|
httpcommand = "GET";
|
||||||
/* Request the most recent versioned descriptor. */
|
/* Request the most recent versioned descriptor. */
|
||||||
@ -894,6 +895,7 @@ directory_send_command(dir_connection_t *conn,
|
|||||||
tor_assert(strlen(resource) <= REND_DESC_ID_V2_LEN_BASE32);
|
tor_assert(strlen(resource) <= REND_DESC_ID_V2_LEN_BASE32);
|
||||||
/* Remember the query to refer to it when a response arrives. */
|
/* Remember the query to refer to it when a response arrives. */
|
||||||
strlcpy(conn->rend_query, payload, sizeof(conn->rend_query));
|
strlcpy(conn->rend_query, payload, sizeof(conn->rend_query));
|
||||||
|
conn->rend_version = 2;
|
||||||
payload = NULL;
|
payload = NULL;
|
||||||
httpcommand = "GET";
|
httpcommand = "GET";
|
||||||
len = strlen(resource) + 32;
|
len = strlen(resource) + 32;
|
||||||
|
@ -1053,6 +1053,9 @@ typedef struct dir_connection_t {
|
|||||||
/** The zlib object doing on-the-fly compression for spooled data. */
|
/** The zlib object doing on-the-fly compression for spooled data. */
|
||||||
tor_zlib_state_t *zlib_state;
|
tor_zlib_state_t *zlib_state;
|
||||||
|
|
||||||
|
/** What hidden service descriptor are we fetching, if any? */
|
||||||
|
int rend_version;
|
||||||
|
|
||||||
/** What rendezvous service are we querying for? */
|
/** What rendezvous service are we querying for? */
|
||||||
char rend_query[REND_SERVICE_ID_LEN_BASE32+1];
|
char rend_query[REND_SERVICE_ID_LEN_BASE32+1];
|
||||||
|
|
||||||
@ -2751,7 +2754,8 @@ connection_t *connection_get_by_type_addr_port_purpose(int type, uint32_t addr,
|
|||||||
uint16_t port, int purpose);
|
uint16_t port, int purpose);
|
||||||
connection_t *connection_get_by_type_state(int type, int state);
|
connection_t *connection_get_by_type_state(int type, int state);
|
||||||
connection_t *connection_get_by_type_state_rendquery(int type, int state,
|
connection_t *connection_get_by_type_state_rendquery(int type, int state,
|
||||||
const char *rendquery);
|
const char *rendquery,
|
||||||
|
int rendversion);
|
||||||
|
|
||||||
#define connection_speaks_cells(conn) ((conn)->type == CONN_TYPE_OR)
|
#define connection_speaks_cells(conn) ((conn)->type == CONN_TYPE_OR)
|
||||||
int connection_is_listener(connection_t *conn);
|
int connection_is_listener(connection_t *conn);
|
||||||
|
@ -401,7 +401,7 @@ rend_client_refetch_renddesc(const char *query)
|
|||||||
return;
|
return;
|
||||||
log_info(LD_REND, "Fetching rendezvous descriptor for service %s",
|
log_info(LD_REND, "Fetching rendezvous descriptor for service %s",
|
||||||
escaped_safe_str(query));
|
escaped_safe_str(query));
|
||||||
if (connection_get_by_type_state_rendquery(CONN_TYPE_DIR, 0, query)) {
|
if (connection_get_by_type_state_rendquery(CONN_TYPE_DIR, 0, query, 0)) {
|
||||||
log_info(LD_REND,"Would fetch a new renddesc here (for %s), but one is "
|
log_info(LD_REND,"Would fetch a new renddesc here (for %s), but one is "
|
||||||
"already in progress.", escaped_safe_str(query));
|
"already in progress.", escaped_safe_str(query));
|
||||||
} else {
|
} else {
|
||||||
@ -421,6 +421,7 @@ rend_client_refetch_v2_renddesc(const char *query)
|
|||||||
char descriptor_id[DIGEST_LEN];
|
char descriptor_id[DIGEST_LEN];
|
||||||
int replicas_left_to_try[REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS];
|
int replicas_left_to_try[REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS];
|
||||||
int i, tries_left;
|
int i, tries_left;
|
||||||
|
rend_cache_entry_t *e = NULL;
|
||||||
tor_assert(query);
|
tor_assert(query);
|
||||||
tor_assert(strlen(query) == REND_SERVICE_ID_LEN_BASE32);
|
tor_assert(strlen(query) == REND_SERVICE_ID_LEN_BASE32);
|
||||||
/* Are we configured to fetch descriptors? */
|
/* Are we configured to fetch descriptors? */
|
||||||
@ -429,6 +430,12 @@ rend_client_refetch_v2_renddesc(const char *query)
|
|||||||
"service descriptor, but are not fetching service descriptors.");
|
"service descriptor, but are not fetching service descriptors.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/* Before fetching, check if we already have the descriptor here. */
|
||||||
|
if (rend_cache_lookup_entry(query, -1, &e) > 0) {
|
||||||
|
log_info(LD_REND, "We would fetch a v2 rendezvous descriptor, but we "
|
||||||
|
"already have that descriptor here. Not fetching.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
log_debug(LD_REND, "Fetching v2 rendezvous descriptor for service %s",
|
log_debug(LD_REND, "Fetching v2 rendezvous descriptor for service %s",
|
||||||
safe_str(query));
|
safe_str(query));
|
||||||
/* Randomly iterate over the replicas until a descriptor can be fetched
|
/* Randomly iterate over the replicas until a descriptor can be fetched
|
||||||
@ -506,7 +513,7 @@ rend_client_remove_intro_point(extend_info_t *failed_intro, const char *query)
|
|||||||
|
|
||||||
/* move all pending streams back to renddesc_wait */
|
/* move all pending streams back to renddesc_wait */
|
||||||
while ((conn = connection_get_by_type_state_rendquery(CONN_TYPE_AP,
|
while ((conn = connection_get_by_type_state_rendquery(CONN_TYPE_AP,
|
||||||
AP_CONN_STATE_CIRCUIT_WAIT, query))) {
|
AP_CONN_STATE_CIRCUIT_WAIT, query, -1))) {
|
||||||
conn->state = AP_CONN_STATE_RENDDESC_WAIT;
|
conn->state = AP_CONN_STATE_RENDDESC_WAIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user