mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 21:23:58 +01:00
Merge branch 'maint-0.4.0'
This commit is contained in:
commit
1c9b629284
4
changes/bug29706_minimal
Normal file
4
changes/bug29706_minimal
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
o Minor bugfixes (memory management, testing):
|
||||||
|
- Stop leaking parts of the shared random state in the shared-random unit
|
||||||
|
tests. The previous fix in 29599 was incomplete.
|
||||||
|
Fixes bug 29706; bugfix on 0.2.9.1-alpha.
|
4
changes/bug29706_refactor
Normal file
4
changes/bug29706_refactor
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
o Minor bugfixes (memory management):
|
||||||
|
- Refactor the shared random state's memory management so that it actually
|
||||||
|
takes ownership of the shared random value pointers.
|
||||||
|
Fixes bug 29706; bugfix on 0.2.9.1-alpha.
|
@ -120,8 +120,8 @@ static const char sr_flag_ns_str[] = "shared-rand-participate";
|
|||||||
static int32_t num_srv_agreements_from_vote;
|
static int32_t num_srv_agreements_from_vote;
|
||||||
|
|
||||||
/* Return a heap allocated copy of the SRV <b>orig</b>. */
|
/* Return a heap allocated copy of the SRV <b>orig</b>. */
|
||||||
STATIC sr_srv_t *
|
sr_srv_t *
|
||||||
srv_dup(const sr_srv_t *orig)
|
sr_srv_dup(const sr_srv_t *orig)
|
||||||
{
|
{
|
||||||
sr_srv_t *duplicate = NULL;
|
sr_srv_t *duplicate = NULL;
|
||||||
|
|
||||||
@ -1253,8 +1253,8 @@ sr_act_post_consensus(const networkstatus_t *consensus)
|
|||||||
* decided by the majority. */
|
* decided by the majority. */
|
||||||
sr_state_unset_fresh_srv();
|
sr_state_unset_fresh_srv();
|
||||||
/* Set the SR values from the given consensus. */
|
/* Set the SR values from the given consensus. */
|
||||||
sr_state_set_previous_srv(srv_dup(consensus->sr_info.previous_srv));
|
sr_state_set_previous_srv(sr_srv_dup(consensus->sr_info.previous_srv));
|
||||||
sr_state_set_current_srv(srv_dup(consensus->sr_info.current_srv));
|
sr_state_set_current_srv(sr_srv_dup(consensus->sr_info.current_srv));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare our state so that it's ready for the next voting period. */
|
/* Prepare our state so that it's ready for the next voting period. */
|
||||||
|
@ -154,6 +154,7 @@ const char *sr_commit_get_rsa_fpr(const sr_commit_t *commit)
|
|||||||
void sr_compute_srv(void);
|
void sr_compute_srv(void);
|
||||||
sr_commit_t *sr_generate_our_commit(time_t timestamp,
|
sr_commit_t *sr_generate_our_commit(time_t timestamp,
|
||||||
const authority_cert_t *my_rsa_cert);
|
const authority_cert_t *my_rsa_cert);
|
||||||
|
sr_srv_t *sr_srv_dup(const sr_srv_t *orig);
|
||||||
|
|
||||||
#ifdef SHARED_RANDOM_PRIVATE
|
#ifdef SHARED_RANDOM_PRIVATE
|
||||||
|
|
||||||
@ -172,7 +173,6 @@ STATIC sr_srv_t *get_majority_srv_from_votes(const smartlist_t *votes,
|
|||||||
int current);
|
int current);
|
||||||
|
|
||||||
STATIC void save_commit_to_state(sr_commit_t *commit);
|
STATIC void save_commit_to_state(sr_commit_t *commit);
|
||||||
STATIC sr_srv_t *srv_dup(const sr_srv_t *orig);
|
|
||||||
STATIC int commitments_are_the_same(const sr_commit_t *commit_one,
|
STATIC int commitments_are_the_same(const sr_commit_t *commit_one,
|
||||||
const sr_commit_t *commit_two);
|
const sr_commit_t *commit_two);
|
||||||
STATIC int commit_is_authoritative(const sr_commit_t *commit,
|
STATIC int commit_is_authoritative(const sr_commit_t *commit,
|
||||||
|
@ -102,6 +102,8 @@ static const config_format_t state_format = {
|
|||||||
&state_extra_var,
|
&state_extra_var,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void state_query_del_(sr_state_object_t obj_type, void *data);
|
||||||
|
|
||||||
/* Return a string representation of a protocol phase. */
|
/* Return a string representation of a protocol phase. */
|
||||||
STATIC const char *
|
STATIC const char *
|
||||||
get_phase_str(sr_phase_t phase)
|
get_phase_str(sr_phase_t phase)
|
||||||
@ -834,6 +836,9 @@ state_query_get_commit(const char *rsa_fpr)
|
|||||||
static void *
|
static void *
|
||||||
state_query_get_(sr_state_object_t obj_type, const void *data)
|
state_query_get_(sr_state_object_t obj_type, const void *data)
|
||||||
{
|
{
|
||||||
|
if (BUG(!sr_state))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
void *obj = NULL;
|
void *obj = NULL;
|
||||||
|
|
||||||
switch (obj_type) {
|
switch (obj_type) {
|
||||||
@ -862,23 +867,44 @@ state_query_get_(sr_state_object_t obj_type, const void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Helper function: This handles the PUT state action using an
|
/* Helper function: This handles the PUT state action using an
|
||||||
* <b>obj_type</b> and <b>data</b> needed for the action. */
|
* <b>obj_type</b> and <b>data</b> needed for the action.
|
||||||
|
* PUT frees the previous data before replacing it, if needed. */
|
||||||
static void
|
static void
|
||||||
state_query_put_(sr_state_object_t obj_type, void *data)
|
state_query_put_(sr_state_object_t obj_type, void *data)
|
||||||
{
|
{
|
||||||
|
if (BUG(!sr_state))
|
||||||
|
return;
|
||||||
|
|
||||||
switch (obj_type) {
|
switch (obj_type) {
|
||||||
case SR_STATE_OBJ_COMMIT:
|
case SR_STATE_OBJ_COMMIT:
|
||||||
{
|
{
|
||||||
sr_commit_t *commit = data;
|
sr_commit_t *commit = data;
|
||||||
tor_assert(commit);
|
tor_assert(commit);
|
||||||
|
/* commit_add_to_state() frees the old commit, if there is one */
|
||||||
commit_add_to_state(commit, sr_state);
|
commit_add_to_state(commit, sr_state);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SR_STATE_OBJ_CURSRV:
|
case SR_STATE_OBJ_CURSRV:
|
||||||
sr_state->current_srv = (sr_srv_t *) data;
|
/* Check if the new pointer is the same as the old one: if it is, it's
|
||||||
|
* probably a bug. The caller may have confused current and previous,
|
||||||
|
* or they may have forgotten to sr_srv_dup().
|
||||||
|
* Putting NULL multiple times is allowed. */
|
||||||
|
if (!BUG(data && sr_state->current_srv == (sr_srv_t *) data)) {
|
||||||
|
/* We own the old SRV, so we need to free it. */
|
||||||
|
state_query_del_(SR_STATE_OBJ_CURSRV, NULL);
|
||||||
|
sr_state->current_srv = (sr_srv_t *) data;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SR_STATE_OBJ_PREVSRV:
|
case SR_STATE_OBJ_PREVSRV:
|
||||||
sr_state->previous_srv = (sr_srv_t *) data;
|
/* Check if the new pointer is the same as the old one: if it is, it's
|
||||||
|
* probably a bug. The caller may have confused current and previous,
|
||||||
|
* or they may have forgotten to sr_srv_dup().
|
||||||
|
* Putting NULL multiple times is allowed. */
|
||||||
|
if (!BUG(data && sr_state->previous_srv == (sr_srv_t *) data)) {
|
||||||
|
/* We own the old SRV, so we need to free it. */
|
||||||
|
state_query_del_(SR_STATE_OBJ_PREVSRV, NULL);
|
||||||
|
sr_state->previous_srv = (sr_srv_t *) data;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SR_STATE_OBJ_VALID_AFTER:
|
case SR_STATE_OBJ_VALID_AFTER:
|
||||||
sr_state->valid_after = *((time_t *) data);
|
sr_state->valid_after = *((time_t *) data);
|
||||||
@ -898,6 +924,9 @@ state_query_put_(sr_state_object_t obj_type, void *data)
|
|||||||
static void
|
static void
|
||||||
state_query_del_all_(sr_state_object_t obj_type)
|
state_query_del_all_(sr_state_object_t obj_type)
|
||||||
{
|
{
|
||||||
|
if (BUG(!sr_state))
|
||||||
|
return;
|
||||||
|
|
||||||
switch (obj_type) {
|
switch (obj_type) {
|
||||||
case SR_STATE_OBJ_COMMIT:
|
case SR_STATE_OBJ_COMMIT:
|
||||||
{
|
{
|
||||||
@ -926,6 +955,9 @@ state_query_del_(sr_state_object_t obj_type, void *data)
|
|||||||
{
|
{
|
||||||
(void) data;
|
(void) data;
|
||||||
|
|
||||||
|
if (BUG(!sr_state))
|
||||||
|
return;
|
||||||
|
|
||||||
switch (obj_type) {
|
switch (obj_type) {
|
||||||
case SR_STATE_OBJ_PREVSRV:
|
case SR_STATE_OBJ_PREVSRV:
|
||||||
tor_free(sr_state->previous_srv);
|
tor_free(sr_state->previous_srv);
|
||||||
@ -986,7 +1018,7 @@ state_query(sr_state_action_t action, sr_state_object_t obj_type,
|
|||||||
|
|
||||||
/* Delete the current SRV value from the state freeing it and the value is set
|
/* Delete the current SRV value from the state freeing it and the value is set
|
||||||
* to NULL meaning empty. */
|
* to NULL meaning empty. */
|
||||||
static void
|
STATIC void
|
||||||
state_del_current_srv(void)
|
state_del_current_srv(void)
|
||||||
{
|
{
|
||||||
state_query(SR_STATE_ACTION_DEL, SR_STATE_OBJ_CURSRV, NULL, NULL);
|
state_query(SR_STATE_ACTION_DEL, SR_STATE_OBJ_CURSRV, NULL, NULL);
|
||||||
@ -994,22 +1026,22 @@ state_del_current_srv(void)
|
|||||||
|
|
||||||
/* Delete the previous SRV value from the state freeing it and the value is
|
/* Delete the previous SRV value from the state freeing it and the value is
|
||||||
* set to NULL meaning empty. */
|
* set to NULL meaning empty. */
|
||||||
static void
|
STATIC void
|
||||||
state_del_previous_srv(void)
|
state_del_previous_srv(void)
|
||||||
{
|
{
|
||||||
state_query(SR_STATE_ACTION_DEL, SR_STATE_OBJ_PREVSRV, NULL, NULL);
|
state_query(SR_STATE_ACTION_DEL, SR_STATE_OBJ_PREVSRV, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Rotate SRV value by freeing the previous value, assigning the current
|
/* Rotate SRV value by setting the previous SRV to the current SRV, and
|
||||||
* value to the previous one and nullifying the current one. */
|
* clearing the current SRV. */
|
||||||
STATIC void
|
STATIC void
|
||||||
state_rotate_srv(void)
|
state_rotate_srv(void)
|
||||||
{
|
{
|
||||||
/* First delete previous SRV from the state. Object will be freed. */
|
/* First delete previous SRV from the state. Object will be freed. */
|
||||||
state_del_previous_srv();
|
state_del_previous_srv();
|
||||||
/* Set previous SRV with the current one. */
|
/* Set previous SRV to a copy of the current one. */
|
||||||
sr_state_set_previous_srv(sr_state_get_current_srv());
|
sr_state_set_previous_srv(sr_srv_dup(sr_state_get_current_srv()));
|
||||||
/* Nullify the current srv. */
|
/* Free and NULL the current srv. */
|
||||||
sr_state_set_current_srv(NULL);
|
sr_state_set_current_srv(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1030,7 +1062,9 @@ sr_state_get_phase(void)
|
|||||||
return *(sr_phase_t *) ptr;
|
return *(sr_phase_t *) ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the previous SRV value from our state. Value CAN be NULL. */
|
/* Return the previous SRV value from our state. Value CAN be NULL.
|
||||||
|
* The state object owns the SRV, so the calling code should not free the SRV.
|
||||||
|
* Use sr_srv_dup() if you want to keep a copy of the SRV. */
|
||||||
const sr_srv_t *
|
const sr_srv_t *
|
||||||
sr_state_get_previous_srv(void)
|
sr_state_get_previous_srv(void)
|
||||||
{
|
{
|
||||||
@ -1049,7 +1083,9 @@ sr_state_set_previous_srv(const sr_srv_t *srv)
|
|||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the current SRV value from our state. Value CAN be NULL. */
|
/* Return the current SRV value from our state. Value CAN be NULL.
|
||||||
|
* The state object owns the SRV, so the calling code should not free the SRV.
|
||||||
|
* Use sr_srv_dup() if you want to keep a copy of the SRV. */
|
||||||
const sr_srv_t *
|
const sr_srv_t *
|
||||||
sr_state_get_current_srv(void)
|
sr_state_get_current_srv(void)
|
||||||
{
|
{
|
||||||
|
@ -140,6 +140,8 @@ STATIC int is_phase_transition(sr_phase_t next_phase);
|
|||||||
|
|
||||||
STATIC void set_sr_phase(sr_phase_t phase);
|
STATIC void set_sr_phase(sr_phase_t phase);
|
||||||
STATIC sr_state_t *get_sr_state(void);
|
STATIC sr_state_t *get_sr_state(void);
|
||||||
|
STATIC void state_del_previous_srv(void);
|
||||||
|
STATIC void state_del_current_srv(void);
|
||||||
|
|
||||||
#endif /* defined(TOR_UNIT_TESTS) */
|
#endif /* defined(TOR_UNIT_TESTS) */
|
||||||
|
|
||||||
|
@ -58,7 +58,8 @@ trusteddirserver_get_by_v3_auth_digest_m(const char *digest)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Setup a minimal dirauth environment by initializing the SR state and
|
/* Setup a minimal dirauth environment by initializing the SR state and
|
||||||
* making sure the options are set to be an authority directory. */
|
* making sure the options are set to be an authority directory.
|
||||||
|
* You must only call this function once per process. */
|
||||||
static void
|
static void
|
||||||
init_authority_state(void)
|
init_authority_state(void)
|
||||||
{
|
{
|
||||||
@ -595,7 +596,9 @@ test_encoding(void *arg)
|
|||||||
|
|
||||||
/** Setup some SRVs in our SR state. If <b>also_current</b> is set, then set
|
/** Setup some SRVs in our SR state. If <b>also_current</b> is set, then set
|
||||||
* both current and previous SRVs.
|
* both current and previous SRVs.
|
||||||
* Helper of test_vote() and test_sr_compute_srv(). */
|
* Helper of test_vote() and test_sr_compute_srv().
|
||||||
|
* You must call sr_state_free_all() to free the state at the end of each test
|
||||||
|
* function (on pass or fail). */
|
||||||
static void
|
static void
|
||||||
test_sr_setup_srv(int also_current)
|
test_sr_setup_srv(int also_current)
|
||||||
{
|
{
|
||||||
@ -605,6 +608,8 @@ test_sr_setup_srv(int also_current)
|
|||||||
"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ",
|
"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ",
|
||||||
sizeof(srv->value));
|
sizeof(srv->value));
|
||||||
|
|
||||||
|
/* sr_state_set_previous_srv() does not free() the old previous srv. */
|
||||||
|
state_del_previous_srv();
|
||||||
sr_state_set_previous_srv(srv);
|
sr_state_set_previous_srv(srv);
|
||||||
|
|
||||||
if (also_current) {
|
if (also_current) {
|
||||||
@ -614,6 +619,8 @@ test_sr_setup_srv(int also_current)
|
|||||||
"NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN",
|
"NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN",
|
||||||
sizeof(srv->value));
|
sizeof(srv->value));
|
||||||
|
|
||||||
|
/* sr_state_set_previous_srv() does not free() the old current srv. */
|
||||||
|
state_del_current_srv();
|
||||||
sr_state_set_current_srv(srv);
|
sr_state_set_current_srv(srv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1069,12 +1076,13 @@ test_sr_get_majority_srv_from_votes(void *arg)
|
|||||||
smartlist_free(votes);
|
smartlist_free(votes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Test utils that don't depend on authority state */
|
||||||
static void
|
static void
|
||||||
test_utils(void *arg)
|
test_utils_general(void *arg)
|
||||||
{
|
{
|
||||||
(void) arg;
|
(void) arg;
|
||||||
|
|
||||||
/* Testing srv_dup(). */
|
/* Testing sr_srv_dup(). */
|
||||||
{
|
{
|
||||||
sr_srv_t *srv = NULL, *dup_srv = NULL;
|
sr_srv_t *srv = NULL, *dup_srv = NULL;
|
||||||
const char *srv_value =
|
const char *srv_value =
|
||||||
@ -1082,7 +1090,7 @@ test_utils(void *arg)
|
|||||||
srv = tor_malloc_zero(sizeof(*srv));
|
srv = tor_malloc_zero(sizeof(*srv));
|
||||||
srv->num_reveals = 42;
|
srv->num_reveals = 42;
|
||||||
memcpy(srv->value, srv_value, sizeof(srv->value));
|
memcpy(srv->value, srv_value, sizeof(srv->value));
|
||||||
dup_srv = srv_dup(srv);
|
dup_srv = sr_srv_dup(srv);
|
||||||
tt_assert(dup_srv);
|
tt_assert(dup_srv);
|
||||||
tt_u64_op(dup_srv->num_reveals, OP_EQ, srv->num_reveals);
|
tt_u64_op(dup_srv->num_reveals, OP_EQ, srv->num_reveals);
|
||||||
tt_mem_op(dup_srv->value, OP_EQ, srv->value, sizeof(srv->value));
|
tt_mem_op(dup_srv->value, OP_EQ, srv->value, sizeof(srv->value));
|
||||||
@ -1133,9 +1141,19 @@ test_utils(void *arg)
|
|||||||
tt_str_op(get_phase_str(SR_PHASE_COMMIT), OP_EQ, "commit");
|
tt_str_op(get_phase_str(SR_PHASE_COMMIT), OP_EQ, "commit");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test utils that depend on authority state */
|
||||||
|
static void
|
||||||
|
test_utils_auth(void *arg)
|
||||||
|
{
|
||||||
|
(void)arg;
|
||||||
|
init_authority_state();
|
||||||
|
|
||||||
/* Testing phase transition */
|
/* Testing phase transition */
|
||||||
{
|
{
|
||||||
init_authority_state();
|
|
||||||
set_sr_phase(SR_PHASE_COMMIT);
|
set_sr_phase(SR_PHASE_COMMIT);
|
||||||
tt_int_op(is_phase_transition(SR_PHASE_REVEAL), OP_EQ, 1);
|
tt_int_op(is_phase_transition(SR_PHASE_REVEAL), OP_EQ, 1);
|
||||||
tt_int_op(is_phase_transition(SR_PHASE_COMMIT), OP_EQ, 0);
|
tt_int_op(is_phase_transition(SR_PHASE_COMMIT), OP_EQ, 0);
|
||||||
@ -1146,8 +1164,193 @@ test_utils(void *arg)
|
|||||||
tt_int_op(is_phase_transition(42), OP_EQ, 1);
|
tt_int_op(is_phase_transition(42), OP_EQ, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Testing get, set, delete, clean SRVs */
|
||||||
|
|
||||||
|
{
|
||||||
|
/* Just set the previous SRV */
|
||||||
|
test_sr_setup_srv(0);
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
|
||||||
|
state_del_previous_srv();
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
/* Delete the SRVs one at a time */
|
||||||
|
test_sr_setup_srv(1);
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
|
||||||
|
state_del_current_srv();
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
|
||||||
|
state_del_previous_srv();
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
|
||||||
|
|
||||||
|
/* And in the opposite order */
|
||||||
|
test_sr_setup_srv(1);
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
|
||||||
|
state_del_previous_srv();
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
|
||||||
|
state_del_current_srv();
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
|
||||||
|
|
||||||
|
/* And both at once */
|
||||||
|
test_sr_setup_srv(1);
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
|
||||||
|
sr_state_clean_srvs();
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
|
||||||
|
|
||||||
|
/* And do the gets and sets multiple times */
|
||||||
|
test_sr_setup_srv(1);
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
|
||||||
|
state_del_previous_srv();
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
|
||||||
|
state_del_previous_srv();
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
|
||||||
|
sr_state_clean_srvs();
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
|
||||||
|
state_del_current_srv();
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
|
||||||
|
sr_state_clean_srvs();
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
|
||||||
|
state_del_current_srv();
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
/* Now set the SRVs to NULL instead */
|
||||||
|
test_sr_setup_srv(1);
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
|
||||||
|
sr_state_set_current_srv(NULL);
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
|
||||||
|
sr_state_set_previous_srv(NULL);
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
|
||||||
|
|
||||||
|
/* And in the opposite order */
|
||||||
|
test_sr_setup_srv(1);
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
|
||||||
|
sr_state_set_previous_srv(NULL);
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
|
||||||
|
sr_state_set_current_srv(NULL);
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
|
||||||
|
|
||||||
|
/* And both at once */
|
||||||
|
test_sr_setup_srv(1);
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
|
||||||
|
sr_state_clean_srvs();
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
|
||||||
|
|
||||||
|
/* And do the gets and sets multiple times */
|
||||||
|
test_sr_setup_srv(1);
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
|
||||||
|
sr_state_set_previous_srv(NULL);
|
||||||
|
sr_state_set_previous_srv(NULL);
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
|
||||||
|
sr_state_set_current_srv(NULL);
|
||||||
|
sr_state_set_previous_srv(NULL);
|
||||||
|
sr_state_set_current_srv(NULL);
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_EQ, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
/* Now copy the values across */
|
||||||
|
test_sr_setup_srv(1);
|
||||||
|
/* Check that the pointers are non-NULL, and different from each other */
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_NE,
|
||||||
|
sr_state_get_current_srv());
|
||||||
|
/* Check that the content is different */
|
||||||
|
tt_mem_op(sr_state_get_previous_srv(), OP_NE,
|
||||||
|
sr_state_get_current_srv(), sizeof(sr_srv_t));
|
||||||
|
/* Set the current to the previous: the protocol goes the other way */
|
||||||
|
sr_state_set_current_srv(sr_srv_dup(sr_state_get_previous_srv()));
|
||||||
|
/* Check that the pointers are non-NULL, and different from each other */
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_NE,
|
||||||
|
sr_state_get_current_srv());
|
||||||
|
/* Check that the content is the same */
|
||||||
|
tt_mem_op(sr_state_get_previous_srv(), OP_EQ,
|
||||||
|
sr_state_get_current_srv(), sizeof(sr_srv_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
/* Now copy a value onto itself */
|
||||||
|
test_sr_setup_srv(1);
|
||||||
|
/* Check that the pointers are non-NULL, and different from each other */
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_NE,
|
||||||
|
sr_state_get_current_srv());
|
||||||
|
/* Take a copy of the old value */
|
||||||
|
sr_srv_t old_current_srv;
|
||||||
|
memcpy(&old_current_srv, sr_state_get_current_srv(), sizeof(sr_srv_t));
|
||||||
|
/* Check that the content is different */
|
||||||
|
tt_mem_op(sr_state_get_previous_srv(), OP_NE,
|
||||||
|
sr_state_get_current_srv(), sizeof(sr_srv_t));
|
||||||
|
/* Set the current to the current: the protocol never replaces an SRV with
|
||||||
|
* the same value */
|
||||||
|
sr_state_set_current_srv(sr_srv_dup(sr_state_get_current_srv()));
|
||||||
|
/* Check that the pointers are non-NULL, and different from each other */
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_NE, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_current_srv(), OP_NE, NULL);
|
||||||
|
tt_ptr_op(sr_state_get_previous_srv(), OP_NE,
|
||||||
|
sr_state_get_current_srv());
|
||||||
|
/* Check that the content is different between current and previous */
|
||||||
|
tt_mem_op(sr_state_get_previous_srv(), OP_NE,
|
||||||
|
sr_state_get_current_srv(), sizeof(sr_srv_t));
|
||||||
|
/* Check that the content is the same as the old content */
|
||||||
|
tt_mem_op(&old_current_srv, OP_EQ,
|
||||||
|
sr_state_get_current_srv(), sizeof(sr_srv_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* I don't think we can say "expect a BUG()" in our tests. */
|
||||||
|
#if 0
|
||||||
|
{
|
||||||
|
/* Now copy a value onto itself without sr_srv_dup().
|
||||||
|
* This should fail with a BUG() warning. */
|
||||||
|
test_sr_setup_srv(1);
|
||||||
|
sr_state_set_current_srv(sr_state_get_current_srv());
|
||||||
|
sr_state_set_previous_srv(sr_state_get_previous_srv());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
done:
|
done:
|
||||||
return;
|
sr_state_free_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1155,6 +1358,7 @@ test_state_transition(void *arg)
|
|||||||
{
|
{
|
||||||
sr_state_t *state = NULL;
|
sr_state_t *state = NULL;
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
|
sr_srv_t *cur = NULL;
|
||||||
|
|
||||||
(void) arg;
|
(void) arg;
|
||||||
|
|
||||||
@ -1193,44 +1397,47 @@ test_state_transition(void *arg)
|
|||||||
|
|
||||||
/* Test SRV rotation in our state. */
|
/* Test SRV rotation in our state. */
|
||||||
{
|
{
|
||||||
const sr_srv_t *cur, *prev;
|
|
||||||
test_sr_setup_srv(1);
|
test_sr_setup_srv(1);
|
||||||
cur = sr_state_get_current_srv();
|
tt_assert(sr_state_get_current_srv());
|
||||||
|
/* Take a copy of the data, because the state owns the pointer */
|
||||||
|
cur = sr_srv_dup(sr_state_get_current_srv());
|
||||||
tt_assert(cur);
|
tt_assert(cur);
|
||||||
/* After, current srv should be the previous and then set to NULL. */
|
/* After, the previous SRV should be the same as the old current SRV, and
|
||||||
|
* the current SRV should be set to NULL */
|
||||||
state_rotate_srv();
|
state_rotate_srv();
|
||||||
prev = sr_state_get_previous_srv();
|
tt_mem_op(sr_state_get_previous_srv(), OP_EQ, cur, sizeof(sr_srv_t));
|
||||||
tt_assert(prev == cur);
|
|
||||||
tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
|
tt_ptr_op(sr_state_get_current_srv(), OP_EQ, NULL);
|
||||||
sr_state_clean_srvs();
|
sr_state_clean_srvs();
|
||||||
|
tor_free(cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* New protocol run. */
|
/* New protocol run. */
|
||||||
{
|
{
|
||||||
const sr_srv_t *cur;
|
|
||||||
/* Setup some new SRVs so we can confirm that a new protocol run
|
/* Setup some new SRVs so we can confirm that a new protocol run
|
||||||
* actually makes them rotate and compute new ones. */
|
* actually makes them rotate and compute new ones. */
|
||||||
test_sr_setup_srv(1);
|
test_sr_setup_srv(1);
|
||||||
cur = sr_state_get_current_srv();
|
tt_assert(sr_state_get_current_srv());
|
||||||
tt_assert(cur);
|
/* Take a copy of the data, because the state owns the pointer */
|
||||||
|
cur = sr_srv_dup(sr_state_get_current_srv());
|
||||||
set_sr_phase(SR_PHASE_REVEAL);
|
set_sr_phase(SR_PHASE_REVEAL);
|
||||||
MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m);
|
MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m);
|
||||||
new_protocol_run(now);
|
new_protocol_run(now);
|
||||||
UNMOCK(get_my_v3_authority_cert);
|
UNMOCK(get_my_v3_authority_cert);
|
||||||
/* Rotation happened. */
|
/* Rotation happened. */
|
||||||
tt_assert(sr_state_get_previous_srv() == cur);
|
tt_mem_op(sr_state_get_previous_srv(), OP_EQ, cur, sizeof(sr_srv_t));
|
||||||
/* We are going into COMMIT phase so we had to rotate our SRVs. Usually
|
/* We are going into COMMIT phase so we had to rotate our SRVs. Usually
|
||||||
* our current SRV would be NULL but a new protocol run should make us
|
* our current SRV would be NULL but a new protocol run should make us
|
||||||
* compute a new SRV. */
|
* compute a new SRV. */
|
||||||
tt_assert(sr_state_get_current_srv());
|
tt_assert(sr_state_get_current_srv());
|
||||||
/* Also, make sure we did change the current. */
|
/* Also, make sure we did change the current. */
|
||||||
tt_assert(sr_state_get_current_srv() != cur);
|
tt_mem_op(sr_state_get_current_srv(), OP_NE, cur, sizeof(sr_srv_t));
|
||||||
/* We should have our commitment alone. */
|
/* We should have our commitment alone. */
|
||||||
tt_int_op(digestmap_size(state->commits), OP_EQ, 1);
|
tt_int_op(digestmap_size(state->commits), OP_EQ, 1);
|
||||||
tt_int_op(state->n_reveal_rounds, OP_EQ, 0);
|
tt_int_op(state->n_reveal_rounds, OP_EQ, 0);
|
||||||
tt_int_op(state->n_commit_rounds, OP_EQ, 0);
|
tt_int_op(state->n_commit_rounds, OP_EQ, 0);
|
||||||
/* 46 here since we were at 45 just before. */
|
/* 46 here since we were at 45 just before. */
|
||||||
tt_u64_op(state->n_protocol_runs, OP_EQ, 46);
|
tt_u64_op(state->n_protocol_runs, OP_EQ, 46);
|
||||||
|
tor_free(cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cleanup of SRVs. */
|
/* Cleanup of SRVs. */
|
||||||
@ -1241,6 +1448,7 @@ test_state_transition(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
tor_free(cur);
|
||||||
sr_state_free_all();
|
sr_state_free_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1436,7 +1644,8 @@ struct testcase_t sr_tests[] = {
|
|||||||
{ "sr_compute_srv", test_sr_compute_srv, TT_FORK, NULL, NULL },
|
{ "sr_compute_srv", test_sr_compute_srv, TT_FORK, NULL, NULL },
|
||||||
{ "sr_get_majority_srv_from_votes", test_sr_get_majority_srv_from_votes,
|
{ "sr_get_majority_srv_from_votes", test_sr_get_majority_srv_from_votes,
|
||||||
TT_FORK, NULL, NULL },
|
TT_FORK, NULL, NULL },
|
||||||
{ "utils", test_utils, TT_FORK, NULL, NULL },
|
{ "utils_general", test_utils_general, TT_FORK, NULL, NULL },
|
||||||
|
{ "utils_auth", test_utils_auth, TT_FORK, NULL, NULL },
|
||||||
{ "state_transition", test_state_transition, TT_FORK, NULL, NULL },
|
{ "state_transition", test_state_transition, TT_FORK, NULL, NULL },
|
||||||
{ "state_update", test_state_update, TT_FORK,
|
{ "state_update", test_state_update, TT_FORK,
|
||||||
NULL, NULL },
|
NULL, NULL },
|
||||||
|
Loading…
Reference in New Issue
Block a user