Resolve the race condition between mDNS name registration and
cricket::Port::SignalPortComplete. The mDNS name registration is asynchronously executed by the mDNS responder, and a host candidate with an mDNS name is only gathered after this completes. SignalPortComplete however is currently done synchronously by UDPPort, and any candidate gathered by a UDPPort after this signal is fired would be discarded. Bug: webrtc:9964, webrtc:9605 Change-Id: If8aaf193ef26c06bd118e6418b62ba0de5e87e3c Reviewed-on: https://webrtc-review.googlesource.com/c/109541 Reviewed-by: Qingsi Wang <qingsi@webrtc.org> Reviewed-by: Zach Stein <zstein@webrtc.org> Reviewed-by: Steve Anton <steveanton@webrtc.org> Commit-Queue: Qingsi Wang <qingsi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25534}
This commit is contained in:
@ -399,9 +399,9 @@ void Port::AddAddress(const rtc::SocketAddress& address,
|
|||||||
const std::string& type,
|
const std::string& type,
|
||||||
uint32_t type_preference,
|
uint32_t type_preference,
|
||||||
uint32_t relay_preference,
|
uint32_t relay_preference,
|
||||||
bool final) {
|
bool is_final) {
|
||||||
AddAddress(address, base_address, related_address, protocol, relay_protocol,
|
AddAddress(address, base_address, related_address, protocol, relay_protocol,
|
||||||
tcptype, type, type_preference, relay_preference, "", final);
|
tcptype, type, type_preference, relay_preference, "", is_final);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Port::AddAddress(const rtc::SocketAddress& address,
|
void Port::AddAddress(const rtc::SocketAddress& address,
|
||||||
@ -448,9 +448,13 @@ void Port::AddAddress(const rtc::SocketAddress& address,
|
|||||||
c.set_address(hostname_address);
|
c.set_address(hostname_address);
|
||||||
RTC_DCHECK(c.related_address() == rtc::SocketAddress());
|
RTC_DCHECK(c.related_address() == rtc::SocketAddress());
|
||||||
if (weak_ptr != nullptr) {
|
if (weak_ptr != nullptr) {
|
||||||
|
weak_ptr->set_mdns_name_registration_status(
|
||||||
|
MdnsNameRegistrationStatus::kCompleted);
|
||||||
weak_ptr->FinishAddingAddress(c, is_final);
|
weak_ptr->FinishAddingAddress(c, is_final);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
set_mdns_name_registration_status(
|
||||||
|
MdnsNameRegistrationStatus::kInProgress);
|
||||||
network_->GetMdnsResponder()->CreateNameForAddress(c.address().ipaddr(),
|
network_->GetMdnsResponder()->CreateNameForAddress(c.address().ipaddr(),
|
||||||
callback);
|
callback);
|
||||||
return;
|
return;
|
||||||
@ -468,6 +472,10 @@ void Port::FinishAddingAddress(const Candidate& c, bool is_final) {
|
|||||||
candidates_.push_back(c);
|
candidates_.push_back(c);
|
||||||
SignalCandidateReady(this, c);
|
SignalCandidateReady(this, c);
|
||||||
|
|
||||||
|
PostAddAddress(is_final);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Port::PostAddAddress(bool is_final) {
|
||||||
if (is_final) {
|
if (is_final) {
|
||||||
SignalPortComplete(this);
|
SignalPortComplete(this);
|
||||||
}
|
}
|
||||||
|
@ -84,6 +84,18 @@ enum class IceCandidatePairState {
|
|||||||
// frozen because we have not implemented ICE freezing logic.
|
// frozen because we have not implemented ICE freezing logic.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class MdnsNameRegistrationStatus {
|
||||||
|
// IP concealment with mDNS is not enabled or the name registration process is
|
||||||
|
// not started yet.
|
||||||
|
kNotStarted,
|
||||||
|
// A request to create and register an mDNS name for a local IP address of a
|
||||||
|
// host candidate is sent to the mDNS responder.
|
||||||
|
kInProgress,
|
||||||
|
// The name registration is complete and the created name is returned by the
|
||||||
|
// mDNS responder.
|
||||||
|
kCompleted,
|
||||||
|
};
|
||||||
|
|
||||||
// Stats that we can return about the port of a STUN candidate.
|
// Stats that we can return about the port of a STUN candidate.
|
||||||
class StunStats {
|
class StunStats {
|
||||||
public:
|
public:
|
||||||
@ -393,7 +405,7 @@ class Port : public PortInterface,
|
|||||||
const std::string& type,
|
const std::string& type,
|
||||||
uint32_t type_preference,
|
uint32_t type_preference,
|
||||||
uint32_t relay_preference,
|
uint32_t relay_preference,
|
||||||
bool final);
|
bool is_final);
|
||||||
|
|
||||||
void AddAddress(const rtc::SocketAddress& address,
|
void AddAddress(const rtc::SocketAddress& address,
|
||||||
const rtc::SocketAddress& base_address,
|
const rtc::SocketAddress& base_address,
|
||||||
@ -409,6 +421,8 @@ class Port : public PortInterface,
|
|||||||
|
|
||||||
void FinishAddingAddress(const Candidate& c, bool is_final);
|
void FinishAddingAddress(const Candidate& c, bool is_final);
|
||||||
|
|
||||||
|
virtual void PostAddAddress(bool is_final);
|
||||||
|
|
||||||
// Adds the given connection to the map keyed by the remote candidate address.
|
// Adds the given connection to the map keyed by the remote candidate address.
|
||||||
// If an existing connection has the same address, the existing one will be
|
// If an existing connection has the same address, the existing one will be
|
||||||
// replaced and destroyed.
|
// replaced and destroyed.
|
||||||
@ -444,6 +458,13 @@ class Port : public PortInterface,
|
|||||||
|
|
||||||
void CopyPortInformationToPacketInfo(rtc::PacketInfo* info) const;
|
void CopyPortInformationToPacketInfo(rtc::PacketInfo* info) const;
|
||||||
|
|
||||||
|
MdnsNameRegistrationStatus mdns_name_registration_status() const {
|
||||||
|
return mdns_name_registration_status_;
|
||||||
|
}
|
||||||
|
void set_mdns_name_registration_status(MdnsNameRegistrationStatus status) {
|
||||||
|
mdns_name_registration_status_ = status;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Construct();
|
void Construct();
|
||||||
// Called when one of our connections deletes itself.
|
// Called when one of our connections deletes itself.
|
||||||
@ -488,6 +509,8 @@ class Port : public PortInterface,
|
|||||||
int16_t network_cost_;
|
int16_t network_cost_;
|
||||||
State state_ = State::INIT;
|
State state_ = State::INIT;
|
||||||
int64_t last_time_all_connections_removed_ = 0;
|
int64_t last_time_all_connections_removed_ = 0;
|
||||||
|
MdnsNameRegistrationStatus mdns_name_registration_status_ =
|
||||||
|
MdnsNameRegistrationStatus::kNotStarted;
|
||||||
|
|
||||||
rtc::WeakPtrFactory<Port> weak_factory_;
|
rtc::WeakPtrFactory<Port> weak_factory_;
|
||||||
|
|
||||||
|
@ -358,6 +358,10 @@ void UDPPort::OnLocalAddressReady(rtc::AsyncPacketSocket* socket,
|
|||||||
MaybePrepareStunCandidate();
|
MaybePrepareStunCandidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UDPPort::PostAddAddress(bool is_final) {
|
||||||
|
MaybeSetPortCompleteOrError();
|
||||||
|
}
|
||||||
|
|
||||||
void UDPPort::OnReadPacket(rtc::AsyncPacketSocket* socket,
|
void UDPPort::OnReadPacket(rtc::AsyncPacketSocket* socket,
|
||||||
const char* data,
|
const char* data,
|
||||||
size_t size,
|
size_t size,
|
||||||
@ -517,8 +521,14 @@ void UDPPort::OnStunBindingOrResolveRequestFailed(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UDPPort::MaybeSetPortCompleteOrError() {
|
void UDPPort::MaybeSetPortCompleteOrError() {
|
||||||
if (ready_)
|
if (mdns_name_registration_status() ==
|
||||||
|
MdnsNameRegistrationStatus::kInProgress) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ready_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Do not set port ready if we are still waiting for bind responses.
|
// Do not set port ready if we are still waiting for bind responses.
|
||||||
const size_t servers_done_bind_request =
|
const size_t servers_done_bind_request =
|
||||||
|
@ -160,6 +160,9 @@ class UDPPort : public Port {
|
|||||||
|
|
||||||
void OnLocalAddressReady(rtc::AsyncPacketSocket* socket,
|
void OnLocalAddressReady(rtc::AsyncPacketSocket* socket,
|
||||||
const rtc::SocketAddress& address);
|
const rtc::SocketAddress& address);
|
||||||
|
|
||||||
|
void PostAddAddress(bool is_final) override;
|
||||||
|
|
||||||
void OnReadPacket(rtc::AsyncPacketSocket* socket,
|
void OnReadPacket(rtc::AsyncPacketSocket* socket,
|
||||||
const char* data,
|
const char* data,
|
||||||
size_t size,
|
size_t size,
|
||||||
|
@ -23,7 +23,7 @@ namespace webrtc {
|
|||||||
|
|
||||||
class FakeMdnsResponder : public MdnsResponderInterface {
|
class FakeMdnsResponder : public MdnsResponderInterface {
|
||||||
public:
|
public:
|
||||||
FakeMdnsResponder() = default;
|
explicit FakeMdnsResponder(rtc::Thread* thread) : thread_(thread) {}
|
||||||
~FakeMdnsResponder() = default;
|
~FakeMdnsResponder() = default;
|
||||||
|
|
||||||
void CreateNameForAddress(const rtc::IPAddress& addr,
|
void CreateNameForAddress(const rtc::IPAddress& addr,
|
||||||
@ -35,7 +35,9 @@ class FakeMdnsResponder : public MdnsResponderInterface {
|
|||||||
name = std::to_string(next_available_id_++) + ".local";
|
name = std::to_string(next_available_id_++) + ".local";
|
||||||
addr_name_map_[addr] = name;
|
addr_name_map_[addr] = name;
|
||||||
}
|
}
|
||||||
callback(addr, name);
|
invoker_.AsyncInvoke<void>(
|
||||||
|
RTC_FROM_HERE, thread_,
|
||||||
|
[callback, addr, name]() { callback(addr, name); });
|
||||||
}
|
}
|
||||||
void RemoveNameForAddress(const rtc::IPAddress& addr,
|
void RemoveNameForAddress(const rtc::IPAddress& addr,
|
||||||
NameRemovedCallback callback) override {
|
NameRemovedCallback callback) override {
|
||||||
@ -43,12 +45,16 @@ class FakeMdnsResponder : public MdnsResponderInterface {
|
|||||||
if (it != addr_name_map_.end()) {
|
if (it != addr_name_map_.end()) {
|
||||||
addr_name_map_.erase(it);
|
addr_name_map_.erase(it);
|
||||||
}
|
}
|
||||||
callback(it != addr_name_map_.end());
|
bool result = it != addr_name_map_.end();
|
||||||
|
invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_,
|
||||||
|
[callback, result]() { callback(result); });
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t next_available_id_ = 0;
|
uint32_t next_available_id_ = 0;
|
||||||
std::map<rtc::IPAddress, std::string> addr_name_map_;
|
std::map<rtc::IPAddress, std::string> addr_name_map_;
|
||||||
|
rtc::Thread* thread_;
|
||||||
|
rtc::AsyncInvoker invoker_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -84,7 +84,8 @@ class FakeNetworkManager : public NetworkManagerBase, public MessageHandler {
|
|||||||
|
|
||||||
void CreateMdnsResponder() {
|
void CreateMdnsResponder() {
|
||||||
if (mdns_responder_ == nullptr) {
|
if (mdns_responder_ == nullptr) {
|
||||||
mdns_responder_ = absl::make_unique<webrtc::FakeMdnsResponder>();
|
mdns_responder_ =
|
||||||
|
absl::make_unique<webrtc::FakeMdnsResponder>(rtc::Thread::Current());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user