зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1567201 - Use mdns_service to handle mDNS queries; r=mjf
Differential Revision: https://phabricator.services.mozilla.com/D46977 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
940a75c186
Коммит
90e44f7695
|
@ -49,7 +49,8 @@ class MediaTransportParent : public dom::PMediaTransportParent {
|
|||
const MediaPacket& packet);
|
||||
mozilla::ipc::IPCResult RecvAddIceCandidate(const string& transportId,
|
||||
const string& candidate,
|
||||
const string& ufrag);
|
||||
const string& ufrag,
|
||||
const string& obfuscatedAddress);
|
||||
mozilla::ipc::IPCResult RecvUpdateNetworkState(const bool& online);
|
||||
mozilla::ipc::IPCResult RecvGetIceStats(
|
||||
const string& transportId, const double& now,
|
||||
|
|
|
@ -81,7 +81,8 @@ parent:
|
|||
|
||||
async AddIceCandidate(string transportId,
|
||||
string candidate,
|
||||
string ufrag);
|
||||
string ufrag,
|
||||
string obfuscatedAddr);
|
||||
|
||||
async UpdateNetworkState(bool online);
|
||||
|
||||
|
|
|
@ -187,8 +187,8 @@ class LoopbackTransport : public MediaTransportHandler {
|
|||
const std::vector<std::string>& aIceOptions) override {}
|
||||
|
||||
void AddIceCandidate(const std::string& aTransportId,
|
||||
const std::string& aCandidate,
|
||||
const std::string& aUfrag) override {}
|
||||
const std::string& aCandidate, const std::string& aUfrag,
|
||||
const std::string& aObfuscatedAddress) override {}
|
||||
|
||||
void UpdateNetworkState(bool aOnline) override {}
|
||||
|
||||
|
|
|
@ -36,10 +36,6 @@
|
|||
|
||||
#include "mozilla/dom/RTCStatsReportBinding.h"
|
||||
|
||||
// mDNS
|
||||
#include "nsIDNSRecord.h"
|
||||
#include "mozilla/net/DNS.h"
|
||||
|
||||
#include "nss.h" // For NSS_NoDB_Init
|
||||
#include "mozilla/PublicSSL.h" // For psm::InitializeCipherSuite
|
||||
|
||||
|
@ -107,8 +103,8 @@ class MediaTransportHandlerSTS : public MediaTransportHandler,
|
|||
const std::vector<std::string>& aIceOptions) override;
|
||||
|
||||
void AddIceCandidate(const std::string& aTransportId,
|
||||
const std::string& aCandidate,
|
||||
const std::string& aUfrag) override;
|
||||
const std::string& aCandidate, const std::string& aUfrag,
|
||||
const std::string& aObfuscatedAddress) override;
|
||||
|
||||
void UpdateNetworkState(bool aOnline) override;
|
||||
|
||||
|
@ -165,45 +161,8 @@ class MediaTransportHandlerSTS : public MediaTransportHandler,
|
|||
std::map<std::string, Transport> mTransports;
|
||||
bool mObfuscateHostAddresses = false;
|
||||
|
||||
// mDNS Support
|
||||
class DNSListener final : public nsIDNSListener {
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIDNSLISTENER
|
||||
|
||||
public:
|
||||
DNSListener(MediaTransportHandlerSTS& aTransportHandler,
|
||||
const std::string& aTransportId, const std::string& aCandidate,
|
||||
std::vector<std::string> aTokenizedCandidate,
|
||||
const std::string& aUfrag)
|
||||
: mTransportHandler(aTransportHandler),
|
||||
mTransportId(aTransportId),
|
||||
mCandidate(aCandidate),
|
||||
mTokenizedCandidate(aTokenizedCandidate),
|
||||
mUfrag(aUfrag) {}
|
||||
|
||||
void Cancel() {
|
||||
mCancel->Cancel(NS_ERROR_ABORT);
|
||||
mCancel = nullptr;
|
||||
}
|
||||
|
||||
MediaTransportHandlerSTS& mTransportHandler;
|
||||
|
||||
const std::string mTransportId;
|
||||
const std::string mCandidate;
|
||||
std::vector<std::string> mTokenizedCandidate;
|
||||
const std::string mUfrag;
|
||||
|
||||
nsCOMPtr<nsICancelable> mCancel;
|
||||
|
||||
private:
|
||||
~DNSListener() = default;
|
||||
};
|
||||
|
||||
void PendingDNSRequestResolved(DNSListener* aListener);
|
||||
|
||||
nsCOMPtr<nsIDNSService> mDNSService;
|
||||
std::set<RefPtr<DNSListener>> mPendingDNSRequests;
|
||||
std::set<std::string> mSignaledAddresses;
|
||||
|
||||
// Init can only be done on main, but we want this to be usable on any thread
|
||||
typedef MozPromise<bool, std::string, false> InitPromise;
|
||||
RefPtr<InitPromise> mInitPromise;
|
||||
|
@ -482,11 +441,6 @@ void MediaTransportHandlerSTS::Destroy() {
|
|||
mInitPromise->Then(
|
||||
mStsThread, __func__,
|
||||
[this, self = RefPtr<MediaTransportHandlerSTS>(this)]() {
|
||||
for (auto& listener : mPendingDNSRequests) {
|
||||
listener->Cancel();
|
||||
}
|
||||
mPendingDNSRequests.clear();
|
||||
|
||||
disconnect_all();
|
||||
if (mIceCtx) {
|
||||
NrIceStats stats = mIceCtx->Destroy();
|
||||
|
@ -722,61 +676,15 @@ static void TokenizeCandidate(const std::string& aCandidate,
|
|||
}
|
||||
}
|
||||
|
||||
void MediaTransportHandlerSTS::AddIceCandidate(const std::string& aTransportId,
|
||||
const std::string& aCandidate,
|
||||
const std::string& aUfrag) {
|
||||
void MediaTransportHandlerSTS::AddIceCandidate(
|
||||
const std::string& aTransportId, const std::string& aCandidate,
|
||||
const std::string& aUfrag, const std::string& aObfuscatedAddress) {
|
||||
mInitPromise->Then(
|
||||
mStsThread, __func__,
|
||||
[=, self = RefPtr<MediaTransportHandlerSTS>(this)]() {
|
||||
std::vector<std::string> tokens;
|
||||
TokenizeCandidate(aCandidate, tokens);
|
||||
|
||||
if (tokens.size() > 4) {
|
||||
std::string addr = tokens[4];
|
||||
|
||||
// Check for address ending with .local
|
||||
size_t nPeriods = std::count(addr.begin(), addr.end(), '.');
|
||||
size_t dotLocalLength = 6; // length of ".local"
|
||||
|
||||
if (nPeriods == 1 &&
|
||||
addr.rfind(".local") + dotLocalLength == addr.length()) {
|
||||
CSFLogDebug(
|
||||
LOGTAG,
|
||||
"Using mDNS to resolve candidate with transport id: %s: %s",
|
||||
aTransportId.c_str(), aCandidate.c_str());
|
||||
|
||||
auto listener =
|
||||
*(mPendingDNSRequests
|
||||
.emplace(new DNSListener(*this, aTransportId, aCandidate,
|
||||
tokens, aUfrag))
|
||||
.first);
|
||||
OriginAttributes attrs;
|
||||
|
||||
if (!mDNSService) {
|
||||
nsresult rv;
|
||||
mDNSService = do_GetService(NS_DNSSERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_ASSERT(false);
|
||||
MOZ_CRASH();
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_FAILED(mDNSService->AsyncResolveNative(
|
||||
nsAutoCString(tokens[4].c_str()), 0, listener, mStsThread,
|
||||
attrs, getter_AddRefs(listener->mCancel)))) {
|
||||
CSFLogError(
|
||||
LOGTAG,
|
||||
"Error using mDNS to resolve candidate with transport id "
|
||||
"%s: %s",
|
||||
aTransportId.c_str(), aCandidate.c_str());
|
||||
}
|
||||
// TODO: Bug 1535690, we don't want to tell the ICE context that
|
||||
// remote trickle is done if we are waiting to resolve a mDNS
|
||||
// candidate.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<NrIceMediaStream> stream(mIceCtx->GetStream(aTransportId));
|
||||
if (!stream) {
|
||||
CSFLogError(LOGTAG,
|
||||
|
@ -785,7 +693,8 @@ void MediaTransportHandlerSTS::AddIceCandidate(const std::string& aTransportId,
|
|||
return;
|
||||
}
|
||||
|
||||
nsresult rv = stream->ParseTrickleCandidate(aCandidate, aUfrag, "");
|
||||
nsresult rv = stream->ParseTrickleCandidate(aCandidate, aUfrag,
|
||||
aObfuscatedAddress);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (mObfuscateHostAddresses && tokens.size() > 4) {
|
||||
mSignaledAddresses.insert(tokens[4]);
|
||||
|
@ -1032,11 +941,6 @@ MediaTransportHandlerSTS::GetIceStats(
|
|||
});
|
||||
}
|
||||
|
||||
void MediaTransportHandlerSTS::PendingDNSRequestResolved(
|
||||
DNSListener* aListener) {
|
||||
mPendingDNSRequests.erase(aListener);
|
||||
}
|
||||
|
||||
RefPtr<MediaTransportHandler::IceLogPromise>
|
||||
MediaTransportHandlerSTS::GetIceLog(const nsCString& aPattern) {
|
||||
return InvokeAsync(
|
||||
|
@ -1414,90 +1318,4 @@ void MediaTransportHandlerSTS::EncryptedPacketSending(TransportLayer* aLayer,
|
|||
OnEncryptedSending(aLayer->flow_id(), aPacket);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(MediaTransportHandlerSTS::DNSListener, nsIDNSListener);
|
||||
|
||||
nsresult MediaTransportHandlerSTS::DNSListener::OnLookupComplete(
|
||||
nsICancelable* aRequest, nsIDNSRecord* aRecord, nsresult aStatus) {
|
||||
if (mCancel) {
|
||||
MOZ_ASSERT(mTransportHandler.mStsThread->IsOnCurrentThread());
|
||||
if (NS_SUCCEEDED(aStatus)) {
|
||||
nsTArray<net::NetAddr> addresses;
|
||||
aRecord->GetAddresses(addresses);
|
||||
|
||||
// https://tools.ietf.org/html/draft-ietf-rtcweb-mdns-ice-candidates-03#section-3.2.2
|
||||
if (addresses.Length() == 1) {
|
||||
char buf[net::kIPv6CStrBufSize];
|
||||
if (!net::NetAddrToString(&addresses[0], buf, sizeof(buf))) {
|
||||
CSFLogError(LOGTAG,
|
||||
"Unable to convert mDNS address for candidate with"
|
||||
" transport id %s: %s",
|
||||
mTransportId.c_str(), mCandidate.c_str());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
CSFLogDebug(LOGTAG,
|
||||
"Adding mDNS candidate with transport id: %s: %s:"
|
||||
" resolved to: %s",
|
||||
mTransportId.c_str(), mCandidate.c_str(), buf);
|
||||
|
||||
// Replace obfuscated address with actual address
|
||||
std::string obfuscatedAddr = mTokenizedCandidate[4];
|
||||
mTokenizedCandidate[4] = buf;
|
||||
std::ostringstream o;
|
||||
for (size_t i = 0; i < mTokenizedCandidate.size(); ++i) {
|
||||
o << mTokenizedCandidate[i];
|
||||
if (i + 1 != mTokenizedCandidate.size()) {
|
||||
o << " ";
|
||||
}
|
||||
}
|
||||
|
||||
std::string mungedCandidate = o.str();
|
||||
|
||||
RefPtr<NrIceMediaStream> stream(
|
||||
mTransportHandler.mIceCtx->GetStream(mTransportId));
|
||||
if (!stream) {
|
||||
CSFLogError(LOGTAG,
|
||||
"No ICE stream for candidate with transport id %s: %s",
|
||||
mTransportId.c_str(), mCandidate.c_str());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv = stream->ParseTrickleCandidate(mungedCandidate, mUfrag,
|
||||
obfuscatedAddr);
|
||||
if (NS_FAILED(rv)) {
|
||||
CSFLogError(LOGTAG,
|
||||
"Couldn't process ICE candidate with transport id %s: "
|
||||
"%s",
|
||||
mTransportId.c_str(), mCandidate.c_str());
|
||||
}
|
||||
} else {
|
||||
CSFLogError(LOGTAG,
|
||||
"More than one mDNS result for candidate with transport"
|
||||
" id: %s: %s, candidate ignored",
|
||||
mTransportId.c_str(), mCandidate.c_str());
|
||||
}
|
||||
} else {
|
||||
CSFLogError(LOGTAG,
|
||||
"Using mDNS failed for candidate with transport id: %s: %s",
|
||||
mTransportId.c_str(), mCandidate.c_str());
|
||||
}
|
||||
|
||||
mCancel = nullptr;
|
||||
mTransportHandler.PendingDNSRequestResolved(this);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult MediaTransportHandlerSTS::DNSListener::OnLookupByTypeComplete(
|
||||
nsICancelable* aRequest, nsIDNSByTypeRecord* aResult, nsresult aStatus) {
|
||||
MOZ_ASSERT_UNREACHABLE(
|
||||
"MediaTranportHandlerSTS::DNSListener::OnLookupByTypeComplete");
|
||||
if (mCancel) {
|
||||
mCancel = nullptr;
|
||||
mTransportHandler.PendingDNSRequestResolved(this);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -110,7 +110,8 @@ class MediaTransportHandler {
|
|||
|
||||
virtual void AddIceCandidate(const std::string& aTransportId,
|
||||
const std::string& aCandidate,
|
||||
const std::string& aUFrag) = 0;
|
||||
const std::string& aUFrag,
|
||||
const std::string& aObfuscatedAddress) = 0;
|
||||
|
||||
virtual void UpdateNetworkState(bool aOnline) = 0;
|
||||
|
||||
|
|
|
@ -280,14 +280,15 @@ void MediaTransportHandlerIPC::SendPacket(const std::string& aTransportId,
|
|||
[](const nsCString& aError) {});
|
||||
}
|
||||
|
||||
void MediaTransportHandlerIPC::AddIceCandidate(const std::string& aTransportId,
|
||||
const std::string& aCandidate,
|
||||
const std::string& aUfrag) {
|
||||
void MediaTransportHandlerIPC::AddIceCandidate(
|
||||
const std::string& aTransportId, const std::string& aCandidate,
|
||||
const std::string& aUfrag, const std::string& aObfuscatedAddress) {
|
||||
mInitPromise->Then(
|
||||
mCallbackThread, __func__,
|
||||
[=, self = RefPtr<MediaTransportHandlerIPC>(this)](bool /*dummy*/) {
|
||||
if (mChild) {
|
||||
mChild->SendAddIceCandidate(aTransportId, aCandidate, aUfrag);
|
||||
mChild->SendAddIceCandidate(aTransportId, aCandidate, aUfrag,
|
||||
aObfuscatedAddress);
|
||||
}
|
||||
},
|
||||
[](const nsCString& aError) {});
|
||||
|
|
|
@ -66,8 +66,8 @@ class MediaTransportHandlerIPC : public MediaTransportHandler {
|
|||
MediaPacket&& aPacket) override;
|
||||
|
||||
void AddIceCandidate(const std::string& aTransportId,
|
||||
const std::string& aCandidate,
|
||||
const std::string& aUfrag) override;
|
||||
const std::string& aCandidate, const std::string& aUfrag,
|
||||
const std::string& aObfuscatedAddress) override;
|
||||
|
||||
void UpdateNetworkState(bool aOnline) override;
|
||||
|
||||
|
|
|
@ -198,8 +198,10 @@ mozilla::ipc::IPCResult MediaTransportParent::RecvSendPacket(
|
|||
}
|
||||
|
||||
mozilla::ipc::IPCResult MediaTransportParent::RecvAddIceCandidate(
|
||||
const string& transportId, const string& candidate, const string& ufrag) {
|
||||
mImpl->mHandler->AddIceCandidate(transportId, candidate, ufrag);
|
||||
const string& transportId, const string& candidate, const string& ufrag,
|
||||
const string& obfuscatedAddr) {
|
||||
mImpl->mHandler->AddIceCandidate(transportId, candidate, ufrag,
|
||||
obfuscatedAddr);
|
||||
return ipc::IPCResult::Ok();
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,28 @@ static const char* pcmLogTag = "PeerConnectionMedia";
|
|||
#define LOGTAG pcmLogTag
|
||||
|
||||
void PeerConnectionMedia::StunAddrsHandler::OnMDNSQueryComplete(
|
||||
const nsCString& hostname, const nsCString& address) {}
|
||||
const nsCString& hostname, const nsCString& address) {
|
||||
ASSERT_ON_THREAD(pcm_->mMainThread);
|
||||
auto itor = pcm_->mQueriedMDNSHostnames.find(hostname.BeginReading());
|
||||
if (itor != pcm_->mQueriedMDNSHostnames.end()) {
|
||||
for (auto& cand : itor->second) {
|
||||
// Replace obfuscated address with actual address
|
||||
std::string obfuscatedAddr = cand.mTokenizedCandidate[4];
|
||||
cand.mTokenizedCandidate[4] = address.BeginReading();
|
||||
std::ostringstream o;
|
||||
for (size_t i = 0; i < cand.mTokenizedCandidate.size(); ++i) {
|
||||
o << cand.mTokenizedCandidate[i];
|
||||
if (i + 1 != cand.mTokenizedCandidate.size()) {
|
||||
o << " ";
|
||||
}
|
||||
}
|
||||
std::string mungedCandidate = o.str();
|
||||
pcm_->mTransportHandler->AddIceCandidate(
|
||||
cand.mTransportId, mungedCandidate, cand.mUfrag, obfuscatedAddr);
|
||||
}
|
||||
pcm_->mQueriedMDNSHostnames.erase(itor);
|
||||
}
|
||||
}
|
||||
|
||||
void PeerConnectionMedia::StunAddrsHandler::OnStunAddrsAvailable(
|
||||
const mozilla::net::NrIceStunAddrArray& addrs) {
|
||||
|
@ -56,8 +77,6 @@ void PeerConnectionMedia::StunAddrsHandler::OnStunAddrsAvailable(
|
|||
if (!pcm_->mStunAddrs.Length()) {
|
||||
pcm_->IceConnectionStateChange_m(dom::RTCIceConnectionState::Failed);
|
||||
}
|
||||
|
||||
pcm_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -317,8 +336,52 @@ void PeerConnectionMedia::ConnectSignals() {
|
|||
void PeerConnectionMedia::AddIceCandidate(const std::string& aCandidate,
|
||||
const std::string& aTransportId,
|
||||
const std::string& aUfrag) {
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
MOZ_ASSERT(!aTransportId.empty());
|
||||
mTransportHandler->AddIceCandidate(aTransportId, aCandidate, aUfrag);
|
||||
|
||||
bool obfuscate_host_addresses = Preferences::GetBool(
|
||||
"media.peerconnection.ice.obfuscate_host_addresses", false);
|
||||
|
||||
if (obfuscate_host_addresses) {
|
||||
std::vector<std::string> tokens;
|
||||
TokenizeCandidate(aCandidate, tokens);
|
||||
|
||||
if (tokens.size() > 4) {
|
||||
std::string addr = tokens[4];
|
||||
|
||||
// Check for address ending with .local
|
||||
size_t nPeriods = std::count(addr.begin(), addr.end(), '.');
|
||||
size_t dotLocalLength = 6; // length of ".local"
|
||||
|
||||
if (nPeriods == 1 &&
|
||||
addr.rfind(".local") + dotLocalLength == addr.length()) {
|
||||
if (mStunAddrsRequest) {
|
||||
PendingIceCandidate cand;
|
||||
cand.mTokenizedCandidate = std::move(tokens);
|
||||
cand.mTransportId = aTransportId;
|
||||
cand.mUfrag = aUfrag;
|
||||
mQueriedMDNSHostnames[addr].push_back(cand);
|
||||
|
||||
mMainThread->Dispatch(NS_NewRunnableFunction(
|
||||
"PeerConnectionMedia::SendQueryMDNSHostname",
|
||||
[self = RefPtr<PeerConnectionMedia>(this), addr]() mutable {
|
||||
if (self->mStunAddrsRequest) {
|
||||
self->mStunAddrsRequest->SendQueryMDNSHostname(
|
||||
nsCString(nsAutoCString(addr.c_str())));
|
||||
}
|
||||
NS_ReleaseOnMainThreadSystemGroup(
|
||||
"PeerConnectionMedia::SendQueryMDNSHostname",
|
||||
self.forget());
|
||||
}));
|
||||
}
|
||||
// TODO: Bug 1535690, we don't want to tell the ICE context that remote
|
||||
// trickle is done if we are waiting to resolve a mDNS candidate.
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mTransportHandler->AddIceCandidate(aTransportId, aCandidate, aUfrag, "");
|
||||
}
|
||||
|
||||
void PeerConnectionMedia::UpdateNetworkState(bool online) {
|
||||
|
|
|
@ -232,6 +232,14 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
|||
// Used to store the mDNS hostnames that we have registered
|
||||
std::set<std::string> mRegisteredMDNSHostnames;
|
||||
|
||||
// Used to store the mDNS hostnames that we have queried
|
||||
struct PendingIceCandidate {
|
||||
std::vector<std::string> mTokenizedCandidate;
|
||||
std::string mTransportId;
|
||||
std::string mUfrag;
|
||||
};
|
||||
std::map<std::string, std::list<PendingIceCandidate>> mQueriedMDNSHostnames;
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PeerConnectionMedia)
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче