Bug 745283 - Part 3: Support send input stream and multicast operation via PUDPSocket.ipdl. r=jduell, r=mt
☠☠ backed out by 5258e5e96848 ☠ ☠
authorShih-Chiang Chien <schien@mozilla.com>
Tue, 06 May 2014 18:32:25 +0800
changeset 223000 fc08327b3d3e0ef355911433ad40874518712e41
parent 222999 ce19c464f5d844f9b027c97773861d347e5b5a4c
child 223001 70bad98676c83b2b3273e8d6ad015917a5947b33
push id3979
push userraliiev@mozilla.com
push dateMon, 13 Oct 2014 16:35:44 +0000
treeherdermozilla-beta@30f2cc610691 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjduell, mt
bugs745283
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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
@@ -695,42 +695,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)) {
@@ -753,99 +748,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_);
 
@@ -1025,24 +999,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);