зеркало из https://github.com/mozilla/gecko-dev.git
Bug 745283 - Part 3: Support send input stream and multicast operation via PUDPSocket.ipdl. r=jduell, r=mt
This commit is contained in:
Родитель
d101e58326
Коммит
6fb3b1ce8f
|
@ -6,6 +6,7 @@
|
|||
#include "nsINetAddr.idl"
|
||||
|
||||
interface nsIUDPSocketInternal;
|
||||
interface nsIInputStream;
|
||||
|
||||
%{ C++
|
||||
namespace mozilla {
|
||||
|
@ -17,7 +18,7 @@ union NetAddr;
|
|||
native NetAddr(mozilla::net::NetAddr);
|
||||
[ptr] native NetAddrPtr(mozilla::net::NetAddr);
|
||||
|
||||
[scriptable, uuid(B47E5A0F-D384-48EF-8885-4259793D9CF0)]
|
||||
[scriptable, uuid(5bb7de5a-8766-4c13-b9ed-14e63168dabf)]
|
||||
interface nsIUDPSocketChild : nsISupports
|
||||
{
|
||||
readonly attribute unsigned short localPort;
|
||||
|
@ -25,7 +26,8 @@ interface nsIUDPSocketChild : nsISupports
|
|||
attribute AUTF8String filterName;
|
||||
|
||||
// Tell the chrome process to bind the UDP socket to a given local host and port
|
||||
void bind(in nsIUDPSocketInternal socket, in AUTF8String host, in unsigned short port);
|
||||
void bind(in nsIUDPSocketInternal socket, in AUTF8String host, in unsigned short port,
|
||||
in bool addressReuse, in bool loopback);
|
||||
|
||||
// Tell the chrome process to perform equivalent operations to all following methods
|
||||
void send(in AUTF8String host, in unsigned short port,
|
||||
|
@ -38,21 +40,28 @@ interface nsIUDPSocketChild : nsISupports
|
|||
[noscript] void sendWithAddress([const] in NetAddrPtr addr,
|
||||
[const, array, size_is(byteLength)] in uint8_t bytes,
|
||||
in unsigned long byteLength);
|
||||
// Send input stream. This must be a buffered stream implementation.
|
||||
void sendBinaryStream(in AUTF8String host, in unsigned short port, in nsIInputStream stream);
|
||||
|
||||
void close();
|
||||
void joinMulticast(in AUTF8String multicastAddress, in AUTF8String iface);
|
||||
void leaveMulticast(in AUTF8String multicastAddress, in AUTF8String iface);
|
||||
};
|
||||
|
||||
/*
|
||||
* Internal interface for callback from chrome process
|
||||
*/
|
||||
[scriptable, uuid(1E27E9B3-C1C8-4B05-A415-1A2C1A641C60)]
|
||||
[scriptable, uuid(44cd9ad5-d574-4169-baf9-e1af0648a143)]
|
||||
interface nsIUDPSocketInternal : nsISupports
|
||||
{
|
||||
void callListenerError(in AUTF8String type, in AUTF8String message, in AUTF8String filename,
|
||||
in uint32_t lineNumber, in uint32_t columnNumber);
|
||||
void callListenerReceivedData(in AUTF8String type, in AUTF8String host, in unsigned short port,
|
||||
[array, size_is(dataLength)] in uint8_t data,
|
||||
// callback while socket is opened. localPort and localAddress is ready until this time.
|
||||
void callListenerOpened();
|
||||
// callback while socket is closed.
|
||||
void callListenerClosed();
|
||||
// callback while incoming packet is received.
|
||||
void callListenerReceivedData(in AUTF8String host, in unsigned short port,
|
||||
[const, array, size_is(dataLength)] in uint8_t data,
|
||||
in unsigned long dataLength);
|
||||
void callListenerVoid(in AUTF8String type);
|
||||
void callListenerSent(in AUTF8String type, in nsresult status);
|
||||
void updateReadyState(in AUTF8String readyState);
|
||||
// callback while any error happened.
|
||||
void callListenerError(in AUTF8String message, in AUTF8String filename, in uint32_t lineNumber);
|
||||
};
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PNecko;
|
||||
include protocol PBlob;
|
||||
include InputStreamParams;
|
||||
|
||||
include "mozilla/net/NeckoMessageUtils.h";
|
||||
include "mozilla/net/DNS.h";
|
||||
|
@ -14,34 +16,19 @@ include "prio.h";
|
|||
using mozilla::net::NetAddr from "mozilla/net/DNS.h";
|
||||
using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
|
||||
|
||||
struct UDPError {
|
||||
nsCString message;
|
||||
nsCString filename;
|
||||
uint32_t lineNumber;
|
||||
uint32_t columnNumber;
|
||||
};
|
||||
|
||||
struct UDPMessage {
|
||||
nsCString fromAddr;
|
||||
uint16_t port;
|
||||
uint8_t[] data;
|
||||
};
|
||||
|
||||
struct UDPAddressInfo {
|
||||
nsCString local;
|
||||
nsCString addr;
|
||||
uint16_t port;
|
||||
};
|
||||
|
||||
struct UDPSendResult {
|
||||
nsresult value;
|
||||
union UDPSocketAddr {
|
||||
UDPAddressInfo;
|
||||
NetAddr;
|
||||
};
|
||||
|
||||
union UDPCallbackData {
|
||||
void_t;
|
||||
UDPMessage;
|
||||
UDPAddressInfo;
|
||||
UDPSendResult;
|
||||
UDPError;
|
||||
union UDPData {
|
||||
uint8_t[];
|
||||
InputStreamParams;
|
||||
};
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -53,13 +40,22 @@ protocol PUDPSocket
|
|||
manager PNecko;
|
||||
|
||||
parent:
|
||||
Data(uint8_t[] data, nsCString remoteAddress, uint16_t port);
|
||||
DataWithAddress(uint8_t[] data, NetAddr addr);
|
||||
Bind(UDPAddressInfo addressInfo, bool addressReuse, bool loopback);
|
||||
|
||||
OutgoingData(UDPData data, UDPSocketAddr addr);
|
||||
|
||||
JoinMulticast(nsCString multicastAddress, nsCString iface);
|
||||
LeaveMulticast(nsCString multicastAddress, nsCString iface);
|
||||
|
||||
Close();
|
||||
|
||||
RequestDelete();
|
||||
|
||||
child:
|
||||
Callback(nsCString type, UDPCallbackData data, nsCString aState);
|
||||
CallbackOpened(UDPAddressInfo addressInfo);
|
||||
CallbackClosed();
|
||||
CallbackReceivedData(UDPAddressInfo addressInfo, uint8_t[] data);
|
||||
CallbackError(nsCString message, nsCString filename, uint32_t lineNumber);
|
||||
__delete__();
|
||||
};
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "UDPSocketChild.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
#include "mozilla/net/NeckoChild.h"
|
||||
|
||||
using mozilla::net::gNeckoChild;
|
||||
|
@ -59,17 +61,20 @@ UDPSocketChild::~UDPSocketChild()
|
|||
// nsIUDPSocketChild Methods
|
||||
|
||||
NS_IMETHODIMP
|
||||
UDPSocketChild::Bind(nsIUDPSocketInternal *aSocket,
|
||||
UDPSocketChild::Bind(nsIUDPSocketInternal* aSocket,
|
||||
const nsACString& aHost,
|
||||
uint16_t aPort)
|
||||
uint16_t aPort,
|
||||
bool aAddressReuse,
|
||||
bool aLoopback)
|
||||
{
|
||||
NS_ENSURE_ARG(aSocket);
|
||||
|
||||
mSocket = aSocket;
|
||||
AddIPDLReference();
|
||||
|
||||
gNeckoChild->SendPUDPSocketConstructor(this, nsCString(aHost), aPort, mFilterName);
|
||||
gNeckoChild->SendPUDPSocketConstructor(this, mFilterName);
|
||||
|
||||
SendBind(UDPAddressInfo(nsCString(aHost), aPort), aAddressReuse, aLoopback);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -83,26 +88,18 @@ UDPSocketChild::Close()
|
|||
NS_IMETHODIMP
|
||||
UDPSocketChild::Send(const nsACString& aHost,
|
||||
uint16_t aPort,
|
||||
const uint8_t *aData,
|
||||
const uint8_t* aData,
|
||||
uint32_t aByteLength)
|
||||
{
|
||||
NS_ENSURE_ARG(aData);
|
||||
|
||||
FallibleTArray<uint8_t> fallibleArray;
|
||||
if (!fallibleArray.InsertElementsAt(0, aData, aByteLength)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
InfallibleTArray<uint8_t> array;
|
||||
array.SwapElements(fallibleArray);
|
||||
SendData(array, nsCString(aHost), aPort);
|
||||
|
||||
return NS_OK;
|
||||
return SendDataInternal(UDPSocketAddr(UDPAddressInfo(nsCString(aHost), aPort)),
|
||||
aData, aByteLength);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UDPSocketChild::SendWithAddr(nsINetAddr *aAddr,
|
||||
const uint8_t *aData,
|
||||
UDPSocketChild::SendWithAddr(nsINetAddr* aAddr,
|
||||
const uint8_t* aData,
|
||||
uint32_t aByteLength)
|
||||
{
|
||||
NS_ENSURE_ARG(aAddr);
|
||||
|
@ -111,17 +108,27 @@ UDPSocketChild::SendWithAddr(nsINetAddr *aAddr,
|
|||
NetAddr addr;
|
||||
aAddr->GetNetAddr(&addr);
|
||||
|
||||
return SendWithAddress(&addr, aData, aByteLength);
|
||||
return SendDataInternal(UDPSocketAddr(addr), aData, aByteLength);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UDPSocketChild::SendWithAddress(const NetAddr *aAddr,
|
||||
const uint8_t *aData,
|
||||
UDPSocketChild::SendWithAddress(const NetAddr* aAddr,
|
||||
const uint8_t* aData,
|
||||
uint32_t aByteLength)
|
||||
{
|
||||
NS_ENSURE_ARG(aAddr);
|
||||
NS_ENSURE_ARG(aData);
|
||||
|
||||
return SendDataInternal(UDPSocketAddr(*aAddr), aData, aByteLength);
|
||||
}
|
||||
|
||||
nsresult
|
||||
UDPSocketChild::SendDataInternal(const UDPSocketAddr& aAddr,
|
||||
const uint8_t* aData,
|
||||
const uint32_t aByteLength)
|
||||
{
|
||||
NS_ENSURE_ARG(aData);
|
||||
|
||||
FallibleTArray<uint8_t> fallibleArray;
|
||||
if (!fallibleArray.InsertElementsAt(0, aData, aByteLength)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -129,13 +136,48 @@ UDPSocketChild::SendWithAddress(const NetAddr *aAddr,
|
|||
|
||||
InfallibleTArray<uint8_t> array;
|
||||
array.SwapElements(fallibleArray);
|
||||
SendDataWithAddress(array, *aAddr);
|
||||
|
||||
SendOutgoingData(array, aAddr);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UDPSocketChild::GetLocalPort(uint16_t *aLocalPort)
|
||||
UDPSocketChild::SendBinaryStream(const nsACString& aHost,
|
||||
uint16_t aPort,
|
||||
nsIInputStream* aStream)
|
||||
{
|
||||
NS_ENSURE_ARG(aStream);
|
||||
|
||||
OptionalInputStreamParams stream;
|
||||
nsTArray<mozilla::ipc::FileDescriptor> fds;
|
||||
SerializeInputStream(aStream, stream, fds);
|
||||
|
||||
MOZ_ASSERT(fds.IsEmpty());
|
||||
|
||||
SendOutgoingData(UDPData(stream), UDPSocketAddr(UDPAddressInfo(nsCString(aHost), aPort)));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UDPSocketChild::JoinMulticast(const nsACString& aMulticastAddress,
|
||||
const nsACString& aInterface)
|
||||
{
|
||||
SendJoinMulticast(nsCString(aMulticastAddress), nsCString(aInterface));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UDPSocketChild::LeaveMulticast(const nsACString& aMulticastAddress,
|
||||
const nsACString& aInterface)
|
||||
{
|
||||
SendLeaveMulticast(nsCString(aMulticastAddress), nsCString(aInterface));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UDPSocketChild::GetLocalPort(uint16_t* aLocalPort)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aLocalPort);
|
||||
|
||||
|
@ -144,14 +186,14 @@ UDPSocketChild::GetLocalPort(uint16_t *aLocalPort)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UDPSocketChild::GetLocalAddress(nsACString &aLocalAddress)
|
||||
UDPSocketChild::GetLocalAddress(nsACString& aLocalAddress)
|
||||
{
|
||||
aLocalAddress = mLocalAddress;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UDPSocketChild::SetFilterName(const nsACString &aFilterName)
|
||||
UDPSocketChild::SetFilterName(const nsACString& aFilterName)
|
||||
{
|
||||
if (!mFilterName.IsEmpty()) {
|
||||
// filter name can only be set once.
|
||||
|
@ -162,7 +204,7 @@ UDPSocketChild::SetFilterName(const nsACString &aFilterName)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UDPSocketChild::GetFilterName(nsACString &aFilterName)
|
||||
UDPSocketChild::GetFilterName(nsACString& aFilterName)
|
||||
{
|
||||
aFilterName = mFilterName;
|
||||
return NS_OK;
|
||||
|
@ -170,39 +212,44 @@ UDPSocketChild::GetFilterName(nsACString &aFilterName)
|
|||
|
||||
// PUDPSocketChild Methods
|
||||
bool
|
||||
UDPSocketChild::RecvCallback(const nsCString &aType,
|
||||
const UDPCallbackData &aData,
|
||||
const nsCString &aState)
|
||||
UDPSocketChild::RecvCallbackOpened(const UDPAddressInfo& aAddressInfo)
|
||||
{
|
||||
if (NS_FAILED(mSocket->UpdateReadyState(aState)))
|
||||
NS_ERROR("Shouldn't fail!");
|
||||
mLocalAddress = aAddressInfo.addr();
|
||||
mLocalPort = aAddressInfo.port();
|
||||
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
if (aData.type() == UDPCallbackData::Tvoid_t) {
|
||||
rv = mSocket->CallListenerVoid(aType);
|
||||
} else if (aData.type() == UDPCallbackData::TUDPError) {
|
||||
const UDPError& err(aData.get_UDPError());
|
||||
rv = mSocket->CallListenerError(aType, err.message(), err.filename(),
|
||||
err.lineNumber(), err.columnNumber());
|
||||
} else if (aData.type() == UDPCallbackData::TUDPMessage) {
|
||||
const UDPMessage& message(aData.get_UDPMessage());
|
||||
InfallibleTArray<uint8_t> data(message.data());
|
||||
rv = mSocket->CallListenerReceivedData(aType, message.fromAddr(), message.port(),
|
||||
data.Elements(), data.Length());
|
||||
} else if (aData.type() == UDPCallbackData::TUDPAddressInfo) {
|
||||
//update local address and port.
|
||||
const UDPAddressInfo& addressInfo(aData.get_UDPAddressInfo());
|
||||
mLocalAddress = addressInfo.local();
|
||||
mLocalPort = addressInfo.port();
|
||||
rv = mSocket->CallListenerVoid(aType);
|
||||
} else if (aData.type() == UDPCallbackData::TUDPSendResult) {
|
||||
const UDPSendResult& returnValue(aData.get_UDPSendResult());
|
||||
rv = mSocket->CallListenerSent(aType, returnValue.value());
|
||||
} else {
|
||||
MOZ_ASSERT(false, "Invalid callback type!");
|
||||
}
|
||||
nsresult rv = mSocket->CallListenerOpened();
|
||||
mozilla::unused << NS_WARN_IF(NS_FAILED(rv));
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
UDPSocketChild::RecvCallbackClosed()
|
||||
{
|
||||
nsresult rv = mSocket->CallListenerClosed();
|
||||
mozilla::unused << NS_WARN_IF(NS_FAILED(rv));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
UDPSocketChild::RecvCallbackReceivedData(const UDPAddressInfo& aAddressInfo,
|
||||
const InfallibleTArray<uint8_t>& aData)
|
||||
{
|
||||
nsresult rv = mSocket->CallListenerReceivedData(aAddressInfo.addr(), aAddressInfo.port(),
|
||||
aData.Elements(), aData.Length());
|
||||
mozilla::unused << NS_WARN_IF(NS_FAILED(rv));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
UDPSocketChild::RecvCallbackError(const nsCString& aMessage,
|
||||
const nsCString& aFilename,
|
||||
const uint32_t& aLineNumber)
|
||||
{
|
||||
nsresult rv = mSocket->CallListenerError(aMessage, aFilename, aLineNumber);
|
||||
mozilla::unused << NS_WARN_IF(NS_FAILED(rv));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -40,10 +40,19 @@ public:
|
|||
UDPSocketChild();
|
||||
virtual ~UDPSocketChild();
|
||||
|
||||
virtual bool RecvCallback(const nsCString& aType,
|
||||
const UDPCallbackData& aData,
|
||||
const nsCString& aState) MOZ_OVERRIDE;
|
||||
virtual bool RecvCallbackOpened(const UDPAddressInfo& aAddressInfo) MOZ_OVERRIDE;
|
||||
virtual bool RecvCallbackClosed() MOZ_OVERRIDE;
|
||||
virtual bool RecvCallbackReceivedData(const UDPAddressInfo& aAddressInfo,
|
||||
const InfallibleTArray<uint8_t>& aData) MOZ_OVERRIDE;
|
||||
virtual bool RecvCallbackError(const nsCString& aMessage,
|
||||
const nsCString& aFilename,
|
||||
const uint32_t& aLineNumber) MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
nsresult SendDataInternal(const UDPSocketAddr& aAddr,
|
||||
const uint8_t* aData,
|
||||
const uint32_t aByteLength);
|
||||
|
||||
uint16_t mLocalPort;
|
||||
nsCString mLocalAddress;
|
||||
nsCString mFilterName;
|
||||
|
|
|
@ -9,181 +9,279 @@
|
|||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsIUDPSocket.h"
|
||||
#include "nsINetAddr.h"
|
||||
#include "mozilla/AppProcessChecker.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
#include "mozilla/net/DNS.h"
|
||||
#include "mozilla/net/NeckoCommon.h"
|
||||
#include "mozilla/net/PNeckoParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
static void
|
||||
FireInternalError(mozilla::net::PUDPSocketParent *aActor, uint32_t aLineNo)
|
||||
{
|
||||
mozilla::unused <<
|
||||
aActor->SendCallback(NS_LITERAL_CSTRING("onerror"),
|
||||
UDPError(NS_LITERAL_CSTRING("Internal error"),
|
||||
NS_LITERAL_CSTRING(__FILE__), aLineNo, 0),
|
||||
NS_LITERAL_CSTRING("connecting"));
|
||||
}
|
||||
|
||||
static nsresult
|
||||
ConvertNetAddrToString(mozilla::net::NetAddr &netAddr, nsACString *address, uint16_t *port)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(address);
|
||||
NS_ENSURE_ARG_POINTER(port);
|
||||
|
||||
*port = 0;
|
||||
uint32_t bufSize = 0;
|
||||
|
||||
switch(netAddr.raw.family) {
|
||||
case AF_INET:
|
||||
*port = PR_ntohs(netAddr.inet.port);
|
||||
bufSize = mozilla::net::kIPv4CStrBufSize;
|
||||
break;
|
||||
case AF_INET6:
|
||||
*port = PR_ntohs(netAddr.inet6.port);
|
||||
bufSize = mozilla::net::kIPv6CStrBufSize;
|
||||
break;
|
||||
default:
|
||||
//impossible
|
||||
MOZ_ASSERT(false, "Unexpected address family");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
address->SetCapacity(bufSize);
|
||||
NetAddrToString(&netAddr, address->BeginWriting(), bufSize);
|
||||
address->SetLength(strlen(address->BeginReading()));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(UDPSocketParent, nsIUDPSocketListener)
|
||||
|
||||
UDPSocketParent::~UDPSocketParent()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
UDPSocketParent::Init(const nsACString& aFilter)
|
||||
{
|
||||
if (!aFilter.IsEmpty()) {
|
||||
nsAutoCString contractId(NS_NETWORK_UDP_SOCKET_FILTER_HANDLER_PREFIX);
|
||||
contractId.Append(aFilter);
|
||||
nsCOMPtr<nsIUDPSocketFilterHandler> filterHandler =
|
||||
do_GetService(contractId.get());
|
||||
if (filterHandler) {
|
||||
nsresult rv = filterHandler->NewFilter(getter_AddRefs(mFilter));
|
||||
if (NS_FAILED(rv)) {
|
||||
printf_stderr("Cannot create filter that content specified. "
|
||||
"filter name: %s, error code: %d.", aFilter.BeginReading(), rv);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
printf_stderr("Content doesn't have a valid filter. "
|
||||
"filter name: %s.", aFilter.BeginReading());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// PUDPSocketParent methods
|
||||
|
||||
bool
|
||||
UDPSocketParent::Init(const nsCString &aHost, const uint16_t aPort)
|
||||
UDPSocketParent::RecvBind(const UDPAddressInfo& aAddressInfo,
|
||||
const bool& aAddressReuse, const bool& aLoopback)
|
||||
{
|
||||
nsresult rv;
|
||||
NS_ASSERTION(mFilter, "No packet filter");
|
||||
// We don't have browser actors in xpcshell, and hence can't run automated
|
||||
// tests without this loophole.
|
||||
if (net::UsingNeckoIPCSecurity() && !mFilter &&
|
||||
!AssertAppProcessPermission(Manager()->Manager(), "udp-socket")) {
|
||||
FireInternalError(__LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIUDPSocket> sock =
|
||||
do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
FireInternalError(this, __LINE__);
|
||||
if (NS_FAILED(BindInternal(aAddressInfo.addr(), aAddressInfo.port(), aAddressReuse, aLoopback))) {
|
||||
FireInternalError(__LINE__);
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsINetAddr> localAddr;
|
||||
mSocket->GetLocalAddr(getter_AddRefs(localAddr));
|
||||
|
||||
nsCString addr;
|
||||
if (NS_FAILED(localAddr->GetAddress(addr))) {
|
||||
FireInternalError(__LINE__);
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16_t port;
|
||||
if (NS_FAILED(localAddr->GetPort(&port))) {
|
||||
FireInternalError(__LINE__);
|
||||
return true;
|
||||
}
|
||||
|
||||
mozilla::unused << SendCallbackOpened(UDPAddressInfo(addr, port));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
UDPSocketParent::BindInternal(const nsCString& aHost, const uint16_t& aPort,
|
||||
const bool& aAddressReuse, const bool& aLoopback)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIUDPSocket> sock =
|
||||
do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv);
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (aHost.IsEmpty()) {
|
||||
rv = sock->Init(aPort, false);
|
||||
rv = sock->Init(aPort, false, aAddressReuse, /* optional_argc = */ 1);
|
||||
} else {
|
||||
PRNetAddr prAddr;
|
||||
PR_InitializeNetAddr(PR_IpAddrAny, aPort, &prAddr);
|
||||
PRStatus status = PR_StringToNetAddr(aHost.BeginReading(), &prAddr);
|
||||
if (status != PR_SUCCESS) {
|
||||
FireInternalError(this, __LINE__);
|
||||
return true;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mozilla::net::NetAddr addr;
|
||||
PRNetAddrToNetAddr(&prAddr, &addr);
|
||||
rv = sock->InitWithAddress(&addr);
|
||||
rv = sock->InitWithAddress(&addr, aAddressReuse, /* optional_argc = */ 1);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
FireInternalError(this, __LINE__);
|
||||
return true;
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = sock->SetMulticastLoopback(aLoopback);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// register listener
|
||||
rv = sock->AsyncListen(this);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mSocket = sock;
|
||||
|
||||
net::NetAddr localAddr;
|
||||
mSocket->GetAddress(&localAddr);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
uint16_t port;
|
||||
nsCString addr;
|
||||
rv = ConvertNetAddrToString(localAddr, &addr, &port);
|
||||
bool
|
||||
UDPSocketParent::RecvOutgoingData(const UDPData& aData,
|
||||
const UDPSocketAddr& aAddr)
|
||||
{
|
||||
MOZ_ASSERT(mSocket);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
FireInternalError(this, __LINE__);
|
||||
return true;
|
||||
nsresult rv;
|
||||
if (mFilter) {
|
||||
// TODO, Bug 933102, filter packets that are sent with hostname.
|
||||
// Until then we simply throw away packets that are sent to a hostname.
|
||||
if (aAddr.type() != UDPSocketAddr::TNetAddr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO, Packet filter doesn't support input stream yet.
|
||||
if (aData.type() != UDPData::TArrayOfuint8_t) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool allowed;
|
||||
const InfallibleTArray<uint8_t>& data(aData.get_ArrayOfuint8_t());
|
||||
rv = mFilter->FilterPacket(&aAddr.get_NetAddr(), data.Elements(),
|
||||
data.Length(), nsIUDPSocketFilter::SF_OUTGOING,
|
||||
&allowed);
|
||||
|
||||
// Sending unallowed data, kill content.
|
||||
if (NS_WARN_IF(NS_FAILED(rv)) || !allowed) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// register listener
|
||||
mSocket->AsyncListen(this);
|
||||
mozilla::unused <<
|
||||
PUDPSocketParent::SendCallback(NS_LITERAL_CSTRING("onopen"),
|
||||
UDPAddressInfo(addr, port),
|
||||
NS_LITERAL_CSTRING("connected"));
|
||||
switch(aData.type()) {
|
||||
case UDPData::TArrayOfuint8_t:
|
||||
Send(aData.get_ArrayOfuint8_t(), aAddr);
|
||||
break;
|
||||
case UDPData::TInputStreamParams:
|
||||
Send(aData.get_InputStreamParams(), aAddr);
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT(false, "Invalid data type!");
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
UDPSocketParent::RecvData(const InfallibleTArray<uint8_t> &aData,
|
||||
const nsCString& aRemoteAddress,
|
||||
const uint16_t& aPort)
|
||||
void
|
||||
UDPSocketParent::Send(const InfallibleTArray<uint8_t>& aData,
|
||||
const UDPSocketAddr& aAddr)
|
||||
{
|
||||
NS_ENSURE_TRUE(mSocket, true);
|
||||
NS_ASSERTION(mFilter, "No packet filter");
|
||||
// TODO, Bug 933102, filter packets that are sent with hostname.
|
||||
// Until then we simply throw away packets that are sent to a hostname.
|
||||
return true;
|
||||
|
||||
#if 0
|
||||
// Enable this once we have filtering working with hostname delivery.
|
||||
uint32_t count;
|
||||
nsresult rv = mSocket->Send(aRemoteAddress,
|
||||
aPort, aData.Elements(),
|
||||
aData.Length(), &count);
|
||||
mozilla::unused <<
|
||||
PUDPSocketParent::SendCallback(NS_LITERAL_CSTRING("onsent"),
|
||||
UDPSendResult(rv),
|
||||
NS_LITERAL_CSTRING("connected"));
|
||||
NS_ENSURE_SUCCESS(rv, true);
|
||||
NS_ENSURE_TRUE(count > 0, true);
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
UDPSocketParent::RecvDataWithAddress(const InfallibleTArray<uint8_t>& aData,
|
||||
const mozilla::net::NetAddr& aAddr)
|
||||
{
|
||||
NS_ENSURE_TRUE(mSocket, true);
|
||||
NS_ASSERTION(mFilter, "No packet filter");
|
||||
|
||||
uint32_t count;
|
||||
nsresult rv;
|
||||
bool allowed;
|
||||
rv = mFilter->FilterPacket(&aAddr, aData.Elements(),
|
||||
aData.Length(), nsIUDPSocketFilter::SF_OUTGOING,
|
||||
&allowed);
|
||||
// Sending unallowed data, kill content.
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
NS_ENSURE_TRUE(allowed, false);
|
||||
uint32_t count;
|
||||
switch(aAddr.type()) {
|
||||
case UDPSocketAddr::TUDPAddressInfo: {
|
||||
const UDPAddressInfo& addrInfo(aAddr.get_UDPAddressInfo());
|
||||
rv = mSocket->Send(addrInfo.addr(), addrInfo.port(),
|
||||
aData.Elements(), aData.Length(), &count);
|
||||
break;
|
||||
}
|
||||
case UDPSocketAddr::TNetAddr: {
|
||||
const NetAddr& addr(aAddr.get_NetAddr());
|
||||
rv = mSocket->SendWithAddress(&addr, aData.Elements(),
|
||||
aData.Length(), &count);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MOZ_ASSERT(false, "Invalid address type!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv)) || count == 0) {
|
||||
FireInternalError(__LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UDPSocketParent::Send(const InputStreamParams& aStream,
|
||||
const UDPSocketAddr& aAddr)
|
||||
{
|
||||
nsTArray<mozilla::ipc::FileDescriptor> fds;
|
||||
nsCOMPtr<nsIInputStream> stream = DeserializeInputStream(aStream, fds);
|
||||
|
||||
if (NS_WARN_IF(!stream)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
switch(aAddr.type()) {
|
||||
case UDPSocketAddr::TUDPAddressInfo: {
|
||||
const UDPAddressInfo& addrInfo(aAddr.get_UDPAddressInfo());
|
||||
rv = mSocket->SendBinaryStream(addrInfo.addr(), addrInfo.port(), stream);
|
||||
break;
|
||||
}
|
||||
case UDPSocketAddr::TNetAddr: {
|
||||
const NetAddr& addr(aAddr.get_NetAddr());
|
||||
rv = mSocket->SendBinaryStreamWithAddress(&addr, stream);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MOZ_ASSERT(false, "Invalid address type!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
FireInternalError(__LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
UDPSocketParent::RecvJoinMulticast(const nsCString& aMulticastAddress,
|
||||
const nsCString& aInterface)
|
||||
{
|
||||
nsresult rv = mSocket->JoinMulticast(aMulticastAddress, aInterface);
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
FireInternalError(__LINE__);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
UDPSocketParent::RecvLeaveMulticast(const nsCString& aMulticastAddress,
|
||||
const nsCString& aInterface)
|
||||
{
|
||||
nsresult rv = mSocket->LeaveMulticast(aMulticastAddress, aInterface);
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
FireInternalError(__LINE__);
|
||||
}
|
||||
|
||||
rv = mSocket->SendWithAddress(&aAddr, aData.Elements(),
|
||||
aData.Length(), &count);
|
||||
mozilla::unused <<
|
||||
PUDPSocketParent::SendCallback(NS_LITERAL_CSTRING("onsent"),
|
||||
UDPSendResult(rv),
|
||||
NS_LITERAL_CSTRING("connected"));
|
||||
NS_ENSURE_SUCCESS(rv, true);
|
||||
NS_ENSURE_TRUE(count > 0, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
UDPSocketParent::RecvClose()
|
||||
{
|
||||
NS_ENSURE_TRUE(mSocket, true);
|
||||
if (!mSocket) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult rv = mSocket->Close();
|
||||
mSocket = nullptr;
|
||||
NS_ENSURE_SUCCESS(rv, true);
|
||||
|
||||
mozilla::unused << NS_WARN_IF(NS_FAILED(rv));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -214,7 +312,6 @@ UDPSocketParent::OnPacketReceived(nsIUDPSocket* aSocket, nsIUDPMessage* aMessage
|
|||
if (!mIPCOpen) {
|
||||
return NS_OK;
|
||||
}
|
||||
NS_ASSERTION(mFilter, "No packet filter");
|
||||
|
||||
uint16_t port;
|
||||
nsCString ip;
|
||||
|
@ -229,30 +326,30 @@ UDPSocketParent::OnPacketReceived(nsIUDPSocket* aSocket, nsIUDPMessage* aMessage
|
|||
const char* buffer = data.get();
|
||||
uint32_t len = data.Length();
|
||||
|
||||
bool allowed;
|
||||
mozilla::net::NetAddr addr;
|
||||
fromAddr->GetNetAddr(&addr);
|
||||
nsresult rv = mFilter->FilterPacket(&addr,
|
||||
(const uint8_t*)buffer, len,
|
||||
nsIUDPSocketFilter::SF_INCOMING,
|
||||
&allowed);
|
||||
// Receiving unallowed data, drop.
|
||||
NS_ENSURE_SUCCESS(rv, NS_OK);
|
||||
NS_ENSURE_TRUE(allowed, NS_OK);
|
||||
if (mFilter) {
|
||||
bool allowed;
|
||||
mozilla::net::NetAddr addr;
|
||||
fromAddr->GetNetAddr(&addr);
|
||||
nsresult rv = mFilter->FilterPacket(&addr,
|
||||
(const uint8_t*)buffer, len,
|
||||
nsIUDPSocketFilter::SF_INCOMING,
|
||||
&allowed);
|
||||
// Receiving unallowed data, drop.
|
||||
if (NS_WARN_IF(NS_FAILED(rv)) || !allowed) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
FallibleTArray<uint8_t> fallibleArray;
|
||||
if (!fallibleArray.InsertElementsAt(0, buffer, len)) {
|
||||
FireInternalError(this, __LINE__);
|
||||
FireInternalError(__LINE__);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
InfallibleTArray<uint8_t> infallibleArray;
|
||||
infallibleArray.SwapElements(fallibleArray);
|
||||
|
||||
// compose callback
|
||||
mozilla::unused <<
|
||||
PUDPSocketParent::SendCallback(NS_LITERAL_CSTRING("ondata"),
|
||||
UDPMessage(ip, port, infallibleArray),
|
||||
NS_LITERAL_CSTRING("connected"));
|
||||
mozilla::unused << SendCallbackReceivedData(UDPAddressInfo(ip, port), infallibleArray);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -262,13 +359,21 @@ UDPSocketParent::OnStopListening(nsIUDPSocket* aSocket, nsresult aStatus)
|
|||
{
|
||||
// underlying socket is dead, send state update to child process
|
||||
if (mIPCOpen) {
|
||||
mozilla::unused <<
|
||||
PUDPSocketParent::SendCallback(NS_LITERAL_CSTRING("onclose"),
|
||||
mozilla::void_t(),
|
||||
NS_LITERAL_CSTRING("closed"));
|
||||
mozilla::unused << SendCallbackClosed();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
UDPSocketParent::FireInternalError(uint32_t aLineNo)
|
||||
{
|
||||
if (!mIPCOpen) {
|
||||
return;
|
||||
}
|
||||
|
||||
mozilla::unused << SendCallbackError(NS_LITERAL_CSTRING("Internal error"),
|
||||
NS_LITERAL_CSTRING(__FILE__), aLineNo);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -22,24 +22,34 @@ public:
|
|||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIUDPSOCKETLISTENER
|
||||
|
||||
explicit UDPSocketParent(nsIUDPSocketFilter* filter) :
|
||||
mIPCOpen(true),
|
||||
mFilter(filter) {}
|
||||
UDPSocketParent() :
|
||||
mIPCOpen(true) {}
|
||||
|
||||
bool Init(const nsCString& aHost, const uint16_t aPort);
|
||||
bool Init(const nsACString& aFilter);
|
||||
|
||||
virtual bool RecvBind(const UDPAddressInfo& aAddressInfo,
|
||||
const bool& aAddressReuse, const bool& aLoopback) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvOutgoingData(const UDPData& aData, const UDPSocketAddr& aAddr) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvClose() MOZ_OVERRIDE;
|
||||
virtual bool RecvData(const InfallibleTArray<uint8_t>& aData,
|
||||
const nsCString& aRemoteAddress,
|
||||
const uint16_t& aPort) MOZ_OVERRIDE;
|
||||
virtual bool RecvDataWithAddress( const InfallibleTArray<uint8_t>& data,
|
||||
const mozilla::net::NetAddr& addr);
|
||||
|
||||
virtual bool RecvRequestDelete() MOZ_OVERRIDE;
|
||||
virtual bool RecvJoinMulticast(const nsCString& aMulticastAddress,
|
||||
const nsCString& aInterface) MOZ_OVERRIDE;
|
||||
virtual bool RecvLeaveMulticast(const nsCString& aMulticastAddress,
|
||||
const nsCString& aInterface) MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
virtual ~UDPSocketParent();
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
|
||||
void Send(const InfallibleTArray<uint8_t>& aData, const UDPSocketAddr& aAddr);
|
||||
void Send(const InputStreamParams& aStream, const UDPSocketAddr& aAddr);
|
||||
nsresult BindInternal(const nsCString& aHost, const uint16_t& aPort,
|
||||
const bool& aAddressReuse, const bool& aLoopback);
|
||||
|
||||
void FireInternalError(uint32_t aLineNo);
|
||||
|
||||
bool mIPCOpen;
|
||||
nsCOMPtr<nsIUDPSocket> mSocket;
|
||||
|
|
|
@ -705,17 +705,13 @@ NrSocketIpc::NrSocketIpc(const nsCOMPtr<nsIEventTarget> &main_thread)
|
|||
|
||||
// IUDPSocketInternal interfaces
|
||||
// callback while error happened in UDP socket operation
|
||||
NS_IMETHODIMP NrSocketIpc::CallListenerError(const nsACString &type,
|
||||
const nsACString &message,
|
||||
NS_IMETHODIMP NrSocketIpc::CallListenerError(const nsACString &message,
|
||||
const nsACString &filename,
|
||||
uint32_t line_number,
|
||||
uint32_t column_number) {
|
||||
uint32_t line_number) {
|
||||
ASSERT_ON_THREAD(main_thread_);
|
||||
MOZ_ASSERT(type.EqualsLiteral("onerror"));
|
||||
|
||||
r_log(LOG_GENERIC, LOG_ERR, "UDP socket error:%s at %s:%d:%d",
|
||||
message.BeginReading(), filename.BeginReading(),
|
||||
line_number, column_number);
|
||||
r_log(LOG_GENERIC, LOG_ERR, "UDP socket error:%s at %s:%d",
|
||||
message.BeginReading(), filename.BeginReading(), line_number );
|
||||
|
||||
ReentrantMonitorAutoEnter mon(monitor_);
|
||||
err_ = true;
|
||||
|
@ -725,12 +721,11 @@ NS_IMETHODIMP NrSocketIpc::CallListenerError(const nsACString &type,
|
|||
}
|
||||
|
||||
// callback while receiving UDP packet
|
||||
NS_IMETHODIMP NrSocketIpc::CallListenerReceivedData(const nsACString &type,
|
||||
const nsACString &host,
|
||||
uint16_t port, uint8_t *data,
|
||||
NS_IMETHODIMP NrSocketIpc::CallListenerReceivedData(const nsACString &host,
|
||||
uint16_t port,
|
||||
const uint8_t *data,
|
||||
uint32_t data_length) {
|
||||
ASSERT_ON_THREAD(main_thread_);
|
||||
MOZ_ASSERT(type.EqualsLiteral("ondata"));
|
||||
|
||||
PRNetAddr addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
|
@ -763,89 +758,68 @@ NS_IMETHODIMP NrSocketIpc::CallListenerReceivedData(const nsACString &type,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// callback while UDP socket is opened or closed
|
||||
NS_IMETHODIMP NrSocketIpc::CallListenerVoid(const nsACString &type) {
|
||||
// callback while UDP socket is opened
|
||||
NS_IMETHODIMP NrSocketIpc::CallListenerOpened() {
|
||||
ASSERT_ON_THREAD(main_thread_);
|
||||
if (type.EqualsLiteral("onopen")) {
|
||||
ReentrantMonitorAutoEnter mon(monitor_);
|
||||
ReentrantMonitorAutoEnter mon(monitor_);
|
||||
|
||||
uint16_t port;
|
||||
if (NS_FAILED(socket_child_->GetLocalPort(&port))) {
|
||||
err_ = true;
|
||||
MOZ_ASSERT(false, "Failed to get local port");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoCString address;
|
||||
if(NS_FAILED(socket_child_->GetLocalAddress(address))) {
|
||||
err_ = true;
|
||||
MOZ_ASSERT(false, "Failed to get local address");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRNetAddr praddr;
|
||||
if (PR_SUCCESS != PR_InitializeNetAddr(PR_IpAddrAny, port, &praddr)) {
|
||||
err_ = true;
|
||||
MOZ_ASSERT(false, "Failed to set port in PRNetAddr");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (PR_SUCCESS != PR_StringToNetAddr(address.BeginReading(), &praddr)) {
|
||||
err_ = true;
|
||||
MOZ_ASSERT(false, "Failed to convert local host to PRNetAddr");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nr_transport_addr expected_addr;
|
||||
if(nr_transport_addr_copy(&expected_addr, &my_addr_)) {
|
||||
err_ = true;
|
||||
MOZ_ASSERT(false, "Failed to copy my_addr_");
|
||||
}
|
||||
|
||||
if (nr_praddr_to_transport_addr(&praddr, &my_addr_, IPPROTO_UDP, 1)) {
|
||||
err_ = true;
|
||||
MOZ_ASSERT(false, "Failed to copy local host to my_addr_");
|
||||
}
|
||||
|
||||
if (nr_transport_addr_cmp(&expected_addr, &my_addr_,
|
||||
NR_TRANSPORT_ADDR_CMP_MODE_ADDR)) {
|
||||
err_ = true;
|
||||
MOZ_ASSERT(false, "Address of opened socket is not expected");
|
||||
}
|
||||
|
||||
mon.NotifyAll();
|
||||
} else if (type.EqualsLiteral("onclose")) {
|
||||
// Already handled in UpdateReadyState, nothing to do here
|
||||
} else {
|
||||
MOZ_ASSERT(false, "Received unexpected event");
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// callback while UDP packet is sent
|
||||
NS_IMETHODIMP NrSocketIpc::CallListenerSent(const nsACString &type,
|
||||
nsresult result) {
|
||||
ASSERT_ON_THREAD(main_thread_);
|
||||
MOZ_ASSERT(type.EqualsLiteral("onsent"));
|
||||
|
||||
if (NS_FAILED(result)) {
|
||||
ReentrantMonitorAutoEnter mon(monitor_);
|
||||
uint16_t port;
|
||||
if (NS_FAILED(socket_child_->GetLocalPort(&port))) {
|
||||
err_ = true;
|
||||
MOZ_ASSERT(false, "Failed to get local port");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoCString address;
|
||||
if(NS_FAILED(socket_child_->GetLocalAddress(address))) {
|
||||
err_ = true;
|
||||
MOZ_ASSERT(false, "Failed to get local address");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRNetAddr praddr;
|
||||
if (PR_SUCCESS != PR_InitializeNetAddr(PR_IpAddrAny, port, &praddr)) {
|
||||
err_ = true;
|
||||
MOZ_ASSERT(false, "Failed to set port in PRNetAddr");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (PR_SUCCESS != PR_StringToNetAddr(address.BeginReading(), &praddr)) {
|
||||
err_ = true;
|
||||
MOZ_ASSERT(false, "Failed to convert local host to PRNetAddr");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nr_transport_addr expected_addr;
|
||||
if(nr_transport_addr_copy(&expected_addr, &my_addr_)) {
|
||||
err_ = true;
|
||||
MOZ_ASSERT(false, "Failed to copy my_addr_");
|
||||
}
|
||||
|
||||
if (nr_praddr_to_transport_addr(&praddr, &my_addr_, IPPROTO_UDP, 1)) {
|
||||
err_ = true;
|
||||
MOZ_ASSERT(false, "Failed to copy local host to my_addr_");
|
||||
}
|
||||
|
||||
if (nr_transport_addr_cmp(&expected_addr, &my_addr_,
|
||||
NR_TRANSPORT_ADDR_CMP_MODE_ADDR)) {
|
||||
err_ = true;
|
||||
MOZ_ASSERT(false, "Address of opened socket is not expected");
|
||||
}
|
||||
|
||||
mon.NotifyAll();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// callback for state update after every socket operation
|
||||
NS_IMETHODIMP NrSocketIpc::UpdateReadyState(const nsACString &readyState) {
|
||||
// callback while UDP socket is closed
|
||||
NS_IMETHODIMP NrSocketIpc::CallListenerClosed() {
|
||||
ASSERT_ON_THREAD(main_thread_);
|
||||
|
||||
ReentrantMonitorAutoEnter mon(monitor_);
|
||||
|
||||
if (readyState.EqualsLiteral("closed")) {
|
||||
MOZ_ASSERT(state_ == NR_CONNECTED || state_ == NR_CLOSING);
|
||||
state_ = NR_CLOSED;
|
||||
}
|
||||
MOZ_ASSERT(state_ == NR_CONNECTED || state_ == NR_CLOSING);
|
||||
state_ = NR_CLOSED;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1035,14 +1009,20 @@ void NrSocketIpc::create_m(const nsACString &host, const uint16_t port) {
|
|||
if (NS_FAILED(rv)) {
|
||||
err_ = true;
|
||||
MOZ_ASSERT(false, "Failed to create UDPSocketChild");
|
||||
mon.NotifyAll();
|
||||
return;
|
||||
}
|
||||
|
||||
socket_child_ = new nsMainThreadPtrHolder<nsIUDPSocketChild>(socketChild);
|
||||
socket_child_->SetFilterName(nsCString("stun"));
|
||||
|
||||
if (NS_FAILED(socket_child_->Bind(this, host, port))) {
|
||||
if (NS_FAILED(socket_child_->Bind(this, host, port,
|
||||
/* reuse = */ false,
|
||||
/* loopback = */ false))) {
|
||||
err_ = true;
|
||||
MOZ_ASSERT(false, "Failed to create UDP socket");
|
||||
mon.NotifyAll();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -236,9 +236,7 @@ NeckoChild::DeallocPTCPServerSocketChild(PTCPServerSocketChild* child)
|
|||
}
|
||||
|
||||
PUDPSocketChild*
|
||||
NeckoChild::AllocPUDPSocketChild(const nsCString& aHost,
|
||||
const uint16_t& aPort,
|
||||
const nsCString& aFilter)
|
||||
NeckoChild::AllocPUDPSocketChild(const nsCString& aFilter)
|
||||
{
|
||||
NS_NOTREACHED("AllocPUDPSocket should not be called");
|
||||
return nullptr;
|
||||
|
|
|
@ -51,9 +51,7 @@ protected:
|
|||
const uint16_t& aBacklog,
|
||||
const nsString& aBinaryType) MOZ_OVERRIDE;
|
||||
virtual bool DeallocPTCPServerSocketChild(PTCPServerSocketChild*) MOZ_OVERRIDE;
|
||||
virtual PUDPSocketChild* AllocPUDPSocketChild(const nsCString& aHost,
|
||||
const uint16_t& aPort,
|
||||
const nsCString& aFilter) MOZ_OVERRIDE;
|
||||
virtual PUDPSocketChild* AllocPUDPSocketChild(const nsCString& aFilter) MOZ_OVERRIDE;
|
||||
virtual bool DeallocPUDPSocketChild(PUDPSocketChild*) MOZ_OVERRIDE;
|
||||
virtual PDNSRequestChild* AllocPDNSRequestChild(const nsCString& aHost,
|
||||
const uint32_t& aFlags) MOZ_OVERRIDE;
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include "nsPrintfCString.h"
|
||||
#include "nsHTMLDNSPrefetch.h"
|
||||
#include "nsIAppsService.h"
|
||||
#include "nsIUDPSocketFilter.h"
|
||||
#include "nsEscape.h"
|
||||
#include "RemoteOpenFileParent.h"
|
||||
#include "SerializedLoadContext.h"
|
||||
|
@ -445,45 +444,18 @@ NeckoParent::DeallocPTCPServerSocketParent(PTCPServerSocketParent* actor)
|
|||
}
|
||||
|
||||
PUDPSocketParent*
|
||||
NeckoParent::AllocPUDPSocketParent(const nsCString& aHost,
|
||||
const uint16_t& aPort,
|
||||
const nsCString& aFilter)
|
||||
NeckoParent::AllocPUDPSocketParent(const nsCString& /* unused */)
|
||||
{
|
||||
UDPSocketParent* p = nullptr;
|
||||
nsRefPtr<UDPSocketParent> p = new UDPSocketParent();
|
||||
|
||||
// Only allow socket if it specifies a valid packet filter.
|
||||
nsAutoCString contractId(NS_NETWORK_UDP_SOCKET_FILTER_HANDLER_PREFIX);
|
||||
contractId.Append(aFilter);
|
||||
|
||||
if (!aFilter.IsEmpty()) {
|
||||
nsCOMPtr<nsIUDPSocketFilterHandler> filterHandler =
|
||||
do_GetService(contractId.get());
|
||||
if (filterHandler) {
|
||||
nsCOMPtr<nsIUDPSocketFilter> filter;
|
||||
nsresult rv = filterHandler->NewFilter(getter_AddRefs(filter));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
p = new UDPSocketParent(filter);
|
||||
} else {
|
||||
printf_stderr("Cannot create filter that content specified. "
|
||||
"filter name: %s, error code: %d.", aFilter.get(), rv);
|
||||
}
|
||||
} else {
|
||||
printf_stderr("Content doesn't have a valid filter. "
|
||||
"filter name: %s.", aFilter.get());
|
||||
}
|
||||
}
|
||||
|
||||
NS_IF_ADDREF(p);
|
||||
return p;
|
||||
return p.forget().take();
|
||||
}
|
||||
|
||||
bool
|
||||
NeckoParent::RecvPUDPSocketConstructor(PUDPSocketParent* aActor,
|
||||
const nsCString& aHost,
|
||||
const uint16_t& aPort,
|
||||
const nsCString& aFilter)
|
||||
{
|
||||
return static_cast<UDPSocketParent*>(aActor)->Init(aHost, aPort);
|
||||
return static_cast<UDPSocketParent*>(aActor)->Init(aFilter);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -153,13 +153,8 @@ protected:
|
|||
const uint16_t& aBacklog,
|
||||
const nsString& aBinaryType) MOZ_OVERRIDE;
|
||||
virtual bool DeallocPTCPServerSocketParent(PTCPServerSocketParent*) MOZ_OVERRIDE;
|
||||
virtual PUDPSocketParent* AllocPUDPSocketParent(const nsCString& aHost,
|
||||
const uint16_t& aPort,
|
||||
const nsCString& aFilter) MOZ_OVERRIDE;
|
||||
virtual bool RecvPUDPSocketConstructor(PUDPSocketParent*,
|
||||
const nsCString& aHost,
|
||||
const uint16_t& aPort,
|
||||
const nsCString& aFilter) MOZ_OVERRIDE;
|
||||
virtual PUDPSocketParent* AllocPUDPSocketParent(const nsCString& aFilter) MOZ_OVERRIDE;
|
||||
virtual bool RecvPUDPSocketConstructor(PUDPSocketParent*, const nsCString& aFilter) MOZ_OVERRIDE;
|
||||
virtual bool DeallocPUDPSocketParent(PUDPSocketParent*) MOZ_OVERRIDE;
|
||||
virtual PDNSRequestParent* AllocPDNSRequestParent(const nsCString& aHost,
|
||||
const uint32_t& aFlags) MOZ_OVERRIDE;
|
||||
|
|
|
@ -69,7 +69,7 @@ parent:
|
|||
|
||||
PWebSocket(PBrowserOrId browser, SerializedLoadContext loadContext);
|
||||
PTCPServerSocket(uint16_t localPort, uint16_t backlog, nsString binaryType);
|
||||
PUDPSocket(nsCString host, uint16_t port, nsCString filter);
|
||||
PUDPSocket(nsCString filter);
|
||||
|
||||
PDNSRequest(nsCString hostName, uint32_t flags);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче