Bug 1345511 - pt 2 - add IPC mechanism for getting stun addrs on main process. r=bwc

PStunAddrsRequest.ipdl defines the new IPC protocol to get stun
  addrs on the main process.
StunAddrsRequestChild requests the stun addrs from the parent.
StunAddrsRequestParent uses a static method on NrIceCtx to get the
  stun addrs from the STS thead and sends the addrs back to the
  child process.
NrIceStunAddr (nricestunaddr.{cpp|h}) wraps nr_local_addr and makes
  it easier to serialize/deserialize over IPC.
NrIceStunAddrMessageUtils follows the pattern used by other Necko
  IPC classes to define top-level serialization/deserialization
  calls used by the IPC framework.

Modifications under netwerk/ipc are to connect the new IPC
protocol to get stun addrs to PNecko since it is a network
related IPC protocol.

MozReview-Commit-ID: GyEapBe5krl

--HG--
extra : rebase_source : c650d6aa4f7928bcae6032424303869074a755d4
This commit is contained in:
Michael Froman 2017-03-21 19:59:05 -05:00
Родитель 032f9ca0bc
Коммит f0c929ff2d
18 изменённых файлов: 527 добавлений и 0 удалений

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

@ -12,6 +12,7 @@ EXPORTS.mtransport += [
'../nricectx.h',
'../nricemediastream.h',
'../nriceresolverfake.h',
'../nricestunaddr.h',
'../rlogconnector.h',
'../runnable_utils.h',
'../sigslot.h',

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

@ -13,6 +13,7 @@ mtransport_lcppsrcs = [
'nricemediastream.cpp',
'nriceresolver.cpp',
'nriceresolverfake.cpp',
'nricestunaddr.cpp',
'nrinterfaceprioritizer.cpp',
'rlogconnector.cpp',
'simpletokenbucket.cpp',

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

@ -0,0 +1,46 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_net_NrIceStunAddrMessageUtils_h
#define mozilla_net_NrIceStunAddrMessageUtils_h
#include "ipc/IPCMessageUtils.h"
#include "mtransport/nricestunaddr.h"
namespace IPC {
template<>
struct ParamTraits<mozilla::NrIceStunAddr>
{
static void Write(Message* aMsg, const mozilla::NrIceStunAddr &aParam)
{
const size_t bufSize = aParam.SerializationBufferSize();
char* buffer = new char[bufSize];
aParam.Serialize(buffer, bufSize);
aMsg->WriteBytes((void*)buffer, bufSize);
delete[] buffer;
}
static bool Read(const Message* aMsg,
PickleIterator* aIter,
mozilla::NrIceStunAddr* aResult)
{
const size_t bufSize = aResult->SerializationBufferSize();
char* buffer = new char[bufSize];
bool result =
aMsg->ReadBytesInto(aIter, (void*)buffer, bufSize);
if (result) {
result = result &&
(NS_OK == aResult->Deserialize(buffer, bufSize));
}
delete[] buffer;
return result;
}
};
} // namespace IPC
#endif // mozilla_net_NrIceStunAddrMessageUtils_h

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

@ -0,0 +1,20 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef PStunAddrsParams_h
#define PStunAddrsParams_h
#include "mtransport/nricestunaddr.h"
#include "nsTArray.h"
namespace mozilla {
namespace net {
// Need to define typedef in .h file--can't seem to in ipdl.h file?
typedef nsTArray<NrIceStunAddr> NrIceStunAddrArray;
} // namespace net
} // namespace mozilla
#endif // PStunAddrsParams_h

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

@ -0,0 +1,29 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PNecko;
using class mozilla::NrIceStunAddr from "mtransport/nricestunaddr.h";
using NrIceStunAddrArray from "mozilla/net/PStunAddrsParams.h";
include "mozilla/net/NrIceStunAddrMessageUtils.h";
namespace mozilla {
namespace net {
async protocol PStunAddrsRequest
{
manager PNecko;
parent:
async GetStunAddrs();
async __delete__();
child:
async OnStunAddrsAvailable(NrIceStunAddrArray iceStunAddrs);
};
} // namespace net
} // namespace mozilla

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

@ -0,0 +1,43 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "StunAddrsRequestChild.h"
#include "mozilla/net/NeckoChild.h"
using namespace mozilla::ipc;
namespace mozilla {
namespace net {
StunAddrsRequestChild::StunAddrsRequestChild(StunAddrsListener* listener) :
mListener(listener)
{
gNeckoChild->SendPStunAddrsRequestConstructor(this);
// IPDL holds a reference until IPDL channel gets destroyed
AddIPDLReference();
}
mozilla::ipc::IPCResult
StunAddrsRequestChild::RecvOnStunAddrsAvailable(const NrIceStunAddrArray& addrs)
{
if (mListener) {
mListener->OnStunAddrsAvailable(addrs);
}
return IPC_OK();
}
void
StunAddrsRequestChild::Cancel()
{
mListener = nullptr;
}
NS_IMPL_ADDREF(StunAddrsRequestChild)
NS_IMPL_RELEASE(StunAddrsRequestChild)
NS_IMPL_ADDREF(StunAddrsListener)
NS_IMPL_RELEASE(StunAddrsListener)
} // namespace net
} // namespace mozilla

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

@ -0,0 +1,58 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_net_StunAddrsRequestChild_h
#define mozilla_net_StunAddrsRequestChild_h
#include "mozilla/net/PStunAddrsRequestChild.h"
namespace mozilla {
namespace net {
class StunAddrsListener {
public:
virtual void OnStunAddrsAvailable(const NrIceStunAddrArray& addrs) = 0;
NS_IMETHOD_(MozExternalRefCountType) AddRef();
NS_IMETHOD_(MozExternalRefCountType) Release();
protected:
virtual ~StunAddrsListener() {}
ThreadSafeAutoRefCnt mRefCnt;
NS_DECL_OWNINGTHREAD
};
class StunAddrsRequestChild final : public PStunAddrsRequestChild
{
public:
explicit StunAddrsRequestChild(StunAddrsListener* listener);
NS_IMETHOD_(MozExternalRefCountType) AddRef();
NS_IMETHOD_(MozExternalRefCountType) Release();
// Not sure why AddIPDLReference & ReleaseIPDLReference don't come
// from PStunAddrsRequestChild since the IPC plumbing seem to
// expect this.
void AddIPDLReference() { AddRef(); }
void ReleaseIPDLReference() { Release(); }
void Cancel();
protected:
virtual ~StunAddrsRequestChild() {}
virtual mozilla::ipc::IPCResult RecvOnStunAddrsAvailable(
const NrIceStunAddrArray& addrs) override;
RefPtr<StunAddrsListener> mListener;
ThreadSafeAutoRefCnt mRefCnt;
NS_DECL_OWNINGTHREAD
};
} // namespace net
} // namespace mozilla
#endif // mozilla_net_StunAddrsRequestChild_h

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

@ -0,0 +1,75 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "StunAddrsRequestParent.h"
#include "../runnable_utils.h"
#include "nsNetUtil.h"
#include "mtransport/nricectx.h"
#include "mtransport/nricemediastream.h" // needed only for including nricectx.h
#include "mtransport/nricestunaddr.h"
using namespace mozilla::ipc;
namespace mozilla {
namespace net {
StunAddrsRequestParent::StunAddrsRequestParent()
{
NS_GetMainThread(getter_AddRefs(mMainThread));
nsresult res;
mSTSThread = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &res);
MOZ_ASSERT(mSTSThread);
}
mozilla::ipc::IPCResult
StunAddrsRequestParent::RecvGetStunAddrs()
{
ASSERT_ON_THREAD(mMainThread);
RUN_ON_THREAD(mSTSThread,
WrapRunnable(this, &StunAddrsRequestParent::GetStunAddrs_s),
NS_DISPATCH_NORMAL);
return IPC_OK();
}
void
StunAddrsRequestParent::ActorDestroy(ActorDestroyReason why)
{
// nothing to do here
}
void
StunAddrsRequestParent::GetStunAddrs_s()
{
ASSERT_ON_THREAD(mSTSThread);
// get the stun addresses while on STS thread
NrIceStunAddrArray addrs; // = NrIceCtx::GetStunAddrs();
// in order to return the result over IPC, we need to be on main thread
RUN_ON_THREAD(mMainThread,
WrapRunnable(this,
&StunAddrsRequestParent::SendStunAddrs_m,
std::move(addrs)),
NS_DISPATCH_NORMAL);
}
void
StunAddrsRequestParent::SendStunAddrs_m(const NrIceStunAddrArray& addrs)
{
ASSERT_ON_THREAD(mMainThread);
// send the new addresses back to the child
Unused << SendOnStunAddrsAvailable(addrs);
}
NS_IMPL_ADDREF(StunAddrsRequestParent)
NS_IMPL_RELEASE(StunAddrsRequestParent)
} // namespace net
} // namespace mozilla

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

@ -0,0 +1,40 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_net_StunAddrsRequestParent_h
#define mozilla_net_StunAddrsRequestParent_h
#include "mozilla/net/PStunAddrsRequestParent.h"
namespace mozilla {
namespace net {
class StunAddrsRequestParent : public PStunAddrsRequestParent
{
public:
StunAddrsRequestParent();
NS_IMETHOD_(MozExternalRefCountType) AddRef();
NS_IMETHOD_(MozExternalRefCountType) Release();
protected:
virtual ~StunAddrsRequestParent() {}
virtual mozilla::ipc::IPCResult RecvGetStunAddrs() override;
virtual void ActorDestroy(ActorDestroyReason why) override;
nsCOMPtr<nsIThread> mMainThread;
nsCOMPtr<nsIEventTarget> mSTSThread;
void GetStunAddrs_s();
void SendStunAddrs_m(const NrIceStunAddrArray& addrs);
ThreadSafeAutoRefCnt mRefCnt;
NS_DECL_OWNINGTHREAD
};
} // namespace net
} // namespace mozilla
#endif // mozilla_net_StunAddrsRequestParent_h

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

@ -0,0 +1,24 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXPORTS.mozilla.net += [
'NrIceStunAddrMessageUtils.h',
'PStunAddrsParams.h',
'StunAddrsRequestChild.h',
'StunAddrsRequestParent.h',
]
UNIFIED_SOURCES += [
'StunAddrsRequestChild.cpp',
'StunAddrsRequestParent.cpp',
]
IPDL_SOURCES += [
'PStunAddrsRequest.ipdl',
]
include("/ipc/chromium/chromium-config.mozbuild")
FINAL_LIBRARY = 'xul'

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

@ -12,4 +12,5 @@ include("/ipc/chromium/chromium-config.mozbuild")
DIRS += [
'/media/mtransport/third_party',
'/media/mtransport/build',
'/media/mtransport/ipc',
]

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

@ -0,0 +1,105 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "logging.h"
// nICEr includes
extern "C" {
#include "nr_api.h"
#include "r_memory.h"
#include "local_addr.h"
}
// Local includes
#include "nricestunaddr.h"
namespace mozilla {
MOZ_MTLOG_MODULE("mtransport")
NrIceStunAddr::NrIceStunAddr()
: localAddr_(new nr_local_addr)
{
memset(localAddr_, 0, sizeof(nr_local_addr));
}
NrIceStunAddr::NrIceStunAddr(const nr_local_addr* addr)
: localAddr_(new nr_local_addr)
{
nr_local_addr_copy(localAddr_,
const_cast<nr_local_addr*>(addr));
}
NrIceStunAddr::NrIceStunAddr(const NrIceStunAddr& rhs)
: localAddr_(new nr_local_addr)
{
nr_local_addr_copy(localAddr_,
const_cast<nr_local_addr*>(rhs.localAddr_));
}
NrIceStunAddr::~NrIceStunAddr()
{
delete localAddr_;
}
size_t
NrIceStunAddr::SerializationBufferSize() const
{
return sizeof(nr_local_addr);
}
nsresult
NrIceStunAddr::Serialize(char* buffer, size_t buffer_size) const
{
if (buffer_size != sizeof(nr_local_addr)) {
MOZ_MTLOG(ML_ERROR, "Failed trying to serialize NrIceStunAddr, "
"input buffer length (" << buffer_size <<
") does not match required length ("
<< sizeof(nr_local_addr) << ")");
MOZ_ASSERT(false, "Failed to serialize NrIceStunAddr, bad buffer size");
return NS_ERROR_FAILURE;
}
nr_local_addr* toAddr = (nr_local_addr*)buffer;
if (nr_local_addr_copy(toAddr, localAddr_)) {
MOZ_MTLOG(ML_ERROR, "Failed trying to serialize NrIceStunAddr, "
"could not copy nr_local_addr.");
MOZ_ASSERT(false, "Failed to serialize NrIceStunAddr, nr_local_addr_copy failed");
return NS_ERROR_FAILURE;
}
// don't serialize what will be a bad addr when we deserialize
toAddr->addr.addr = nullptr;
return NS_OK;
}
nsresult
NrIceStunAddr::Deserialize(const char* buffer, size_t buffer_size)
{
if (buffer_size != sizeof(nr_local_addr)) {
MOZ_MTLOG(ML_ERROR, "Failed trying to deserialize NrIceStunAddr, "
"input buffer length (" << buffer_size <<
") does not match required length ("
<< sizeof(nr_local_addr) << ")");
MOZ_ASSERT(false, "Failed to deserialize NrIceStunAddr, bad buffer size");
return NS_ERROR_FAILURE;
}
nr_local_addr* from_addr =
const_cast<nr_local_addr*>((const nr_local_addr*)buffer);
// At this point, from_addr->addr.addr is invalid (null), but will
// be fixed by nr_local_addr_copy.
if (nr_local_addr_copy(localAddr_, from_addr)) {
MOZ_MTLOG(ML_ERROR, "Failed trying to deserialize NrIceStunAddr, "
"could not copy nr_local_addr.");
MOZ_ASSERT(false, "Failed to deserialize NrIceStunAddr, nr_local_addr_copy failed");
return NS_ERROR_FAILURE;
}
return NS_OK;
}
} // namespace mozilla

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

@ -0,0 +1,37 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nricestunaddr_h__
#define nricestunaddr_h__
#include "nsError.h" // for nsresult
typedef struct nr_local_addr_ nr_local_addr;
namespace mozilla {
class NrIceStunAddr {
public:
NrIceStunAddr(); // needed for IPC deserialization
explicit NrIceStunAddr(const nr_local_addr* addr);
NrIceStunAddr(const NrIceStunAddr& rhs);
~NrIceStunAddr();
const nr_local_addr& localAddr() const { return *localAddr_; }
// serialization/deserialization helper functions for use
// in media/mtransport/ipc/NrIceStunAddrMessagUtils.h
size_t SerializationBufferSize() const;
nsresult Serialize(char* buffer, size_t buffer_size) const;
nsresult Deserialize(const char* buffer, size_t buffer_size);
private:
nr_local_addr* localAddr_;
};
} // namespace mozilla
#endif // nricestunaddr_h__

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

@ -23,6 +23,7 @@
#include "mozilla/dom/network/TCPServerSocketChild.h"
#include "mozilla/dom/network/UDPSocketChild.h"
#include "mozilla/net/AltDataOutputStreamChild.h"
#include "mozilla/net/StunAddrsRequestChild.h"
#ifdef NECKO_PROTOCOL_rtsp
#include "mozilla/net/RtspControllerChild.h"
@ -89,6 +90,23 @@ NeckoChild::DeallocPHttpChannelChild(PHttpChannelChild* channel)
return true;
}
PStunAddrsRequestChild*
NeckoChild::AllocPStunAddrsRequestChild()
{
// We don't allocate here: instead we always use IPDL constructor that takes
// an existing object
NS_NOTREACHED("AllocPStunAddrsRequestChild should not be called on child");
return nullptr;
}
bool
NeckoChild::DeallocPStunAddrsRequestChild(PStunAddrsRequestChild* aActor)
{
StunAddrsRequestChild* p = static_cast<StunAddrsRequestChild*>(aActor);
p->ReleaseIPDLReference();
return true;
}
PAltDataOutputStreamChild*
NeckoChild::AllocPAltDataOutputStreamChild(
const nsCString& type,

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

@ -30,6 +30,10 @@ protected:
const HttpChannelCreationArgs& aOpenArgs) override;
virtual bool DeallocPHttpChannelChild(PHttpChannelChild*) override;
virtual PStunAddrsRequestChild* AllocPStunAddrsRequestChild() override;
virtual bool
DeallocPStunAddrsRequestChild(PStunAddrsRequestChild* aActor) override;
virtual PAltDataOutputStreamChild* AllocPAltDataOutputStreamChild(const nsCString& type, PHttpChannelChild* channel) override;
virtual bool DeallocPAltDataOutputStreamChild(PAltDataOutputStreamChild* aActor) override;

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

@ -25,6 +25,7 @@
#include "mozilla/net/DNSRequestParent.h"
#include "mozilla/net/ChannelDiverterParent.h"
#include "mozilla/net/IPCTransportProvider.h"
#include "mozilla/net/StunAddrsRequestParent.h"
#include "mozilla/dom/ChromeUtils.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/TabContext.h"
@ -326,6 +327,22 @@ NeckoParent::RecvPHttpChannelConstructor(
return IPC_OK();
}
PStunAddrsRequestParent*
NeckoParent::AllocPStunAddrsRequestParent()
{
StunAddrsRequestParent* p = new StunAddrsRequestParent();
p->AddRef();
return p;
}
bool
NeckoParent::DeallocPStunAddrsRequestParent(PStunAddrsRequestParent* aActor)
{
StunAddrsRequestParent* p = static_cast<StunAddrsRequestParent*>(aActor);
p->Release();
return true;
}
PAltDataOutputStreamParent*
NeckoParent::AllocPAltDataOutputStreamParent(
const nsCString& type,

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

@ -105,6 +105,10 @@ protected:
const HttpChannelCreationArgs& aOpenArgs) override;
virtual bool DeallocPHttpChannelParent(PHttpChannelParent*) override;
virtual PStunAddrsRequestParent* AllocPStunAddrsRequestParent() override;
virtual bool
DeallocPStunAddrsRequestParent(PStunAddrsRequestParent* aActor) override;
virtual PAltDataOutputStreamParent* AllocPAltDataOutputStreamParent(
const nsCString& type, PHttpChannelParent* channel) override;
virtual bool DeallocPAltDataOutputStreamParent(

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

@ -24,6 +24,7 @@ include protocol PDataChannel;
include protocol PTransportProvider;
include protocol PChildToParentStream; //FIXME: bug #792908
include protocol PParentToChildStream; //FIXME: bug #792908
include protocol PStunAddrsRequest;
include protocol PRtspController;
include protocol PRtspChannel;
@ -59,6 +60,7 @@ nested(upto inside_cpow) sync protocol PNecko
manages PChannelDiverter;
manages PTransportProvider;
manages PAltDataOutputStream;
manages PStunAddrsRequest;
parent:
async __delete__();
@ -118,6 +120,8 @@ parent:
async PAltDataOutputStream(nsCString type, PHttpChannel channel);
async PStunAddrsRequest();
/**
* Throttling of channels
*/