/* Helper function: This handles the PUT state action using an * <b>obj_type</b> and <b>data</b> needed for the action. */ static void state_query_put_(sr_state_object_t obj_type, void *data) { switch (obj_type) { case SR_STATE_OBJ_COMMIT: { sr_commit_t *commit = data; tor_assert(commit); commit_add_to_state(commit, sr_state); break; } case SR_STATE_OBJ_CURSRV: sr_state->current_srv = (sr_srv_t *) data; break; case SR_STATE_OBJ_PREVSRV: sr_state->previous_srv = (sr_srv_t *) data; break; case SR_STATE_OBJ_VALID_AFTER: sr_state->valid_after = *((time_t *) data); break; /* It's not allowed to change the phase nor the full commitments map from * the state. The phase is decided during a strict process post voting and * the commits should be put individually. */ case SR_STATE_OBJ_PHASE: case SR_STATE_OBJ_COMMITS: default: tor_assert(0); } }
/* Parse the Commit line(s) in the disk state and translate them to the * the memory state. Return 0 on success else -1 on error. */ static int disk_state_parse_commits(sr_state_t *state, const sr_disk_state_t *disk_state) { config_line_t *line; smartlist_t *args = NULL; tor_assert(state); tor_assert(disk_state); for (line = disk_state->Commit; line; line = line->next) { sr_commit_t *commit = NULL; /* Extra safety. */ if (strcasecmp(line->key, dstate_commit_key) || line->value == NULL) { /* Ignore any lines that are not commits. */ tor_fragile_assert(); continue; } args = smartlist_new(); smartlist_split_string(args, line->value, " ", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0); if (smartlist_len(args) < 3) { log_warn(LD_BUG, "SR: Too few arguments in Commit Line: %s", escaped(line->value)); goto error; } commit = sr_parse_commit(args); if (commit == NULL) { /* Ignore badly formed commit. It could also be a authority * fingerprint that we don't know about so it shouldn't be used. */ smartlist_free(args); continue; } /* We consider parseable commit from our disk state to be valid because * they need to be in the first place to get in there. */ commit->valid = 1; /* Add commit to our state pointer. */ commit_add_to_state(commit, state); SMARTLIST_FOREACH(args, char *, cp, tor_free(cp)); smartlist_free(args); } return 0; error: SMARTLIST_FOREACH(args, char *, cp, tor_free(cp)); smartlist_free(args); return -1; }
/* Helper function: This handles the PUT state action using an * <b>obj_type</b> and <b>data</b> needed for the action. * PUT frees the previous data before replacing it, if needed. */ static void state_query_put_(sr_state_object_t obj_type, void *data) { if (BUG(!sr_state)) return; switch (obj_type) { case SR_STATE_OBJ_COMMIT: { sr_commit_t *commit = data; tor_assert(commit); /* commit_add_to_state() frees the old commit, if there is one */ commit_add_to_state(commit, sr_state); break; } case SR_STATE_OBJ_CURSRV: /* 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; case SR_STATE_OBJ_PREVSRV: /* 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; case SR_STATE_OBJ_VALID_AFTER: sr_state->valid_after = *((time_t *) data); break; /* It's not allowed to change the phase nor the full commitments map from * the state. The phase is decided during a strict process post voting and * the commits should be put individually. */ case SR_STATE_OBJ_PHASE: case SR_STATE_OBJ_COMMITS: default: tor_assert(0); } }