From 89f5eeefb83231c6eb7b8a857b173a9f962f3c0d Mon Sep 17 00:00:00 2001 From: David Goulet Date: Thu, 3 Feb 2022 20:06:36 +0000 Subject: [PATCH] hs: Decode flow-control line This puts the flow control version (unparsed) in the descriptor. The client doesn't use it yet. Signed-off-by: David Goulet --- src/feature/hs/hs_descriptor.c | 18 ++++++++++++++++++ src/feature/hs/hs_descriptor.h | 4 ++++ src/test/hs_test_helpers.c | 6 ++++++ src/test/test_protover.c | 25 +++++++++++++++++++++++-- 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/feature/hs/hs_descriptor.c b/src/feature/hs/hs_descriptor.c index 80273c27b1..523ededf8c 100644 --- a/src/feature/hs/hs_descriptor.c +++ b/src/feature/hs/hs_descriptor.c @@ -2347,6 +2347,23 @@ desc_decode_encrypted_v3(const hs_descriptor_t *desc, desc_encrypted_out->single_onion_service = 1; } + /* Get flow control if any. */ + tok = find_opt_by_keyword(tokens, R3_FLOW_CONTROL); + if (tok) { + int ok; + + tor_asprintf(&desc_encrypted_out->flow_control_pv, "FlowCtrl=%s", + tok->args[0]); + uint8_t sendme_inc = + (uint8_t) tor_parse_uint64(tok->args[1], 10, 0, UINT8_MAX, &ok, NULL); + if (!ok || !congestion_control_validate_sendme_increment(sendme_inc)) { + log_warn(LD_REND, "Service descriptor flow control sendme " + "value is invalid"); + goto err; + } + desc_encrypted_out->sendme_inc = sendme_inc; + } + /* Initialize the descriptor's introduction point list before we start * decoding. Having 0 intro point is valid. Then decode them all. */ desc_encrypted_out->intro_points = smartlist_new(); @@ -2757,6 +2774,7 @@ hs_desc_encrypted_data_free_contents(hs_desc_encrypted_data_t *desc) hs_desc_intro_point_free(ip)); smartlist_free(desc->intro_points); } + tor_free(desc->flow_control_pv); memwipe(desc, 0, sizeof(*desc)); } diff --git a/src/feature/hs/hs_descriptor.h b/src/feature/hs/hs_descriptor.h index d959431369..8f5ee6a2f1 100644 --- a/src/feature/hs/hs_descriptor.h +++ b/src/feature/hs/hs_descriptor.h @@ -167,6 +167,10 @@ typedef struct hs_desc_encrypted_data_t { /** Is this descriptor a single onion service? */ unsigned int single_onion_service : 1; + /** Flow control protocol version line. */ + char *flow_control_pv; + uint8_t sendme_inc; + /** A list of intro points. Contains hs_desc_intro_point_t objects. */ smartlist_t *intro_points; } hs_desc_encrypted_data_t; diff --git a/src/test/hs_test_helpers.c b/src/test/hs_test_helpers.c index 2af4f71d72..20b225ba4a 100644 --- a/src/test/hs_test_helpers.c +++ b/src/test/hs_test_helpers.c @@ -4,6 +4,7 @@ #define HS_CLIENT_PRIVATE #include "core/or/or.h" +#include "core/or/versions.h" #include "lib/crypt_ops/crypto_ed25519.h" #include "test/test.h" #include "feature/nodelist/torcert.h" @@ -186,6 +187,7 @@ hs_helper_build_hs_desc_impl(unsigned int no_ip, desc->encrypted_data.create2_ntor = 1; desc->encrypted_data.intro_auth_types = smartlist_new(); desc->encrypted_data.single_onion_service = 1; + desc->encrypted_data.flow_control_pv = tor_strdup("FlowCtrl=1-2"); smartlist_add(desc->encrypted_data.intro_auth_types, tor_strdup("ed25519")); desc->encrypted_data.intro_points = smartlist_new(); if (!no_ip) { @@ -332,6 +334,10 @@ hs_helper_desc_equal(const hs_descriptor_t *desc1, /* Encrypted data section. */ tt_uint_op(desc1->encrypted_data.create2_ntor, OP_EQ, desc2->encrypted_data.create2_ntor); + tt_uint_op(desc1->encrypted_data.single_onion_service, OP_EQ, + desc2->encrypted_data.single_onion_service); + tt_str_op(desc1->encrypted_data.flow_control_pv, OP_EQ, + desc2->encrypted_data.flow_control_pv); /* Authentication type. */ tt_int_op(!!desc1->encrypted_data.intro_auth_types, OP_EQ, diff --git a/src/test/test_protover.c b/src/test/test_protover.c index ae40556220..7ad02cb9c1 100644 --- a/src/test/test_protover.c +++ b/src/test/test_protover.c @@ -355,6 +355,9 @@ test_protover_supports_version(void *arg) #define PROTOVER_PADDING_V1 1 #define PROTOVER_FLOWCTRL_V1 1 +#define PROTOVER_FLOWCTRL_V2 2 + +#define PROTOVER_RELAY_NTOR_V3 4 /* Make sure we haven't forgotten any supported protocols */ static void @@ -644,7 +647,8 @@ test_protover_vote_roundtrip_ours(void *args) "supports_establish_intro_dos_extension: %d,\n" \ "supports_v3_hsdir: %d,\n" \ "supports_v3_rendezvous_point: %d,\n" \ - "supports_hs_setup_padding: %d.", \ + "supports_hs_setup_padding: %d,\n" \ + "supports_congestion_control: %d.", \ (flags).protocols_known, \ (flags).supports_extend2_cells, \ (flags).supports_accepting_ipv6_extends, \ @@ -656,7 +660,8 @@ test_protover_vote_roundtrip_ours(void *args) (flags).supports_establish_intro_dos_extension, \ (flags).supports_v3_hsdir, \ (flags).supports_v3_rendezvous_point, \ - (flags).supports_hs_setup_padding); \ + (flags).supports_hs_setup_padding, \ + (flags).supports_congestion_control); \ STMT_END /* Test that the proto_string version version_macro sets summary_flag. */ @@ -699,6 +704,22 @@ test_protover_summarize_flags(void *args) /* Now check version exceptions */ + /* Congestion control. */ + memset(&flags, 0, sizeof(flags)); + summarize_protover_flags(&flags, + PROTOVER("FlowCtrl", PROTOVER_FLOWCTRL_V2), + NULL); + summarize_protover_flags(&flags, + PROTOVER("Relay", PROTOVER_RELAY_NTOR_V3), + NULL); + DEBUG_PROTOVER(flags); + tt_int_op(flags.protocols_known, OP_EQ, 1); + tt_int_op(flags.supports_congestion_control, OP_EQ, 1); + /* Now clear those flags, and check the rest are zero */ + flags.protocols_known = 0; + flags.supports_congestion_control = 0; + tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags)); + /* EXTEND2 cell support */ memset(&flags, 0, sizeof(flags)); summarize_protover_flags(&flags, NULL, "Tor 0.2.4.8-alpha"); -- 2.11.4.GIT