blob: f8070bd6b84d7ad9943e8c32e812d0fa8b12eec9 [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"
18
19#include <gtest/gtest.h>
20
21#include "dns/DnsTlsDispatcher.h"
Ben Schwartz33860762017-10-25 14:41:02 -040022#include "dns/DnsTlsQueryMap.h"
Ben Schwartzded1b702017-10-25 14:41:02 -040023#include "dns/DnsTlsServer.h"
24#include "dns/DnsTlsSessionCache.h"
25#include "dns/DnsTlsSocket.h"
26#include "dns/DnsTlsTransport.h"
27#include "dns/IDnsTlsSocket.h"
28#include "dns/IDnsTlsSocketFactory.h"
Ben Schwartz33860762017-10-25 14:41:02 -040029#include "dns/IDnsTlsSocketObserver.h"
Ben Schwartzded1b702017-10-25 14:41:02 -040030
31#include <chrono>
32#include <arpa/inet.h>
33#include <android-base/macros.h>
34#include <netdutils/Slice.h>
35
36#include "log/log.h"
37
38namespace android {
39namespace net {
40
41using netdutils::Slice;
42using netdutils::makeSlice;
43
44typedef std::vector<uint8_t> bytevec;
45
46static void parseServer(const char* server, in_port_t port, sockaddr_storage* parsed) {
47 sockaddr_in* sin = reinterpret_cast<sockaddr_in*>(parsed);
48 if (inet_pton(AF_INET, server, &(sin->sin_addr)) == 1) {
49 // IPv4 parse succeeded, so it's IPv4
50 sin->sin_family = AF_INET;
51 sin->sin_port = htons(port);
52 return;
53 }
54 sockaddr_in6* sin6 = reinterpret_cast<sockaddr_in6*>(parsed);
55 if (inet_pton(AF_INET6, server, &(sin6->sin6_addr)) == 1){
56 // IPv6 parse succeeded, so it's IPv6.
57 sin6->sin6_family = AF_INET6;
58 sin6->sin6_port = htons(port);
59 return;
60 }
61 ALOGE("Failed to parse server address: %s", server);
62}
63
64bytevec FINGERPRINT1 = { 1 };
Ben Schwartze5595152017-10-25 14:41:02 -040065bytevec FINGERPRINT2 = { 2 };
Ben Schwartzded1b702017-10-25 14:41:02 -040066
67std::string SERVERNAME1 = "dns.example.com";
Ben Schwartze5595152017-10-25 14:41:02 -040068std::string SERVERNAME2 = "dns.example.org";
Ben Schwartzded1b702017-10-25 14:41:02 -040069
70// BaseTest just provides constants that are useful for the tests.
71class BaseTest : public ::testing::Test {
Erik Klineab999f12018-07-04 11:29:31 +090072 protected:
Ben Schwartzded1b702017-10-25 14:41:02 -040073 BaseTest() {
74 parseServer("192.0.2.1", 853, &V4ADDR1);
75 parseServer("192.0.2.2", 853, &V4ADDR2);
Ben Schwartze5595152017-10-25 14:41:02 -040076 parseServer("2001:db8::1", 853, &V6ADDR1);
77 parseServer("2001:db8::2", 853, &V6ADDR2);
Ben Schwartzded1b702017-10-25 14:41:02 -040078
79 SERVER1 = DnsTlsServer(V4ADDR1);
80 SERVER1.fingerprints.insert(FINGERPRINT1);
81 SERVER1.name = SERVERNAME1;
82 }
83
84 sockaddr_storage V4ADDR1;
85 sockaddr_storage V4ADDR2;
Ben Schwartze5595152017-10-25 14:41:02 -040086 sockaddr_storage V6ADDR1;
87 sockaddr_storage V6ADDR2;
Ben Schwartzded1b702017-10-25 14:41:02 -040088
89 DnsTlsServer SERVER1;
90};
91
92bytevec make_query(uint16_t id, size_t size) {
93 bytevec vec(size);
94 vec[0] = id >> 8;
95 vec[1] = id;
96 // Arbitrarily fill the query body with unique data.
97 for (size_t i = 2; i < size; ++i) {
98 vec[i] = id + i;
99 }
100 return vec;
101}
102
103// Query constants
104const unsigned MARK = 123;
105const uint16_t ID = 52;
106const uint16_t SIZE = 22;
107const bytevec QUERY = make_query(ID, SIZE);
108
109template <class T>
110class FakeSocketFactory : public IDnsTlsSocketFactory {
Erik Klineab999f12018-07-04 11:29:31 +0900111 public:
Ben Schwartzded1b702017-10-25 14:41:02 -0400112 FakeSocketFactory() {}
113 std::unique_ptr<IDnsTlsSocket> createDnsTlsSocket(
114 const DnsTlsServer& server ATTRIBUTE_UNUSED,
115 unsigned mark ATTRIBUTE_UNUSED,
Ben Schwartz33860762017-10-25 14:41:02 -0400116 IDnsTlsSocketObserver* observer,
Ben Schwartzded1b702017-10-25 14:41:02 -0400117 DnsTlsSessionCache* cache ATTRIBUTE_UNUSED) override {
Ben Schwartz33860762017-10-25 14:41:02 -0400118 return std::make_unique<T>(observer);
Ben Schwartzded1b702017-10-25 14:41:02 -0400119 }
120};
121
122bytevec make_echo(uint16_t id, const Slice query) {
123 bytevec response(query.size() + 2);
124 response[0] = id >> 8;
125 response[1] = id;
126 // Echo the query as the fake response.
127 memcpy(response.data() + 2, query.base(), query.size());
128 return response;
129}
130
131// Simplest possible fake server. This just echoes the query as the response.
132class FakeSocketEcho : public IDnsTlsSocket {
Erik Klineab999f12018-07-04 11:29:31 +0900133 public:
134 explicit FakeSocketEcho(IDnsTlsSocketObserver* observer) : mObserver(observer) {}
Ben Schwartz33860762017-10-25 14:41:02 -0400135 bool query(uint16_t id, const Slice query) override {
136 // Return the response immediately (asynchronously).
137 std::thread(&IDnsTlsSocketObserver::onResponse, mObserver, make_echo(id, query)).detach();
Bernie Innocenti0f167432018-05-17 22:25:54 +0900138 return true;
Ben Schwartzded1b702017-10-25 14:41:02 -0400139 }
Erik Klineab999f12018-07-04 11:29:31 +0900140
141 private:
Ben Schwartz33860762017-10-25 14:41:02 -0400142 IDnsTlsSocketObserver* const mObserver;
Ben Schwartzded1b702017-10-25 14:41:02 -0400143};
144
145class TransportTest : public BaseTest {};
146
147TEST_F(TransportTest, Query) {
148 FakeSocketFactory<FakeSocketEcho> factory;
149 DnsTlsTransport transport(SERVER1, MARK, &factory);
Ben Schwartz33860762017-10-25 14:41:02 -0400150 auto r = transport.query(makeSlice(QUERY)).get();
Ben Schwartzded1b702017-10-25 14:41:02 -0400151
152 EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
153 EXPECT_EQ(QUERY, r.response);
154}
155
Ben Schwartz33860762017-10-25 14:41:02 -0400156TEST_F(TransportTest, SerialQueries_100000) {
Ben Schwartzded1b702017-10-25 14:41:02 -0400157 FakeSocketFactory<FakeSocketEcho> factory;
158 DnsTlsTransport transport(SERVER1, MARK, &factory);
159 // Send more than 65536 queries serially.
160 for (int i = 0; i < 100000; ++i) {
Ben Schwartz33860762017-10-25 14:41:02 -0400161 auto r = transport.query(makeSlice(QUERY)).get();
Ben Schwartzded1b702017-10-25 14:41:02 -0400162
163 EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
164 EXPECT_EQ(QUERY, r.response);
165 }
166}
167
Ben Schwartz33860762017-10-25 14:41:02 -0400168// These queries might be handled in serial or parallel as they race the
169// responses.
170TEST_F(TransportTest, RacingQueries_10000) {
171 FakeSocketFactory<FakeSocketEcho> factory;
172 DnsTlsTransport transport(SERVER1, MARK, &factory);
173 std::vector<std::future<DnsTlsTransport::Result>> results;
174 // Fewer than 65536 queries to avoid ID exhaustion.
Bernie Innocenti1bcc25a2018-08-10 17:15:00 +0900175 const int num_queries = 10000;
176 results.reserve(num_queries);
177 for (int i = 0; i < num_queries; ++i) {
Ben Schwartz33860762017-10-25 14:41:02 -0400178 results.push_back(transport.query(makeSlice(QUERY)));
179 }
180 for (auto& result : results) {
181 auto r = result.get();
182 EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
183 EXPECT_EQ(QUERY, r.response);
184 }
185}
186
187// A server that waits until sDelay queries are queued before responding.
188class FakeSocketDelay : public IDnsTlsSocket {
Erik Klineab999f12018-07-04 11:29:31 +0900189 public:
190 explicit FakeSocketDelay(IDnsTlsSocketObserver* observer) : mObserver(observer) {}
Bernie Innocentiabf8a342018-08-10 15:17:16 +0900191 ~FakeSocketDelay() { std::lock_guard guard(mLock); }
Ben Schwartz33860762017-10-25 14:41:02 -0400192 static size_t sDelay;
193 static bool sReverse;
194
195 bool query(uint16_t id, const Slice query) override {
196 ALOGD("FakeSocketDelay got query with ID %d", int(id));
Bernie Innocentiabf8a342018-08-10 15:17:16 +0900197 std::lock_guard guard(mLock);
Ben Schwartz33860762017-10-25 14:41:02 -0400198 // Check for duplicate IDs.
199 EXPECT_EQ(0U, mIds.count(id));
200 mIds.insert(id);
201
202 // Store response.
203 mResponses.push_back(make_echo(id, query));
204
205 ALOGD("Up to %zu out of %zu queries", mResponses.size(), sDelay);
206 if (mResponses.size() == sDelay) {
207 std::thread(&FakeSocketDelay::sendResponses, this).detach();
208 }
209 return true;
210 }
Erik Klineab999f12018-07-04 11:29:31 +0900211
212 private:
Ben Schwartz33860762017-10-25 14:41:02 -0400213 void sendResponses() {
Bernie Innocentiabf8a342018-08-10 15:17:16 +0900214 std::lock_guard guard(mLock);
Ben Schwartz33860762017-10-25 14:41:02 -0400215 if (sReverse) {
216 std::reverse(std::begin(mResponses), std::end(mResponses));
217 }
218 for (auto& response : mResponses) {
219 mObserver->onResponse(response);
220 }
221 mIds.clear();
222 mResponses.clear();
223 }
224
225 std::mutex mLock;
226 IDnsTlsSocketObserver* const mObserver;
227 std::set<uint16_t> mIds GUARDED_BY(mLock);
228 std::vector<bytevec> mResponses GUARDED_BY(mLock);
229};
230
231size_t FakeSocketDelay::sDelay;
232bool FakeSocketDelay::sReverse;
233
234TEST_F(TransportTest, ParallelColliding) {
235 FakeSocketDelay::sDelay = 10;
236 FakeSocketDelay::sReverse = false;
237 FakeSocketFactory<FakeSocketDelay> factory;
238 DnsTlsTransport transport(SERVER1, MARK, &factory);
239 std::vector<std::future<DnsTlsTransport::Result>> results;
240 // Fewer than 65536 queries to avoid ID exhaustion.
Bernie Innocenti1bcc25a2018-08-10 17:15:00 +0900241 results.reserve(FakeSocketDelay::sDelay);
Ben Schwartz33860762017-10-25 14:41:02 -0400242 for (size_t i = 0; i < FakeSocketDelay::sDelay; ++i) {
243 results.push_back(transport.query(makeSlice(QUERY)));
244 }
245 for (auto& result : results) {
246 auto r = result.get();
247 EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
248 EXPECT_EQ(QUERY, r.response);
249 }
250}
251
252TEST_F(TransportTest, ParallelColliding_Max) {
253 FakeSocketDelay::sDelay = 65536;
254 FakeSocketDelay::sReverse = false;
255 FakeSocketFactory<FakeSocketDelay> factory;
256 DnsTlsTransport transport(SERVER1, MARK, &factory);
257 std::vector<std::future<DnsTlsTransport::Result>> results;
258 // Exactly 65536 queries should still be possible in parallel,
259 // even if they all have the same original ID.
Bernie Innocenti1bcc25a2018-08-10 17:15:00 +0900260 results.reserve(FakeSocketDelay::sDelay);
Ben Schwartz33860762017-10-25 14:41:02 -0400261 for (size_t i = 0; i < FakeSocketDelay::sDelay; ++i) {
262 results.push_back(transport.query(makeSlice(QUERY)));
263 }
264 for (auto& result : results) {
265 auto r = result.get();
266 EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
267 EXPECT_EQ(QUERY, r.response);
268 }
269}
270
271TEST_F(TransportTest, ParallelUnique) {
272 FakeSocketDelay::sDelay = 10;
273 FakeSocketDelay::sReverse = false;
274 FakeSocketFactory<FakeSocketDelay> factory;
275 DnsTlsTransport transport(SERVER1, MARK, &factory);
276 std::vector<bytevec> queries(FakeSocketDelay::sDelay);
277 std::vector<std::future<DnsTlsTransport::Result>> results;
Bernie Innocenti1bcc25a2018-08-10 17:15:00 +0900278 results.reserve(FakeSocketDelay::sDelay);
Ben Schwartz33860762017-10-25 14:41:02 -0400279 for (size_t i = 0; i < FakeSocketDelay::sDelay; ++i) {
280 queries[i] = make_query(i, SIZE);
281 results.push_back(transport.query(makeSlice(queries[i])));
282 }
283 for (size_t i = 0 ; i < FakeSocketDelay::sDelay; ++i) {
284 auto r = results[i].get();
285 EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
286 EXPECT_EQ(queries[i], r.response);
287 }
288}
289
290TEST_F(TransportTest, ParallelUnique_Max) {
291 FakeSocketDelay::sDelay = 65536;
292 FakeSocketDelay::sReverse = false;
293 FakeSocketFactory<FakeSocketDelay> factory;
294 DnsTlsTransport transport(SERVER1, MARK, &factory);
295 std::vector<bytevec> queries(FakeSocketDelay::sDelay);
296 std::vector<std::future<DnsTlsTransport::Result>> results;
297 // Exactly 65536 queries should still be possible in parallel,
298 // and they should all be mapped correctly back to the original ID.
Bernie Innocenti1bcc25a2018-08-10 17:15:00 +0900299 results.reserve(FakeSocketDelay::sDelay);
Ben Schwartz33860762017-10-25 14:41:02 -0400300 for (size_t i = 0; i < FakeSocketDelay::sDelay; ++i) {
301 queries[i] = make_query(i, SIZE);
302 results.push_back(transport.query(makeSlice(queries[i])));
303 }
304 for (size_t i = 0 ; i < FakeSocketDelay::sDelay; ++i) {
305 auto r = results[i].get();
306 EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
307 EXPECT_EQ(queries[i], r.response);
308 }
309}
310
311TEST_F(TransportTest, IdExhaustion) {
Bernie Innocenti1bcc25a2018-08-10 17:15:00 +0900312 const int num_queries = 65536;
Ben Schwartz33860762017-10-25 14:41:02 -0400313 // A delay of 65537 is unreachable, because the maximum number
314 // of outstanding queries is 65536.
Bernie Innocenti1bcc25a2018-08-10 17:15:00 +0900315 FakeSocketDelay::sDelay = num_queries + 1;
Ben Schwartz33860762017-10-25 14:41:02 -0400316 FakeSocketDelay::sReverse = false;
317 FakeSocketFactory<FakeSocketDelay> factory;
318 DnsTlsTransport transport(SERVER1, MARK, &factory);
319 std::vector<std::future<DnsTlsTransport::Result>> results;
320 // Issue the maximum number of queries.
Bernie Innocenti1bcc25a2018-08-10 17:15:00 +0900321 results.reserve(num_queries);
322 for (int i = 0; i < num_queries; ++i) {
Ben Schwartz33860762017-10-25 14:41:02 -0400323 results.push_back(transport.query(makeSlice(QUERY)));
324 }
325
326 // The ID space is now full, so subsequent queries should fail immediately.
327 auto r = transport.query(makeSlice(QUERY)).get();
328 EXPECT_EQ(DnsTlsTransport::Response::internal_error, r.code);
329 EXPECT_TRUE(r.response.empty());
330
331 for (auto& result : results) {
332 // All other queries should remain outstanding.
333 EXPECT_EQ(std::future_status::timeout,
334 result.wait_for(std::chrono::duration<int>::zero()));
335 }
336}
337
338// Responses can come back from the server in any order. This should have no
339// effect on Transport's observed behavior.
340TEST_F(TransportTest, ReverseOrder) {
341 FakeSocketDelay::sDelay = 10;
342 FakeSocketDelay::sReverse = true;
343 FakeSocketFactory<FakeSocketDelay> factory;
344 DnsTlsTransport transport(SERVER1, MARK, &factory);
345 std::vector<bytevec> queries(FakeSocketDelay::sDelay);
346 std::vector<std::future<DnsTlsTransport::Result>> results;
Bernie Innocenti1bcc25a2018-08-10 17:15:00 +0900347 results.reserve(FakeSocketDelay::sDelay);
Ben Schwartz33860762017-10-25 14:41:02 -0400348 for (size_t i = 0; i < FakeSocketDelay::sDelay; ++i) {
349 queries[i] = make_query(i, SIZE);
350 results.push_back(transport.query(makeSlice(queries[i])));
351 }
352 for (size_t i = 0 ; i < FakeSocketDelay::sDelay; ++i) {
353 auto r = results[i].get();
354 EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
355 EXPECT_EQ(queries[i], r.response);
356 }
357}
358
359TEST_F(TransportTest, ReverseOrder_Max) {
360 FakeSocketDelay::sDelay = 65536;
361 FakeSocketDelay::sReverse = true;
362 FakeSocketFactory<FakeSocketDelay> factory;
363 DnsTlsTransport transport(SERVER1, MARK, &factory);
364 std::vector<bytevec> queries(FakeSocketDelay::sDelay);
365 std::vector<std::future<DnsTlsTransport::Result>> results;
Bernie Innocenti1bcc25a2018-08-10 17:15:00 +0900366 results.reserve(FakeSocketDelay::sDelay);
Ben Schwartz33860762017-10-25 14:41:02 -0400367 for (size_t i = 0; i < FakeSocketDelay::sDelay; ++i) {
368 queries[i] = make_query(i, SIZE);
369 results.push_back(transport.query(makeSlice(queries[i])));
370 }
371 for (size_t i = 0 ; i < FakeSocketDelay::sDelay; ++i) {
372 auto r = results[i].get();
373 EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
374 EXPECT_EQ(queries[i], r.response);
375 }
376}
377
Ben Schwartzded1b702017-10-25 14:41:02 -0400378// Returning null from the factory indicates a connection failure.
379class NullSocketFactory : public IDnsTlsSocketFactory {
Erik Klineab999f12018-07-04 11:29:31 +0900380 public:
Ben Schwartzded1b702017-10-25 14:41:02 -0400381 NullSocketFactory() {}
382 std::unique_ptr<IDnsTlsSocket> createDnsTlsSocket(
383 const DnsTlsServer& server ATTRIBUTE_UNUSED,
384 unsigned mark ATTRIBUTE_UNUSED,
Ben Schwartz33860762017-10-25 14:41:02 -0400385 IDnsTlsSocketObserver* observer ATTRIBUTE_UNUSED,
Ben Schwartzded1b702017-10-25 14:41:02 -0400386 DnsTlsSessionCache* cache ATTRIBUTE_UNUSED) override {
387 return nullptr;
388 }
389};
390
391TEST_F(TransportTest, ConnectFail) {
392 NullSocketFactory factory;
393 DnsTlsTransport transport(SERVER1, MARK, &factory);
Ben Schwartz33860762017-10-25 14:41:02 -0400394 auto r = transport.query(makeSlice(QUERY)).get();
Ben Schwartzded1b702017-10-25 14:41:02 -0400395
396 EXPECT_EQ(DnsTlsTransport::Response::network_error, r.code);
397 EXPECT_TRUE(r.response.empty());
398}
399
Ben Schwartz33860762017-10-25 14:41:02 -0400400// Simulate a socket that connects but then immediately receives a server
401// close notification.
402class FakeSocketClose : public IDnsTlsSocket {
Erik Klineab999f12018-07-04 11:29:31 +0900403 public:
404 explicit FakeSocketClose(IDnsTlsSocketObserver* observer)
405 : mCloser(&IDnsTlsSocketObserver::onClosed, observer) {}
Ben Schwartz33860762017-10-25 14:41:02 -0400406 ~FakeSocketClose() { mCloser.join(); }
407 bool query(uint16_t id ATTRIBUTE_UNUSED,
408 const Slice query ATTRIBUTE_UNUSED) override {
409 return true;
410 }
Erik Klineab999f12018-07-04 11:29:31 +0900411
412 private:
Ben Schwartz33860762017-10-25 14:41:02 -0400413 std::thread mCloser;
414};
415
416TEST_F(TransportTest, CloseRetryFail) {
417 FakeSocketFactory<FakeSocketClose> factory;
418 DnsTlsTransport transport(SERVER1, MARK, &factory);
419 auto r = transport.query(makeSlice(QUERY)).get();
420
421 EXPECT_EQ(DnsTlsTransport::Response::network_error, r.code);
422 EXPECT_TRUE(r.response.empty());
423}
424
425// Simulate a server that occasionally closes the connection and silently
426// drops some queries.
427class FakeSocketLimited : public IDnsTlsSocket {
Erik Klineab999f12018-07-04 11:29:31 +0900428 public:
Ben Schwartz33860762017-10-25 14:41:02 -0400429 static int sLimit; // Number of queries to answer per socket.
430 static size_t sMaxSize; // Silently discard queries greater than this size.
Erik Klineab999f12018-07-04 11:29:31 +0900431 explicit FakeSocketLimited(IDnsTlsSocketObserver* observer)
432 : mObserver(observer), mQueries(0) {}
Ben Schwartz33860762017-10-25 14:41:02 -0400433 ~FakeSocketLimited() {
434 {
435 ALOGD("~FakeSocketLimited acquiring mLock");
Bernie Innocentiabf8a342018-08-10 15:17:16 +0900436 std::lock_guard guard(mLock);
Ben Schwartz33860762017-10-25 14:41:02 -0400437 ALOGD("~FakeSocketLimited acquired mLock");
438 for (auto& thread : mThreads) {
439 ALOGD("~FakeSocketLimited joining response thread");
440 thread.join();
441 ALOGD("~FakeSocketLimited joined response thread");
442 }
443 mThreads.clear();
444 }
445
446 if (mCloser) {
447 ALOGD("~FakeSocketLimited joining closer thread");
448 mCloser->join();
449 ALOGD("~FakeSocketLimited joined closer thread");
450 }
451 }
452 bool query(uint16_t id, const Slice query) override {
453 ALOGD("FakeSocketLimited::query acquiring mLock");
Bernie Innocentiabf8a342018-08-10 15:17:16 +0900454 std::lock_guard guard(mLock);
Ben Schwartz33860762017-10-25 14:41:02 -0400455 ALOGD("FakeSocketLimited::query acquired mLock");
456 ++mQueries;
457
458 if (mQueries <= sLimit) {
459 ALOGD("size %zu vs. limit of %zu", query.size(), sMaxSize);
460 if (query.size() <= sMaxSize) {
461 // Return the response immediately (asynchronously).
462 mThreads.emplace_back(&IDnsTlsSocketObserver::onResponse, mObserver, make_echo(id, query));
463 }
464 }
465 if (mQueries == sLimit) {
466 mCloser = std::make_unique<std::thread>(&FakeSocketLimited::sendClose, this);
467 }
468 return mQueries <= sLimit;
469 }
Erik Klineab999f12018-07-04 11:29:31 +0900470
471 private:
Ben Schwartz33860762017-10-25 14:41:02 -0400472 void sendClose() {
473 {
474 ALOGD("FakeSocketLimited::sendClose acquiring mLock");
Bernie Innocentiabf8a342018-08-10 15:17:16 +0900475 std::lock_guard guard(mLock);
Ben Schwartz33860762017-10-25 14:41:02 -0400476 ALOGD("FakeSocketLimited::sendClose acquired mLock");
477 for (auto& thread : mThreads) {
478 ALOGD("FakeSocketLimited::sendClose joining response thread");
479 thread.join();
480 ALOGD("FakeSocketLimited::sendClose joined response thread");
481 }
482 mThreads.clear();
483 }
484 mObserver->onClosed();
485 }
486 std::mutex mLock;
487 IDnsTlsSocketObserver* const mObserver;
488 int mQueries GUARDED_BY(mLock);
489 std::vector<std::thread> mThreads GUARDED_BY(mLock);
490 std::unique_ptr<std::thread> mCloser GUARDED_BY(mLock);
491};
492
493int FakeSocketLimited::sLimit;
494size_t FakeSocketLimited::sMaxSize;
495
496TEST_F(TransportTest, SilentDrop) {
497 FakeSocketLimited::sLimit = 10; // Close the socket after 10 queries.
498 FakeSocketLimited::sMaxSize = 0; // Silently drop all queries
499 FakeSocketFactory<FakeSocketLimited> factory;
500 DnsTlsTransport transport(SERVER1, MARK, &factory);
501
502 // Queue up 10 queries. They will all be ignored, and after the 10th,
503 // the socket will close. Transport will retry them all, until they
504 // all hit the retry limit and expire.
505 std::vector<std::future<DnsTlsTransport::Result>> results;
Bernie Innocenti1bcc25a2018-08-10 17:15:00 +0900506 results.reserve(FakeSocketLimited::sLimit);
Ben Schwartz33860762017-10-25 14:41:02 -0400507 for (int i = 0; i < FakeSocketLimited::sLimit; ++i) {
508 results.push_back(transport.query(makeSlice(QUERY)));
509 }
510 for (auto& result : results) {
511 auto r = result.get();
512 EXPECT_EQ(DnsTlsTransport::Response::network_error, r.code);
513 EXPECT_TRUE(r.response.empty());
514 }
515}
516
517TEST_F(TransportTest, PartialDrop) {
518 FakeSocketLimited::sLimit = 10; // Close the socket after 10 queries.
519 FakeSocketLimited::sMaxSize = SIZE - 2; // Silently drop "long" queries
520 FakeSocketFactory<FakeSocketLimited> factory;
521 DnsTlsTransport transport(SERVER1, MARK, &factory);
522
523 // Queue up 100 queries, alternating "short" which will be served and "long"
524 // which will be dropped.
Bernie Innocenti1bcc25a2018-08-10 17:15:00 +0900525 const int num_queries = 10 * FakeSocketLimited::sLimit;
Ben Schwartz33860762017-10-25 14:41:02 -0400526 std::vector<bytevec> queries(num_queries);
527 std::vector<std::future<DnsTlsTransport::Result>> results;
Bernie Innocenti1bcc25a2018-08-10 17:15:00 +0900528 results.reserve(num_queries);
Ben Schwartz33860762017-10-25 14:41:02 -0400529 for (int i = 0; i < num_queries; ++i) {
530 queries[i] = make_query(i, SIZE + (i % 2));
531 results.push_back(transport.query(makeSlice(queries[i])));
532 }
533 // Just check the short queries, which are at the even indices.
534 for (int i = 0; i < num_queries; i += 2) {
535 auto r = results[i].get();
536 EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
537 EXPECT_EQ(queries[i], r.response);
538 }
539}
540
541// Simulate a malfunctioning server that injects extra miscellaneous
542// responses to queries that were not asked. This will cause wrong answers but
543// must not crash the Transport.
544class FakeSocketGarbage : public IDnsTlsSocket {
Erik Klineab999f12018-07-04 11:29:31 +0900545 public:
546 explicit FakeSocketGarbage(IDnsTlsSocketObserver* observer) : mObserver(observer) {
Ben Schwartz33860762017-10-25 14:41:02 -0400547 // Inject a garbage event.
548 mThreads.emplace_back(&IDnsTlsSocketObserver::onResponse, mObserver, make_query(ID + 1, SIZE));
549 }
550 ~FakeSocketGarbage() {
Bernie Innocentiabf8a342018-08-10 15:17:16 +0900551 std::lock_guard guard(mLock);
Ben Schwartz33860762017-10-25 14:41:02 -0400552 for (auto& thread : mThreads) {
553 thread.join();
554 }
555 }
556 bool query(uint16_t id, const Slice query) override {
Bernie Innocentiabf8a342018-08-10 15:17:16 +0900557 std::lock_guard guard(mLock);
Ben Schwartz33860762017-10-25 14:41:02 -0400558 // Return the response twice.
559 auto echo = make_echo(id, query);
560 mThreads.emplace_back(&IDnsTlsSocketObserver::onResponse, mObserver, echo);
561 mThreads.emplace_back(&IDnsTlsSocketObserver::onResponse, mObserver, echo);
562 // Also return some other garbage
563 mThreads.emplace_back(&IDnsTlsSocketObserver::onResponse, mObserver, make_query(id + 1, query.size() + 2));
564 return true;
565 }
Erik Klineab999f12018-07-04 11:29:31 +0900566
567 private:
Ben Schwartz33860762017-10-25 14:41:02 -0400568 std::mutex mLock;
569 std::vector<std::thread> mThreads GUARDED_BY(mLock);
570 IDnsTlsSocketObserver* const mObserver;
571};
572
573TEST_F(TransportTest, IgnoringGarbage) {
574 FakeSocketFactory<FakeSocketGarbage> factory;
575 DnsTlsTransport transport(SERVER1, MARK, &factory);
576 for (int i = 0; i < 10; ++i) {
577 auto r = transport.query(makeSlice(QUERY)).get();
578
579 EXPECT_EQ(DnsTlsTransport::Response::success, r.code);
580 // Don't check the response because this server is malfunctioning.
581 }
582}
583
Ben Schwartzded1b702017-10-25 14:41:02 -0400584// Dispatcher tests
585class DispatcherTest : public BaseTest {};
586
587TEST_F(DispatcherTest, Query) {
588 bytevec ans(4096);
589 int resplen = 0;
590
591 auto factory = std::make_unique<FakeSocketFactory<FakeSocketEcho>>();
592 DnsTlsDispatcher dispatcher(std::move(factory));
593 auto r = dispatcher.query(SERVER1, MARK, makeSlice(QUERY),
594 makeSlice(ans), &resplen);
595
596 EXPECT_EQ(DnsTlsTransport::Response::success, r);
597 EXPECT_EQ(int(QUERY.size()), resplen);
598 ans.resize(resplen);
599 EXPECT_EQ(QUERY, ans);
600}
601
602TEST_F(DispatcherTest, AnswerTooLarge) {
603 bytevec ans(SIZE - 1); // Too small to hold the answer
604 int resplen = 0;
605
606 auto factory = std::make_unique<FakeSocketFactory<FakeSocketEcho>>();
607 DnsTlsDispatcher dispatcher(std::move(factory));
608 auto r = dispatcher.query(SERVER1, MARK, makeSlice(QUERY),
609 makeSlice(ans), &resplen);
610
611 EXPECT_EQ(DnsTlsTransport::Response::limit_error, r);
612}
613
614template<class T>
615class TrackingFakeSocketFactory : public IDnsTlsSocketFactory {
Erik Klineab999f12018-07-04 11:29:31 +0900616 public:
Ben Schwartzded1b702017-10-25 14:41:02 -0400617 TrackingFakeSocketFactory() {}
618 std::unique_ptr<IDnsTlsSocket> createDnsTlsSocket(
619 const DnsTlsServer& server,
620 unsigned mark,
Ben Schwartz33860762017-10-25 14:41:02 -0400621 IDnsTlsSocketObserver* observer,
Ben Schwartzded1b702017-10-25 14:41:02 -0400622 DnsTlsSessionCache* cache ATTRIBUTE_UNUSED) override {
Bernie Innocentiabf8a342018-08-10 15:17:16 +0900623 std::lock_guard guard(mLock);
Ben Schwartzded1b702017-10-25 14:41:02 -0400624 keys.emplace(mark, server);
Ben Schwartz33860762017-10-25 14:41:02 -0400625 return std::make_unique<T>(observer);
Ben Schwartzded1b702017-10-25 14:41:02 -0400626 }
627 std::multiset<std::pair<unsigned, DnsTlsServer>> keys;
Erik Klineab999f12018-07-04 11:29:31 +0900628
629 private:
Ben Schwartzded1b702017-10-25 14:41:02 -0400630 std::mutex mLock;
631};
632
633TEST_F(DispatcherTest, Dispatching) {
Ben Schwartz33860762017-10-25 14:41:02 -0400634 FakeSocketDelay::sDelay = 5;
635 FakeSocketDelay::sReverse = true;
636 auto factory = std::make_unique<TrackingFakeSocketFactory<FakeSocketDelay>>();
Ben Schwartzded1b702017-10-25 14:41:02 -0400637 auto* weak_factory = factory.get(); // Valid as long as dispatcher is in scope.
638 DnsTlsDispatcher dispatcher(std::move(factory));
639
640 // Populate a vector of two servers and two socket marks, four combinations
641 // in total.
642 std::vector<std::pair<unsigned, DnsTlsServer>> keys;
643 keys.emplace_back(MARK, SERVER1);
644 keys.emplace_back(MARK + 1, SERVER1);
645 keys.emplace_back(MARK, V4ADDR2);
646 keys.emplace_back(MARK + 1, V4ADDR2);
647
Ben Schwartz33860762017-10-25 14:41:02 -0400648 // Do several queries on each server. They should all succeed.
Ben Schwartzded1b702017-10-25 14:41:02 -0400649 std::vector<std::thread> threads;
Ben Schwartz33860762017-10-25 14:41:02 -0400650 for (size_t i = 0; i < FakeSocketDelay::sDelay * keys.size(); ++i) {
Ben Schwartzded1b702017-10-25 14:41:02 -0400651 auto key = keys[i % keys.size()];
652 threads.emplace_back([key, i] (DnsTlsDispatcher* dispatcher) {
653 auto q = make_query(i, SIZE);
654 bytevec ans(4096);
655 int resplen = 0;
656 unsigned mark = key.first;
657 const DnsTlsServer& server = key.second;
658 auto r = dispatcher->query(server, mark, makeSlice(q),
659 makeSlice(ans), &resplen);
660 EXPECT_EQ(DnsTlsTransport::Response::success, r);
661 EXPECT_EQ(int(q.size()), resplen);
662 ans.resize(resplen);
663 EXPECT_EQ(q, ans);
664 }, &dispatcher);
665 }
666 for (auto& thread : threads) {
667 thread.join();
668 }
669 // We expect that the factory created one socket for each key.
670 EXPECT_EQ(keys.size(), weak_factory->keys.size());
671 for (auto& key : keys) {
672 EXPECT_EQ(1U, weak_factory->keys.count(key));
673 }
674}
675
Ben Schwartze5595152017-10-25 14:41:02 -0400676// Check DnsTlsServer's comparison logic.
677AddressComparator ADDRESS_COMPARATOR;
678bool isAddressEqual(const DnsTlsServer& s1, const DnsTlsServer& s2) {
679 bool cmp1 = ADDRESS_COMPARATOR(s1, s2);
680 bool cmp2 = ADDRESS_COMPARATOR(s2, s1);
681 EXPECT_FALSE(cmp1 && cmp2);
682 return !cmp1 && !cmp2;
683}
684
685void checkUnequal(const DnsTlsServer& s1, const DnsTlsServer& s2) {
686 EXPECT_TRUE(s1 == s1);
687 EXPECT_TRUE(s2 == s2);
688 EXPECT_TRUE(isAddressEqual(s1, s1));
689 EXPECT_TRUE(isAddressEqual(s2, s2));
690
691 EXPECT_TRUE(s1 < s2 ^ s2 < s1);
692 EXPECT_FALSE(s1 == s2);
693 EXPECT_FALSE(s2 == s1);
694}
695
696class ServerTest : public BaseTest {};
697
698TEST_F(ServerTest, IPv4) {
699 checkUnequal(V4ADDR1, V4ADDR2);
700 EXPECT_FALSE(isAddressEqual(V4ADDR1, V4ADDR2));
701}
702
703TEST_F(ServerTest, IPv6) {
704 checkUnequal(V6ADDR1, V6ADDR2);
705 EXPECT_FALSE(isAddressEqual(V6ADDR1, V6ADDR2));
706}
707
708TEST_F(ServerTest, MixedAddressFamily) {
709 checkUnequal(V6ADDR1, V4ADDR1);
710 EXPECT_FALSE(isAddressEqual(V6ADDR1, V4ADDR1));
711}
712
713TEST_F(ServerTest, IPv6ScopeId) {
714 DnsTlsServer s1(V6ADDR1), s2(V6ADDR1);
715 sockaddr_in6* addr1 = reinterpret_cast<sockaddr_in6*>(&s1.ss);
716 addr1->sin6_scope_id = 1;
717 sockaddr_in6* addr2 = reinterpret_cast<sockaddr_in6*>(&s2.ss);
718 addr2->sin6_scope_id = 2;
719 checkUnequal(s1, s2);
720 EXPECT_FALSE(isAddressEqual(s1, s2));
Erik Kline1564d482018-03-07 17:09:35 +0900721
722 EXPECT_FALSE(s1.wasExplicitlyConfigured());
723 EXPECT_FALSE(s2.wasExplicitlyConfigured());
Ben Schwartze5595152017-10-25 14:41:02 -0400724}
725
726TEST_F(ServerTest, IPv6FlowInfo) {
727 DnsTlsServer s1(V6ADDR1), s2(V6ADDR1);
728 sockaddr_in6* addr1 = reinterpret_cast<sockaddr_in6*>(&s1.ss);
729 addr1->sin6_flowinfo = 1;
730 sockaddr_in6* addr2 = reinterpret_cast<sockaddr_in6*>(&s2.ss);
731 addr2->sin6_flowinfo = 2;
732 // All comparisons ignore flowinfo.
733 EXPECT_EQ(s1, s2);
734 EXPECT_TRUE(isAddressEqual(s1, s2));
Erik Kline1564d482018-03-07 17:09:35 +0900735
736 EXPECT_FALSE(s1.wasExplicitlyConfigured());
737 EXPECT_FALSE(s2.wasExplicitlyConfigured());
Ben Schwartze5595152017-10-25 14:41:02 -0400738}
739
740TEST_F(ServerTest, Port) {
741 DnsTlsServer s1, s2;
742 parseServer("192.0.2.1", 853, &s1.ss);
743 parseServer("192.0.2.1", 854, &s2.ss);
744 checkUnequal(s1, s2);
745 EXPECT_TRUE(isAddressEqual(s1, s2));
746
747 DnsTlsServer s3, s4;
748 parseServer("2001:db8::1", 853, &s3.ss);
749 parseServer("2001:db8::1", 852, &s4.ss);
750 checkUnequal(s3, s4);
751 EXPECT_TRUE(isAddressEqual(s3, s4));
Erik Kline1564d482018-03-07 17:09:35 +0900752
753 EXPECT_FALSE(s1.wasExplicitlyConfigured());
754 EXPECT_FALSE(s2.wasExplicitlyConfigured());
Ben Schwartze5595152017-10-25 14:41:02 -0400755}
756
757TEST_F(ServerTest, Name) {
758 DnsTlsServer s1(V4ADDR1), s2(V4ADDR1);
759 s1.name = SERVERNAME1;
760 checkUnequal(s1, s2);
761 s2.name = SERVERNAME2;
762 checkUnequal(s1, s2);
763 EXPECT_TRUE(isAddressEqual(s1, s2));
Erik Kline1564d482018-03-07 17:09:35 +0900764
765 EXPECT_TRUE(s1.wasExplicitlyConfigured());
766 EXPECT_TRUE(s2.wasExplicitlyConfigured());
Ben Schwartze5595152017-10-25 14:41:02 -0400767}
768
769TEST_F(ServerTest, Fingerprint) {
770 DnsTlsServer s1(V4ADDR1), s2(V4ADDR1);
771
772 s1.fingerprints.insert(FINGERPRINT1);
773 checkUnequal(s1, s2);
774 EXPECT_TRUE(isAddressEqual(s1, s2));
775
776 s2.fingerprints.insert(FINGERPRINT2);
777 checkUnequal(s1, s2);
778 EXPECT_TRUE(isAddressEqual(s1, s2));
779
780 s2.fingerprints.insert(FINGERPRINT1);
781 checkUnequal(s1, s2);
782 EXPECT_TRUE(isAddressEqual(s1, s2));
783
784 s1.fingerprints.insert(FINGERPRINT2);
785 EXPECT_EQ(s1, s2);
786 EXPECT_TRUE(isAddressEqual(s1, s2));
Erik Kline1564d482018-03-07 17:09:35 +0900787
788 EXPECT_TRUE(s1.wasExplicitlyConfigured());
789 EXPECT_TRUE(s2.wasExplicitlyConfigured());
Ben Schwartze5595152017-10-25 14:41:02 -0400790}
791
Ben Schwartz33860762017-10-25 14:41:02 -0400792TEST(QueryMapTest, Basic) {
793 DnsTlsQueryMap map;
794
795 EXPECT_TRUE(map.empty());
796
797 bytevec q0 = make_query(999, SIZE);
798 bytevec q1 = make_query(888, SIZE);
799 bytevec q2 = make_query(777, SIZE);
800
801 auto f0 = map.recordQuery(makeSlice(q0));
802 auto f1 = map.recordQuery(makeSlice(q1));
803 auto f2 = map.recordQuery(makeSlice(q2));
804
805 // Check return values of recordQuery
806 EXPECT_EQ(0, f0->query.newId);
807 EXPECT_EQ(1, f1->query.newId);
808 EXPECT_EQ(2, f2->query.newId);
809
810 // Check side effects of recordQuery
811 EXPECT_FALSE(map.empty());
812
813 auto all = map.getAll();
814 EXPECT_EQ(3U, all.size());
815
816 EXPECT_EQ(0, all[0].newId);
817 EXPECT_EQ(1, all[1].newId);
818 EXPECT_EQ(2, all[2].newId);
819
820 EXPECT_EQ(makeSlice(q0), all[0].query);
821 EXPECT_EQ(makeSlice(q1), all[1].query);
822 EXPECT_EQ(makeSlice(q2), all[2].query);
823
824 bytevec a0 = make_query(0, SIZE);
825 bytevec a1 = make_query(1, SIZE);
826 bytevec a2 = make_query(2, SIZE);
827
828 // Return responses out of order
829 map.onResponse(a2);
830 map.onResponse(a0);
831 map.onResponse(a1);
832
833 EXPECT_TRUE(map.empty());
834
835 auto r0 = f0->result.get();
836 auto r1 = f1->result.get();
837 auto r2 = f2->result.get();
838
839 EXPECT_EQ(DnsTlsQueryMap::Response::success, r0.code);
840 EXPECT_EQ(DnsTlsQueryMap::Response::success, r1.code);
841 EXPECT_EQ(DnsTlsQueryMap::Response::success, r2.code);
842
843 const bytevec& d0 = r0.response;
844 const bytevec& d1 = r1.response;
845 const bytevec& d2 = r2.response;
846
847 // The ID should match the query
848 EXPECT_EQ(999, d0[0] << 8 | d0[1]);
849 EXPECT_EQ(888, d1[0] << 8 | d1[1]);
850 EXPECT_EQ(777, d2[0] << 8 | d2[1]);
851 // The body should match the answer
852 EXPECT_EQ(bytevec(a0.begin() + 2, a0.end()), bytevec(d0.begin() + 2, d0.end()));
853 EXPECT_EQ(bytevec(a1.begin() + 2, a1.end()), bytevec(d1.begin() + 2, d1.end()));
854 EXPECT_EQ(bytevec(a2.begin() + 2, a2.end()), bytevec(d2.begin() + 2, d2.end()));
855}
856
857TEST(QueryMapTest, FillHole) {
858 DnsTlsQueryMap map;
859 std::vector<std::unique_ptr<DnsTlsQueryMap::QueryFuture>> futures(UINT16_MAX + 1);
860 for (uint32_t i = 0; i <= UINT16_MAX; ++i) {
861 futures[i] = map.recordQuery(makeSlice(QUERY));
862 ASSERT_TRUE(futures[i]); // answers[i] should be nonnull.
863 EXPECT_EQ(i, futures[i]->query.newId);
864 }
865
866 // The map should now be full.
867 EXPECT_EQ(size_t(UINT16_MAX + 1), map.getAll().size());
868
869 // Trying to add another query should fail because the map is full.
870 EXPECT_FALSE(map.recordQuery(makeSlice(QUERY)));
871
872 // Send an answer to query 40000
873 auto answer = make_query(40000, SIZE);
874 map.onResponse(answer);
875 auto result = futures[40000]->result.get();
876 EXPECT_EQ(DnsTlsQueryMap::Response::success, result.code);
877 EXPECT_EQ(ID, result.response[0] << 8 | result.response[1]);
878 EXPECT_EQ(bytevec(answer.begin() + 2, answer.end()),
879 bytevec(result.response.begin() + 2, result.response.end()));
880
881 // There should now be room in the map.
882 EXPECT_EQ(size_t(UINT16_MAX), map.getAll().size());
883 auto f = map.recordQuery(makeSlice(QUERY));
884 ASSERT_TRUE(f);
885 EXPECT_EQ(40000, f->query.newId);
886
887 // The map should now be full again.
888 EXPECT_EQ(size_t(UINT16_MAX + 1), map.getAll().size());
889 EXPECT_FALSE(map.recordQuery(makeSlice(QUERY)));
890}
891
Ben Schwartzded1b702017-10-25 14:41:02 -0400892} // end of namespace net
893} // end of namespace android