Commit f733b8ac authored by Nick Mathewson's avatar Nick Mathewson 🦀
Browse files

Merge remote-tracking branch 'tor-github/pr/1719/head' into maint-0.4.3

parents a79841fd f0964628
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
@@ -3079,7 +3079,15 @@ on the public Tor network.
    before it will treat advertised bandwidths as wholly
    unreliable. (Default: 500)

== HIDDEN SERVICE OPTIONS
[[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)


HIDDEN SERVICE OPTIONS
----------------------

The following options are used to configure a hidden service. Some options
apply per service and some apply for the whole tor instance.
+1 −1
Original line number Diff line number Diff line
@@ -73,7 +73,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