• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "discovery/mdns/mdns_records.h"
6 
7 #include <limits>
8 #include <string>
9 #include <utility>
10 #include <vector>
11 
12 #include "discovery/mdns/mdns_reader.h"
13 #include "discovery/mdns/mdns_writer.h"
14 #include "discovery/mdns/testing/hash_test_util.h"
15 #include "discovery/mdns/testing/mdns_test_util.h"
16 #include "gmock/gmock.h"
17 #include "gtest/gtest.h"
18 #include "platform/api/network_interface.h"
19 
20 namespace openscreen {
21 namespace discovery {
22 
23 using testing::ElementsAreArray;
24 
25 namespace {
26 
27 constexpr std::chrono::seconds kTtl{120};
28 
29 template <class T>
TestCopyAndMove(const T & value)30 void TestCopyAndMove(const T& value) {
31   T value_copy_constuct(value);
32   EXPECT_EQ(value_copy_constuct, value);
33   T value_copy_assign = value;
34   EXPECT_EQ(value_copy_assign, value);
35   T value_move_constuct(std::move(value_copy_constuct));
36   EXPECT_EQ(value_move_constuct, value);
37   T value_move_assign = std::move(value_copy_assign);
38   EXPECT_EQ(value_move_assign, value);
39 }
40 
41 }  // namespace
42 
TEST(MdnsDomainNameTest,Construct)43 TEST(MdnsDomainNameTest, Construct) {
44   DomainName name1;
45   EXPECT_TRUE(name1.empty());
46   EXPECT_EQ(name1.MaxWireSize(), UINT64_C(1));
47   EXPECT_EQ(name1.labels().size(), UINT64_C(0));
48 
49   DomainName name2{"MyDevice", "_mYSERvice", "local"};
50   EXPECT_FALSE(name2.empty());
51   EXPECT_EQ(name2.MaxWireSize(), UINT64_C(27));
52   ASSERT_EQ(name2.labels().size(), UINT64_C(3));
53   EXPECT_EQ(name2.labels()[0], "MyDevice");
54   EXPECT_EQ(name2.labels()[1], "_mYSERvice");
55   EXPECT_EQ(name2.labels()[2], "local");
56   EXPECT_EQ(name2.ToString(), "MyDevice._mYSERvice.local");
57 
58   std::vector<absl::string_view> labels{"OtherDevice", "_MYservice", "LOcal"};
59   DomainName name3(labels);
60   EXPECT_FALSE(name3.empty());
61   EXPECT_EQ(name3.MaxWireSize(), UINT64_C(30));
62   ASSERT_EQ(name3.labels().size(), UINT64_C(3));
63   EXPECT_EQ(name3.labels()[0], "OtherDevice");
64   EXPECT_EQ(name3.labels()[1], "_MYservice");
65   EXPECT_EQ(name3.labels()[2], "LOcal");
66   EXPECT_EQ(name3.ToString(), "OtherDevice._MYservice.LOcal");
67 }
68 
TEST(MdnsDomainNameTest,Compare)69 TEST(MdnsDomainNameTest, Compare) {
70   DomainName first{"testing", "local"};
71   DomainName second{"TeStInG", "LOCAL"};
72   DomainName third{"testing"};
73   DomainName fourth{"testing.local"};
74   DomainName fifth{"Testing.Local"};
75 
76   EXPECT_EQ(first, second);
77   EXPECT_TRUE(first >= second);
78   EXPECT_TRUE(second >= first);
79   EXPECT_TRUE(first <= second);
80   EXPECT_TRUE(second <= first);
81   EXPECT_EQ(fourth, fifth);
82   EXPECT_NE(first, third);
83   EXPECT_NE(first, fourth);
84 
85   EXPECT_FALSE(first < second);
86   EXPECT_FALSE(second < first);
87   EXPECT_FALSE(first < third);
88   EXPECT_TRUE(third < first);
89   EXPECT_TRUE(third <= first);
90   EXPECT_FALSE(third > first);
91   EXPECT_TRUE(first < fourth);
92   EXPECT_TRUE(fourth > first);
93   EXPECT_TRUE(fourth >= first);
94   EXPECT_TRUE(first < fifth);
95   EXPECT_FALSE(fifth < first);
96 
97   EXPECT_FALSE(second < third);
98   EXPECT_TRUE(third < second);
99   EXPECT_TRUE(second < fourth);
100   EXPECT_FALSE(fourth < second);
101   EXPECT_TRUE(second < fifth);
102   EXPECT_FALSE(fifth < second);
103 
104   EXPECT_TRUE(third < fourth);
105   EXPECT_FALSE(fourth < third);
106   EXPECT_TRUE(third < fifth);
107   EXPECT_FALSE(fifth < third);
108 
109   EXPECT_FALSE(fourth < fifth);
110   EXPECT_FALSE(fifth < fourth);
111 
112   EXPECT_TRUE(VerifyTypeImplementsAbslHashCorrectly(
113       {first, second, third, fourth, fifth}));
114 }
115 
TEST(MdnsDomainNameTest,CopyAndMove)116 TEST(MdnsDomainNameTest, CopyAndMove) {
117   TestCopyAndMove(DomainName{"testing", "local"});
118 }
119 
TEST(MdnsRawRecordRdataTest,Construct)120 TEST(MdnsRawRecordRdataTest, Construct) {
121   constexpr uint8_t kRawRdata[] = {
122       0x05, 'c', 'n', 'a', 'm', 'e', 0xc0, 0x00,
123   };
124 
125   RawRecordRdata rdata1;
126   EXPECT_EQ(rdata1.MaxWireSize(), UINT64_C(2));
127   EXPECT_EQ(rdata1.size(), UINT16_C(0));
128 
129   RawRecordRdata rdata2(kRawRdata, sizeof(kRawRdata));
130   EXPECT_EQ(rdata2.MaxWireSize(), UINT64_C(10));
131   EXPECT_EQ(rdata2.size(), UINT16_C(8));
132   EXPECT_THAT(
133       std::vector<uint8_t>(rdata2.data(), rdata2.data() + rdata2.size()),
134       ElementsAreArray(kRawRdata));
135 
136   RawRecordRdata rdata3(
137       std::vector<uint8_t>(kRawRdata, kRawRdata + sizeof(kRawRdata)));
138   EXPECT_EQ(rdata3.MaxWireSize(), UINT64_C(10));
139   EXPECT_EQ(rdata3.size(), UINT16_C(8));
140   EXPECT_THAT(
141       std::vector<uint8_t>(rdata3.data(), rdata3.data() + rdata3.size()),
142       ElementsAreArray(kRawRdata));
143 }
144 
TEST(MdnsRawRecordRdataTest,Compare)145 TEST(MdnsRawRecordRdataTest, Compare) {
146   constexpr uint8_t kRawRdata1[] = {
147       0x05, 'c', 'n', 'a', 'm', 'e', 0xc0, 0x00,
148   };
149   constexpr uint8_t kRawRdata2[] = {
150       0x05, 'r', 'd', 'a', 't', 'a',
151   };
152 
153   RawRecordRdata rdata1(kRawRdata1, sizeof(kRawRdata1));
154   RawRecordRdata rdata2(kRawRdata1, sizeof(kRawRdata1));
155   RawRecordRdata rdata3(kRawRdata2, sizeof(kRawRdata2));
156 
157   EXPECT_EQ(rdata1, rdata2);
158   EXPECT_NE(rdata1, rdata3);
159 
160   EXPECT_TRUE(VerifyTypeImplementsAbslHashCorrectly({rdata1, rdata2, rdata3}));
161 }
162 
TEST(MdnsRawRecordRdataTest,CopyAndMove)163 TEST(MdnsRawRecordRdataTest, CopyAndMove) {
164   constexpr uint8_t kRawRdata[] = {
165       0x05, 'c', 'n', 'a', 'm', 'e', 0xc0, 0x00,
166   };
167   TestCopyAndMove(RawRecordRdata(kRawRdata, sizeof(kRawRdata)));
168 }
169 
TEST(MdnsSrvRecordRdataTest,Construct)170 TEST(MdnsSrvRecordRdataTest, Construct) {
171   SrvRecordRdata rdata1;
172   EXPECT_EQ(rdata1.MaxWireSize(), UINT64_C(9));
173   EXPECT_EQ(rdata1.priority(), UINT16_C(0));
174   EXPECT_EQ(rdata1.weight(), UINT16_C(0));
175   EXPECT_EQ(rdata1.port(), UINT16_C(0));
176   EXPECT_EQ(rdata1.target(), DomainName());
177 
178   SrvRecordRdata rdata2(1, 2, 3, DomainName{"testing", "local"});
179   EXPECT_EQ(rdata2.MaxWireSize(), UINT64_C(23));
180   EXPECT_EQ(rdata2.priority(), UINT16_C(1));
181   EXPECT_EQ(rdata2.weight(), UINT16_C(2));
182   EXPECT_EQ(rdata2.port(), UINT16_C(3));
183   EXPECT_EQ(rdata2.target(), (DomainName{"testing", "local"}));
184 }
185 
TEST(MdnsSrvRecordRdataTest,Compare)186 TEST(MdnsSrvRecordRdataTest, Compare) {
187   SrvRecordRdata rdata1(1, 2, 3, DomainName{"testing", "local"});
188   SrvRecordRdata rdata2(1, 2, 3, DomainName{"testing", "local"});
189   SrvRecordRdata rdata3(4, 2, 3, DomainName{"testing", "local"});
190   SrvRecordRdata rdata4(1, 5, 3, DomainName{"testing", "local"});
191   SrvRecordRdata rdata5(1, 2, 6, DomainName{"testing", "local"});
192   SrvRecordRdata rdata6(1, 2, 3, DomainName{"device", "local"});
193 
194   EXPECT_EQ(rdata1, rdata2);
195   EXPECT_NE(rdata1, rdata3);
196   EXPECT_NE(rdata1, rdata4);
197   EXPECT_NE(rdata1, rdata5);
198   EXPECT_NE(rdata1, rdata6);
199 
200   EXPECT_TRUE(VerifyTypeImplementsAbslHashCorrectly(
201       {rdata1, rdata2, rdata3, rdata4, rdata5, rdata6}));
202 }
203 
TEST(MdnsSrvRecordRdataTest,CopyAndMove)204 TEST(MdnsSrvRecordRdataTest, CopyAndMove) {
205   TestCopyAndMove(SrvRecordRdata(1, 2, 3, DomainName{"testing", "local"}));
206 }
207 
TEST(MdnsARecordRdataTest,Construct)208 TEST(MdnsARecordRdataTest, Construct) {
209   ARecordRdata rdata1;
210   EXPECT_EQ(rdata1.MaxWireSize(), UINT64_C(6));
211   EXPECT_EQ(rdata1.ipv4_address(), (IPAddress{0, 0, 0, 0}));
212 
213   ARecordRdata rdata2(IPAddress{8, 8, 8, 8});
214   EXPECT_EQ(rdata2.MaxWireSize(), UINT64_C(6));
215   EXPECT_EQ(rdata2.ipv4_address(), (IPAddress{8, 8, 8, 8}));
216 }
217 
TEST(MdnsARecordRdataTest,Compare)218 TEST(MdnsARecordRdataTest, Compare) {
219   ARecordRdata rdata1(IPAddress{8, 8, 8, 8});
220   ARecordRdata rdata2(IPAddress{8, 8, 8, 8});
221   ARecordRdata rdata3(IPAddress{1, 2, 3, 4});
222 
223   EXPECT_EQ(rdata1, rdata2);
224   EXPECT_NE(rdata1, rdata3);
225 
226   EXPECT_TRUE(VerifyTypeImplementsAbslHashCorrectly({rdata1, rdata2, rdata3}));
227 }
228 
TEST(MdnsARecordRdataTest,CopyAndMove)229 TEST(MdnsARecordRdataTest, CopyAndMove) {
230   TestCopyAndMove(ARecordRdata(IPAddress{8, 8, 8, 8}));
231 }
232 
TEST(MdnsAAAARecordRdataTest,Construct)233 TEST(MdnsAAAARecordRdataTest, Construct) {
234   constexpr uint16_t kIPv6AddressHextets1[] = {
235       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
236   };
237   constexpr uint16_t kIPv6AddressHextets2[] = {
238       0xfe80, 0x0000, 0x0000, 0x0000, 0x0202, 0xb3ff, 0xfe1e, 0x8329,
239   };
240 
241   IPAddress address1(kIPv6AddressHextets1);
242   AAAARecordRdata rdata1;
243   EXPECT_EQ(rdata1.MaxWireSize(), UINT64_C(18));
244   EXPECT_EQ(rdata1.ipv6_address(), address1);
245 
246   IPAddress address2(kIPv6AddressHextets2);
247   AAAARecordRdata rdata2(address2);
248   EXPECT_EQ(rdata2.MaxWireSize(), UINT64_C(18));
249   EXPECT_EQ(rdata2.ipv6_address(), address2);
250 }
251 
TEST(MdnsAAAARecordRdataTest,Compare)252 TEST(MdnsAAAARecordRdataTest, Compare) {
253   constexpr uint16_t kIPv6AddressHextets1[] = {
254       0x0001, 0x0203, 0x0405, 0x0607, 0x0809, 0x0A0B, 0x0C0D, 0x0E0F,
255   };
256   constexpr uint16_t kIPv6AddressHextets2[] = {
257       0xfe80, 0x0000, 0x0000, 0x0000, 0x0202, 0xb3ff, 0xfe1e, 0x8329,
258   };
259 
260   IPAddress address1(kIPv6AddressHextets1);
261   IPAddress address2(kIPv6AddressHextets2);
262   AAAARecordRdata rdata1(address1);
263   AAAARecordRdata rdata2(address1);
264   AAAARecordRdata rdata3(address2);
265 
266   EXPECT_EQ(rdata1, rdata2);
267   EXPECT_NE(rdata1, rdata3);
268 
269   EXPECT_TRUE(VerifyTypeImplementsAbslHashCorrectly({rdata1, rdata2, rdata3}));
270 }
271 
TEST(MdnsAAAARecordRdataTest,CopyAndMove)272 TEST(MdnsAAAARecordRdataTest, CopyAndMove) {
273   constexpr uint16_t kIPv6AddressHextets[] = {
274       0xfe80, 0x0000, 0x0000, 0x0000, 0x0202, 0xb3ff, 0xfe1e, 0x8329,
275   };
276   TestCopyAndMove(AAAARecordRdata(IPAddress(kIPv6AddressHextets)));
277 }
278 
TEST(MdnsPtrRecordRdataTest,Construct)279 TEST(MdnsPtrRecordRdataTest, Construct) {
280   PtrRecordRdata rdata1;
281   EXPECT_EQ(rdata1.MaxWireSize(), UINT64_C(3));
282   EXPECT_EQ(rdata1.ptr_domain(), DomainName());
283 
284   PtrRecordRdata rdata2(DomainName{"testing", "local"});
285   EXPECT_EQ(rdata2.MaxWireSize(), UINT64_C(17));
286   EXPECT_EQ(rdata2.ptr_domain(), (DomainName{"testing", "local"}));
287 }
288 
TEST(MdnsPtrRecordRdataTest,Compare)289 TEST(MdnsPtrRecordRdataTest, Compare) {
290   PtrRecordRdata rdata1(DomainName{"testing", "local"});
291   PtrRecordRdata rdata2(DomainName{"testing", "local"});
292   PtrRecordRdata rdata3(DomainName{"device", "local"});
293 
294   EXPECT_EQ(rdata1, rdata2);
295   EXPECT_NE(rdata1, rdata3);
296 
297   EXPECT_TRUE(VerifyTypeImplementsAbslHashCorrectly({rdata1, rdata2, rdata3}));
298 }
299 
TEST(MdnsPtrRecordRdataTest,CopyAndMove)300 TEST(MdnsPtrRecordRdataTest, CopyAndMove) {
301   TestCopyAndMove(PtrRecordRdata(DomainName{"testing", "local"}));
302 }
303 
TEST(MdnsTxtRecordRdataTest,Construct)304 TEST(MdnsTxtRecordRdataTest, Construct) {
305   TxtRecordRdata rdata1;
306   EXPECT_EQ(rdata1.MaxWireSize(), UINT64_C(3));
307   EXPECT_EQ(rdata1.texts(), std::vector<std::string>());
308 
309   TxtRecordRdata rdata2 = MakeTxtRecord({"foo=1", "bar=2"});
310   EXPECT_EQ(rdata2.MaxWireSize(), UINT64_C(14));
311   EXPECT_EQ(rdata2.texts(), (std::vector<std::string>{"foo=1", "bar=2"}));
312 }
313 
TEST(MdnsTxtRecordRdataTest,Compare)314 TEST(MdnsTxtRecordRdataTest, Compare) {
315   TxtRecordRdata rdata1 = MakeTxtRecord({"foo=1", "bar=2"});
316   TxtRecordRdata rdata2 = MakeTxtRecord({"foo=1", "bar=2"});
317   TxtRecordRdata rdata3 = MakeTxtRecord({"foo=1"});
318   TxtRecordRdata rdata4 = MakeTxtRecord({"E=mc^2", "F=ma"});
319 
320   EXPECT_EQ(rdata1, rdata2);
321   EXPECT_NE(rdata1, rdata3);
322   EXPECT_NE(rdata1, rdata4);
323 
324   EXPECT_TRUE(
325       VerifyTypeImplementsAbslHashCorrectly({rdata1, rdata2, rdata3, rdata4}));
326 }
327 
TEST(MdnsTxtRecordRdataTest,CopyAndMove)328 TEST(MdnsTxtRecordRdataTest, CopyAndMove) {
329   TestCopyAndMove(MakeTxtRecord({"foo=1", "bar=2"}));
330 }
331 
TEST(MdnsNsecRecordRdataTest,Construct)332 TEST(MdnsNsecRecordRdataTest, Construct) {
333   const DomainName domain{"testing", "local"};
334   NsecRecordRdata rdata(domain);
335   EXPECT_EQ(rdata.MaxWireSize(), domain.MaxWireSize());
336   EXPECT_EQ(rdata.next_domain_name(), domain);
337 
338   rdata = NsecRecordRdata(domain, DnsType::kA);
339   // It takes 3 bytes to encode the kA and kSRV records because:
340   // - Both record types have value less than 256, so they are both in window
341   //   block 1.
342   // - The bitmap length for this block is always a single byte
343   // - DnsType kA = 1 (encoded in byte 1)
344   // So the full encoded version is:
345   //   00000000 00000001 01000000
346   //   |window| | size | | 0-7  |
347   // For a total of 3 bytes.
348   EXPECT_EQ(rdata.encoded_types(), (std::vector<uint8_t>{0x00, 0x01, 0x40}));
349   EXPECT_EQ(rdata.MaxWireSize(), domain.MaxWireSize() + 3);
350   EXPECT_EQ(rdata.next_domain_name(), domain);
351 
352   // It takes 8 bytes to encode the kA and kSRV records because:
353   // - Both record types have value less than 256, so they are both in window
354   //   block 1.
355   // - The bitmap length for this block is always a single byte
356   // - DnsTypes  kTXT = 16 (encoded in byte 3)
357   // So the full encoded version is:
358   //   00000000 00000011 00000000 00000000 10000000
359   //   |window| | size | | 0-7  | | 8-15 | |16-23 |
360   // For a total of 5 bytes.
361   rdata = NsecRecordRdata(domain, DnsType::kTXT);
362   EXPECT_EQ(rdata.encoded_types(),
363             (std::vector<uint8_t>{0x00, 0x03, 0x00, 0x00, 0x80}));
364   EXPECT_EQ(rdata.MaxWireSize(), domain.MaxWireSize() + 5);
365   EXPECT_EQ(rdata.next_domain_name(), domain);
366 
367   // It takes 8 bytes to encode the kA and kSRV records because:
368   // - Both record types have value less than 256, so they are both in window
369   //   block 1.
370   // - The bitmap length for this block is always a single byte
371   // - DnsTypes kSRV = 33 (encoded in byte 5)
372   // So the full encoded version is:
373   //   00000000 00000101 00000000 00000000 00000000 00000000 01000000
374   //   |window| | size | | 0-7  | | 8-15 | |16-23 | |24-31 | |32-39 |
375   // For a total of 7 bytes.
376   rdata = NsecRecordRdata(domain, DnsType::kSRV);
377   EXPECT_EQ(rdata.encoded_types(),
378             (std::vector<uint8_t>{0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x40}));
379   EXPECT_EQ(rdata.MaxWireSize(), domain.MaxWireSize() + 7);
380   EXPECT_EQ(rdata.next_domain_name(), domain);
381 
382   // It takes 8 bytes to encode the kA and kSRV records because:
383   // - Both record types have value less than 256, so they are both in window
384   //   block 1.
385   // - The bitmap length for this block is always a single byte
386   // - DnsTypes kNSEC = 47
387   // So the full encoded version is:
388   //   00000000 00000110 00000000 00000000 00000000 00000000 0000000  00000001
389   //   |window| | size | | 0-7  | | 8-15 | |16-23 | |24-31 | |32-39 | |40-47 |
390   // For a total of 8 bytes.
391   rdata = NsecRecordRdata(domain, DnsType::kNSEC);
392   EXPECT_EQ(
393       rdata.encoded_types(),
394       (std::vector<uint8_t>{0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}));
395   EXPECT_EQ(rdata.MaxWireSize(), domain.MaxWireSize() + 8);
396   EXPECT_EQ(rdata.next_domain_name(), domain);
397 
398   // It takes 8 bytes to encode the kA and kSRV records because:
399   // - Both record types have value less than 256, so they are both in window
400   //   block 1.
401   // - The bitmap length for this block is always a single byte
402   // - DnsTypes kNSEC = 255
403   // So 32 bits are required for the bitfield, for a total of 34 bits.
404   rdata = NsecRecordRdata(domain, DnsType::kANY);
405   std::vector<uint8_t> results{0x00, 32};
406   for (int i = 1; i < 32; i++) {
407     results.push_back(0x00);
408   }
409   results.push_back(0x01);
410   EXPECT_EQ(rdata.encoded_types(), results);
411   EXPECT_EQ(rdata.MaxWireSize(), domain.MaxWireSize() + 34);
412   EXPECT_EQ(rdata.next_domain_name(), domain);
413 
414   // It takes 8 bytes to encode the kA and kSRV records because:
415   // - Both record types have value less than 256, so they are both in window
416   //   block 1.
417   // - The bitmap length for this block is always a single byte
418   // - DnsTypes have the following values:
419   //   - kA = 1 (encoded in byte 1)
420   //     kTXT = 16 (encoded in byte 3)
421   //   - kSRV = 33 (encoded in byte 5)
422   //   - kNSEC = 47 (encoded in 6 bytes)
423   // - The largest of these is 47, so 6 bytes are needed to encode this data.
424   // So the full encoded version is:
425   //   00000000 00000110 01000000 00000000 10000000 00000000 0100000  00000001
426   //   |window| | size | | 0-7  | | 8-15 | |16-23 | |24-31 | |32-39 | |40-47 |
427   // For a total of 8 bytes.
428   rdata = NsecRecordRdata(domain, DnsType::kA, DnsType::kTXT, DnsType::kSRV,
429                           DnsType::kNSEC);
430   EXPECT_EQ(
431       rdata.encoded_types(),
432       (std::vector<uint8_t>{0x00, 0x06, 0x40, 0x00, 0x80, 0x00, 0x40, 0x01}));
433   EXPECT_EQ(rdata.MaxWireSize(), domain.MaxWireSize() + 8);
434   EXPECT_EQ(rdata.next_domain_name(), domain);
435 }
436 
TEST(MdnsNsecRecordRdataTest,Compare)437 TEST(MdnsNsecRecordRdataTest, Compare) {
438   const DomainName domain{"testing", "local"};
439   const NsecRecordRdata rdata1(domain, DnsType::kA, DnsType::kSRV);
440   const NsecRecordRdata rdata2(domain, DnsType::kSRV, DnsType::kA);
441   const NsecRecordRdata rdata3(domain, DnsType::kSRV, DnsType::kA,
442                                DnsType::kAAAA);
443   const NsecRecordRdata rdata4(domain, DnsType::kSRV, DnsType::kAAAA);
444 
445   // Ensure equal Rdata values are evaluated as equal.
446   EXPECT_EQ(rdata1, rdata1);
447   EXPECT_EQ(rdata1, rdata2);
448   EXPECT_EQ(rdata2, rdata1);
449 
450   // Ensure different Rdata values are not.
451   EXPECT_NE(rdata1, rdata3);
452   EXPECT_NE(rdata1, rdata4);
453   EXPECT_NE(rdata3, rdata4);
454 
455   EXPECT_TRUE(
456       VerifyTypeImplementsAbslHashCorrectly({rdata1, rdata2, rdata3, rdata4}));
457 }
458 
TEST(MdnsNsecRecordRdataTest,CopyAndMove)459 TEST(MdnsNsecRecordRdataTest, CopyAndMove) {
460   TestCopyAndMove(NsecRecordRdata(DomainName{"testing", "local"}, DnsType::kA,
461                                   DnsType::kSRV));
462 }
463 
TEST(MdnsOptRecordRdataTest,Construct)464 TEST(MdnsOptRecordRdataTest, Construct) {
465   OptRecordRdata rdata1;
466   EXPECT_EQ(rdata1.MaxWireSize(), size_t{0});
467   EXPECT_EQ(rdata1.options().size(), size_t{0});
468 
469   OptRecordRdata::Option opt1{12, 34, {0x12, 0x34}};
470   OptRecordRdata::Option opt2{12, 34, {0x12, 0x34}};
471   OptRecordRdata::Option opt3{12, 34, {0x12, 0x34, 0x56}};
472   OptRecordRdata::Option opt4{34, 12, {0x00}};
473   OptRecordRdata::Option opt5{12, 12, {0x12, 0x34}};
474   rdata1 = OptRecordRdata(opt1, opt2, opt3, opt4, opt5);
475   EXPECT_EQ(rdata1.MaxWireSize(), size_t{30});
476 
477   ASSERT_EQ(rdata1.options().size(), size_t{5});
478   EXPECT_EQ(rdata1.options()[0], opt5);
479   EXPECT_EQ(rdata1.options()[1], opt1);
480   EXPECT_EQ(rdata1.options()[2], opt2);
481   EXPECT_EQ(rdata1.options()[3], opt3);
482   EXPECT_EQ(rdata1.options()[4], opt4);
483 }
484 
TEST(MdnsOptRecordRdataTest,Compare)485 TEST(MdnsOptRecordRdataTest, Compare) {
486   OptRecordRdata::Option opt1{12, 34, {0x12, 0x34}};
487   OptRecordRdata::Option opt2{12, 34, {0x12, 0x34}};
488   OptRecordRdata::Option opt3{12, 34, {0x12, 0x56}};
489   OptRecordRdata rdata1(opt1);
490   OptRecordRdata rdata2(opt2);
491   OptRecordRdata rdata3(opt3);
492   OptRecordRdata rdata4;
493 
494   EXPECT_EQ(rdata1, rdata1);
495   EXPECT_EQ(rdata2, rdata2);
496   EXPECT_EQ(rdata3, rdata3);
497   EXPECT_EQ(rdata4, rdata4);
498 
499   EXPECT_EQ(rdata1, rdata2);
500   EXPECT_NE(rdata1, rdata3);
501   EXPECT_NE(rdata1, rdata4);
502   EXPECT_NE(rdata2, rdata3);
503   EXPECT_NE(rdata2, rdata4);
504   EXPECT_NE(rdata3, rdata4);
505 
506   EXPECT_TRUE(
507       VerifyTypeImplementsAbslHashCorrectly({rdata1, rdata2, rdata3, rdata4}));
508 }
509 
TEST(MdnsOptRecordRdataTest,CopyAndMove)510 TEST(MdnsOptRecordRdataTest, CopyAndMove) {
511   OptRecordRdata::Option opt1{12, 34, {0x12, 0x34}};
512   TestCopyAndMove(OptRecordRdata(opt1));
513 }
514 
TEST(MdnsRecordTest,Construct)515 TEST(MdnsRecordTest, Construct) {
516   MdnsRecord record1;
517   EXPECT_EQ(record1.MaxWireSize(), UINT64_C(11));
518   EXPECT_EQ(record1.name(), DomainName());
519   EXPECT_EQ(record1.dns_type(), static_cast<DnsType>(0));
520   EXPECT_EQ(record1.dns_class(), static_cast<DnsClass>(0));
521   EXPECT_EQ(record1.record_type(), RecordType::kShared);
522   EXPECT_EQ(record1.ttl(),
523             std::chrono::seconds(255));  // 255 is kDefaultRecordTTLSeconds
524   EXPECT_EQ(record1.rdata(), Rdata(RawRecordRdata()));
525 
526   MdnsRecord record2(DomainName{"hostname", "local"}, DnsType::kPTR,
527                      DnsClass::kIN, RecordType::kUnique, kTtl,
528                      PtrRecordRdata(DomainName{"testing", "local"}));
529   EXPECT_EQ(record2.MaxWireSize(), UINT64_C(41));
530   EXPECT_EQ(record2.name(), (DomainName{"hostname", "local"}));
531   EXPECT_EQ(record2.dns_type(), DnsType::kPTR);
532   EXPECT_EQ(record2.dns_class(), DnsClass::kIN);
533   EXPECT_EQ(record2.record_type(), RecordType::kUnique);
534   EXPECT_EQ(record2.ttl(), kTtl);
535   EXPECT_EQ(record2.rdata(),
536             Rdata(PtrRecordRdata(DomainName{"testing", "local"})));
537 }
538 
TEST(MdnsRecordTest,Compare)539 TEST(MdnsRecordTest, Compare) {
540   const MdnsRecord record1(DomainName{"hostname", "local"}, DnsType::kPTR,
541                            DnsClass::kIN, RecordType::kShared, kTtl,
542                            PtrRecordRdata(DomainName{"testing", "local"}));
543   const MdnsRecord record2(DomainName{"hostname", "local"}, DnsType::kPTR,
544                            DnsClass::kIN, RecordType::kShared, kTtl,
545                            PtrRecordRdata(DomainName{"testing", "local"}));
546   const MdnsRecord record3(DomainName{"othername", "local"}, DnsType::kPTR,
547                            DnsClass::kIN, RecordType::kShared, kTtl,
548                            PtrRecordRdata(DomainName{"testing", "local"}));
549   const MdnsRecord record4(DomainName{"hostname", "local"}, DnsType::kA,
550                            DnsClass::kIN, RecordType::kShared, kTtl,
551                            ARecordRdata(IPAddress{8, 8, 8, 8}));
552   const MdnsRecord record5(DomainName{"hostname", "local"}, DnsType::kPTR,
553                            DnsClass::kIN, RecordType::kUnique, kTtl,
554                            PtrRecordRdata(DomainName{"testing", "local"}));
555   const MdnsRecord record6(DomainName{"hostname", "local"}, DnsType::kPTR,
556                            DnsClass::kIN, RecordType::kShared,
557                            std::chrono::seconds(200),
558                            PtrRecordRdata(DomainName{"testing", "local"}));
559   const MdnsRecord record7(DomainName{"hostname", "local"}, DnsType::kPTR,
560                            DnsClass::kIN, RecordType::kShared, kTtl,
561                            PtrRecordRdata(DomainName{"device", "local"}));
562   const MdnsRecord record8(
563       DomainName{"testing", "local"}, DnsType::kNSEC, DnsClass::kIN,
564       RecordType::kUnique, std::chrono::seconds(120),
565       NsecRecordRdata(DomainName{"testing", "local"}, DnsType::kA));
566   const MdnsRecord record9(
567       DomainName{"testing", "local"}, DnsType::kNSEC, DnsClass::kIN,
568       RecordType::kUnique, std::chrono::seconds(120),
569       NsecRecordRdata(DomainName{"testing", "local"}, DnsType::kAAAA));
570 
571   EXPECT_EQ(record1, record2);
572 
573   // Account for intentional differences between > / < and = / !=. This is
574   // unfortunate but required difference for > / < per RFC.
575   EXPECT_NE(record1, record6);
576   ASSERT_FALSE(record1 > record6);
577   ASSERT_FALSE(record6 > record1);
578 
579   std::vector<const MdnsRecord*> records_sorted{
580       &record4, &record7, &record1, &record5, &record3, &record8, &record9};
581   for (size_t i = 0; i < records_sorted.size(); i++) {
582     for (size_t j = i + 1; j < records_sorted.size(); j++) {
583       EXPECT_NE(*records_sorted[i], *records_sorted[j])
584           << "failure for i=" << i << " , j=" << j;
585       EXPECT_GT(*records_sorted[j], *records_sorted[i])
586           << "failure for i=" << i << " , j=" << j;
587       EXPECT_LT(*records_sorted[i], *records_sorted[j])
588           << "failure for i=" << i << " , j=" << j;
589     }
590   }
591 
592   EXPECT_TRUE(VerifyTypeImplementsAbslHashCorrectly(
593       {record1, record2, record3, record4, record5, record6, record7, record8,
594        record9}));
595 }
596 
TEST(MdnsRecordTest,CopyAndMove)597 TEST(MdnsRecordTest, CopyAndMove) {
598   MdnsRecord record(DomainName{"hostname", "local"}, DnsType::kPTR,
599                     DnsClass::kIN, RecordType::kUnique, kTtl,
600                     PtrRecordRdata(DomainName{"testing", "local"}));
601   TestCopyAndMove(record);
602 }
603 
TEST(MdnsQuestionTest,Construct)604 TEST(MdnsQuestionTest, Construct) {
605   MdnsQuestion question1;
606   EXPECT_EQ(question1.MaxWireSize(), UINT64_C(5));
607   EXPECT_EQ(question1.name(), DomainName());
608   EXPECT_EQ(question1.dns_type(), static_cast<DnsType>(0));
609   EXPECT_EQ(question1.dns_class(), static_cast<DnsClass>(0));
610   EXPECT_EQ(question1.response_type(), ResponseType::kMulticast);
611 
612   MdnsQuestion question2(DomainName{"testing", "local"}, DnsType::kPTR,
613                          DnsClass::kIN, ResponseType::kUnicast);
614   EXPECT_EQ(question2.MaxWireSize(), UINT64_C(19));
615   EXPECT_EQ(question2.name(), (DomainName{"testing", "local"}));
616   EXPECT_EQ(question2.dns_type(), DnsType::kPTR);
617   EXPECT_EQ(question2.dns_class(), DnsClass::kIN);
618   EXPECT_EQ(question2.response_type(), ResponseType::kUnicast);
619 }
620 
TEST(MdnsQuestionTest,Compare)621 TEST(MdnsQuestionTest, Compare) {
622   MdnsQuestion question1(DomainName{"testing", "local"}, DnsType::kPTR,
623                          DnsClass::kIN, ResponseType::kMulticast);
624   MdnsQuestion question2(DomainName{"testing", "local"}, DnsType::kPTR,
625                          DnsClass::kIN, ResponseType::kMulticast);
626   MdnsQuestion question3(DomainName{"hostname", "local"}, DnsType::kPTR,
627                          DnsClass::kIN, ResponseType::kMulticast);
628   MdnsQuestion question4(DomainName{"testing", "local"}, DnsType::kA,
629                          DnsClass::kIN, ResponseType::kMulticast);
630   MdnsQuestion question5(DomainName{"hostname", "local"}, DnsType::kPTR,
631                          DnsClass::kIN, ResponseType::kUnicast);
632 
633   EXPECT_EQ(question1, question2);
634   EXPECT_NE(question1, question3);
635   EXPECT_NE(question1, question4);
636   EXPECT_NE(question1, question5);
637 
638   EXPECT_TRUE(VerifyTypeImplementsAbslHashCorrectly(
639       {question1, question2, question3, question4, question5}));
640 }
641 
TEST(MdnsQuestionTest,CopyAndMove)642 TEST(MdnsQuestionTest, CopyAndMove) {
643   MdnsQuestion question(DomainName{"testing", "local"}, DnsType::kPTR,
644                         DnsClass::kIN, ResponseType::kUnicast);
645   TestCopyAndMove(question);
646 }
647 
TEST(MdnsMessageTest,Construct)648 TEST(MdnsMessageTest, Construct) {
649   MdnsMessage message1;
650   EXPECT_EQ(message1.MaxWireSize(), UINT64_C(12));
651   EXPECT_EQ(message1.id(), UINT16_C(0));
652   EXPECT_EQ(message1.type(), MessageType::Query);
653   EXPECT_EQ(message1.questions().size(), UINT64_C(0));
654   EXPECT_EQ(message1.answers().size(), UINT64_C(0));
655   EXPECT_EQ(message1.authority_records().size(), UINT64_C(0));
656   EXPECT_EQ(message1.additional_records().size(), UINT64_C(0));
657 
658   MdnsQuestion question(DomainName{"testing", "local"}, DnsType::kPTR,
659                         DnsClass::kIN, ResponseType::kUnicast);
660   MdnsRecord record1(DomainName{"record1"}, DnsType::kA, DnsClass::kIN,
661                      RecordType::kShared, kTtl,
662                      ARecordRdata(IPAddress{172, 0, 0, 1}));
663   MdnsRecord record2(DomainName{"record2"}, DnsType::kTXT, DnsClass::kIN,
664                      RecordType::kShared, kTtl,
665                      MakeTxtRecord({"foo=1", "bar=2"}));
666   MdnsRecord record3(DomainName{"record3"}, DnsType::kPTR, DnsClass::kIN,
667                      RecordType::kShared, kTtl,
668                      PtrRecordRdata(DomainName{"device", "local"}));
669 
670   MdnsMessage message2(123, MessageType::Response);
671   EXPECT_EQ(message2.MaxWireSize(), UINT64_C(12));
672   EXPECT_EQ(message2.id(), UINT16_C(123));
673   EXPECT_EQ(message2.type(), MessageType::Response);
674   EXPECT_EQ(message2.questions().size(), UINT64_C(0));
675   EXPECT_EQ(message2.answers().size(), UINT64_C(0));
676   EXPECT_EQ(message2.authority_records().size(), UINT64_C(0));
677   EXPECT_EQ(message2.additional_records().size(), UINT64_C(0));
678 
679   message2.AddQuestion(question);
680   message2.AddAnswer(record1);
681   message2.AddAuthorityRecord(record2);
682   message2.AddAdditionalRecord(record3);
683 
684   EXPECT_EQ(message2.MaxWireSize(), UINT64_C(118));
685   ASSERT_EQ(message2.questions().size(), UINT64_C(1));
686   ASSERT_EQ(message2.answers().size(), UINT64_C(1));
687   ASSERT_EQ(message2.authority_records().size(), UINT64_C(1));
688   ASSERT_EQ(message2.additional_records().size(), UINT64_C(1));
689 
690   EXPECT_EQ(message2.questions()[0], question);
691   EXPECT_EQ(message2.answers()[0], record1);
692   EXPECT_EQ(message2.authority_records()[0], record2);
693   EXPECT_EQ(message2.additional_records()[0], record3);
694 
695   MdnsMessage message3(
696       123, MessageType::Response, std::vector<MdnsQuestion>{question},
697       std::vector<MdnsRecord>{record1}, std::vector<MdnsRecord>{record2},
698       std::vector<MdnsRecord>{record3});
699 
700   EXPECT_EQ(message3.MaxWireSize(), UINT64_C(118));
701   ASSERT_EQ(message3.questions().size(), UINT64_C(1));
702   ASSERT_EQ(message3.answers().size(), UINT64_C(1));
703   ASSERT_EQ(message3.authority_records().size(), UINT64_C(1));
704   ASSERT_EQ(message3.additional_records().size(), UINT64_C(1));
705 
706   EXPECT_EQ(message3.questions()[0], question);
707   EXPECT_EQ(message3.answers()[0], record1);
708   EXPECT_EQ(message3.authority_records()[0], record2);
709   EXPECT_EQ(message3.additional_records()[0], record3);
710 }
711 
TEST(MdnsMessageTest,Compare)712 TEST(MdnsMessageTest, Compare) {
713   MdnsQuestion question(DomainName{"testing", "local"}, DnsType::kPTR,
714                         DnsClass::kIN, ResponseType::kUnicast);
715   MdnsRecord record1(DomainName{"record1"}, DnsType::kA, DnsClass::kIN,
716                      RecordType::kShared, kTtl,
717                      ARecordRdata(IPAddress{172, 0, 0, 1}));
718   MdnsRecord record2(DomainName{"record2"}, DnsType::kTXT, DnsClass::kIN,
719                      RecordType::kShared, kTtl,
720                      MakeTxtRecord({"foo=1", "bar=2"}));
721   MdnsRecord record3(DomainName{"record3"}, DnsType::kPTR, DnsClass::kIN,
722                      RecordType::kShared, kTtl,
723                      PtrRecordRdata(DomainName{"device", "local"}));
724 
725   MdnsMessage message1(
726       123, MessageType::Response, std::vector<MdnsQuestion>{question},
727       std::vector<MdnsRecord>{record1}, std::vector<MdnsRecord>{record2},
728       std::vector<MdnsRecord>{record3});
729   MdnsMessage message2(
730       123, MessageType::Response, std::vector<MdnsQuestion>{question},
731       std::vector<MdnsRecord>{record1}, std::vector<MdnsRecord>{record2},
732       std::vector<MdnsRecord>{record3});
733   MdnsMessage message3(
734       456, MessageType::Response, std::vector<MdnsQuestion>{question},
735       std::vector<MdnsRecord>{record1}, std::vector<MdnsRecord>{record2},
736       std::vector<MdnsRecord>{record3});
737   MdnsMessage message4(
738       123, MessageType::Query, std::vector<MdnsQuestion>{question},
739       std::vector<MdnsRecord>{record1}, std::vector<MdnsRecord>{record2},
740       std::vector<MdnsRecord>{record3});
741   MdnsMessage message5(123, MessageType::Response, std::vector<MdnsQuestion>{},
742                        std::vector<MdnsRecord>{record1},
743                        std::vector<MdnsRecord>{record2},
744                        std::vector<MdnsRecord>{record3});
745   MdnsMessage message6(
746       123, MessageType::Response, std::vector<MdnsQuestion>{question},
747       std::vector<MdnsRecord>{}, std::vector<MdnsRecord>{record2},
748       std::vector<MdnsRecord>{record3});
749   MdnsMessage message7(
750       123, MessageType::Response, std::vector<MdnsQuestion>{question},
751       std::vector<MdnsRecord>{record1}, std::vector<MdnsRecord>{},
752       std::vector<MdnsRecord>{record3});
753   MdnsMessage message8(
754       123, MessageType::Response, std::vector<MdnsQuestion>{question},
755       std::vector<MdnsRecord>{record1}, std::vector<MdnsRecord>{record2},
756       std::vector<MdnsRecord>{});
757 
758   EXPECT_EQ(message1, message2);
759   EXPECT_NE(message1, message3);
760   EXPECT_NE(message1, message4);
761   EXPECT_NE(message1, message5);
762   EXPECT_NE(message1, message6);
763   EXPECT_NE(message1, message7);
764   EXPECT_NE(message1, message8);
765 
766   EXPECT_TRUE(VerifyTypeImplementsAbslHashCorrectly(
767       {message1, message2, message3, message4, message5, message6, message7,
768        message8}));
769 }
770 
TEST(MdnsMessageTest,CopyAndMove)771 TEST(MdnsMessageTest, CopyAndMove) {
772   MdnsQuestion question(DomainName{"testing", "local"}, DnsType::kPTR,
773                         DnsClass::kIN, ResponseType::kUnicast);
774   MdnsRecord record1(DomainName{"record1"}, DnsType::kA, DnsClass::kIN,
775                      RecordType::kShared, kTtl,
776                      ARecordRdata(IPAddress{172, 0, 0, 1}));
777   MdnsRecord record2(DomainName{"record2"}, DnsType::kTXT, DnsClass::kIN,
778                      RecordType::kShared, kTtl,
779                      MakeTxtRecord({"foo=1", "bar=2"}));
780   MdnsRecord record3(DomainName{"record3"}, DnsType::kPTR, DnsClass::kIN,
781                      RecordType::kShared, kTtl,
782                      PtrRecordRdata(DomainName{"device", "local"}));
783   MdnsMessage message(
784       123, MessageType::Response, std::vector<MdnsQuestion>{question},
785       std::vector<MdnsRecord>{record1}, std::vector<MdnsRecord>{record2},
786       std::vector<MdnsRecord>{record3});
787   TestCopyAndMove(message);
788 }
789 
TEST(MdnsRecordOperations,CanBeProcessed)790 TEST(MdnsRecordOperations, CanBeProcessed) {
791   EXPECT_FALSE(CanBeProcessed(static_cast<DnsType>(1234)));
792   EXPECT_FALSE(CanBeProcessed(static_cast<DnsType>(222)));
793   EXPECT_FALSE(CanBeProcessed(static_cast<DnsType>(8973)));
794 }
795 
796 }  // namespace discovery
797 }  // namespace openscreen
798