Bug 745283 - Part 3: Support send input stream and multicast operation via PUDPSocket.ipdl. r=jduell, r=mt
authorShih-Chiang Chien <schien@mozilla.com>
Tue, 06 May 2014 18:32:25 +0800
changeset 201689 d0ab836a651799713886dd5edf309a945f0b694c
parent 201688 69e68a879b44f58e5044467b99cf5e6687690d29
child 201690 4f6affdf52b6db940cc6bacde684d765d99cfd12
push idunknown
push userunknown
push dateunknown
reviewersjduell, mt
bugs745283
milestone34.0a1
Bug 745283 - Part 3: Support send input stream and multicast operation via PUDPSocket.ipdl. r=jduell, r=mt
dom/network/interfaces/nsIUDPSocketChild.idl
dom/network/src/PUDPSocket.ipdl
dom/network/src/UDPSocketChild.cpp
dom/network/src/UDPSocketChild.h
dom/network/src/UDPSocketParent.cpp
dom/network/src/UDPSocketParent.h
media/mtransport/nr_socket_prsock.cpp
netwerk/ipc/NeckoChild.cpp
netwerk/ipc/NeckoChild.h
netwerk/ipc/NeckoParent.cpp
netwerk/ipc/NeckoParent.h
netwerk/ipc/PNecko.ipdl
--- a/dom/network/interfaces/nsIUDPSocketChild.idl
+++ b/dom/network/interfaces/nsIUDPSocketChild.idl
@@ -1,58 +1,67 @@
 /* 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"
 
 interface nsIUDPSocketInternal;
+interface nsIInputStream;
 
 %{ C++
 namespace mozilla {
 namespace net {
 union NetAddr;
 }
 }
 %}
 native NetAddr(mozilla::net::NetAddr);
 [ptr] native NetAddrPtr(mozilla::net::NetAddr);
 
-[scriptable, uuid(B47E5A0F-D384-48EF-8885-4259793D9CF0)]
+[scriptable, uuid(5bb7de5a-8766-4c13-b9ed-14e63168dabf)]
 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);
+  void bind(in nsIUDPSocketInternal socket, in AUTF8String host, in unsigned short port,
+            in bool addressReuse, in bool loopback);
 
   // Tell the chrome process to perform equivalent operations to all following methods
   void send(in AUTF8String host, in unsigned short port,
             [const, array, size_is(byteLength)] in uint8_t bytes,
             in unsigned long byteLength);
   // Send without DNS query
   void sendWithAddr(in nsINetAddr addr,
                     [const, array, size_is(byteLength)] in uint8_t bytes,
                     in unsigned long byteLength);
   [noscript] void sendWithAddress([const] in NetAddrPtr addr,
                                   [const, array, size_is(byteLength)] in uint8_t bytes,
                                   in unsigned long byteLength);
+  // Send input stream. This must be a buffered stream implementation.
+  void sendBinaryStream(in AUTF8String host, in unsigned short port, in nsIInputStream stream);
+
   void close();
+  void joinMulticast(in AUTF8String multicastAddress, in AUTF8String iface);
+  void leaveMulticast(in AUTF8String multicastAddress, in AUTF8String iface);
 };
 
 /*
  * Internal interface for callback from chrome process
  */
-[scriptable, uuid(1E27E9B3-C1C8-4B05-A415-1A2C1A641C60)]
+[scriptable, uuid(44cd9ad5-d574-4169-baf9-e1af0648a143)]
 interface nsIUDPSocketInternal : nsISupports
 {
-  void callListenerError(in AUTF8String type, in AUTF8String message, in AUTF8String filename,
-                         in uint32_t lineNumber, in uint32_t columnNumber);
-  void callListenerReceivedData(in AUTF8String type, in AUTF8String host, in unsigned short port,
-                                [array, size_is(dataLength)] in uint8_t data,
+  // callback while socket is opened. localPort and localAddress is ready until this time.
+  void callListenerOpened();
+  // callback while socket is closed.
+  void callListenerClosed();
+  // callback while incoming packet is received.
+  void callListenerReceivedData(in AUTF8String host, in unsigned short port,
+                                [const, array, size_is(dataLength)] in uint8_t data,
                                 in unsigned long dataLength);
-  void callListenerVoid(in AUTF8String type);
-  void callListenerSent(in AUTF8String type, in nsresult status);
-  void updateReadyState(in AUTF8String readyState);
+  // callback while any error happened.
+  void callListenerError(in AUTF8String message, in AUTF8String filename, in uint32_t lineNumber);
 };
--- a/dom/network/src/PUDPSocket.ipdl
+++ b/dom/network/src/PUDPSocket.ipdl
@@ -1,69 +1,65 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
 
 /* 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 protocol PNecko;
+include protocol PBlob;
+include InputStreamParams;
 
 include "mozilla/net/NeckoMessageUtils.h";
 include "mozilla/net/DNS.h";
 include "prio.h";
 
 using mozilla::net::NetAddr from "mozilla/net/DNS.h";
 using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
 
-struct UDPError {
-  nsCString message;
-  nsCString filename;
-  uint32_t lineNumber;
-  uint32_t columnNumber;
-};
-
-struct UDPMessage {
-  nsCString fromAddr;
-  uint16_t port;
-  uint8_t[] data;
-};
-
 struct UDPAddressInfo {
-  nsCString local;
+  nsCString addr;
   uint16_t port;
 };
 
-struct UDPSendResult {
-  nsresult value;
+union UDPSocketAddr {
+  UDPAddressInfo;
+  NetAddr;
 };
 
-union UDPCallbackData {
-  void_t;
-  UDPMessage;
-  UDPAddressInfo;
-  UDPSendResult;
-  UDPError;
+union UDPData {
+  uint8_t[];
+  InputStreamParams;
 };
 
 namespace mozilla {
 namespace net {
 
 //-------------------------------------------------------------------
 protocol PUDPSocket
 {
   manager PNecko;
 
 parent:
-  Data(uint8_t[] data, nsCString remoteAddress, uint16_t port);
-  DataWithAddress(uint8_t[] data, NetAddr addr);
+  Bind(UDPAddressInfo addressInfo, bool addressReuse, bool loopback);
+
+  OutgoingData(UDPData data, UDPSocketAddr addr);
+
+  JoinMulticast(nsCString multicastAddress, nsCString iface);
+  LeaveMulticast(nsCString multicastAddress, nsCString iface);
+
   Close();
+
   RequestDelete();
 
 child:
-  Callback(nsCString type, UDPCallbackData data, nsCString aState);
+  CallbackOpened(UDPAddressInfo addressInfo);
+  CallbackClosed();
+  CallbackReceivedData(UDPAddressInfo addressInfo, uint8_t[] data);
+  CallbackError(nsCString message, nsCString filename, uint32_t lineNumber);
   __delete__();
 };
 
 
 } // namespace net
 } // namespace mozilla
 
--- a/dom/network/src/UDPSocketChild.cpp
+++ b/dom/network/src/UDPSocketChild.cpp
@@ -1,13 +1,15 @@
 /* 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 "UDPSocketChild.h"
+#include "mozilla/unused.h"
+#include "mozilla/ipc/InputStreamUtils.h"
 #include "mozilla/net/NeckoChild.h"
 
 using mozilla::net::gNeckoChild;
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_ISUPPORTS(UDPSocketChildBase, nsIUDPSocketChild)
@@ -54,158 +56,203 @@ UDPSocketChild::UDPSocketChild()
 
 UDPSocketChild::~UDPSocketChild()
 {
 }
 
 // nsIUDPSocketChild Methods
 
 NS_IMETHODIMP
-UDPSocketChild::Bind(nsIUDPSocketInternal *aSocket,
+UDPSocketChild::Bind(nsIUDPSocketInternal* aSocket,
                      const nsACString& aHost,
-                     uint16_t aPort)
+                     uint16_t aPort,
+                     bool aAddressReuse,
+                     bool aLoopback)
 {
   NS_ENSURE_ARG(aSocket);
 
   mSocket = aSocket;
   AddIPDLReference();
 
-  gNeckoChild->SendPUDPSocketConstructor(this, nsCString(aHost), aPort, mFilterName);
+  gNeckoChild->SendPUDPSocketConstructor(this, mFilterName);
 
+  SendBind(UDPAddressInfo(nsCString(aHost), aPort), aAddressReuse, aLoopback);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 UDPSocketChild::Close()
 {
   SendClose();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 UDPSocketChild::Send(const nsACString& aHost,
                      uint16_t aPort,
-                     const uint8_t *aData,
+                     const uint8_t* aData,
                      uint32_t aByteLength)
 {
   NS_ENSURE_ARG(aData);
 
+  return SendDataInternal(UDPSocketAddr(UDPAddressInfo(nsCString(aHost), aPort)),
+                          aData, aByteLength);
+}
+
+NS_IMETHODIMP
+UDPSocketChild::SendWithAddr(nsINetAddr* aAddr,
+                             const uint8_t* aData,
+                             uint32_t aByteLength)
+{
+  NS_ENSURE_ARG(aAddr);
+  NS_ENSURE_ARG(aData);
+
+  NetAddr addr;
+  aAddr->GetNetAddr(&addr);
+
+  return SendDataInternal(UDPSocketAddr(addr), aData, aByteLength);
+}
+
+NS_IMETHODIMP
+UDPSocketChild::SendWithAddress(const NetAddr* aAddr,
+                                const uint8_t* aData,
+                                uint32_t aByteLength)
+{
+  NS_ENSURE_ARG(aAddr);
+  NS_ENSURE_ARG(aData);
+
+  return SendDataInternal(UDPSocketAddr(*aAddr), aData, aByteLength);
+}
+
+nsresult
+UDPSocketChild::SendDataInternal(const UDPSocketAddr& aAddr,
+                                 const uint8_t* aData,
+                                 const uint32_t aByteLength)
+{
+  NS_ENSURE_ARG(aData);
+
   FallibleTArray<uint8_t> fallibleArray;
   if (!fallibleArray.InsertElementsAt(0, aData, aByteLength)) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   InfallibleTArray<uint8_t> array;
   array.SwapElements(fallibleArray);
-  SendData(array, nsCString(aHost), aPort);
+
+  SendOutgoingData(array, aAddr);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-UDPSocketChild::SendWithAddr(nsINetAddr *aAddr,
-                             const uint8_t *aData,
-                             uint32_t aByteLength)
+UDPSocketChild::SendBinaryStream(const nsACString& aHost,
+                                 uint16_t aPort,
+                                 nsIInputStream* aStream)
 {
-  NS_ENSURE_ARG(aAddr);
-  NS_ENSURE_ARG(aData);
-
-  NetAddr addr;
-  aAddr->GetNetAddr(&addr);
-
-  return SendWithAddress(&addr, aData, aByteLength);
-}
+  NS_ENSURE_ARG(aStream);
 
-NS_IMETHODIMP
-UDPSocketChild::SendWithAddress(const NetAddr *aAddr,
-                                const uint8_t *aData,
-                                uint32_t aByteLength)
-{
-  NS_ENSURE_ARG(aAddr);
-  NS_ENSURE_ARG(aData);
+  OptionalInputStreamParams stream;
+  nsTArray<mozilla::ipc::FileDescriptor> fds;
+  SerializeInputStream(aStream, stream, fds);
 
-  FallibleTArray<uint8_t> fallibleArray;
-  if (!fallibleArray.InsertElementsAt(0, aData, aByteLength)) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
+  MOZ_ASSERT(fds.IsEmpty());
 
-  InfallibleTArray<uint8_t> array;
-  array.SwapElements(fallibleArray);
-  SendDataWithAddress(array, *aAddr);
+  SendOutgoingData(UDPData(stream), UDPSocketAddr(UDPAddressInfo(nsCString(aHost), aPort)));
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-UDPSocketChild::GetLocalPort(uint16_t *aLocalPort)
+UDPSocketChild::JoinMulticast(const nsACString& aMulticastAddress,
+                              const nsACString& aInterface)
+{
+  SendJoinMulticast(nsCString(aMulticastAddress), nsCString(aInterface));
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+UDPSocketChild::LeaveMulticast(const nsACString& aMulticastAddress,
+                               const nsACString& aInterface)
+{
+  SendLeaveMulticast(nsCString(aMulticastAddress), nsCString(aInterface));
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+UDPSocketChild::GetLocalPort(uint16_t* aLocalPort)
 {
   NS_ENSURE_ARG_POINTER(aLocalPort);
 
   *aLocalPort = mLocalPort;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-UDPSocketChild::GetLocalAddress(nsACString &aLocalAddress)
+UDPSocketChild::GetLocalAddress(nsACString& aLocalAddress)
 {
   aLocalAddress = mLocalAddress;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-UDPSocketChild::SetFilterName(const nsACString &aFilterName)
+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)
+UDPSocketChild::GetFilterName(nsACString& aFilterName)
 {
   aFilterName = mFilterName;
   return NS_OK;
 }
 
 // PUDPSocketChild Methods
 bool
-UDPSocketChild::RecvCallback(const nsCString &aType,
-                             const UDPCallbackData &aData,
-                             const nsCString &aState)
+UDPSocketChild::RecvCallbackOpened(const UDPAddressInfo& aAddressInfo)
 {
-  if (NS_FAILED(mSocket->UpdateReadyState(aState)))
-    NS_ERROR("Shouldn't fail!");
+  mLocalAddress = aAddressInfo.addr();
+  mLocalPort = aAddressInfo.port();
+
+  nsresult rv = mSocket->CallListenerOpened();
+  mozilla::unused << NS_WARN_IF(NS_FAILED(rv));
+
+  return true;
+}
+
+bool
+UDPSocketChild::RecvCallbackClosed()
+{
+  nsresult rv = mSocket->CallListenerClosed();
+  mozilla::unused << NS_WARN_IF(NS_FAILED(rv));
 
-  nsresult rv = NS_ERROR_FAILURE;
-  if (aData.type() == UDPCallbackData::Tvoid_t) {
-    rv = mSocket->CallListenerVoid(aType);
-  } else if (aData.type() == UDPCallbackData::TUDPError) {
-    const UDPError& err(aData.get_UDPError());
-    rv = mSocket->CallListenerError(aType, err.message(), err.filename(),
-                                    err.lineNumber(), err.columnNumber());
-  } else if (aData.type() == UDPCallbackData::TUDPMessage) {
-    const UDPMessage& message(aData.get_UDPMessage());
-    InfallibleTArray<uint8_t> data(message.data());
-    rv = mSocket->CallListenerReceivedData(aType, message.fromAddr(), message.port(),
-                                           data.Elements(), data.Length());
-  } else if (aData.type() == UDPCallbackData::TUDPAddressInfo) {
-    //update local address and port.
-    const UDPAddressInfo& addressInfo(aData.get_UDPAddressInfo());
-    mLocalAddress = addressInfo.local();
-    mLocalPort = addressInfo.port();
-    rv = mSocket->CallListenerVoid(aType);
-  } else if (aData.type() == UDPCallbackData::TUDPSendResult) {
-    const UDPSendResult& returnValue(aData.get_UDPSendResult());
-    rv = mSocket->CallListenerSent(aType, returnValue.value());
-  } else {
-    MOZ_ASSERT(false, "Invalid callback type!");
-  }
+  return true;
+}
+
+bool
+UDPSocketChild::RecvCallbackReceivedData(const UDPAddressInfo& aAddressInfo,
+                                         const InfallibleTArray<uint8_t>& aData)
+{
+  nsresult rv = mSocket->CallListenerReceivedData(aAddressInfo.addr(), aAddressInfo.port(),
+                                                  aData.Elements(), aData.Length());
+  mozilla::unused << NS_WARN_IF(NS_FAILED(rv));
 
-  NS_ENSURE_SUCCESS(rv, true);
+  return true;
+}
+
+bool
+UDPSocketChild::RecvCallbackError(const nsCString& aMessage,
+                                  const nsCString& aFilename,
+                                  const uint32_t& aLineNumber)
+{
+  nsresult rv = mSocket->CallListenerError(aMessage, aFilename, aLineNumber);
+  mozilla::unused << NS_WARN_IF(NS_FAILED(rv));
 
   return true;
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/network/src/UDPSocketChild.h
+++ b/dom/network/src/UDPSocketChild.h
@@ -35,20 +35,29 @@ class UDPSocketChild : public mozilla::n
 {
 public:
   NS_DECL_NSIUDPSOCKETCHILD
   NS_IMETHOD_(MozExternalRefCountType) Release() MOZ_OVERRIDE;
 
   UDPSocketChild();
   virtual ~UDPSocketChild();
 
-  virtual bool RecvCallback(const nsCString& aType,
-                            const UDPCallbackData& aData,
-                            const nsCString& aState) MOZ_OVERRIDE;
+  virtual bool RecvCallbackOpened(const UDPAddressInfo& aAddressInfo) MOZ_OVERRIDE;
+  virtual bool RecvCallbackClosed() MOZ_OVERRIDE;
+  virtual bool RecvCallbackReceivedData(const UDPAddressInfo& aAddressInfo,
+                                        const InfallibleTArray<uint8_t>& aData) MOZ_OVERRIDE;
+  virtual bool RecvCallbackError(const nsCString& aMessage,
+                                 const nsCString& aFilename,
+                                 const uint32_t& aLineNumber) MOZ_OVERRIDE;
+
 private:
+  nsresult SendDataInternal(const UDPSocketAddr& aAddr,
+                            const uint8_t* aData,
+                            const uint32_t aByteLength);
+
   uint16_t mLocalPort;
   nsCString mLocalAddress;
   nsCString mFilterName;
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/network/src/UDPSocketParent.cpp
+++ b/dom/network/src/UDPSocketParent.cpp
@@ -4,191 +4,289 @@
  * 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"
 #include "nsINetAddr.h"
+#include "mozilla/AppProcessChecker.h"
 #include "mozilla/unused.h"
+#include "mozilla/ipc/InputStreamUtils.h"
 #include "mozilla/net/DNS.h"
+#include "mozilla/net/NeckoCommon.h"
+#include "mozilla/net/PNeckoParent.h"
 
 namespace mozilla {
 namespace dom {
 
-static void
-FireInternalError(mozilla::net::PUDPSocketParent *aActor, uint32_t aLineNo)
-{
-  mozilla::unused <<
-      aActor->SendCallback(NS_LITERAL_CSTRING("onerror"),
-                          UDPError(NS_LITERAL_CSTRING("Internal error"),
-                                   NS_LITERAL_CSTRING(__FILE__), aLineNo, 0),
-                          NS_LITERAL_CSTRING("connecting"));
-}
-
-static nsresult
-ConvertNetAddrToString(mozilla::net::NetAddr &netAddr, nsACString *address, uint16_t *port)
-{
-  NS_ENSURE_ARG_POINTER(address);
-  NS_ENSURE_ARG_POINTER(port);
-
-  *port = 0;
-  uint32_t bufSize = 0;
-
-  switch(netAddr.raw.family) {
-  case AF_INET:
-    *port = PR_ntohs(netAddr.inet.port);
-    bufSize = mozilla::net::kIPv4CStrBufSize;
-    break;
-  case AF_INET6:
-    *port = PR_ntohs(netAddr.inet6.port);
-    bufSize = mozilla::net::kIPv6CStrBufSize;
-    break;
-  default:
-    //impossible
-    MOZ_ASSERT(false, "Unexpected address family");
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  address->SetCapacity(bufSize);
-  NetAddrToString(&netAddr, address->BeginWriting(), bufSize);
-  address->SetLength(strlen(address->BeginReading()));
-
-  return NS_OK;
-}
-
 NS_IMPL_ISUPPORTS(UDPSocketParent, nsIUDPSocketListener)
 
 UDPSocketParent::~UDPSocketParent()
 {
 }
 
+bool
+UDPSocketParent::Init(const nsACString& aFilter)
+{
+  if (!aFilter.IsEmpty()) {
+    nsAutoCString contractId(NS_NETWORK_UDP_SOCKET_FILTER_HANDLER_PREFIX);
+    contractId.Append(aFilter);
+    nsCOMPtr<nsIUDPSocketFilterHandler> filterHandler =
+      do_GetService(contractId.get());
+    if (filterHandler) {
+      nsresult rv = filterHandler->NewFilter(getter_AddRefs(mFilter));
+      if (NS_FAILED(rv)) {
+        printf_stderr("Cannot create filter that content specified. "
+                      "filter name: %s, error code: %d.", aFilter.BeginReading(), rv);
+        return false;
+      }
+    } else {
+      printf_stderr("Content doesn't have a valid filter. "
+                    "filter name: %s.", aFilter.BeginReading());
+      return false;
+    }
+  }
+  return true;
+}
+
 // PUDPSocketParent methods
 
 bool
-UDPSocketParent::Init(const nsCString &aHost, const uint16_t aPort)
+UDPSocketParent::RecvBind(const UDPAddressInfo& aAddressInfo,
+                          const bool& aAddressReuse, const bool& aLoopback)
+{
+  // We don't have browser actors in xpcshell, and hence can't run automated
+  // tests without this loophole.
+  if (net::UsingNeckoIPCSecurity() && !mFilter &&
+      !AssertAppProcessPermission(Manager()->Manager(), "udp-socket")) {
+    FireInternalError(__LINE__);
+    return false;
+  }
+
+  if (NS_FAILED(BindInternal(aAddressInfo.addr(), aAddressInfo.port(), aAddressReuse, aLoopback))) {
+    FireInternalError(__LINE__);
+    return true;
+  }
+
+  nsCOMPtr<nsINetAddr> localAddr;
+  mSocket->GetLocalAddr(getter_AddRefs(localAddr));
+
+  nsCString addr;
+  if (NS_FAILED(localAddr->GetAddress(addr))) {
+    FireInternalError(__LINE__);
+    return true;
+  }
+
+  uint16_t port;
+  if (NS_FAILED(localAddr->GetPort(&port))) {
+    FireInternalError(__LINE__);
+    return true;
+  }
+
+  mozilla::unused << SendCallbackOpened(UDPAddressInfo(addr, port));
+
+  return true;
+}
+
+nsresult
+UDPSocketParent::BindInternal(const nsCString& aHost, const uint16_t& aPort,
+                              const bool& aAddressReuse, const bool& aLoopback)
 {
   nsresult rv;
-  NS_ASSERTION(mFilter, "No packet filter");
 
   nsCOMPtr<nsIUDPSocket> sock =
       do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv);
-  if (NS_FAILED(rv)) {
-    FireInternalError(this, __LINE__);
-    return true;
+
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
   }
 
   if (aHost.IsEmpty()) {
-    rv = sock->Init(aPort, false);
+    rv = sock->Init(aPort, false, aAddressReuse, /* optional_argc = */ 1);
   } else {
     PRNetAddr prAddr;
     PR_InitializeNetAddr(PR_IpAddrAny, aPort, &prAddr);
     PRStatus status = PR_StringToNetAddr(aHost.BeginReading(), &prAddr);
     if (status != PR_SUCCESS) {
-      FireInternalError(this, __LINE__);
-      return true;
+      return NS_ERROR_FAILURE;
     }
 
     mozilla::net::NetAddr addr;
     PRNetAddrToNetAddr(&prAddr, &addr);
-    rv = sock->InitWithAddress(&addr);
+    rv = sock->InitWithAddress(&addr, aAddressReuse, /* optional_argc = */ 1);
+  }
+
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
   }
 
-  if (NS_FAILED(rv)) {
-    FireInternalError(this, __LINE__);
-    return true;
+  rv = sock->SetMulticastLoopback(aLoopback);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  // register listener
+  rv = sock->AsyncListen(this);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
   }
 
   mSocket = sock;
 
-  net::NetAddr localAddr;
-  mSocket->GetAddress(&localAddr);
+  return NS_OK;
+}
+
+bool
+UDPSocketParent::RecvOutgoingData(const UDPData& aData,
+                                  const UDPSocketAddr& aAddr)
+{
+  MOZ_ASSERT(mSocket);
+
+  nsresult rv;
+  if (mFilter) {
+    // TODO, Bug 933102, filter packets that are sent with hostname.
+    // Until then we simply throw away packets that are sent to a hostname.
+    if (aAddr.type() != UDPSocketAddr::TNetAddr) {
+      return true;
+    }
+
+    // TODO, Packet filter doesn't support input stream yet.
+    if (aData.type() != UDPData::TArrayOfuint8_t) {
+      return true;
+    }
+
+    bool allowed;
+    const InfallibleTArray<uint8_t>& data(aData.get_ArrayOfuint8_t());
+    rv = mFilter->FilterPacket(&aAddr.get_NetAddr(), data.Elements(),
+                               data.Length(), nsIUDPSocketFilter::SF_OUTGOING,
+                               &allowed);
+
+    // Sending unallowed data, kill content.
+    if (NS_WARN_IF(NS_FAILED(rv)) || !allowed) {
+      return false;
+    }
+  }
+
+  switch(aData.type()) {
+    case UDPData::TArrayOfuint8_t:
+      Send(aData.get_ArrayOfuint8_t(), aAddr);
+      break;
+    case UDPData::TInputStreamParams:
+      Send(aData.get_InputStreamParams(), aAddr);
+      break;
+    default:
+      MOZ_ASSERT(false, "Invalid data type!");
+      return true;
+  }
+
+  return true;
+}
 
-  uint16_t port;
-  nsCString addr;
-  rv = ConvertNetAddrToString(localAddr, &addr, &port);
+void
+UDPSocketParent::Send(const InfallibleTArray<uint8_t>& aData,
+                      const UDPSocketAddr& aAddr)
+{
+  nsresult rv;
+  uint32_t count;
+  switch(aAddr.type()) {
+    case UDPSocketAddr::TUDPAddressInfo: {
+      const UDPAddressInfo& addrInfo(aAddr.get_UDPAddressInfo());
+      rv = mSocket->Send(addrInfo.addr(), addrInfo.port(),
+                         aData.Elements(), aData.Length(), &count);
+      break;
+    }
+    case UDPSocketAddr::TNetAddr: {
+      const NetAddr& addr(aAddr.get_NetAddr());
+      rv = mSocket->SendWithAddress(&addr, aData.Elements(),
+                                    aData.Length(), &count);
+      break;
+    }
+    default:
+      MOZ_ASSERT(false, "Invalid address type!");
+      return;
+  }
+
+  if (NS_WARN_IF(NS_FAILED(rv)) || count == 0) {
+    FireInternalError(__LINE__);
+  }
+}
+
+void
+UDPSocketParent::Send(const InputStreamParams& aStream,
+                      const UDPSocketAddr& aAddr)
+{
+  nsTArray<mozilla::ipc::FileDescriptor> fds;
+  nsCOMPtr<nsIInputStream> stream = DeserializeInputStream(aStream, fds);
+
+  if (NS_WARN_IF(!stream)) {
+    return;
+  }
+
+  nsresult rv;
+  switch(aAddr.type()) {
+    case UDPSocketAddr::TUDPAddressInfo: {
+      const UDPAddressInfo& addrInfo(aAddr.get_UDPAddressInfo());
+      rv = mSocket->SendBinaryStream(addrInfo.addr(), addrInfo.port(), stream);
+      break;
+    }
+    case UDPSocketAddr::TNetAddr: {
+      const NetAddr& addr(aAddr.get_NetAddr());
+      rv = mSocket->SendBinaryStreamWithAddress(&addr, stream);
+      break;
+    }
+    default:
+      MOZ_ASSERT(false, "Invalid address type!");
+      return;
+  }
 
   if (NS_FAILED(rv)) {
-    FireInternalError(this, __LINE__);
-    return true;
+    FireInternalError(__LINE__);
   }
+}
 
-  // register listener
-  mSocket->AsyncListen(this);
-  mozilla::unused <<
-      PUDPSocketParent::SendCallback(NS_LITERAL_CSTRING("onopen"),
-                                     UDPAddressInfo(addr, port),
-                                     NS_LITERAL_CSTRING("connected"));
+bool
+UDPSocketParent::RecvJoinMulticast(const nsCString& aMulticastAddress,
+                                   const nsCString& aInterface)
+{
+  nsresult rv = mSocket->JoinMulticast(aMulticastAddress, aInterface);
+
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    FireInternalError(__LINE__);
+  }
 
   return true;
 }
 
 bool
-UDPSocketParent::RecvData(const InfallibleTArray<uint8_t> &aData,
-                          const nsCString& aRemoteAddress,
-                          const uint16_t& aPort)
+UDPSocketParent::RecvLeaveMulticast(const nsCString& aMulticastAddress,
+                                    const nsCString& aInterface)
 {
-  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(),
-                              aData.Length(), &count);
-  mozilla::unused <<
-      PUDPSocketParent::SendCallback(NS_LITERAL_CSTRING("onsent"),
-                                     UDPSendResult(rv),
-                                     NS_LITERAL_CSTRING("connected"));
-  NS_ENSURE_SUCCESS(rv, true);
-  NS_ENSURE_TRUE(count > 0, true);
-  return true;
-#endif
-}
+  nsresult rv = mSocket->LeaveMulticast(aMulticastAddress, aInterface);
 
-bool
-UDPSocketParent::RecvDataWithAddress(const InfallibleTArray<uint8_t>& aData,
-                                     const mozilla::net::NetAddr& aAddr)
-{
-  NS_ENSURE_TRUE(mSocket, true);
-  NS_ASSERTION(mFilter, "No packet filter");
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    FireInternalError(__LINE__);
+  }
 
-  uint32_t 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),
-                                     NS_LITERAL_CSTRING("connected"));
-  NS_ENSURE_SUCCESS(rv, true);
-  NS_ENSURE_TRUE(count > 0, true);
   return true;
 }
 
 bool
 UDPSocketParent::RecvClose()
 {
-  NS_ENSURE_TRUE(mSocket, true);
+  if (!mSocket) {
+    return true;
+  }
+
   nsresult rv = mSocket->Close();
   mSocket = nullptr;
-  NS_ENSURE_SUCCESS(rv, true);
+
+  mozilla::unused << NS_WARN_IF(NS_FAILED(rv));
+
   return true;
 }
 
 bool
 UDPSocketParent::RecvRequestDelete()
 {
   mozilla::unused << Send__delete__(this);
   return true;
@@ -209,66 +307,73 @@ UDPSocketParent::ActorDestroy(ActorDestr
 
 NS_IMETHODIMP
 UDPSocketParent::OnPacketReceived(nsIUDPSocket* aSocket, nsIUDPMessage* aMessage)
 {
   // receiving packet from remote host, forward the message content to child process
   if (!mIPCOpen) {
     return NS_OK;
   }
-  NS_ASSERTION(mFilter, "No packet filter");
 
   uint16_t port;
   nsCString ip;
   nsCOMPtr<nsINetAddr> fromAddr;
   aMessage->GetFromAddr(getter_AddRefs(fromAddr));
   fromAddr->GetPort(&port);
   fromAddr->GetAddress(ip);
 
   nsCString data;
   aMessage->GetData(data);
 
   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);
+  if (mFilter) {
+    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.
+    if (NS_WARN_IF(NS_FAILED(rv)) || !allowed) {
+      return NS_OK;
+    }
+  }
 
   FallibleTArray<uint8_t> fallibleArray;
   if (!fallibleArray.InsertElementsAt(0, buffer, len)) {
-    FireInternalError(this, __LINE__);
+    FireInternalError(__LINE__);
     return NS_ERROR_OUT_OF_MEMORY;
   }
   InfallibleTArray<uint8_t> infallibleArray;
   infallibleArray.SwapElements(fallibleArray);
 
   // compose callback
-  mozilla::unused <<
-      PUDPSocketParent::SendCallback(NS_LITERAL_CSTRING("ondata"),
-                                     UDPMessage(ip, port, infallibleArray),
-                                     NS_LITERAL_CSTRING("connected"));
+  mozilla::unused << SendCallbackReceivedData(UDPAddressInfo(ip, port), infallibleArray);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 UDPSocketParent::OnStopListening(nsIUDPSocket* aSocket, nsresult aStatus)
 {
   // underlying socket is dead, send state update to child process
   if (mIPCOpen) {
-    mozilla::unused <<
-        PUDPSocketParent::SendCallback(NS_LITERAL_CSTRING("onclose"),
-                                       mozilla::void_t(),
-                                       NS_LITERAL_CSTRING("closed"));
+    mozilla::unused << SendCallbackClosed();
   }
   return NS_OK;
 }
 
+void
+UDPSocketParent::FireInternalError(uint32_t aLineNo)
+{
+  if (!mIPCOpen) {
+    return;
+  }
+
+  mozilla::unused << SendCallbackError(NS_LITERAL_CSTRING("Internal error"),
+                                       NS_LITERAL_CSTRING(__FILE__), aLineNo);
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/network/src/UDPSocketParent.h
+++ b/dom/network/src/UDPSocketParent.h
@@ -17,34 +17,44 @@ namespace dom {
 
 class UDPSocketParent : public mozilla::net::PUDPSocketParent
                       , public nsIUDPSocketListener
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIUDPSOCKETLISTENER
 
-  explicit UDPSocketParent(nsIUDPSocketFilter* filter) :
-    mIPCOpen(true),
-    mFilter(filter) {}
+  UDPSocketParent() :
+    mIPCOpen(true) {}
+
+  bool Init(const nsACString& aFilter);
 
-  bool Init(const nsCString& aHost, const uint16_t aPort);
+  virtual bool RecvBind(const UDPAddressInfo& aAddressInfo,
+                        const bool& aAddressReuse, const bool& aLoopback) MOZ_OVERRIDE;
+
+  virtual bool RecvOutgoingData(const UDPData& aData, const UDPSocketAddr& aAddr) MOZ_OVERRIDE;
 
   virtual bool RecvClose() MOZ_OVERRIDE;
-  virtual bool RecvData(const InfallibleTArray<uint8_t>& aData,
-                        const nsCString& aRemoteAddress,
-                        const uint16_t& aPort) MOZ_OVERRIDE;
-  virtual bool RecvDataWithAddress( const InfallibleTArray<uint8_t>& data,
-                                    const mozilla::net::NetAddr& addr);
+
   virtual bool RecvRequestDelete() MOZ_OVERRIDE;
+  virtual bool RecvJoinMulticast(const nsCString& aMulticastAddress,
+                                 const nsCString& aInterface) MOZ_OVERRIDE;
+  virtual bool RecvLeaveMulticast(const nsCString& aMulticastAddress,
+                                  const nsCString& aInterface) MOZ_OVERRIDE;
 
 private:
   virtual ~UDPSocketParent();
 
   virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
+  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);
+
+  void FireInternalError(uint32_t aLineNo);
 
   bool mIPCOpen;
   nsCOMPtr<nsIUDPSocket> mSocket;
   nsCOMPtr<nsIUDPSocketFilter> mFilter;
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/media/mtransport/nr_socket_prsock.cpp
+++ b/media/mtransport/nr_socket_prsock.cpp
@@ -700,42 +700,37 @@ NrSocketIpc::NrSocketIpc(const nsCOMPtr<
     : err_(false),
       state_(NR_INIT),
       main_thread_(main_thread),
       monitor_("NrSocketIpc") {
 }
 
 // IUDPSocketInternal interfaces
 // callback while error happened in UDP socket operation
-NS_IMETHODIMP NrSocketIpc::CallListenerError(const nsACString &type,
-                                             const nsACString &message,
+NS_IMETHODIMP NrSocketIpc::CallListenerError(const nsACString &message,
                                              const nsACString &filename,
-                                             uint32_t line_number,
-                                             uint32_t column_number) {
+                                             uint32_t line_number) {
   ASSERT_ON_THREAD(main_thread_);
-  MOZ_ASSERT(type.EqualsLiteral("onerror"));
 
-  r_log(LOG_GENERIC, LOG_ERR, "UDP socket error:%s at %s:%d:%d",
-        message.BeginReading(), filename.BeginReading(),
-        line_number, column_number);
+  r_log(LOG_GENERIC, LOG_ERR, "UDP socket error:%s at %s:%d",
+        message.BeginReading(), filename.BeginReading(), line_number );
 
   ReentrantMonitorAutoEnter mon(monitor_);
   err_ = true;
   monitor_.NotifyAll();
 
   return NS_OK;
 }
 
 // callback while receiving UDP packet
-NS_IMETHODIMP NrSocketIpc::CallListenerReceivedData(const nsACString &type,
-                                                    const nsACString &host,
-                                                    uint16_t port, uint8_t *data,
+NS_IMETHODIMP NrSocketIpc::CallListenerReceivedData(const nsACString &host,
+                                                    uint16_t port,
+                                                    const uint8_t *data,
                                                     uint32_t data_length) {
   ASSERT_ON_THREAD(main_thread_);
-  MOZ_ASSERT(type.EqualsLiteral("ondata"));
 
   PRNetAddr addr;
   memset(&addr, 0, sizeof(addr));
 
   {
     ReentrantMonitorAutoEnter mon(monitor_);
 
     if (PR_SUCCESS != PR_StringToNetAddr(host.BeginReading(), &addr)) {
@@ -758,99 +753,78 @@ NS_IMETHODIMP NrSocketIpc::CallListenerR
   RUN_ON_THREAD(sts_thread_,
                 mozilla::WrapRunnable(nsRefPtr<NrSocketIpc>(this),
                                       &NrSocketIpc::recv_callback_s,
                                       msg),
                 NS_DISPATCH_NORMAL);
   return NS_OK;
 }
 
-// callback while UDP socket is opened or closed
-NS_IMETHODIMP NrSocketIpc::CallListenerVoid(const nsACString &type) {
+// callback while UDP socket is opened
+NS_IMETHODIMP NrSocketIpc::CallListenerOpened() {
   ASSERT_ON_THREAD(main_thread_);
-  if (type.EqualsLiteral("onopen")) {
-    ReentrantMonitorAutoEnter mon(monitor_);
-
-    uint16_t port;
-    if (NS_FAILED(socket_child_->GetLocalPort(&port))) {
-      err_ = true;
-      MOZ_ASSERT(false, "Failed to get local port");
-      return NS_OK;
-    }
+  ReentrantMonitorAutoEnter mon(monitor_);
 
-    nsAutoCString address;
-    if(NS_FAILED(socket_child_->GetLocalAddress(address))) {
-      err_ = true;
-      MOZ_ASSERT(false, "Failed to get local address");
-      return NS_OK;
-    }
+  uint16_t port;
+  if (NS_FAILED(socket_child_->GetLocalPort(&port))) {
+    err_ = true;
+    MOZ_ASSERT(false, "Failed to get local port");
+    return NS_OK;
+  }
 
-    PRNetAddr praddr;
-    if (PR_SUCCESS != PR_InitializeNetAddr(PR_IpAddrAny, port, &praddr)) {
-      err_ = true;
-      MOZ_ASSERT(false, "Failed to set port in PRNetAddr");
-      return NS_OK;
-    }
+  nsAutoCString address;
+  if(NS_FAILED(socket_child_->GetLocalAddress(address))) {
+    err_ = true;
+    MOZ_ASSERT(false, "Failed to get local address");
+    return NS_OK;
+  }
 
-    if (PR_SUCCESS != PR_StringToNetAddr(address.BeginReading(), &praddr)) {
-      err_ = true;
-      MOZ_ASSERT(false, "Failed to convert local host to PRNetAddr");
-      return NS_OK;
-    }
+  PRNetAddr praddr;
+  if (PR_SUCCESS != PR_InitializeNetAddr(PR_IpAddrAny, port, &praddr)) {
+    err_ = true;
+    MOZ_ASSERT(false, "Failed to set port in PRNetAddr");
+    return NS_OK;
+  }
 
-    nr_transport_addr expected_addr;
-    if(nr_transport_addr_copy(&expected_addr, &my_addr_)) {
-      err_ = true;
-      MOZ_ASSERT(false, "Failed to copy my_addr_");
-    }
+  if (PR_SUCCESS != PR_StringToNetAddr(address.BeginReading(), &praddr)) {
+    err_ = true;
+    MOZ_ASSERT(false, "Failed to convert local host to PRNetAddr");
+    return NS_OK;
+  }
 
-    if (nr_praddr_to_transport_addr(&praddr, &my_addr_, IPPROTO_UDP, 1)) {
-      err_ = true;
-      MOZ_ASSERT(false, "Failed to copy local host to my_addr_");
-    }
+  nr_transport_addr expected_addr;
+  if(nr_transport_addr_copy(&expected_addr, &my_addr_)) {
+    err_ = true;
+    MOZ_ASSERT(false, "Failed to copy my_addr_");
+  }
 
-    if (nr_transport_addr_cmp(&expected_addr, &my_addr_,
-                              NR_TRANSPORT_ADDR_CMP_MODE_ADDR)) {
-      err_ = true;
-      MOZ_ASSERT(false, "Address of opened socket is not expected");
-    }
+  if (nr_praddr_to_transport_addr(&praddr, &my_addr_, IPPROTO_UDP, 1)) {
+    err_ = true;
+    MOZ_ASSERT(false, "Failed to copy local host to my_addr_");
+  }
 
-    mon.NotifyAll();
-  } else if (type.EqualsLiteral("onclose")) {
-    // Already handled in UpdateReadyState, nothing to do here
-  } else {
-    MOZ_ASSERT(false, "Received unexpected event");
+  if (nr_transport_addr_cmp(&expected_addr, &my_addr_,
+                            NR_TRANSPORT_ADDR_CMP_MODE_ADDR)) {
+    err_ = true;
+    MOZ_ASSERT(false, "Address of opened socket is not expected");
   }
 
+  mon.NotifyAll();
+
   return NS_OK;
 }
 
-// callback while UDP packet is sent
-NS_IMETHODIMP NrSocketIpc::CallListenerSent(const nsACString &type,
-                                            nsresult result) {
-  ASSERT_ON_THREAD(main_thread_);
-  MOZ_ASSERT(type.EqualsLiteral("onsent"));
-
-  if (NS_FAILED(result)) {
-    ReentrantMonitorAutoEnter mon(monitor_);
-    err_ = true;
-  }
-  return NS_OK;
-}
-
-// callback for state update after every socket operation
-NS_IMETHODIMP NrSocketIpc::UpdateReadyState(const nsACString &readyState) {
+// callback while UDP socket is closed
+NS_IMETHODIMP NrSocketIpc::CallListenerClosed() {
   ASSERT_ON_THREAD(main_thread_);
 
   ReentrantMonitorAutoEnter mon(monitor_);
 
-  if (readyState.EqualsLiteral("closed")) {
-    MOZ_ASSERT(state_ == NR_CONNECTED || state_ == NR_CLOSING);
-    state_ = NR_CLOSED;
-  }
+  MOZ_ASSERT(state_ == NR_CONNECTED || state_ == NR_CLOSING);
+  state_ = NR_CLOSED;
 
   return NS_OK;
 }
 
 // nr_socket public APIs
 int NrSocketIpc::create(nr_transport_addr *addr) {
   ASSERT_ON_THREAD(sts_thread_);
 
@@ -1030,24 +1004,30 @@ void NrSocketIpc::create_m(const nsACStr
 
   ReentrantMonitorAutoEnter mon(monitor_);
 
   nsresult rv;
   nsCOMPtr<nsIUDPSocketChild> socketChild = do_CreateInstance("@mozilla.org/udp-socket-child;1", &rv);
   if (NS_FAILED(rv)) {
     err_ = true;
     MOZ_ASSERT(false, "Failed to create UDPSocketChild");
+    mon.NotifyAll();
+    return;
   }
 
   socket_child_ = new nsMainThreadPtrHolder<nsIUDPSocketChild>(socketChild);
   socket_child_->SetFilterName(nsCString("stun"));
 
-  if (NS_FAILED(socket_child_->Bind(this, host, port))) {
+  if (NS_FAILED(socket_child_->Bind(this, host, port,
+                                    /* reuse = */ false,
+                                    /* loopback = */ false))) {
     err_ = true;
     MOZ_ASSERT(false, "Failed to create UDP socket");
+    mon.NotifyAll();
+    return;
   }
 }
 
 void NrSocketIpc::sendto_m(const net::NetAddr &addr, nsAutoPtr<DataBuffer> buf) {
   ASSERT_ON_THREAD(main_thread_);
 
   MOZ_ASSERT(socket_child_);
 
--- a/netwerk/ipc/NeckoChild.cpp
+++ b/netwerk/ipc/NeckoChild.cpp
@@ -231,19 +231,17 @@ bool
 NeckoChild::DeallocPTCPServerSocketChild(PTCPServerSocketChild* child)
 {
   TCPServerSocketChild* p = static_cast<TCPServerSocketChild*>(child);
   p->ReleaseIPDLReference();
   return true;
 }
 
 PUDPSocketChild*
-NeckoChild::AllocPUDPSocketChild(const nsCString& aHost,
-                                 const uint16_t& aPort,
-                                 const nsCString& aFilter)
+NeckoChild::AllocPUDPSocketChild(const nsCString& aFilter)
 {
   NS_NOTREACHED("AllocPUDPSocket should not be called");
   return nullptr;
 }
 
 bool
 NeckoChild::DeallocPUDPSocketChild(PUDPSocketChild* child)
 {
--- a/netwerk/ipc/NeckoChild.h
+++ b/netwerk/ipc/NeckoChild.h
@@ -46,19 +46,17 @@ protected:
   virtual PTCPSocketChild* AllocPTCPSocketChild(const nsString& host,
                                                 const uint16_t& port) MOZ_OVERRIDE;
   virtual bool DeallocPTCPSocketChild(PTCPSocketChild*) MOZ_OVERRIDE;
   virtual PTCPServerSocketChild*
     AllocPTCPServerSocketChild(const uint16_t& aLocalPort,
                                const uint16_t& aBacklog,
                                const nsString& aBinaryType) MOZ_OVERRIDE;
   virtual bool DeallocPTCPServerSocketChild(PTCPServerSocketChild*) MOZ_OVERRIDE;
-  virtual PUDPSocketChild* AllocPUDPSocketChild(const nsCString& aHost,
-                                                const uint16_t& aPort,
-                                                const nsCString& aFilter) MOZ_OVERRIDE;
+  virtual PUDPSocketChild* AllocPUDPSocketChild(const nsCString& aFilter) MOZ_OVERRIDE;
   virtual bool DeallocPUDPSocketChild(PUDPSocketChild*) MOZ_OVERRIDE;
   virtual PDNSRequestChild* AllocPDNSRequestChild(const nsCString& aHost,
                                                   const uint32_t& aFlags) MOZ_OVERRIDE;
   virtual bool DeallocPDNSRequestChild(PDNSRequestChild*) MOZ_OVERRIDE;
   virtual PRemoteOpenFileChild*
     AllocPRemoteOpenFileChild(const SerializedLoadContext& aSerialized,
                               const URIParams&,
                               const OptionalURIParams&) MOZ_OVERRIDE;
--- a/netwerk/ipc/NeckoParent.cpp
+++ b/netwerk/ipc/NeckoParent.cpp
@@ -26,17 +26,16 @@
 #include "mozilla/dom/network/TCPServerSocketParent.h"
 #include "mozilla/dom/network/UDPSocketParent.h"
 #include "mozilla/ipc/URIUtils.h"
 #include "mozilla/LoadContext.h"
 #include "mozilla/AppProcessChecker.h"
 #include "nsPrintfCString.h"
 #include "nsHTMLDNSPrefetch.h"
 #include "nsIAppsService.h"
-#include "nsIUDPSocketFilter.h"
 #include "nsEscape.h"
 #include "RemoteOpenFileParent.h"
 #include "SerializedLoadContext.h"
 #include "nsAuthInformationHolder.h"
 #include "nsIAuthPromptCallback.h"
 
 using mozilla::dom::ContentParent;
 using mozilla::dom::TabParent;
@@ -440,55 +439,28 @@ bool
 NeckoParent::DeallocPTCPServerSocketParent(PTCPServerSocketParent* actor)
 {
   TCPServerSocketParent* p = static_cast<TCPServerSocketParent*>(actor);
    p->ReleaseIPDLReference();
   return true;
 }
 
 PUDPSocketParent*
-NeckoParent::AllocPUDPSocketParent(const nsCString& aHost,
-                                   const uint16_t& aPort,
-                                   const nsCString& aFilter)
+NeckoParent::AllocPUDPSocketParent(const nsCString& /* unused */)
 {
-  UDPSocketParent* p = nullptr;
-
-  // Only allow socket if it specifies a valid packet filter.
-  nsAutoCString contractId(NS_NETWORK_UDP_SOCKET_FILTER_HANDLER_PREFIX);
-  contractId.Append(aFilter);
+  nsRefPtr<UDPSocketParent> p = new UDPSocketParent();
 
-  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;
+  return p.forget().take();
 }
 
 bool
 NeckoParent::RecvPUDPSocketConstructor(PUDPSocketParent* aActor,
-                                       const nsCString& aHost,
-                                       const uint16_t& aPort,
                                        const nsCString& aFilter)
 {
-  return static_cast<UDPSocketParent*>(aActor)->Init(aHost, aPort);
+  return static_cast<UDPSocketParent*>(aActor)->Init(aFilter);
 }
 
 bool
 NeckoParent::DeallocPUDPSocketParent(PUDPSocketParent* actor)
 {
   UDPSocketParent* p = static_cast<UDPSocketParent*>(actor);
   p->Release();
   return true;
--- a/netwerk/ipc/NeckoParent.h
+++ b/netwerk/ipc/NeckoParent.h
@@ -148,23 +148,18 @@ protected:
     AllocPTCPServerSocketParent(const uint16_t& aLocalPort,
                                 const uint16_t& aBacklog,
                                 const nsString& aBinaryType) MOZ_OVERRIDE;
   virtual bool RecvPTCPServerSocketConstructor(PTCPServerSocketParent*,
                                                const uint16_t& aLocalPort,
                                                const uint16_t& aBacklog,
                                                const nsString& aBinaryType) MOZ_OVERRIDE;
   virtual bool DeallocPTCPServerSocketParent(PTCPServerSocketParent*) MOZ_OVERRIDE;
-  virtual PUDPSocketParent* AllocPUDPSocketParent(const nsCString& aHost,
-                                                  const uint16_t& aPort,
-                                                  const nsCString& aFilter) MOZ_OVERRIDE;
-  virtual bool RecvPUDPSocketConstructor(PUDPSocketParent*,
-                                         const nsCString& aHost,
-                                         const uint16_t& aPort,
-                                         const nsCString& aFilter) MOZ_OVERRIDE;
+  virtual PUDPSocketParent* AllocPUDPSocketParent(const nsCString& aFilter) MOZ_OVERRIDE;
+  virtual bool RecvPUDPSocketConstructor(PUDPSocketParent*, const nsCString& aFilter) MOZ_OVERRIDE;
   virtual bool DeallocPUDPSocketParent(PUDPSocketParent*) MOZ_OVERRIDE;
   virtual PDNSRequestParent* AllocPDNSRequestParent(const nsCString& aHost,
                                                     const uint32_t& aFlags) MOZ_OVERRIDE;
   virtual bool RecvPDNSRequestConstructor(PDNSRequestParent* actor,
                                           const nsCString& hostName,
                                           const uint32_t& flags) MOZ_OVERRIDE;
   virtual bool DeallocPDNSRequestParent(PDNSRequestParent*) MOZ_OVERRIDE;
   virtual bool RecvHTMLDNSPrefetch(const nsString& hostname,
--- a/netwerk/ipc/PNecko.ipdl
+++ b/netwerk/ipc/PNecko.ipdl
@@ -64,17 +64,17 @@ parent:
                SerializedLoadContext loadContext,
                HttpChannelCreationArgs args);
   PWyciwygChannel();
   PFTPChannel(PBrowserOrId browser, SerializedLoadContext loadContext,
               FTPChannelCreationArgs args);
 
   PWebSocket(PBrowserOrId browser, SerializedLoadContext loadContext);
   PTCPServerSocket(uint16_t localPort, uint16_t backlog, nsString binaryType);
-  PUDPSocket(nsCString host, uint16_t port, nsCString filter);
+  PUDPSocket(nsCString filter);
 
   PDNSRequest(nsCString hostName, uint32_t flags);
 
   PRemoteOpenFile(SerializedLoadContext loadContext,
                   URIParams fileuri,
                   OptionalURIParams appuri);
 
   HTMLDNSPrefetch(nsString hostname, uint16_t flags);