Loading changes/ticket33029 0 → 100644 +5 −0 Original line number Diff line number Diff line o Major bugfixes (directory authority): - Directory authorities will now send a 503 (not enough bandwidth) code to clients when under bandwidth pressure. Known relays and other authorities will always be answered regardless of the bandwidth situation. Fixes bug 33029; bugfix on 0.1.2.5-alpha. doc/tor.1.txt +9 −1 Original line number Diff line number Diff line Loading @@ -2965,6 +2965,13 @@ on the public Tor network. //Out of order because it logically belongs with the other CCs options. [[AuthDirInvalidCCs]] **AuthDirInvalidCCs** __CC__,... + [[AuthDirRejectRequestsUnderLoad]] **AuthDirRejectRequestsUnderLoad** **0**|**1**:: If set, the directory authority will start rejecting directory requests from non relay connections by sending a 503 error code if it is under bandwidth pressure (reaching the configured limit if any). Relays will always tried to be answered even if this is on. (Default: 1) [[AuthDirRejectCCs]] **AuthDirRejectCCs** __CC__,...:: Authoritative directories only. These options contain a comma-separated list of country codes such that any server in one of those country codes Loading Loading @@ -3064,7 +3071,8 @@ on the public Tor network. V3 authoritative directories only. Configures the server's preferred delay between publishing its vote and assuming it has all the votes from all the other authorities. Note that the actual time used is not the server's preferred time, but the consensus of all preferences. (Default: 5 minutes) preferred time, but the consensus of all preferences. (Default: 5 minutes) [[V3AuthVotingInterval]] **V3AuthVotingInterval** __N__ **minutes**|**hours**:: V3 authoritative directories only. Configures the server's preferred voting Loading scripts/maint/practracker/exceptions.txt +1 −1 Original line number Diff line number Diff line Loading @@ -71,7 +71,7 @@ problem function-size /src/core/mainloop/connection.c:connection_handle_read_imp problem function-size /src/core/mainloop/connection.c:connection_buf_read_from_socket() 180 problem function-size /src/core/mainloop/connection.c:connection_handle_write_impl() 241 problem function-size /src/core/mainloop/connection.c:assert_connection_ok() 143 problem dependency-violation /src/core/mainloop/connection.c 44 problem dependency-violation /src/core/mainloop/connection.c 47 problem dependency-violation /src/core/mainloop/cpuworker.c 12 problem include-count /src/core/mainloop/mainloop.c 64 problem function-size /src/core/mainloop/mainloop.c:conn_close_if_marked() 108 Loading src/core/mainloop/connection.c +29 −27 Original line number Diff line number Diff line Loading @@ -91,6 +91,7 @@ #include "feature/control/control.h" #include "feature/control/control_events.h" #include "feature/dirauth/authmode.h" #include "feature/dirauth/dirauth_config.h" #include "feature/dircache/dirserv.h" #include "feature/dircommon/directory.h" #include "feature/hibernate/hibernate.h" Loading Loading @@ -3137,7 +3138,7 @@ connection_mark_all_noncontrol_connections(void) * uses pluggable transports, since we should then limit it even if it * comes from an internal IP address. */ static int connection_is_rate_limited(connection_t *conn) connection_is_rate_limited(const connection_t *conn) { const or_options_t *options = get_options(); if (conn->linked) Loading Loading @@ -3272,14 +3273,14 @@ connection_bucket_write_limit(connection_t *conn, time_t now) global_bucket_val, conn_bucket); } /** Return 1 if the global write buckets are low enough that we /** Return true iff the global write buckets are low enough that we * shouldn't send <b>attempt</b> bytes of low-priority directory stuff * out to <b>conn</b>. Else return 0. * Priority was 1 for v1 requests (directories and running-routers), * and 2 for v2 requests and later (statuses and descriptors). * out to <b>conn</b>. * * If we are a directory authority, always answer dir requests thus true is * always returned. * * There are a lot of parameters we could use here: * Note: There are a lot of parameters we could use here: * - global_relayed_write_bucket. Low is bad. * - global_write_bucket. Low is bad. * - bandwidthrate. Low is bad. Loading @@ -3291,39 +3292,40 @@ connection_bucket_write_limit(connection_t *conn, time_t now) * mean is "total directory bytes added to outbufs recently", but * that's harder to quantify and harder to keep track of. */ int global_write_bucket_low(connection_t *conn, size_t attempt, int priority) bool connection_dir_is_global_write_low(const connection_t *conn, size_t attempt) { size_t smaller_bucket = MIN(token_bucket_rw_get_write(&global_bucket), token_bucket_rw_get_write(&global_relayed_bucket)); if (authdir_mode(get_options()) && priority>1) return 0; /* there's always room to answer v2 if we're an auth dir */ /* Special case for authorities (directory only). */ if (authdir_mode_v3(get_options())) { /* Are we configured to possibly reject requests under load? */ if (!dirauth_should_reject_requests_under_load()) { /* Answer request no matter what. */ return false; } /* Always answer requests from a known relay which includes the other * authorities. The following looks up the addresses for relays that we * have their descriptor _and_ any configured trusted directories. */ if (nodelist_probably_contains_address(&conn->addr)) { return false; } } if (!connection_is_rate_limited(conn)) return 0; /* local conns don't get limited */ return false; /* local conns don't get limited */ if (smaller_bucket < attempt) return 1; /* not enough space no matter the priority */ return true; /* not enough space. */ { const time_t diff = approx_time() - write_buckets_last_empty_at; if (diff <= 1) return 1; /* we're already hitting our limits, no more please */ } if (priority == 1) { /* old-style v1 query */ /* Could we handle *two* of these requests within the next two seconds? */ const or_options_t *options = get_options(); size_t can_write = (size_t) (smaller_bucket + 2*(options->RelayBandwidthRate ? options->RelayBandwidthRate : options->BandwidthRate)); if (can_write < 2*attempt) return 1; } else { /* v2 query */ /* no further constraints yet */ return true; /* we're already hitting our limits, no more please */ } return 0; return false; } /** When did we last tell the accounting subsystem about transmitted Loading src/core/mainloop/connection.h +2 −2 Original line number Diff line number Diff line Loading @@ -219,8 +219,8 @@ void connection_mark_all_noncontrol_listeners(void); void connection_mark_all_noncontrol_connections(void); ssize_t connection_bucket_write_limit(struct connection_t *conn, time_t now); int global_write_bucket_low(struct connection_t *conn, size_t attempt, int priority); bool connection_dir_is_global_write_low(const struct connection_t *conn, size_t attempt); void connection_bucket_init(void); void connection_bucket_adjust(const struct or_options_t *options); void connection_bucket_refill_all(time_t now, Loading Loading
changes/ticket33029 0 → 100644 +5 −0 Original line number Diff line number Diff line o Major bugfixes (directory authority): - Directory authorities will now send a 503 (not enough bandwidth) code to clients when under bandwidth pressure. Known relays and other authorities will always be answered regardless of the bandwidth situation. Fixes bug 33029; bugfix on 0.1.2.5-alpha.
doc/tor.1.txt +9 −1 Original line number Diff line number Diff line Loading @@ -2965,6 +2965,13 @@ on the public Tor network. //Out of order because it logically belongs with the other CCs options. [[AuthDirInvalidCCs]] **AuthDirInvalidCCs** __CC__,... + [[AuthDirRejectRequestsUnderLoad]] **AuthDirRejectRequestsUnderLoad** **0**|**1**:: If set, the directory authority will start rejecting directory requests from non relay connections by sending a 503 error code if it is under bandwidth pressure (reaching the configured limit if any). Relays will always tried to be answered even if this is on. (Default: 1) [[AuthDirRejectCCs]] **AuthDirRejectCCs** __CC__,...:: Authoritative directories only. These options contain a comma-separated list of country codes such that any server in one of those country codes Loading Loading @@ -3064,7 +3071,8 @@ on the public Tor network. V3 authoritative directories only. Configures the server's preferred delay between publishing its vote and assuming it has all the votes from all the other authorities. Note that the actual time used is not the server's preferred time, but the consensus of all preferences. (Default: 5 minutes) preferred time, but the consensus of all preferences. (Default: 5 minutes) [[V3AuthVotingInterval]] **V3AuthVotingInterval** __N__ **minutes**|**hours**:: V3 authoritative directories only. Configures the server's preferred voting Loading
scripts/maint/practracker/exceptions.txt +1 −1 Original line number Diff line number Diff line Loading @@ -71,7 +71,7 @@ problem function-size /src/core/mainloop/connection.c:connection_handle_read_imp problem function-size /src/core/mainloop/connection.c:connection_buf_read_from_socket() 180 problem function-size /src/core/mainloop/connection.c:connection_handle_write_impl() 241 problem function-size /src/core/mainloop/connection.c:assert_connection_ok() 143 problem dependency-violation /src/core/mainloop/connection.c 44 problem dependency-violation /src/core/mainloop/connection.c 47 problem dependency-violation /src/core/mainloop/cpuworker.c 12 problem include-count /src/core/mainloop/mainloop.c 64 problem function-size /src/core/mainloop/mainloop.c:conn_close_if_marked() 108 Loading
src/core/mainloop/connection.c +29 −27 Original line number Diff line number Diff line Loading @@ -91,6 +91,7 @@ #include "feature/control/control.h" #include "feature/control/control_events.h" #include "feature/dirauth/authmode.h" #include "feature/dirauth/dirauth_config.h" #include "feature/dircache/dirserv.h" #include "feature/dircommon/directory.h" #include "feature/hibernate/hibernate.h" Loading Loading @@ -3137,7 +3138,7 @@ connection_mark_all_noncontrol_connections(void) * uses pluggable transports, since we should then limit it even if it * comes from an internal IP address. */ static int connection_is_rate_limited(connection_t *conn) connection_is_rate_limited(const connection_t *conn) { const or_options_t *options = get_options(); if (conn->linked) Loading Loading @@ -3272,14 +3273,14 @@ connection_bucket_write_limit(connection_t *conn, time_t now) global_bucket_val, conn_bucket); } /** Return 1 if the global write buckets are low enough that we /** Return true iff the global write buckets are low enough that we * shouldn't send <b>attempt</b> bytes of low-priority directory stuff * out to <b>conn</b>. Else return 0. * Priority was 1 for v1 requests (directories and running-routers), * and 2 for v2 requests and later (statuses and descriptors). * out to <b>conn</b>. * * If we are a directory authority, always answer dir requests thus true is * always returned. * * There are a lot of parameters we could use here: * Note: There are a lot of parameters we could use here: * - global_relayed_write_bucket. Low is bad. * - global_write_bucket. Low is bad. * - bandwidthrate. Low is bad. Loading @@ -3291,39 +3292,40 @@ connection_bucket_write_limit(connection_t *conn, time_t now) * mean is "total directory bytes added to outbufs recently", but * that's harder to quantify and harder to keep track of. */ int global_write_bucket_low(connection_t *conn, size_t attempt, int priority) bool connection_dir_is_global_write_low(const connection_t *conn, size_t attempt) { size_t smaller_bucket = MIN(token_bucket_rw_get_write(&global_bucket), token_bucket_rw_get_write(&global_relayed_bucket)); if (authdir_mode(get_options()) && priority>1) return 0; /* there's always room to answer v2 if we're an auth dir */ /* Special case for authorities (directory only). */ if (authdir_mode_v3(get_options())) { /* Are we configured to possibly reject requests under load? */ if (!dirauth_should_reject_requests_under_load()) { /* Answer request no matter what. */ return false; } /* Always answer requests from a known relay which includes the other * authorities. The following looks up the addresses for relays that we * have their descriptor _and_ any configured trusted directories. */ if (nodelist_probably_contains_address(&conn->addr)) { return false; } } if (!connection_is_rate_limited(conn)) return 0; /* local conns don't get limited */ return false; /* local conns don't get limited */ if (smaller_bucket < attempt) return 1; /* not enough space no matter the priority */ return true; /* not enough space. */ { const time_t diff = approx_time() - write_buckets_last_empty_at; if (diff <= 1) return 1; /* we're already hitting our limits, no more please */ } if (priority == 1) { /* old-style v1 query */ /* Could we handle *two* of these requests within the next two seconds? */ const or_options_t *options = get_options(); size_t can_write = (size_t) (smaller_bucket + 2*(options->RelayBandwidthRate ? options->RelayBandwidthRate : options->BandwidthRate)); if (can_write < 2*attempt) return 1; } else { /* v2 query */ /* no further constraints yet */ return true; /* we're already hitting our limits, no more please */ } return 0; return false; } /** When did we last tell the accounting subsystem about transmitted Loading
src/core/mainloop/connection.h +2 −2 Original line number Diff line number Diff line Loading @@ -219,8 +219,8 @@ void connection_mark_all_noncontrol_listeners(void); void connection_mark_all_noncontrol_connections(void); ssize_t connection_bucket_write_limit(struct connection_t *conn, time_t now); int global_write_bucket_low(struct connection_t *conn, size_t attempt, int priority); bool connection_dir_is_global_write_low(const struct connection_t *conn, size_t attempt); void connection_bucket_init(void); void connection_bucket_adjust(const struct or_options_t *options); void connection_bucket_refill_all(time_t now, Loading