* loading keys requires that we are an actual running tor process. */
static smartlist_t *hs_service_staging_list;
+/** True if the list of available router descriptors might have changed which
+ * might result in an altered hash ring. Check if the hash ring changed and
+ * reupload if needed */
+static int consider_republishing_hs_descriptors = 0;
+
static void set_descriptor_revision_counter(hs_descriptor_t *hs_desc);
/* Helper: Function to compare two objects in the service map. Return 1 if the
FOR_EACH_DESCRIPTOR_BEGIN(service, desc) {
int for_next_period = 0;
- /* Can this descriptor be uploaed? */
+ /* If we were asked to re-examine the hash ring, and it changed, then
+ schedule an upload */
+ if (consider_republishing_hs_descriptors &&
+ service_desc_hsdirs_changed(service, desc)) {
+ service_desc_schedule_upload(desc, now, 0);
+ }
+
+ /* Can this descriptor be uploaded? */
if (!should_service_upload_descriptor(service, desc, now)) {
continue;
}
upload_descriptor_to_all(service, desc, for_next_period);
} FOR_EACH_DESCRIPTOR_END;
} FOR_EACH_SERVICE_END;
+
+ /* We are done considering whether to republish rend descriptors */
+ consider_republishing_hs_descriptors = 0;
}
/* Called when the introduction point circuit is done building and ready to be
/** The set of HSDirs have changed: check if the change affects our descriptor
* HSDir placement, and if it does, reupload the desc. */
-static int
+int
service_desc_hsdirs_changed(const hs_service_t *service,
const hs_service_descriptor_t *desc)
{
/* ========== */
/* We just received a new batch of descriptors which might affect the shape of
- * the HSDir hash ring. Signal that we should re-upload our HS descriptors. */
+ * the HSDir hash ring. Signal that we should reexamine the hash ring and
+ * re-upload our HS descriptors if needed. */
void
hs_hsdir_set_changed_consider_reupload(void)
{
- time_t now = approx_time();
-
- /* Check if HS subsystem is initialized */
- if (!hs_service_map) {
- return;
- }
-
- /* Basic test: If we have not bootstrapped 100% yet, no point in even trying
- to upload descriptor. */
- if (!router_have_minimum_dir_info()) {
- return;
- }
-
- log_info(LD_GENERAL, "Received new dirinfo: Checking hash ring for changes");
-
- /* Go over all descriptors and check if the set of HSDirs changed for any of
- * them. Schedule reupload if so. */
- FOR_EACH_SERVICE_BEGIN(service) {
- FOR_EACH_DESCRIPTOR_BEGIN(service, desc) {
- if (service_desc_hsdirs_changed(service, desc)) {
- service_desc_schedule_upload(desc, now, 0);
- }
- } FOR_EACH_DESCRIPTOR_END;
- } FOR_EACH_SERVICE_END;
+ log_info(LD_REND, "New dirinfo arrived: consider reuploading descriptor");
+ consider_republishing_hs_descriptors = 1;
}
/* Return the number of service we have configured and usable. */
curr_hsdir_index, nickname, 1);
}
- /* Now call router_dir_info_changed() again and see that it detected the hash
- ring change and updated the upload time */
+ /* Now call service_desc_hsdirs_changed() and see that it detected the hash
+ ring change */
time_t now = approx_time();
tt_assert(now);
- router_dir_info_changed();
- tt_int_op(desc->next_upload_time, OP_EQ, now);
+ tt_int_op(service_desc_hsdirs_changed(service, desc), OP_EQ, 1);
/* Now pretend that the descriptor changed, and order a reupload to all
HSDirs. Make sure that the set of previous HSDirs was cleared. */
OP_EQ, 0);
tt_assert(service->desc_next == NULL);
+ /* Now let's re-create desc_next and get out of overlap period. We should
+ test that desc_current gets replaced by desc_next, and desc_next becomes
+ NULL. */
+ desc_next = service_descriptor_new();
+ desc_next->next_upload_time = 240; /* Our marker to recognize it. */
+ service->desc_next = desc_next;
+
/* Going out of the overlap period. */
ret = parse_rfc1123_time("Sat, 26 Oct 1985 12:00:00 UTC",
&mock_ns.valid_after);
tt_mem_op(service->desc_current, OP_EQ, desc_next, sizeof(*desc_next));
tt_assert(service->desc_next == NULL);
+ /* Calling rotate_all_descriptors() another time should do nothing */
+ rotate_all_descriptors(now);
+ tt_int_op(service->state.in_overlap_period, OP_EQ, 0);
+ tt_mem_op(service->desc_current, OP_EQ, desc_next, sizeof(*desc_next));
+ tt_assert(service->desc_next == NULL);
+
done:
hs_free_all();
UNMOCK(circuit_mark_for_close_);