mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-28 14:23:30 +01:00
if the rend desc cache entry was fetched more than 15 mins ago,
then try to fetch a new one. but if the new fetch fails, use the old one. svn:r1540
This commit is contained in:
parent
09e66bbd14
commit
e79a578fec
@ -178,9 +178,12 @@ _connection_mark_for_close(connection_t *conn, char reason)
|
|||||||
case CONN_TYPE_AP_LISTENER:
|
case CONN_TYPE_AP_LISTENER:
|
||||||
case CONN_TYPE_DIR_LISTENER:
|
case CONN_TYPE_DIR_LISTENER:
|
||||||
case CONN_TYPE_CPUWORKER:
|
case CONN_TYPE_CPUWORKER:
|
||||||
case CONN_TYPE_DIR:
|
|
||||||
/* No special processing needed. */
|
/* No special processing needed. */
|
||||||
break;
|
break;
|
||||||
|
case CONN_TYPE_DIR:
|
||||||
|
if(conn->purpose == DIR_PURPOSE_FETCH_RENDDESC)
|
||||||
|
rend_client_desc_fetched(conn->rend_query, 0);
|
||||||
|
break;
|
||||||
case CONN_TYPE_OR:
|
case CONN_TYPE_OR:
|
||||||
/* Remember why we're closing this connection. */
|
/* Remember why we're closing this connection. */
|
||||||
if (conn->state != OR_CONN_STATE_OPEN) {
|
if (conn->state != OR_CONN_STATE_OPEN) {
|
||||||
|
@ -728,13 +728,14 @@ static int connection_ap_handshake_process_socks(connection_t *conn) {
|
|||||||
return connection_ap_handshake_attach_circuit(conn);
|
return connection_ap_handshake_attach_circuit(conn);
|
||||||
} else {
|
} else {
|
||||||
/* it's a hidden-service request */
|
/* it's a hidden-service request */
|
||||||
const char *descp;
|
rend_cache_entry_t *entry;
|
||||||
int desc_len;
|
|
||||||
|
|
||||||
strcpy(conn->rend_query, socks->address); /* this strcpy is safe -RD */
|
strcpy(conn->rend_query, socks->address); /* this strcpy is safe -RD */
|
||||||
log_fn(LOG_INFO,"Got a hidden service request for ID '%s'", conn->rend_query);
|
log_fn(LOG_INFO,"Got a hidden service request for ID '%s'", conn->rend_query);
|
||||||
/* see if we already have it cached */
|
/* see if we already have it cached */
|
||||||
if (rend_cache_lookup_desc(conn->rend_query, &descp, &desc_len) == 1) {
|
if (rend_cache_lookup_entry(conn->rend_query, &entry) == 1 &&
|
||||||
|
#define NUM_SECONDS_BEFORE_REFETCH (60*15)
|
||||||
|
entry->received + NUM_SECONDS_BEFORE_REFETCH < time(NULL)) {
|
||||||
conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
|
conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
|
||||||
return connection_ap_handshake_attach_circuit(conn);
|
return connection_ap_handshake_attach_circuit(conn);
|
||||||
} else {
|
} else {
|
||||||
|
@ -275,16 +275,18 @@ int connection_dir_process_inbuf(connection_t *conn) {
|
|||||||
switch(status_code) {
|
switch(status_code) {
|
||||||
case 200:
|
case 200:
|
||||||
if(rend_cache_store(body, body_len) < 0) {
|
if(rend_cache_store(body, body_len) < 0) {
|
||||||
log_fn(LOG_WARN,"Failed to store rendezvous descriptor. Abandoning stream.");
|
log_fn(LOG_WARN,"Failed to store rendezvous descriptor.");
|
||||||
/* alice's ap_stream is just going to have to time out. */
|
/* alice's ap_stream will notice when connection_mark_for_close
|
||||||
|
* cleans it up */
|
||||||
} else {
|
} else {
|
||||||
/* success. notify pending connections about this. */
|
/* success. notify pending connections about this. */
|
||||||
rend_client_desc_fetched(conn->rend_query, 1);
|
rend_client_desc_fetched(conn->rend_query, 1);
|
||||||
|
conn->purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 404:
|
case 404:
|
||||||
/* not there. also notify pending connections. */
|
/* not there. pending connections will be notified when
|
||||||
rend_client_desc_fetched(conn->rend_query, 0);
|
* connection_mark_for_close cleans it up. */
|
||||||
break;
|
break;
|
||||||
case 400:
|
case 400:
|
||||||
log_fn(LOG_WARN,"http status 400 (bad request). Dirserver didn't like our rendezvous query?");
|
log_fn(LOG_WARN,"http status 400 (bad request). Dirserver didn't like our rendezvous query?");
|
||||||
|
@ -176,10 +176,11 @@
|
|||||||
#define _DIR_PURPOSE_MIN 1
|
#define _DIR_PURPOSE_MIN 1
|
||||||
#define DIR_PURPOSE_FETCH_DIR 1
|
#define DIR_PURPOSE_FETCH_DIR 1
|
||||||
#define DIR_PURPOSE_FETCH_RENDDESC 2
|
#define DIR_PURPOSE_FETCH_RENDDESC 2
|
||||||
#define DIR_PURPOSE_UPLOAD_DIR 3
|
#define DIR_PURPOSE_HAS_FETCHED_RENDDESC 3
|
||||||
#define DIR_PURPOSE_UPLOAD_RENDDESC 4
|
#define DIR_PURPOSE_UPLOAD_DIR 4
|
||||||
#define DIR_PURPOSE_SERVER 5
|
#define DIR_PURPOSE_UPLOAD_RENDDESC 5
|
||||||
#define _DIR_PURPOSE_MAX 5
|
#define DIR_PURPOSE_SERVER 6
|
||||||
|
#define _DIR_PURPOSE_MAX 6
|
||||||
|
|
||||||
#define CIRCUIT_STATE_BUILDING 0 /* I'm the OP, still haven't done all my handshakes */
|
#define CIRCUIT_STATE_BUILDING 0 /* I'm the OP, still haven't done all my handshakes */
|
||||||
#define CIRCUIT_STATE_ONIONSKIN_PENDING 1 /* waiting to process the onionskin */
|
#define CIRCUIT_STATE_ONIONSKIN_PENDING 1 /* waiting to process the onionskin */
|
||||||
|
@ -46,31 +46,24 @@ rend_client_send_establish_rendezvous(circuit_t *circ)
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
rend_client_send_introduction(circuit_t *introcirc, circuit_t *rendcirc) {
|
rend_client_send_introduction(circuit_t *introcirc, circuit_t *rendcirc) {
|
||||||
const char *descp;
|
int payload_len, r;
|
||||||
int desc_len, payload_len, r;
|
|
||||||
char payload[RELAY_PAYLOAD_SIZE];
|
char payload[RELAY_PAYLOAD_SIZE];
|
||||||
char tmp[(MAX_NICKNAME_LEN+1)+REND_COOKIE_LEN+DH_KEY_LEN];
|
char tmp[(MAX_NICKNAME_LEN+1)+REND_COOKIE_LEN+DH_KEY_LEN];
|
||||||
rend_service_descriptor_t *parsed=NULL;
|
rend_cache_entry_t *entry;
|
||||||
crypt_path_t *cpath;
|
crypt_path_t *cpath;
|
||||||
|
|
||||||
assert(introcirc->purpose == CIRCUIT_PURPOSE_C_INTRODUCING);
|
assert(introcirc->purpose == CIRCUIT_PURPOSE_C_INTRODUCING);
|
||||||
assert(rendcirc->purpose == CIRCUIT_PURPOSE_C_REND_READY);
|
assert(rendcirc->purpose == CIRCUIT_PURPOSE_C_REND_READY);
|
||||||
assert(!rend_cmp_service_ids(introcirc->rend_query, rendcirc->rend_query));
|
assert(!rend_cmp_service_ids(introcirc->rend_query, rendcirc->rend_query));
|
||||||
|
|
||||||
if(rend_cache_lookup_desc(introcirc->rend_query, &descp, &desc_len) < 1) {
|
if(rend_cache_lookup_entry(introcirc->rend_query, &entry) < 1) {
|
||||||
log_fn(LOG_WARN,"query '%s' didn't have valid rend desc in cache. Failing.",
|
log_fn(LOG_WARN,"query '%s' didn't have valid rend desc in cache. Failing.",
|
||||||
introcirc->rend_query);
|
introcirc->rend_query);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
parsed = rend_parse_service_descriptor(descp,desc_len);
|
|
||||||
if (!parsed) {
|
|
||||||
log_fn(LOG_WARN,"Couldn't parse service descriptor");
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* first 20 bytes of payload are the hash of bob's pk */
|
/* first 20 bytes of payload are the hash of bob's pk */
|
||||||
if (crypto_pk_get_digest(parsed->pk, payload)<0) {
|
if (crypto_pk_get_digest(entry->parsed->pk, payload)<0) {
|
||||||
log_fn(LOG_WARN, "Couldn't hash public key.");
|
log_fn(LOG_WARN, "Couldn't hash public key.");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@ -97,7 +90,7 @@ rend_client_send_introduction(circuit_t *introcirc, circuit_t *rendcirc) {
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = crypto_pk_public_hybrid_encrypt(parsed->pk, tmp,
|
r = crypto_pk_public_hybrid_encrypt(entry->parsed->pk, tmp,
|
||||||
MAX_NICKNAME_LEN+1+REND_COOKIE_LEN+DH_KEY_LEN,
|
MAX_NICKNAME_LEN+1+REND_COOKIE_LEN+DH_KEY_LEN,
|
||||||
payload+DIGEST_LEN,
|
payload+DIGEST_LEN,
|
||||||
PK_PKCS1_OAEP_PADDING, 0);
|
PK_PKCS1_OAEP_PADDING, 0);
|
||||||
@ -108,8 +101,6 @@ rend_client_send_introduction(circuit_t *introcirc, circuit_t *rendcirc) {
|
|||||||
|
|
||||||
payload_len = DIGEST_LEN + r;
|
payload_len = DIGEST_LEN + r;
|
||||||
|
|
||||||
rend_service_descriptor_free(parsed);
|
|
||||||
|
|
||||||
if (connection_edge_send_command(NULL, introcirc,
|
if (connection_edge_send_command(NULL, introcirc,
|
||||||
RELAY_COMMAND_INTRODUCE1,
|
RELAY_COMMAND_INTRODUCE1,
|
||||||
payload, payload_len,
|
payload, payload_len,
|
||||||
@ -124,8 +115,6 @@ rend_client_send_introduction(circuit_t *introcirc, circuit_t *rendcirc) {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
err:
|
err:
|
||||||
if(parsed)
|
|
||||||
rend_service_descriptor_free(parsed);
|
|
||||||
circuit_mark_for_close(introcirc);
|
circuit_mark_for_close(introcirc);
|
||||||
circuit_mark_for_close(rendcirc);
|
circuit_mark_for_close(rendcirc);
|
||||||
return -1;
|
return -1;
|
||||||
@ -239,6 +228,7 @@ void rend_client_desc_fetched(char *query, int success) {
|
|||||||
connection_t **carray;
|
connection_t **carray;
|
||||||
connection_t *conn;
|
connection_t *conn;
|
||||||
int n, i;
|
int n, i;
|
||||||
|
rend_cache_entry_t *entry;
|
||||||
|
|
||||||
get_connection_array(&carray, &n);
|
get_connection_array(&carray, &n);
|
||||||
|
|
||||||
@ -250,7 +240,10 @@ void rend_client_desc_fetched(char *query, int success) {
|
|||||||
if (rend_cmp_service_ids(conn->rend_query, query))
|
if (rend_cmp_service_ids(conn->rend_query, query))
|
||||||
continue;
|
continue;
|
||||||
/* great, this guy was waiting */
|
/* great, this guy was waiting */
|
||||||
if(success) {
|
if(success ||
|
||||||
|
rend_cache_lookup_entry(conn->rend_query, &entry) == 1) {
|
||||||
|
/* either this fetch worked, or it failed but there was a
|
||||||
|
* valid entry from before which we should reuse */
|
||||||
log_fn(LOG_INFO,"Rend desc retrieved. Launching circuits.");
|
log_fn(LOG_INFO,"Rend desc retrieved. Launching circuits.");
|
||||||
conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
|
conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
|
||||||
if (connection_ap_handshake_attach_circuit(conn) < 0) {
|
if (connection_ap_handshake_attach_circuit(conn) < 0) {
|
||||||
@ -258,8 +251,8 @@ void rend_client_desc_fetched(char *query, int success) {
|
|||||||
log_fn(LOG_WARN,"attaching to a rend circ failed. Closing conn.");
|
log_fn(LOG_WARN,"attaching to a rend circ failed. Closing conn.");
|
||||||
connection_mark_for_close(conn,0);
|
connection_mark_for_close(conn,0);
|
||||||
}
|
}
|
||||||
} else { /* 404 */
|
} else { /* 404, or fetch didn't get that far */
|
||||||
log_fn(LOG_WARN,"service id '%s' not found. Closing conn.", query);
|
log_fn(LOG_WARN,"service id '%s' fetched failed, and not in cache. Closing conn.", query);
|
||||||
connection_mark_for_close(conn,0);
|
connection_mark_for_close(conn,0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user