• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/dns/https_record_rdata.h"
6 
7 #include <map>
8 #include <memory>
9 #include <string>
10 #include <vector>
11 
12 #include "base/strings/string_piece.h"
13 #include "net/base/ip_address.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 
17 namespace net {
18 namespace {
19 
TEST(HttpsRecordRdataTest,ParsesAlias)20 TEST(HttpsRecordRdataTest, ParsesAlias) {
21   const char kRdata[] =
22       // Priority: 0 for alias record
23       "\000\000"
24       // Alias name: chromium.org
25       "\010chromium\003org\000";
26 
27   std::unique_ptr<HttpsRecordRdata> rdata =
28       HttpsRecordRdata::Parse(base::StringPiece(kRdata, sizeof(kRdata) - 1));
29   ASSERT_TRUE(rdata);
30 
31   AliasFormHttpsRecordRdata expected("chromium.org");
32   EXPECT_TRUE(rdata->IsEqual(&expected));
33 
34   EXPECT_TRUE(rdata->IsAlias());
35   AliasFormHttpsRecordRdata* alias_rdata = rdata->AsAliasForm();
36   ASSERT_TRUE(alias_rdata);
37   EXPECT_EQ(alias_rdata->alias_name(), "chromium.org");
38 }
39 
TEST(HttpsRecordRdataTest,ParseAliasWithEmptyName)40 TEST(HttpsRecordRdataTest, ParseAliasWithEmptyName) {
41   const char kRdata[] =
42       // Priority: 0 for alias record
43       "\000\000"
44       // Alias name: ""
45       "\000";
46 
47   std::unique_ptr<HttpsRecordRdata> rdata =
48       HttpsRecordRdata::Parse(base::StringPiece(kRdata, sizeof(kRdata) - 1));
49   ASSERT_TRUE(rdata);
50 
51   AliasFormHttpsRecordRdata expected("");
52   EXPECT_TRUE(rdata->IsEqual(&expected));
53 
54   EXPECT_TRUE(rdata->IsAlias());
55   AliasFormHttpsRecordRdata* alias_rdata = rdata->AsAliasForm();
56   ASSERT_TRUE(alias_rdata);
57   EXPECT_TRUE(alias_rdata->alias_name().empty());
58 }
59 
TEST(HttpsRecordRdataTest,IgnoreAliasParams)60 TEST(HttpsRecordRdataTest, IgnoreAliasParams) {
61   const char kRdata[] =
62       // Priority: 0 for alias record
63       "\000\000"
64       // Alias name: chromium.org
65       "\010chromium\003org\000"
66       // no-default-alpn
67       "\000\002\000\000";
68 
69   std::unique_ptr<HttpsRecordRdata> rdata =
70       HttpsRecordRdata::Parse(base::StringPiece(kRdata, sizeof(kRdata) - 1));
71   ASSERT_TRUE(rdata);
72 
73   AliasFormHttpsRecordRdata expected("chromium.org");
74   EXPECT_TRUE(rdata->IsEqual(&expected));
75 
76   EXPECT_TRUE(rdata->IsAlias());
77   AliasFormHttpsRecordRdata* alias_rdata = rdata->AsAliasForm();
78   ASSERT_TRUE(alias_rdata);
79   EXPECT_EQ(alias_rdata->alias_name(), "chromium.org");
80 }
81 
TEST(HttpsRecordRdataTest,ParsesService)82 TEST(HttpsRecordRdataTest, ParsesService) {
83   const char kRdata[] =
84       // Priority: 1
85       "\000\001"
86       // Service name: chromium.org
87       "\010chromium\003org\000"
88       // mandatory=alpn,no-default-alpn,port,ipv4hint,echconfig,ipv6hint
89       "\000\000\000\014\000\001\000\002\000\003\000\004\000\005\000\006"
90       // alpn=foo,bar
91       "\000\001\000\010\003foo\003bar"
92       // no-default-alpn
93       "\000\002\000\000"
94       // port=46
95       "\000\003\000\002\000\056"
96       // ipv4hint=8.8.8.8
97       "\000\004\000\004\010\010\010\010"
98       // echconfig=hello
99       "\000\005\000\005hello"
100       // ipv6hint=2001:4860:4860::8888
101       "\000\006\000\020\x20\x01\x48\x60\x48\x60\x00\x00\x00\x00\x00\x00\x00\x00"
102       "\x88\x88"
103       // Unknown key7=foo
104       "\000\007\000\003foo";
105 
106   std::unique_ptr<HttpsRecordRdata> rdata =
107       HttpsRecordRdata::Parse(base::StringPiece(kRdata, sizeof(kRdata) - 1));
108   ASSERT_TRUE(rdata);
109 
110   IPAddress expected_ipv6;
111   ASSERT_TRUE(expected_ipv6.AssignFromIPLiteral("2001:4860:4860::8888"));
112   ServiceFormHttpsRecordRdata expected(
113       1 /* priority */, "chromium.org", std::set<uint16_t>({1, 2, 3, 4, 5, 6}),
114       std::vector<std::string>({"foo", "bar"}) /* alpn_ids */,
115       false /* default_alpn */, absl::optional<uint16_t>(46) /* port */,
116       std::vector<IPAddress>({IPAddress(8, 8, 8, 8)}) /* ipv4_hint */,
117       "hello" /* ech_config */,
118       std::vector<IPAddress>({expected_ipv6}) /* ipv6_hint */,
119       std::map<uint16_t, std::string>({{7, "foo"}}) /* unparsed_params */);
120   EXPECT_TRUE(rdata->IsEqual(&expected));
121 
122   EXPECT_FALSE(rdata->IsAlias());
123   ServiceFormHttpsRecordRdata* service_rdata = rdata->AsServiceForm();
124   ASSERT_TRUE(service_rdata);
125   EXPECT_EQ(service_rdata->priority(), 1);
126   EXPECT_EQ(service_rdata->service_name(), "chromium.org");
127   EXPECT_THAT(service_rdata->mandatory_keys(),
128               testing::ElementsAre(1, 2, 3, 4, 5, 6));
129   EXPECT_THAT(service_rdata->alpn_ids(), testing::ElementsAre("foo", "bar"));
130   EXPECT_FALSE(service_rdata->default_alpn());
131   EXPECT_THAT(service_rdata->port(), testing::Optional(46));
132   EXPECT_THAT(service_rdata->ipv4_hint(),
133               testing::ElementsAre(IPAddress(8, 8, 8, 8)));
134   EXPECT_EQ(service_rdata->ech_config(), "hello");
135   EXPECT_THAT(service_rdata->ipv6_hint(), testing::ElementsAre(expected_ipv6));
136   EXPECT_THAT(service_rdata->unparsed_params(),
137               testing::ElementsAre(testing::Pair(7, "foo")));
138   EXPECT_TRUE(service_rdata->IsCompatible());
139 }
140 
TEST(HttpsRecordRdataTest,RejectCorruptRdata)141 TEST(HttpsRecordRdataTest, RejectCorruptRdata) {
142   const char kRdata[] =
143       // Priority: 5
144       "\000\005"
145       // Service name: chromium.org
146       "\010chromium\003org\000"
147       // Malformed alpn
148       "\000\001\000\005hi";
149 
150   std::unique_ptr<HttpsRecordRdata> rdata =
151       HttpsRecordRdata::Parse(base::StringPiece(kRdata, sizeof(kRdata) - 1));
152   EXPECT_FALSE(rdata);
153 }
154 
TEST(HttpsRecordRdataTest,AliasIsEqualRejectsWrongType)155 TEST(HttpsRecordRdataTest, AliasIsEqualRejectsWrongType) {
156   AliasFormHttpsRecordRdata alias("alias.name.test");
157   ServiceFormHttpsRecordRdata service(
158       1u /* priority */, "service.name.test", {} /* mandatory_keys */,
159       {} /* alpn_ids */, true /* default_alpn */, absl::nullopt /* port */,
160       {} /* ipv4_hint */, "" /* ech_config */, {} /* ipv6_hint */,
161       {} /* unparsed_params */);
162 
163   EXPECT_TRUE(alias.IsEqual(&alias));
164   EXPECT_FALSE(alias.IsEqual(&service));
165 }
166 
TEST(HttpsRecordRdataTest,ServiceIsEqualRejectsWrongType)167 TEST(HttpsRecordRdataTest, ServiceIsEqualRejectsWrongType) {
168   AliasFormHttpsRecordRdata alias("alias.name.test");
169   ServiceFormHttpsRecordRdata service(
170       1u /* priority */, "service.name.test", {} /* mandatory_keys */,
171       {} /* alpn_ids */, true /* default_alpn */, absl::nullopt /* port */,
172       {} /* ipv4_hint */, "" /* ech_config */, {} /* ipv6_hint */,
173       {} /* unparsed_params */);
174 
175   EXPECT_FALSE(service.IsEqual(&alias));
176   EXPECT_TRUE(service.IsEqual(&service));
177 }
178 
179 }  // namespace
180 }  // namespace net
181