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