xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/quic_connection_id.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_H_
6 #define QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_H_
7 
8 #include <cstdint>
9 #include <string>
10 #include <vector>
11 
12 #include "absl/types/span.h"
13 #include "quiche/quic/platform/api/quic_export.h"
14 
15 namespace quic {
16 
17 // This is a property of QUIC headers, it indicates whether the connection ID
18 // should actually be sent over the wire (or was sent on received packets).
19 enum QuicConnectionIdIncluded : uint8_t {
20   CONNECTION_ID_PRESENT = 1,
21   CONNECTION_ID_ABSENT = 2,
22 };
23 
24 // Maximum connection ID length supported by versions that use the encoding from
25 // draft-ietf-quic-invariants-06.
26 inline constexpr uint8_t kQuicMaxConnectionIdWithLengthPrefixLength = 20;
27 
28 // Maximum connection ID length supported by versions that use the encoding from
29 // draft-ietf-quic-invariants-05.
30 inline constexpr uint8_t kQuicMaxConnectionId4BitLength = 18;
31 
32 // kQuicDefaultConnectionIdLength is the only supported length for QUIC
33 // versions < v99, and is the default picked for all versions.
34 inline constexpr uint8_t kQuicDefaultConnectionIdLength = 8;
35 
36 // According to the IETF spec, the initial server connection ID generated by
37 // the client must be at least this long.
38 inline constexpr uint8_t kQuicMinimumInitialConnectionIdLength = 8;
39 
40 class QUICHE_EXPORT QuicConnectionId {
41  public:
42   // Creates a connection ID of length zero.
43   QuicConnectionId();
44 
45   // Creates a connection ID from network order bytes.
46   QuicConnectionId(const char* data, uint8_t length);
47   QuicConnectionId(const absl::Span<const uint8_t> data);
48 
49   // Creates a connection ID from another connection ID.
50   QuicConnectionId(const QuicConnectionId& other);
51 
52   // Assignment operator.
53   QuicConnectionId& operator=(const QuicConnectionId& other);
54 
55   ~QuicConnectionId();
56 
57   // Returns the length of the connection ID, in bytes.
58   uint8_t length() const;
59 
60   // Sets the length of the connection ID, in bytes.
61   // WARNING: Calling set_length() can change the in-memory location of the
62   // connection ID. Callers must therefore ensure they call data() or
63   // mutable_data() after they call set_length().
64   void set_length(uint8_t length);
65 
66   // Returns a pointer to the connection ID bytes, in network byte order.
67   const char* data() const;
68 
69   // Returns a mutable pointer to the connection ID bytes,
70   // in network byte order.
71   char* mutable_data();
72 
73   // Returns whether the connection ID has length zero.
74   bool IsEmpty() const;
75 
76   // Hash() is required to use connection IDs as keys in hash tables.
77   // During the lifetime of a process, the output of Hash() is guaranteed to be
78   // the same for connection IDs that are equal to one another. Note however
79   // that this property is not guaranteed across process lifetimes. This makes
80   // Hash() suitable for data structures such as hash tables but not for sending
81   // a hash over the network.
82   size_t Hash() const;
83 
84   // Allow absl::Hash to hash std::pair<QuicConnectionId, H>.
85   template <typename H>
AbslHashValue(H h,const QuicConnectionId & c)86   friend H AbslHashValue(H h, const QuicConnectionId& c) {
87     return H::combine(std::move(h), c.Hash());
88   }
89 
90   // Generates an ASCII string that represents
91   // the contents of the connection ID, or "0" if it is empty.
92   std::string ToString() const;
93 
94   // operator<< allows easily logging connection IDs.
95   friend QUICHE_EXPORT std::ostream& operator<<(std::ostream& os,
96                                                 const QuicConnectionId& v);
97 
98   bool operator==(const QuicConnectionId& v) const;
99   bool operator!=(const QuicConnectionId& v) const;
100   // operator< is required to use connection IDs as keys in hash tables.
101   bool operator<(const QuicConnectionId& v) const;
102 
103  private:
104   // The connection ID is represented in network byte order.
105   union {
106     // If the connection ID fits in |data_short_|, it is stored in the
107     // first |length_| bytes of |data_short_|.
108     // Otherwise it is stored in |data_long_| which is guaranteed to have a size
109     // equal to |length_|.
110     // A value of 11 was chosen because our commonly used connection ID length
111     // is 8 and with the length, the class is padded to at least 12 bytes
112     // anyway.
113     struct {
114       uint8_t padding_;  // Match length_ field of the other union member.
115       char data_short_[11];
116     };
117     struct {
118       uint8_t length_;  // length of the connection ID, in bytes.
119       char* data_long_;
120     };
121   };
122 };
123 
124 // Creates a connection ID of length zero, unless the restart flag
125 // quic_connection_ids_network_byte_order is false in which case
126 // it returns an 8-byte all-zeroes connection ID.
127 QUICHE_EXPORT QuicConnectionId EmptyQuicConnectionId();
128 
129 // QuicConnectionIdHash can be passed as hash argument to hash tables.
130 // During the lifetime of a process, the output of QuicConnectionIdHash is
131 // guaranteed to be the same for connection IDs that are equal to one another.
132 // Note however that this property is not guaranteed across process lifetimes.
133 // This makes QuicConnectionIdHash suitable for data structures such as hash
134 // tables but not for sending a hash over the network.
135 class QUICHE_EXPORT QuicConnectionIdHash {
136  public:
operator()137   size_t operator()(QuicConnectionId const& connection_id) const noexcept {
138     return connection_id.Hash();
139   }
140 };
141 
142 }  // namespace quic
143 
144 #endif  // QUICHE_QUIC_CORE_QUIC_CONNECTION_ID_H_
145