You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
98 lines
2.8 KiB
98 lines
2.8 KiB
7 months ago
|
// Copyright 2019 The Chromium 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 "discovery/mdns/mdns_receiver.h"
|
||
|
|
||
|
#include <utility>
|
||
|
|
||
|
#include "discovery/mdns/mdns_reader.h"
|
||
|
#include "util/trace_logging.h"
|
||
|
|
||
|
namespace openscreen {
|
||
|
namespace discovery {
|
||
|
|
||
|
MdnsReceiver::ResponseClient::~ResponseClient() = default;
|
||
|
|
||
|
MdnsReceiver::MdnsReceiver(Config config) : config_(std::move(config)) {}
|
||
|
|
||
|
MdnsReceiver::~MdnsReceiver() {
|
||
|
if (state_ == State::kRunning) {
|
||
|
Stop();
|
||
|
}
|
||
|
|
||
|
OSP_DCHECK(response_clients_.empty());
|
||
|
}
|
||
|
|
||
|
void MdnsReceiver::SetQueryCallback(
|
||
|
std::function<void(const MdnsMessage&, const IPEndpoint&)> callback) {
|
||
|
// This check verifies that either new or stored callback has a target. It
|
||
|
// will fail in case multiple objects try to set or clear the callback.
|
||
|
OSP_DCHECK(static_cast<bool>(query_callback_) != static_cast<bool>(callback));
|
||
|
query_callback_ = callback;
|
||
|
}
|
||
|
|
||
|
void MdnsReceiver::AddResponseCallback(ResponseClient* callback) {
|
||
|
auto it =
|
||
|
std::find(response_clients_.begin(), response_clients_.end(), callback);
|
||
|
OSP_DCHECK(it == response_clients_.end());
|
||
|
|
||
|
response_clients_.push_back(callback);
|
||
|
}
|
||
|
|
||
|
void MdnsReceiver::RemoveResponseCallback(ResponseClient* callback) {
|
||
|
auto it =
|
||
|
std::find(response_clients_.begin(), response_clients_.end(), callback);
|
||
|
OSP_DCHECK(it != response_clients_.end());
|
||
|
|
||
|
response_clients_.erase(it);
|
||
|
}
|
||
|
|
||
|
void MdnsReceiver::Start() {
|
||
|
state_ = State::kRunning;
|
||
|
}
|
||
|
|
||
|
void MdnsReceiver::Stop() {
|
||
|
state_ = State::kStopped;
|
||
|
}
|
||
|
|
||
|
void MdnsReceiver::OnRead(UdpSocket* socket,
|
||
|
ErrorOr<UdpPacket> packet_or_error) {
|
||
|
if (state_ != State::kRunning || packet_or_error.is_error()) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
UdpPacket packet = std::move(packet_or_error.value());
|
||
|
|
||
|
TRACE_SCOPED(TraceCategory::kMdns, "MdnsReceiver::OnRead");
|
||
|
MdnsReader reader(config_, packet.data(), packet.size());
|
||
|
const ErrorOr<MdnsMessage> message = reader.Read();
|
||
|
if (message.is_error()) {
|
||
|
if (message.error().code() == Error::Code::kMdnsNonConformingFailure) {
|
||
|
OSP_DVLOG << "mDNS message dropped due to invalid rcode or opcode...";
|
||
|
} else {
|
||
|
OSP_DVLOG << "mDNS message failed to parse...";
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (message.value().type() == MessageType::Response) {
|
||
|
for (ResponseClient* client : response_clients_) {
|
||
|
client->OnMessageReceived(message.value());
|
||
|
}
|
||
|
if (response_clients_.empty()) {
|
||
|
OSP_DVLOG
|
||
|
<< "mDNS response message dropped. No response client registered...";
|
||
|
}
|
||
|
} else {
|
||
|
if (query_callback_) {
|
||
|
query_callback_(message.value(), packet.source());
|
||
|
} else {
|
||
|
OSP_DVLOG << "mDNS query message dropped. No query client registered...";
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
} // namespace discovery
|
||
|
} // namespace openscreen
|