mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
prop224: Add service replay cache
Signed-off-by: David Goulet <dgoulet@torproject.org>
This commit is contained in:
committed by
Nick Mathewson
parent
27dd1a716c
commit
77b279c35c
@@ -794,6 +794,7 @@ hs_circ_handle_introduce2(const hs_service_t *service,
|
||||
const uint8_t *payload, size_t payload_len)
|
||||
{
|
||||
int ret = -1;
|
||||
time_t elapsed;
|
||||
hs_cell_introduce2_data_t data;
|
||||
|
||||
tor_assert(service);
|
||||
@@ -817,6 +818,22 @@ hs_circ_handle_introduce2(const hs_service_t *service,
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Check whether we've seen this REND_COOKIE before to detect repeats. */
|
||||
if (replaycache_add_test_and_elapsed(
|
||||
service->state.replay_cache_rend_cookie,
|
||||
data.rendezvous_cookie, sizeof(data.rendezvous_cookie),
|
||||
&elapsed)) {
|
||||
/* A Tor client will send a new INTRODUCE1 cell with the same REND_COOKIE
|
||||
* as its previous one if its intro circ times out while in state
|
||||
* CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT. If we received the first
|
||||
* INTRODUCE1 cell (the intro-point relay converts it into an INTRODUCE2
|
||||
* cell), we are already trying to connect to that rend point (and may
|
||||
* have already succeeded); drop this cell. */
|
||||
log_info(LD_REND, "We received an INTRODUCE2 cell with same REND_COOKIE "
|
||||
"field %ld seconds ago. Dropping cell.", elapsed);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* At this point, we just confirmed that the full INTRODUCE2 cell is valid
|
||||
* so increment our counter that we've seen one on this intro point. */
|
||||
ip->introduce2_count++;
|
||||
|
||||
@@ -2080,6 +2080,9 @@ hs_service_new(const or_options_t *options)
|
||||
set_service_default_config(&service->config, options);
|
||||
/* Set the default service version. */
|
||||
service->config.version = HS_SERVICE_DEFAULT_VERSION;
|
||||
/* Allocate the CLIENT_PK replay cache in service state. */
|
||||
service->state.replay_cache_rend_cookie =
|
||||
replaycache_new(REND_REPLAY_TIME_INTERVAL, REND_REPLAY_TIME_INTERVAL);
|
||||
return service;
|
||||
}
|
||||
|
||||
@@ -2101,6 +2104,11 @@ hs_service_free(hs_service_t *service)
|
||||
/* Free service configuration. */
|
||||
service_clear_config(&service->config);
|
||||
|
||||
/* Free replay cache from state. */
|
||||
if (service->state.replay_cache_rend_cookie) {
|
||||
replaycache_free(service->state.replay_cache_rend_cookie);
|
||||
}
|
||||
|
||||
/* Wipe service keys. */
|
||||
memwipe(&service->keys.identity_sk, 0, sizeof(service->keys.identity_sk));
|
||||
|
||||
|
||||
@@ -181,6 +181,13 @@ typedef struct hs_service_state_t {
|
||||
/* Indicate that the service has entered the overlap period. We use this
|
||||
* flag to check for descriptor rotation. */
|
||||
unsigned int in_overlap_period : 1;
|
||||
|
||||
/* Replay cache tracking the REND_COOKIE found in INTRODUCE2 cell to detect
|
||||
* repeats. Clients may send INTRODUCE1 cells for the same rendezvous point
|
||||
* through two or more different introduction points; when they do, this
|
||||
* keeps us from launching multiple simultaneous attempts to connect to the
|
||||
* same rend point. */
|
||||
replaycache_t *replay_cache_rend_cookie;
|
||||
} hs_service_state_t;
|
||||
|
||||
/* Representation of a service running on this tor instance. */
|
||||
|
||||
Reference in New Issue
Block a user