Bug 1345511 - pt 3 - start using IPC call for stun addrs in PCMedia. r=bwc

Two new calls are added to NrIceCtx.
1) A static call to allow StunAddrsRequestParent to get stun addrs from the main
process.
2) A call to allow StunAddrsRequestChild to pass the new stun addrs back to
PeerConnectionMedia on the content process.

PeerConnectionMedia, when running in e10s mode, sets up the StunAddrsRequestChild
and makes the async request to get the stun addrs.  When they are returned, it
sets the stun addrs in NrIceCtx avoid the network calls that would otherwise
cause a further restricted sandbox to fail.

MozReview-Commit-ID: C2hYBzm6WNv

--HG--
extra : rebase_source : 4c71056850c418efdc0f709f4d838a3e0bf4bee2
This commit is contained in:
Michael Froman 2017-03-22 09:59:46 -05:00
parent f0c929ff2d
commit 647131bd6f
5 changed files with 125 additions and 3 deletions

View File

@ -49,7 +49,7 @@ StunAddrsRequestParent::GetStunAddrs_s()
ASSERT_ON_THREAD(mSTSThread);
// get the stun addresses while on STS thread
NrIceStunAddrArray addrs; // = NrIceCtx::GetStunAddrs();
NrIceStunAddrArray addrs = NrIceCtx::GetStunAddrs();
// in order to return the result over IPC, we need to be on main thread
RUN_ON_THREAD(mMainThread,

View File

@ -82,6 +82,7 @@ extern "C" {
#include "stun_client_ctx.h"
#include "stun_reg.h"
#include "stun_server_ctx.h"
#include "stun_util.h"
#include "ice_codeword.h"
#include "ice_ctx.h"
#include "ice_candidate.h"
@ -520,6 +521,51 @@ NrIceCtx::GetNewPwd()
return pwdStr;
}
#define MAXADDRS 100 // mirrors setting in ice_ctx.c
/* static */
nsTArray<NrIceStunAddr>
NrIceCtx::GetStunAddrs()
{
nsTArray<NrIceStunAddr> addrs;
nr_local_addr local_addrs[MAXADDRS];
int addr_ct=0;
// most likely running on parent process and need crypto vtbl
// initialized on Windows (Linux and OSX don't seem to care)
if (!initialized) {
nr_crypto_vtbl = &nr_ice_crypto_nss_vtbl;
}
MOZ_MTLOG(ML_INFO, "NrIceCtx static call to find local stun addresses");
if (nr_stun_find_local_addresses(local_addrs, MAXADDRS, &addr_ct)) {
MOZ_MTLOG(ML_INFO, "Error finding local stun addresses");
} else {
for(int i=0; i<addr_ct; ++i) {
NrIceStunAddr addr(&local_addrs[i]);
addrs.AppendElement(addr);
}
}
return addrs;
}
void
NrIceCtx::SetStunAddrs(const nsTArray<NrIceStunAddr>& addrs)
{
nr_local_addr* local_addrs;
local_addrs = new nr_local_addr[addrs.Length()];
for(size_t i=0; i<addrs.Length(); ++i) {
nr_local_addr_copy(&local_addrs[i],
const_cast<nr_local_addr*>(&addrs[i].localAddr()));
}
nr_ice_set_local_addresses(ctx_, local_addrs, addrs.Length());
delete[] local_addrs;
}
bool
NrIceCtx::Initialize()
{

View File

@ -63,8 +63,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "nsAutoPtr.h"
#include "nsIEventTarget.h"
#include "nsITimer.h"
#include "nsTArray.h"
#include "m_cpp_utils.h"
#include "nricestunaddr.h"
typedef struct nr_ice_ctx_ nr_ice_ctx;
typedef struct nr_ice_peer_ctx_ nr_ice_peer_ctx;
@ -233,6 +235,11 @@ class NrIceCtx {
static std::string GetNewUfrag();
static std::string GetNewPwd();
// static GetStunAddrs for use in parent process to support
// sandboxing restrictions
static nsTArray<NrIceStunAddr> GetStunAddrs();
void SetStunAddrs(const nsTArray<NrIceStunAddr>& addrs);
bool Initialize();
bool Initialize(const std::string& ufrag, const std::string& pwd);

View File

@ -259,6 +259,21 @@ PeerConnectionMedia::ProtocolProxyQueryHandler::SetProxyOnPcm(
NS_IMPL_ISUPPORTS(PeerConnectionMedia::ProtocolProxyQueryHandler, nsIProtocolProxyCallback)
void
PeerConnectionMedia::StunAddrsHandler::OnStunAddrsAvailable(
const mozilla::net::NrIceStunAddrArray& addrs)
{
CSFLogInfo(logTag, "%s: receiving (%d) stun addrs", __FUNCTION__,
(int)addrs.Length());
if (pcm_) {
pcm_->mStunAddrs = addrs;
pcm_->mLocalAddrsCompleted = true;
pcm_->mStunAddrsRequest = nullptr;
pcm_->FlushIceCtxOperationQueueIfReady();
pcm_ = nullptr;
}
}
PeerConnectionMedia::PeerConnectionMedia(PeerConnectionImpl *parent)
: mParent(parent),
mParentHandle(parent->GetHandle()),
@ -269,7 +284,27 @@ PeerConnectionMedia::PeerConnectionMedia(PeerConnectionImpl *parent)
mMainThread(mParent->GetMainThread()),
mSTSThread(mParent->GetSTSThread()),
mProxyResolveCompleted(false),
mIceRestartState(ICE_RESTART_NONE) {
mIceRestartState(ICE_RESTART_NONE),
mLocalAddrsCompleted(false) {
}
void
PeerConnectionMedia::InitLocalAddrs()
{
if (XRE_IsContentProcess()) {
CSFLogDebug(logTag, "%s: Get stun addresses via IPC",
mParentHandle.c_str());
// We're in the content process, so send a request over IPC for the
// stun address discovery.
mStunAddrsRequest =
new StunAddrsRequestChild(new StunAddrsHandler(this));
mStunAddrsRequest->SendGetStunAddrs();
} else {
// No content process, so don't need to hold up the ice event queue
// until completion of stun address discovery. We can let the
// discovery of stun addresses happen in the same process.
mLocalAddrsCompleted = true;
}
}
nsresult
@ -353,6 +388,9 @@ nsresult PeerConnectionMedia::Init(const std::vector<NrIceStunServer>& stun_serv
bool ice_tcp = Preferences::GetBool("media.peerconnection.ice.tcp", false);
// setup the stun local addresses IPC async call
InitLocalAddrs();
// TODO(ekr@rtfm.com): need some way to set not offerer later
// Looks like a bug in the NrIceCtx API.
mIceCtxHdlr = NrIceCtxHandler::Create("PC:" + mParentName,
@ -920,6 +958,10 @@ PeerConnectionMedia::EnsureIceGathering_s(bool aDefaultRouteOnly,
return;
}
if (mStunAddrs.Length()) {
mIceCtxHdlr->ctx()->SetStunAddrs(mStunAddrs);
}
// Start gathering, but only if there are streams
for (size_t i = 0; i < mIceCtxHdlr->ctx()->GetStreamCount(); ++i) {
if (mIceCtxHdlr->ctx()->GetStream(i)) {
@ -1017,6 +1059,11 @@ PeerConnectionMedia::SelfDestruct()
mRemoteSourceStreams[i]->DetachMedia_m();
}
if (mStunAddrsRequest) {
mStunAddrsRequest->Cancel();
mStunAddrsRequest = nullptr;
}
if (mProxyRequest) {
mProxyRequest->Cancel(NS_ERROR_ABORT);
mProxyRequest = nullptr;

View File

@ -14,6 +14,7 @@
#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/net/StunAddrsRequestChild.h"
#include "nsComponentManagerUtils.h"
#include "nsIProtocolProxyCallback.h"
@ -431,6 +432,7 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
RefPtr<WebRtcCallWrapper> mCall;
private:
void InitLocalAddrs(); // for stun local address IPC request
nsresult InitProxy();
class ProtocolProxyQueryHandler : public nsIProtocolProxyCallback {
public:
@ -449,6 +451,17 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
virtual ~ProtocolProxyQueryHandler() {}
};
class StunAddrsHandler : public net::StunAddrsListener {
public:
explicit StunAddrsHandler(PeerConnectionMedia *pcm) :
pcm_(pcm) {}
void OnStunAddrsAvailable(
const mozilla::net::NrIceStunAddrArray& addrs) override;
private:
RefPtr<PeerConnectionMedia> pcm_;
virtual ~StunAddrsHandler() {}
};
// Shutdown media transport. Must be called on STS thread.
void ShutdownMediaTransport_s();
@ -522,7 +535,7 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
uint16_t aDefaultRtcpPort,
uint16_t aMLine);
bool IsIceCtxReady() const {
return mProxyResolveCompleted;
return mProxyResolveCompleted && mLocalAddrsCompleted;
}
// The parent PC
@ -577,6 +590,15 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
// Used to track the state of ice restart
IceRestartState mIceRestartState;
// Used to cancel incoming stun addrs response
RefPtr<net::StunAddrsRequestChild> mStunAddrsRequest;
// Used to track the state of the stun addr IPC request
bool mLocalAddrsCompleted;
// Used to store the result of the stun addr IPC request
nsTArray<NrIceStunAddr> mStunAddrs;
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PeerConnectionMedia)
};