Backport bugfix for #814 (r16915 and r16916).

svn:r17258
This commit is contained in:
Karsten Loesing 2008-11-12 10:47:20 +00:00
parent db94f36633
commit 257215489d
5 changed files with 35 additions and 11 deletions

View File

@ -12,6 +12,14 @@ Changes in version 0.2.0.32 - 2008-??-??
- Fix a DOS opportunity during the voting signature collection process
at directory authorities. Spotted by rovv. Bugfix on 0.2.0.x.
o Major bugfixes (hidden services):
- When fetching v0 and v2 rendezvous service descriptors in parallel,
we were failing the whole hidden service request when the v0
descriptor fetch fails, even if the v2 fetch is still pending and
might succeed. Similarly, if the last v2 fetch fails, we were
failing the whole hidden service request even if a v0 fetch is
still pending. Fixes bug 814. Bugfix on 0.2.0.10-alpha.
o Minor bugfixes:
- Fix several infrequent memory leaks spotted by Coverity.
- When testing for libevent functions, set the LDFLAGS variable

View File

@ -479,8 +479,13 @@ connection_about_to_close_connection(connection_t *conn)
* failed: forget about this router, and maybe try again. */
connection_dir_request_failed(dir_conn);
}
if (conn->purpose == DIR_PURPOSE_FETCH_RENDDESC)
rend_client_desc_here(dir_conn->rend_query); /* give it a try */
if (conn->purpose == DIR_PURPOSE_FETCH_RENDDESC) {
/* Give it a try. However, there is no re-fetching for v0 rend
* descriptors; if the response is empty or the descriptor is
* unusable, close pending connections (unless a v2 request is
* still in progress). */
rend_client_desc_trynow(dir_conn->rend_query, 0);
}
/* If we were trying to fetch a v2 rend desc and did not succeed,
* retry as needed. (If a fetch is successful, the connection state
* is changed to DIR_PURPOSE_HAS_FETCHED_RENDDESC to mark that

View File

@ -1805,7 +1805,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
} else {
/* success. notify pending connections about this. */
conn->_base.purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC;
rend_client_desc_here(conn->rend_query);
rend_client_desc_trynow(conn->rend_query, -1);
}
break;
case 404:
@ -1851,7 +1851,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
log_info(LD_REND, "Successfully fetched v2 rendezvous "
"descriptor.");
conn->_base.purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC;
rend_client_desc_here(conn->rend_query);
rend_client_desc_trynow(conn->rend_query, -1);
break;
}
break;

View File

@ -3645,7 +3645,7 @@ int rend_client_rendezvous_acked(origin_circuit_t *circ, const char *request,
size_t request_len);
int rend_client_receive_rendezvous(origin_circuit_t *circ, const char *request,
size_t request_len);
void rend_client_desc_here(const char *query);
void rend_client_desc_trynow(const char *query, int rend_version);
extend_info_t *rend_client_get_random_intro(const char *query);

View File

@ -461,6 +461,8 @@ rend_client_refetch_v2_renddesc(const char *query)
log_info(LD_REND, "Could not pick one of the responsible hidden "
"service directories to fetch descriptors, because "
"we already tried them all unsuccessfully.");
/* Close pending connections (unless a v0 request is still going on). */
rend_client_desc_trynow(query, 2);
return;
}
@ -617,11 +619,14 @@ rend_client_receive_rendezvous(origin_circuit_t *circ, const char *request,
/** Find all the apconns in state AP_CONN_STATE_RENDDESC_WAIT that
* are waiting on query. If there's a working cache entry here
* with at least one intro point, move them to the next state;
* else fail them.
* with at least one intro point, move them to the next state. If
* <b>rend_version</b> is non-negative, fail connections that have
* requested <b>query</b> unless there are still descriptor fetch
* requests in progress for other descriptor versions than
* <b>rend_version</b>.
*/
void
rend_client_desc_here(const char *query)
rend_client_desc_trynow(const char *query, int rend_version)
{
edge_connection_t *conn;
rend_cache_entry_t *entry;
@ -657,9 +662,15 @@ rend_client_desc_here(const char *query)
connection_mark_unattached_ap(conn, END_STREAM_REASON_CANT_ATTACH);
}
} else { /* 404, or fetch didn't get that far */
log_notice(LD_REND,"Closing stream for '%s.onion': hidden service is "
"unavailable (try again later).", safe_str(query));
connection_mark_unattached_ap(conn, END_STREAM_REASON_RESOLVEFAILED);
/* Unless there are requests for another descriptor version pending,
* close the connection. */
if (rend_version >= 0 &&
!connection_get_by_type_state_rendquery(CONN_TYPE_DIR, 0, query,
rend_version == 0 ? 2 : 0)) {
log_notice(LD_REND,"Closing stream for '%s.onion': hidden service is "
"unavailable (try again later).", safe_str(query));
connection_mark_unattached_ap(conn, END_STREAM_REASON_RESOLVEFAILED);
}
}
});
}