summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2006-02-11 23:15:40 +0000
committerRoger Dingledine <arma@torproject.org>2006-02-11 23:15:40 +0000
commite847085c043757dbf89b79d224c2c628ecd391ca (patch)
treea0ef70e10866fbbb0e5331dca33c8490e31af129 /src
parent484a3f3d77566e83ba3ad36e2c5e79ba32e93816 (diff)
downloadtor-e847085c043757dbf89b79d224c2c628ecd391ca.tar.gz
tor-e847085c043757dbf89b79d224c2c628ecd391ca.zip
When a client asks for an old-style directory and our write bucket
is empty, don't give it to him. This way small servers can continue to serve the directory *sometimes*, without getting overloaded. svn:r5968
Diffstat (limited to 'src')
-rw-r--r--src/or/connection.c7
-rw-r--r--src/or/directory.c16
-rw-r--r--src/or/or.h1
3 files changed, 20 insertions, 4 deletions
diff --git a/src/or/connection.c b/src/or/connection.c
index bb993ca43d..19f9165a7e 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -1036,6 +1036,13 @@ connection_bucket_write_limit(connection_t *conn)
return at_most;
}
+/** Return 1 if the global write bucket has no bytes in it,
+ * or return 0 if it does. */
+int global_write_bucket_empty(void)
+{
+ return global_write_bucket <= 0;
+}
+
/** We just read num_read onto conn. Decrement buckets appropriately. */
static void
connection_read_bucket_decrement(connection_t *conn, int num_read)
diff --git a/src/or/directory.c b/src/or/directory.c
index 23fc62deef..084da5c63d 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -1387,10 +1387,6 @@ directory_handle_command_get(connection_t *conn, char *headers,
int deflated = !strcmp(url,"/tor/dir.z");
dlen = dirserv_get_directory(&cp, deflated);
- note_request(url, dlen);
-
- tor_free(url);
-
if (dlen == 0) {
notice(LD_DIRSERV,"Client asked for the mirrored directory, but we "
"don't have a good one yet. Sending 503 Dir not available.");
@@ -1398,9 +1394,21 @@ directory_handle_command_get(connection_t *conn, char *headers,
/* try to get a new one now */
if (!already_fetching_directory(DIR_PURPOSE_FETCH_DIR))
directory_get_from_dirserver(DIR_PURPOSE_FETCH_DIR, NULL, 1);
+ tor_free(url);
return 0;
}
+ if (global_write_bucket_empty()) {
+ info(LD_DIRSERV,
+ "Client asked for the mirrored directory, but we've been "
+ "writing too many bytes lately. Sending 503 Dir busy.");
+ write_http_status_line(conn, 503, "Directory busy, try again later");
+ tor_free(url);
+ return 0;
+ }
+
+ note_request(url, dlen);
+
debug(LD_DIRSERV,"Dumping %sdirectory to client.",
deflated?"deflated ":"");
format_rfc1123_time(date, time(NULL));
diff --git a/src/or/or.h b/src/or/or.h
index 680a0fb1a3..47c1901eca 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -1635,6 +1635,7 @@ int retry_all_listeners(int force, smartlist_t *replaced_conns,
smartlist_t *new_conns);
int connection_bucket_write_limit(connection_t *conn);
+int global_write_bucket_empty(void);
void connection_bucket_init(void);
void connection_bucket_refill(struct timeval *now);