1 /*
2 * Copyright (c) Facebook, Inc. and its affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 */
8
9 #pragma once
10
11 #include <folly/Optional.h>
12
13 #include <folly/String.h>
14 #include <folly/hash/Hash.h>
15 #include <folly/io/Cursor.h>
16 #include <folly/io/IOBuf.h>
17
18 #include <array>
19
20 #include <quic/QuicConstants.h>
21
22 namespace quic {
23 constexpr uint8_t kStatelessResetTokenLength = 16;
24 using StatelessResetToken = std::array<uint8_t, kStatelessResetTokenLength>;
25
26 // max size of a connId as specified in the draft
27 constexpr size_t kMaxConnectionIdSize = 20;
28
29 // Minimum required length (in bytes) for the destination connection-id
30 // on inbound initial packets.
31 constexpr size_t kMinInitialDestinationConnIdLength = 8;
32
33 constexpr uint64_t kInitialSequenceNumber = 0x0;
34
35 // First two bits of CID is version
36 enum class ConnectionIdVersion : uint8_t { V0 = 0, V1 = 1, V2 = 2, V3 = 3 };
37
38 struct ConnectionId {
39 uint8_t* data();
40
41 const uint8_t* data() const;
42
43 uint8_t size() const;
44
45 explicit ConnectionId(const std::vector<uint8_t>& connidIn);
46
47 explicit ConnectionId(folly::io::Cursor& cursor, size_t len);
48
49 bool operator==(const ConnectionId& other) const;
50 bool operator!=(const ConnectionId& other) const;
51
52 std::string hex() const;
53
54 /**
55 * Create an connection without any checks for tests.
56 */
57 static ConnectionId createWithoutChecks(const std::vector<uint8_t>& connidIn);
58
59 /**
60 * Create a random ConnectionId with the given length.
61 */
62 static ConnectionId createRandom(size_t len);
63
64 private:
65 ConnectionId() = default;
66
67 std::array<uint8_t, kMaxConnectionIdSize> connid;
68 uint8_t connidLen;
69 };
70
71 struct ConnectionIdHash {
operatorConnectionIdHash72 size_t operator()(const ConnectionId& connId) const {
73 return folly::hash::fnv32_buf(connId.data(), connId.size());
74 }
75 };
76
77 inline std::ostream& operator<<(std::ostream& os, const ConnectionId& connId) {
78 os << connId.hex();
79 return os;
80 }
81
toData(const ConnectionId & connId)82 inline folly::IOBuf toData(const ConnectionId& connId) {
83 return folly::IOBuf::wrapBufferAsValue(connId.data(), connId.size());
84 }
85
86 struct ConnectionIdData {
ConnectionIdDataConnectionIdData87 ConnectionIdData(const ConnectionId& connIdIn, uint64_t sequenceNumberIn)
88 : connId(connIdIn), sequenceNumber(sequenceNumberIn) {}
89
ConnectionIdDataConnectionIdData90 ConnectionIdData(
91 const ConnectionId& connIdIn,
92 uint64_t sequenceNumberIn,
93 StatelessResetToken tokenIn)
94 : connId(connIdIn), sequenceNumber(sequenceNumberIn), token(tokenIn) {}
95
96 ConnectionId connId;
97 uint64_t sequenceNumber;
98 folly::Optional<StatelessResetToken> token;
99 };
100
101 /**
102 * Encapsulate parameters to generate server chosen connection id
103 */
104 struct ServerConnectionIdParams {
ServerConnectionIdParamsServerConnectionIdParams105 explicit ServerConnectionIdParams(
106 uint32_t hostIdIn,
107 uint8_t processIdIn,
108 uint8_t workerIdIn)
109 : ServerConnectionIdParams(
110 ConnectionIdVersion::V1,
111 hostIdIn,
112 processIdIn,
113 workerIdIn) {}
114
ServerConnectionIdParamsServerConnectionIdParams115 explicit ServerConnectionIdParams(
116 ConnectionIdVersion versionIn,
117 uint32_t hostIdIn,
118 uint8_t processIdIn,
119 uint8_t workerIdIn) {
120 setVersion(versionIn);
121 setHostId(hostIdIn);
122 setProcessId(processIdIn);
123 setWorkerId(workerIdIn);
124 }
125
126 /**
127 * Set Quic connection-id short version
128 */
129 void setVersion(ConnectionIdVersion versionIn);
130
131 /**
132 * Set Quic Host id
133 * Depending on version, lower 2 or 3 bytes used
134 */
135 void setHostId(uint32_t hostIdIn);
136
137 /**
138 * Set Quic process id
139 */
140 void setProcessId(uint8_t processIdIn);
141
142 /**
143 * Set Quic server worker Id
144 */
145 void setWorkerId(uint8_t workerIdIn);
146
147 // Quic connection-id short version
148 ConnectionIdVersion version{ConnectionIdVersion::V0};
149 // Quic Host id
150 uint32_t hostId{0};
151 // Quic process id
152 uint8_t processId{0};
153 // Quic server worker Id
154 uint8_t workerId{0};
155 };
156
157 bool operator==(
158 const ServerConnectionIdParams& lhs,
159 const ServerConnectionIdParams& rhs);
160
161 bool operator!=(
162 const ServerConnectionIdParams& lhs,
163 const ServerConnectionIdParams& rhs);
164
165 } // namespace quic
166