From 0fe9cfef743a00fb38d62e95bbb012a523a8eb3e Mon Sep 17 00:00:00 2001 From: David Goulet Date: Mon, 22 Jan 2024 14:57:19 -0500 Subject: [PATCH] ntorv3: Adapt CC client extension to new code Signed-off-by: David Goulet --- src/core/crypto/onion_crypto.c | 62 ++++++++++++++++++++++--- src/core/or/congestion_control_common.c | 39 ++++++++++++++++ src/core/or/congestion_control_common.h | 3 ++ 3 files changed, 98 insertions(+), 6 deletions(-) diff --git a/src/core/crypto/onion_crypto.c b/src/core/crypto/onion_crypto.c index 8c785a5c1a..8507f9f163 100644 --- a/src/core/crypto/onion_crypto.c +++ b/src/core/crypto/onion_crypto.c @@ -159,6 +159,59 @@ parse_ntor3_server_ext(const uint8_t *data, size_t data_len, return ret; } +/** Parse all ntorv3 extensions and populate the params_out with the parsed + * values. + * + * If the extension is not present, the corresponding params_out values are + * untouched. + * + * The returned value in params_out are coherent but should not be considered + * valid. The caller must do a proper validation on them. + * + * Return true on success else false indicating a parsing error or incoherent + * values in an extension. */ +static bool +parse_ntorv3_client_ext(const uint8_t *data, const size_t data_len, + circuit_params_t *params_out) +{ + bool ret = false; + trn_extension_t *ext = NULL; + + /* Parse extension from payload. */ + if (trn_extension_parse(&ext, data, data_len) < 0) { + goto end; + } + + for (size_t idx = 0; idx < trn_extension_get_num(ext); idx++) { + const trn_extension_field_t *field = trn_extension_get_fields(ext, idx); + if (field == NULL) { + ret = -1; + goto end; + } + + switch (trn_extension_field_get_field_type(field)) { + case TRUNNEL_NTORV3_EXT_TYPE_CC_RESPONSE: + ret = congestion_control_ntor3_parse_ext_response(field, params_out); + break; + default: + /* Fail on unknown extensions. */ + ret = false; + break; + } + + if (!ret) { + goto end; + } + } + + /* Success. */ + ret = true; + + end: + trn_extension_free(ext); + return ret; +} + /** Return a new server_onion_keys_t object with all of the keys * and other info we might need to do onion handshakes. (We make a copy of * our keys for each cpuworker to avoid race conditions with the main thread, @@ -608,10 +661,8 @@ negotiate_v3_ntor_client_circ_params(const uint8_t *param_response_msg, size_t param_response_len, circuit_params_t *params_out) { - int ret = congestion_control_parse_ext_response(param_response_msg, - param_response_len, - params_out); - if (ret < 0) { + if (!parse_ntorv3_client_ext(param_response_msg, param_response_len, + params_out)) { return -1; } @@ -626,10 +677,9 @@ negotiate_v3_ntor_client_circ_params(const uint8_t *param_response_msg, * In either case, we cannot proceed on this circuit, and must try a * new one. */ - if (ret && !congestion_control_enabled()) { + if (params_out->cc_enabled && !congestion_control_enabled()) { return -1; } - params_out->cc_enabled = ret; return 0; } diff --git a/src/core/or/congestion_control_common.c b/src/core/or/congestion_control_common.c index 83a0afed30..841dea4eef 100644 --- a/src/core/or/congestion_control_common.c +++ b/src/core/or/congestion_control_common.c @@ -1088,6 +1088,45 @@ congestion_control_ntor3_build_ext_response(const circuit_params_t *our_params) return field; } +/** Parse the given response in the extension field and populate the params_out + * with what we find in the extensions. + * + * Return true on success else false indicating an error. */ +bool +congestion_control_ntor3_parse_ext_response(const trn_extension_field_t *field, + circuit_params_t *params_out) +{ + bool ret = false; + trn_ntorv3_ext_cc_response_t *cc_field = NULL; + + tor_assert(field); + tor_assert(params_out); + tor_assert(trn_extension_field_get_field_type(field) == + TRUNNEL_NTORV3_EXT_TYPE_CC_RESPONSE); + + /* Parse the field into the congestion control field. */ + if (trn_ntorv3_ext_cc_response_parse(&cc_field, + trn_extension_field_getconstarray_field(field), + trn_extension_field_getlen_field(field)) < 0) { + goto end; + } + + uint8_t sendme_inc_cells = + trn_ntorv3_ext_cc_response_get_sendme_inc(cc_field); + if (!congestion_control_validate_sendme_increment(sendme_inc_cells)) { + goto end; + } + + /* All good. Get value and break */ + params_out->cc_enabled = true; + params_out->sendme_inc_cells = sendme_inc_cells; + ret = true; + + end: + trn_ntorv3_ext_cc_response_free(cc_field); + return ret; +} + /** Return true iff the given sendme increment is within the acceptable * margins. */ bool diff --git a/src/core/or/congestion_control_common.h b/src/core/or/congestion_control_common.h index a9454f493c..9f284a7ec2 100644 --- a/src/core/or/congestion_control_common.h +++ b/src/core/or/congestion_control_common.h @@ -71,6 +71,9 @@ bool congestion_control_enabled(void); bool congestion_control_ntor3_parse_ext_request( const trn_extension_field_t *ext, circuit_params_t *params_out); +bool congestion_control_ntor3_parse_ext_response( + const trn_extension_field_t *field, + circuit_params_t *params_out); trn_extension_field_t *congestion_control_build_ext_request(void); trn_extension_field_t *congestion_control_ntor3_build_ext_response( const circuit_params_t *our_params); -- 2.47.3