Bug 1266667: socket reuse option for TCPSocket. r=mcmanus

MozReview-Commit-ID: CJEK714ruLl

--HG--
extra : rebase_source : a52f8c96c0fed3881f3480a38dc2167f1eb4c451
This commit is contained in:
Nils Ohlmeier [:drno] 2016-12-21 23:38:06 -08:00
parent 5b20fb2bce
commit 54ada30c75
10 changed files with 60 additions and 5 deletions

View File

@ -45,7 +45,8 @@ parent:
// address specified in |localAddr| and |localPort|.
async OpenBind(nsCString host, uint16_t port,
nsCString localAddr, uint16_t localPort,
bool useSSL, bool aUseArrayBuffers, nsCString aFilter);
bool useSSL, bool reuseAddrPort,
bool aUseArrayBuffers, nsCString aFilter);
// When child's send() is called, this message requrests parent to send
// data and update it's trackingNumber.

View File

@ -109,7 +109,7 @@ void
TCPSocketChild::SendWindowlessOpenBind(nsITCPSocketCallback* aSocket,
const nsACString& aRemoteHost, uint16_t aRemotePort,
const nsACString& aLocalHost, uint16_t aLocalPort,
bool aUseSSL)
bool aUseSSL, bool aReuseAddrPort)
{
mSocket = aSocket;
AddIPDLReference();
@ -118,7 +118,8 @@ TCPSocketChild::SendWindowlessOpenBind(nsITCPSocketCallback* aSocket,
aRemotePort);
PTCPSocketChild::SendOpenBind(nsCString(aRemoteHost), aRemotePort,
nsCString(aLocalHost), aLocalPort,
aUseSSL, true, mFilterName);
aUseSSL, aReuseAddrPort,
true, mFilterName);
}
void

View File

@ -56,7 +56,7 @@ public:
void SendWindowlessOpenBind(nsITCPSocketCallback* aSocket,
const nsACString& aRemoteHost, uint16_t aRemotePort,
const nsACString& aLocalHost, uint16_t aLocalPort,
bool aUseSSL);
bool aUseSSL, bool aUseRealtimeOptions);
NS_IMETHOD SendSendArray(nsTArray<uint8_t>& aArray,
uint32_t aTrackingNumber);
void SendSend(const nsACString& aData, uint32_t aTrackingNumber);

View File

@ -134,6 +134,7 @@ TCPSocketParent::RecvOpenBind(const nsCString& aRemoteHost,
const nsCString& aLocalAddr,
const uint16_t& aLocalPort,
const bool& aUseSSL,
const bool& aReuseAddrPort,
const bool& aUseArrayBuffers,
const nsCString& aFilter)
{
@ -154,6 +155,10 @@ TCPSocketParent::RecvOpenBind(const nsCString& aRemoteHost,
return IPC_OK();
}
// in most cases aReuseAddrPort is false, but ICE TCP needs
// sockets options set that allow addr/port reuse
socketTransport->SetReuseAddrPort(aReuseAddrPort);
PRNetAddr prAddr;
if (PR_SUCCESS != PR_InitializeNetAddr(PR_IpAddrAny, aLocalPort, &prAddr)) {
FireInteralError(this, __LINE__);

View File

@ -55,6 +55,7 @@ public:
const nsCString& aLocalAddr,
const uint16_t& aLocalPort,
const bool& aUseSSL,
const bool& aReuseAddrPort,
const bool& aUseArrayBuffers,
const nsCString& aFilter) override;

View File

@ -1967,7 +1967,8 @@ void NrTcpSocketIpc::connect_i(const nsACString &remote_addr,
socket_child_->SendWindowlessOpenBind(this,
remote_addr, remote_port,
local_addr, local_port,
/* use ssl */ false);
/* use ssl */ false,
/* reuse addr port */ true);
}
void NrTcpSocketIpc::write_i(nsAutoPtr<InfallibleTArray<uint8_t>> arr,

View File

@ -129,6 +129,11 @@ interface nsISocketTransport : nsITransport
unsigned long getTimeout(in unsigned long aType);
void setTimeout(in unsigned long aType, in unsigned long aValue);
/**
* True to set addr and port reuse socket options.
*/
void setReuseAddrPort(in bool reuseAddrPort);
/**
* Values for the aType parameter passed to get/setTimeout.
*/

View File

@ -740,6 +740,7 @@ nsSocketTransport::nsSocketTransport()
, mProxyTransparentResolvesHost(false)
, mHttpsProxy(false)
, mConnectionFlags(0)
, mReuseAddrPort(false)
, mState(STATE_CLOSED)
, mAttached(false)
, mInputClosed(true)
@ -1354,6 +1355,32 @@ nsSocketTransport::InitiateSocket()
status = PR_SetSocketOption(fd, &opt);
NS_ASSERTION(status == PR_SUCCESS, "unable to make socket non-blocking");
if (mReuseAddrPort) {
SOCKET_LOG((" Setting port/addr reuse socket options\n"));
// Set ReuseAddr for TCP sockets to enable having several
// sockets bound to same local IP and port
PRSocketOptionData opt_reuseaddr;
opt_reuseaddr.option = PR_SockOpt_Reuseaddr;
opt_reuseaddr.value.reuse_addr = PR_TRUE;
status = PR_SetSocketOption(fd, &opt_reuseaddr);
if (status != PR_SUCCESS) {
SOCKET_LOG((" Couldn't set reuse addr socket option: %d\n",
status));
}
// And also set ReusePort for platforms supporting this socket option
PRSocketOptionData opt_reuseport;
opt_reuseport.option = PR_SockOpt_Reuseport;
opt_reuseport.value.reuse_port = PR_TRUE;
status = PR_SetSocketOption(fd, &opt_reuseport);
if (status != PR_SUCCESS
&& PR_GetError() != PR_OPERATION_NOT_SUPPORTED_ERROR) {
SOCKET_LOG((" Couldn't set reuse port socket option: %d\n",
status));
}
}
// disable the nagle algorithm - if we rely on it to coalesce writes into
// full packets the final packet of a multi segment POST/PUT or pipeline
// sequence is delayed a full rtt
@ -2538,6 +2565,13 @@ nsSocketTransport::SetTimeout(uint32_t type, uint32_t value)
return NS_OK;
}
NS_IMETHODIMP
nsSocketTransport::SetReuseAddrPort(bool reuseAddrPort)
{
mReuseAddrPort = reuseAddrPort;
return NS_OK;
}
NS_IMETHODIMP
nsSocketTransport::SetQoSBits(uint8_t aQoSBits)
{

View File

@ -302,6 +302,7 @@ private:
bool mProxyTransparentResolvesHost;
bool mHttpsProxy;
uint32_t mConnectionFlags;
bool mReuseAddrPort;
// The origin attributes are used to create sockets. The first party domain
// will eventually be used to isolate OCSP cache and is only non-empty when

View File

@ -1651,6 +1651,12 @@ SocketTransportShim::SetTimeout(uint32_t aType, uint32_t aValue)
return mWrapped->SetTimeout(aType, aValue);
}
NS_IMETHODIMP
SocketTransportShim::SetReuseAddrPort(bool aReuseAddrPort)
{
return mWrapped->SetReuseAddrPort(aReuseAddrPort);
}
NS_IMETHODIMP
SocketTransportShim::GetQoSBits(uint8_t *aQoSBits)
{