Bug 950660: Part 1: Support bind in TCPSocket from content process r=jdm

This commit is contained in:
"Chih-Kai (Patrick) Wang" 2015-01-05 15:49:24 +08:00
parent 4916737c63
commit 4d498a7431
4 changed files with 115 additions and 0 deletions

View File

@ -41,6 +41,12 @@ parent:
// |binaryType| (from TCPOption.binaryType).
Open(nsString host, uint16_t port, bool useSSL, bool useArrayBuffers);
// Ask parent to open a socket and bind the newly-opened socket to a local
// address specified in |localAddr| and |localPort|.
OpenBind(nsCString host, uint16_t port,
nsCString localAddr, uint16_t localPort,
bool useSSL, nsCString binaryType);
// When child's send() is called, this message requrests parent to send
// data and update it's trackingNumber.
Data(SendableData data, uint32_t trackingNumber);

View File

@ -102,6 +102,23 @@ TCPSocketChild::SendOpen(TCPSocket* aSocket, bool aUseSSL, bool aUseArrayBuffers
PTCPSocketChild::SendOpen(mHost, mPort, aUseSSL, aUseArrayBuffers);
}
NS_IMETHODIMP
TCPSocketChild::SendWindowlessOpenBind(nsITCPSocketInternal* aSocket,
const nsACString& aRemoteHost, uint16_t aRemotePort,
const nsACString& aLocalHost, uint16_t aLocalPort,
bool aUseSSL)
{
mSocket = aSocket;
AddIPDLReference();
gNeckoChild->SendPTCPSocketConstructor(this,
NS_ConvertUTF8toUTF16(aRemoteHost),
aRemotePort);
PTCPSocketChild::SendOpenBind(nsCString(aRemoteHost), aRemotePort,
nsCString(aLocalHost), aLocalPort,
aUseSSL, NS_LITERAL_CSTRING("arraybuffer"));
return NS_OK;
}
void
TCPSocketChildBase::ReleaseIPDLReference()
{
@ -147,6 +164,16 @@ TCPSocketChild::RecvCallback(const nsString& aType,
} else if (aData.type() == CallbackData::TSendableData) {
const SendableData& data = aData.get_SendableData();
if (data.type() == SendableData::TArrayOfuint8_t) {
// See if we can pass array directly.
nsCOMPtr<nsITCPSocketInternalNative> nativeSocket = do_QueryInterface(mSocket);
if (nativeSocket) {
const InfallibleTArray<uint8_t>& buffer = data.get_ArrayOfuint8_t();
nativeSocket->CallListenerNativeArray(const_cast<uint8_t*>(buffer.Elements()),
buffer.Length());
return true;
}
}
AutoJSAPI api;
if (NS_WARN_IF(!api.Init(mSocket->GetOwner()))) {
return true;
@ -199,6 +226,13 @@ TCPSocketChild::SendSend(const ArrayBuffer& aData,
return NS_OK;
}
NS_IMETHODIMP
TCPSocketChild::SendSendArray(nsTArray<uint8_t> *aArr, uint32_t aTrackingNumber)
{
SendData(*aArr, aTrackingNumber);
return NS_OK;
}
void
TCPSocketChild::SetSocket(TCPSocket* aSocket)
{

View File

@ -16,6 +16,8 @@
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/TabParent.h"
#include "mozilla/HoldDropJSObjects.h"
#include "nsISocketTransportService.h"
#include "nsISocketTransport.h"
#include "nsIScriptSecurityManager.h"
#include "nsNetUtil.h"
@ -170,6 +172,72 @@ TCPSocketParent::RecvOpen(const nsString& aHost, const uint16_t& aPort, const bo
return true;
}
bool
TCPSocketParent::RecvOpenBind(const nsCString& aRemoteHost,
const uint16_t& aRemotePort,
const nsCString& aLocalAddr,
const uint16_t& aLocalPort,
const bool& aUseSSL,
const nsCString& aBinaryType)
{
if (net::UsingNeckoIPCSecurity() &&
!AssertAppProcessPermission(Manager()->Manager(), "tcp-socket")) {
FireInteralError(this, __LINE__);
return true;
}
nsresult rv;
nsCOMPtr<nsISocketTransportService> sts =
do_GetService("@mozilla.org/network/socket-transport-service;1", &rv);
if (NS_FAILED(rv)) {
FireInteralError(this, __LINE__);
return true;
}
nsCOMPtr<nsISocketTransport> socketTransport;
rv = sts->CreateTransport(nullptr, 0,
aRemoteHost, aRemotePort,
nullptr, getter_AddRefs(socketTransport));
if (NS_FAILED(rv)) {
FireInteralError(this, __LINE__);
return true;
}
PRNetAddr prAddr;
if (PR_SUCCESS != PR_InitializeNetAddr(PR_IpAddrAny, aLocalPort, &prAddr)) {
FireInteralError(this, __LINE__);
return true;
}
if (PR_SUCCESS != PR_StringToNetAddr(aLocalAddr.BeginReading(), &prAddr)) {
FireInteralError(this, __LINE__);
return true;
}
mozilla::net::NetAddr addr;
PRNetAddrToNetAddr(&prAddr, &addr);
rv = socketTransport->Bind(&addr);
if (NS_FAILED(rv)) {
FireInteralError(this, __LINE__);
return true;
}
// Obtain App ID
uint32_t appId = nsIScriptSecurityManager::NO_APP_ID;
const PContentParent *content = Manager()->Manager();
const InfallibleTArray<PBrowserParent*>& browsers = content->ManagedPBrowserParent();
if (browsers.Length() > 0) {
TabParent *tab = static_cast<TabParent*>(browsers[0]);
appId = tab->OwnAppId();
}
mSocket = new TCPSocket(nullptr, aRemoteHost, aRemotePort, aUseSSL,
aBinaryType.EqualsLiteral("arraybuffer"));
mSocket->SetAppIdAndBrowser(appId, inBrowser);
mSocket->SetSocketBridgeParent(this);
NS_ENSURE_SUCCESS(mSocket->InitWithTransport(socketTransport), true);
return true;
}
bool
TCPSocketParent::RecvStartTLS()
{

View File

@ -52,6 +52,13 @@ public:
virtual bool RecvOpen(const nsString& aHost, const uint16_t& aPort,
const bool& useSSL, const bool& aUseArrayBuffers) override;
virtual bool RecvOpenBind(const nsCString& aRemoteHost,
const uint16_t& aRemotePort,
const nsCString& aLocalAddr,
const uint16_t& aLocalPort,
const bool& aUseSSL,
const nsCString& aBinaryType) override;
virtual bool RecvStartTLS() override;
virtual bool RecvSuspend() override;
virtual bool RecvResume() override;