#include "services/network/mdns_responder.h"
#include <algorithm>
#include <cmath>
#include <numeric>
#include <optional>
#include <queue>
#include <string>
#include <utility>
#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_macros.h"
#include "base/not_fatal_until.h"
#include "base/numerics/safe_conversions.h"
#include "base/rand_util.h"
#include "base/strings/stringprintf.h"
#include "base/time/default_tick_clock.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "base/uuid.h"
#include "net/base/address_family.h"
#include "net/base/io_buffer.h"
#include "net/base/ip_address.h"
#include "net/base/net_errors.h"
#include "net/dns/dns_names_util.h"
#include "net/dns/dns_response.h"
#include "net/dns/dns_util.h"
#include "net/dns/mdns_client.h"
#include "net/dns/public/dns_protocol.h"
#include "net/dns/public/util.h"
#include "net/dns/record_parsed.h"
#include "net/dns/record_rdata.h"
#include "net/socket/datagram_server_socket.h"
#include "net/socket/udp_server_socket.h"
#include "services/network/public/cpp/features.h"
namespace network {
namespace {
MdnsResponderServiceError;
const base::TimeDelta kMinIntervalBetweenSameRecord = …;
const base::TimeDelta kMinIntervalBetweenMdnsResponses = …;
const base::TimeDelta kDefaultTtlForRecordWithHostname = …;
const int kMinNumAnnouncementsToSend = …;
const uint8_t kMaxMdnsResponseRetries = …;
const uint8_t kSendQueueCapacity = …;
const base::TimeDelta kMaxScheduledDelay = …;
const char kMdnsNameGeneratorServiceInstanceName[] = …;
const uint16_t kMaxTxtRecordSizeInBytes = …;
const int kMaxKeySizeInTxtRecord = …;
const char kKeyPrefixInTxtRecord[] = …;
const char kTxtversLine[] = …;
constexpr auto kMinRandDelayForSharedResult = …;
constexpr auto kMaxRandDelayForSharedResult = …;
class RandomUuidNameGenerator
: public network::MdnsResponderManager::NameGenerator { … };
bool QueryTypeAndAddressFamilyAreCompatible(uint16_t qtype,
net::AddressFamily af) { … }
std::vector<net::DnsResourceRecord> CreateAddressResourceRecords(
const std::map<std::string, net::IPAddress>& name_addr_map,
const base::TimeDelta& ttl) { … }
std::string CreateNsecRdata(const net::IPAddress& addr,
uint16_t containing_nsec_rr_offset) { … }
std::vector<net::DnsResourceRecord> CreateNsecResourceRecords(
const std::map<std::string, net::IPAddress>& name_addr_map,
uint16_t first_nsec_rr_offset) { … }
std::string CreateTxtRdataWithNames(const std::set<std::string>& names,
uint16_t txt_rdata_size_limit) { … }
net::DnsResourceRecord CreateTxtRecordWithNames(
const base::TimeDelta& ttl,
const std::string& service_instance_name,
const std::set<std::string>& names) { … }
bool IsProbeQuery(const net::DnsQuery& query) { … }
struct PendingPacket { … };
}
namespace mdns_helper {
scoped_refptr<net::IOBufferWithSize> CreateResolutionResponse(
const base::TimeDelta& ttl,
const std::map<std::string, net::IPAddress>& name_addr_map) { … }
scoped_refptr<net::IOBufferWithSize> CreateNegativeResponse(
const std::map<std::string, net::IPAddress>& name_addr_map) { … }
scoped_refptr<net::IOBufferWithSize>
CreateResponseToMdnsNameGeneratorServiceQuery(
const base::TimeDelta& ttl,
const std::set<std::string>& mdns_names) { … }
}
class MdnsResponderManager::SocketHandler { … };
class MdnsResponderManager::SocketHandler::ResponseScheduler { … };
bool MdnsResponderManager::SocketHandler::Send(
scoped_refptr<net::IOBufferWithSize> buf,
scoped_refptr<MdnsResponseSendOption> option) { … }
int MdnsResponderManager::SocketHandler::DoSend(PendingPacket pending_packet) { … }
void MdnsResponderManager::SocketHandler::SetTickClockForTesting(
const base::TickClock* tick_clock) { … }
bool MdnsResponderManager::SocketHandler::ResponseScheduler::ScheduleNextSend(
scoped_refptr<net::IOBufferWithSize> buf,
scoped_refptr<MdnsResponseSendOption> option) { … }
std::optional<base::TimeDelta> MdnsResponderManager::SocketHandler::
ResponseScheduler::ComputeResponseDelayAndUpdateNextAvailableTime(
RateLimitScheme rate_limit_scheme,
const MdnsResponseSendOption& option) { … }
void MdnsResponderManager::SocketHandler::ResponseScheduler::
DispatchPendingPackets() { … }
MdnsResponseSendOption::MdnsResponseSendOption() = default;
MdnsResponseSendOption::~MdnsResponseSendOption() = default;
constexpr base::TimeDelta MdnsResponderManager::kManagerStartThrottleDelay;
MdnsResponderManager::MdnsResponderManager() : … { … }
MdnsResponderManager::MdnsResponderManager(
net::MDnsSocketFactory* socket_factory)
: … { … }
MdnsResponderManager::~MdnsResponderManager() { … }
void MdnsResponderManager::StartIfNeeded() { … }
void MdnsResponderManager::CreateMdnsResponder(
mojo::PendingReceiver<mojom::MdnsResponder> receiver) { … }
bool MdnsResponderManager::Send(scoped_refptr<net::IOBufferWithSize> buf,
scoped_refptr<MdnsResponseSendOption> option) { … }
void MdnsResponderManager::OnMojoConnectionError(MdnsResponder* responder) { … }
void MdnsResponderManager::SetNameGeneratorForTesting(
std::unique_ptr<MdnsResponderManager::NameGenerator> name_generator) { … }
void MdnsResponderManager::SetTickClockForTesting(
const base::TickClock* tick_clock) { … }
void MdnsResponderManager::HandleAddressNameConflictIfAny(
const std::map<std::string, std::set<net::IPAddress>>& external_maps) { … }
void MdnsResponderManager::HandleTxtNameConflict() { … }
void MdnsResponderManager::OnMdnsQueryReceived(
const net::DnsQuery& query,
uint16_t recv_socket_handler_id) { … }
void MdnsResponderManager::OnSocketHandlerReadError(uint16_t socket_handler_id,
int result) { … }
bool MdnsResponderManager::IsFatalError(int result) { … }
void MdnsResponderManager::HandleMdnsNameGeneratorServiceQuery(
const net::DnsQuery& query,
uint16_t recv_socket_handler_id) { … }
void MdnsResponderManager::
SendGoodbyePacketForMdnsNameGeneratorServiceIfNecessary() { … }
int MdnsResponderManager::SocketHandler::HandlePacket(int result) { … }
MdnsResponder::MdnsResponder(
mojo::PendingReceiver<mojom::MdnsResponder> receiver,
MdnsResponderManager* manager)
: … { … }
MdnsResponder::~MdnsResponder() { … }
void MdnsResponder::CreateNameForAddress(
const net::IPAddress& address,
mojom::MdnsResponder::CreateNameForAddressCallback callback) { … }
void MdnsResponder::RemoveNameForAddress(
const net::IPAddress& address,
mojom::MdnsResponder::RemoveNameForAddressCallback callback) { … }
void MdnsResponder::OnMdnsQueryReceived(const net::DnsQuery& query,
uint16_t recv_socket_handler_id) { … }
bool MdnsResponder::HasConflictWithExternalResolution(
const std::string& name,
const std::set<net::IPAddress>& external_mapped_addreses) { … }
bool MdnsResponder::SendMdnsResponse(
scoped_refptr<net::IOBufferWithSize> response,
scoped_refptr<MdnsResponseSendOption> option) { … }
bool MdnsResponder::SendGoodbyePacketForNameAddressMap(
const std::map<std::string, net::IPAddress>& name_addr_map) { … }
std::map<std::string, net::IPAddress>::iterator
MdnsResponder::FindNameCreatedForAddress(const net::IPAddress& address) { … }
}