From e79a578feca34e01d4d71fa5c824f84fe649993a Mon Sep 17 00:00:00 2001 From: Roger Dingledine Date: Wed, 7 Apr 2004 22:41:00 +0000 Subject: [PATCH] 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 --- src/or/connection.c | 5 ++++- src/or/connection_edge.c | 7 ++++--- src/or/directory.c | 10 ++++++---- src/or/or.h | 9 +++++---- src/or/rendclient.c | 31 ++++++++++++------------------- 5 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/or/connection.c b/src/or/connection.c index 25b6a8b045..ac3a7d8d61 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -178,9 +178,12 @@ _connection_mark_for_close(connection_t *conn, char reason) case CONN_TYPE_AP_LISTENER: case CONN_TYPE_DIR_LISTENER: case CONN_TYPE_CPUWORKER: - case CONN_TYPE_DIR: /* No special processing needed. */ 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: /* Remember why we're closing this connection. */ if (conn->state != OR_CONN_STATE_OPEN) { diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 36b57c064e..a9cbafa87c 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -728,13 +728,14 @@ static int connection_ap_handshake_process_socks(connection_t *conn) { return connection_ap_handshake_attach_circuit(conn); } else { /* it's a hidden-service request */ - const char *descp; - int desc_len; + rend_cache_entry_t *entry; 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); /* 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; return connection_ap_handshake_attach_circuit(conn); } else { diff --git a/src/or/directory.c b/src/or/directory.c index 1af6bf59db..6a9fb40f4a 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -275,16 +275,18 @@ int connection_dir_process_inbuf(connection_t *conn) { switch(status_code) { case 200: if(rend_cache_store(body, body_len) < 0) { - log_fn(LOG_WARN,"Failed to store rendezvous descriptor. Abandoning stream."); - /* alice's ap_stream is just going to have to time out. */ + log_fn(LOG_WARN,"Failed to store rendezvous descriptor."); + /* alice's ap_stream will notice when connection_mark_for_close + * cleans it up */ } else { /* success. notify pending connections about this. */ rend_client_desc_fetched(conn->rend_query, 1); + conn->purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC; } break; case 404: - /* not there. also notify pending connections. */ - rend_client_desc_fetched(conn->rend_query, 0); + /* not there. pending connections will be notified when + * connection_mark_for_close cleans it up. */ break; case 400: log_fn(LOG_WARN,"http status 400 (bad request). Dirserver didn't like our rendezvous query?"); diff --git a/src/or/or.h b/src/or/or.h index 9ecb5c0300..ba49c6e009 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -176,10 +176,11 @@ #define _DIR_PURPOSE_MIN 1 #define DIR_PURPOSE_FETCH_DIR 1 #define DIR_PURPOSE_FETCH_RENDDESC 2 -#define DIR_PURPOSE_UPLOAD_DIR 3 -#define DIR_PURPOSE_UPLOAD_RENDDESC 4 -#define DIR_PURPOSE_SERVER 5 -#define _DIR_PURPOSE_MAX 5 +#define DIR_PURPOSE_HAS_FETCHED_RENDDESC 3 +#define DIR_PURPOSE_UPLOAD_DIR 4 +#define DIR_PURPOSE_UPLOAD_RENDDESC 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_ONIONSKIN_PENDING 1 /* waiting to process the onionskin */ diff --git a/src/or/rendclient.c b/src/or/rendclient.c index fead31ccde..ecb2eb4a38 100644 --- a/src/or/rendclient.c +++ b/src/or/rendclient.c @@ -46,31 +46,24 @@ rend_client_send_establish_rendezvous(circuit_t *circ) */ int rend_client_send_introduction(circuit_t *introcirc, circuit_t *rendcirc) { - const char *descp; - int desc_len, payload_len, r; + int payload_len, r; char payload[RELAY_PAYLOAD_SIZE]; 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; assert(introcirc->purpose == CIRCUIT_PURPOSE_C_INTRODUCING); assert(rendcirc->purpose == CIRCUIT_PURPOSE_C_REND_READY); 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.", introcirc->rend_query); 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 */ - 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."); goto err; } @@ -97,7 +90,7 @@ rend_client_send_introduction(circuit_t *introcirc, circuit_t *rendcirc) { 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, payload+DIGEST_LEN, PK_PKCS1_OAEP_PADDING, 0); @@ -108,8 +101,6 @@ rend_client_send_introduction(circuit_t *introcirc, circuit_t *rendcirc) { payload_len = DIGEST_LEN + r; - rend_service_descriptor_free(parsed); - if (connection_edge_send_command(NULL, introcirc, RELAY_COMMAND_INTRODUCE1, payload, payload_len, @@ -124,8 +115,6 @@ rend_client_send_introduction(circuit_t *introcirc, circuit_t *rendcirc) { return 0; err: - if(parsed) - rend_service_descriptor_free(parsed); circuit_mark_for_close(introcirc); circuit_mark_for_close(rendcirc); return -1; @@ -239,6 +228,7 @@ void rend_client_desc_fetched(char *query, int success) { connection_t **carray; connection_t *conn; int n, i; + rend_cache_entry_t *entry; 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)) continue; /* 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."); conn->state = AP_CONN_STATE_CIRCUIT_WAIT; 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."); connection_mark_for_close(conn,0); } - } else { /* 404 */ - log_fn(LOG_WARN,"service id '%s' not found. Closing conn.", query); + } else { /* 404, or fetch didn't get that far */ + log_fn(LOG_WARN,"service id '%s' fetched failed, and not in cache. Closing conn.", query); connection_mark_for_close(conn,0); } }