summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quiche/quic/load_balancer/load_balancer_encoder.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/third_party/quiche/src/quiche/quic/load_balancer/load_balancer_encoder.h')
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/load_balancer/load_balancer_encoder.h123
1 files changed, 123 insertions, 0 deletions
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/load_balancer/load_balancer_encoder.h b/chromium/net/third_party/quiche/src/quiche/quic/load_balancer/load_balancer_encoder.h
new file mode 100644
index 00000000000..b48bb19a839
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quiche/quic/load_balancer/load_balancer_encoder.h
@@ -0,0 +1,123 @@
+// Copyright (c) 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_ENCODER_H_
+#define QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_ENCODER_H_
+
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/load_balancer/load_balancer_config.h"
+#include "quiche/quic/load_balancer/load_balancer_server_id.h"
+
+namespace quic {
+
+namespace test {
+class LoadBalancerEncoderPeer;
+}
+
+// Default length of a 4-tuple connection ID.
+inline constexpr uint8_t kLoadBalancerUnroutableLen = 8;
+
+// Interface which receives notifications when the current config is updated.
+class QUIC_EXPORT_PRIVATE LoadBalancerEncoderVisitorInterface {
+ public:
+ virtual ~LoadBalancerEncoderVisitorInterface() {}
+
+ // Called when a config is added where none existed.
+ //
+ // Connections that support address migration should retire unroutable
+ // connection IDs and replace them with routable ones using the new config,
+ // while avoiding sending a sudden storm of packets containing
+ // RETIRE_CONNECTION_ID and NEW_CONNECTION_ID frames.
+ virtual void OnConfigAdded(const uint8_t config_id) = 0;
+ // Called when the config is changed.
+ //
+ // Existing routable connection IDs should be retired before the decoder stops
+ // supporting that config. The timing of this event is deployment-dependent
+ // and might be tied to the arrival of a new config at the encoder.
+ virtual void OnConfigChanged(const uint8_t old_config_id,
+ const uint8_t new_config_id) = 0;
+ // Called when a config is deleted. The encoder will generate unroutable
+ // connection IDs from now on.
+ //
+ // New connections will not be able to support address migration until a new
+ // config arrives. Existing connections can retain connection IDs that use the
+ // deleted config, which will only become unroutable once the decoder also
+ // deletes it. The time of that deletion is deployment-dependent and might be
+ // tied to the arrival of a new config at the encoder.
+ virtual void OnConfigDeleted(const uint8_t config_id) = 0;
+};
+
+// Manages QUIC-LB configurations to properly encode a given server ID in a
+// QUIC Connection ID.
+class QUIC_EXPORT_PRIVATE LoadBalancerEncoder {
+ public:
+ // Returns a newly created encoder with no active config, if
+ // |unroutable_connection_id_length| is valid. |visitor| specifies an optional
+ // interface to receive callbacks when config status changes.
+ // If |len_self_encoded| is true, then the first byte of any generated
+ // connection ids will encode the length. Otherwise, those bits will be
+ // random. |unroutable_connection_id_length| specifies the length of
+ // connection IDs to be generated when there is no active config. It must not
+ // be 0 and must not be larger than the RFC9000 maximum of 20.
+ static absl::optional<LoadBalancerEncoder> Create(
+ QuicRandom& random, LoadBalancerEncoderVisitorInterface* const visitor,
+ const bool len_self_encoded,
+ const uint8_t unroutable_connection_id_len = kLoadBalancerUnroutableLen);
+
+ // Attempts to replace the current config and server_id with |config| and
+ // |server_id|. If the length |server_id| does not match the server_id_length
+ // of |config| or the ID of |config| matches the ID of the current config,
+ // returns false and leaves the current config unchanged. Otherwise, returns
+ // true. When the encoder runs out of nonces, it will delete the config and
+ // begin generating unroutable connection IDs.
+ bool UpdateConfig(const LoadBalancerConfig& config,
+ const LoadBalancerServerId server_id);
+
+ // Delete the current config and generate unroutable connection IDs from now
+ // on.
+ void DeleteConfig();
+
+ // Returns the number of additional connection IDs that can be generated with
+ // the current config, or 0 if there is no current config.
+ absl::uint128 num_nonces_left() const { return num_nonces_left_; }
+
+ // Returns true if there is an active configuration.
+ bool IsEncoding() const { return config_.has_value(); }
+ // Returns true if there is an active configuration that uses encryption.
+ bool IsEncrypted() const {
+ return config_.has_value() && config_->IsEncrypted();
+ }
+
+ // If there's an active config, generates a connection ID using it. If not,
+ // generates an unroutable connection_id. If there's an error, returns a zero-
+ // length Connection ID.
+ QuicConnectionId GenerateConnectionId();
+
+ private:
+ friend class test::LoadBalancerEncoderPeer;
+
+ LoadBalancerEncoder(QuicRandom& random,
+ LoadBalancerEncoderVisitorInterface* const visitor,
+ const bool len_self_encoded,
+ const uint8_t unroutable_connection_id_len)
+ : random_(random),
+ len_self_encoded_(len_self_encoded),
+ visitor_(visitor),
+ unroutable_connection_id_len_(unroutable_connection_id_len) {}
+
+ QuicConnectionId MakeUnroutableConnectionId(uint8_t first_byte);
+
+ QuicRandom& random_;
+ const bool len_self_encoded_;
+ LoadBalancerEncoderVisitorInterface* const visitor_;
+ const uint8_t unroutable_connection_id_len_;
+
+ absl::optional<LoadBalancerConfig> config_;
+ absl::uint128 seed_, num_nonces_left_ = 0;
+ absl::optional<LoadBalancerServerId> server_id_;
+};
+
+} // namespace quic
+
+#endif // QUICHE_QUIC_LOAD_BALANCER_LOAD_BALANCER_ENCODER_H_