1 // Copyright (c) 2022 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 #include "quiche/quic/load_balancer/load_balancer_decoder.h"
6
7 #include <cstdint>
8
9 #include "absl/strings/string_view.h"
10 #include "absl/types/span.h"
11 #include "quiche/quic/core/quic_connection_id.h"
12 #include "quiche/quic/load_balancer/load_balancer_config.h"
13 #include "quiche/quic/load_balancer/load_balancer_server_id.h"
14 #include "quiche/quic/platform/api/quic_expect_bug.h"
15 #include "quiche/quic/platform/api/quic_test.h"
16
17 namespace quic {
18
19 namespace test {
20
21 namespace {
22
23 class LoadBalancerDecoderTest : public QuicTest {};
24
25 // Convenience function to shorten the code. Does not check if |array| is long
26 // enough or |length| is valid for a server ID.
MakeServerId(const uint8_t array[],const uint8_t length)27 inline LoadBalancerServerId MakeServerId(const uint8_t array[],
28 const uint8_t length) {
29 return LoadBalancerServerId(absl::Span<const uint8_t>(array, length));
30 }
31
32 constexpr char kRawKey[] = {0x8f, 0x95, 0xf0, 0x92, 0x45, 0x76, 0x5f, 0x80,
33 0x25, 0x69, 0x34, 0xe5, 0x0c, 0x66, 0x20, 0x7f};
34 constexpr absl::string_view kKey(kRawKey, kLoadBalancerKeyLen);
35 constexpr uint8_t kServerId[] = {0xed, 0x79, 0x3a, 0x51, 0xd4, 0x9b, 0x8f, 0x5f,
36 0xab, 0x65, 0xba, 0x04, 0xc3, 0x33, 0x0a};
37
38 struct LoadBalancerDecoderTestCase {
39 LoadBalancerConfig config;
40 QuicConnectionId connection_id;
41 LoadBalancerServerId server_id;
42 };
43
TEST_F(LoadBalancerDecoderTest,UnencryptedConnectionIdTestVectors)44 TEST_F(LoadBalancerDecoderTest, UnencryptedConnectionIdTestVectors) {
45 const struct LoadBalancerDecoderTestCase test_vectors[2] = {
46 {
47 *LoadBalancerConfig::CreateUnencrypted(0, 3, 4),
48 QuicConnectionId({0x07, 0xed, 0x79, 0x3a, 0x80, 0x49, 0x71, 0x8a}),
49 MakeServerId(kServerId, 3),
50 },
51 {
52 *LoadBalancerConfig::CreateUnencrypted(1, 8, 5),
53 QuicConnectionId({0x2d, 0xed, 0x79, 0x3a, 0x51, 0xd4, 0x9b, 0x8f,
54 0x5f, 0xee, 0x15, 0xda, 0x27, 0xc4}),
55 MakeServerId(kServerId, 8),
56 }};
57 for (const auto& test : test_vectors) {
58 LoadBalancerDecoder decoder;
59 LoadBalancerServerId answer;
60 EXPECT_TRUE(decoder.AddConfig(test.config));
61 EXPECT_TRUE(decoder.GetServerId(test.connection_id, answer));
62 EXPECT_EQ(answer, test.server_id);
63 }
64 }
65
66 // Compare test vectors from Appendix B of draft-ietf-quic-load-balancers-19.
TEST_F(LoadBalancerDecoderTest,DecoderTestVectors)67 TEST_F(LoadBalancerDecoderTest, DecoderTestVectors) {
68 // Try (1) the "standard" CID length of 8
69 // (2) server_id_len > nonce_len, so there is a fourth decryption pass
70 // (3) the single-pass encryption case
71 // (4) An even total length.
72 const struct LoadBalancerDecoderTestCase test_vectors[4] = {
73 {
74 *LoadBalancerConfig::Create(0, 3, 4, kKey),
75 QuicConnectionId({0x07, 0x20, 0xb1, 0xd0, 0x7b, 0x35, 0x9d, 0x3c}),
76 MakeServerId(kServerId, 3),
77 },
78 {
79 *LoadBalancerConfig::Create(1, 10, 5, kKey),
80 QuicConnectionId({0x2f, 0xcc, 0x38, 0x1b, 0xc7, 0x4c, 0xb4, 0xfb,
81 0xad, 0x28, 0x23, 0xa3, 0xd1, 0xf8, 0xfe, 0xd2}),
82 MakeServerId(kServerId, 10),
83 },
84 {
85 *LoadBalancerConfig::Create(2, 8, 8, kKey),
86 QuicConnectionId({0x50, 0x4d, 0xd2, 0xd0, 0x5a, 0x7b, 0x0d, 0xe9,
87 0xb2, 0xb9, 0x90, 0x7a, 0xfb, 0x5e, 0xcf, 0x8c,
88 0xc3}),
89 MakeServerId(kServerId, 8),
90 },
91 {
92 *LoadBalancerConfig::Create(0, 9, 9, kKey),
93 QuicConnectionId({0x12, 0x57, 0x79, 0xc9, 0xcc, 0x86, 0xbe, 0xb3,
94 0xa3, 0xa4, 0xa3, 0xca, 0x96, 0xfc, 0xe4, 0xbf,
95 0xe0, 0xcd, 0xbc}),
96 MakeServerId(kServerId, 9),
97 },
98 };
99 for (const auto& test : test_vectors) {
100 LoadBalancerDecoder decoder;
101 EXPECT_TRUE(decoder.AddConfig(test.config));
102 LoadBalancerServerId answer;
103 EXPECT_TRUE(decoder.GetServerId(test.connection_id, answer));
104 EXPECT_EQ(answer, test.server_id);
105 }
106 }
107
TEST_F(LoadBalancerDecoderTest,InvalidConfigId)108 TEST_F(LoadBalancerDecoderTest, InvalidConfigId) {
109 LoadBalancerServerId server_id({0x01, 0x02, 0x03});
110 EXPECT_TRUE(server_id.IsValid());
111 LoadBalancerDecoder decoder;
112 EXPECT_TRUE(
113 decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(1, 3, 4)));
114 QuicConnectionId wrong_config_id(
115 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07});
116 LoadBalancerServerId answer;
117 EXPECT_FALSE(decoder.GetServerId(
118 QuicConnectionId({0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}),
119 answer));
120 }
121
TEST_F(LoadBalancerDecoderTest,UnroutableCodepoint)122 TEST_F(LoadBalancerDecoderTest, UnroutableCodepoint) {
123 LoadBalancerServerId server_id({0x01, 0x02, 0x03});
124 EXPECT_TRUE(server_id.IsValid());
125 LoadBalancerDecoder decoder;
126 EXPECT_TRUE(
127 decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(1, 3, 4)));
128 LoadBalancerServerId answer;
129 EXPECT_FALSE(decoder.GetServerId(
130 QuicConnectionId({0xe0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}),
131 answer));
132 }
133
TEST_F(LoadBalancerDecoderTest,UnroutableCodepointAnyLength)134 TEST_F(LoadBalancerDecoderTest, UnroutableCodepointAnyLength) {
135 LoadBalancerServerId server_id({0x01, 0x02, 0x03});
136 EXPECT_TRUE(server_id.IsValid());
137 LoadBalancerDecoder decoder;
138 EXPECT_TRUE(
139 decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(1, 3, 4)));
140 LoadBalancerServerId answer;
141 EXPECT_FALSE(decoder.GetServerId(QuicConnectionId({0xff}), answer));
142 }
143
TEST_F(LoadBalancerDecoderTest,ConnectionIdTooShort)144 TEST_F(LoadBalancerDecoderTest, ConnectionIdTooShort) {
145 LoadBalancerServerId server_id({0x01, 0x02, 0x03});
146 EXPECT_TRUE(server_id.IsValid());
147 LoadBalancerDecoder decoder;
148 EXPECT_TRUE(
149 decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(0, 3, 4)));
150 LoadBalancerServerId answer;
151 EXPECT_FALSE(decoder.GetServerId(
152 QuicConnectionId({0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06}), answer));
153 }
154
TEST_F(LoadBalancerDecoderTest,ConnectionIdTooLongIsOK)155 TEST_F(LoadBalancerDecoderTest, ConnectionIdTooLongIsOK) {
156 LoadBalancerServerId server_id({0x01, 0x02, 0x03});
157 LoadBalancerDecoder decoder;
158 EXPECT_TRUE(
159 decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(0, 3, 4)));
160 LoadBalancerServerId answer;
161 EXPECT_TRUE(decoder.GetServerId(
162 QuicConnectionId({0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}),
163 answer));
164 EXPECT_EQ(answer, server_id);
165 }
166
TEST_F(LoadBalancerDecoderTest,DeleteConfigBadId)167 TEST_F(LoadBalancerDecoderTest, DeleteConfigBadId) {
168 LoadBalancerDecoder decoder;
169 decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(2, 3, 4));
170 decoder.DeleteConfig(0);
171 EXPECT_QUIC_BUG(decoder.DeleteConfig(7),
172 "Decoder deleting config with invalid config_id 7");
173 LoadBalancerServerId answer;
174 EXPECT_TRUE(decoder.GetServerId(
175 QuicConnectionId({0x40, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}),
176 answer));
177 }
178
TEST_F(LoadBalancerDecoderTest,DeleteConfigGoodId)179 TEST_F(LoadBalancerDecoderTest, DeleteConfigGoodId) {
180 LoadBalancerDecoder decoder;
181 decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(2, 3, 4));
182 decoder.DeleteConfig(2);
183 LoadBalancerServerId answer;
184 EXPECT_FALSE(decoder.GetServerId(
185 QuicConnectionId({0x40, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}),
186 answer));
187 }
188
189 // Create two server IDs and make sure the decoder decodes the correct one.
TEST_F(LoadBalancerDecoderTest,TwoServerIds)190 TEST_F(LoadBalancerDecoderTest, TwoServerIds) {
191 LoadBalancerServerId server_id1({0x01, 0x02, 0x03});
192 EXPECT_TRUE(server_id1.IsValid());
193 LoadBalancerServerId server_id2({0x04, 0x05, 0x06});
194 LoadBalancerDecoder decoder;
195 EXPECT_TRUE(
196 decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(0, 3, 4)));
197 LoadBalancerServerId answer;
198 EXPECT_TRUE(decoder.GetServerId(
199 QuicConnectionId({0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}),
200 answer));
201 EXPECT_EQ(answer, server_id1);
202 EXPECT_TRUE(decoder.GetServerId(
203 QuicConnectionId({0x00, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a}),
204 answer));
205 EXPECT_EQ(answer, server_id2);
206 }
207
TEST_F(LoadBalancerDecoderTest,GetConfigId)208 TEST_F(LoadBalancerDecoderTest, GetConfigId) {
209 EXPECT_FALSE(
210 LoadBalancerDecoder::GetConfigId(QuicConnectionId()).has_value());
211 for (uint8_t i = 0; i < kNumLoadBalancerConfigs; i++) {
212 const QuicConnectionId connection_id(
213 {static_cast<unsigned char>(i << kConnectionIdLengthBits)});
214 auto config_id = LoadBalancerDecoder::GetConfigId(connection_id);
215 EXPECT_EQ(config_id,
216 LoadBalancerDecoder::GetConfigId(connection_id.data()[0]));
217 EXPECT_TRUE(config_id.has_value());
218 EXPECT_EQ(*config_id, i);
219 }
220 EXPECT_FALSE(
221 LoadBalancerDecoder::GetConfigId(QuicConnectionId({0xe0})).has_value());
222 }
223
TEST_F(LoadBalancerDecoderTest,GetConfig)224 TEST_F(LoadBalancerDecoderTest, GetConfig) {
225 LoadBalancerDecoder decoder;
226 decoder.AddConfig(*LoadBalancerConfig::CreateUnencrypted(2, 3, 4));
227
228 EXPECT_EQ(decoder.GetConfig(0), nullptr);
229 EXPECT_EQ(decoder.GetConfig(1), nullptr);
230 EXPECT_EQ(decoder.GetConfig(3), nullptr);
231 EXPECT_EQ(decoder.GetConfig(4), nullptr);
232
233 const LoadBalancerConfig* config = decoder.GetConfig(2);
234 ASSERT_NE(config, nullptr);
235 EXPECT_EQ(config->server_id_len(), 3);
236 EXPECT_EQ(config->nonce_len(), 4);
237 EXPECT_FALSE(config->IsEncrypted());
238 }
239
TEST_F(LoadBalancerDecoderTest,OnePassIgnoreAdditionalBytes)240 TEST_F(LoadBalancerDecoderTest, OnePassIgnoreAdditionalBytes) {
241 uint8_t ptext[] = {0x00, 0xed, 0x79, 0x3a, 0x51, 0xd4, 0x9b, 0x8f, 0x5f, 0xee,
242 0x08, 0x0d, 0xbf, 0x48, 0xc0, 0xd1, 0xe5, 0xda, 0x41};
243 uint8_t ctext[] = {0x00, 0x4d, 0xd2, 0xd0, 0x5a, 0x7b, 0x0d, 0xe9, 0xb2, 0xb9,
244 0x90, 0x7a, 0xfb, 0x5e, 0xcf, 0x8c, 0xc3, 0xda, 0x41};
245 LoadBalancerDecoder decoder;
246 decoder.AddConfig(
247 *LoadBalancerConfig::Create(0, 8, 8, absl::string_view(kRawKey, 16)));
248 LoadBalancerServerId original_server_id(absl::Span<uint8_t>(&ptext[1], 8));
249 QuicConnectionId cid(absl::Span<uint8_t>(ctext, sizeof(ctext)));
250 LoadBalancerServerId answer;
251 EXPECT_TRUE(decoder.GetServerId(cid, answer));
252 EXPECT_EQ(answer, original_server_id);
253 }
254
255 } // namespace
256
257 } // namespace test
258
259 } // namespace quic
260