Commit 09fb7987 authored by Nick Mathewson's avatar Nick Mathewson 🦀
Browse files

Merge branch 'maint-0.4.3'

parents d559ca3d f733b8ac
Loading
Loading
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.
+9 −1
Original line number Diff line number Diff line
@@ -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
@@ -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
+1 −1
Original line number Diff line number Diff line
@@ -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
+29 −27
Original line number Diff line number Diff line
@@ -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"
@@ -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)
@@ -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.
@@ -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
+2 −2
Original line number Diff line number Diff line
@@ -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