summaryrefslogtreecommitdiff
path: root/src/feature
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2018-07-17 16:19:32 -0400
committerNick Mathewson <nickm@torproject.org>2018-07-17 16:19:32 -0400
commite2b744ce38edb8901cff3288634c4ebb5b4568b9 (patch)
tree9af8bf64a8ed5412ea7b55bd08f3e390867ce770 /src/feature
parent12afdcc15a8429bcc50d9287321849b6fa924c2f (diff)
parent14b507e5207ce7e581c5fc773921f8cf65d08247 (diff)
downloadtor-e2b744ce38edb8901cff3288634c4ebb5b4568b9.tar.gz
tor-e2b744ce38edb8901cff3288634c4ebb5b4568b9.zip
Merge branch 'bug25552_ope_squashed'
Diffstat (limited to 'src/feature')
-rw-r--r--src/feature/dircommon/voting_schedule.c2
-rw-r--r--src/feature/hs/hs_common.c3
-rw-r--r--src/feature/hs/hs_service.c309
-rw-r--r--src/feature/hs/hs_service.h14
-rw-r--r--src/feature/hs_common/shared_random_client.c36
-rw-r--r--src/feature/hs_common/shared_random_client.h3
6 files changed, 142 insertions, 225 deletions
diff --git a/src/feature/dircommon/voting_schedule.c b/src/feature/dircommon/voting_schedule.c
index 84c016c2b9..07e65ef06d 100644
--- a/src/feature/dircommon/voting_schedule.c
+++ b/src/feature/dircommon/voting_schedule.c
@@ -168,7 +168,7 @@ voting_schedule_get_next_valid_after_time(void)
done:
if (need_to_recalculate_voting_schedule) {
- voting_schedule_recalculate_timing(get_options(), now);
+ voting_schedule_recalculate_timing(get_options(), approx_time());
voting_schedule.created_on_demand = 1;
}
diff --git a/src/feature/hs/hs_common.c b/src/feature/hs/hs_common.c
index 723cfa6ea8..328430be08 100644
--- a/src/feature/hs/hs_common.c
+++ b/src/feature/hs/hs_common.c
@@ -1102,8 +1102,7 @@ hs_in_period_between_tp_and_srv,(const networkstatus_t *consensus, time_t now))
/* Get start time of next TP and of current SRV protocol run, and check if we
* are between them. */
valid_after = consensus->valid_after;
- srv_start_time =
- sr_state_get_start_time_of_current_protocol_run(valid_after);
+ srv_start_time = sr_state_get_start_time_of_current_protocol_run();
tp_start_time = hs_get_start_time_of_next_time_period(srv_start_time);
if (valid_after >= srv_start_time && valid_after < tp_start_time) {
diff --git a/src/feature/hs/hs_service.c b/src/feature/hs/hs_service.c
index 8b4de21387..54204dd070 100644
--- a/src/feature/hs/hs_service.c
+++ b/src/feature/hs/hs_service.c
@@ -17,6 +17,7 @@
#include "core/mainloop/connection.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "lib/crypt_ops/crypto_util.h"
+#include "lib/crypt_ops/crypto_ope.h"
#include "feature/dircache/directory.h"
#include "core/mainloop/main.h"
#include "feature/nodelist/networkstatus.h"
@@ -102,7 +103,8 @@ static smartlist_t *hs_service_staging_list;
static int consider_republishing_hs_descriptors = 0;
/* Static declaration. */
-static void set_descriptor_revision_counter(hs_descriptor_t *hs_desc);
+static void set_descriptor_revision_counter(hs_service_descriptor_t *hs_desc,
+ time_t now, bool is_current);
static void move_descriptors(hs_service_t *src, hs_service_t *dst);
/* Helper: Function to compare two objects in the service map. Return 1 if the
@@ -443,7 +445,7 @@ service_intro_point_new(const extend_info_t *ei, unsigned int is_legacy)
if (BUG(intro_point_max_lifetime < intro_point_min_lifetime)) {
goto err;
}
- ip->time_to_expire = time(NULL) +
+ ip->time_to_expire = approx_time() +
crypto_rand_int_range(intro_point_min_lifetime,intro_point_max_lifetime);
}
@@ -1084,6 +1086,7 @@ service_descriptor_free_(hs_service_descriptor_t *desc)
SMARTLIST_FOREACH(desc->previous_hsdirs, char *, s, tor_free(s));
smartlist_free(desc->previous_hsdirs);
}
+ crypto_ope_free(desc->ope_cipher);
tor_free(desc);
}
@@ -1388,13 +1391,30 @@ build_service_desc_plaintext(const hs_service_t *service,
return ret;
}
+/** Compute the descriptor's OPE cipher for encrypting revision counters. */
+static crypto_ope_t *
+generate_ope_cipher_for_desc(const hs_service_descriptor_t *hs_desc)
+{
+ /* Compute OPE key as H("rev-counter-generation" | blinded privkey) */
+ uint8_t key[DIGEST256_LEN];
+ crypto_digest_t *digest = crypto_digest256_new(DIGEST_SHA3_256);
+ const char ope_key_prefix[] = "rev-counter-generation";
+ const ed25519_secret_key_t *eph_privkey = &hs_desc->blinded_kp.seckey;
+ crypto_digest_add_bytes(digest, ope_key_prefix, sizeof(ope_key_prefix));
+ crypto_digest_add_bytes(digest, (char*)eph_privkey->seckey,
+ sizeof(eph_privkey->seckey));
+ crypto_digest_get_digest(digest, (char *)key, sizeof(key));
+ crypto_digest_free(digest);
+
+ return crypto_ope_new(key);
+}
+
/* For the given service and descriptor object, create the key material which
* is the blinded keypair and the descriptor signing keypair. Return 0 on
* success else -1 on error where the generated keys MUST be ignored. */
static int
build_service_desc_keys(const hs_service_t *service,
- hs_service_descriptor_t *desc,
- uint64_t time_period_num)
+ hs_service_descriptor_t *desc)
{
int ret = 0;
ed25519_keypair_t kp;
@@ -1410,10 +1430,17 @@ build_service_desc_keys(const hs_service_t *service,
memcpy(&kp.pubkey, &service->keys.identity_pk, sizeof(kp.pubkey));
memcpy(&kp.seckey, &service->keys.identity_sk, sizeof(kp.seckey));
/* Build blinded keypair for this time period. */
- hs_build_blinded_keypair(&kp, NULL, 0, time_period_num, &desc->blinded_kp);
+ hs_build_blinded_keypair(&kp, NULL, 0, desc->time_period_num,
+ &desc->blinded_kp);
/* Let's not keep too much traces of our keys in memory. */
memwipe(&kp, 0, sizeof(kp));
+ /* Compute the OPE cipher struct (it's tied to the current blinded key) */
+ log_info(LD_GENERAL,
+ "Getting OPE for TP#%u", (unsigned) desc->time_period_num);
+ tor_assert_nonfatal(!desc->ope_cipher);
+ desc->ope_cipher = generate_ope_cipher_for_desc(desc);
+
/* No need for extra strong, this is a temporary key only for this
* descriptor. Nothing long term. */
if (ed25519_keypair_generate(&desc->signing_kp, 0) < 0) {
@@ -1444,10 +1471,12 @@ build_service_descriptor(hs_service_t *service, time_t now,
tor_assert(desc_out);
desc = service_descriptor_new();
+
+ /* Set current time period */
desc->time_period_num = time_period_num;
/* Create the needed keys so we can setup the descriptor content. */
- if (build_service_desc_keys(service, desc, time_period_num) < 0) {
+ if (build_service_desc_keys(service, desc) < 0) {
goto err;
}
/* Setup plaintext descriptor content. */
@@ -1459,9 +1488,6 @@ build_service_descriptor(hs_service_t *service, time_t now,
goto err;
}
- /* Set the revision counter for this descriptor */
- set_descriptor_revision_counter(desc->desc);
-
/* Let's make sure that we've created a descriptor that can actually be
* encoded properly. This function also checks if the encoded output is
* decodable after. */
@@ -1769,7 +1795,6 @@ service_desc_schedule_upload(hs_service_descriptor_t *desc,
/* Update the given descriptor from the given service. The possible update
* actions includes:
* - Picking missing intro points if needed.
- * - Incrementing the revision counter if needed.
*/
static void
update_service_descriptor(hs_service_t *service,
@@ -1933,19 +1958,12 @@ cleanup_intro_points(hs_service_t *service, time_t now)
/* Set the next rotation time of the descriptors for the given service for the
* time now. */
static void
-set_rotation_time(hs_service_t *service, time_t now)
+set_rotation_time(hs_service_t *service)
{
- time_t valid_after;
- const networkstatus_t *ns = networkstatus_get_live_consensus(now);
- if (ns) {
- valid_after = ns->valid_after;
- } else {
- valid_after = now;
- }
-
tor_assert(service);
+
service->state.next_rotation_time =
- sr_state_get_start_time_of_current_protocol_run(valid_after) +
+ sr_state_get_start_time_of_current_protocol_run() +
sr_state_get_protocol_run_duration();
{
@@ -2012,7 +2030,7 @@ should_rotate_descriptors(hs_service_t *service, time_t now)
* will be freed, the next one put in as the current and finally the next
* descriptor pointer is NULLified. */
static void
-rotate_service_descriptors(hs_service_t *service, time_t now)
+rotate_service_descriptors(hs_service_t *service)
{
if (service->desc_current) {
/* Close all IP circuits for the descriptor. */
@@ -2027,7 +2045,7 @@ rotate_service_descriptors(hs_service_t *service, time_t now)
service->desc_next = NULL;
/* We've just rotated, set the next time for the rotation. */
- set_rotation_time(service, now);
+ set_rotation_time(service);
}
/* Rotate descriptors for each service if needed. A non existing current
@@ -2055,7 +2073,7 @@ rotate_all_descriptors(time_t now)
service->desc_current, service->desc_next,
safe_str_client(service->onion_address));
- rotate_service_descriptors(service, now);
+ rotate_service_descriptors(service);
} FOR_EACH_SERVICE_END;
}
@@ -2077,7 +2095,7 @@ run_housekeeping_event(time_t now)
/* Set the next rotation time of the descriptors. If it's Oct 25th
* 23:47:00, the next rotation time is when the next SRV is computed
* which is at Oct 26th 00:00:00 that is in 13 minutes. */
- set_rotation_time(service, now);
+ set_rotation_time(service);
}
/* Cleanup invalid intro points from the service descriptor. */
@@ -2326,13 +2344,17 @@ upload_descriptor_to_hsdir(const hs_service_t *service,
int is_next_desc = (service->desc_next == desc);
const uint8_t *idx = (is_next_desc) ? hsdir->hsdir_index.store_second:
hsdir->hsdir_index.store_first;
+ char *blinded_pubkey_log_str =
+ tor_strdup(hex_str((char*)&desc->blinded_kp.pubkey.pubkey, 32));
log_info(LD_REND, "Service %s %s descriptor of revision %" PRIu64
- " initiated upload request to %s with index %s",
+ " initiated upload request to %s with index %s (%s)",
safe_str_client(service->onion_address),
(is_next_desc) ? "next" : "current",
desc->desc->plaintext_data.revision_counter,
safe_str_client(node_describe(hsdir)),
- safe_str_client(hex_str((const char *) idx, 32)));
+ safe_str_client(hex_str((const char *) idx, 32)),
+ safe_str_client(blinded_pubkey_log_str));
+ tor_free(blinded_pubkey_log_str);
/* Fire a UPLOAD control port event. */
hs_control_desc_event_upload(service->onion_address, hsdir->identity,
@@ -2344,197 +2366,77 @@ upload_descriptor_to_hsdir(const hs_service_t *service,
return;
}
-/** Return a newly-allocated string for our state file which contains revision
- * counter information for <b>desc</b>. The format is:
+/** Set the revision counter in <b>hs_desc</b>. We do this by encrypting a
+ * timestamp using an OPE scheme and using the ciphertext as our revision
+ * counter.
*
- * HidServRevCounter <blinded_pubkey> <rev_counter>
- */
-STATIC char *
-encode_desc_rev_counter_for_state(const hs_service_descriptor_t *desc)
-{
- char *state_str = NULL;
- char blinded_pubkey_b64[ED25519_BASE64_LEN+1];
- uint64_t rev_counter = desc->desc->plaintext_data.revision_counter;
- const ed25519_public_key_t *blinded_pubkey = &desc->blinded_kp.pubkey;
-
- /* Turn the blinded key into b64 so that we save it on state */
- tor_assert(blinded_pubkey);
- if (ed25519_public_to_base64(blinded_pubkey_b64, blinded_pubkey) < 0) {
- goto done;
- }
-
- /* Format is: <blinded key> <rev counter> */
- tor_asprintf(&state_str, "%s %" PRIu64, blinded_pubkey_b64, rev_counter);
-
- log_info(LD_GENERAL, "[!] Adding rev counter %" PRIu64 " for %s!",
- rev_counter, blinded_pubkey_b64);
-
- done:
- return state_str;
-}
-
-/** Update HS descriptor revision counters in our state by removing the old
- * ones and writing down the ones that are currently active. */
+ * If <b>is_current</b> is true, then this is the current HS descriptor,
+ * otherwise it's the next one. */
static void
-update_revision_counters_in_state(void)
-{
- config_line_t *lines = NULL;
- config_line_t **nextline = &lines;
- or_state_t *state = get_or_state();
-
- /* Prepare our state structure with the rev counters */
- FOR_EACH_SERVICE_BEGIN(service) {
- FOR_EACH_DESCRIPTOR_BEGIN(service, desc) {
- /* We don't want to save zero counters */
- if (desc->desc->plaintext_data.revision_counter == 0) {
- continue;
- }
-
- *nextline = tor_malloc_zero(sizeof(config_line_t));
- (*nextline)->key = tor_strdup("HidServRevCounter");
- (*nextline)->value = encode_desc_rev_counter_for_state(desc);
- nextline = &(*nextline)->next;
- } FOR_EACH_DESCRIPTOR_END;
- } FOR_EACH_SERVICE_END;
-
- /* Remove the old rev counters, and replace them with the new ones */
- config_free_lines(state->HidServRevCounter);
- state->HidServRevCounter = lines;
-
- /* Set the state as dirty since we just edited it */
- if (!get_options()->AvoidDiskWrites) {
- or_state_mark_dirty(state, 0);
- }
-}
-
-/** Scan the string <b>state_line</b> for the revision counter of the service
- * with <b>blinded_pubkey</b>. Set <b>service_found_out</b> to True if the
- * line is relevant to this service, and return the cached revision
- * counter. Else set <b>service_found_out</b> to False. */
-STATIC uint64_t
-check_state_line_for_service_rev_counter(const char *state_line,
- const ed25519_public_key_t *blinded_pubkey,
- int *service_found_out)
+set_descriptor_revision_counter(hs_service_descriptor_t *hs_desc, time_t now,
+ bool is_current)
{
- smartlist_t *items = NULL;
- int ok;
- ed25519_public_key_t pubkey_in_state;
uint64_t rev_counter = 0;
- tor_assert(service_found_out);
- tor_assert(state_line);
- tor_assert(blinded_pubkey);
+ /* Get current time */
+ time_t srv_start = 0;
- /* Assume that the line is not for this service */
- *service_found_out = 0;
-
- /* Start parsing the state line */
- items = smartlist_new();
- smartlist_split_string(items, state_line, NULL,
- SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
- if (smartlist_len(items) < 2) {
- log_warn(LD_GENERAL, "Incomplete rev counter line. Ignoring.");
- goto done;
- }
-
- char *b64_key_str = smartlist_get(items, 0);
- char *saved_rev_counter_str = smartlist_get(items, 1);
-
- /* Parse blinded key to check if it's for this hidden service */
- if (ed25519_public_from_base64(&pubkey_in_state, b64_key_str) < 0) {
- log_warn(LD_GENERAL, "Unable to base64 key in revcount line. Ignoring.");
- goto done;
- }
- /* State line not for this hidden service */
- if (!ed25519_pubkey_eq(&pubkey_in_state, blinded_pubkey)) {
- goto done;
- }
-
- rev_counter = tor_parse_uint64(saved_rev_counter_str,
- 10, 0, UINT64_MAX, &ok, NULL);
- if (!ok) {
- log_warn(LD_GENERAL, "Unable to parse rev counter. Ignoring.");
- goto done;
+ /* As our revision counter plaintext value, we use the seconds since the
+ * start of the SR protocol run that is relevant to this descriptor. This is
+ * guaranteed to be a positive value since we need the SRV to start making a
+ * descriptor (so that we know where to upload it).
+ *
+ * Depending on whether we are building the current or the next descriptor,
+ * services use a different SRV value. See [SERVICEUPLOAD] in
+ * rend-spec-v3.txt:
+ *
+ * In particular, for the current descriptor (aka first descriptor), Tor
+ * always uses the previous SRV for uploading the descriptor, and hence we
+ * should use the start time of the previous protocol run here.
+ *
+ * Whereas for the next descriptor (aka second descriptor), Tor always uses
+ * the current SRV for uploading the descriptor. and hence we use the start
+ * time of the current protocol run.
+ */
+ if (is_current) {
+ srv_start = sr_state_get_start_time_of_previous_protocol_run();
+ } else {
+ srv_start = sr_state_get_start_time_of_current_protocol_run();
}
- /* Since we got this far, the line was for this service */
- *service_found_out = 1;
-
- log_info(LD_GENERAL, "Found rev counter for %s: %" PRIu64,
- b64_key_str, rev_counter);
-
- done:
- tor_assert(items);
- SMARTLIST_FOREACH(items, char*, s, tor_free(s));
- smartlist_free(items);
-
- return rev_counter;
-}
-
-/** Dig into our state file and find the current revision counter for the
- * service with blinded key <b>blinded_pubkey</b>. If no revision counter is
- * found, return 0. */
-static uint64_t
-get_rev_counter_for_service(const ed25519_public_key_t *blinded_pubkey)
-{
- or_state_t *state = get_or_state();
- config_line_t *line;
+ log_info(LD_REND, "Setting rev counter for TP #%u: "
+ "SRV started at %d, now %d (%s)",
+ (unsigned) hs_desc->time_period_num, (int)srv_start,
+ (int)now, is_current ? "current" : "next");
- /* Set default value for rev counters (if not found) to 0 */
- uint64_t final_rev_counter = 0;
+ tor_assert_nonfatal(now >= srv_start);
- for (line = state->HidServRevCounter ; line ; line = line->next) {
- int service_found = 0;
- uint64_t rev_counter = 0;
+ /* Compute seconds elapsed since the start of the time period. That's the
+ * number of seconds of how long this blinded key has been active. */
+ time_t seconds_since_start_of_srv = now - srv_start;
- tor_assert(!strcmp(line->key, "HidServRevCounter"));
+ /* Increment by one so that we are definitely sure this is strictly
+ * positive and not zero. */
+ seconds_since_start_of_srv++;
- /* Scan all the HidServRevCounter lines till we find the line for this
- service: */
- rev_counter = check_state_line_for_service_rev_counter(line->value,
- blinded_pubkey,
- &service_found);
- if (service_found) {
- final_rev_counter = rev_counter;
- goto done;
- }
+ /* Check for too big inputs. */
+ if (BUG(seconds_since_start_of_srv > OPE_INPUT_MAX)) {
+ seconds_since_start_of_srv = OPE_INPUT_MAX;
}
- done:
- return final_rev_counter;
-}
-
-/** Update the value of the revision counter for <b>hs_desc</b> and save it on
- our state file. */
-static void
-increment_descriptor_revision_counter(hs_descriptor_t *hs_desc)
-{
- /* Find stored rev counter if it exists */
- uint64_t rev_counter =
- get_rev_counter_for_service(&hs_desc->plaintext_data.blinded_pubkey);
+ /* Now we compute the final revision counter value by encrypting the
+ plaintext using our OPE cipher: */
+ tor_assert(hs_desc->ope_cipher);
+ rev_counter = crypto_ope_encrypt(hs_desc->ope_cipher,
+ (int) seconds_since_start_of_srv);
- /* Increment the revision counter of <b>hs_desc</b> so the next update (which
- * will trigger an upload) will have the right value. We do this at this
- * stage to only do it once because a descriptor can have many updates before
- * being uploaded. By doing it at upload, we are sure to only increment by 1
- * and thus avoid leaking how many operations we made on the descriptor from
- * the previous one before uploading. */
- rev_counter++;
- hs_desc->plaintext_data.revision_counter = rev_counter;
+ /* The OPE module returns CRYPTO_OPE_ERROR in case of errors. */
+ tor_assert_nonfatal(rev_counter < CRYPTO_OPE_ERROR);
- update_revision_counters_in_state();
-}
+ log_info(LD_REND, "Encrypted revision counter %d to %ld",
+ (int) seconds_since_start_of_srv, (long int) rev_counter);
-/** Set the revision counter in <b>hs_desc</b>, using the state file to find
- * the current counter value if it exists. */
-static void
-set_descriptor_revision_counter(hs_descriptor_t *hs_desc)
-{
- /* Find stored rev counter if it exists */
- uint64_t rev_counter =
- get_rev_counter_for_service(&hs_desc->plaintext_data.blinded_pubkey);
-
- hs_desc->plaintext_data.revision_counter = rev_counter;
+ hs_desc->desc->plaintext_data.revision_counter = rev_counter;
}
/* Encode and sign the service descriptor desc and upload it to the
@@ -2592,9 +2494,6 @@ upload_descriptor_to_all(const hs_service_t *service,
safe_str_client(service->onion_address), fmt_next_time);
}
- /* Update the revision counter of this descriptor */
- increment_descriptor_revision_counter(desc->desc);
-
smartlist_free(responsible_dirs);
return;
}
@@ -2734,6 +2633,10 @@ run_upload_descriptor_event(time_t now)
* accurate because all circuits have been established. */
build_desc_intro_points(service, desc, now);
+ /* Set the desc revision counter right before uploading */
+ set_descriptor_revision_counter(desc, approx_time(),
+ service->desc_current == desc);
+
upload_descriptor_to_all(service, desc);
} FOR_EACH_DESCRIPTOR_END;
} FOR_EACH_SERVICE_END;
diff --git a/src/feature/hs/hs_service.h b/src/feature/hs/hs_service.h
index 22bfcacc26..4cd05e3897 100644
--- a/src/feature/hs/hs_service.h
+++ b/src/feature/hs/hs_service.h
@@ -131,6 +131,10 @@ typedef struct hs_service_descriptor_t {
* from this list, this means we received new dirinfo and we need to
* reupload our descriptor. */
smartlist_t *previous_hsdirs;
+
+ /** The OPE cipher for encrypting revision counters for this descriptor.
+ * Tied to the descriptor blinded key. */
+ struct crypto_ope_t *ope_cipher;
} hs_service_descriptor_t;
/* Service key material. */
@@ -346,19 +350,10 @@ STATIC void build_all_descriptors(time_t now);
STATIC void update_all_descriptors(time_t now);
STATIC void run_upload_descriptor_event(time_t now);
-STATIC char *
-encode_desc_rev_counter_for_state(const hs_service_descriptor_t *desc);
-
STATIC void service_descriptor_free_(hs_service_descriptor_t *desc);
#define service_descriptor_free(d) \
FREE_AND_NULL(hs_service_descriptor_t, \
service_descriptor_free_, (d))
-
-STATIC uint64_t
-check_state_line_for_service_rev_counter(const char *state_line,
- const ed25519_public_key_t *blinded_pubkey,
- int *service_found_out);
-
STATIC int
write_address_to_file(const hs_service_t *service, const char *fname_);
@@ -375,4 +370,3 @@ STATIC int service_desc_hsdirs_changed(const hs_service_t *service,
#endif /* defined(HS_SERVICE_PRIVATE) */
#endif /* !defined(TOR_HS_SERVICE_H) */
-
diff --git a/src/feature/hs_common/shared_random_client.c b/src/feature/hs_common/shared_random_client.c
index 329f053d3b..ff98a719db 100644
--- a/src/feature/hs_common/shared_random_client.c
+++ b/src/feature/hs_common/shared_random_client.c
@@ -222,24 +222,44 @@ sr_parse_srv(const smartlist_t *args)
return srv;
}
-/** Return the start time of the current SR protocol run. For example, if the
- * time is 23/06/2017 23:47:08 and a full SR protocol run is 24 hours, this
- * function should return 23/06/2017 00:00:00. */
+/** Return the start time of the current SR protocol run using the times from
+ * the current consensus. For example, if the latest consensus valid-after is
+ * 23/06/2017 23:00:00 and a full SR protocol run is 24 hours, this function
+ * returns 23/06/2017 00:00:00. */
time_t
-sr_state_get_start_time_of_current_protocol_run(time_t now)
+sr_state_get_start_time_of_current_protocol_run(void)
{
int total_rounds = SHARED_RANDOM_N_ROUNDS * SHARED_RANDOM_N_PHASES;
int voting_interval = get_voting_interval();
/* Find the time the current round started. */
- time_t beginning_of_current_round = get_start_time_of_current_round();
+ time_t beginning_of_curr_round = get_start_time_of_current_round();
/* Get current SR protocol round */
- int current_round = (now / voting_interval) % total_rounds;
+ int curr_round_slot;
+ curr_round_slot = (beginning_of_curr_round / voting_interval) % total_rounds;
/* Get start time by subtracting the time elapsed from the beginning of the
protocol run */
- time_t time_elapsed_since_start_of_run = current_round * voting_interval;
- return beginning_of_current_round - time_elapsed_since_start_of_run;
+ time_t time_elapsed_since_start_of_run = curr_round_slot * voting_interval;
+
+ log_debug(LD_GENERAL, "Current SRV proto run: Start of current round: %u. "
+ "Time elapsed: %u (%d)", (unsigned) beginning_of_curr_round,
+ (unsigned) time_elapsed_since_start_of_run, voting_interval);
+
+ return beginning_of_curr_round - time_elapsed_since_start_of_run;
+}
+
+/** Return the start time of the previous SR protocol run. See
+ * sr_state_get_start_time_of_current_protocol_run() for more details. */
+time_t
+sr_state_get_start_time_of_previous_protocol_run(void)
+{
+ time_t start_time_of_current_run =
+ sr_state_get_start_time_of_current_protocol_run();
+
+ /* We get the start time of previous protocol run, by getting the start time
+ * of current run and the subtracting a full protocol run from that. */
+ return start_time_of_current_run - sr_state_get_protocol_run_duration();
}
/** Return the time (in seconds) it takes to complete a full SR protocol phase
diff --git a/src/feature/hs_common/shared_random_client.h b/src/feature/hs_common/shared_random_client.h
index 497a015c18..0e26f530a4 100644
--- a/src/feature/hs_common/shared_random_client.h
+++ b/src/feature/hs_common/shared_random_client.h
@@ -34,7 +34,8 @@ sr_srv_t *sr_parse_srv(const smartlist_t *args);
/* Number of phase we have in a protocol. */
#define SHARED_RANDOM_N_PHASES 2
-time_t sr_state_get_start_time_of_current_protocol_run(time_t now);
+time_t sr_state_get_start_time_of_current_protocol_run(void);
+time_t sr_state_get_start_time_of_previous_protocol_run(void);
unsigned int sr_state_get_phase_duration(void);
unsigned int sr_state_get_protocol_run_duration(void);
time_t get_start_time_of_current_round(void);