Преглед изворни кода

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

Roger Dingledine пре 19 година
родитељ
комит
e847085c04
3 измењених фајлова са 20 додато и 4 уклоњено
  1. 7 0
      src/or/connection.c
  2. 12 4
      src/or/directory.c
  3. 1 0
      src/or/or.h

+ 7 - 0
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)

+ 12 - 4
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));

+ 1 - 0
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);