commit c0e9698fca7cfc5d736f1df6b997c7d0bc5246b0 Author: Nick Mathewson nickm@torproject.org Date: Tue Jun 20 11:43:37 2017 -0400
Extract "decompress" portion of connection_dir_client_reached_eof() --- src/or/directory.c | 190 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 106 insertions(+), 84 deletions(-)
diff --git a/src/or/directory.c b/src/or/directory.c index ecd9811..52a24e0 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -2191,6 +2191,108 @@ static int handle_response_fetch_renddesc_v2(dir_connection_t *, static int handle_response_upload_renddesc_v2(dir_connection_t *, const response_handler_args_t *);
+static int +dir_client_decompress_response_body(char **bodyp, size_t *bodylenp, + dir_connection_t *conn, + compress_method_t compression, + int anonymized_connection) +{ + int rv = 0; + const char *body = *bodyp; + size_t body_len = *bodylenp; + int allow_partial = (conn->base_.purpose == DIR_PURPOSE_FETCH_SERVERDESC || + conn->base_.purpose == DIR_PURPOSE_FETCH_EXTRAINFO || + conn->base_.purpose == DIR_PURPOSE_FETCH_MICRODESC); + + int plausible = body_is_plausible(body, body_len, conn->base_.purpose); + if (compression != NO_METHOD || !plausible) { + int severity = LOG_DEBUG; + char *new_body = NULL; + size_t new_len = 0; + const char *description1, *description2; + int want_to_try_both = 0; + int tried_both = 0; + compress_method_t guessed = detect_compression_method(body, body_len); + + description1 = compression_method_get_human_name(compression); + + if (BUG(description1 == NULL)) + description1 = compression_method_get_human_name(UNKNOWN_METHOD); + + if (guessed == UNKNOWN_METHOD && !plausible) + description2 = "confusing binary junk"; + else + description2 = compression_method_get_human_name(guessed); + + /* Tell the user if we don't believe what we're told about compression.*/ + want_to_try_both = (compression == UNKNOWN_METHOD || + guessed != compression); + if (want_to_try_both) { + severity = LOG_INFO; + } + + tor_log(severity, LD_HTTP, + "HTTP body from server '%s:%d' was labeled as %s, " + "%s it seems to be %s.%s", + conn->base_.address, conn->base_.port, description1, + guessed != compression?"but":"and", + description2, + (compression>0 && guessed>0 && want_to_try_both)? + " Trying both.":""); + + /* Try declared compression first if we can. + * tor_compress_supports_method() also returns true for NO_METHOD. + * Ensure that the server is not sending us data compressed using a + * compression method that is not allowed for anonymous connections. */ + if (anonymized_connection && + ! allowed_anonymous_connection_compression_method(compression)) { + warn_disallowed_anonymous_compression_method(compression); + rv = -1; + goto done; + } + + if (tor_compress_supports_method(compression)) + tor_uncompress(&new_body, &new_len, body, body_len, compression, + !allow_partial, LOG_PROTOCOL_WARN); + + /* Okay, if that didn't work, and we think that it was compressed + * differently, try that. */ + if (anonymized_connection && + ! allowed_anonymous_connection_compression_method(guessed)) { + warn_disallowed_anonymous_compression_method(guessed); + rv = -1; + goto done; + } + + if (!new_body && tor_compress_supports_method(guessed) && + compression != guessed) { + tor_uncompress(&new_body, &new_len, body, body_len, guessed, + !allow_partial, LOG_PROTOCOL_WARN); + tried_both = 1; + } + /* If we're pretty sure that we have a compressed directory, and + * we didn't manage to uncompress it, then warn and bail. */ + if (!plausible && !new_body) { + log_fn(LOG_PROTOCOL_WARN, LD_HTTP, + "Unable to decompress HTTP body (tried %s%s%s, server '%s:%d').", + description1, + tried_both?" and ":"", + tried_both?description2:"", + conn->base_.address, conn->base_.port); + rv = -1; + goto done; + } + if (new_body) { + tor_free(*bodyp); + *bodyp = new_body; + *bodylenp = new_len; + } + } + + done: + return rv; +} + /** We are a client, and we've finished reading the server's * response. Parse it and act appropriately. * @@ -2211,7 +2313,6 @@ connection_dir_client_reached_eof(dir_connection_t *conn) time_t date_header = 0; long apparent_skew; compress_method_t compression; - int plausible; int skewed = 0; int rv; int allow_partial = (conn->base_.purpose == DIR_PURPOSE_FETCH_SERVERDESC || @@ -2325,89 +2426,10 @@ connection_dir_client_reached_eof(dir_connection_t *conn) goto done; }
- plausible = body_is_plausible(body, body_len, conn->base_.purpose); - if (compression != NO_METHOD || !plausible) { - int severity = LOG_DEBUG; - char *new_body = NULL; - size_t new_len = 0; - const char *description1, *description2; - int want_to_try_both = 0; - int tried_both = 0; - compress_method_t guessed = detect_compression_method(body, body_len); - - description1 = compression_method_get_human_name(compression); - - if (BUG(description1 == NULL)) - description1 = compression_method_get_human_name(UNKNOWN_METHOD); - - if (guessed == UNKNOWN_METHOD && !plausible) - description2 = "confusing binary junk"; - else - description2 = compression_method_get_human_name(guessed); - - /* Tell the user if we don't believe what we're told about compression.*/ - want_to_try_both = (compression == UNKNOWN_METHOD || - guessed != compression); - if (want_to_try_both) { - severity = LOG_INFO; - } - - tor_log(severity, LD_HTTP, - "HTTP body from server '%s:%d' was labeled as %s, " - "%s it seems to be %s.%s", - conn->base_.address, conn->base_.port, description1, - guessed != compression?"but":"and", - description2, - (compression>0 && guessed>0 && want_to_try_both)? - " Trying both.":""); - - /* Try declared compression first if we can. - * tor_compress_supports_method() also returns true for NO_METHOD. - * Ensure that the server is not sending us data compressed using a - * compression method that is not allowed for anonymous connections. */ - if (anonymized_connection && - ! allowed_anonymous_connection_compression_method(compression)) { - warn_disallowed_anonymous_compression_method(compression); - rv = -1; - goto done; - } - - if (tor_compress_supports_method(compression)) - tor_uncompress(&new_body, &new_len, body, body_len, compression, - !allow_partial, LOG_PROTOCOL_WARN); - - /* Okay, if that didn't work, and we think that it was compressed - * differently, try that. */ - if (anonymized_connection && - ! allowed_anonymous_connection_compression_method(guessed)) { - warn_disallowed_anonymous_compression_method(guessed); - rv = -1; - goto done; - } - - if (!new_body && tor_compress_supports_method(guessed) && - compression != guessed) { - tor_uncompress(&new_body, &new_len, body, body_len, guessed, - !allow_partial, LOG_PROTOCOL_WARN); - tried_both = 1; - } - /* If we're pretty sure that we have a compressed directory, and - * we didn't manage to uncompress it, then warn and bail. */ - if (!plausible && !new_body) { - log_fn(LOG_PROTOCOL_WARN, LD_HTTP, - "Unable to decompress HTTP body (tried %s%s%s, server '%s:%d').", - description1, - tried_both?" and ":"", - tried_both?description2:"", - conn->base_.address, conn->base_.port); - rv = -1; - goto done; - } - if (new_body) { - tor_free(body); - body = new_body; - body_len = new_len; - } + if (dir_client_decompress_response_body(&body, &body_len, + conn, compression, anonymized_connection) < 0) { + rv = -1; + goto done; }
response_handler_args_t args;