blob: 2b336b73c43a4134fc48e5302f9809873567db33 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/connectivity/network/mdns/service/agents/address_responder.h"
#include <lib/zx/time.h>
#include <gtest/gtest.h>
#include "src/connectivity/network/mdns/service/test/agent_test.h"
namespace mdns {
namespace test {
class AddressResponderTest : public AgentTest {
public:
AddressResponderTest() {}
protected:
// Expects that local addresses are transmitted to the multicast address.
void ExpectAddresses(Media media, IpVersions ip_versions) {
auto message = ExpectOutboundMessage(ReplyAddress::Multicast(media, ip_versions));
ExpectAddressPlaceholder(message.get(), MdnsResourceSection::kAnswer);
ExpectNoOtherQuestionOrResource(message.get());
}
// Expects that |addresses| for |host_full_name| are transmitted to the multicast address.
void ExpectAddresses(const std::string& host_full_name,
const std::vector<inet::IpAddress>& addresses, Media media,
IpVersions ip_versions) {
auto message = ExpectOutboundMessage(ReplyAddress::Multicast(media, ip_versions));
AgentTest::ExpectAddresses(message.get(), MdnsResourceSection::kAnswer, host_full_name,
addresses);
ExpectNoOtherQuestionOrResource(message.get());
}
};
constexpr char kHostFullName[] = "test2host.local.";
const std::vector<inet::IpAddress> kAddresses{inet::IpAddress(192, 168, 1, 200),
inet::IpAddress(192, 168, 1, 201)};
constexpr uint32_t kInterfaceId = 1;
// Tests initial startup of the responder.
TEST_F(AddressResponderTest, Startup) {
AddressResponder under_test(this, Media::kBoth, IpVersions::kBoth);
SetAgent(under_test);
under_test.Start(kLocalHostFullName);
// No initial action.
ExpectNoOther();
}
// Tests that multicast sends are rate-limited.
TEST_F(AddressResponderTest, MulticastRateLimit) {
AddressResponder under_test(this, Media::kBoth, IpVersions::kBoth);
SetAgent(under_test);
// Normal startup.
under_test.Start(kLocalHostFullName);
ExpectNoOther();
ReplyAddress sender_address0(
inet::SocketAddress(192, 168, 1, 1, inet::IpPort::From_uint16_t(5353)),
inet::IpAddress(192, 168, 1, 100), kInterfaceId, Media::kWireless, IpVersions::kV4);
ReplyAddress sender_address1(
inet::SocketAddress(192, 168, 1, 2, inet::IpPort::From_uint16_t(5353)),
inet::IpAddress(0xfe80, 1), kInterfaceId, Media::kWired, IpVersions::kV6);
// First question.
under_test.ReceiveQuestion(DnsQuestion(kLocalHostFullName, DnsType::kA),
ReplyAddress::Multicast(Media::kBoth, IpVersions::kBoth),
sender_address0);
ExpectAddresses(Media::kBoth, IpVersions::kBoth);
ExpectNoOther();
// Second question - answer should be delayed 1s.
under_test.ReceiveQuestion(DnsQuestion(kLocalHostFullName, DnsType::kA),
ReplyAddress::Multicast(Media::kBoth, IpVersions::kBoth),
sender_address0);
ExpectPostTaskForTimeAndInvoke(zx::sec(1), zx::sec(1));
ExpectAddresses(Media::kBoth, IpVersions::kBoth);
ExpectNoOther();
// Third and fourth questions - one answer, delayed 1s.
under_test.ReceiveQuestion(DnsQuestion(kLocalHostFullName, DnsType::kA),
ReplyAddress::Multicast(Media::kBoth, IpVersions::kBoth),
sender_address0);
under_test.ReceiveQuestion(DnsQuestion(kLocalHostFullName, DnsType::kA),
ReplyAddress::Multicast(Media::kBoth, IpVersions::kBoth),
sender_address1);
ExpectPostTaskForTimeAndInvoke(zx::sec(1), zx::sec(1));
ExpectAddresses(Media::kBoth, IpVersions::kBoth);
ExpectNoOther();
}
// Tests operation with a explicit host name and addresses.
TEST_F(AddressResponderTest, HostNameAndAddresses) {
AddressResponder under_test(this, kHostFullName, kAddresses, Media::kBoth, IpVersions::kBoth);
SetAgent(under_test);
// Normal startup.
under_test.Start(kLocalHostFullName);
ExpectNoOther();
ReplyAddress sender_address(
inet::SocketAddress(192, 168, 1, 1, inet::IpPort::From_uint16_t(5353)),
inet::IpAddress(192, 168, 1, 100), kInterfaceId, Media::kWireless, IpVersions::kV4);
under_test.ReceiveQuestion(DnsQuestion(kHostFullName, DnsType::kA),
ReplyAddress::Multicast(Media::kBoth, IpVersions::kBoth),
sender_address);
ExpectAddresses(kHostFullName, kAddresses, Media::kBoth, IpVersions::kBoth);
ExpectNoOther();
}
// Tests operation with wired media only.
TEST_F(AddressResponderTest, WiredOnly) {
AddressResponder under_test(this, kHostFullName, kAddresses, Media::kWired, IpVersions::kBoth);
SetAgent(under_test);
// Normal startup.
under_test.Start(kLocalHostFullName);
ExpectNoOther();
ReplyAddress sender_address0(
inet::SocketAddress(192, 168, 1, 1, inet::IpPort::From_uint16_t(5353)),
inet::IpAddress(192, 168, 1, 100), kInterfaceId, Media::kWireless, IpVersions::kV4);
under_test.ReceiveQuestion(DnsQuestion(kHostFullName, DnsType::kA),
ReplyAddress::Multicast(Media::kBoth, IpVersions::kBoth),
sender_address0);
// Expect no response, because the sender address is wireless.
ExpectNoOther();
ReplyAddress sender_address1(
inet::SocketAddress(192, 168, 1, 1, inet::IpPort::From_uint16_t(5353)),
inet::IpAddress(192, 168, 1, 100), kInterfaceId, Media::kWired, IpVersions::kBoth);
under_test.ReceiveQuestion(DnsQuestion(kHostFullName, DnsType::kA),
ReplyAddress::Multicast(Media::kBoth, IpVersions::kBoth),
sender_address1);
ExpectAddresses(kHostFullName, kAddresses, Media::kWired, IpVersions::kBoth);
ExpectNoOther();
}
// Tests operation with wireless media only.
TEST_F(AddressResponderTest, WirelessOnly) {
AddressResponder under_test(this, kHostFullName, kAddresses, Media::kWireless, IpVersions::kBoth);
SetAgent(under_test);
// Normal startup.
under_test.Start(kLocalHostFullName);
ExpectNoOther();
ReplyAddress sender_address0(
inet::SocketAddress(192, 168, 1, 1, inet::IpPort::From_uint16_t(5353)),
inet::IpAddress(192, 168, 1, 100), kInterfaceId, Media::kWired, IpVersions::kV4);
under_test.ReceiveQuestion(DnsQuestion(kHostFullName, DnsType::kA),
ReplyAddress::Multicast(Media::kBoth, IpVersions::kBoth),
sender_address0);
// Expect no response, because the sender address is wired.
ExpectNoOther();
ReplyAddress sender_address1(
inet::SocketAddress(192, 168, 1, 1, inet::IpPort::From_uint16_t(5353)),
inet::IpAddress(192, 168, 1, 100), kInterfaceId, Media::kWireless, IpVersions::kBoth);
under_test.ReceiveQuestion(DnsQuestion(kHostFullName, DnsType::kA),
ReplyAddress::Multicast(Media::kBoth, IpVersions::kBoth),
sender_address1);
ExpectAddresses(kHostFullName, kAddresses, Media::kWireless, IpVersions::kBoth);
ExpectNoOther();
}
// Tests operation with V4 ip_version only.
TEST_F(AddressResponderTest, V4Only) {
AddressResponder under_test(this, kHostFullName, kAddresses, Media::kBoth, IpVersions::kV4);
SetAgent(under_test);
// Normal startup.
under_test.Start(kLocalHostFullName);
ExpectNoOther();
ReplyAddress sender_address0(
inet::SocketAddress(192, 168, 1, 1, inet::IpPort::From_uint16_t(5353)),
inet::IpAddress(0xfe80, 1), kInterfaceId, Media::kWireless, IpVersions::kV6);
under_test.ReceiveQuestion(DnsQuestion(kHostFullName, DnsType::kA),
ReplyAddress::Multicast(Media::kBoth, IpVersions::kBoth),
sender_address0);
// Expect no response, because the sender address is V6.
ExpectNoOther();
ReplyAddress sender_address1(
inet::SocketAddress(192, 168, 1, 1, inet::IpPort::From_uint16_t(5353)),
inet::IpAddress(192, 168, 1, 100), kInterfaceId, Media::kWired, IpVersions::kV4);
under_test.ReceiveQuestion(DnsQuestion(kHostFullName, DnsType::kA),
ReplyAddress::Multicast(Media::kBoth, IpVersions::kBoth),
sender_address1);
ExpectAddresses(kHostFullName, kAddresses, Media::kBoth, IpVersions::kV4);
ExpectNoOther();
}
// Tests operation with Vt ip_version only.
TEST_F(AddressResponderTest, V6Only) {
AddressResponder under_test(this, kHostFullName, kAddresses, Media::kBoth, IpVersions::kV6);
SetAgent(under_test);
// Normal startup.
under_test.Start(kLocalHostFullName);
ExpectNoOther();
ReplyAddress sender_address0(
inet::SocketAddress(192, 168, 1, 1, inet::IpPort::From_uint16_t(5353)),
inet::IpAddress(192, 168, 1, 100), kInterfaceId, Media::kWireless, IpVersions::kV4);
under_test.ReceiveQuestion(DnsQuestion(kHostFullName, DnsType::kA),
ReplyAddress::Multicast(Media::kBoth, IpVersions::kBoth),
sender_address0);
// Expect no response, because the sender address is V4.
ExpectNoOther();
ReplyAddress sender_address1(
inet::SocketAddress(192, 168, 1, 1, inet::IpPort::From_uint16_t(5353)),
inet::IpAddress(0xfe80, 1), kInterfaceId, Media::kWired, IpVersions::kV6);
under_test.ReceiveQuestion(DnsQuestion(kHostFullName, DnsType::kA),
ReplyAddress::Multicast(Media::kBoth, IpVersions::kBoth),
sender_address1);
ExpectAddresses(kHostFullName, kAddresses, Media::kBoth, IpVersions::kV6);
ExpectNoOther();
}
} // namespace test
} // namespace mdns