aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2007-10-10 20:06:38 +0000
committerNick Mathewson <nickm@torproject.org>2007-10-10 20:06:38 +0000
commit976c8f8a71b8dac7dc683e54cce02fcfe4146780 (patch)
tree29f356e640a7b4cd2520c9e21ca1bd313759956f
parent8effa68b73402335a02651600167390942ee926e (diff)
downloadtor-976c8f8a71b8dac7dc683e54cce02fcfe4146780.tar
tor-976c8f8a71b8dac7dc683e54cce02fcfe4146780.tar.gz
r15646@catbus: nickm | 2007-10-10 16:01:54 -0400
Fix some memory leaks when serving v3 networkstatus documents and v3 certs. Generate 503 correctly when serving v3 networkstatus documents and v3 certs. svn:r11850
-rw-r--r--ChangeLog4
-rw-r--r--src/or/directory.c45
2 files changed, 37 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index 34c59d4f1..395e5360d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -29,6 +29,8 @@ Changes in version 0.2.0.8-alpha - 2007-10-12
- Add more ways for tools to download the votes that lead to the current
consensus.
- Caches now download v3 network status documents as needed.
+ - Send a 503 when low on bandwidth and a vote, consensus, or certificate
+ is requested.
o Minor features (network statuses):
- Tweak the implementation of proposal 109 slightly: allow at most
@@ -57,6 +59,8 @@ Changes in version 0.2.0.8-alpha - 2007-10-12
not on our preferred schedule.
- Make the return values and messages from signature uploads and downloads
more sensible.
+ - Fix a memory leak when serving votes and consensus documents, and
+ another when serving certificates.
o Minor bugfixes (performance):
- Use a slightly simpler string hashing algorithm (copying Python's
diff --git a/src/or/directory.c b/src/or/directory.c
index ba69bb75f..9dd218b4b 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -2161,9 +2161,10 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
if (!strcmpstart(url,"/tor/status-vote/current/") ||
!strcmpstart(url,"/tor/status-vote/next/")) {
- /*XXXX020 implement if-modified-since and 503-rate-limiting */
+ /*XXXX020 implement if-modified-since */
int current = 1;
ssize_t body_len = 0;
+ ssize_t estimated_len = 0;
smartlist_t *items = smartlist_create();
smartlist_t *dir_items = smartlist_create();
int lifetime = 60; /* XXXX020 should actually use vote intervals. */
@@ -2211,13 +2212,24 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
}
if (!smartlist_len(dir_items) && !smartlist_len(items)) {
write_http_status_line(conn, 404, "Not found");
- goto done;
+ goto vote_done;
}
- SMARTLIST_FOREACH(items, const char *, item,
- if (!deflated)
- body_len += strlen(item));
SMARTLIST_FOREACH(dir_items, cached_dir_t *, d,
body_len += deflated ? d->dir_z_len : d->dir_len);
+ estimated_len += body_len;
+ SMARTLIST_FOREACH(items, const char *, item, {
+ size_t ln = strlen(item);
+ if (deflated) {
+ body_len += ln; estimated_len += ln;
+ } else {
+ estimated_len += ln/2;
+ }
+ });
+
+ if (global_write_bucket_low(TO_CONN(conn), estimated_len, 1)) {
+ write_http_status_line(conn, 503, "Directory busy, try again later.");
+ goto vote_done;
+ }
write_http_response_header(conn, body_len ? body_len : -1, deflated,
lifetime);
@@ -2237,6 +2249,9 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
deflated ? d->dir_z_len : d->dir_len,
TO_CONN(conn)));
}
+ vote_done:
+ smartlist_free(items);
+ smartlist_free(dir_items);
goto done;
}
@@ -2306,6 +2321,7 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
}
if (!strcmpstart(url,"/tor/keys/")) {
+ /*XXXX020 implement if-modified-since */
smartlist_t *certs = smartlist_create();
ssize_t len = -1;
if (!strcmp(url, "/tor/keys/all")) {
@@ -2345,19 +2361,23 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
} else {
write_http_status_line(conn, 400, "Bad request");
smartlist_free(certs);
- goto done;
+ goto keys_done;
}
if (!smartlist_len(certs)) {
write_http_status_line(conn, 404, "Not found");
smartlist_free(certs);
- goto done;
+ goto keys_done;
}
- if (!deflated) {
- len = 0;
- SMARTLIST_FOREACH(certs, authority_cert_t *, c,
- len += c->cache_info.signed_descriptor_len);
+ len = 0;
+ SMARTLIST_FOREACH(certs, authority_cert_t *, c,
+ len += c->cache_info.signed_descriptor_len);
+
+ if (global_write_bucket_low(TO_CONN(conn), deflated?len/2:len, 1)) {
+ write_http_status_line(conn, 503, "Directory busy, try again later.");
+ goto keys_done;
}
- write_http_response_header(conn, len, deflated, 60*60);
+
+ write_http_response_header(conn, deflated?-1:len, deflated, 60*60);
if (deflated) {
conn->zlib_state = tor_zlib_new(1, ZLIB_METHOD);
SMARTLIST_FOREACH(certs, authority_cert_t *, c,
@@ -2371,6 +2391,7 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
c->cache_info.signed_descriptor_len,
TO_CONN(conn)));
}
+ keys_done:
smartlist_free(certs);
goto done;
}