if (!contents)
return -1;
- pending_vote = dirvote_add_vote(contents, &msg, &status);
+ pending_vote = dirvote_add_vote(contents, 0, &msg, &status);
tor_free(contents);
if (!pending_vote) {
log_warn(LD_DIR, "Couldn't store my own vote! (I told myself, '%s'.)",
* *<b>status_out</b> to an HTTP response and status code. (V3 authority
* only) */
pending_vote_t *
-dirvote_add_vote(const char *vote_body, const char **msg_out, int *status_out)
+dirvote_add_vote(const char *vote_body, time_t time_posted,
+ const char **msg_out, int *status_out)
{
networkstatus_t *vote;
networkstatus_voter_info_t *vi;
goto err;
}
+ if (!time_posted) { /* I imported this one myself */
+ log_notice(LD_DIR, "Retrieved vote from %s.", vi->address);
+ }
+
+ /* Check if we received it, as a post, after the cutoff when we
+ * start asking other dir auths for it. If we do, the best plan
+ * is to discard it, because using it greatly increases the chances
+ * of a split vote for this round (some dir auths got it in time,
+ * some didn't). */
+ if (time_posted && time_posted > voting_schedule.fetch_missing_votes) {
+ char tbuf1[ISO_TIME_LEN+1], tbuf2[ISO_TIME_LEN+1];
+ format_iso_time(tbuf1, time_posted);
+ format_iso_time(tbuf2, voting_schedule.fetch_missing_votes);
+ log_warn(LD_DIR, "Rejecting vote from %s received at %s; "
+ "our cutoff for received votes is %s", vi->address, tbuf1, tbuf2);
+ *msg_out = "Vote received too late, would be dangerous to count it";
+ goto err;
+ }
+
/* Fetch any new router descriptors we just learned about */
update_consensus_router_descriptor_downloads(time(NULL), 1, vote);
!strcmp(url,"/tor/post/vote")) { /* v3 networkstatus vote */
const char *msg = "OK";
int status;
- if (dirvote_add_vote(body, &msg, &status)) {
+ if (dirvote_add_vote(body, approx_time(), &msg, &status)) {
write_short_http_response(conn, status, "Vote stored");
} else {
tor_assert(msg);