]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
ntorv3: Adapt CC client extension to new code
authorDavid Goulet <dgoulet@torproject.org>
Mon, 22 Jan 2024 19:57:19 +0000 (14:57 -0500)
committerDavid Goulet <dgoulet@torproject.org>
Wed, 31 Jan 2024 15:15:07 +0000 (10:15 -0500)
Signed-off-by: David Goulet <dgoulet@torproject.org>
src/core/crypto/onion_crypto.c
src/core/or/congestion_control_common.c
src/core/or/congestion_control_common.h

index 8c785a5c1a378afc1e89baf41785e8c2a32a1c7c..8507f9f1639a75d24728679b2e5362d9257639e3 100644 (file)
@@ -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;
 }
index 83a0afed301174a78fd5fee860fa8554d69d1591..841dea4eeff9f46be9b29df659c0535cab32fa42 100644 (file)
@@ -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
index a9454f493c08a5d2d026526d010797d017ee2e06..9f284a7ec202888a1ed664601b7c19de91943e7c 100644 (file)
@@ -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);