xref: /aosp_15_r20/external/openscreen/discovery/mdns/mdns_receiver_unittest.cc (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
1*3f982cf4SFabien Sanglard // Copyright 2019 The Chromium Authors. All rights reserved.
2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be
3*3f982cf4SFabien Sanglard // found in the LICENSE file.
4*3f982cf4SFabien Sanglard 
5*3f982cf4SFabien Sanglard #include "discovery/mdns/mdns_receiver.h"
6*3f982cf4SFabien Sanglard 
7*3f982cf4SFabien Sanglard #include <memory>
8*3f982cf4SFabien Sanglard #include <utility>
9*3f982cf4SFabien Sanglard #include <vector>
10*3f982cf4SFabien Sanglard 
11*3f982cf4SFabien Sanglard #include "discovery/common/config.h"
12*3f982cf4SFabien Sanglard #include "discovery/mdns/mdns_records.h"
13*3f982cf4SFabien Sanglard #include "gmock/gmock.h"
14*3f982cf4SFabien Sanglard #include "gtest/gtest.h"
15*3f982cf4SFabien Sanglard #include "platform/api/time.h"
16*3f982cf4SFabien Sanglard #include "platform/test/fake_udp_socket.h"
17*3f982cf4SFabien Sanglard 
18*3f982cf4SFabien Sanglard namespace openscreen {
19*3f982cf4SFabien Sanglard namespace discovery {
20*3f982cf4SFabien Sanglard 
21*3f982cf4SFabien Sanglard using testing::_;
22*3f982cf4SFabien Sanglard using testing::Return;
23*3f982cf4SFabien Sanglard 
24*3f982cf4SFabien Sanglard class MockMdnsReceiverDelegate : public MdnsReceiver::ResponseClient {
25*3f982cf4SFabien Sanglard  public:
26*3f982cf4SFabien Sanglard   MOCK_METHOD(void, OnMessageReceived, (const MdnsMessage&));
27*3f982cf4SFabien Sanglard };
28*3f982cf4SFabien Sanglard 
TEST(MdnsReceiverTest,ReceiveQuery)29*3f982cf4SFabien Sanglard TEST(MdnsReceiverTest, ReceiveQuery) {
30*3f982cf4SFabien Sanglard   // clang-format off
31*3f982cf4SFabien Sanglard   const std::vector<uint8_t> kQueryBytes = {
32*3f982cf4SFabien Sanglard       0x00, 0x01,  // ID = 1
33*3f982cf4SFabien Sanglard       0x00, 0x00,  // FLAGS = None
34*3f982cf4SFabien Sanglard       0x00, 0x01,  // Question count
35*3f982cf4SFabien Sanglard       0x00, 0x00,  // Answer count
36*3f982cf4SFabien Sanglard       0x00, 0x00,  // Authority count
37*3f982cf4SFabien Sanglard       0x00, 0x00,  // Additional count
38*3f982cf4SFabien Sanglard       // Question
39*3f982cf4SFabien Sanglard       0x07, 't', 'e', 's', 't', 'i', 'n', 'g',
40*3f982cf4SFabien Sanglard       0x05, 'l', 'o', 'c', 'a', 'l',
41*3f982cf4SFabien Sanglard       0x00,
42*3f982cf4SFabien Sanglard       0x00, 0x01,  // TYPE = A (1)
43*3f982cf4SFabien Sanglard       0x00, 0x01,  // CLASS = IN (1)
44*3f982cf4SFabien Sanglard   };
45*3f982cf4SFabien Sanglard   // clang-format on
46*3f982cf4SFabien Sanglard 
47*3f982cf4SFabien Sanglard   Config config;
48*3f982cf4SFabien Sanglard   FakeUdpSocket socket;
49*3f982cf4SFabien Sanglard   MockMdnsReceiverDelegate delegate;
50*3f982cf4SFabien Sanglard   MdnsReceiver receiver(config);
51*3f982cf4SFabien Sanglard   receiver.SetQueryCallback(
52*3f982cf4SFabien Sanglard       [&delegate](const MdnsMessage& message, const IPEndpoint& endpoint) {
53*3f982cf4SFabien Sanglard         delegate.OnMessageReceived(message);
54*3f982cf4SFabien Sanglard       });
55*3f982cf4SFabien Sanglard   receiver.Start();
56*3f982cf4SFabien Sanglard 
57*3f982cf4SFabien Sanglard   MdnsQuestion question(DomainName{"testing", "local"}, DnsType::kA,
58*3f982cf4SFabien Sanglard                         DnsClass::kIN, ResponseType::kMulticast);
59*3f982cf4SFabien Sanglard   MdnsMessage message(1, MessageType::Query);
60*3f982cf4SFabien Sanglard   message.AddQuestion(question);
61*3f982cf4SFabien Sanglard 
62*3f982cf4SFabien Sanglard   UdpPacket packet(kQueryBytes.data(), kQueryBytes.data() + kQueryBytes.size());
63*3f982cf4SFabien Sanglard   packet.set_source(
64*3f982cf4SFabien Sanglard       IPEndpoint{.address = IPAddress(192, 168, 1, 1), .port = 31337});
65*3f982cf4SFabien Sanglard   packet.set_destination(
66*3f982cf4SFabien Sanglard       IPEndpoint{.address = IPAddress(kDefaultMulticastGroupIPv4),
67*3f982cf4SFabien Sanglard                  .port = kDefaultMulticastPort});
68*3f982cf4SFabien Sanglard 
69*3f982cf4SFabien Sanglard   // Imitate a call to OnRead from NetworkRunner by calling it manually here
70*3f982cf4SFabien Sanglard   EXPECT_CALL(delegate, OnMessageReceived(message)).Times(1);
71*3f982cf4SFabien Sanglard   receiver.OnRead(&socket, std::move(packet));
72*3f982cf4SFabien Sanglard 
73*3f982cf4SFabien Sanglard   receiver.Stop();
74*3f982cf4SFabien Sanglard }
75*3f982cf4SFabien Sanglard 
TEST(MdnsReceiverTest,ReceiveResponse)76*3f982cf4SFabien Sanglard TEST(MdnsReceiverTest, ReceiveResponse) {
77*3f982cf4SFabien Sanglard   // clang-format off
78*3f982cf4SFabien Sanglard   const std::vector<uint8_t> kResponseBytes = {
79*3f982cf4SFabien Sanglard       0x00, 0x01,  // ID = 1
80*3f982cf4SFabien Sanglard       0x84, 0x00,  // FLAGS = AA | RESPONSE
81*3f982cf4SFabien Sanglard       0x00, 0x00,  // Question count
82*3f982cf4SFabien Sanglard       0x00, 0x01,  // Answer count
83*3f982cf4SFabien Sanglard       0x00, 0x00,  // Authority count
84*3f982cf4SFabien Sanglard       0x00, 0x00,  // Additional count
85*3f982cf4SFabien Sanglard       // Answer
86*3f982cf4SFabien Sanglard       0x07, 't', 'e', 's', 't', 'i', 'n', 'g',
87*3f982cf4SFabien Sanglard       0x05, 'l', 'o', 'c', 'a', 'l',
88*3f982cf4SFabien Sanglard       0x00,
89*3f982cf4SFabien Sanglard       0x00, 0x01,              // TYPE = A (1)
90*3f982cf4SFabien Sanglard       0x00, 0x01,              // CLASS = IN (1)
91*3f982cf4SFabien Sanglard       0x00, 0x00, 0x00, 0x78,  // TTL = 120 seconds
92*3f982cf4SFabien Sanglard       0x00, 0x04,              // RDLENGTH = 4 bytes
93*3f982cf4SFabien Sanglard       0xac, 0x00, 0x00, 0x01,  // 172.0.0.1
94*3f982cf4SFabien Sanglard   };
95*3f982cf4SFabien Sanglard 
96*3f982cf4SFabien Sanglard   constexpr uint16_t kIPv6AddressHextets[] = {
97*3f982cf4SFabien Sanglard       0xfe80, 0x0000, 0x0000, 0x0000,
98*3f982cf4SFabien Sanglard       0x0202, 0xb3ff, 0xfe1e, 0x8329,
99*3f982cf4SFabien Sanglard   };
100*3f982cf4SFabien Sanglard   // clang-format on
101*3f982cf4SFabien Sanglard 
102*3f982cf4SFabien Sanglard   Config config;
103*3f982cf4SFabien Sanglard   FakeUdpSocket socket;
104*3f982cf4SFabien Sanglard   MockMdnsReceiverDelegate delegate;
105*3f982cf4SFabien Sanglard   MdnsReceiver receiver(config);
106*3f982cf4SFabien Sanglard   receiver.AddResponseCallback(&delegate);
107*3f982cf4SFabien Sanglard   receiver.Start();
108*3f982cf4SFabien Sanglard 
109*3f982cf4SFabien Sanglard   MdnsRecord record(DomainName{"testing", "local"}, DnsType::kA, DnsClass::kIN,
110*3f982cf4SFabien Sanglard                     RecordType::kShared, std::chrono::seconds(120),
111*3f982cf4SFabien Sanglard                     ARecordRdata(IPAddress{172, 0, 0, 1}));
112*3f982cf4SFabien Sanglard   MdnsMessage message(1, MessageType::Response);
113*3f982cf4SFabien Sanglard   message.AddAnswer(record);
114*3f982cf4SFabien Sanglard 
115*3f982cf4SFabien Sanglard   UdpPacket packet(kResponseBytes.size());
116*3f982cf4SFabien Sanglard   packet.assign(kResponseBytes.data(),
117*3f982cf4SFabien Sanglard                 kResponseBytes.data() + kResponseBytes.size());
118*3f982cf4SFabien Sanglard   packet.set_source(
119*3f982cf4SFabien Sanglard       IPEndpoint{.address = IPAddress(kIPv6AddressHextets), .port = 31337});
120*3f982cf4SFabien Sanglard   packet.set_destination(
121*3f982cf4SFabien Sanglard       IPEndpoint{.address = IPAddress(kDefaultMulticastGroupIPv6),
122*3f982cf4SFabien Sanglard                  .port = kDefaultMulticastPort});
123*3f982cf4SFabien Sanglard 
124*3f982cf4SFabien Sanglard   // Imitate a call to OnRead from NetworkRunner by calling it manually here
125*3f982cf4SFabien Sanglard   EXPECT_CALL(delegate, OnMessageReceived(message)).Times(1);
126*3f982cf4SFabien Sanglard   receiver.OnRead(&socket, std::move(packet));
127*3f982cf4SFabien Sanglard 
128*3f982cf4SFabien Sanglard   receiver.Stop();
129*3f982cf4SFabien Sanglard   receiver.RemoveResponseCallback(&delegate);
130*3f982cf4SFabien Sanglard }
131*3f982cf4SFabien Sanglard 
132*3f982cf4SFabien Sanglard }  // namespace discovery
133*3f982cf4SFabien Sanglard }  // namespace openscreen
134