Bug 870660: Part 1: Add packat filter to UDPSocketParent/Child. r=jduell

This commit is contained in:
Patrick Wang 2013-11-30 00:13:44 +08:00
Родитель 1c1cb515cf
Коммит 7c8f13cfcf
12 изменённых файлов: 152 добавлений и 19 удалений

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

@ -22,6 +22,8 @@ interface nsIUDPSocketChild : nsISupports
{
readonly attribute unsigned short localPort;
readonly attribute AUTF8String localAddress;
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);

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

@ -67,7 +67,7 @@ UDPSocketChild::Bind(nsIUDPSocketInternal *aSocket,
mSocket = aSocket;
AddIPDLReference();
gNeckoChild->SendPUDPSocketConstructor(this, nsCString(aHost), aPort);
gNeckoChild->SendPUDPSocketConstructor(this, nsCString(aHost), aPort, mFilterName);
return NS_OK;
}
@ -149,6 +149,24 @@ UDPSocketChild::GetLocalAddress(nsACString &aLocalAddress)
return NS_OK;
}
NS_IMETHODIMP
UDPSocketChild::SetFilterName(const nsACString &aFilterName)
{
if (!mFilterName.IsEmpty()) {
// filter name can only be set once.
return NS_ERROR_FAILURE;
}
mFilterName = aFilterName;
return NS_OK;
}
NS_IMETHODIMP
UDPSocketChild::GetFilterName(nsACString &aFilterName)
{
aFilterName = mFilterName;
return NS_OK;
}
// PUDPSocketChild Methods
bool
UDPSocketChild::RecvCallback(const nsCString &aType,

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

@ -46,6 +46,7 @@ public:
private:
uint16_t mLocalPort;
nsCString mLocalAddress;
nsCString mFilterName;
};
} // namespace dom

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

@ -1,7 +1,10 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsIServiceManager.h"
#include "UDPSocketParent.h"
#include "nsComponentManagerUtils.h"
#include "nsIUDPSocket.h"
@ -65,6 +68,7 @@ bool
UDPSocketParent::Init(const nsCString &aHost, const uint16_t aPort)
{
nsresult rv;
NS_ASSERTION(mFilter, "No packet filter");
nsCOMPtr<nsIUDPSocket> sock =
do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv);
@ -124,6 +128,13 @@ UDPSocketParent::RecvData(const InfallibleTArray<uint8_t> &aData,
const uint16_t& aPort)
{
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(),
@ -135,6 +146,7 @@ UDPSocketParent::RecvData(const InfallibleTArray<uint8_t> &aData,
NS_ENSURE_SUCCESS(rv, true);
NS_ENSURE_TRUE(count > 0, true);
return true;
#endif
}
bool
@ -142,9 +154,20 @@ 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 = mSocket->SendWithAddress(&aAddr, aData.Elements(),
aData.Length(), &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);
rv = mSocket->SendWithAddress(&aAddr, aData.Elements(),
aData.Length(), &count);
mozilla::unused <<
PUDPSocketParent::SendCallback(NS_LITERAL_CSTRING("onsent"),
UDPSendResult(rv),
@ -191,6 +214,7 @@ UDPSocketParent::OnPacketReceived(nsIUDPSocket* aSocket, nsIUDPMessage* aMessage
if (!mIPCOpen) {
return NS_OK;
}
NS_ASSERTION(mFilter, "No packet filter");
uint16_t port;
nsCString ip;
@ -205,6 +229,17 @@ 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);
FallibleTArray<uint8_t> fallibleArray;
if (!fallibleArray.InsertElementsAt(0, buffer, len)) {
FireInternalError(this, __LINE__);

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

@ -1,3 +1,5 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -8,6 +10,7 @@
#include "mozilla/net/PUDPSocketParent.h"
#include "nsCOMPtr.h"
#include "nsIUDPSocket.h"
#include "nsIUDPSocketFilter.h"
namespace mozilla {
namespace dom {
@ -19,7 +22,10 @@ public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIUDPSOCKETLISTENER
UDPSocketParent() : mIPCOpen(true) {}
UDPSocketParent(nsIUDPSocketFilter* filter) :
mIPCOpen(true),
mFilter(filter) {}
virtual ~UDPSocketParent();
bool Init(const nsCString& aHost, const uint16_t aPort);
@ -37,6 +43,7 @@ private:
bool mIPCOpen;
nsCOMPtr<nsIUDPSocket> mSocket;
nsCOMPtr<nsIUDPSocketFilter> mFilter;
};
} // namespace dom

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

@ -107,6 +107,7 @@ XPIDL_SOURCES += [
'nsITraceableChannel.idl',
'nsITransport.idl',
'nsIUDPSocket.idl',
'nsIUDPSocketFilter.idl',
'nsIUnicharStreamLoader.idl',
'nsIUploadChannel.idl',
'nsIUploadChannel2.idl',

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

@ -0,0 +1,45 @@
/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
#include "nsINetAddr.idl"
native NetAddr(mozilla::net::NetAddr);
[ptr] native NetAddrPtr(mozilla::net::NetAddr);
/**
* Filters are created and run on the parent, and filter all UDP packets, both
* ingoing and outgoing. The child must specify the name of a recognized filter
* in order to create a UDP socket.
*/
[uuid(24f20de4-09e9-42ab-947a-0d6a3d103d59)]
interface nsIUDPSocketFilter : nsISupports
{
const long SF_INCOMING = 0;
const long SF_OUTGOING = 1;
bool filterPacket([const]in NetAddrPtr remote_addr,
[const, array, size_is(len)]in uint8_t data,
in unsigned long len,
in long direction);
};
/**
* Factory of a specified filter.
*/
[uuid(81ee76c6-4753-4125-9c8c-290ed9ba62fb)]
interface nsIUDPSocketFilterHandler : nsISupports
{
nsIUDPSocketFilter newFilter();
};
%{C++
/**
* Filter handlers are registered with XPCOM under the following CONTRACTID prefix:
*/
#define NS_NETWORK_UDP_SOCKET_FILTER_HANDLER_PREFIX "@mozilla.org/network/udp-filter-handler;1?name="
%}

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

@ -214,7 +214,8 @@ NeckoChild::DeallocPTCPServerSocketChild(PTCPServerSocketChild* child)
PUDPSocketChild*
NeckoChild::AllocPUDPSocketChild(const nsCString& aHost,
const uint16_t& aPort)
const uint16_t& aPort,
const nsCString& aFilter)
{
NS_NOTREACHED("AllocPUDPSocket should not be called");
return nullptr;

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

@ -48,7 +48,8 @@ protected:
const nsString& aBinaryType);
virtual bool DeallocPTCPServerSocketChild(PTCPServerSocketChild*);
virtual PUDPSocketChild* AllocPUDPSocketChild(const nsCString& aHost,
const uint16_t& aPort);
const uint16_t& aPort,
const nsCString& aFilter);
virtual bool DeallocPUDPSocketChild(PUDPSocketChild*);
virtual PRemoteOpenFileChild* AllocPRemoteOpenFileChild(const URIParams&,
const OptionalURIParams&);

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

@ -28,6 +28,7 @@
#include "nsPrintfCString.h"
#include "nsHTMLDNSPrefetch.h"
#include "nsIAppsService.h"
#include "nsIUDPSocketFilter.h"
#include "nsEscape.h"
#include "RemoteOpenFileParent.h"
#include "SerializedLoadContext.h"
@ -379,23 +380,42 @@ NeckoParent::DeallocPTCPServerSocketParent(PTCPServerSocketParent* actor)
PUDPSocketParent*
NeckoParent::AllocPUDPSocketParent(const nsCString& aHost,
const uint16_t& aPort)
const uint16_t& aPort,
const nsCString& aFilter)
{
bool enabled = Preferences::GetBool("media.peerconnection.ipc.enabled", false);
if (!enabled) {
NS_WARNING("Not support UDP socket in content process, aborting subprocess");
return nullptr;
}
UDPSocketParent* p = new UDPSocketParent();
p->AddRef();
return p;
UDPSocketParent* p;
// 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;
}
bool
NeckoParent::RecvPUDPSocketConstructor(PUDPSocketParent* aActor,
const nsCString& aHost,
const uint16_t& aPort)
const uint16_t& aPort,
const nsCString& aFilter)
{
return static_cast<UDPSocketParent*>(aActor)->Init(aHost, aPort);
}

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

@ -117,10 +117,12 @@ protected:
const nsString& aBinaryType);
virtual bool DeallocPTCPServerSocketParent(PTCPServerSocketParent*);
virtual PUDPSocketParent* AllocPUDPSocketParent(const nsCString& aHost,
const uint16_t& aPort);
const uint16_t& aPort,
const nsCString& aFilter);
virtual bool RecvPUDPSocketConstructor(PUDPSocketParent*,
const nsCString& aHost,
const uint16_t& aPort);
const uint16_t& aPort,
const nsCString& aFilter);
virtual bool DeallocPUDPSocketParent(PUDPSocketParent*);
virtual bool RecvHTMLDNSPrefetch(const nsString& hostname,
const uint16_t& flags);

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

@ -57,7 +57,7 @@ parent:
PWebSocket(PBrowser browser, SerializedLoadContext loadContext);
PTCPServerSocket(uint16_t localPort, uint16_t backlog, nsString binaryType);
PUDPSocket(nsCString host, uint16_t port);
PUDPSocket(nsCString host, uint16_t port, nsCString filter);
PRemoteOpenFile(URIParams fileuri, OptionalURIParams appuri);