diff options
author | juga0 <juga@riseup.net> | 2018-11-02 18:38:46 +0000 |
---|---|---|
committer | teor <teor@torproject.org> | 2019-03-26 17:40:45 +1000 |
commit | 3eacae42b2ade91bc5d0e3761dce1e785aad7621 (patch) | |
tree | b96814cc2caf15a63ce8d82db4765ef58c5ec748 | |
parent | 41cd05562f68c23f8c3d95472e20a86165f6dc20 (diff) | |
download | tor-3eacae42b2ade91bc5d0e3761dce1e785aad7621.tar.gz tor-3eacae42b2ade91bc5d0e3761dce1e785aad7621.zip |
Serve bandwidth file used in the next vote
When a directory authority is using a bandwidth file to obtain the
bandwidth values that will be included in the next vote, serve this
bandwidth file at /tor/status-vote/next/bandwidth.z.
-rw-r--r-- | src/feature/dircache/dircache.c | 24 | ||||
-rw-r--r-- | src/test/test_dir_handle_get.c | 76 |
2 files changed, 100 insertions, 0 deletions
diff --git a/src/feature/dircache/dircache.c b/src/feature/dircache/dircache.c index e8cb284165..f373b74c85 100644 --- a/src/feature/dircache/dircache.c +++ b/src/feature/dircache/dircache.c @@ -357,12 +357,15 @@ static int handle_get_robots(dir_connection_t *conn, const get_handler_args_t *args); static int handle_get_networkstatus_bridges(dir_connection_t *conn, const get_handler_args_t *args); +static int handle_get_next_bandwidth(dir_connection_t *conn, + const get_handler_args_t *args); /** Table for handling GET requests. */ static const url_table_ent_t url_table[] = { { "/tor/", 0, handle_get_frontpage }, { "/tor/status-vote/current/consensus", 1, handle_get_current_consensus }, { "/tor/status-vote/current/", 1, handle_get_status_vote }, + { "/tor/status-vote/next/bandwidth", 0, handle_get_next_bandwidth }, { "/tor/status-vote/next/", 1, handle_get_status_vote }, { "/tor/micro/d/", 1, handle_get_microdesc }, { "/tor/server/", 1, handle_get_descriptor }, @@ -1438,6 +1441,27 @@ handle_get_networkstatus_bridges(dir_connection_t *conn, return 0; } +/** Helper function for GET the bandwidth file used for the next vote */ +static int +handle_get_next_bandwidth(dir_connection_t *conn, + const get_handler_args_t *args) +{ + (void)args; + log_debug(LD_DIR, "Getting next bandwidth."); + const or_options_t *options = get_options(); + if (options->V3BandwidthsFile) { + int lifetime = 60; + char *bandwidth = read_file_to_str(options->V3BandwidthsFile, 0, NULL); + size_t len = strlen(bandwidth); + write_http_response_header(conn, len, NO_METHOD, lifetime); + connection_buf_add(bandwidth, len, TO_CONN(conn)); + tor_free(bandwidth); + } else { + write_short_http_response(conn, 404, "Not found"); + } + return 0; +} + /** Helper function for GET robots.txt or /tor/robots.txt */ static int handle_get_robots(dir_connection_t *conn, const get_handler_args_t *args) diff --git a/src/test/test_dir_handle_get.c b/src/test/test_dir_handle_get.c index 90691fff94..8b2ee3ecac 100644 --- a/src/test/test_dir_handle_get.c +++ b/src/test/test_dir_handle_get.c @@ -2217,6 +2217,31 @@ test_dir_handle_get_status_vote_next_authority_not_found(void* data) tor_free(header); } +static void +test_dir_handle_get_status_vote_next_bandwidth_not_found(void* data) +{ + dir_connection_t *conn = NULL; + char *header = NULL; + (void) data; + + MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock); + + conn = new_dir_conn(); + + tt_int_op(0, OP_EQ, directory_handle_command_get(conn, + GET("/tor/status-vote/next/bandwdith"), NULL, 0)); + + fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE, + NULL, NULL, 1, 0); + tt_assert(header); + tt_str_op(NOT_FOUND, OP_EQ, header); + + done: + UNMOCK(connection_write_to_buf_impl_); + connection_free_minimal(TO_CONN(conn)); + tor_free(header); +} + NS_DECL(const char*, dirvote_get_pending_consensus, (consensus_flavor_t flav)); @@ -2455,6 +2480,55 @@ test_dir_handle_get_status_vote_next_authority(void* data) } static void +test_dir_handle_get_status_vote_next_bandwidth(void* data) +{ + dir_connection_t *conn = NULL; + char *header = NULL, *body = NULL; + size_t body_used = 0; + (void) data; + + const char *content = + "1541171221\n" + "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 " + "master_key_ed25519=YaqV4vbvPYKucElk297eVdNArDz9HtIwUoIeo0+cVIpQ " + "bw=760 nick=Test time=2018-05-08T16:13:26\n"; + + init_mock_options(); + MOCK(get_options, mock_get_options); + mock_options->V3BandwidthsFile = tor_strdup( + get_fname_rnd("V3BandwidthsFile") + ); + + write_str_to_file(mock_options->V3BandwidthsFile, content, 0); + + MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock); + + conn = new_dir_conn(); + tt_int_op(0, OP_EQ, directory_handle_command_get(conn, + GET("/tor/status-vote/next/bandwidth"), NULL, 0)); + + fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE, + &body, &body_used, strlen(content)+1, 0); + + tt_assert(header); + tt_ptr_op(strstr(header, "HTTP/1.0 200 OK\r\n"), OP_EQ, header); + tt_assert(strstr(header, "Content-Type: text/plain\r\n")); + tt_assert(strstr(header, "Content-Encoding: identity\r\n")); + tt_assert(strstr(header, "Content-Length: 167\r\n")); + + tt_int_op(body_used, OP_EQ, strlen(body)); + tt_str_op(content, OP_EQ, body); + + done: + UNMOCK(get_options); + UNMOCK(connection_write_to_buf_impl_); + connection_free_minimal(TO_CONN(conn)); + tor_free(header); + tor_free(body); + or_options_free(mock_options); mock_options = NULL; +} + +static void test_dir_handle_get_status_vote_current_authority(void* data) { dir_connection_t *conn = NULL; @@ -2627,6 +2701,8 @@ struct testcase_t dir_handle_get_tests[] = { DIR_HANDLE_CMD(status_vote_current_authority, 0), DIR_HANDLE_CMD(status_vote_next_authority_not_found, 0), DIR_HANDLE_CMD(status_vote_next_authority, 0), + DIR_HANDLE_CMD(status_vote_next_bandwidth_not_found, 0), + DIR_HANDLE_CMD(status_vote_next_bandwidth, 0), DIR_HANDLE_CMD(status_vote_current_consensus_ns_not_enough_sigs, TT_FORK), DIR_HANDLE_CMD(status_vote_current_consensus_ns_not_found, TT_FORK), DIR_HANDLE_CMD(status_vote_current_consensus_too_old, TT_FORK), |