Bug 1215092 - WebSocketEventService and WebSocket discovering - part 2 - Unique Serial number for WebSocketChannel in IPC, r=michal

This commit is contained in:
Andrea Marchesini 2015-10-28 11:42:00 +00:00
parent 6addd278b1
commit efe3c01f37
13 changed files with 84 additions and 16 deletions

View File

@ -145,7 +145,8 @@ NeckoChild::DeallocPWyciwygChannelChild(PWyciwygChannelChild* channel)
PWebSocketChild*
NeckoChild::AllocPWebSocketChild(const PBrowserOrId& browser,
const SerializedLoadContext& aSerialized)
const SerializedLoadContext& aSerialized,
const uint32_t& aSerial)
{
NS_NOTREACHED("AllocPWebSocketChild should not be called");
return nullptr;

View File

@ -40,7 +40,8 @@ protected:
virtual bool DeallocPFTPChannelChild(PFTPChannelChild*) override;
virtual PWebSocketChild*
AllocPWebSocketChild(const PBrowserOrId&,
const SerializedLoadContext&) override;
const SerializedLoadContext&,
const uint32_t&) override;
virtual bool DeallocPWebSocketChild(PWebSocketChild*) override;
virtual PTCPSocketChild* AllocPTCPSocketChild(const nsString& host,
const uint16_t& port) override;

View File

@ -320,7 +320,8 @@ NeckoParent::DeallocPWyciwygChannelParent(PWyciwygChannelParent* channel)
PWebSocketParent*
NeckoParent::AllocPWebSocketParent(const PBrowserOrId& browser,
const SerializedLoadContext& serialized)
const SerializedLoadContext& serialized,
const uint32_t& aSerial)
{
nsCOMPtr<nsILoadContext> loadContext;
const char *error = CreateChannelLoadContext(browser, Manager(),
@ -335,7 +336,8 @@ NeckoParent::AllocPWebSocketParent(const PBrowserOrId& browser,
RefPtr<TabParent> tabParent = TabParent::GetFrom(browser.get_PBrowserParent());
PBOverrideStatus overrideStatus = PBOverrideStatusFromLoadContext(serialized);
WebSocketChannelParent* p = new WebSocketChannelParent(tabParent, loadContext,
overrideStatus);
overrideStatus,
aSerial);
p->AddRef();
return p;
}

View File

@ -124,7 +124,8 @@ protected:
virtual bool DeallocPFTPChannelParent(PFTPChannelParent*) override;
virtual PWebSocketParent*
AllocPWebSocketParent(const PBrowserOrId& browser,
const SerializedLoadContext& aSerialized) override;
const SerializedLoadContext& aSerialized,
const uint32_t& aSerial) override;
virtual bool DeallocPWebSocketParent(PWebSocketParent*) override;
virtual PTCPSocketParent* AllocPTCPSocketParent(const nsString& host,
const uint16_t& port) override;

View File

@ -68,7 +68,8 @@ parent:
PFTPChannel(PBrowserOrId browser, SerializedLoadContext loadContext,
FTPChannelCreationArgs args);
PWebSocket(PBrowserOrId browser, SerializedLoadContext loadContext);
PWebSocket(PBrowserOrId browser, SerializedLoadContext loadContext,
uint32_t aSerialID);
PTCPServerSocket(uint16_t localPort, uint16_t backlog, bool useArrayBuffers);
PUDPSocket(Principal principal, nsCString filter);

View File

@ -14,12 +14,25 @@
#include "nsStandardURL.h"
#include "LoadInfo.h"
#include "nsIDOMNode.h"
#include "mozilla/dom/ContentChild.h"
using mozilla::dom::ContentChild;
PRLogModuleInfo *webSocketLog = nullptr;
namespace mozilla {
namespace net {
static uint64_t gNextWebSocketID = 0;
// We use only 53 bits for the WebSocket serial ID so that it can be converted
// to and from a JS value without loss of precision. The upper bits of the
// WebSocket serial ID hold the process ID. The lower bits identify the
// WebSocket.
static const uint64_t kWebSocketIDTotalBits = 53;
static const uint64_t kWebSocketIDProcessBits = 22;
static const uint64_t kWebSocketIDWebSocketBits = kWebSocketIDTotalBits - kWebSocketIDProcessBits;
BaseWebSocketChannel::BaseWebSocketChannel()
: mWasOpened(0)
, mClientSetPingInterval(0)
@ -31,6 +44,24 @@ BaseWebSocketChannel::BaseWebSocketChannel()
{
if (!webSocketLog)
webSocketLog = PR_NewLogModule("nsWebSocket");
// Generation of a unique serial ID.
uint64_t processID = 0;
if (XRE_IsContentProcess()) {
ContentChild* cc = ContentChild::GetSingleton();
processID = cc->GetID();
}
uint64_t processBits = processID & ((uint64_t(1) << kWebSocketIDProcessBits) - 1);
// Make sure no actual webSocket ends up with mWebSocketID == 0 but less then
// what the kWebSocketIDProcessBits allows.
if (++gNextWebSocketID >= (uint64_t(1) << kWebSocketIDWebSocketBits)) {
gNextWebSocketID = 1;
}
uint64_t webSocketBits = gNextWebSocketID & ((uint64_t(1) << kWebSocketIDWebSocketBits) - 1);
mSerial = (processBits << kWebSocketIDWebSocketBits) | webSocketBits;
}
//-----------------------------------------------------------------------------
@ -197,6 +228,24 @@ BaseWebSocketChannel::InitLoadInfo(nsIDOMNode* aLoadingNode,
return NS_OK;
}
NS_IMETHODIMP
BaseWebSocketChannel::GetSerial(uint32_t* aSerial)
{
if (!aSerial) {
return NS_ERROR_FAILURE;
}
*aSerial = mSerial;
return NS_OK;
}
NS_IMETHODIMP
BaseWebSocketChannel::SetSerial(uint32_t aSerial)
{
mSerial = aSerial;
return NS_OK;
}
//-----------------------------------------------------------------------------
// BaseWebSocketChannel::nsIProtocolHandler
//-----------------------------------------------------------------------------

View File

@ -55,6 +55,8 @@ class BaseWebSocketChannel : public nsIWebSocketChannel,
NS_IMETHOD InitLoadInfo(nsIDOMNode* aLoadingNode, nsIPrincipal* aLoadingPrincipal,
nsIPrincipal* aTriggeringPrincipal, uint32_t aSecurityFlags,
uint32_t aContentPolicyType) override;
NS_IMETHOD GetSerial(uint32_t* aSerial) override;
NS_IMETHOD SetSerial(uint32_t aSerial) override;
// Off main thread URI access.
virtual void GetEffectiveURL(nsAString& aEffectiveURL) const = 0;
@ -98,6 +100,8 @@ class BaseWebSocketChannel : public nsIWebSocketChannel,
uint32_t mPingInterval; /* milliseconds */
uint32_t mPingResponseTimeout; /* milliseconds */
uint32_t mSerial;
};
} // namespace net

View File

@ -1138,8 +1138,6 @@ NS_IMPL_ISUPPORTS(OutboundEnqueuer, nsIRunnable)
// WebSocketChannel
//-----------------------------------------------------------------------------
uint32_t WebSocketChannel::sSerialSeed = 0;
WebSocketChannel::WebSocketChannel() :
mPort(0),
mCloseTimeout(20000),
@ -1194,8 +1192,6 @@ WebSocketChannel::WebSocketChannel() :
if (NS_FAILED(rv))
LOG(("Failed to initiate dashboard service."));
mSerial = sSerialSeed++;
mService = WebSocketEventService::GetOrCreate();
}

View File

@ -294,8 +294,6 @@ private:
bool mPrivateBrowsing;
nsCOMPtr<nsIDashboardEventNotifier> mConnectionLogService;
uint32_t mSerial;
static uint32_t sSerialSeed;
// These members are used for network per-app metering (bug 855949)
// Currently, they are only available on gonk.

View File

@ -489,7 +489,8 @@ WebSocketChannelChild::AsyncOpen(nsIURI *aURI,
NS_ENSURE_SUCCESS(rv, rv);
gNeckoChild->SendPWebSocketConstructor(this, tabChild,
IPC::SerializedLoadContext(this));
IPC::SerializedLoadContext(this),
mSerial);
if (!SendAsyncOpen(uri, nsCString(aOrigin), aInnerWindowID, mProtocol,
mEncrypted, mPingInterval, mClientSetPingInterval,
mPingResponseTimeout, mClientSetPingTimeout, loadInfoArgs)) {

View File

@ -26,10 +26,12 @@ NS_IMPL_ISUPPORTS(WebSocketChannelParent,
WebSocketChannelParent::WebSocketChannelParent(nsIAuthPromptProvider* aAuthProvider,
nsILoadContext* aLoadContext,
PBOverrideStatus aOverrideStatus)
PBOverrideStatus aOverrideStatus,
uint32_t aSerial)
: mAuthProvider(aAuthProvider)
, mLoadContext(aLoadContext)
, mIPCOpen(true)
, mSerial(aSerial)
{
// Websocket channels can't have a private browsing override
MOZ_ASSERT_IF(!aLoadContext, aOverrideStatus == kPBOverride_Unset);
@ -95,6 +97,11 @@ WebSocketChannelParent::RecvAsyncOpen(const URIParams& aURI,
if (NS_FAILED(rv))
goto fail;
rv = mChannel->SetSerial(mSerial);
if (NS_WARN_IF(NS_FAILED(rv))) {
goto fail;
}
rv = LoadInfoArgsToLoadInfo(aLoadInfoArgs, getter_AddRefs(loadInfo));
if (NS_FAILED(rv))
goto fail;

View File

@ -35,7 +35,8 @@ class WebSocketChannelParent : public PWebSocketParent,
WebSocketChannelParent(nsIAuthPromptProvider* aAuthProvider,
nsILoadContext* aLoadContext,
PBOverrideStatus aOverrideStatus);
PBOverrideStatus aOverrideStatus,
uint32_t aSerial);
private:
bool RecvAsyncOpen(const URIParams& aURI,
@ -66,6 +67,7 @@ class WebSocketChannelParent : public PWebSocketParent,
nsCOMPtr<nsILoadContext> mLoadContext;
bool mIPCOpen;
uint32_t mSerial;
};
} // namespace net

View File

@ -22,7 +22,7 @@ interface nsIPrincipal;
* We are also making it scriptable for now, but this may change once we have
* WebSockets for Workers.
*/
[scriptable, uuid(352e0c08-f14c-40c8-ad06-2f8bb5d9d9e0)]
[scriptable, uuid(1bfc252b-ad46-413c-860b-2079bf1399c7)]
interface nsIWebSocketChannel : nsISupports
{
/**
@ -223,4 +223,9 @@ interface nsIWebSocketChannel : nsISupports
*/
attribute unsigned long pingTimeout;
/**
* Unique ID for this channel. It's not readonly because when the channel is
* created via IPC, the serial number is received from the child process.
*/
attribute unsigned long serial;
};