blob: 459738937fc4a903fbd36f17e11bf79e46efc6ff [file] [log] [blame]
Ben Schwartzded1b702017-10-25 14:41:02 -04001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "dns_tls_test"
Bernie Innocenti31e43e12018-09-25 15:28:12 +090018#define LOG_NDEBUG 1 // Set to 0 to enable verbose debug logging
Ben Schwartzded1b702017-10-25 14:41:02 -040019
20#include <gtest/gtest.h>
21
Mike Yu5ae61542018-10-19 22:11:43 +080022#include "netd_resolv/DnsTlsDispatcher.h"
23#include "netd_resolv/DnsTlsQueryMap.h"
24#include "netd_resolv/DnsTlsServer.h"
25#include "netd_resolv/DnsTlsSessionCache.h"
26#include "netd_resolv/DnsTlsSocket.h"
27#include "netd_resolv/DnsTlsTransport.h"
28#include "netd_resolv/IDnsTlsSocket.h"
29#include "netd_resolv/IDnsTlsSocketFactory.h"
30#include "netd_resolv/IDnsTlsSocketObserver.h"
Ben Schwartzded1b702017-10-25 14:41:02 -040031
32#include <chrono>
33#include <arpa/inet.h>
34#include <android-base/macros.h>
35#include <netdutils/Slice.h>
36
37#include "log/log.h"
38
39namespace android {
40namespace net {
41
42using netdutils::Slice;
43using netdutils::makeSlice;
44
45typedef std::vector<uint8_t> bytevec;
46
47static void parseServer(const char* server, in_port_t port, sockaddr_storage* parsed) {
48 sockaddr_in* sin = reinterpret_cast<sockaddr_in*>(parsed);
49 if (inet_pton(AF_INET, server, &(sin->sin_addr)) == 1) {
50 // IPv4 parse succeeded, so it's IPv4
51 sin->sin_family = AF_INET;
52 sin->sin_port = htons(port);
53 return;
54 }
55 sockaddr_in6* sin6 = reinterpret_cast<sockaddr_in6*>(parsed);
56 if (inet_pton(AF_INET6, server, &(sin6->sin6_addr)) == 1){
57 // IPv6 parse succeeded, so it's IPv6.
58 sin6->sin6_family = AF_INET6;
59 sin6->sin6_port = htons(port);
60 return;
61 }
62 ALOGE("Failed to parse server address: %s", server);
63}
64
65bytevec FINGERPRINT1 = { 1 };
Ben Schwartze5595152017-10-25 14:41:02 -040066bytevec FINGERPRINT2 = { 2 };
Ben Schwartzded1b702017-10-25 14:41:02 -040067
68std::string SERVERNAME1 = "dns.example.com";
Ben Schwartze5595152017-10-25 14:41:02 -040069std::string SERVERNAME2 = "dns.example.org";
Ben Schwartzded1b702017-10-25 14:41:02 -040070
71// BaseTest just provides constants that are useful for the tests.
72class BaseTest : public ::testing::Test {
Erik Klineab999f12018-07-04 11:29:31 +090073 protected:
Ben Schwartzded1b702017-10-25 14:41:02 -040074 BaseTest() {
75 parseServer("192.0.2.1", 853, &V4ADDR1);
76 parseServer("192.0.2.2", 853, &V4ADDR2);
Ben Schwartze5595152017-10-25 14:41:02 -040077 parseServer("2001:db8::1", 853, &V6ADDR1);
78 parseServer("2001:db8::2", 853, &V6ADDR2);
Ben Schwartzded1b702017-10-25 14:41:02 -040079
80 SERVER1 = DnsTlsServer(V4ADDR1);
81 SERVER1.fingerprints.insert(FINGERPRINT1);
82 SERVER1.name = SERVERNAME1;
83 }
84
85 sockaddr_storage V4ADDR1;
86 sockaddr_storage V4ADDR2;
Ben Schwartze5595152017-10-25 14:41:02 -040087 sockaddr_storage V6ADDR1;
88 sockaddr_storage V6ADDR2;
Ben Schwartzded1b702017-10-25 14:41:02 -040089
90 DnsTlsServer SERVER1;
91};
92
93bytevec make_query(uint16_t id, size_t size) {
94 bytevec vec(size);
95 vec[0] = id >> 8;
96 vec[1] = id;
97 // Arbitrarily fill the query body with unique data.
98 for (size_t i = 2; i < size; ++i) {
99 vec[i] = id + i;
100 }
101 return vec;
102}
103
104// Query constants
105const unsigned MARK = 123;
106const uint16_t ID = 52;
107const uint16_t SIZE = 22;
108const bytevec QUERY = make_query(ID, SIZE);
109
110template <class T>
111class FakeSocketFactory : public IDnsTlsSocketFactory {
Erik Klineab999f12018-07-04 11:29:31 +0900112 public:
Ben Schwartzded1b702017-10-25 14:41:02 -0400113 FakeSocketFactory() {}
114 std::unique_ptr<IDnsTlsSocket> createDnsTlsSocket(
115 const DnsTlsServer& server ATTRIBUTE_UNUSED,
116 unsigned mark ATTRIBUTE_UNUSED,
Ben Schwartz33860762017-10-25 14:41:02 -0400117 IDnsTlsSocketObserver* observer,
Ben Schwartzded1b702017-10-25 14:41:02 -0400118 DnsTlsSessionCache* cache ATTRIBUTE_UNUSED) override {
Ben Schwartz33860762017-10-25 14:41:02 -0400119 return std::make_unique<T>(observer);
Ben Schwartzded1b702017-10-25 14:41:02 -0400120 }
121};
122
123bytevec make_echo(uint16_t id, const Slice query) {
124 bytevec response(query.size() + 2);
125 response[0] = id >> 8;
126 response[1] = id;
127 // Echo the query as the fake response.
128 memcpy(response.data() + 2, query.base(), query.size());
129 return response;
130}
131
132// Simplest possible fake server. This just echoes the query as the response.
133class FakeSocketEcho : public IDnsTlsSocket {
Erik Klineab999f12018-07-04 11:29:31 +0900134 public:
135 explicit FakeSocketEcho(IDnsTlsSocketObserver* observer) : mObserver(observer) {}
Ben Schwartz33860762017-10-25 14:41:02 -0400136 bool query(uint16_t id, const Slice query) override {
137 // Return the response immediately (asynchronously).
138 std::thread(&IDnsTlsSocketObserver::onResponse, mObserver, make_echo(id, query)).detach();
Bernie Innocenti0f167432018-05-17 22:25:54 +0900139 return true;
Ben Schwartzded1b702017-10-25 14:41:02 -0400140 }
Erik Klineab999f12018-07-04 11:29:31 +0900141
142 private:
Ben Schwartz33860762017-10-25 14:41:02 -0400143 IDnsTlsSocketObserver* const mObserver;
Ben Schwartzded1b702017-10-25 14:41:02 -0400144};
145
146class TransportTest : public BaseTest {};
147
148TEST_F(TransportTest, Query) {
149 FakeSocketFactory<FakeSocketEcho> factory;
150 DnsTlsTransport transport(SERVER1, MARK, &factory);
Ben Schwartz33860762017-10-25 14:41:02 -0400151 auto r = transport.query(makeSlice(QUERY)).get();
Ben Schwartzded1b702017-10-25 14:41:02 -0400152
153 EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
154 EXPECT_EQ(QUERY, r.response);
155}
156
Ben Schwartzaac6cac2018-07-24 12:20:56 -0400157// Fake Socket that echoes the observed query ID as the response body.
158class FakeSocketId : public IDnsTlsSocket {
159 public:
160 explicit FakeSocketId(IDnsTlsSocketObserver* observer) : mObserver(observer) {}
161 bool query(uint16_t id, const Slice query ATTRIBUTE_UNUSED) override {
162 // Return the response immediately (asynchronously).
163 bytevec response(4);
164 // Echo the ID in the header to match the response to the query.
165 // This will be overwritten by DnsTlsQueryMap.
166 response[0] = id >> 8;
167 response[1] = id;
168 // Echo the ID in the body, so that the test can verify which ID was used by
169 // DnsTlsQueryMap.
170 response[2] = id >> 8;
171 response[3] = id;
172 std::thread(&IDnsTlsSocketObserver::onResponse, mObserver, response).detach();
173 return true;
174 }
Ben Schwartzded1b702017-10-25 14:41:02 -0400175
Ben Schwartzaac6cac2018-07-24 12:20:56 -0400176 private:
177 IDnsTlsSocketObserver* const mObserver;
178};
179
180// Test that IDs are properly reused
181TEST_F(TransportTest, IdReuse) {
182 FakeSocketFactory<FakeSocketId> factory;
183 DnsTlsTransport transport(SERVER1, MARK, &factory);
184 for (int i = 0; i < 100; ++i) {
185 // Send a query.
186 std::future<DnsTlsServer::Result> f = transport.query(makeSlice(QUERY));
187 // Wait for the response.
188 DnsTlsServer::Result r = f.get();
Ben Schwartzded1b702017-10-25 14:41:02 -0400189 EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
Ben Schwartzaac6cac2018-07-24 12:20:56 -0400190
191 // All queries should have an observed ID of zero, because it is returned to the ID pool
192 // after each use.
193 EXPECT_EQ(0, (r.response[2] << 8) | r.response[3]);
Ben Schwartzded1b702017-10-25 14:41:02 -0400194 }
195}
196
Ben Schwartz33860762017-10-25 14:41:02 -0400197// These queries might be handled in serial or parallel as they race the
198// responses.
199TEST_F(TransportTest, RacingQueries_10000) {
200 FakeSocketFactory<FakeSocketEcho> factory;
201 DnsTlsTransport transport(SERVER1, MARK, &factory);
202 std::vector<std::future<DnsTlsTransport::Result>> results;
203 // Fewer than 65536 queries to avoid ID exhaustion.
Bernie Innocenti1bcc25a2018-08-10 17:15:00 +0900204 const int num_queries = 10000;
205 results.reserve(num_queries);
206 for (int i = 0; i < num_queries; ++i) {
Ben Schwartz33860762017-10-25 14:41:02 -0400207 results.push_back(transport.query(makeSlice(QUERY)));
208 }
209 for (auto& result : results) {
210 auto r = result.get();
211 EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
212 EXPECT_EQ(QUERY, r.response);
213 }
214}
215
216// A server that waits until sDelay queries are queued before responding.
217class FakeSocketDelay : public IDnsTlsSocket {
Erik Klineab999f12018-07-04 11:29:31 +0900218 public:
219 explicit FakeSocketDelay(IDnsTlsSocketObserver* observer) : mObserver(observer) {}
Bernie Innocentiabf8a342018-08-10 15:17:16 +0900220 ~FakeSocketDelay() { std::lock_guard guard(mLock); }
Ben Schwartz33860762017-10-25 14:41:02 -0400221 static size_t sDelay;
222 static bool sReverse;
223
224 bool query(uint16_t id, const Slice query) override {
Bernie Innocenti31e43e12018-09-25 15:28:12 +0900225 ALOGV("FakeSocketDelay got query with ID %d", int(id));
Bernie Innocentiabf8a342018-08-10 15:17:16 +0900226 std::lock_guard guard(mLock);
Ben Schwartz33860762017-10-25 14:41:02 -0400227 // Check for duplicate IDs.
228 EXPECT_EQ(0U, mIds.count(id));
229 mIds.insert(id);
230
231 // Store response.
232 mResponses.push_back(make_echo(id, query));
233
Bernie Innocenti31e43e12018-09-25 15:28:12 +0900234 ALOGV("Up to %zu out of %zu queries", mResponses.size(), sDelay);
Ben Schwartz33860762017-10-25 14:41:02 -0400235 if (mResponses.size() == sDelay) {
236 std::thread(&FakeSocketDelay::sendResponses, this).detach();
237 }
238 return true;
239 }
Erik Klineab999f12018-07-04 11:29:31 +0900240
241 private:
Ben Schwartz33860762017-10-25 14:41:02 -0400242 void sendResponses() {
Bernie Innocentiabf8a342018-08-10 15:17:16 +0900243 std::lock_guard guard(mLock);
Ben Schwartz33860762017-10-25 14:41:02 -0400244 if (sReverse) {
245 std::reverse(std::begin(mResponses), std::end(mResponses));
246 }
247 for (auto& response : mResponses) {
248 mObserver->onResponse(response);
249 }
250 mIds.clear();
251 mResponses.clear();
252 }
253
254 std::mutex mLock;
255 IDnsTlsSocketObserver* const mObserver;
256 std::set<uint16_t> mIds GUARDED_BY(mLock);
257 std::vector<bytevec> mResponses GUARDED_BY(mLock);
258};
259
260size_t FakeSocketDelay::sDelay;
261bool FakeSocketDelay::sReverse;
262
263TEST_F(TransportTest, ParallelColliding) {
264 FakeSocketDelay::sDelay = 10;
265 FakeSocketDelay::sReverse = false;
266 FakeSocketFactory<FakeSocketDelay> factory;
267 DnsTlsTransport transport(SERVER1, MARK, &factory);
268 std::vector<std::future<DnsTlsTransport::Result>> results;
269 // Fewer than 65536 queries to avoid ID exhaustion.
Bernie Innocenti1bcc25a2018-08-10 17:15:00 +0900270 results.reserve(FakeSocketDelay::sDelay);
Ben Schwartz33860762017-10-25 14:41:02 -0400271 for (size_t i = 0; i < FakeSocketDelay::sDelay; ++i) {
272 results.push_back(transport.query(makeSlice(QUERY)));
273 }
274 for (auto& result : results) {
275 auto r = result.get();
276 EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
277 EXPECT_EQ(QUERY, r.response);
278 }
279}
280
281TEST_F(TransportTest, ParallelColliding_Max) {
282 FakeSocketDelay::sDelay = 65536;
283 FakeSocketDelay::sReverse = false;
284 FakeSocketFactory<FakeSocketDelay> factory;
285 DnsTlsTransport transport(SERVER1, MARK, &factory);
286 std::vector<std::future<DnsTlsTransport::Result>> results;
287 // Exactly 65536 queries should still be possible in parallel,
288 // even if they all have the same original ID.
Bernie Innocenti1bcc25a2018-08-10 17:15:00 +0900289 results.reserve(FakeSocketDelay::sDelay);
Ben Schwartz33860762017-10-25 14:41:02 -0400290 for (size_t i = 0; i < FakeSocketDelay::sDelay; ++i) {
291 results.push_back(transport.query(makeSlice(QUERY)));
292 }
293 for (auto& result : results) {
294 auto r = result.get();
295 EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
296 EXPECT_EQ(QUERY, r.response);
297 }
298}
299
300TEST_F(TransportTest, ParallelUnique) {
301 FakeSocketDelay::sDelay = 10;
302 FakeSocketDelay::sReverse = false;
303 FakeSocketFactory<FakeSocketDelay> factory;
304 DnsTlsTransport transport(SERVER1, MARK, &factory);
305 std::vector<bytevec> queries(FakeSocketDelay::sDelay);
306 std::vector<std::future<DnsTlsTransport::Result>> results;
Bernie Innocenti1bcc25a2018-08-10 17:15:00 +0900307 results.reserve(FakeSocketDelay::sDelay);
Ben Schwartz33860762017-10-25 14:41:02 -0400308 for (size_t i = 0; i < FakeSocketDelay::sDelay; ++i) {
309 queries[i] = make_query(i, SIZE);
310 results.push_back(transport.query(makeSlice(queries[i])));
311 }
312 for (size_t i = 0 ; i < FakeSocketDelay::sDelay; ++i) {
313 auto r = results[i].get();
314 EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
315 EXPECT_EQ(queries[i], r.response);
316 }
317}
318
319TEST_F(TransportTest, ParallelUnique_Max) {
320 FakeSocketDelay::sDelay = 65536;
321 FakeSocketDelay::sReverse = false;
322 FakeSocketFactory<FakeSocketDelay> factory;
323 DnsTlsTransport transport(SERVER1, MARK, &factory);
324 std::vector<bytevec> queries(FakeSocketDelay::sDelay);
325 std::vector<std::future<DnsTlsTransport::Result>> results;
326 // Exactly 65536 queries should still be possible in parallel,
327 // and they should all be mapped correctly back to the original ID.
Bernie Innocenti1bcc25a2018-08-10 17:15:00 +0900328 results.reserve(FakeSocketDelay::sDelay);
Ben Schwartz33860762017-10-25 14:41:02 -0400329 for (size_t i = 0; i < FakeSocketDelay::sDelay; ++i) {
330 queries[i] = make_query(i, SIZE);
331 results.push_back(transport.query(makeSlice(queries[i])));
332 }
333 for (size_t i = 0 ; i < FakeSocketDelay::sDelay; ++i) {
334 auto r = results[i].get();
335 EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
336 EXPECT_EQ(queries[i], r.response);
337 }
338}
339
340TEST_F(TransportTest, IdExhaustion) {
Bernie Innocenti1bcc25a2018-08-10 17:15:00 +0900341 const int num_queries = 65536;
Ben Schwartz33860762017-10-25 14:41:02 -0400342 // A delay of 65537 is unreachable, because the maximum number
343 // of outstanding queries is 65536.
Bernie Innocenti1bcc25a2018-08-10 17:15:00 +0900344 FakeSocketDelay::sDelay = num_queries + 1;
Ben Schwartz33860762017-10-25 14:41:02 -0400345 FakeSocketDelay::sReverse = false;
346 FakeSocketFactory<FakeSocketDelay> factory;
347 DnsTlsTransport transport(SERVER1, MARK, &factory);
348 std::vector<std::future<DnsTlsTransport::Result>> results;
349 // Issue the maximum number of queries.
Bernie Innocenti1bcc25a2018-08-10 17:15:00 +0900350 results.reserve(num_queries);
351 for (int i = 0; i < num_queries; ++i) {
Ben Schwartz33860762017-10-25 14:41:02 -0400352 results.push_back(transport.query(makeSlice(QUERY)));
353 }
354
355 // The ID space is now full, so subsequent queries should fail immediately.
356 auto r = transport.query(makeSlice(QUERY)).get();
357 EXPECT_EQ(DnsTlsTransport::Response::internal_error, r.code);
358 EXPECT_TRUE(r.response.empty());
359
360 for (auto& result : results) {
361 // All other queries should remain outstanding.
362 EXPECT_EQ(std::future_status::timeout,
363 result.wait_for(std::chrono::duration<int>::zero()));
364 }
365}
366
367// Responses can come back from the server in any order. This should have no
368// effect on Transport's observed behavior.
369TEST_F(TransportTest, ReverseOrder) {
370 FakeSocketDelay::sDelay = 10;
371 FakeSocketDelay::sReverse = true;
372 FakeSocketFactory<FakeSocketDelay> factory;
373 DnsTlsTransport transport(SERVER1, MARK, &factory);
374 std::vector<bytevec> queries(FakeSocketDelay::sDelay);
375 std::vector<std::future<DnsTlsTransport::Result>> results;
Bernie Innocenti1bcc25a2018-08-10 17:15:00 +0900376 results.reserve(FakeSocketDelay::sDelay);
Ben Schwartz33860762017-10-25 14:41:02 -0400377 for (size_t i = 0; i < FakeSocketDelay::sDelay; ++i) {
378 queries[i] = make_query(i, SIZE);
379 results.push_back(transport.query(makeSlice(queries[i])));
380 }
381 for (size_t i = 0 ; i < FakeSocketDelay::sDelay; ++i) {
382 auto r = results[i].get();
383 EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
384 EXPECT_EQ(queries[i], r.response);
385 }
386}
387
388TEST_F(TransportTest, ReverseOrder_Max) {
389 FakeSocketDelay::sDelay = 65536;
390 FakeSocketDelay::sReverse = true;
391 FakeSocketFactory<FakeSocketDelay> factory;
392 DnsTlsTransport transport(SERVER1, MARK, &factory);
393 std::vector<bytevec> queries(FakeSocketDelay::sDelay);
394 std::vector<std::future<DnsTlsTransport::Result>> results;
Bernie Innocenti1bcc25a2018-08-10 17:15:00 +0900395 results.reserve(FakeSocketDelay::sDelay);
Ben Schwartz33860762017-10-25 14:41:02 -0400396 for (size_t i = 0; i < FakeSocketDelay::sDelay; ++i) {
397 queries[i] = make_query(i, SIZE);
398 results.push_back(transport.query(makeSlice(queries[i])));
399 }
400 for (size_t i = 0 ; i < FakeSocketDelay::sDelay; ++i) {
401 auto r = results[i].get();
402 EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
403 EXPECT_EQ(queries[i], r.response);
404 }
405}
406
Ben Schwartzded1b702017-10-25 14:41:02 -0400407// Returning null from the factory indicates a connection failure.
408class NullSocketFactory : public IDnsTlsSocketFactory {
Erik Klineab999f12018-07-04 11:29:31 +0900409 public:
Ben Schwartzded1b702017-10-25 14:41:02 -0400410 NullSocketFactory() {}
411 std::unique_ptr<IDnsTlsSocket> createDnsTlsSocket(
412 const DnsTlsServer& server ATTRIBUTE_UNUSED,
413 unsigned mark ATTRIBUTE_UNUSED,
Ben Schwartz33860762017-10-25 14:41:02 -0400414 IDnsTlsSocketObserver* observer ATTRIBUTE_UNUSED,
Ben Schwartzded1b702017-10-25 14:41:02 -0400415 DnsTlsSessionCache* cache ATTRIBUTE_UNUSED) override {
416 return nullptr;
417 }
418};
419
420TEST_F(TransportTest, ConnectFail) {
421 NullSocketFactory factory;
422 DnsTlsTransport transport(SERVER1, MARK, &factory);
Ben Schwartz33860762017-10-25 14:41:02 -0400423 auto r = transport.query(makeSlice(QUERY)).get();
Ben Schwartzded1b702017-10-25 14:41:02 -0400424
425 EXPECT_EQ(DnsTlsTransport::Response::network_error, r.code);
426 EXPECT_TRUE(r.response.empty());
427}
428
Ben Schwartz33860762017-10-25 14:41:02 -0400429// Simulate a socket that connects but then immediately receives a server
430// close notification.
431class FakeSocketClose : public IDnsTlsSocket {
Erik Klineab999f12018-07-04 11:29:31 +0900432 public:
433 explicit FakeSocketClose(IDnsTlsSocketObserver* observer)
434 : mCloser(&IDnsTlsSocketObserver::onClosed, observer) {}
Ben Schwartz33860762017-10-25 14:41:02 -0400435 ~FakeSocketClose() { mCloser.join(); }
436 bool query(uint16_t id ATTRIBUTE_UNUSED,
437 const Slice query ATTRIBUTE_UNUSED) override {
438 return true;
439 }
Erik Klineab999f12018-07-04 11:29:31 +0900440
441 private:
Ben Schwartz33860762017-10-25 14:41:02 -0400442 std::thread mCloser;
443};
444
445TEST_F(TransportTest, CloseRetryFail) {
446 FakeSocketFactory<FakeSocketClose> factory;
447 DnsTlsTransport transport(SERVER1, MARK, &factory);
448 auto r = transport.query(makeSlice(QUERY)).get();
449
450 EXPECT_EQ(DnsTlsTransport::Response::network_error, r.code);
451 EXPECT_TRUE(r.response.empty());
452}
453
454// Simulate a server that occasionally closes the connection and silently
455// drops some queries.
456class FakeSocketLimited : public IDnsTlsSocket {
Erik Klineab999f12018-07-04 11:29:31 +0900457 public:
Ben Schwartz33860762017-10-25 14:41:02 -0400458 static int sLimit; // Number of queries to answer per socket.
459 static size_t sMaxSize; // Silently discard queries greater than this size.
Erik Klineab999f12018-07-04 11:29:31 +0900460 explicit FakeSocketLimited(IDnsTlsSocketObserver* observer)
461 : mObserver(observer), mQueries(0) {}
Ben Schwartz33860762017-10-25 14:41:02 -0400462 ~FakeSocketLimited() {
463 {
Bernie Innocenti31e43e12018-09-25 15:28:12 +0900464 ALOGV("~FakeSocketLimited acquiring mLock");
Bernie Innocentiabf8a342018-08-10 15:17:16 +0900465 std::lock_guard guard(mLock);
Bernie Innocenti31e43e12018-09-25 15:28:12 +0900466 ALOGV("~FakeSocketLimited acquired mLock");
Ben Schwartz33860762017-10-25 14:41:02 -0400467 for (auto& thread : mThreads) {
Bernie Innocenti31e43e12018-09-25 15:28:12 +0900468 ALOGV("~FakeSocketLimited joining response thread");
Ben Schwartz33860762017-10-25 14:41:02 -0400469 thread.join();
Bernie Innocenti31e43e12018-09-25 15:28:12 +0900470 ALOGV("~FakeSocketLimited joined response thread");
Ben Schwartz33860762017-10-25 14:41:02 -0400471 }
472 mThreads.clear();
473 }
474
475 if (mCloser) {
Bernie Innocenti31e43e12018-09-25 15:28:12 +0900476 ALOGV("~FakeSocketLimited joining closer thread");
Ben Schwartz33860762017-10-25 14:41:02 -0400477 mCloser->join();
Bernie Innocenti31e43e12018-09-25 15:28:12 +0900478 ALOGV("~FakeSocketLimited joined closer thread");
Ben Schwartz33860762017-10-25 14:41:02 -0400479 }
480 }
481 bool query(uint16_t id, const Slice query) override {
Bernie Innocenti31e43e12018-09-25 15:28:12 +0900482 ALOGV("FakeSocketLimited::query acquiring mLock");
Bernie Innocentiabf8a342018-08-10 15:17:16 +0900483 std::lock_guard guard(mLock);
Bernie Innocenti31e43e12018-09-25 15:28:12 +0900484 ALOGV("FakeSocketLimited::query acquired mLock");
Ben Schwartz33860762017-10-25 14:41:02 -0400485 ++mQueries;
486
487 if (mQueries <= sLimit) {
Bernie Innocenti31e43e12018-09-25 15:28:12 +0900488 ALOGV("size %zu vs. limit of %zu", query.size(), sMaxSize);
Ben Schwartz33860762017-10-25 14:41:02 -0400489 if (query.size() <= sMaxSize) {
490 // Return the response immediately (asynchronously).
491 mThreads.emplace_back(&IDnsTlsSocketObserver::onResponse, mObserver, make_echo(id, query));
492 }
493 }
494 if (mQueries == sLimit) {
495 mCloser = std::make_unique<std::thread>(&FakeSocketLimited::sendClose, this);
496 }
497 return mQueries <= sLimit;
498 }
Erik Klineab999f12018-07-04 11:29:31 +0900499
500 private:
Ben Schwartz33860762017-10-25 14:41:02 -0400501 void sendClose() {
502 {
Bernie Innocenti31e43e12018-09-25 15:28:12 +0900503 ALOGV("FakeSocketLimited::sendClose acquiring mLock");
Bernie Innocentiabf8a342018-08-10 15:17:16 +0900504 std::lock_guard guard(mLock);
Bernie Innocenti31e43e12018-09-25 15:28:12 +0900505 ALOGV("FakeSocketLimited::sendClose acquired mLock");
Ben Schwartz33860762017-10-25 14:41:02 -0400506 for (auto& thread : mThreads) {
Bernie Innocenti31e43e12018-09-25 15:28:12 +0900507 ALOGV("FakeSocketLimited::sendClose joining response thread");
Ben Schwartz33860762017-10-25 14:41:02 -0400508 thread.join();
Bernie Innocenti31e43e12018-09-25 15:28:12 +0900509 ALOGV("FakeSocketLimited::sendClose joined response thread");
Ben Schwartz33860762017-10-25 14:41:02 -0400510 }
511 mThreads.clear();
512 }
513 mObserver->onClosed();
514 }
515 std::mutex mLock;
516 IDnsTlsSocketObserver* const mObserver;
517 int mQueries GUARDED_BY(mLock);
518 std::vector<std::thread> mThreads GUARDED_BY(mLock);
519 std::unique_ptr<std::thread> mCloser GUARDED_BY(mLock);
520};
521
522int FakeSocketLimited::sLimit;
523size_t FakeSocketLimited::sMaxSize;
524
525TEST_F(TransportTest, SilentDrop) {
526 FakeSocketLimited::sLimit = 10; // Close the socket after 10 queries.
527 FakeSocketLimited::sMaxSize = 0; // Silently drop all queries
528 FakeSocketFactory<FakeSocketLimited> factory;
529 DnsTlsTransport transport(SERVER1, MARK, &factory);
530
531 // Queue up 10 queries. They will all be ignored, and after the 10th,
532 // the socket will close. Transport will retry them all, until they
533 // all hit the retry limit and expire.
534 std::vector<std::future<DnsTlsTransport::Result>> results;
Bernie Innocenti1bcc25a2018-08-10 17:15:00 +0900535 results.reserve(FakeSocketLimited::sLimit);
Ben Schwartz33860762017-10-25 14:41:02 -0400536 for (int i = 0; i < FakeSocketLimited::sLimit; ++i) {
537 results.push_back(transport.query(makeSlice(QUERY)));
538 }
539 for (auto& result : results) {
540 auto r = result.get();
541 EXPECT_EQ(DnsTlsTransport::Response::network_error, r.code);
542 EXPECT_TRUE(r.response.empty());
543 }
544}
545
546TEST_F(TransportTest, PartialDrop) {
547 FakeSocketLimited::sLimit = 10; // Close the socket after 10 queries.
548 FakeSocketLimited::sMaxSize = SIZE - 2; // Silently drop "long" queries
549 FakeSocketFactory<FakeSocketLimited> factory;
550 DnsTlsTransport transport(SERVER1, MARK, &factory);
551
552 // Queue up 100 queries, alternating "short" which will be served and "long"
553 // which will be dropped.
Bernie Innocenti1bcc25a2018-08-10 17:15:00 +0900554 const int num_queries = 10 * FakeSocketLimited::sLimit;
Ben Schwartz33860762017-10-25 14:41:02 -0400555 std::vector<bytevec> queries(num_queries);
556 std::vector<std::future<DnsTlsTransport::Result>> results;
Bernie Innocenti1bcc25a2018-08-10 17:15:00 +0900557 results.reserve(num_queries);
Ben Schwartz33860762017-10-25 14:41:02 -0400558 for (int i = 0; i < num_queries; ++i) {
559 queries[i] = make_query(i, SIZE + (i % 2));
560 results.push_back(transport.query(makeSlice(queries[i])));
561 }
562 // Just check the short queries, which are at the even indices.
563 for (int i = 0; i < num_queries; i += 2) {
564 auto r = results[i].get();
565 EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
566 EXPECT_EQ(queries[i], r.response);
567 }
568}
569
570// Simulate a malfunctioning server that injects extra miscellaneous
571// responses to queries that were not asked. This will cause wrong answers but
572// must not crash the Transport.
573class FakeSocketGarbage : public IDnsTlsSocket {
Erik Klineab999f12018-07-04 11:29:31 +0900574 public:
575 explicit FakeSocketGarbage(IDnsTlsSocketObserver* observer) : mObserver(observer) {
Ben Schwartz33860762017-10-25 14:41:02 -0400576 // Inject a garbage event.
577 mThreads.emplace_back(&IDnsTlsSocketObserver::onResponse, mObserver, make_query(ID + 1, SIZE));
578 }
579 ~FakeSocketGarbage() {
Bernie Innocentiabf8a342018-08-10 15:17:16 +0900580 std::lock_guard guard(mLock);
Ben Schwartz33860762017-10-25 14:41:02 -0400581 for (auto& thread : mThreads) {
582 thread.join();
583 }
584 }
585 bool query(uint16_t id, const Slice query) override {
Bernie Innocentiabf8a342018-08-10 15:17:16 +0900586 std::lock_guard guard(mLock);
Ben Schwartz33860762017-10-25 14:41:02 -0400587 // Return the response twice.
588 auto echo = make_echo(id, query);
589 mThreads.emplace_back(&IDnsTlsSocketObserver::onResponse, mObserver, echo);
590 mThreads.emplace_back(&IDnsTlsSocketObserver::onResponse, mObserver, echo);
591 // Also return some other garbage
592 mThreads.emplace_back(&IDnsTlsSocketObserver::onResponse, mObserver, make_query(id + 1, query.size() + 2));
593 return true;
594 }
Erik Klineab999f12018-07-04 11:29:31 +0900595
596 private:
Ben Schwartz33860762017-10-25 14:41:02 -0400597 std::mutex mLock;
598 std::vector<std::thread> mThreads GUARDED_BY(mLock);
599 IDnsTlsSocketObserver* const mObserver;
600};
601
602TEST_F(TransportTest, IgnoringGarbage) {
603 FakeSocketFactory<FakeSocketGarbage> factory;
604 DnsTlsTransport transport(SERVER1, MARK, &factory);
605 for (int i = 0; i < 10; ++i) {
606 auto r = transport.query(makeSlice(QUERY)).get();
607
608 EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
609 // Don't check the response because this server is malfunctioning.
610 }
611}
612
Ben Schwartzded1b702017-10-25 14:41:02 -0400613// Dispatcher tests
614class DispatcherTest : public BaseTest {};
615
616TEST_F(DispatcherTest, Query) {
617 bytevec ans(4096);
618 int resplen = 0;
619
620 auto factory = std::make_unique<FakeSocketFactory<FakeSocketEcho>>();
621 DnsTlsDispatcher dispatcher(std::move(factory));
622 auto r = dispatcher.query(SERVER1, MARK, makeSlice(QUERY),
623 makeSlice(ans), &resplen);
624
625 EXPECT_EQ(DnsTlsTransport::Response::success, r);
626 EXPECT_EQ(int(QUERY.size()), resplen);
627 ans.resize(resplen);
628 EXPECT_EQ(QUERY, ans);
629}
630
631TEST_F(DispatcherTest, AnswerTooLarge) {
632 bytevec ans(SIZE - 1); // Too small to hold the answer
633 int resplen = 0;
634
635 auto factory = std::make_unique<FakeSocketFactory<FakeSocketEcho>>();
636 DnsTlsDispatcher dispatcher(std::move(factory));
637 auto r = dispatcher.query(SERVER1, MARK, makeSlice(QUERY),
638 makeSlice(ans), &resplen);
639
640 EXPECT_EQ(DnsTlsTransport::Response::limit_error, r);
641}
642
643template<class T>
644class TrackingFakeSocketFactory : public IDnsTlsSocketFactory {
Erik Klineab999f12018-07-04 11:29:31 +0900645 public:
Ben Schwartzded1b702017-10-25 14:41:02 -0400646 TrackingFakeSocketFactory() {}
647 std::unique_ptr<IDnsTlsSocket> createDnsTlsSocket(
648 const DnsTlsServer& server,
649 unsigned mark,
Ben Schwartz33860762017-10-25 14:41:02 -0400650 IDnsTlsSocketObserver* observer,
Ben Schwartzded1b702017-10-25 14:41:02 -0400651 DnsTlsSessionCache* cache ATTRIBUTE_UNUSED) override {
Bernie Innocentiabf8a342018-08-10 15:17:16 +0900652 std::lock_guard guard(mLock);
Ben Schwartzded1b702017-10-25 14:41:02 -0400653 keys.emplace(mark, server);
Ben Schwartz33860762017-10-25 14:41:02 -0400654 return std::make_unique<T>(observer);
Ben Schwartzded1b702017-10-25 14:41:02 -0400655 }
656 std::multiset<std::pair<unsigned, DnsTlsServer>> keys;
Erik Klineab999f12018-07-04 11:29:31 +0900657
658 private:
Ben Schwartzded1b702017-10-25 14:41:02 -0400659 std::mutex mLock;
660};
661
662TEST_F(DispatcherTest, Dispatching) {
Ben Schwartz33860762017-10-25 14:41:02 -0400663 FakeSocketDelay::sDelay = 5;
664 FakeSocketDelay::sReverse = true;
665 auto factory = std::make_unique<TrackingFakeSocketFactory<FakeSocketDelay>>();
Ben Schwartzded1b702017-10-25 14:41:02 -0400666 auto* weak_factory = factory.get(); // Valid as long as dispatcher is in scope.
667 DnsTlsDispatcher dispatcher(std::move(factory));
668
669 // Populate a vector of two servers and two socket marks, four combinations
670 // in total.
671 std::vector<std::pair<unsigned, DnsTlsServer>> keys;
672 keys.emplace_back(MARK, SERVER1);
673 keys.emplace_back(MARK + 1, SERVER1);
674 keys.emplace_back(MARK, V4ADDR2);
675 keys.emplace_back(MARK + 1, V4ADDR2);
676
Ben Schwartz33860762017-10-25 14:41:02 -0400677 // Do several queries on each server. They should all succeed.
Ben Schwartzded1b702017-10-25 14:41:02 -0400678 std::vector<std::thread> threads;
Ben Schwartz33860762017-10-25 14:41:02 -0400679 for (size_t i = 0; i < FakeSocketDelay::sDelay * keys.size(); ++i) {
Ben Schwartzded1b702017-10-25 14:41:02 -0400680 auto key = keys[i % keys.size()];
681 threads.emplace_back([key, i] (DnsTlsDispatcher* dispatcher) {
682 auto q = make_query(i, SIZE);
683 bytevec ans(4096);
684 int resplen = 0;
685 unsigned mark = key.first;
686 const DnsTlsServer& server = key.second;
687 auto r = dispatcher->query(server, mark, makeSlice(q),
688 makeSlice(ans), &resplen);
689 EXPECT_EQ(DnsTlsTransport::Response::success, r);
690 EXPECT_EQ(int(q.size()), resplen);
691 ans.resize(resplen);
692 EXPECT_EQ(q, ans);
693 }, &dispatcher);
694 }
695 for (auto& thread : threads) {
696 thread.join();
697 }
698 // We expect that the factory created one socket for each key.
699 EXPECT_EQ(keys.size(), weak_factory->keys.size());
700 for (auto& key : keys) {
701 EXPECT_EQ(1U, weak_factory->keys.count(key));
702 }
703}
704
Ben Schwartze5595152017-10-25 14:41:02 -0400705// Check DnsTlsServer's comparison logic.
706AddressComparator ADDRESS_COMPARATOR;
707bool isAddressEqual(const DnsTlsServer& s1, const DnsTlsServer& s2) {
708 bool cmp1 = ADDRESS_COMPARATOR(s1, s2);
709 bool cmp2 = ADDRESS_COMPARATOR(s2, s1);
710 EXPECT_FALSE(cmp1 && cmp2);
711 return !cmp1 && !cmp2;
712}
713
714void checkUnequal(const DnsTlsServer& s1, const DnsTlsServer& s2) {
715 EXPECT_TRUE(s1 == s1);
716 EXPECT_TRUE(s2 == s2);
717 EXPECT_TRUE(isAddressEqual(s1, s1));
718 EXPECT_TRUE(isAddressEqual(s2, s2));
719
720 EXPECT_TRUE(s1 < s2 ^ s2 < s1);
721 EXPECT_FALSE(s1 == s2);
722 EXPECT_FALSE(s2 == s1);
723}
724
725class ServerTest : public BaseTest {};
726
727TEST_F(ServerTest, IPv4) {
728 checkUnequal(V4ADDR1, V4ADDR2);
729 EXPECT_FALSE(isAddressEqual(V4ADDR1, V4ADDR2));
730}
731
732TEST_F(ServerTest, IPv6) {
733 checkUnequal(V6ADDR1, V6ADDR2);
734 EXPECT_FALSE(isAddressEqual(V6ADDR1, V6ADDR2));
735}
736
737TEST_F(ServerTest, MixedAddressFamily) {
738 checkUnequal(V6ADDR1, V4ADDR1);
739 EXPECT_FALSE(isAddressEqual(V6ADDR1, V4ADDR1));
740}
741
742TEST_F(ServerTest, IPv6ScopeId) {
743 DnsTlsServer s1(V6ADDR1), s2(V6ADDR1);
744 sockaddr_in6* addr1 = reinterpret_cast<sockaddr_in6*>(&s1.ss);
745 addr1->sin6_scope_id = 1;
746 sockaddr_in6* addr2 = reinterpret_cast<sockaddr_in6*>(&s2.ss);
747 addr2->sin6_scope_id = 2;
748 checkUnequal(s1, s2);
749 EXPECT_FALSE(isAddressEqual(s1, s2));
Erik Kline1564d482018-03-07 17:09:35 +0900750
751 EXPECT_FALSE(s1.wasExplicitlyConfigured());
752 EXPECT_FALSE(s2.wasExplicitlyConfigured());
Ben Schwartze5595152017-10-25 14:41:02 -0400753}
754
755TEST_F(ServerTest, IPv6FlowInfo) {
756 DnsTlsServer s1(V6ADDR1), s2(V6ADDR1);
757 sockaddr_in6* addr1 = reinterpret_cast<sockaddr_in6*>(&s1.ss);
758 addr1->sin6_flowinfo = 1;
759 sockaddr_in6* addr2 = reinterpret_cast<sockaddr_in6*>(&s2.ss);
760 addr2->sin6_flowinfo = 2;
761 // All comparisons ignore flowinfo.
762 EXPECT_EQ(s1, s2);
763 EXPECT_TRUE(isAddressEqual(s1, s2));
Erik Kline1564d482018-03-07 17:09:35 +0900764
765 EXPECT_FALSE(s1.wasExplicitlyConfigured());
766 EXPECT_FALSE(s2.wasExplicitlyConfigured());
Ben Schwartze5595152017-10-25 14:41:02 -0400767}
768
769TEST_F(ServerTest, Port) {
770 DnsTlsServer s1, s2;
771 parseServer("192.0.2.1", 853, &s1.ss);
772 parseServer("192.0.2.1", 854, &s2.ss);
773 checkUnequal(s1, s2);
774 EXPECT_TRUE(isAddressEqual(s1, s2));
775
776 DnsTlsServer s3, s4;
777 parseServer("2001:db8::1", 853, &s3.ss);
778 parseServer("2001:db8::1", 852, &s4.ss);
779 checkUnequal(s3, s4);
780 EXPECT_TRUE(isAddressEqual(s3, s4));
Erik Kline1564d482018-03-07 17:09:35 +0900781
782 EXPECT_FALSE(s1.wasExplicitlyConfigured());
783 EXPECT_FALSE(s2.wasExplicitlyConfigured());
Ben Schwartze5595152017-10-25 14:41:02 -0400784}
785
786TEST_F(ServerTest, Name) {
787 DnsTlsServer s1(V4ADDR1), s2(V4ADDR1);
788 s1.name = SERVERNAME1;
789 checkUnequal(s1, s2);
790 s2.name = SERVERNAME2;
791 checkUnequal(s1, s2);
792 EXPECT_TRUE(isAddressEqual(s1, s2));
Erik Kline1564d482018-03-07 17:09:35 +0900793
794 EXPECT_TRUE(s1.wasExplicitlyConfigured());
795 EXPECT_TRUE(s2.wasExplicitlyConfigured());
Ben Schwartze5595152017-10-25 14:41:02 -0400796}
797
798TEST_F(ServerTest, Fingerprint) {
799 DnsTlsServer s1(V4ADDR1), s2(V4ADDR1);
800
801 s1.fingerprints.insert(FINGERPRINT1);
802 checkUnequal(s1, s2);
803 EXPECT_TRUE(isAddressEqual(s1, s2));
804
805 s2.fingerprints.insert(FINGERPRINT2);
806 checkUnequal(s1, s2);
807 EXPECT_TRUE(isAddressEqual(s1, s2));
808
809 s2.fingerprints.insert(FINGERPRINT1);
810 checkUnequal(s1, s2);
811 EXPECT_TRUE(isAddressEqual(s1, s2));
812
813 s1.fingerprints.insert(FINGERPRINT2);
814 EXPECT_EQ(s1, s2);
815 EXPECT_TRUE(isAddressEqual(s1, s2));
Erik Kline1564d482018-03-07 17:09:35 +0900816
817 EXPECT_TRUE(s1.wasExplicitlyConfigured());
818 EXPECT_TRUE(s2.wasExplicitlyConfigured());
Ben Schwartze5595152017-10-25 14:41:02 -0400819}
820
Ben Schwartz33860762017-10-25 14:41:02 -0400821TEST(QueryMapTest, Basic) {
822 DnsTlsQueryMap map;
823
824 EXPECT_TRUE(map.empty());
825
826 bytevec q0 = make_query(999, SIZE);
827 bytevec q1 = make_query(888, SIZE);
828 bytevec q2 = make_query(777, SIZE);
829
830 auto f0 = map.recordQuery(makeSlice(q0));
831 auto f1 = map.recordQuery(makeSlice(q1));
832 auto f2 = map.recordQuery(makeSlice(q2));
833
834 // Check return values of recordQuery
835 EXPECT_EQ(0, f0->query.newId);
836 EXPECT_EQ(1, f1->query.newId);
837 EXPECT_EQ(2, f2->query.newId);
838
839 // Check side effects of recordQuery
840 EXPECT_FALSE(map.empty());
841
842 auto all = map.getAll();
843 EXPECT_EQ(3U, all.size());
844
845 EXPECT_EQ(0, all[0].newId);
846 EXPECT_EQ(1, all[1].newId);
847 EXPECT_EQ(2, all[2].newId);
848
849 EXPECT_EQ(makeSlice(q0), all[0].query);
850 EXPECT_EQ(makeSlice(q1), all[1].query);
851 EXPECT_EQ(makeSlice(q2), all[2].query);
852
853 bytevec a0 = make_query(0, SIZE);
854 bytevec a1 = make_query(1, SIZE);
855 bytevec a2 = make_query(2, SIZE);
856
857 // Return responses out of order
858 map.onResponse(a2);
859 map.onResponse(a0);
860 map.onResponse(a1);
861
862 EXPECT_TRUE(map.empty());
863
864 auto r0 = f0->result.get();
865 auto r1 = f1->result.get();
866 auto r2 = f2->result.get();
867
868 EXPECT_EQ(DnsTlsQueryMap::Response::success, r0.code);
869 EXPECT_EQ(DnsTlsQueryMap::Response::success, r1.code);
870 EXPECT_EQ(DnsTlsQueryMap::Response::success, r2.code);
871
872 const bytevec& d0 = r0.response;
873 const bytevec& d1 = r1.response;
874 const bytevec& d2 = r2.response;
875
876 // The ID should match the query
877 EXPECT_EQ(999, d0[0] << 8 | d0[1]);
878 EXPECT_EQ(888, d1[0] << 8 | d1[1]);
879 EXPECT_EQ(777, d2[0] << 8 | d2[1]);
880 // The body should match the answer
881 EXPECT_EQ(bytevec(a0.begin() + 2, a0.end()), bytevec(d0.begin() + 2, d0.end()));
882 EXPECT_EQ(bytevec(a1.begin() + 2, a1.end()), bytevec(d1.begin() + 2, d1.end()));
883 EXPECT_EQ(bytevec(a2.begin() + 2, a2.end()), bytevec(d2.begin() + 2, d2.end()));
884}
885
886TEST(QueryMapTest, FillHole) {
887 DnsTlsQueryMap map;
888 std::vector<std::unique_ptr<DnsTlsQueryMap::QueryFuture>> futures(UINT16_MAX + 1);
889 for (uint32_t i = 0; i <= UINT16_MAX; ++i) {
890 futures[i] = map.recordQuery(makeSlice(QUERY));
891 ASSERT_TRUE(futures[i]); // answers[i] should be nonnull.
892 EXPECT_EQ(i, futures[i]->query.newId);
893 }
894
895 // The map should now be full.
896 EXPECT_EQ(size_t(UINT16_MAX + 1), map.getAll().size());
897
898 // Trying to add another query should fail because the map is full.
899 EXPECT_FALSE(map.recordQuery(makeSlice(QUERY)));
900
901 // Send an answer to query 40000
902 auto answer = make_query(40000, SIZE);
903 map.onResponse(answer);
904 auto result = futures[40000]->result.get();
905 EXPECT_EQ(DnsTlsQueryMap::Response::success, result.code);
906 EXPECT_EQ(ID, result.response[0] << 8 | result.response[1]);
907 EXPECT_EQ(bytevec(answer.begin() + 2, answer.end()),
908 bytevec(result.response.begin() + 2, result.response.end()));
909
910 // There should now be room in the map.
911 EXPECT_EQ(size_t(UINT16_MAX), map.getAll().size());
912 auto f = map.recordQuery(makeSlice(QUERY));
913 ASSERT_TRUE(f);
914 EXPECT_EQ(40000, f->query.newId);
915
916 // The map should now be full again.
917 EXPECT_EQ(size_t(UINT16_MAX + 1), map.getAll().size());
918 EXPECT_FALSE(map.recordQuery(makeSlice(QUERY)));
919}
920
Ben Schwartzded1b702017-10-25 14:41:02 -0400921} // end of namespace net
922} // end of namespace android