[tor-commits] [tor/master] Decide compression method in the various handle_* functions().

nickm at torproject.org nickm at torproject.org
Mon May 15 21:26:28 UTC 2017


commit cf2f7a1bea3beb03368fc309e7bf7d9ba598b6dd
Author: Alexander Færøy <ahf at torproject.org>
Date:   Thu May 11 03:32:51 2017 +0200

    Decide compression method in the various handle_* functions().
    
    See: https://bugs.torproject.org/21667
---
 src/or/directory.c | 89 ++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 56 insertions(+), 33 deletions(-)

diff --git a/src/or/directory.c b/src/or/directory.c
index ca49388..78e0fb3 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -3706,6 +3706,22 @@ find_best_diff(const smartlist_t *digests, int flav,
   return NULL;
 }
 
+/** Try to find the best supported compression method possible from a given
+ * <b>compression_methods</b>. Return NO_METHOD if no mutually supported
+ * compression method could be found. */
+static compress_method_t
+find_best_compression_method(unsigned compression_methods)
+{
+  unsigned u;
+  for (u = 0; u < ARRAY_LENGTH(srv_meth_pref_precompressed); ++u) {
+    compress_method_t method = srv_meth_pref_precompressed[u];
+    if (compression_methods & (1u<<method))
+      return method;
+  }
+
+  return NO_METHOD;
+}
+
 /** Helper function for GET /tor/status-vote/current/consensus
  */
 static int
@@ -3713,7 +3729,8 @@ handle_get_current_consensus(dir_connection_t *conn,
                              const get_handler_args_t *args)
 {
   const char *url = args->url;
-  const int compressed = args->compression_supported & (1u << ZLIB_METHOD);
+  const compress_method_t compress_method =
+    find_best_compression_method(args->compression_supported);
   const time_t if_modified_since = args->if_modified_since;
   int clear_spool = 0;
 
@@ -3786,11 +3803,11 @@ handle_get_current_consensus(dir_connection_t *conn,
     } else if (flavor) {
       spooled = spooled_resource_new(DIR_SPOOL_NETWORKSTATUS,
                                      (uint8_t*)flavor, strlen(flavor));
-      compression_used = compressed ? ZLIB_METHOD : NO_METHOD;
+      compression_used = compress_method;
     } else {
       spooled = spooled_resource_new(DIR_SPOOL_NETWORKSTATUS,
                                      NULL, 0);
-      compression_used = compressed ? ZLIB_METHOD : NO_METHOD;
+      compression_used = compress_method;
     }
     tor_free(flavor);
     smartlist_add(conn->spool, spooled);
@@ -3806,7 +3823,7 @@ handle_get_current_consensus(dir_connection_t *conn,
   size_t size_guess = 0;
   int n_expired = 0;
   dirserv_spool_remove_missing_and_guess_size(conn, if_modified_since,
-                                              compressed,
+                                              compress_method != NO_METHOD,
                                               &size_guess,
                                               &n_expired);
 
@@ -3848,8 +3865,8 @@ handle_get_current_consensus(dir_connection_t *conn,
   write_http_response_header(conn, -1,
                              compression_used,
                              smartlist_len(conn->spool) == 1 ? lifetime : 0);
-  if (! compressed)
-    conn->compress_state = tor_compress_new(0, ZLIB_METHOD,
+  if (compress_method != NO_METHOD)
+    conn->compress_state = tor_compress_new(0, compress_method,
                                             HIGH_COMPRESSION);
 
   /* Prime the connection with some data. */
@@ -3870,7 +3887,8 @@ static int
 handle_get_status_vote(dir_connection_t *conn, const get_handler_args_t *args)
 {
   const char *url = args->url;
-  const int compressed = args->compression_supported & (1u << ZLIB_METHOD);
+  const compress_method_t compress_method =
+    find_best_compression_method(args->compression_supported);
   {
     int current;
     ssize_t body_len = 0;
@@ -3927,13 +3945,13 @@ handle_get_status_vote(dir_connection_t *conn, const get_handler_args_t *args)
       goto vote_done;
     }
     SMARTLIST_FOREACH(dir_items, cached_dir_t *, d,
-                      body_len += compressed
+                      body_len += compress_method != NO_METHOD
                       ? d->dir_compressed_len
                       : d->dir_len);
     estimated_len += body_len;
     SMARTLIST_FOREACH(items, const char *, item, {
         size_t ln = strlen(item);
-        if (compressed) {
+        if (compress_method != NO_METHOD) {
           estimated_len += ln/2;
         } else {
           body_len += ln; estimated_len += ln;
@@ -3945,12 +3963,12 @@ handle_get_status_vote(dir_connection_t *conn, const get_handler_args_t *args)
       goto vote_done;
     }
     write_http_response_header(conn, body_len ? body_len : -1,
-                 compressed ? ZLIB_METHOD : NO_METHOD,
+                 compress_method,
                  lifetime);
 
     if (smartlist_len(items)) {
-      if (compressed) {
-        conn->compress_state = tor_compress_new(1, ZLIB_METHOD,
+      if (compress_method != NO_METHOD) {
+        conn->compress_state = tor_compress_new(1, compress_method,
                            choose_compression_level(estimated_len));
         SMARTLIST_FOREACH(items, const char *, c,
                  connection_write_to_buf_compress(c, strlen(c), conn, 0));
@@ -3961,9 +3979,9 @@ handle_get_status_vote(dir_connection_t *conn, const get_handler_args_t *args)
       }
     } else {
       SMARTLIST_FOREACH(dir_items, cached_dir_t *, d,
-          connection_write_to_buf(compressed
+          connection_write_to_buf(compress_method != NO_METHOD
                                   ? d->dir_compressed : d->dir,
-                                  compressed
+                                  compress_method != NO_METHOD
                                   ? d->dir_compressed_len : d->dir_len,
                                   TO_CONN(conn)));
     }
@@ -3982,7 +4000,8 @@ static int
 handle_get_microdesc(dir_connection_t *conn, const get_handler_args_t *args)
 {
   const char *url = args->url;
-  const int compressed = args->compression_supported & (1u << ZLIB_METHOD);
+  const compress_method_t compress_method =
+    find_best_compression_method(args->compression_supported);
   int clear_spool = 1;
   {
     conn->spool = smartlist_new();
@@ -3993,7 +4012,8 @@ handle_get_microdesc(dir_connection_t *conn, const get_handler_args_t *args)
                                       DSR_DIGEST256|DSR_BASE64|DSR_SORT_UNIQ);
 
     size_t size_guess = 0;
-    dirserv_spool_remove_missing_and_guess_size(conn, 0, compressed,
+    dirserv_spool_remove_missing_and_guess_size(conn, 0,
+                                                compress_method != NO_METHOD,
                                                 &size_guess, NULL);
     if (smartlist_len(conn->spool) == 0) {
       write_http_status_line(conn, 404, "Not found");
@@ -4009,11 +4029,11 @@ handle_get_microdesc(dir_connection_t *conn, const get_handler_args_t *args)
 
     clear_spool = 0;
     write_http_response_header(conn, -1,
-                               compressed ? ZLIB_METHOD : NO_METHOD,
+                               compress_method,
                                MICRODESC_CACHE_LIFETIME);
 
-    if (compressed)
-      conn->compress_state = tor_compress_new(1, ZLIB_METHOD,
+    if (compress_method != NO_METHOD)
+      conn->compress_state = tor_compress_new(1, compress_method,
                                       choose_compression_level(size_guess));
 
     const int initial_flush_result = connection_dirserv_flushed_some(conn);
@@ -4034,7 +4054,8 @@ static int
 handle_get_descriptor(dir_connection_t *conn, const get_handler_args_t *args)
 {
   const char *url = args->url;
-  const int compressed = args->compression_supported & (1u << ZLIB_METHOD);
+  const compress_method_t compress_method =
+    find_best_compression_method(args->compression_supported);
   const or_options_t *options = get_options();
   int clear_spool = 1;
   if (!strcmpstart(url,"/tor/server/") ||
@@ -4073,8 +4094,8 @@ handle_get_descriptor(dir_connection_t *conn, const get_handler_args_t *args)
     size_t size_guess = 0;
     int n_expired = 0;
     dirserv_spool_remove_missing_and_guess_size(conn, publish_cutoff,
-                                                compressed, &size_guess,
-                                                &n_expired);
+                                                compress_method != NO_METHOD,
+                                                &size_guess, &n_expired);
 
     /* If we are the bridge authority and the descriptor is a bridge
      * descriptor, remember that we served this descriptor for desc stats. */
@@ -4104,11 +4125,9 @@ handle_get_descriptor(dir_connection_t *conn, const get_handler_args_t *args)
         dir_conn_clear_spool(conn);
         goto done;
       }
-      write_http_response_header(conn, -1,
-                                 compressed ? ZLIB_METHOD : NO_METHOD,
-                                 cache_lifetime);
-      if (compressed)
-        conn->compress_state = tor_compress_new(1, ZLIB_METHOD,
+      write_http_response_header(conn, -1, compress_method, cache_lifetime);
+      if (compress_method != NO_METHOD)
+        conn->compress_state = tor_compress_new(1, compress_method,
                                         choose_compression_level(size_guess));
       clear_spool = 0;
       /* Prime the connection with some data. */
@@ -4129,7 +4148,8 @@ static int
 handle_get_keys(dir_connection_t *conn, const get_handler_args_t *args)
 {
   const char *url = args->url;
-  const int compressed = args->compression_supported & (1u << ZLIB_METHOD);
+  const compress_method_t compress_method =
+    find_best_compression_method(args->compression_supported);
   const time_t if_modified_since = args->if_modified_since;
   {
     smartlist_t *certs = smartlist_new();
@@ -4192,16 +4212,19 @@ handle_get_keys(dir_connection_t *conn, const get_handler_args_t *args)
     SMARTLIST_FOREACH(certs, authority_cert_t *, c,
                       len += c->cache_info.signed_descriptor_len);
 
-    if (global_write_bucket_low(TO_CONN(conn), compressed?len/2:len, 2)) {
+    if (global_write_bucket_low(TO_CONN(conn),
+                                compress_method != NO_METHOD ? len/2 : len,
+                                2)) {
       write_http_status_line(conn, 503, "Directory busy, try again later");
       goto keys_done;
     }
 
-    write_http_response_header(conn, compressed?-1:len,
-                               compressed ? ZLIB_METHOD : NO_METHOD,
+    write_http_response_header(conn,
+                               compress_method != NO_METHOD ? -1 : len,
+                               compress_method,
                                60*60);
-    if (compressed) {
-      conn->compress_state = tor_compress_new(1, ZLIB_METHOD,
+    if (compress_method != NO_METHOD) {
+      conn->compress_state = tor_compress_new(1, compress_method,
                                               choose_compression_level(len));
       SMARTLIST_FOREACH(certs, authority_cert_t *, c,
             connection_write_to_buf_compress(





More information about the tor-commits mailing list