Bug 1217677: increase UDP socket receive buffer for <= Win7. r=jesup,mcmanus

MozReview-Commit-ID: A3yCZZ3Pwcu

--HG--
extra : rebase_source : 67d200194ed72076fcb6064f16ec94334f8fb5e7
This commit is contained in:
Nils Ohlmeier [:drno] 2016-03-01 21:46:50 -08:00
Родитель 1a7d746ecc
Коммит 01210346dd
9 изменённых файлов: 94 добавлений и 12 удалений

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

@ -41,7 +41,7 @@ protocol PUDPSocket
manager PNecko or PBackground;
parent:
async Bind(UDPAddressInfo addressInfo, bool addressReuse, bool loopback);
async Bind(UDPAddressInfo addressInfo, bool addressReuse, bool loopback, uint32_t recvBufferSize);
async Connect(UDPAddressInfo addressInfo);
async OutgoingData(UDPData data, UDPSocketAddr addr);

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

@ -503,7 +503,8 @@ UDPSocket::InitRemote(const nsAString& aLocalAddress,
NS_ConvertUTF16toUTF8(aLocalAddress),
aLocalPort,
mAddressReuse,
mLoopback);
mLoopback,
0);
if (NS_FAILED(rv)) {
return rv;

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

@ -171,7 +171,8 @@ UDPSocketChild::Bind(nsIUDPSocketInternal* aSocket,
const nsACString& aHost,
uint16_t aPort,
bool aAddressReuse,
bool aLoopback)
bool aLoopback,
uint32_t recvBufferSize)
{
UDPSOCKET_LOG(("%s: %s:%u", __FUNCTION__, PromiseFlatCString(aHost).get(), aPort));
@ -190,7 +191,7 @@ UDPSocketChild::Bind(nsIUDPSocketInternal* aSocket,
mFilterName);
}
SendBind(UDPAddressInfo(nsCString(aHost), aPort), aAddressReuse, aLoopback);
SendBind(UDPAddressInfo(nsCString(aHost), aPort), aAddressReuse, aLoopback, recvBufferSize);
return NS_OK;
}

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

@ -161,11 +161,12 @@ UDPSocketParent::Init(const IPC::Principal& aPrincipal,
bool
UDPSocketParent::RecvBind(const UDPAddressInfo& aAddressInfo,
const bool& aAddressReuse, const bool& aLoopback)
const bool& aAddressReuse, const bool& aLoopback,
const uint32_t& recvBufferSize)
{
UDPSOCKET_LOG(("%s: %s:%u", __FUNCTION__, aAddressInfo.addr().get(), aAddressInfo.port()));
if (NS_FAILED(BindInternal(aAddressInfo.addr(), aAddressInfo.port(), aAddressReuse, aLoopback))) {
if (NS_FAILED(BindInternal(aAddressInfo.addr(), aAddressInfo.port(), aAddressReuse, aLoopback, recvBufferSize))) {
FireInternalError(__LINE__);
return true;
}
@ -193,11 +194,12 @@ UDPSocketParent::RecvBind(const UDPAddressInfo& aAddressInfo,
nsresult
UDPSocketParent::BindInternal(const nsCString& aHost, const uint16_t& aPort,
const bool& aAddressReuse, const bool& aLoopback)
const bool& aAddressReuse, const bool& aLoopback,
const uint32_t& recvBufferSize)
{
nsresult rv;
UDPSOCKET_LOG(("%s: [this=%p] %s:%u addressReuse: %d loopback: %d", __FUNCTION__, this, nsCString(aHost).get(), aPort, aAddressReuse, aLoopback));
UDPSOCKET_LOG(("%s: [this=%p] %s:%u addressReuse: %d loopback: %d recvBufferSize: %lu", __FUNCTION__, this, nsCString(aHost).get(), aPort, aAddressReuse, aLoopback, recvBufferSize));
nsCOMPtr<nsIUDPSocket> sock =
do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv);
@ -243,6 +245,12 @@ UDPSocketParent::BindInternal(const nsCString& aHost, const uint16_t& aPort,
return rv;
}
}
if (recvBufferSize != 0) {
rv = sock->SetRecvBufferSize(recvBufferSize);
if (NS_WARN_IF(NS_FAILED(rv))) {
UDPSOCKET_LOG(("%s: [this=%p] %s:%u failed to set recv buffer size to: %lu", __FUNCTION__, this, nsCString(aHost).get(), aPort, recvBufferSize));
}
}
// register listener
rv = sock->AsyncListen(this);

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

@ -35,7 +35,8 @@ public:
bool Init(const IPC::Principal& aPrincipal, const nsACString& aFilter);
virtual bool RecvBind(const UDPAddressInfo& aAddressInfo,
const bool& aAddressReuse, const bool& aLoopback) override;
const bool& aAddressReuse, const bool& aLoopback,
const uint32_t& recvBufferSize) override;
virtual bool RecvConnect(const UDPAddressInfo& aAddressInfo) override;
void DoSendConnectResponse(const UDPAddressInfo& aAddressInfo);
void SendConnectResponse(nsIEventTarget *aThread,
@ -62,7 +63,8 @@ private:
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);
const bool& aAddressReuse, const bool& aLoopback,
const uint32_t& recvBufferSize);
nsresult ConnectInternal(const nsCString& aHost, const uint16_t& aPort);
void FireInternalError(uint32_t aLineNo);
void SendInternalError(nsIEventTarget *aThread,

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

@ -32,7 +32,7 @@ interface nsIUDPSocketChild : nsISupports
// Tell the chrome process to bind the UDP socket to a given local host and port
void bind(in nsIUDPSocketInternal socket, in nsIPrincipal principal,
in AUTF8String host, in unsigned short port,
in bool addressReuse, in bool loopback);
in bool addressReuse, in bool loopback, in uint32_t recvBufferSize);
// Tell the chrome process to connect the UDP socket to a given remote host and port
void connect(in nsIUDPSocketInternal socket, in AUTF8String host, in unsigned short port);

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

@ -114,6 +114,10 @@ nrappkit copyright:
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#ifdef XP_WIN
#include "mozilla/WindowsVersion.h"
#endif
#if defined(MOZILLA_INTERNAL_API)
// csi_platform.h deep in nrappkit defines LOG_INFO and LOG_WARNING
#ifdef LOG_INFO
@ -600,6 +604,25 @@ int NrSocket::create(nr_transport_addr *addr) {
"family=%d, err=%d", naddr.raw.family, PR_GetError());
ABORT(R_INTERNAL);
}
#ifdef XP_WIN
if (!mozilla::IsWin8OrLater()) {
PRSocketOptionData opt_rcvbuf;
opt_rcvbuf.option = PR_SockOpt_RecvBufferSize;
// Increase default receive buffer size on <= Win7 to be able to
// receive an unpaced HD (>= 720p = 1280x720 - I Frame ~ 21K size)
// stream without losing packets.
// Manual testing showed that 100K buffer size was not enough and the
// packet loss dis-appeared with 256K buffer size.
// See bug 1252769 for future improvements of this.
opt_rcvbuf.value.recv_buffer_size = 256 * 1024;
status = PR_SetSocketOption(fd_, &opt_rcvbuf);
if (status != PR_SUCCESS) {
r_log(LOG_GENERIC, LOG_CRIT,
"Couldn't set receive buffer size socket option: %d", status);
ABORT(R_INTERNAL);
}
}
#endif
break;
case IPPROTO_TCP:
if (!(fd_ = PR_OpenTCPSocket(naddr.raw.family))) {
@ -1457,6 +1480,7 @@ int NrUdpSocketIpc::accept(nr_transport_addr *addrp, nr_socket **sockp) {
void NrUdpSocketIpc::create_i(const nsACString &host, const uint16_t port) {
ASSERT_ON_THREAD(io_thread_);
uint32_t recvBuffSize = 0;
nsresult rv;
nsCOMPtr<nsIUDPSocketChild> socketChild = do_CreateInstance("@mozilla.org/udp-socket-child;1", &rv);
if (NS_FAILED(rv)) {
@ -1485,10 +1509,22 @@ void NrUdpSocketIpc::create_i(const nsACString &host, const uint16_t port) {
return;
}
#ifdef XP_WIN
if (!mozilla::IsWin8OrLater()) {
// Increase default receive buffer size on <= Win7 to be able to
// receive an unpaced HD (>= 720p = 1280x720 - I Frame ~ 21K size)
// stream without losing packets.
// Manual testing showed that 100K buffer size was not enough and the
// packet loss dis-appeared with 256K buffer size.
// See bug 1252769 for future improvements of this.
recvBuffSize = 256 * 1024;
}
#endif
// XXX bug 1126232 - don't use null Principal!
if (NS_FAILED(socket_child_->Bind(proxy, nullptr, host, port,
/* reuse = */ false,
/* loopback = */ false))) {
/* loopback = */ false,
/* recv buffer size */ recvBuffSize))) {
err_ = true;
MOZ_ASSERT(false, "Failed to create UDP socket");
mon.NotifyAll();

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

@ -259,6 +259,13 @@ interface nsIUDPSocket : nsISupports
* Note: This is currently write-only.
*/
[noscript] attribute NetAddr multicastInterfaceAddr;
/**
* recvBufferSize
*
* The size of the receive buffer. Default depends on the OS.
*/
[noscript] attribute long recvBufferSize;
};
/**

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

@ -1474,6 +1474,33 @@ nsUDPSocket::SetMulticastLoopback(bool aLoopback)
return NS_OK;
}
NS_IMETHODIMP
nsUDPSocket::GetRecvBufferSize(int* size)
{
// Bug 1252759 - missing support for GetSocketOption
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsUDPSocket::SetRecvBufferSize(int size)
{
if (NS_WARN_IF(!mFD)) {
return NS_ERROR_NOT_INITIALIZED;
}
PRSocketOptionData opt;
opt.option = PR_SockOpt_RecvBufferSize;
opt.value.recv_buffer_size = size;
nsresult rv = SetSocketOption(opt);
if (NS_WARN_IF(NS_FAILED(rv))) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP
nsUDPSocket::GetMulticastInterface(nsACString& aIface)
{