aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/TODO3
-rw-r--r--src/or/directory.c79
-rw-r--r--src/or/dirvote.c38
-rw-r--r--src/or/or.h5
4 files changed, 123 insertions, 2 deletions
diff --git a/doc/TODO b/doc/TODO
index b2daf9def..041b4e0a8 100644
--- a/doc/TODO
+++ b/doc/TODO
@@ -90,7 +90,8 @@ Things we'd like to do in 0.2.0.x:
- Fix all XXXX020s in vote code
. Code to generate consensus from a list of votes
* Detect whether votes are really all for the same period.
- - Push/pull documents as appropriate.
+ . Push/pull documents as appropriate.
+ o Serve interim votes and signatures.
- Pull votes and signatures if we don't get them.
o Store consensuses
- Cache votes and signatures on disk.
diff --git a/src/or/directory.c b/src/or/directory.c
index 76e6c99ac..0847f23fd 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -1935,6 +1935,85 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
return 0;
}
+ if (!strcmpstart(url,"/tor/status-vote/current/") ||
+ !strcmpstart(url,"/tor/status-vote/next/")) {
+ char *url_mem = url;
+ size_t url_len = strlen(url);
+ int deflated = !strcmp(url+url_len-2, ".z");
+ int current = 1;
+ ssize_t body_len = 0;
+ smartlist_t *items = smartlist_create();
+ smartlist_t *dir_items = smartlist_create();
+ int lifetime = 60; /* XXXX020 should actually use vote intervals. */
+ if (deflated)
+ url[url_len-2] = '\0';
+ url += strlen("/tor/status-vote/");
+ current = !strcmpstart(url, "current/");
+ url = strchr(url, '/');
+ tor_assert(url);
+ ++url;
+ if (!strcmp(url, "consensus")) {
+ const char *item;
+ tor_assert(!current); /* we handle current consensus specially above,
+ * since it wants to be spooled. */
+ if ((item = dirvote_get_pending_consensus()))
+ smartlist_add(items, (char*)item);
+ } else if (current && !strcmp(url, "consensus-signatures")) {
+ /* XXXX020 the spec says that we should implement
+ * currrent/consensus-signatures too. Why? */
+ const char *item;
+ if ((item=dirvote_get_pending_detached_signatures()))
+ smartlist_add(items, (char*)item);
+ } else if (current && !strcmp(url, "authority")) {
+ const cached_dir_t *d;
+ if ((d=dirvote_get_vote(NULL)))
+ smartlist_add(dir_items, (cached_dir_t*)d);
+ } else if (current) {
+ const cached_dir_t *d;
+ smartlist_t *fps = smartlist_create();
+ dir_split_resource_into_fingerprints(url, fps, NULL, 1, 1);
+ SMARTLIST_FOREACH(fps, char *, fp, {
+ if ((d = dirvote_get_vote(fp)))
+ smartlist_add(dir_items, (cached_dir_t*)d);
+ tor_free(fp);
+ });
+ smartlist_free(fps);
+ }
+ if (!smartlist_len(dir_items) && !smartlist_len(items)) {
+ write_http_status_line(conn, 404, "Not found");
+ tor_free(url_mem);
+ return 0;
+ }
+ SMARTLIST_FOREACH(items, const char *, item,
+ if (!deflated)
+ body_len += strlen(item));
+ SMARTLIST_FOREACH(dir_items, cached_dir_t *, d,
+ body_len += deflated ? d->dir_z_len : d->dir_len);
+ write_http_response_header(conn, body_len ? body_len : -1,
+ deflated?"application/octet_stream":"text/plain",
+ deflated?"deflate":NULL,
+ lifetime);
+
+ if (smartlist_len(items)) {
+ if (deflated) {
+ conn->zlib_state = tor_zlib_new(1, ZLIB_METHOD);
+ SMARTLIST_FOREACH(items, const char *, c,
+ connection_write_to_buf_zlib(c, strlen(c), conn, 0));
+ connection_write_to_buf_zlib("", 0, conn, 1);
+ } else {
+ SMARTLIST_FOREACH(items, const char *, c,
+ connection_write_to_buf(c, strlen(c), TO_CONN(conn)));
+ }
+ } else {
+ SMARTLIST_FOREACH(dir_items, cached_dir_t *, d,
+ connection_write_to_buf(deflated ? d->dir_z : d->dir,
+ deflated ? d->dir_z_len : d->dir_len,
+ TO_CONN(conn)));
+ }
+ tor_free(url_mem);
+ return 0;
+ }
+
if (!strcmpstart(url,"/tor/server/") ||
!strcmpstart(url,"/tor/extra/")) {
char *url_mem = url;
diff --git a/src/or/dirvote.c b/src/or/dirvote.c
index 5d0471375..2c88b07c9 100644
--- a/src/or/dirvote.c
+++ b/src/or/dirvote.c
@@ -1096,7 +1096,6 @@ dirvote_recalculate_timing(time_t now)
memset(&voting_schedule, 0, sizeof(voting_schedule));
if (consensus) {
- /* XXXX020 sanity-check these somewhere! */
interval = consensus->fresh_until - consensus->valid_after;
vote_delay = consensus->vote_seconds;
dist_delay = consensus->dist_seconds;
@@ -1605,3 +1604,40 @@ dirvote_free_all(void)
}
}
+/* ====
+ * Access to pending items.
+ * ==== */
+
+/** DOCDOC */
+const char *
+dirvote_get_pending_consensus(void)
+{
+ return pending_consensus_body;
+}
+
+/** DOCDOC */
+const char *
+dirvote_get_pending_detached_signatures(void)
+{
+ return pending_consensus_signatures;
+}
+
+/** DOCDOC */
+const cached_dir_t *
+dirvote_get_vote(const char *id)
+{
+ if (!pending_vote_list)
+ return NULL;
+ if (id == NULL) {
+ authority_cert_t *c = get_my_v3_authority_cert();
+ if (c)
+ id = c->cache_info.identity_digest;
+ else
+ return NULL;
+ }
+ SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, pv,
+ if (!memcmp(get_voter(pv->vote)->identity_digest, id, DIGEST_LEN))
+ return pv->vote_body);
+ return NULL;
+}
+
diff --git a/src/or/or.h b/src/or/or.h
index 4d04a7f02..a0d9b087e 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -2881,6 +2881,11 @@ int dirvote_compute_consensus(void);
int dirvote_add_signatures(const char *detached_signatures_body);
int dirvote_publish_consensus(void);
+/* Item access */
+const char *dirvote_get_pending_consensus(void);
+const char *dirvote_get_pending_detached_signatures(void);
+const cached_dir_t *dirvote_get_vote(const char *id);
+
#ifdef DIRVOTE_PRIVATE
time_t median_time(smartlist_t *times);
int median_int(smartlist_t *times);