dns_response_result_extractor_unittest.cc 96 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169
  1. // Copyright 2020 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. #include "net/dns/dns_response_result_extractor.h"
  5. #include <string>
  6. #include <utility>
  7. #include <vector>
  8. #include "base/strings/string_piece.h"
  9. #include "base/time/time.h"
  10. #include "net/base/connection_endpoint_metadata_test_util.h"
  11. #include "net/base/host_port_pair.h"
  12. #include "net/base/ip_address.h"
  13. #include "net/base/ip_endpoint.h"
  14. #include "net/base/net_errors.h"
  15. #include "net/dns/dns_query.h"
  16. #include "net/dns/dns_response.h"
  17. #include "net/dns/dns_test_util.h"
  18. #include "net/dns/host_cache.h"
  19. #include "net/dns/host_resolver_results_test_util.h"
  20. #include "net/dns/public/dns_protocol.h"
  21. #include "net/dns/public/dns_query_type.h"
  22. #include "net/test/gtest_util.h"
  23. #include "testing/gmock/include/gmock/gmock.h"
  24. #include "testing/gtest/include/gtest/gtest.h"
  25. #include "third_party/abseil-cpp/absl/types/optional.h"
  26. namespace net {
  27. namespace {
  28. TEST(DnsResponseResultExtractorTest, ExtractsSingleARecord) {
  29. constexpr char kName[] = "address.test";
  30. const IPAddress kExpected(192, 168, 0, 1);
  31. DnsResponse response = BuildTestDnsAddressResponse(kName, kExpected);
  32. DnsResponseResultExtractor extractor(&response);
  33. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  34. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::A,
  35. /*original_domain_name=*/kName,
  36. /*request_port=*/0, &results),
  37. DnsResponseResultExtractor::ExtractionError::kOk);
  38. EXPECT_THAT(results.error(), test::IsOk());
  39. IPEndPoint expected_endpoint(kExpected, 0 /* port */);
  40. EXPECT_THAT(results.GetEndpoints(),
  41. testing::Optional(testing::ElementsAre(ExpectEndpointResult(
  42. testing::ElementsAre(expected_endpoint)))));
  43. EXPECT_THAT(results.aliases(), testing::Pointee(testing::ElementsAre(kName)));
  44. EXPECT_TRUE(results.has_ttl());
  45. }
  46. TEST(DnsResponseResultExtractorTest, ExtractsSingleAAAARecord) {
  47. constexpr char kName[] = "address.test";
  48. IPAddress expected;
  49. CHECK(expected.AssignFromIPLiteral("2001:4860:4860::8888"));
  50. DnsResponse response = BuildTestDnsAddressResponse(kName, expected);
  51. DnsResponseResultExtractor extractor(&response);
  52. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  53. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::AAAA,
  54. /*original_domain_name=*/kName,
  55. /*request_port=*/0, &results),
  56. DnsResponseResultExtractor::ExtractionError::kOk);
  57. EXPECT_THAT(results.error(), test::IsOk());
  58. IPEndPoint expected_endpoint(expected, 0 /* port */);
  59. EXPECT_THAT(results.GetEndpoints(),
  60. testing::Optional(testing::ElementsAre(ExpectEndpointResult(
  61. testing::ElementsAre(expected_endpoint)))));
  62. EXPECT_THAT(results.aliases(), testing::Pointee(testing::ElementsAre(kName)));
  63. }
  64. TEST(DnsResponseResultExtractorTest, ExtractsSingleARecordWithCname) {
  65. const IPAddress kExpected(192, 168, 0, 1);
  66. constexpr char kName[] = "address.test";
  67. constexpr char kCanonicalName[] = "alias.test";
  68. DnsResponse response =
  69. BuildTestDnsAddressResponseWithCname(kName, kExpected, kCanonicalName);
  70. DnsResponseResultExtractor extractor(&response);
  71. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  72. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::A,
  73. /*original_domain_name=*/kName,
  74. /*request_port=*/0, &results),
  75. DnsResponseResultExtractor::ExtractionError::kOk);
  76. EXPECT_THAT(results.error(), test::IsOk());
  77. IPEndPoint expected_endpoint(kExpected, 0 /* port */);
  78. EXPECT_THAT(results.GetEndpoints(),
  79. testing::Optional(testing::ElementsAre(ExpectEndpointResult(
  80. testing::ElementsAre(expected_endpoint)))));
  81. EXPECT_THAT(results.aliases(), testing::Pointee(testing::UnorderedElementsAre(
  82. kName, kCanonicalName)));
  83. }
  84. TEST(DnsResponseResultExtractorTest, ExtractsARecordsWithCname) {
  85. constexpr char kName[] = "addresses.test";
  86. DnsResponse response = BuildTestDnsResponse(
  87. "addresses.test", dns_protocol::kTypeA,
  88. {
  89. BuildTestAddressRecord("alias.test", IPAddress(74, 125, 226, 179)),
  90. BuildTestAddressRecord("alias.test", IPAddress(74, 125, 226, 180)),
  91. BuildTestCnameRecord(kName, "alias.test"),
  92. BuildTestAddressRecord("alias.test", IPAddress(74, 125, 226, 176)),
  93. BuildTestAddressRecord("alias.test", IPAddress(74, 125, 226, 177)),
  94. BuildTestAddressRecord("alias.test", IPAddress(74, 125, 226, 178)),
  95. });
  96. DnsResponseResultExtractor extractor(&response);
  97. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  98. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::A,
  99. /*original_domain_name=*/kName,
  100. /*request_port=*/0, &results),
  101. DnsResponseResultExtractor::ExtractionError::kOk);
  102. EXPECT_THAT(results.error(), test::IsOk());
  103. EXPECT_THAT(
  104. results.GetEndpoints(),
  105. testing::Optional(testing::ElementsAre(
  106. ExpectEndpointResult(testing::UnorderedElementsAre(
  107. IPEndPoint(IPAddress(74, 125, 226, 179), 0 /* port */),
  108. IPEndPoint(IPAddress(74, 125, 226, 178), 0 /* port */),
  109. IPEndPoint(IPAddress(74, 125, 226, 180), 0 /* port */),
  110. IPEndPoint(IPAddress(74, 125, 226, 176), 0 /* port */),
  111. IPEndPoint(IPAddress(74, 125, 226, 177), 0 /* port */))))));
  112. EXPECT_THAT(results.aliases(), testing::Pointee(testing::UnorderedElementsAre(
  113. "alias.test", kName)));
  114. }
  115. TEST(DnsResponseResultExtractorTest, ExtractsNxdomainAResponses) {
  116. constexpr char kName[] = "address.test";
  117. constexpr auto kTtl = base::Hours(2);
  118. DnsResponse response = BuildTestDnsResponse(
  119. kName, dns_protocol::kTypeA, /*answers=*/{},
  120. /*authority=*/
  121. {BuildTestDnsRecord(kName, dns_protocol::kTypeSOA, "fake rdata", kTtl)},
  122. /*additional=*/{}, dns_protocol::kRcodeNXDOMAIN);
  123. DnsResponseResultExtractor extractor(&response);
  124. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  125. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::A,
  126. /*original_domain_name=*/kName,
  127. /*request_port=*/0, &results),
  128. DnsResponseResultExtractor::ExtractionError::kOk);
  129. EXPECT_THAT(results.error(), test::IsError(ERR_NAME_NOT_RESOLVED));
  130. EXPECT_THAT(results.GetEndpoints(), testing::Optional(testing::IsEmpty()));
  131. EXPECT_THAT(results.aliases(), testing::Pointee(testing::ElementsAre(kName)));
  132. ASSERT_TRUE(results.has_ttl());
  133. EXPECT_EQ(results.ttl(), kTtl);
  134. }
  135. TEST(DnsResponseResultExtractorTest, ExtractsNodataAResponses) {
  136. constexpr char kName[] = "address.test";
  137. constexpr auto kTtl = base::Minutes(15);
  138. DnsResponse response = BuildTestDnsResponse(
  139. kName, dns_protocol::kTypeA, /*answers=*/{},
  140. /*authority=*/
  141. {BuildTestDnsRecord(kName, dns_protocol::kTypeSOA, "fake rdata", kTtl)});
  142. DnsResponseResultExtractor extractor(&response);
  143. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  144. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::A,
  145. /*original_domain_name=*/kName,
  146. /*request_port=*/0, &results),
  147. DnsResponseResultExtractor::ExtractionError::kOk);
  148. EXPECT_THAT(results.error(), test::IsError(ERR_NAME_NOT_RESOLVED));
  149. EXPECT_THAT(results.GetEndpoints(), testing::Optional(testing::IsEmpty()));
  150. EXPECT_THAT(results.aliases(), testing::Pointee(testing::ElementsAre(kName)));
  151. ASSERT_TRUE(results.has_ttl());
  152. EXPECT_EQ(results.ttl(), kTtl);
  153. }
  154. TEST(DnsResponseResultExtractorTest, RejectsMalformedARecord) {
  155. constexpr char kName[] = "address.test";
  156. DnsResponse response = BuildTestDnsResponse(
  157. kName, dns_protocol::kTypeA,
  158. {BuildTestDnsRecord(kName, dns_protocol::kTypeA,
  159. "malformed rdata")} /* answers */);
  160. DnsResponseResultExtractor extractor(&response);
  161. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  162. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::A,
  163. /*original_domain_name=*/kName,
  164. /*request_port=*/0, &results),
  165. DnsResponseResultExtractor::ExtractionError::kMalformedRecord);
  166. EXPECT_THAT(results.error(), test::IsError(ERR_DNS_MALFORMED_RESPONSE));
  167. EXPECT_FALSE(results.has_ttl());
  168. }
  169. TEST(DnsResponseResultExtractorTest, RejectsWrongNameARecord) {
  170. constexpr char kName[] = "address.test";
  171. DnsResponse response = BuildTestDnsAddressResponse(
  172. kName, IPAddress(1, 2, 3, 4), "different.test");
  173. DnsResponseResultExtractor extractor(&response);
  174. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  175. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::A,
  176. /*original_domain_name=*/kName,
  177. /*request_port=*/0, &results),
  178. DnsResponseResultExtractor::ExtractionError::kNameMismatch);
  179. EXPECT_THAT(results.error(), test::IsError(ERR_DNS_MALFORMED_RESPONSE));
  180. EXPECT_FALSE(results.has_ttl());
  181. }
  182. TEST(DnsResponseResultExtractorTest, IgnoresWrongTypeRecordsInAResponse) {
  183. constexpr char kName[] = "address.test";
  184. DnsResponse response = BuildTestDnsResponse(
  185. kName, dns_protocol::kTypeA,
  186. {BuildTestTextRecord("address.test", {"foo"} /* text_strings */)});
  187. DnsResponseResultExtractor extractor(&response);
  188. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  189. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::A,
  190. /*original_domain_name=*/kName,
  191. /*request_port=*/0, &results),
  192. DnsResponseResultExtractor::ExtractionError::kOk);
  193. EXPECT_THAT(results.error(), test::IsError(ERR_NAME_NOT_RESOLVED));
  194. EXPECT_THAT(results.GetEndpoints(), testing::Optional(testing::IsEmpty()));
  195. EXPECT_THAT(results.aliases(),
  196. testing::Pointee(testing::ElementsAre("address.test")));
  197. EXPECT_FALSE(results.has_ttl());
  198. }
  199. TEST(DnsResponseResultExtractorTest, IgnoresWrongTypeRecordsMixedWithARecords) {
  200. constexpr char kName[] = "address.test";
  201. const IPAddress kExpected(8, 8, 8, 8);
  202. constexpr auto kTtl = base::Days(3);
  203. DnsResponse response = BuildTestDnsResponse(
  204. kName, dns_protocol::kTypeA,
  205. {BuildTestTextRecord(kName, /*text_strings=*/{"foo"}, base::Hours(2)),
  206. BuildTestAddressRecord(kName, kExpected, kTtl)});
  207. DnsResponseResultExtractor extractor(&response);
  208. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  209. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::A,
  210. /*original_domain_name=*/kName,
  211. /*request_port=*/0, &results),
  212. DnsResponseResultExtractor::ExtractionError::kOk);
  213. EXPECT_THAT(results.error(), test::IsOk());
  214. IPEndPoint expected_endpoint(kExpected, 0 /* port */);
  215. EXPECT_THAT(results.GetEndpoints(),
  216. testing::Optional(testing::ElementsAre(ExpectEndpointResult(
  217. testing::ElementsAre(expected_endpoint)))));
  218. EXPECT_THAT(results.aliases(), testing::Pointee(testing::ElementsAre(kName)));
  219. ASSERT_TRUE(results.has_ttl());
  220. EXPECT_EQ(results.ttl(), kTtl);
  221. }
  222. TEST(DnsResponseResultExtractorTest, ExtractsMinATtl) {
  223. constexpr char kName[] = "name.test";
  224. constexpr base::TimeDelta kMinTtl = base::Minutes(4);
  225. DnsResponse response = BuildTestDnsResponse(
  226. kName, dns_protocol::kTypeA,
  227. {BuildTestAddressRecord(kName, IPAddress(1, 2, 3, 4), base::Hours(3)),
  228. BuildTestAddressRecord(kName, IPAddress(2, 3, 4, 5), kMinTtl),
  229. BuildTestAddressRecord(kName, IPAddress(3, 4, 5, 6),
  230. base::Minutes(15))});
  231. DnsResponseResultExtractor extractor(&response);
  232. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  233. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::A,
  234. /*original_domain_name=*/kName,
  235. /*request_port=*/0, &results),
  236. DnsResponseResultExtractor::ExtractionError::kOk);
  237. ASSERT_TRUE(results.has_ttl());
  238. EXPECT_EQ(results.ttl(), kMinTtl);
  239. }
  240. TEST(DnsResponseResultExtractorTest, ExtractsTxtResponses) {
  241. constexpr char kName[] = "name.test";
  242. // Simulate two separate DNS records, each with multiple strings.
  243. std::vector<std::string> foo_records = {"foo1", "foo2", "foo3"};
  244. std::vector<std::string> bar_records = {"bar1", "bar2"};
  245. std::vector<std::vector<std::string>> text_records = {foo_records,
  246. bar_records};
  247. DnsResponse response =
  248. BuildTestDnsTextResponse(kName, std::move(text_records));
  249. DnsResponseResultExtractor extractor(&response);
  250. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  251. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::TXT,
  252. /*original_domain_name=*/kName,
  253. /*request_port=*/0, &results),
  254. DnsResponseResultExtractor::ExtractionError::kOk);
  255. EXPECT_THAT(results.error(), test::IsOk());
  256. // Order between separate DNS records is undefined, but each record should
  257. // stay in order as that order may be meaningful.
  258. ASSERT_THAT(results.text_records(),
  259. testing::Optional(testing::UnorderedElementsAre(
  260. "foo1", "foo2", "foo3", "bar1", "bar2")));
  261. std::vector<std::string> results_vector = results.text_records().value();
  262. EXPECT_NE(results_vector.end(),
  263. std::search(results_vector.begin(), results_vector.end(),
  264. foo_records.begin(), foo_records.end()));
  265. EXPECT_NE(results_vector.end(),
  266. std::search(results_vector.begin(), results_vector.end(),
  267. bar_records.begin(), bar_records.end()));
  268. }
  269. TEST(DnsResponseResultExtractorTest, ExtractsNxdomainTxtResponses) {
  270. constexpr char kName[] = "name.test";
  271. constexpr auto kTtl = base::Days(4);
  272. DnsResponse response = BuildTestDnsResponse(
  273. kName, dns_protocol::kTypeTXT, /*answers=*/{},
  274. /*authority=*/
  275. {BuildTestDnsRecord(kName, dns_protocol::kTypeSOA, "fake rdata", kTtl)},
  276. /*additional=*/{}, dns_protocol::kRcodeNXDOMAIN);
  277. DnsResponseResultExtractor extractor(&response);
  278. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  279. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::TXT,
  280. /*original_domain_name=*/kName,
  281. /*request_port=*/0, &results),
  282. DnsResponseResultExtractor::ExtractionError::kOk);
  283. EXPECT_THAT(results.error(), test::IsError(ERR_NAME_NOT_RESOLVED));
  284. EXPECT_THAT(results.text_records(), testing::Optional(testing::IsEmpty()));
  285. ASSERT_TRUE(results.has_ttl());
  286. EXPECT_EQ(results.ttl(), kTtl);
  287. }
  288. TEST(DnsResponseResultExtractorTest, ExtractsNodataTxtResponses) {
  289. constexpr char kName[] = "name.test";
  290. constexpr auto kTtl = base::Minutes(42);
  291. DnsResponse response = BuildTestDnsResponse(
  292. kName, dns_protocol::kTypeTXT,
  293. /*answers=*/{}, /*authority=*/
  294. {BuildTestDnsRecord(kName, dns_protocol::kTypeSOA, "fake rdata", kTtl)});
  295. DnsResponseResultExtractor extractor(&response);
  296. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  297. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::TXT,
  298. /*original_domain_name=*/kName,
  299. /*request_port=*/0, &results),
  300. DnsResponseResultExtractor::ExtractionError::kOk);
  301. EXPECT_THAT(results.error(), test::IsError(ERR_NAME_NOT_RESOLVED));
  302. EXPECT_THAT(results.text_records(), testing::Optional(testing::IsEmpty()));
  303. ASSERT_TRUE(results.has_ttl());
  304. EXPECT_EQ(results.ttl(), kTtl);
  305. }
  306. TEST(DnsResponseResultExtractorTest, RejectsMalformedTxtRecord) {
  307. constexpr char kName[] = "name.test";
  308. DnsResponse response = BuildTestDnsResponse(
  309. kName, dns_protocol::kTypeTXT,
  310. {BuildTestDnsRecord(kName, dns_protocol::kTypeTXT,
  311. "malformed rdata")} /* answers */);
  312. DnsResponseResultExtractor extractor(&response);
  313. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  314. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::TXT,
  315. /*original_domain_name=*/kName,
  316. /*request_port=*/0, &results),
  317. DnsResponseResultExtractor::ExtractionError::kMalformedRecord);
  318. EXPECT_THAT(results.error(), test::IsError(ERR_DNS_MALFORMED_RESPONSE));
  319. EXPECT_FALSE(results.has_ttl());
  320. }
  321. TEST(DnsResponseResultExtractorTest, RejectsWrongNameTxtRecord) {
  322. constexpr char kName[] = "name.test";
  323. DnsResponse response =
  324. BuildTestDnsTextResponse(kName, {{"foo"}}, "different.test");
  325. DnsResponseResultExtractor extractor(&response);
  326. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  327. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::TXT,
  328. /*original_domain_name=*/kName,
  329. /*request_port=*/0, &results),
  330. DnsResponseResultExtractor::ExtractionError::kNameMismatch);
  331. EXPECT_THAT(results.error(), test::IsError(ERR_DNS_MALFORMED_RESPONSE));
  332. EXPECT_FALSE(results.has_ttl());
  333. }
  334. TEST(DnsResponseResultExtractorTest, IgnoresWrongTypeTxtResponses) {
  335. constexpr char kName[] = "name.test";
  336. DnsResponse response = BuildTestDnsResponse(
  337. kName, dns_protocol::kTypeTXT,
  338. {BuildTestAddressRecord(kName, IPAddress(1, 2, 3, 4))});
  339. DnsResponseResultExtractor extractor(&response);
  340. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  341. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::TXT,
  342. /*original_domain_name=*/kName,
  343. /*request_port=*/0, &results),
  344. DnsResponseResultExtractor::ExtractionError::kOk);
  345. EXPECT_THAT(results.error(), test::IsError(ERR_NAME_NOT_RESOLVED));
  346. EXPECT_THAT(results.text_records(), testing::Optional(testing::IsEmpty()));
  347. EXPECT_FALSE(results.has_ttl());
  348. }
  349. TEST(DnsResponseResultExtractorTest, ExtractsMinTxtTtl) {
  350. constexpr char kName[] = "name.test";
  351. constexpr base::TimeDelta kMinTtl = base::Minutes(4);
  352. DnsResponse response = BuildTestDnsResponse(
  353. kName, dns_protocol::kTypeTXT,
  354. {BuildTestTextRecord(kName, {"foo"}, base::Hours(3)),
  355. BuildTestTextRecord(kName, {"bar"}, kMinTtl),
  356. BuildTestTextRecord(kName, {"baz"}, base::Minutes(15))});
  357. DnsResponseResultExtractor extractor(&response);
  358. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  359. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::TXT,
  360. /*original_domain_name=*/kName,
  361. /*request_port=*/0, &results),
  362. DnsResponseResultExtractor::ExtractionError::kOk);
  363. ASSERT_TRUE(results.has_ttl());
  364. EXPECT_EQ(results.ttl(), kMinTtl);
  365. }
  366. TEST(DnsResponseResultExtractorTest, ExtractsPtrResponses) {
  367. constexpr char kName[] = "name.test";
  368. DnsResponse response =
  369. BuildTestDnsPointerResponse(kName, {"foo.com", "bar.com"});
  370. DnsResponseResultExtractor extractor(&response);
  371. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  372. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::PTR,
  373. /*original_domain_name=*/kName,
  374. /*request_port=*/0, &results),
  375. DnsResponseResultExtractor::ExtractionError::kOk);
  376. EXPECT_THAT(results.error(), test::IsOk());
  377. // Order between separate records is undefined.
  378. EXPECT_THAT(results.hostnames(),
  379. testing::Optional(testing::UnorderedElementsAre(
  380. HostPortPair("foo.com", 0), HostPortPair("bar.com", 0))));
  381. }
  382. TEST(DnsResponseResultExtractorTest, ExtractsNxdomainPtrResponses) {
  383. constexpr char kName[] = "name.test";
  384. constexpr auto kTtl = base::Hours(5);
  385. DnsResponse response = BuildTestDnsResponse(
  386. kName, dns_protocol::kTypePTR, /*answers=*/{},
  387. /*authority=*/
  388. {BuildTestDnsRecord(kName, dns_protocol::kTypeSOA, "fake rdata", kTtl)},
  389. /*additional=*/{}, dns_protocol::kRcodeNXDOMAIN);
  390. DnsResponseResultExtractor extractor(&response);
  391. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  392. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::PTR,
  393. /*original_domain_name=*/kName,
  394. /*request_port=*/0, &results),
  395. DnsResponseResultExtractor::ExtractionError::kOk);
  396. EXPECT_THAT(results.error(), test::IsError(ERR_NAME_NOT_RESOLVED));
  397. EXPECT_THAT(results.hostnames(), testing::Optional(testing::IsEmpty()));
  398. ASSERT_TRUE(results.has_ttl());
  399. EXPECT_EQ(results.ttl(), kTtl);
  400. }
  401. TEST(DnsResponseResultExtractorTest, ExtractsNodataPtrResponses) {
  402. constexpr char kName[] = "name.test";
  403. constexpr auto kTtl = base::Minutes(50);
  404. DnsResponse response = BuildTestDnsResponse(
  405. kName, dns_protocol::kTypePTR, /*answers=*/{},
  406. /*authority=*/
  407. {BuildTestDnsRecord(kName, dns_protocol::kTypeSOA, "fake rdata", kTtl)});
  408. DnsResponseResultExtractor extractor(&response);
  409. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  410. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::PTR,
  411. /*original_domain_name=*/kName,
  412. /*request_port=*/0, &results),
  413. DnsResponseResultExtractor::ExtractionError::kOk);
  414. EXPECT_THAT(results.error(), test::IsError(ERR_NAME_NOT_RESOLVED));
  415. EXPECT_THAT(results.hostnames(), testing::Optional(testing::IsEmpty()));
  416. ASSERT_TRUE(results.has_ttl());
  417. EXPECT_EQ(results.ttl(), kTtl);
  418. }
  419. TEST(DnsResponseResultExtractorTest, RejectsMalformedPtrRecord) {
  420. constexpr char kName[] = "name.test";
  421. DnsResponse response = BuildTestDnsResponse(
  422. kName, dns_protocol::kTypePTR,
  423. {BuildTestDnsRecord(kName, dns_protocol::kTypePTR,
  424. "malformed rdata")} /* answers */);
  425. DnsResponseResultExtractor extractor(&response);
  426. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  427. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::PTR,
  428. /*original_domain_name=*/kName,
  429. /*request_port=*/0, &results),
  430. DnsResponseResultExtractor::ExtractionError::kMalformedRecord);
  431. EXPECT_THAT(results.error(), test::IsError(ERR_DNS_MALFORMED_RESPONSE));
  432. EXPECT_FALSE(results.has_ttl());
  433. }
  434. TEST(DnsResponseResultExtractorTest, RejectsWrongNamePtrRecord) {
  435. constexpr char kName[] = "name.test";
  436. DnsResponse response = BuildTestDnsPointerResponse(
  437. kName, {"foo.com", "bar.com"}, "different.test");
  438. DnsResponseResultExtractor extractor(&response);
  439. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  440. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::PTR,
  441. /*original_domain_name=*/kName,
  442. /*request_port=*/0, &results),
  443. DnsResponseResultExtractor::ExtractionError::kNameMismatch);
  444. EXPECT_THAT(results.error(), test::IsError(ERR_DNS_MALFORMED_RESPONSE));
  445. EXPECT_FALSE(results.has_ttl());
  446. }
  447. TEST(DnsResponseResultExtractorTest, IgnoresWrongTypePtrResponses) {
  448. constexpr char kName[] = "name.test";
  449. DnsResponse response = BuildTestDnsResponse(
  450. kName, dns_protocol::kTypePTR,
  451. {BuildTestAddressRecord(kName, IPAddress(1, 2, 3, 4))});
  452. DnsResponseResultExtractor extractor(&response);
  453. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  454. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::PTR,
  455. /*original_domain_name=*/kName,
  456. /*request_port=*/0, &results),
  457. DnsResponseResultExtractor::ExtractionError::kOk);
  458. EXPECT_THAT(results.error(), test::IsError(ERR_NAME_NOT_RESOLVED));
  459. EXPECT_THAT(results.hostnames(), testing::Optional(testing::IsEmpty()));
  460. EXPECT_FALSE(results.has_ttl());
  461. }
  462. TEST(DnsResponseResultExtractorTest, ExtractsSrvResponses) {
  463. constexpr char kName[] = "name.test";
  464. const TestServiceRecord kRecord1 = {2, 3, 1223, "foo.com"};
  465. const TestServiceRecord kRecord2 = {5, 10, 80, "bar.com"};
  466. const TestServiceRecord kRecord3 = {5, 1, 5, "google.com"};
  467. const TestServiceRecord kRecord4 = {2, 100, 12345, "chromium.org"};
  468. DnsResponse response = BuildTestDnsServiceResponse(
  469. kName, {kRecord1, kRecord2, kRecord3, kRecord4});
  470. DnsResponseResultExtractor extractor(&response);
  471. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  472. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::SRV,
  473. /*original_domain_name=*/kName,
  474. /*request_port=*/0, &results),
  475. DnsResponseResultExtractor::ExtractionError::kOk);
  476. EXPECT_THAT(results.error(), test::IsOk());
  477. // Expect ordered by priority, and random within a priority.
  478. absl::optional<std::vector<HostPortPair>> result_hosts = results.hostnames();
  479. ASSERT_THAT(
  480. result_hosts,
  481. testing::Optional(testing::UnorderedElementsAre(
  482. HostPortPair("foo.com", 1223), HostPortPair("bar.com", 80),
  483. HostPortPair("google.com", 5), HostPortPair("chromium.org", 12345))));
  484. auto priority2 = std::vector<HostPortPair>(result_hosts.value().begin(),
  485. result_hosts.value().begin() + 2);
  486. EXPECT_THAT(priority2, testing::UnorderedElementsAre(
  487. HostPortPair("foo.com", 1223),
  488. HostPortPair("chromium.org", 12345)));
  489. auto priority5 = std::vector<HostPortPair>(result_hosts.value().begin() + 2,
  490. result_hosts.value().end());
  491. EXPECT_THAT(priority5,
  492. testing::UnorderedElementsAre(HostPortPair("bar.com", 80),
  493. HostPortPair("google.com", 5)));
  494. }
  495. // 0-weight services are allowed. Ensure that we can handle such records,
  496. // especially the case where all entries have weight 0.
  497. TEST(DnsResponseResultExtractorTest, ExtractsZeroWeightSrvResponses) {
  498. constexpr char kName[] = "name.test";
  499. const TestServiceRecord kRecord1 = {5, 0, 80, "bar.com"};
  500. const TestServiceRecord kRecord2 = {5, 0, 5, "google.com"};
  501. DnsResponse response =
  502. BuildTestDnsServiceResponse(kName, {kRecord1, kRecord2});
  503. DnsResponseResultExtractor extractor(&response);
  504. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  505. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::SRV,
  506. /*original_domain_name=*/kName,
  507. /*request_port=*/0, &results),
  508. DnsResponseResultExtractor::ExtractionError::kOk);
  509. EXPECT_THAT(results.error(), test::IsOk());
  510. // Expect ordered by priority, and random within a priority.
  511. EXPECT_THAT(results.hostnames(),
  512. testing::Optional(testing::UnorderedElementsAre(
  513. HostPortPair("bar.com", 80), HostPortPair("google.com", 5))));
  514. }
  515. TEST(DnsResponseResultExtractorTest, ExtractsNxdomainSrvResponses) {
  516. constexpr char kName[] = "name.test";
  517. constexpr auto kTtl = base::Days(7);
  518. DnsResponse response = BuildTestDnsResponse(
  519. kName, dns_protocol::kTypeSRV, /*answers=*/{},
  520. /*authority=*/
  521. {BuildTestDnsRecord(kName, dns_protocol::kTypeSOA, "fake rdata", kTtl)},
  522. /*additional=*/{}, dns_protocol::kRcodeNXDOMAIN);
  523. DnsResponseResultExtractor extractor(&response);
  524. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  525. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::SRV,
  526. /*original_domain_name=*/kName,
  527. /*request_port=*/0, &results),
  528. DnsResponseResultExtractor::ExtractionError::kOk);
  529. EXPECT_THAT(results.error(), test::IsError(ERR_NAME_NOT_RESOLVED));
  530. EXPECT_THAT(results.hostnames(), testing::Optional(testing::IsEmpty()));
  531. ASSERT_TRUE(results.has_ttl());
  532. EXPECT_EQ(results.ttl(), kTtl);
  533. }
  534. TEST(DnsResponseResultExtractorTest, ExtractsNodataSrvResponses) {
  535. constexpr char kName[] = "name.test";
  536. constexpr auto kTtl = base::Hours(12);
  537. DnsResponse response = BuildTestDnsResponse(
  538. kName, dns_protocol::kTypeSRV, /*answers=*/{},
  539. /*authority=*/
  540. {BuildTestDnsRecord(kName, dns_protocol::kTypeSOA, "fake rdata", kTtl)});
  541. DnsResponseResultExtractor extractor(&response);
  542. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  543. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::SRV,
  544. /*original_domain_name=*/kName,
  545. /*request_port=*/0, &results),
  546. DnsResponseResultExtractor::ExtractionError::kOk);
  547. EXPECT_THAT(results.error(), test::IsError(ERR_NAME_NOT_RESOLVED));
  548. EXPECT_THAT(results.hostnames(), testing::Optional(testing::IsEmpty()));
  549. ASSERT_TRUE(results.has_ttl());
  550. EXPECT_EQ(results.ttl(), kTtl);
  551. }
  552. TEST(DnsResponseResultExtractorTest, RejectsMalformedSrvRecord) {
  553. constexpr char kName[] = "name.test";
  554. DnsResponse response = BuildTestDnsResponse(
  555. kName, dns_protocol::kTypeSRV,
  556. {BuildTestDnsRecord(kName, dns_protocol::kTypeSRV,
  557. "malformed rdata")} /* answers */);
  558. DnsResponseResultExtractor extractor(&response);
  559. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  560. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::SRV,
  561. /*original_domain_name=*/kName,
  562. /*request_port=*/0, &results),
  563. DnsResponseResultExtractor::ExtractionError::kMalformedRecord);
  564. EXPECT_THAT(results.error(), test::IsError(ERR_DNS_MALFORMED_RESPONSE));
  565. EXPECT_FALSE(results.has_ttl());
  566. }
  567. TEST(DnsResponseResultExtractorTest, RejectsWrongNameSrvRecord) {
  568. constexpr char kName[] = "name.test";
  569. const TestServiceRecord kRecord = {2, 3, 1223, "foo.com"};
  570. DnsResponse response =
  571. BuildTestDnsServiceResponse(kName, {kRecord}, "different.test");
  572. DnsResponseResultExtractor extractor(&response);
  573. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  574. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::SRV,
  575. /*original_domain_name=*/kName,
  576. /*request_port=*/0, &results),
  577. DnsResponseResultExtractor::ExtractionError::kNameMismatch);
  578. EXPECT_THAT(results.error(), test::IsError(ERR_DNS_MALFORMED_RESPONSE));
  579. EXPECT_FALSE(results.has_ttl());
  580. }
  581. TEST(DnsResponseResultExtractorTest, IgnoresWrongTypeSrvResponses) {
  582. constexpr char kName[] = "name.test";
  583. DnsResponse response = BuildTestDnsResponse(
  584. kName, dns_protocol::kTypeSRV,
  585. {BuildTestAddressRecord(kName, IPAddress(1, 2, 3, 4))});
  586. DnsResponseResultExtractor extractor(&response);
  587. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  588. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::SRV,
  589. /*original_domain_name=*/kName,
  590. /*request_port=*/0, &results),
  591. DnsResponseResultExtractor::ExtractionError::kOk);
  592. EXPECT_THAT(results.error(), test::IsError(ERR_NAME_NOT_RESOLVED));
  593. EXPECT_THAT(results.hostnames(), testing::Optional(testing::IsEmpty()));
  594. EXPECT_FALSE(results.has_ttl());
  595. }
  596. TEST(DnsResponseResultExtractorTest, ExtractsExperimentalHttpsResponses) {
  597. constexpr char kName[] = "https.test";
  598. constexpr auto kTtl = base::Minutes(31);
  599. DnsResponse response = BuildTestDnsResponse(
  600. kName, dns_protocol::kTypeHttps,
  601. {BuildTestHttpsAliasRecord(kName, "alias.test", kTtl)});
  602. DnsResponseResultExtractor extractor(&response);
  603. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  604. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS_EXPERIMENTAL,
  605. /*original_domain_name=*/kName,
  606. /*request_port=*/0, &results),
  607. DnsResponseResultExtractor::ExtractionError::kOk);
  608. EXPECT_THAT(results.error(), test::IsOk());
  609. EXPECT_THAT(results.https_record_compatibility(),
  610. testing::Pointee(testing::ElementsAre(true)));
  611. ASSERT_TRUE(results.has_ttl());
  612. EXPECT_EQ(results.ttl(), kTtl);
  613. }
  614. TEST(DnsResponseResultExtractorTest,
  615. ExtractsNxdomainExperimentalHttpsResponses) {
  616. constexpr char kName[] = "https.test";
  617. constexpr auto kTtl = base::Hours(8);
  618. DnsResponse response = BuildTestDnsResponse(
  619. kName, dns_protocol::kTypeHttps, /*answers=*/{},
  620. /*authority=*/
  621. {BuildTestDnsRecord(kName, dns_protocol::kTypeSOA, "fake rdata", kTtl)},
  622. /*additional=*/{}, dns_protocol::kRcodeNXDOMAIN);
  623. DnsResponseResultExtractor extractor(&response);
  624. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  625. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS_EXPERIMENTAL,
  626. /*original_domain_name=*/kName,
  627. /*request_port=*/0, &results),
  628. DnsResponseResultExtractor::ExtractionError::kOk);
  629. EXPECT_THAT(results.error(), test::IsError(ERR_NAME_NOT_RESOLVED));
  630. EXPECT_THAT(results.https_record_compatibility(),
  631. testing::Pointee(testing::IsEmpty()));
  632. ASSERT_TRUE(results.has_ttl());
  633. EXPECT_EQ(results.ttl(), kTtl);
  634. }
  635. TEST(DnsResponseResultExtractorTest, ExtractsNodataExperimentalHttpsResponses) {
  636. constexpr char kName[] = "https.test";
  637. constexpr auto kTtl = base::Days(3);
  638. DnsResponse response = BuildTestDnsResponse(
  639. kName, dns_protocol::kTypeHttps, /*answers=*/{},
  640. /*authority=*/
  641. {BuildTestDnsRecord(kName, dns_protocol::kTypeSOA, "fake rdata", kTtl)});
  642. DnsResponseResultExtractor extractor(&response);
  643. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  644. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS_EXPERIMENTAL,
  645. /*original_domain_name=*/kName,
  646. /*request_port=*/0, &results),
  647. DnsResponseResultExtractor::ExtractionError::kOk);
  648. EXPECT_THAT(results.error(), test::IsError(ERR_NAME_NOT_RESOLVED));
  649. EXPECT_THAT(results.https_record_compatibility(),
  650. testing::Pointee(testing::IsEmpty()));
  651. ASSERT_TRUE(results.has_ttl());
  652. EXPECT_EQ(results.ttl(), kTtl);
  653. }
  654. TEST(DnsResponseResultExtractorTest, RejectsMalformedExperimentalHttpsRecord) {
  655. constexpr char kName[] = "https.test";
  656. DnsResponse response = BuildTestDnsResponse(
  657. kName, dns_protocol::kTypeHttps,
  658. {BuildTestDnsRecord(kName, dns_protocol::kTypeHttps,
  659. "malformed rdata")} /* answers */);
  660. DnsResponseResultExtractor extractor(&response);
  661. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  662. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS_EXPERIMENTAL,
  663. /*original_domain_name=*/kName,
  664. /*request_port=*/0, &results),
  665. DnsResponseResultExtractor::ExtractionError::kMalformedRecord);
  666. EXPECT_THAT(results.error(), test::IsError(ERR_DNS_MALFORMED_RESPONSE));
  667. EXPECT_FALSE(results.has_ttl());
  668. }
  669. TEST(DnsResponseResultExtractorTest, RejectsWrongNameExperimentalHttpsRecord) {
  670. constexpr char kName[] = "https.test";
  671. DnsResponse response = BuildTestDnsResponse(
  672. kName, dns_protocol::kTypeHttps,
  673. {BuildTestHttpsAliasRecord("different.test", "alias.test")});
  674. DnsResponseResultExtractor extractor(&response);
  675. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  676. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS_EXPERIMENTAL,
  677. /*original_domain_name=*/kName,
  678. /*request_port=*/0, &results),
  679. DnsResponseResultExtractor::ExtractionError::kNameMismatch);
  680. EXPECT_THAT(results.error(), test::IsError(ERR_DNS_MALFORMED_RESPONSE));
  681. EXPECT_FALSE(results.has_ttl());
  682. }
  683. TEST(DnsResponseResultExtractorTest,
  684. IgnoresWrongTypeExperimentalHttpsResponses) {
  685. constexpr char kName[] = "https.test";
  686. DnsResponse response = BuildTestDnsResponse(
  687. kName, dns_protocol::kTypeHttps,
  688. {BuildTestAddressRecord(kName, IPAddress(1, 2, 3, 4))});
  689. DnsResponseResultExtractor extractor(&response);
  690. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  691. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS_EXPERIMENTAL,
  692. /*original_domain_name=*/kName,
  693. /*request_port=*/0, &results),
  694. DnsResponseResultExtractor::ExtractionError::kOk);
  695. EXPECT_THAT(results.error(), test::IsError(ERR_NAME_NOT_RESOLVED));
  696. EXPECT_THAT(results.https_record_compatibility(),
  697. testing::Pointee(testing::IsEmpty()));
  698. EXPECT_FALSE(results.has_ttl());
  699. }
  700. TEST(DnsResponseResultExtractorTest,
  701. IgnoresAdditionalExperimentalHttpsRecords) {
  702. constexpr char kName[] = "https.test";
  703. constexpr auto kTtl = base::Days(3);
  704. DnsResponse response = BuildTestDnsResponse(
  705. kName, dns_protocol::kTypeHttps,
  706. /*answers=*/{BuildTestHttpsAliasRecord(kName, "alias.test", kTtl)},
  707. /*authority=*/{},
  708. /*additional=*/
  709. {BuildTestHttpsServiceRecord(kName, 3u, "service1.test", {},
  710. base::Minutes(44)),
  711. BuildTestHttpsServiceRecord(kName, 2u, "service2.test", {},
  712. base::Minutes(30))});
  713. DnsResponseResultExtractor extractor(&response);
  714. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  715. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS_EXPERIMENTAL,
  716. /*original_domain_name=*/kName,
  717. /*request_port=*/0, &results),
  718. DnsResponseResultExtractor::ExtractionError::kOk);
  719. EXPECT_THAT(results.error(), test::IsOk());
  720. EXPECT_THAT(results.https_record_compatibility(),
  721. testing::Pointee(testing::ElementsAre(true)));
  722. ASSERT_TRUE(results.has_ttl());
  723. EXPECT_EQ(results.ttl(), kTtl);
  724. }
  725. TEST(DnsResponseResultExtractorTest, ExtractsBasicHttpsResponses) {
  726. constexpr char kName[] = "https.test";
  727. constexpr auto kTtl = base::Hours(12);
  728. DnsResponse response =
  729. BuildTestDnsResponse(kName, dns_protocol::kTypeHttps,
  730. {BuildTestHttpsServiceRecord(kName, /*priority=*/4,
  731. /*service_name=*/".",
  732. /*params=*/{}, kTtl)});
  733. DnsResponseResultExtractor extractor(&response);
  734. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  735. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS,
  736. /*original_domain_name=*/kName,
  737. /*request_port=*/0, &results),
  738. DnsResponseResultExtractor::ExtractionError::kOk);
  739. EXPECT_THAT(results.error(), test::IsOk());
  740. EXPECT_THAT(
  741. results.GetMetadatas(),
  742. testing::Optional(testing::ElementsAre(ExpectConnectionEndpointMetadata(
  743. testing::ElementsAre(dns_protocol::kHttpsServiceDefaultAlpn),
  744. testing::IsEmpty(), kName))));
  745. EXPECT_THAT(results.https_record_compatibility(),
  746. testing::Pointee(testing::ElementsAre(true)));
  747. ASSERT_TRUE(results.has_ttl());
  748. EXPECT_EQ(results.ttl(), kTtl);
  749. }
  750. TEST(DnsResponseResultExtractorTest, ExtractsComprehensiveHttpsResponses) {
  751. constexpr char kName[] = "https.test";
  752. constexpr char kAlpn[] = "foo";
  753. constexpr uint8_t kEchConfig[] = "EEEEEEEEECH!";
  754. constexpr auto kTtl = base::Hours(12);
  755. DnsResponse response = BuildTestDnsResponse(
  756. kName, dns_protocol::kTypeHttps,
  757. {BuildTestHttpsServiceRecord(
  758. kName, /*priority=*/4,
  759. /*service_name=*/".",
  760. /*params=*/
  761. {BuildTestHttpsServiceAlpnParam({kAlpn}),
  762. BuildTestHttpsServiceEchConfigParam(kEchConfig)},
  763. kTtl),
  764. BuildTestHttpsServiceRecord(
  765. kName, /*priority=*/3,
  766. /*service_name=*/".",
  767. /*params=*/
  768. {BuildTestHttpsServiceAlpnParam({kAlpn}),
  769. {dns_protocol::kHttpsServiceParamKeyNoDefaultAlpn, ""}},
  770. /*ttl=*/base::Days(3))});
  771. DnsResponseResultExtractor extractor(&response);
  772. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  773. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS,
  774. /*original_domain_name=*/kName,
  775. /*request_port=*/0, &results),
  776. DnsResponseResultExtractor::ExtractionError::kOk);
  777. EXPECT_THAT(results.error(), test::IsOk());
  778. EXPECT_THAT(results.GetMetadatas(),
  779. testing::Optional(testing::ElementsAre(
  780. ExpectConnectionEndpointMetadata(testing::ElementsAre(kAlpn),
  781. testing::IsEmpty(), kName),
  782. ExpectConnectionEndpointMetadata(
  783. testing::ElementsAre(
  784. kAlpn, dns_protocol::kHttpsServiceDefaultAlpn),
  785. testing::ElementsAreArray(kEchConfig), kName))));
  786. EXPECT_THAT(results.https_record_compatibility(),
  787. testing::Pointee(testing::ElementsAre(true, true)));
  788. ASSERT_TRUE(results.has_ttl());
  789. EXPECT_EQ(results.ttl(), kTtl);
  790. }
  791. TEST(DnsResponseResultExtractorTest, IgnoresHttpsResponseWithAlias) {
  792. constexpr char kName[] = "https.test";
  793. DnsResponse response =
  794. BuildTestDnsResponse(kName, dns_protocol::kTypeHttps,
  795. {BuildTestHttpsServiceRecord(kName, /*priority=*/4,
  796. /*service_name=*/".",
  797. /*params=*/{}),
  798. BuildTestHttpsAliasRecord(kName, "alias.test")});
  799. DnsResponseResultExtractor extractor(&response);
  800. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  801. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS,
  802. /*original_domain_name=*/kName,
  803. /*request_port=*/0, &results),
  804. DnsResponseResultExtractor::ExtractionError::kOk);
  805. EXPECT_THAT(results.error(), test::IsError(ERR_NAME_NOT_RESOLVED));
  806. EXPECT_THAT(results.GetMetadatas(), testing::Optional(testing::IsEmpty()));
  807. // Expected to still output record compatibility for otherwise-ignored records
  808. EXPECT_THAT(results.https_record_compatibility(),
  809. testing::Pointee(testing::ElementsAre(true, true)));
  810. }
  811. // Expect the entire response to be ignored if all HTTPS records have the
  812. // "no-default-alpn" param.
  813. TEST(DnsResponseResultExtractorTest, IgnoresHttpsResponseWithNoDefaultAlpn) {
  814. constexpr char kName[] = "https.test";
  815. DnsResponse response = BuildTestDnsResponse(
  816. kName, dns_protocol::kTypeHttps,
  817. {BuildTestHttpsServiceRecord(
  818. kName, /*priority=*/4,
  819. /*service_name=*/".",
  820. /*params=*/
  821. {BuildTestHttpsServiceAlpnParam({"foo1"}),
  822. {dns_protocol::kHttpsServiceParamKeyNoDefaultAlpn, ""}}),
  823. BuildTestHttpsServiceRecord(
  824. kName, /*priority=*/5,
  825. /*service_name=*/".",
  826. /*params=*/
  827. {BuildTestHttpsServiceAlpnParam({"foo2"}),
  828. {dns_protocol::kHttpsServiceParamKeyNoDefaultAlpn, ""}})});
  829. DnsResponseResultExtractor extractor(&response);
  830. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  831. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS,
  832. /*original_domain_name=*/kName,
  833. /*request_port=*/0, &results),
  834. DnsResponseResultExtractor::ExtractionError::kOk);
  835. EXPECT_THAT(results.error(), test::IsError(ERR_NAME_NOT_RESOLVED));
  836. EXPECT_THAT(results.GetMetadatas(), testing::Optional(testing::IsEmpty()));
  837. // Expected to still output record compatibility for otherwise-ignored records
  838. EXPECT_THAT(results.https_record_compatibility(),
  839. testing::Pointee(testing::ElementsAre(true, true)));
  840. }
  841. // Unsupported/unknown HTTPS params are simply ignored if not marked mandatory.
  842. TEST(DnsResponseResultExtractorTest, IgnoresUnsupportedParamsInHttpsRecord) {
  843. constexpr char kName[] = "https.test";
  844. constexpr uint16_t kMadeUpParamKey = 65500; // From the private-use block.
  845. DnsResponse response = BuildTestDnsResponse(
  846. kName, dns_protocol::kTypeHttps,
  847. {BuildTestHttpsServiceRecord(kName, /*priority=*/4,
  848. /*service_name=*/".",
  849. /*params=*/
  850. {{kMadeUpParamKey, "foo"}})});
  851. DnsResponseResultExtractor extractor(&response);
  852. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  853. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS,
  854. /*original_domain_name=*/kName,
  855. /*request_port=*/0, &results),
  856. DnsResponseResultExtractor::ExtractionError::kOk);
  857. EXPECT_THAT(results.error(), test::IsOk());
  858. EXPECT_THAT(
  859. results.GetMetadatas(),
  860. testing::Optional(testing::ElementsAre(ExpectConnectionEndpointMetadata(
  861. testing::ElementsAre(dns_protocol::kHttpsServiceDefaultAlpn),
  862. testing::IsEmpty(), kName))));
  863. EXPECT_THAT(results.https_record_compatibility(),
  864. testing::Pointee(testing::ElementsAre(true)));
  865. }
  866. // Entire record is dropped if an unsupported/unknown HTTPS param is marked
  867. // mandatory.
  868. TEST(DnsResponseResultExtractorTest,
  869. IgnoresHttpsRecordWithUnsupportedMandatoryParam) {
  870. constexpr char kName[] = "https.test";
  871. constexpr uint16_t kMadeUpParamKey = 65500; // From the private-use block.
  872. DnsResponse response = BuildTestDnsResponse(
  873. kName, dns_protocol::kTypeHttps,
  874. {BuildTestHttpsServiceRecord(
  875. kName, /*priority=*/4,
  876. /*service_name=*/".",
  877. /*params=*/
  878. {BuildTestHttpsServiceAlpnParam({"ignored_alpn"}),
  879. BuildTestHttpsServiceMandatoryParam({kMadeUpParamKey}),
  880. {kMadeUpParamKey, "foo"}}),
  881. BuildTestHttpsServiceRecord(
  882. kName, /*priority=*/5,
  883. /*service_name=*/".",
  884. /*params=*/{BuildTestHttpsServiceAlpnParam({"foo"})})});
  885. DnsResponseResultExtractor extractor(&response);
  886. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  887. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS,
  888. /*original_domain_name=*/kName,
  889. /*request_port=*/0, &results),
  890. DnsResponseResultExtractor::ExtractionError::kOk);
  891. EXPECT_THAT(results.error(), test::IsOk());
  892. EXPECT_THAT(
  893. results.GetMetadatas(),
  894. testing::Optional(testing::ElementsAre(ExpectConnectionEndpointMetadata(
  895. testing::ElementsAre("foo", dns_protocol::kHttpsServiceDefaultAlpn),
  896. testing::IsEmpty(), kName))));
  897. EXPECT_THAT(results.https_record_compatibility(),
  898. testing::Pointee(testing::ElementsAre(false, true)));
  899. }
  900. TEST(DnsResponseResultExtractorTest,
  901. ExtractsHttpsRecordWithMatchingServiceName) {
  902. constexpr char kName[] = "https.test";
  903. DnsResponse response = BuildTestDnsResponse(
  904. kName, dns_protocol::kTypeHttps,
  905. {BuildTestHttpsServiceRecord(kName, /*priority=*/4,
  906. /*service_name=*/kName,
  907. /*params=*/
  908. {BuildTestHttpsServiceAlpnParam({"foo"})})});
  909. DnsResponseResultExtractor extractor(&response);
  910. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  911. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS,
  912. /*original_domain_name=*/kName,
  913. /*request_port=*/0, &results),
  914. DnsResponseResultExtractor::ExtractionError::kOk);
  915. EXPECT_THAT(results.error(), test::IsOk());
  916. EXPECT_THAT(
  917. results.GetMetadatas(),
  918. testing::Optional(testing::ElementsAre(ExpectConnectionEndpointMetadata(
  919. testing::ElementsAre("foo", dns_protocol::kHttpsServiceDefaultAlpn),
  920. testing::IsEmpty(), kName))));
  921. EXPECT_THAT(results.https_record_compatibility(),
  922. testing::Pointee(testing::ElementsAre(true)));
  923. }
  924. TEST(DnsResponseResultExtractorTest,
  925. ExtractsHttpsRecordWithMatchingDefaultServiceName) {
  926. constexpr char kName[] = "https.test";
  927. DnsResponse response = BuildTestDnsResponse(
  928. kName, dns_protocol::kTypeHttps,
  929. {BuildTestHttpsServiceRecord(kName, /*priority=*/4,
  930. /*service_name=*/".",
  931. /*params=*/
  932. {BuildTestHttpsServiceAlpnParam({"foo"})})});
  933. DnsResponseResultExtractor extractor(&response);
  934. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  935. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS,
  936. /*original_domain_name=*/kName,
  937. /*request_port=*/0, &results),
  938. DnsResponseResultExtractor::ExtractionError::kOk);
  939. EXPECT_THAT(results.error(), test::IsOk());
  940. EXPECT_THAT(
  941. results.GetMetadatas(),
  942. testing::Optional(testing::ElementsAre(ExpectConnectionEndpointMetadata(
  943. testing::ElementsAre("foo", dns_protocol::kHttpsServiceDefaultAlpn),
  944. testing::IsEmpty(), kName))));
  945. EXPECT_THAT(results.https_record_compatibility(),
  946. testing::Pointee(testing::ElementsAre(true)));
  947. }
  948. TEST(DnsResponseResultExtractorTest,
  949. ExtractsHttpsRecordWithPrefixedNameAndMatchingServiceName) {
  950. constexpr char kName[] = "https.test";
  951. constexpr char kPrefixedName[] = "_444._https.https.test";
  952. DnsResponse response = BuildTestDnsResponse(
  953. kPrefixedName, dns_protocol::kTypeHttps,
  954. {BuildTestHttpsServiceRecord(kPrefixedName, /*priority=*/4,
  955. /*service_name=*/kName,
  956. /*params=*/
  957. {BuildTestHttpsServiceAlpnParam({"foo"})})});
  958. DnsResponseResultExtractor extractor(&response);
  959. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  960. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS,
  961. /*original_domain_name=*/kName,
  962. /*request_port=*/0, &results),
  963. DnsResponseResultExtractor::ExtractionError::kOk);
  964. EXPECT_THAT(results.error(), test::IsOk());
  965. EXPECT_THAT(
  966. results.GetMetadatas(),
  967. testing::Optional(testing::ElementsAre(ExpectConnectionEndpointMetadata(
  968. testing::ElementsAre("foo", dns_protocol::kHttpsServiceDefaultAlpn),
  969. testing::IsEmpty(), kName))));
  970. EXPECT_THAT(results.https_record_compatibility(),
  971. testing::Pointee(testing::ElementsAre(true)));
  972. }
  973. TEST(DnsResponseResultExtractorTest,
  974. ExtractsHttpsRecordWithAliasingAndMatchingServiceName) {
  975. constexpr char kName[] = "https.test";
  976. DnsResponse response = BuildTestDnsResponse(
  977. kName, dns_protocol::kTypeHttps,
  978. {BuildTestCnameRecord(kName, "alias.test"),
  979. BuildTestHttpsServiceRecord("alias.test", /*priority=*/4,
  980. /*service_name=*/kName,
  981. /*params=*/
  982. {BuildTestHttpsServiceAlpnParam({"foo"})})});
  983. DnsResponseResultExtractor extractor(&response);
  984. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  985. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS,
  986. /*original_domain_name=*/kName,
  987. /*request_port=*/0, &results),
  988. DnsResponseResultExtractor::ExtractionError::kOk);
  989. EXPECT_THAT(results.error(), test::IsOk());
  990. EXPECT_THAT(
  991. results.GetMetadatas(),
  992. testing::Optional(testing::ElementsAre(ExpectConnectionEndpointMetadata(
  993. testing::ElementsAre("foo", dns_protocol::kHttpsServiceDefaultAlpn),
  994. testing::IsEmpty(), kName))));
  995. EXPECT_THAT(results.https_record_compatibility(),
  996. testing::Pointee(testing::ElementsAre(true)));
  997. }
  998. TEST(DnsResponseResultExtractorTest,
  999. IgnoreHttpsRecordWithNonMatchingServiceName) {
  1000. constexpr char kName[] = "https.test";
  1001. DnsResponse response = BuildTestDnsResponse(
  1002. kName, dns_protocol::kTypeHttps,
  1003. {BuildTestHttpsServiceRecord(
  1004. kName, /*priority=*/4,
  1005. /*service_name=*/"other.service.test",
  1006. /*params=*/
  1007. {BuildTestHttpsServiceAlpnParam({"ignored"})}),
  1008. BuildTestHttpsServiceRecord("https.test", /*priority=*/5,
  1009. /*service_name=*/".",
  1010. /*params=*/
  1011. {BuildTestHttpsServiceAlpnParam({"foo"})})});
  1012. DnsResponseResultExtractor extractor(&response);
  1013. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1014. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS,
  1015. /*original_domain_name=*/kName,
  1016. /*request_port=*/0, &results),
  1017. DnsResponseResultExtractor::ExtractionError::kOk);
  1018. EXPECT_THAT(results.error(), test::IsOk());
  1019. EXPECT_THAT(
  1020. results.GetMetadatas(),
  1021. testing::Optional(testing::ElementsAre(ExpectConnectionEndpointMetadata(
  1022. testing::ElementsAre("foo", dns_protocol::kHttpsServiceDefaultAlpn),
  1023. testing::IsEmpty(), kName))));
  1024. EXPECT_THAT(results.https_record_compatibility(),
  1025. testing::Pointee(testing::ElementsAre(true, true)));
  1026. }
  1027. TEST(DnsResponseResultExtractorTest,
  1028. ExtractsHttpsRecordWithPrefixedNameAndDefaultServiceName) {
  1029. constexpr char kPrefixedName[] = "_445._https.https.test";
  1030. DnsResponse response = BuildTestDnsResponse(
  1031. kPrefixedName, dns_protocol::kTypeHttps,
  1032. {BuildTestHttpsServiceRecord(kPrefixedName, /*priority=*/4,
  1033. /*service_name=*/".",
  1034. /*params=*/
  1035. {BuildTestHttpsServiceAlpnParam({"foo"})})});
  1036. DnsResponseResultExtractor extractor(&response);
  1037. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1038. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS,
  1039. /*original_domain_name=*/"https.test",
  1040. /*request_port=*/0, &results),
  1041. DnsResponseResultExtractor::ExtractionError::kOk);
  1042. EXPECT_THAT(results.error(), test::IsOk());
  1043. EXPECT_THAT(
  1044. results.GetMetadatas(),
  1045. testing::Optional(testing::ElementsAre(ExpectConnectionEndpointMetadata(
  1046. testing::ElementsAre("foo", dns_protocol::kHttpsServiceDefaultAlpn),
  1047. testing::IsEmpty(), kPrefixedName))));
  1048. EXPECT_THAT(results.https_record_compatibility(),
  1049. testing::Pointee(testing::ElementsAre(true)));
  1050. }
  1051. TEST(DnsResponseResultExtractorTest,
  1052. ExtractsHttpsRecordWithAliasingAndDefaultServiceName) {
  1053. constexpr char kName[] = "https.test";
  1054. DnsResponse response = BuildTestDnsResponse(
  1055. kName, dns_protocol::kTypeHttps,
  1056. {BuildTestCnameRecord(kName, "alias.test"),
  1057. BuildTestHttpsServiceRecord("alias.test", /*priority=*/4,
  1058. /*service_name=*/".",
  1059. /*params=*/
  1060. {BuildTestHttpsServiceAlpnParam({"foo"})})});
  1061. DnsResponseResultExtractor extractor(&response);
  1062. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1063. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS,
  1064. /*original_domain_name=*/kName,
  1065. /*request_port=*/0, &results),
  1066. DnsResponseResultExtractor::ExtractionError::kOk);
  1067. EXPECT_THAT(results.error(), test::IsOk());
  1068. EXPECT_THAT(
  1069. results.GetMetadatas(),
  1070. testing::Optional(testing::ElementsAre(ExpectConnectionEndpointMetadata(
  1071. testing::ElementsAre("foo", dns_protocol::kHttpsServiceDefaultAlpn),
  1072. testing::IsEmpty(), "alias.test"))));
  1073. EXPECT_THAT(results.https_record_compatibility(),
  1074. testing::Pointee(testing::ElementsAre(true)));
  1075. }
  1076. TEST(DnsResponseResultExtractorTest, ExtractsHttpsRecordWithMatchingPort) {
  1077. constexpr char kName[] = "https.test";
  1078. constexpr uint16_t kPort = 4567;
  1079. DnsResponse response = BuildTestDnsResponse(
  1080. kName, dns_protocol::kTypeHttps,
  1081. {BuildTestHttpsServiceRecord(kName, /*priority=*/4,
  1082. /*service_name=*/".",
  1083. /*params=*/
  1084. {BuildTestHttpsServiceAlpnParam({"foo"}),
  1085. BuildTestHttpsServicePortParam(kPort)})});
  1086. DnsResponseResultExtractor extractor(&response);
  1087. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1088. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS,
  1089. /*original_domain_name=*/kName,
  1090. /*request_port=*/kPort, &results),
  1091. DnsResponseResultExtractor::ExtractionError::kOk);
  1092. EXPECT_THAT(results.error(), test::IsOk());
  1093. EXPECT_THAT(
  1094. results.GetMetadatas(),
  1095. testing::Optional(testing::ElementsAre(ExpectConnectionEndpointMetadata(
  1096. testing::ElementsAre("foo", dns_protocol::kHttpsServiceDefaultAlpn),
  1097. testing::IsEmpty(), kName))));
  1098. EXPECT_THAT(results.https_record_compatibility(),
  1099. testing::Pointee(testing::ElementsAre(true)));
  1100. }
  1101. TEST(DnsResponseResultExtractorTest, IgnoresHttpsRecordWithMismatchingPort) {
  1102. constexpr char kName[] = "https.test";
  1103. DnsResponse response = BuildTestDnsResponse(
  1104. kName, dns_protocol::kTypeHttps,
  1105. {BuildTestHttpsServiceRecord(kName, /*priority=*/4,
  1106. /*service_name=*/".",
  1107. /*params=*/
  1108. {BuildTestHttpsServiceAlpnParam({"ignored"}),
  1109. BuildTestHttpsServicePortParam(1003)}),
  1110. BuildTestHttpsServiceRecord(kName, /*priority=*/4,
  1111. /*service_name=*/".",
  1112. /*params=*/
  1113. {BuildTestHttpsServiceAlpnParam({"foo"})})});
  1114. DnsResponseResultExtractor extractor(&response);
  1115. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1116. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS,
  1117. /*original_domain_name=*/kName,
  1118. /*request_port=*/55, &results),
  1119. DnsResponseResultExtractor::ExtractionError::kOk);
  1120. EXPECT_THAT(results.error(), test::IsOk());
  1121. EXPECT_THAT(
  1122. results.GetMetadatas(),
  1123. testing::Optional(testing::ElementsAre(ExpectConnectionEndpointMetadata(
  1124. testing::ElementsAre("foo", dns_protocol::kHttpsServiceDefaultAlpn),
  1125. testing::IsEmpty(), kName))));
  1126. EXPECT_THAT(results.https_record_compatibility(),
  1127. testing::Pointee(testing::ElementsAre(true, true)));
  1128. }
  1129. // HTTPS records with "no-default-alpn" but also no "alpn" are not
  1130. // "self-consistent" and should be ignored.
  1131. TEST(DnsResponseResultExtractorTest, IgnoresHttpsRecordWithNoAlpn) {
  1132. constexpr char kName[] = "https.test";
  1133. DnsResponse response = BuildTestDnsResponse(
  1134. kName, dns_protocol::kTypeHttps,
  1135. {BuildTestHttpsServiceRecord(
  1136. kName, /*priority=*/4,
  1137. /*service_name=*/".",
  1138. /*params=*/
  1139. {{dns_protocol::kHttpsServiceParamKeyNoDefaultAlpn, ""}}),
  1140. BuildTestHttpsServiceRecord(kName, /*priority=*/4,
  1141. /*service_name=*/".",
  1142. /*params=*/
  1143. {BuildTestHttpsServiceAlpnParam({"foo"})})});
  1144. DnsResponseResultExtractor extractor(&response);
  1145. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1146. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS,
  1147. /*original_domain_name=*/kName,
  1148. /*request_port=*/55, &results),
  1149. DnsResponseResultExtractor::ExtractionError::kOk);
  1150. EXPECT_THAT(results.error(), test::IsOk());
  1151. EXPECT_THAT(
  1152. results.GetMetadatas(),
  1153. testing::Optional(testing::ElementsAre(ExpectConnectionEndpointMetadata(
  1154. testing::ElementsAre("foo", dns_protocol::kHttpsServiceDefaultAlpn),
  1155. testing::IsEmpty(), kName))));
  1156. EXPECT_THAT(results.https_record_compatibility(),
  1157. testing::Pointee(testing::ElementsAre(true, true)));
  1158. }
  1159. // Expect the entire response to be ignored if all HTTPS records have the
  1160. // "no-default-alpn" param.
  1161. TEST(DnsResponseResultExtractorTest,
  1162. IgnoresHttpsResponseWithNoCompatibleDefaultAlpn) {
  1163. constexpr char kName[] = "https.test";
  1164. constexpr uint16_t kMadeUpParamKey = 65500; // From the private-use block.
  1165. DnsResponse response = BuildTestDnsResponse(
  1166. kName, dns_protocol::kTypeHttps,
  1167. {BuildTestHttpsServiceRecord(
  1168. kName, /*priority=*/4,
  1169. /*service_name=*/".",
  1170. /*params=*/
  1171. {BuildTestHttpsServiceAlpnParam({"foo1"}),
  1172. {dns_protocol::kHttpsServiceParamKeyNoDefaultAlpn, ""}}),
  1173. BuildTestHttpsServiceRecord(
  1174. kName, /*priority=*/5,
  1175. /*service_name=*/".",
  1176. /*params=*/
  1177. {BuildTestHttpsServiceAlpnParam({"foo2"}),
  1178. {dns_protocol::kHttpsServiceParamKeyNoDefaultAlpn, ""}}),
  1179. // Allows default ALPN, but ignored due to non-matching service name.
  1180. BuildTestHttpsServiceRecord(kName, /*priority=*/3,
  1181. /*service_name=*/"other.test",
  1182. /*params=*/{}),
  1183. // Allows default ALPN, but ignored due to incompatible param.
  1184. BuildTestHttpsServiceRecord(
  1185. kName, /*priority=*/6,
  1186. /*service_name=*/".",
  1187. /*params=*/
  1188. {BuildTestHttpsServiceMandatoryParam({kMadeUpParamKey}),
  1189. {kMadeUpParamKey, "foo"}}),
  1190. // Allows default ALPN, but ignored due to mismatching port.
  1191. BuildTestHttpsServiceRecord(
  1192. kName, /*priority=*/10,
  1193. /*service_name=*/".",
  1194. /*params=*/{BuildTestHttpsServicePortParam(1005)})});
  1195. DnsResponseResultExtractor extractor(&response);
  1196. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1197. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS,
  1198. /*original_domain_name=*/kName,
  1199. /*request_port=*/0, &results),
  1200. DnsResponseResultExtractor::ExtractionError::kOk);
  1201. EXPECT_THAT(results.error(), test::IsError(ERR_NAME_NOT_RESOLVED));
  1202. EXPECT_THAT(results.GetMetadatas(), testing::Optional(testing::IsEmpty()));
  1203. // Expected to still output record compatibility for otherwise-ignored records
  1204. EXPECT_THAT(
  1205. results.https_record_compatibility(),
  1206. testing::Pointee(testing::ElementsAre(true, true, true, false, true)));
  1207. }
  1208. TEST(DnsResponseResultExtractorTest, ExtractsNxdomainHttpsResponses) {
  1209. constexpr char kName[] = "https.test";
  1210. constexpr auto kTtl = base::Minutes(45);
  1211. DnsResponse response = BuildTestDnsResponse(
  1212. kName, dns_protocol::kTypeHttps, /*answers=*/{},
  1213. /*authority=*/
  1214. {BuildTestDnsRecord(kName, dns_protocol::kTypeSOA, "fake rdata", kTtl)},
  1215. /*additional=*/{}, dns_protocol::kRcodeNXDOMAIN);
  1216. DnsResponseResultExtractor extractor(&response);
  1217. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1218. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS,
  1219. /*original_domain_name=*/kName,
  1220. /*request_port=*/0, &results),
  1221. DnsResponseResultExtractor::ExtractionError::kOk);
  1222. EXPECT_THAT(results.error(), test::IsError(ERR_NAME_NOT_RESOLVED));
  1223. EXPECT_THAT(results.GetMetadatas(), testing::Optional(testing::IsEmpty()));
  1224. EXPECT_THAT(results.https_record_compatibility(),
  1225. testing::Pointee(testing::IsEmpty()));
  1226. ASSERT_TRUE(results.has_ttl());
  1227. EXPECT_EQ(results.ttl(), kTtl);
  1228. }
  1229. TEST(DnsResponseResultExtractorTest, ExtractsNodataHttpsResponses) {
  1230. constexpr char kName[] = "https.test";
  1231. constexpr auto kTtl = base::Hours(36);
  1232. DnsResponse response = BuildTestDnsResponse(
  1233. kName, dns_protocol::kTypeHttps, /*answers=*/{},
  1234. /*authority=*/
  1235. {BuildTestDnsRecord(kName, dns_protocol::kTypeSOA, "fake rdata", kTtl)});
  1236. DnsResponseResultExtractor extractor(&response);
  1237. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1238. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS,
  1239. /*original_domain_name=*/kName,
  1240. /*request_port=*/0, &results),
  1241. DnsResponseResultExtractor::ExtractionError::kOk);
  1242. EXPECT_THAT(results.error(), test::IsError(ERR_NAME_NOT_RESOLVED));
  1243. EXPECT_THAT(results.GetMetadatas(), testing::Optional(testing::IsEmpty()));
  1244. EXPECT_THAT(results.https_record_compatibility(),
  1245. testing::Pointee(testing::IsEmpty()));
  1246. ASSERT_TRUE(results.has_ttl());
  1247. EXPECT_EQ(results.ttl(), kTtl);
  1248. }
  1249. TEST(DnsResponseResultExtractorTest, RejectsMalformedHttpsRecord) {
  1250. constexpr char kName[] = "https.test";
  1251. DnsResponse response = BuildTestDnsResponse(
  1252. kName, dns_protocol::kTypeHttps,
  1253. {BuildTestDnsRecord(kName, dns_protocol::kTypeHttps,
  1254. "malformed rdata")} /* answers */);
  1255. DnsResponseResultExtractor extractor(&response);
  1256. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1257. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS,
  1258. /*original_domain_name=*/kName,
  1259. /*request_port=*/0, &results),
  1260. DnsResponseResultExtractor::ExtractionError::kMalformedRecord);
  1261. EXPECT_THAT(results.error(), test::IsError(ERR_DNS_MALFORMED_RESPONSE));
  1262. EXPECT_FALSE(results.has_ttl());
  1263. }
  1264. TEST(DnsResponseResultExtractorTest, RejectsWrongNameHttpsRecord) {
  1265. constexpr char kName[] = "https.test";
  1266. DnsResponse response = BuildTestDnsResponse(
  1267. kName, dns_protocol::kTypeHttps,
  1268. {BuildTestHttpsAliasRecord("different.test", "alias.test")});
  1269. DnsResponseResultExtractor extractor(&response);
  1270. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1271. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS,
  1272. /*original_domain_name=*/kName,
  1273. /*request_port=*/0, &results),
  1274. DnsResponseResultExtractor::ExtractionError::kNameMismatch);
  1275. EXPECT_THAT(results.error(), test::IsError(ERR_DNS_MALFORMED_RESPONSE));
  1276. EXPECT_FALSE(results.has_ttl());
  1277. }
  1278. TEST(DnsResponseResultExtractorTest, IgnoresWrongTypeHttpsResponses) {
  1279. constexpr char kName[] = "https.test";
  1280. DnsResponse response = BuildTestDnsResponse(
  1281. kName, dns_protocol::kTypeHttps,
  1282. {BuildTestAddressRecord(kName, IPAddress(1, 2, 3, 4))});
  1283. DnsResponseResultExtractor extractor(&response);
  1284. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1285. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS,
  1286. /*original_domain_name=*/kName,
  1287. /*request_port=*/0, &results),
  1288. DnsResponseResultExtractor::ExtractionError::kOk);
  1289. EXPECT_THAT(results.error(), test::IsError(ERR_NAME_NOT_RESOLVED));
  1290. EXPECT_THAT(results.GetMetadatas(), testing::Optional(testing::IsEmpty()));
  1291. EXPECT_THAT(results.https_record_compatibility(),
  1292. testing::Pointee(testing::IsEmpty()));
  1293. }
  1294. TEST(DnsResponseResultExtractorTest, IgnoresAdditionalHttpsRecords) {
  1295. constexpr char kName[] = "https.test";
  1296. constexpr auto kTtl = base::Days(5);
  1297. // Give all records an "alpn" value to help validate that only the correct
  1298. // record is used.
  1299. DnsResponse response = BuildTestDnsResponse(
  1300. kName, dns_protocol::kTypeHttps,
  1301. /*answers=*/
  1302. {BuildTestHttpsServiceRecord(kName, /*priority=*/5u,
  1303. /*service_name=*/".",
  1304. /*params=*/
  1305. {BuildTestHttpsServiceAlpnParam({"foo1"})},
  1306. kTtl)},
  1307. /*authority=*/{},
  1308. /*additional=*/
  1309. {BuildTestHttpsServiceRecord(kName, /*priority=*/3u, /*service_name=*/".",
  1310. /*params=*/
  1311. {BuildTestHttpsServiceAlpnParam({"foo2"})},
  1312. base::Minutes(44)),
  1313. BuildTestHttpsServiceRecord(kName, /*priority=*/2u, /*service_name=*/".",
  1314. /*params=*/
  1315. {BuildTestHttpsServiceAlpnParam({"foo3"})},
  1316. base::Minutes(30))});
  1317. DnsResponseResultExtractor extractor(&response);
  1318. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1319. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::HTTPS,
  1320. /*original_domain_name=*/kName,
  1321. /*request_port=*/0, &results),
  1322. DnsResponseResultExtractor::ExtractionError::kOk);
  1323. EXPECT_THAT(results.error(), test::IsOk());
  1324. EXPECT_THAT(
  1325. results.GetMetadatas(),
  1326. testing::Optional(testing::ElementsAre(ExpectConnectionEndpointMetadata(
  1327. testing::ElementsAre("foo1", dns_protocol::kHttpsServiceDefaultAlpn),
  1328. testing::IsEmpty(), kName))));
  1329. EXPECT_THAT(results.https_record_compatibility(),
  1330. testing::Pointee(testing::ElementsAre(true)));
  1331. ASSERT_TRUE(results.has_ttl());
  1332. EXPECT_EQ(results.ttl(), kTtl);
  1333. }
  1334. TEST(DnsResponseResultExtractorTest, IgnoresUnsolicitedHttpsRecords) {
  1335. constexpr char kName[] = "name.test";
  1336. DnsResponse response = BuildTestDnsResponse(
  1337. kName, dns_protocol::kTypeTXT,
  1338. {BuildTestDnsRecord(kName, dns_protocol::kTypeTXT,
  1339. "\003foo")} /* answers */,
  1340. {} /* authority */,
  1341. {BuildTestHttpsServiceRecord(
  1342. "https.test", /*priority=*/3u, /*service_name=*/".",
  1343. /*params=*/
  1344. {BuildTestHttpsServiceAlpnParam({"foo2"})}, base::Minutes(44)),
  1345. BuildTestHttpsServiceRecord("https.test", /*priority=*/2u,
  1346. /*service_name=*/".",
  1347. /*params=*/
  1348. {BuildTestHttpsServiceAlpnParam({"foo3"})},
  1349. base::Minutes(30))} /* additional */);
  1350. DnsResponseResultExtractor extractor(&response);
  1351. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1352. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::TXT,
  1353. /*original_domain_name=*/kName,
  1354. /*request_port=*/0, &results),
  1355. DnsResponseResultExtractor::ExtractionError::kOk);
  1356. EXPECT_THAT(results.error(), test::IsOk());
  1357. EXPECT_THAT(results.text_records(),
  1358. testing::Optional(testing::ElementsAre("foo")));
  1359. EXPECT_FALSE(results.GetMetadatas());
  1360. EXPECT_FALSE(results.https_record_compatibility());
  1361. }
  1362. TEST(DnsResponseResultExtractorTest, HandlesInOrderCnameChain) {
  1363. constexpr char kName[] = "first.test";
  1364. DnsResponse response =
  1365. BuildTestDnsResponse(kName, dns_protocol::kTypeTXT,
  1366. {BuildTestCnameRecord(kName, "second.test"),
  1367. BuildTestCnameRecord("second.test", "third.test"),
  1368. BuildTestCnameRecord("third.test", "fourth.test"),
  1369. BuildTestTextRecord("fourth.test", {"foo"}),
  1370. BuildTestTextRecord("fourth.test", {"bar"})});
  1371. DnsResponseResultExtractor extractor(&response);
  1372. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1373. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::TXT,
  1374. /*original_domain_name=*/kName,
  1375. /*request_port=*/0, &results),
  1376. DnsResponseResultExtractor::ExtractionError::kOk);
  1377. EXPECT_THAT(results.error(), test::IsOk());
  1378. EXPECT_THAT(results.text_records(),
  1379. testing::Optional(testing::UnorderedElementsAre("foo", "bar")));
  1380. }
  1381. TEST(DnsResponseResultExtractorTest, HandlesInOrderCnameChainTypeA) {
  1382. constexpr char kName[] = "first.test";
  1383. const IPAddress kExpected(192, 168, 0, 1);
  1384. IPEndPoint expected_endpoint(kExpected, 0 /* port */);
  1385. DnsResponse response =
  1386. BuildTestDnsResponse(kName, dns_protocol::kTypeA,
  1387. {BuildTestCnameRecord(kName, "second.test"),
  1388. BuildTestCnameRecord("second.test", "third.test"),
  1389. BuildTestCnameRecord("third.test", "fourth.test"),
  1390. BuildTestAddressRecord("fourth.test", kExpected)});
  1391. DnsResponseResultExtractor extractor(&response);
  1392. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1393. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::A,
  1394. /*original_domain_name=*/kName,
  1395. /*request_port=*/0, &results),
  1396. DnsResponseResultExtractor::ExtractionError::kOk);
  1397. EXPECT_THAT(results.error(), test::IsOk());
  1398. EXPECT_THAT(results.GetEndpoints(),
  1399. testing::Optional(testing::ElementsAre(ExpectEndpointResult(
  1400. testing::ElementsAre(expected_endpoint)))));
  1401. EXPECT_THAT(results.aliases(),
  1402. testing::Pointee(testing::UnorderedElementsAre(
  1403. "fourth.test", "third.test", "second.test", kName)));
  1404. }
  1405. TEST(DnsResponseResultExtractorTest, HandlesReverseOrderCnameChain) {
  1406. constexpr char kName[] = "first.test";
  1407. DnsResponse response =
  1408. BuildTestDnsResponse(kName, dns_protocol::kTypeTXT,
  1409. {BuildTestTextRecord("fourth.test", {"foo"}),
  1410. BuildTestCnameRecord("third.test", "fourth.test"),
  1411. BuildTestCnameRecord("second.test", "third.test"),
  1412. BuildTestCnameRecord(kName, "second.test")});
  1413. DnsResponseResultExtractor extractor(&response);
  1414. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1415. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::TXT,
  1416. /*original_domain_name=*/kName,
  1417. /*request_port=*/0, &results),
  1418. DnsResponseResultExtractor::ExtractionError::kOk);
  1419. EXPECT_THAT(results.error(), test::IsOk());
  1420. EXPECT_THAT(results.text_records(),
  1421. testing::Optional(testing::ElementsAre("foo")));
  1422. }
  1423. TEST(DnsResponseResultExtractorTest, HandlesReverseOrderCnameChainTypeA) {
  1424. constexpr char kName[] = "first.test";
  1425. const IPAddress kExpected(192, 168, 0, 1);
  1426. IPEndPoint expected_endpoint(kExpected, 0 /* port */);
  1427. DnsResponse response =
  1428. BuildTestDnsResponse(kName, dns_protocol::kTypeA,
  1429. {BuildTestAddressRecord("fourth.test", kExpected),
  1430. BuildTestCnameRecord("third.test", "fourth.test"),
  1431. BuildTestCnameRecord("second.test", "third.test"),
  1432. BuildTestCnameRecord(kName, "second.test")});
  1433. DnsResponseResultExtractor extractor(&response);
  1434. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1435. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::A,
  1436. /*original_domain_name=*/kName,
  1437. /*request_port=*/0, &results),
  1438. DnsResponseResultExtractor::ExtractionError::kOk);
  1439. EXPECT_THAT(results.error(), test::IsOk());
  1440. EXPECT_THAT(results.GetEndpoints(),
  1441. testing::Optional(testing::ElementsAre(ExpectEndpointResult(
  1442. testing::ElementsAre(expected_endpoint)))));
  1443. EXPECT_THAT(results.aliases(),
  1444. testing::Pointee(testing::UnorderedElementsAre(
  1445. "fourth.test", "third.test", "second.test", kName)));
  1446. }
  1447. TEST(DnsResponseResultExtractorTest, HandlesArbitraryOrderCnameChain) {
  1448. constexpr char kName[] = "first.test";
  1449. DnsResponse response =
  1450. BuildTestDnsResponse(kName, dns_protocol::kTypeTXT,
  1451. {BuildTestCnameRecord("second.test", "third.test"),
  1452. BuildTestTextRecord("fourth.test", {"foo"}),
  1453. BuildTestCnameRecord("third.test", "fourth.test"),
  1454. BuildTestCnameRecord(kName, "second.test")});
  1455. DnsResponseResultExtractor extractor(&response);
  1456. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1457. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::TXT,
  1458. /*original_domain_name=*/kName,
  1459. /*request_port=*/0, &results),
  1460. DnsResponseResultExtractor::ExtractionError::kOk);
  1461. EXPECT_THAT(results.error(), test::IsOk());
  1462. EXPECT_THAT(results.text_records(),
  1463. testing::Optional(testing::ElementsAre("foo")));
  1464. }
  1465. TEST(DnsResponseResultExtractorTest, HandlesArbitraryOrderCnameChainTypeA) {
  1466. constexpr char kName[] = "first.test";
  1467. const IPAddress kExpected(192, 168, 0, 1);
  1468. IPEndPoint expected_endpoint(kExpected, 0 /* port */);
  1469. // Alias names are chosen so that the chain order is not in alphabetical
  1470. // order.
  1471. DnsResponse response =
  1472. BuildTestDnsResponse(kName, dns_protocol::kTypeA,
  1473. {BuildTestCnameRecord("qsecond.test", "athird.test"),
  1474. BuildTestAddressRecord("zfourth.test", kExpected),
  1475. BuildTestCnameRecord("athird.test", "zfourth.test"),
  1476. BuildTestCnameRecord(kName, "qsecond.test")});
  1477. DnsResponseResultExtractor extractor(&response);
  1478. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1479. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::A,
  1480. /*original_domain_name=*/kName,
  1481. /*request_port=*/0, &results),
  1482. DnsResponseResultExtractor::ExtractionError::kOk);
  1483. EXPECT_THAT(results.error(), test::IsOk());
  1484. EXPECT_THAT(results.GetEndpoints(),
  1485. testing::Optional(testing::ElementsAre(ExpectEndpointResult(
  1486. testing::ElementsAre(expected_endpoint)))));
  1487. EXPECT_THAT(results.aliases(),
  1488. testing::Pointee(testing::UnorderedElementsAre(
  1489. "zfourth.test", "athird.test", "qsecond.test", kName)));
  1490. }
  1491. TEST(DnsResponseResultExtractorTest, IgnoresNonResultTypesMixedWithCnameChain) {
  1492. constexpr char kName[] = "first.test";
  1493. DnsResponse response = BuildTestDnsResponse(
  1494. kName, dns_protocol::kTypeTXT,
  1495. {BuildTestCnameRecord("second.test", "third.test"),
  1496. BuildTestTextRecord("fourth.test", {"foo"}),
  1497. BuildTestCnameRecord("third.test", "fourth.test"),
  1498. BuildTestAddressRecord("third.test", IPAddress(1, 2, 3, 4)),
  1499. BuildTestCnameRecord(kName, "second.test"),
  1500. BuildTestAddressRecord("fourth.test", IPAddress(2, 3, 4, 5))});
  1501. DnsResponseResultExtractor extractor(&response);
  1502. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1503. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::TXT,
  1504. /*original_domain_name=*/kName,
  1505. /*request_port=*/0, &results),
  1506. DnsResponseResultExtractor::ExtractionError::kOk);
  1507. EXPECT_THAT(results.error(), test::IsOk());
  1508. EXPECT_THAT(results.text_records(),
  1509. testing::Optional(testing::ElementsAre("foo")));
  1510. EXPECT_FALSE(results.GetEndpoints());
  1511. EXPECT_FALSE(results.aliases());
  1512. }
  1513. TEST(DnsResponseResultExtractorTest,
  1514. IgnoresNonResultTypesMixedWithCnameChainTypeA) {
  1515. constexpr char kName[] = "first.test";
  1516. const IPAddress kExpected(192, 168, 0, 1);
  1517. IPEndPoint expected_endpoint(kExpected, 0 /* port */);
  1518. DnsResponse response =
  1519. BuildTestDnsResponse(kName, dns_protocol::kTypeA,
  1520. {BuildTestCnameRecord("second.test", "third.test"),
  1521. BuildTestTextRecord("fourth.test", {"foo"}),
  1522. BuildTestCnameRecord("third.test", "fourth.test"),
  1523. BuildTestCnameRecord(kName, "second.test"),
  1524. BuildTestAddressRecord("fourth.test", kExpected)});
  1525. DnsResponseResultExtractor extractor(&response);
  1526. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1527. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::A,
  1528. /*original_domain_name=*/kName,
  1529. /*request_port=*/0, &results),
  1530. DnsResponseResultExtractor::ExtractionError::kOk);
  1531. EXPECT_THAT(results.error(), test::IsOk());
  1532. EXPECT_FALSE(results.text_records());
  1533. EXPECT_THAT(results.GetEndpoints(),
  1534. testing::Optional(testing::ElementsAre(ExpectEndpointResult(
  1535. testing::ElementsAre(expected_endpoint)))));
  1536. EXPECT_THAT(results.aliases(),
  1537. testing::Pointee(testing::UnorderedElementsAre(
  1538. "fourth.test", "third.test", "second.test", kName)));
  1539. }
  1540. TEST(DnsResponseResultExtractorTest, HandlesCnameChainWithoutResult) {
  1541. constexpr char kName[] = "first.test";
  1542. DnsResponse response =
  1543. BuildTestDnsResponse(kName, dns_protocol::kTypeTXT,
  1544. {BuildTestCnameRecord("second.test", "third.test"),
  1545. BuildTestCnameRecord("third.test", "fourth.test"),
  1546. BuildTestCnameRecord(kName, "second.test")});
  1547. DnsResponseResultExtractor extractor(&response);
  1548. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1549. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::TXT,
  1550. /*original_domain_name=*/kName,
  1551. /*request_port=*/0, &results),
  1552. DnsResponseResultExtractor::ExtractionError::kOk);
  1553. EXPECT_THAT(results.error(), test::IsError(ERR_NAME_NOT_RESOLVED));
  1554. EXPECT_THAT(results.text_records(), testing::Optional(testing::IsEmpty()));
  1555. }
  1556. TEST(DnsResponseResultExtractorTest, HandlesCnameChainWithoutResultTypeA) {
  1557. constexpr char kName[] = "first.test";
  1558. DnsResponse response =
  1559. BuildTestDnsResponse(kName, dns_protocol::kTypeA,
  1560. {BuildTestCnameRecord("second.test", "third.test"),
  1561. BuildTestCnameRecord("third.test", "fourth.test"),
  1562. BuildTestCnameRecord(kName, "second.test")});
  1563. DnsResponseResultExtractor extractor(&response);
  1564. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1565. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::A,
  1566. /*original_domain_name=*/kName,
  1567. /*request_port=*/0, &results),
  1568. DnsResponseResultExtractor::ExtractionError::kOk);
  1569. EXPECT_THAT(results.error(), test::IsError(ERR_NAME_NOT_RESOLVED));
  1570. EXPECT_THAT(results.GetEndpoints(), testing::Optional(testing::IsEmpty()));
  1571. EXPECT_THAT(results.aliases(),
  1572. testing::Pointee(testing::UnorderedElementsAre(
  1573. "fourth.test", "third.test", "second.test", kName)));
  1574. }
  1575. TEST(DnsResponseResultExtractorTest, RejectsCnameChainWithLoop) {
  1576. constexpr char kName[] = "first.test";
  1577. DnsResponse response =
  1578. BuildTestDnsResponse(kName, dns_protocol::kTypeTXT,
  1579. {BuildTestCnameRecord("second.test", "third.test"),
  1580. BuildTestTextRecord("third.test", {"foo"}),
  1581. BuildTestCnameRecord("third.test", "second.test"),
  1582. BuildTestCnameRecord(kName, "second.test")});
  1583. DnsResponseResultExtractor extractor(&response);
  1584. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1585. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::TXT,
  1586. /*original_domain_name=*/kName,
  1587. /*request_port=*/0, &results),
  1588. DnsResponseResultExtractor::ExtractionError::kBadAliasChain);
  1589. EXPECT_THAT(results.error(), test::IsError(ERR_DNS_MALFORMED_RESPONSE));
  1590. }
  1591. TEST(DnsResponseResultExtractorTest, RejectsCnameChainWithLoopToBeginning) {
  1592. constexpr char kName[] = "first.test";
  1593. DnsResponse response =
  1594. BuildTestDnsResponse(kName, dns_protocol::kTypeTXT,
  1595. {BuildTestCnameRecord("second.test", "third.test"),
  1596. BuildTestTextRecord("third.test", {"foo"}),
  1597. BuildTestCnameRecord("third.test", "first.test"),
  1598. BuildTestCnameRecord(kName, "second.test")});
  1599. DnsResponseResultExtractor extractor(&response);
  1600. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1601. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::TXT,
  1602. /*original_domain_name=*/kName,
  1603. /*request_port=*/0, &results),
  1604. DnsResponseResultExtractor::ExtractionError::kBadAliasChain);
  1605. EXPECT_THAT(results.error(), test::IsError(ERR_DNS_MALFORMED_RESPONSE));
  1606. }
  1607. TEST(DnsResponseResultExtractorTest,
  1608. RejectsCnameChainWithLoopToBeginningWithoutResult) {
  1609. constexpr char kName[] = "first.test";
  1610. DnsResponse response =
  1611. BuildTestDnsResponse(kName, dns_protocol::kTypeTXT,
  1612. {BuildTestCnameRecord("second.test", "third.test"),
  1613. BuildTestCnameRecord("third.test", "first.test"),
  1614. BuildTestCnameRecord(kName, "second.test")});
  1615. DnsResponseResultExtractor extractor(&response);
  1616. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1617. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::TXT,
  1618. /*original_domain_name=*/kName,
  1619. /*request_port=*/0, &results),
  1620. DnsResponseResultExtractor::ExtractionError::kBadAliasChain);
  1621. EXPECT_THAT(results.error(), test::IsError(ERR_DNS_MALFORMED_RESPONSE));
  1622. }
  1623. TEST(DnsResponseResultExtractorTest, RejectsCnameChainWithWrongStart) {
  1624. constexpr char kName[] = "test.test";
  1625. DnsResponse response =
  1626. BuildTestDnsResponse(kName, dns_protocol::kTypeTXT,
  1627. {BuildTestCnameRecord("second.test", "third.test"),
  1628. BuildTestTextRecord("fourth.test", {"foo"}),
  1629. BuildTestCnameRecord("third.test", "fourth.test"),
  1630. BuildTestCnameRecord("first.test", "second.test")});
  1631. DnsResponseResultExtractor extractor(&response);
  1632. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1633. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::TXT,
  1634. /*original_domain_name=*/kName,
  1635. /*request_port=*/0, &results),
  1636. DnsResponseResultExtractor::ExtractionError::kBadAliasChain);
  1637. EXPECT_THAT(results.error(), test::IsError(ERR_DNS_MALFORMED_RESPONSE));
  1638. }
  1639. TEST(DnsResponseResultExtractorTest, RejectsCnameChainWithWrongResultName) {
  1640. constexpr char kName[] = "first.test";
  1641. DnsResponse response =
  1642. BuildTestDnsResponse(kName, dns_protocol::kTypeTXT,
  1643. {BuildTestCnameRecord("second.test", "third.test"),
  1644. BuildTestTextRecord("third.test", {"foo"}),
  1645. BuildTestCnameRecord("third.test", "fourth.test"),
  1646. BuildTestCnameRecord(kName, "second.test")});
  1647. DnsResponseResultExtractor extractor(&response);
  1648. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1649. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::TXT,
  1650. /*original_domain_name=*/kName,
  1651. /*request_port=*/0, &results),
  1652. DnsResponseResultExtractor::ExtractionError::kNameMismatch);
  1653. EXPECT_THAT(results.error(), test::IsError(ERR_DNS_MALFORMED_RESPONSE));
  1654. }
  1655. TEST(DnsResponseResultExtractorTest, RejectsCnameSharedWithResult) {
  1656. constexpr char kName[] = "first.test";
  1657. DnsResponse response =
  1658. BuildTestDnsResponse(kName, dns_protocol::kTypeTXT,
  1659. {BuildTestCnameRecord("second.test", "third.test"),
  1660. BuildTestTextRecord(kName, {"foo"}),
  1661. BuildTestCnameRecord("third.test", "fourth.test"),
  1662. BuildTestCnameRecord(kName, "second.test")});
  1663. DnsResponseResultExtractor extractor(&response);
  1664. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1665. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::TXT,
  1666. /*original_domain_name=*/kName,
  1667. /*request_port=*/0, &results),
  1668. DnsResponseResultExtractor::ExtractionError::kNameMismatch);
  1669. EXPECT_THAT(results.error(), test::IsError(ERR_DNS_MALFORMED_RESPONSE));
  1670. }
  1671. TEST(DnsResponseResultExtractorTest, RejectsDisjointCnameChain) {
  1672. constexpr char kName[] = "first.test";
  1673. DnsResponse response = BuildTestDnsResponse(
  1674. kName, dns_protocol::kTypeTXT,
  1675. {BuildTestCnameRecord("second.test", "third.test"),
  1676. BuildTestTextRecord("fourth.test", {"foo"}),
  1677. BuildTestCnameRecord("third.test", "fourth.test"),
  1678. BuildTestCnameRecord("other1.test", "other2.test"),
  1679. BuildTestCnameRecord(kName, "second.test"),
  1680. BuildTestCnameRecord("other2.test", "other3.test")});
  1681. DnsResponseResultExtractor extractor(&response);
  1682. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1683. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::TXT,
  1684. /*original_domain_name=*/kName,
  1685. /*request_port=*/0, &results),
  1686. DnsResponseResultExtractor::ExtractionError::kBadAliasChain);
  1687. EXPECT_THAT(results.error(), test::IsError(ERR_DNS_MALFORMED_RESPONSE));
  1688. }
  1689. TEST(DnsResponseResultExtractorTest, RejectsDoubledCnames) {
  1690. constexpr char kName[] = "first.test";
  1691. DnsResponse response =
  1692. BuildTestDnsResponse(kName, dns_protocol::kTypeTXT,
  1693. {BuildTestCnameRecord("second.test", "third.test"),
  1694. BuildTestTextRecord("fourth.test", {"foo"}),
  1695. BuildTestCnameRecord("third.test", "fourth.test"),
  1696. BuildTestCnameRecord("third.test", "fifth.test"),
  1697. BuildTestCnameRecord(kName, "second.test")});
  1698. DnsResponseResultExtractor extractor(&response);
  1699. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1700. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::TXT,
  1701. /*original_domain_name=*/kName,
  1702. /*request_port=*/0, &results),
  1703. DnsResponseResultExtractor::ExtractionError::kMultipleCnames);
  1704. EXPECT_THAT(results.error(), test::IsError(ERR_DNS_MALFORMED_RESPONSE));
  1705. }
  1706. TEST(DnsResponseResultExtractorTest, IgnoresTtlFromNonResultType) {
  1707. constexpr char kName[] = "name.test";
  1708. constexpr base::TimeDelta kMinTtl = base::Minutes(4);
  1709. DnsResponse response = BuildTestDnsResponse(
  1710. kName, dns_protocol::kTypeTXT,
  1711. {BuildTestTextRecord(kName, {"foo"}, base::Hours(3)),
  1712. BuildTestTextRecord(kName, {"bar"}, kMinTtl),
  1713. BuildTestAddressRecord(kName, IPAddress(1, 2, 3, 4), base::Seconds(2)),
  1714. BuildTestTextRecord(kName, {"baz"}, base::Minutes(15))});
  1715. DnsResponseResultExtractor extractor(&response);
  1716. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1717. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::TXT,
  1718. /*original_domain_name=*/kName,
  1719. /*request_port=*/0, &results),
  1720. DnsResponseResultExtractor::ExtractionError::kOk);
  1721. ASSERT_TRUE(results.has_ttl());
  1722. EXPECT_EQ(results.ttl(), kMinTtl);
  1723. }
  1724. TEST(DnsResponseResultExtractorTest, ExtractsTtlFromCname) {
  1725. constexpr char kName[] = "name.test";
  1726. constexpr char kAlias[] = "alias.test";
  1727. constexpr base::TimeDelta kMinTtl = base::Minutes(4);
  1728. DnsResponse response = BuildTestDnsResponse(
  1729. "name.test", dns_protocol::kTypeTXT,
  1730. {BuildTestTextRecord(kAlias, {"foo"}, base::Hours(3)),
  1731. BuildTestTextRecord(kAlias, {"bar"}, base::Hours(2)),
  1732. BuildTestTextRecord(kAlias, {"baz"}, base::Minutes(15)),
  1733. BuildTestCnameRecord(kName, kAlias, kMinTtl)});
  1734. DnsResponseResultExtractor extractor(&response);
  1735. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1736. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::TXT,
  1737. /*original_domain_name=*/kName,
  1738. /*request_port=*/0, &results),
  1739. DnsResponseResultExtractor::ExtractionError::kOk);
  1740. ASSERT_TRUE(results.has_ttl());
  1741. EXPECT_EQ(results.ttl(), kMinTtl);
  1742. }
  1743. TEST(DnsResponseResultExtractorTest, ValidatesAliasNames) {
  1744. constexpr char kName[] = "first.test";
  1745. const IPAddress kExpected(192, 168, 0, 1);
  1746. IPEndPoint expected_endpoint(kExpected, 0 /* port */);
  1747. DnsResponse response =
  1748. BuildTestDnsResponse(kName, dns_protocol::kTypeA,
  1749. {BuildTestCnameRecord(kName, "second.test"),
  1750. BuildTestCnameRecord("second.test", "localhost"),
  1751. BuildTestCnameRecord("localhost", "fourth.test"),
  1752. BuildTestAddressRecord("fourth.test", kExpected)});
  1753. DnsResponseResultExtractor extractor(&response);
  1754. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1755. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::A,
  1756. /*original_domain_name=*/kName,
  1757. /*request_port=*/0, &results),
  1758. DnsResponseResultExtractor::ExtractionError::kOk);
  1759. EXPECT_THAT(results.error(), test::IsOk());
  1760. EXPECT_THAT(results.GetEndpoints(),
  1761. testing::Optional(testing::ElementsAre(ExpectEndpointResult(
  1762. testing::ElementsAre(expected_endpoint)))));
  1763. // Expect "localhost" to be validated out of the alias list.
  1764. EXPECT_THAT(results.aliases(), testing::Pointee(testing::UnorderedElementsAre(
  1765. "fourth.test", "second.test", kName)));
  1766. }
  1767. TEST(DnsResponseResultExtractorTest, CanonicalizesAliasNames) {
  1768. const IPAddress kExpected(192, 168, 0, 1);
  1769. constexpr char kName[] = "address.test";
  1770. DnsResponse response =
  1771. BuildTestDnsAddressResponseWithCname(kName, kExpected, "ALIAS.test.");
  1772. DnsResponseResultExtractor extractor(&response);
  1773. HostCache::Entry results(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
  1774. EXPECT_EQ(extractor.ExtractDnsResults(DnsQueryType::A,
  1775. /*original_domain_name=*/kName,
  1776. /*request_port=*/0, &results),
  1777. DnsResponseResultExtractor::ExtractionError::kOk);
  1778. EXPECT_THAT(results.error(), test::IsOk());
  1779. IPEndPoint expected_endpoint(kExpected, 0 /* port */);
  1780. EXPECT_THAT(results.GetEndpoints(),
  1781. testing::Optional(testing::ElementsAre(ExpectEndpointResult(
  1782. testing::ElementsAre(expected_endpoint)))));
  1783. EXPECT_THAT(results.aliases(), testing::Pointee(testing::UnorderedElementsAre(
  1784. kName, "alias.test")));
  1785. }
  1786. } // namespace
  1787. } // namespace net