Bug 1506219 - Use a known remote for applications loaded from file:// URIs r=bwc

Fall back to using Google's DNS server to determine the associated local
addresses for web applications that are not loaded over the network.  This
includes the loopback address, which is frequently used in the unit tests.

Provide a separate function for setting the target for the default local
address lookup.

Differential Revision: https://phabricator.services.mozilla.com/D37331

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Ryan Alderete 2019-07-22 15:42:06 +00:00
Родитель 35bd2662ca
Коммит 14e5b45ecc
14 изменённых файлов: 168 добавлений и 92 удалений

Просмотреть файл

@ -30,9 +30,10 @@ class MediaTransportParent : public dom::PMediaTransportParent {
mozilla::ipc::IPCResult RecvEnsureProvisionalTransport(
const string& transportId, const string& localUfrag,
const string& localPwd, const int& componentCount);
mozilla::ipc::IPCResult RecvSetTargetForDefaultLocalAddressLookup(
const string& targetIp, uint16_t targetPort);
mozilla::ipc::IPCResult RecvStartIceGathering(
const bool& defaultRouteOnly, const string& remoteIp, uint16_t remotePort,
const net::NrIceStunAddrArray& stunAddrs);
const bool& defaultRouteOnly, const net::NrIceStunAddrArray& stunAddrs);
mozilla::ipc::IPCResult RecvActivateTransport(
const string& transportId, const string& localUfrag,
const string& localPwd, const int& componentCount,

Просмотреть файл

@ -54,9 +54,10 @@ parent:
string localPwd,
int componentCount);
async SetTargetForDefaultLocalAddressLookup(string targetIp,
uint16_t targetPort);
async StartIceGathering(bool defaultRouteOnly,
string remoteIp,
uint16_t remotePort,
NrIceStunAddrArray stunAddrs);
async ActivateTransport(string transportId,

Просмотреть файл

@ -519,9 +519,10 @@ void NrIceCtx::InitializeGlobals(bool allow_loopback, bool tcp_enabled,
}
}
void NrIceCtx::SetRemoteAddr(const std::string& remote_ip,
uint16_t remote_port) {
nr_ice_set_remote_address(ctx_, remote_ip.c_str(), remote_port);
void NrIceCtx::SetTargetForDefaultLocalAddressLookup(
const std::string& target_ip, uint16_t target_port) {
nr_ice_set_target_for_default_local_address_lookup(ctx_, target_ip.c_str(),
target_port);
}
#define MAXADDRS 100 // mirrors setting in ice_ctx.c

Просмотреть файл

@ -224,9 +224,8 @@ class NrIceCtx {
bool tcp_enabled = true,
bool allow_link_local = false);
// Set the IP address and port number for the remote. Must be called before
// SetStunAddrs.
void SetRemoteAddr(const std::string& remote_ip, uint16_t remote_port);
void SetTargetForDefaultLocalAddressLookup(const std::string& target_ip,
uint16_t target_port);
// static GetStunAddrs for use in parent process to support
// sandboxing restrictions

Просмотреть файл

@ -420,7 +420,7 @@ int nr_ice_ctx_create(char *label, UINT4 flags, nr_ice_ctx **ctxp)
}
}
ctx->remote_addr=0;
ctx->target_for_default_local_address_lookup=0;
STAILQ_INIT(&ctx->streams);
STAILQ_INIT(&ctx->sockets);
@ -457,7 +457,7 @@ static void nr_ice_ctx_destroy_cb(NR_SOCKET s, int how, void *cb_arg)
RFREE(ctx->local_addrs);
RFREE(ctx->remote_addr);
RFREE(ctx->target_for_default_local_address_lookup);
for (i = 0; i < ctx->turn_server_ct; i++) {
RFREE(ctx->turn_servers[i].username);
@ -612,36 +612,37 @@ static int nr_ice_ctx_pair_new_trickle_candidates(nr_ice_ctx *ctx, nr_ice_candid
are sent. This lets us query the local address assigned to the socket by the
kernel.
If the context's remote address is NULL, we can fall back on connecting to a
known public address (namely Google's):
If the context's remote address is NULL, then the application wasn't loaded
over the network, and we can fall back on connecting to a known public
address (namely Google's):
IPv4: 8.8.8.8
IPv6: 2001:4860:4860::8888
*/
static int nr_ice_get_default_address(nr_ice_ctx *ctx, int ip_version, nr_transport_addr *addrp)
static int nr_ice_get_default_address(nr_ice_ctx *ctx, int ip_version, nr_transport_addr* addrp)
{
int r,_status;
nr_transport_addr addr, known_remote_addr;
nr_transport_addr *remote_addr=ctx->remote_addr;
nr_transport_addr *remote_addr=ctx->target_for_default_local_address_lookup;
nr_socket *sock=0;
switch(ip_version) {
case NR_IPV4:
if ((r=nr_str_port_to_transport_addr("0.0.0.0", 0, IPPROTO_UDP, &addr)))
ABORT(r);
if (!remote_addr) {
if (!remote_addr || nr_transport_addr_is_loopback(remote_addr)) {
if ((r=nr_str_port_to_transport_addr("8.8.8.8", 53, IPPROTO_UDP, &known_remote_addr)))
ABORT(r);
remote_addr = &known_remote_addr;
remote_addr=&known_remote_addr;
}
break;
case NR_IPV6:
if ((r=nr_str_port_to_transport_addr("::0", 0, IPPROTO_UDP, &addr)))
ABORT(r);
if (!remote_addr) {
if (!remote_addr || nr_transport_addr_is_loopback(remote_addr)) {
if ((r=nr_str_port_to_transport_addr("2001:4860:4860::8888", 53, IPPROTO_UDP, &known_remote_addr)))
ABORT(r);
remote_addr = &known_remote_addr;
remote_addr=&known_remote_addr;
}
break;
default:
@ -752,14 +753,23 @@ int nr_ice_set_local_addresses(nr_ice_ctx *ctx,
ctx->label,
(char*)(ctx->flags & NR_ICE_CTX_FLAGS_ONLY_DEFAULT_ADDRS?"yes":"no"));
if ((!addr_ct) || (ctx->flags & NR_ICE_CTX_FLAGS_ONLY_DEFAULT_ADDRS)) {
/* Get just the default IPv4 and IPv6 addrs */
if(!nr_ice_get_default_local_address(ctx, NR_IPV4, local_addrs, addr_ct,
&default_addrs[default_addr_ct])) {
++default_addr_ct;
}
if(!nr_ice_get_default_local_address(ctx, NR_IPV6, local_addrs, addr_ct,
&default_addrs[default_addr_ct])) {
++default_addr_ct;
if (ctx->target_for_default_local_address_lookup) {
/* Get just the default IPv4 or IPv6 addr */
if(!nr_ice_get_default_local_address(
ctx, ctx->target_for_default_local_address_lookup->ip_version,
local_addrs, addr_ct, &default_addrs[default_addr_ct])) {
++default_addr_ct;
}
} else {
/* Get just the default IPv4 and IPv6 addrs */
if(!nr_ice_get_default_local_address(ctx, NR_IPV4, local_addrs, addr_ct,
&default_addrs[default_addr_ct])) {
++default_addr_ct;
}
if(!nr_ice_get_default_local_address(ctx, NR_IPV6, local_addrs, addr_ct,
&default_addrs[default_addr_ct])) {
++default_addr_ct;
}
}
if (!default_addr_ct) {
r_log(LOG_ICE,LOG_ERR,"ICE(%s): failed to find default addresses",ctx->label);
@ -795,19 +805,19 @@ int nr_ice_set_local_addresses(nr_ice_ctx *ctx,
return(_status);
}
int nr_ice_set_remote_address(nr_ice_ctx *ctx, const char *remote_ip, UINT2 remote_port)
int nr_ice_set_target_for_default_local_address_lookup(nr_ice_ctx *ctx, const char *target_ip, UINT2 target_port)
{
int r,_status;
if (ctx->remote_addr) {
RFREE(ctx->remote_addr);
ctx->remote_addr=0;
if (ctx->target_for_default_local_address_lookup) {
RFREE(ctx->target_for_default_local_address_lookup);
ctx->target_for_default_local_address_lookup=0;
}
if (!(ctx->remote_addr=RCALLOC(sizeof(nr_transport_addr))))
if (!(ctx->target_for_default_local_address_lookup=RCALLOC(sizeof(nr_transport_addr))))
ABORT(R_NO_MEMORY);
if ((r=nr_str_port_to_transport_addr(remote_ip, remote_port, IPPROTO_UDP, ctx->remote_addr)))
if ((r=nr_str_port_to_transport_addr(target_ip, target_port, IPPROTO_UDP, ctx->target_for_default_local_address_lookup)))
ABORT(r);
_status=0;

Просмотреть файл

@ -161,7 +161,7 @@ struct nr_ice_ctx_ {
char force_net_interface[MAXIFNAME];
nr_ice_stats stats;
nr_transport_addr *remote_addr; /* The address for the origin */
nr_transport_addr *target_for_default_local_address_lookup;
};
int nr_ice_ctx_create(char *label, UINT4 flags, nr_ice_ctx **ctxp);
@ -177,7 +177,7 @@ void nr_ice_ctx_add_flags(nr_ice_ctx *ctx, UINT4 flags);
void nr_ice_ctx_remove_flags(nr_ice_ctx *ctx, UINT4 flags);
int nr_ice_ctx_destroy(nr_ice_ctx **ctxp);
int nr_ice_set_local_addresses(nr_ice_ctx *ctx, nr_local_addr* stun_addrs, int stun_addr_ct);
int nr_ice_set_remote_address(nr_ice_ctx *ctx, const char *remote_ip, UINT2 remote_port);
int nr_ice_set_target_for_default_local_address_lookup(nr_ice_ctx *ctx, const char *target_ip, UINT2 target_port);
int nr_ice_gather(nr_ice_ctx *ctx, NR_async_cb done_cb, void *cb_arg);
int nr_ice_add_candidate(nr_ice_ctx *ctx, nr_ice_candidate *cand);
void nr_ice_gather_finished_cb(NR_SOCKET s, int h, void *cb_arg);

Просмотреть файл

@ -174,12 +174,14 @@ class LoopbackTransport : public MediaTransportHandler {
const std::string& aLocalPwd,
size_t aComponentCount) override {}
void SetTargetForDefaultLocalAddressLookup(const std::string& aTargetIp,
uint16_t aTargetPort) override {}
// We set default-route-only as late as possible because it depends on what
// capture permissions have been granted on the window, which could easily
// change between Init (ie; when the PC is created) and StartIceGathering
// (ie; when we set the local description).
void StartIceGathering(bool aDefaultRouteOnly, const std::string& aRemoteIp,
uint16_t aRemotePort,
void StartIceGathering(bool aDefaultRouteOnly,
// TODO: It probably makes sense to look
// this up internally
const nsTArray<NrIceStunAddr>& aStunAddrs) override {}

Просмотреть файл

@ -79,12 +79,14 @@ class MediaTransportHandlerSTS : public MediaTransportHandler,
const std::string& aPwd,
size_t aComponentCount) override;
void SetTargetForDefaultLocalAddressLookup(const std::string& aTargetIp,
uint16_t aTargetPort) override;
// We set default-route-only as late as possible because it depends on what
// capture permissions have been granted on the window, which could easily
// change between Init (ie; when the PC is created) and StartIceGathering
// (ie; when we set the local description).
void StartIceGathering(bool aDefaultRouteOnly, const std::string& aRemoteIp,
uint16_t aRemotePort,
void StartIceGathering(bool aDefaultRouteOnly,
// This will go away once mtransport moves to its
// own process, because we won't need to get this
// via IPC anymore
@ -641,9 +643,18 @@ void MediaTransportHandlerSTS::ActivateTransport(
[](const std::string& aError) {});
}
void MediaTransportHandlerSTS::SetTargetForDefaultLocalAddressLookup(
const std::string& aTargetIp, uint16_t aTargetPort) {
mInitPromise->Then(
mStsThread, __func__,
[=, self = RefPtr<MediaTransportHandlerSTS>(this)]() {
mIceCtx->SetTargetForDefaultLocalAddressLookup(aTargetIp, aTargetPort);
},
[](const std::string& aError) {});
}
void MediaTransportHandlerSTS::StartIceGathering(
bool aDefaultRouteOnly, const std::string& aRemoteIp, uint16_t aRemotePort,
const nsTArray<NrIceStunAddr>& aStunAddrs) {
bool aDefaultRouteOnly, const nsTArray<NrIceStunAddr>& aStunAddrs) {
mInitPromise->Then(
mStsThread, __func__,
[=, self = RefPtr<MediaTransportHandlerSTS>(this)]() {
@ -652,8 +663,6 @@ void MediaTransportHandlerSTS::StartIceGathering(
// setting those flags happens in StartGathering. We could probably
// just set them here, and only do it here.
mIceCtx->SetCtxFlags(aDefaultRouteOnly, mProxyOnly);
mIceCtx->SetRemoteAddr(aRemoteIp, aRemotePort);
if (aStunAddrs.Length()) {
mIceCtx->SetStunAddrs(aStunAddrs);

Просмотреть файл

@ -78,13 +78,14 @@ class MediaTransportHandler {
const std::string& aLocalPwd,
size_t aComponentCount) = 0;
virtual void SetTargetForDefaultLocalAddressLookup(
const std::string& aTargetIp, uint16_t aTargetPort) = 0;
// We set default-route-only as late as possible because it depends on what
// capture permissions have been granted on the window, which could easily
// change between Init (ie; when the PC is created) and StartIceGathering
// (ie; when we set the local description).
virtual void StartIceGathering(bool aDefaultRouteOnly,
const std::string& aRemoteIp,
uint16_t aRemotePort,
// TODO: It probably makes sense to look
// this up internally
const nsTArray<NrIceStunAddr>& aStunAddrs) = 0;

Просмотреть файл

@ -183,20 +183,32 @@ void MediaTransportHandlerIPC::EnsureProvisionalTransport(
[](const nsCString& aError) {});
}
void MediaTransportHandlerIPC::SetTargetForDefaultLocalAddressLookup(
const std::string& aTargetIp, uint16_t aTargetPort) {
mInitPromise->Then(
mCallbackThread, __func__,
[=, self = RefPtr<MediaTransportHandlerIPC>(this)](bool /*dummy*/) {
if (mChild) {
mChild->SendSetTargetForDefaultLocalAddressLookup(aTargetIp,
aTargetPort);
}
},
[](const nsCString& aError) {});
}
// We set default-route-only as late as possible because it depends on what
// capture permissions have been granted on the window, which could easily
// change between Init (ie; when the PC is created) and StartIceGathering
// (ie; when we set the local description).
void MediaTransportHandlerIPC::StartIceGathering(
bool aDefaultRouteOnly, const std::string& aRemoteIp, uint16_t aRemotePort,
bool aDefaultRouteOnly,
// TODO(bug 1522205): It probably makes sense to look this up internally
const nsTArray<NrIceStunAddr>& aStunAddrs) {
mInitPromise->Then(
mCallbackThread, __func__,
[=, self = RefPtr<MediaTransportHandlerIPC>(this)](bool /*dummy*/) {
if (mChild) {
mChild->SendStartIceGathering(aDefaultRouteOnly, aRemoteIp,
aRemotePort, aStunAddrs);
mChild->SendStartIceGathering(aDefaultRouteOnly, aStunAddrs);
}
},
[](const nsCString& aError) {});
@ -321,9 +333,7 @@ MediaTransportHandlerIPC::GetIceStats(
MediaTransportChild::MediaTransportChild(MediaTransportHandlerIPC* aUser)
: mUser(aUser) {}
MediaTransportChild::~MediaTransportChild() {
mUser->mChild = nullptr;
}
MediaTransportChild::~MediaTransportChild() { mUser->mChild = nullptr; }
mozilla::ipc::IPCResult MediaTransportChild::RecvOnCandidate(
const string& transportId, const CandidateInfo& candidateInfo) {

Просмотреть файл

@ -36,12 +36,14 @@ class MediaTransportHandlerIPC : public MediaTransportHandler {
const std::string& aLocalPwd,
size_t aComponentCount) override;
void SetTargetForDefaultLocalAddressLookup(const std::string& aTargetIp,
uint16_t aTargetPort) override;
// We set default-route-only as late as possible because it depends on what
// capture permissions have been granted on the window, which could easily
// change between Init (ie; when the PC is created) and StartIceGathering
// (ie; when we set the local description).
void StartIceGathering(bool aDefaultRouteOnly, const std::string& aRemoteIp,
uint16_t aRemotePort,
void StartIceGathering(bool aDefaultRouteOnly,
// TODO: It probably makes sense to look
// this up internally
const nsTArray<NrIceStunAddr>& aStunAddrs) override;

Просмотреть файл

@ -127,7 +127,6 @@ mozilla::ipc::IPCResult MediaTransportParent::RecvExitPrivateMode() {
mozilla::ipc::IPCResult MediaTransportParent::RecvCreateIceCtx(
const string& name, nsTArray<RTCIceServer>&& iceServers,
const RTCIceTransportPolicy& icePolicy) {
nsresult rv = mImpl->mHandler->CreateIceCtx(name, iceServers, icePolicy);
if (NS_FAILED(rv)) {
return ipc::IPCResult::Fail(WrapNotNull(this), __func__,
@ -151,11 +150,16 @@ mozilla::ipc::IPCResult MediaTransportParent::RecvEnsureProvisionalTransport(
return ipc::IPCResult::Ok();
}
mozilla::ipc::IPCResult
MediaTransportParent::RecvSetTargetForDefaultLocalAddressLookup(
const std::string& targetIp, uint16_t targetPort) {
mImpl->mHandler->SetTargetForDefaultLocalAddressLookup(targetIp, targetPort);
return ipc::IPCResult::Ok();
}
mozilla::ipc::IPCResult MediaTransportParent::RecvStartIceGathering(
const bool& defaultRouteOnly, const std::string& remoteIp,
uint16_t remotePort, const net::NrIceStunAddrArray& stunAddrs) {
mImpl->mHandler->StartIceGathering(defaultRouteOnly, remoteIp, remotePort,
stunAddrs);
const bool& defaultRouteOnly, const net::NrIceStunAddrArray& stunAddrs) {
mImpl->mHandler->StartIceGathering(defaultRouteOnly, stunAddrs);
return ipc::IPCResult::Ok();
}
@ -233,7 +237,6 @@ mozilla::ipc::IPCResult MediaTransportParent::RecvGetIceStats(
return ipc::IPCResult::Ok();
}
void MediaTransportParent::ActorDestroy(ActorDestroyReason aWhy) {
}
void MediaTransportParent::ActorDestroy(ActorDestroyReason aWhy) {}
} // namespace mozilla

Просмотреть файл

@ -114,8 +114,7 @@ PeerConnectionMedia::PeerConnectionMedia(PeerConnectionImpl* parent)
mProxyResolveCompleted(false),
mProxyConfig(nullptr),
mLocalAddrsCompleted(false),
mRemoteIp(),
mRemotePort(0) {}
mTargetForDefaultLocalAddressLookupIsSet(false) {}
PeerConnectionMedia::~PeerConnectionMedia() {
MOZ_RELEASE_ASSERT(!mMainThread);
@ -206,31 +205,7 @@ nsresult PeerConnectionMedia::InitProxy() {
}
nsresult PeerConnectionMedia::Init() {
// Get the remote address and port number from the parent.
Document* doc =
mParent->GetWindow() ? mParent->GetWindow()->GetDoc() : nullptr;
MOZ_ASSERT(doc);
nsIChannel* channel = doc->GetChannel();
MOZ_ASSERT(channel);
nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal =
do_QueryInterface(channel);
MOZ_ASSERT(httpChannelInternal);
nsresult rv;
rv = httpChannelInternal->GetRemoteAddress(mRemoteIp);
if (NS_FAILED(rv) || mRemoteIp.IsEmpty()) {
CSFLogError(LOGTAG, "%s: Couldn't get remote IP address", __FUNCTION__);
return rv;
}
rv = httpChannelInternal->GetRemotePort(&mRemotePort);
if (NS_FAILED(rv)) {
CSFLogError(LOGTAG, "%s: Couldn't get remote port number", __FUNCTION__);
return rv;
}
rv = InitProxy();
nsresult rv = InitProxy();
NS_ENSURE_SUCCESS(rv, rv);
// setup the stun local addresses IPC async call
@ -445,6 +420,56 @@ void PeerConnectionMedia::GatherIfReady() {
PerformOrEnqueueIceCtxOperation(runnable);
}
nsresult PeerConnectionMedia::SetTargetForDefaultLocalAddressLookup() {
Document* doc = mParent->GetWindow()->GetExtantDoc();
if (!doc) {
MOZ_ASSERT(false, "Failed to get document from window");
NS_WARNING("Failed to get document from window");
return NS_ERROR_FAILURE;
}
bool isFileScheme;
doc->GetDocumentURI()->SchemeIs("file", &isFileScheme);
if (!isFileScheme) {
nsIChannel* channel = doc->GetChannel();
if (!channel) {
MOZ_ASSERT(false, "Failed to get channel from document");
NS_WARNING("Failed to get channel from document");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal =
do_QueryInterface(channel);
if (!httpChannelInternal) {
NS_WARNING(
"Failed to get HTTP channel internal from document loaded "
"over network");
return NS_ERROR_FAILURE;
}
nsCString remoteIp;
nsresult rv = httpChannelInternal->GetRemoteAddress(remoteIp);
if (NS_FAILED(rv) || remoteIp.IsEmpty()) {
CSFLogError(LOGTAG, "%s: Failed to get remote IP address: %d",
__FUNCTION__, (int)rv);
return rv;
}
int32_t remotePort;
rv = httpChannelInternal->GetRemotePort(&remotePort);
if (NS_FAILED(rv)) {
CSFLogError(LOGTAG, "%s: Failed to get remote port number: %d",
__FUNCTION__, (int)rv);
return rv;
}
mTransportHandler->SetTargetForDefaultLocalAddressLookup(remoteIp.get(),
remotePort);
}
return NS_OK;
}
void PeerConnectionMedia::EnsureIceGathering(bool aDefaultRouteOnly) {
if (mProxyConfig) {
// Note that this could check if PrivacyRequested() is set on the PC and
@ -456,6 +481,17 @@ void PeerConnectionMedia::EnsureIceGathering(bool aDefaultRouteOnly) {
mProxyConfig.reset();
}
if (!mTargetForDefaultLocalAddressLookupIsSet) {
nsresult rv = SetTargetForDefaultLocalAddressLookup();
if (NS_FAILED(rv)) {
CSFLogError(LOGTAG,
"%s: Unable to set target for default local address lookup",
__FUNCTION__);
return;
}
mTargetForDefaultLocalAddressLookupIsSet = true;
}
// Make sure we don't call StartIceGathering if we're in e10s mode
// and we received no STUN addresses from the parent process. In the
// absence of previously provided STUN addresses, StartIceGathering will
@ -467,8 +503,7 @@ void PeerConnectionMedia::EnsureIceGathering(bool aDefaultRouteOnly) {
return;
}
mTransportHandler->StartIceGathering(aDefaultRouteOnly, mRemoteIp.get(),
mRemotePort, mStunAddrs);
mTransportHandler->StartIceGathering(aDefaultRouteOnly, mStunAddrs);
}
void PeerConnectionMedia::SelfDestruct() {

Просмотреть файл

@ -177,6 +177,7 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
void GatherIfReady();
void FlushIceCtxOperationQueueIfReady();
void PerformOrEnqueueIceCtxOperation(nsIRunnable* runnable);
nsresult SetTargetForDefaultLocalAddressLookup();
void EnsureIceGathering(bool aDefaultRouteOnly);
bool GetPrefDefaultAddressOnly() const;
@ -236,8 +237,9 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
// Used to store the result of the stun addr IPC request
nsTArray<NrIceStunAddr> mStunAddrs;
nsCString mRemoteIp;
int32_t mRemotePort;
// Used to ensure the target for default local address lookup is only set
// once.
bool mTargetForDefaultLocalAddressLookupIsSet;
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PeerConnectionMedia)
};