LCOV - code coverage report
Current view: top level - dom/network - UDPSocketParent.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 270 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 29 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
       5             :  * You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "nsIServiceManager.h"
       8             : #include "UDPSocketParent.h"
       9             : #include "nsComponentManagerUtils.h"
      10             : #include "nsIUDPSocket.h"
      11             : #include "nsINetAddr.h"
      12             : #include "mozilla/Unused.h"
      13             : #include "mozilla/ipc/InputStreamUtils.h"
      14             : #include "mozilla/net/DNS.h"
      15             : #include "mozilla/net/NeckoCommon.h"
      16             : #include "mozilla/net/PNeckoParent.h"
      17             : #include "nsIPermissionManager.h"
      18             : #include "nsIScriptSecurityManager.h"
      19             : #include "mozilla/ipc/PBackgroundParent.h"
      20             : #include "mtransport/runnable_utils.h"
      21             : 
      22             : namespace mozilla {
      23             : namespace dom {
      24             : 
      25           0 : NS_IMPL_ISUPPORTS(UDPSocketParent, nsIUDPSocketListener)
      26             : 
      27           0 : UDPSocketParent::UDPSocketParent(PBackgroundParent* aManager)
      28             :   : mBackgroundManager(aManager)
      29           0 :   , mIPCOpen(true)
      30             : {
      31           0 : }
      32             : 
      33           0 : UDPSocketParent::UDPSocketParent(PNeckoParent* aManager)
      34             :   : mBackgroundManager(nullptr)
      35           0 :   , mIPCOpen(true)
      36             : {
      37           0 : }
      38             : 
      39           0 : UDPSocketParent::~UDPSocketParent()
      40             : {
      41           0 : }
      42             : 
      43             : bool
      44           0 : UDPSocketParent::Init(const IPC::Principal& aPrincipal,
      45             :                       const nsACString& aFilter)
      46             : {
      47           0 :   MOZ_ASSERT_IF(mBackgroundManager, !aPrincipal);
      48             :   // will be used once we move all UDPSocket to PBackground, or
      49             :   // if we add in Principal checking for mtransport
      50           0 :   Unused << mBackgroundManager;
      51             : 
      52           0 :   mPrincipal = aPrincipal;
      53           0 :   if (net::UsingNeckoIPCSecurity() &&
      54           0 :       mPrincipal &&
      55           0 :       !ContentParent::IgnoreIPCPrincipal()) {
      56             :     nsCOMPtr<nsIPermissionManager> permMgr =
      57           0 :       services::GetPermissionManager();
      58           0 :     if (!permMgr) {
      59           0 :       NS_WARNING("No PermissionManager available!");
      60           0 :       return false;
      61             :     }
      62             : 
      63           0 :     uint32_t permission = nsIPermissionManager::DENY_ACTION;
      64           0 :     permMgr->TestExactPermissionFromPrincipal(mPrincipal, "udp-socket",
      65           0 :                                               &permission);
      66           0 :     if (permission != nsIPermissionManager::ALLOW_ACTION) {
      67           0 :       return false;
      68             :     }
      69             :   }
      70             : 
      71           0 :   if (!aFilter.IsEmpty()) {
      72           0 :     nsAutoCString contractId(NS_NETWORK_UDP_SOCKET_FILTER_HANDLER_PREFIX);
      73           0 :     contractId.Append(aFilter);
      74             :     nsCOMPtr<nsISocketFilterHandler> filterHandler =
      75           0 :       do_GetService(contractId.get());
      76           0 :     if (filterHandler) {
      77           0 :       nsresult rv = filterHandler->NewFilter(getter_AddRefs(mFilter));
      78           0 :       if (NS_FAILED(rv)) {
      79           0 :         printf_stderr("Cannot create filter that content specified. "
      80           0 :                       "filter name: %s, error code: %u.", aFilter.BeginReading(),  static_cast<uint32_t>(rv));
      81           0 :         return false;
      82             :       }
      83             :     } else {
      84           0 :       printf_stderr("Content doesn't have a valid filter. "
      85           0 :                     "filter name: %s.", aFilter.BeginReading());
      86           0 :       return false;
      87             :     }
      88             :   }
      89             :   // We don't have browser actors in xpcshell, and hence can't run automated
      90             :   // tests without this loophole.
      91           0 :   if (net::UsingNeckoIPCSecurity() && !mFilter &&
      92           0 :       (!mPrincipal || ContentParent::IgnoreIPCPrincipal())) {
      93           0 :     return false;
      94             :   }
      95           0 :   return true;
      96             : }
      97             : 
      98             : // PUDPSocketParent methods
      99             : 
     100             : mozilla::ipc::IPCResult
     101           0 : UDPSocketParent::RecvBind(const UDPAddressInfo& aAddressInfo,
     102             :                           const bool& aAddressReuse, const bool& aLoopback,
     103             :                           const uint32_t& recvBufferSize,
     104             :                           const uint32_t& sendBufferSize)
     105             : {
     106           0 :   UDPSOCKET_LOG(("%s: %s:%u", __FUNCTION__, aAddressInfo.addr().get(), aAddressInfo.port()));
     107             : 
     108           0 :   if (NS_FAILED(BindInternal(aAddressInfo.addr(), aAddressInfo.port(),
     109             :                              aAddressReuse, aLoopback, recvBufferSize,
     110             :                              sendBufferSize))) {
     111           0 :     FireInternalError(__LINE__);
     112           0 :     return IPC_OK();
     113             :   }
     114             : 
     115           0 :   nsCOMPtr<nsINetAddr> localAddr;
     116           0 :   mSocket->GetLocalAddr(getter_AddRefs(localAddr));
     117             : 
     118           0 :   nsCString addr;
     119           0 :   if (NS_FAILED(localAddr->GetAddress(addr))) {
     120           0 :     FireInternalError(__LINE__);
     121           0 :     return IPC_OK();
     122             :   }
     123             : 
     124             :   uint16_t port;
     125           0 :   if (NS_FAILED(localAddr->GetPort(&port))) {
     126           0 :     FireInternalError(__LINE__);
     127           0 :     return IPC_OK();
     128             :   }
     129             : 
     130           0 :   UDPSOCKET_LOG(("%s: SendCallbackOpened: %s:%u", __FUNCTION__, addr.get(), port));
     131           0 :   mozilla::Unused << SendCallbackOpened(UDPAddressInfo(addr, port));
     132             : 
     133           0 :   return IPC_OK();
     134             : }
     135             : 
     136             : nsresult
     137           0 : UDPSocketParent::BindInternal(const nsCString& aHost, const uint16_t& aPort,
     138             :                               const bool& aAddressReuse, const bool& aLoopback,
     139             :                               const uint32_t& recvBufferSize,
     140             :                               const uint32_t& sendBufferSize)
     141             : {
     142             :   nsresult rv;
     143             : 
     144           0 :   UDPSOCKET_LOG(("%s: [this=%p] %s:%u addressReuse: %d loopback: %d recvBufferSize: %"
     145             :                  PRIu32 ", sendBufferSize: %" PRIu32,
     146             :                 __FUNCTION__, this, nsCString(aHost).get(), aPort,
     147             :                 aAddressReuse, aLoopback, recvBufferSize, sendBufferSize));
     148             : 
     149             :   nsCOMPtr<nsIUDPSocket> sock =
     150           0 :       do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv);
     151             : 
     152           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     153           0 :     return rv;
     154             :   }
     155             : 
     156           0 :   if (aHost.IsEmpty()) {
     157           0 :     rv = sock->Init(aPort, false, mPrincipal, aAddressReuse,
     158           0 :                     /* optional_argc = */ 1);
     159             :   } else {
     160             :     PRNetAddr prAddr;
     161           0 :     PR_InitializeNetAddr(PR_IpAddrAny, aPort, &prAddr);
     162           0 :     PRStatus status = PR_StringToNetAddr(aHost.BeginReading(), &prAddr);
     163           0 :     if (status != PR_SUCCESS) {
     164           0 :       return NS_ERROR_FAILURE;
     165             :     }
     166             : 
     167             :     mozilla::net::NetAddr addr;
     168           0 :     PRNetAddrToNetAddr(&prAddr, &addr);
     169           0 :     rv = sock->InitWithAddress(&addr, mPrincipal, aAddressReuse,
     170           0 :                                /* optional_argc = */ 1);
     171             :   }
     172             : 
     173           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     174           0 :     return rv;
     175             :   }
     176             : 
     177           0 :   nsCOMPtr<nsINetAddr> laddr;
     178           0 :   rv = sock->GetLocalAddr(getter_AddRefs(laddr));
     179           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     180           0 :     return rv;
     181             :   }
     182             :   uint16_t family;
     183           0 :   rv = laddr->GetFamily(&family);
     184           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     185           0 :     return rv;
     186             :   }
     187           0 :   if (family == nsINetAddr::FAMILY_INET) {
     188           0 :     rv = sock->SetMulticastLoopback(aLoopback);
     189           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     190           0 :       return rv;
     191             :     }
     192             :   }
     193             :   // TODO: once bug 1252759 is fixed query buffer first and only increase
     194           0 :   if (recvBufferSize != 0) {
     195           0 :     rv = sock->SetRecvBufferSize(recvBufferSize);
     196           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     197           0 :       UDPSOCKET_LOG(("%s: [this=%p] %s:%u failed to set recv buffer size to: %" PRIu32, __FUNCTION__, this, nsCString(aHost).get(), aPort, recvBufferSize));
     198             :     }
     199             :   }
     200           0 :   if (sendBufferSize != 0) {
     201           0 :     rv = sock->SetSendBufferSize(sendBufferSize);
     202           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     203           0 :       UDPSOCKET_LOG(("%s: [this=%p] %s:%u failed to set send buffer size to: %" PRIu32, __FUNCTION__, this, nsCString(aHost).get(), aPort, sendBufferSize));
     204             :     }
     205             :   }
     206             : 
     207             :   // register listener
     208           0 :   rv = sock->AsyncListen(this);
     209           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     210           0 :     return rv;
     211             :   }
     212             : 
     213           0 :   mSocket = sock;
     214             : 
     215           0 :   return NS_OK;
     216             : }
     217             : 
     218             : 
     219           0 : static nsCOMPtr<nsIEventTarget> GetSTSThread()
     220             : {
     221             :   nsresult rv;
     222             : 
     223           0 :   nsCOMPtr<nsIEventTarget> sts_thread;
     224             : 
     225           0 :   sts_thread = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
     226           0 :   MOZ_ASSERT(NS_SUCCEEDED(rv));
     227             : 
     228           0 :   return sts_thread;
     229             : }
     230             : 
     231           0 : static void CheckSTSThread()
     232             : {
     233           0 :   DebugOnly<nsCOMPtr<nsIEventTarget>> sts_thread = GetSTSThread();
     234             : 
     235           0 :   ASSERT_ON_THREAD(sts_thread.value);
     236           0 : }
     237             : 
     238             : 
     239             : // Proxy the Connect() request to the STS thread, since it may block and
     240             : // should be done there.
     241             : mozilla::ipc::IPCResult
     242           0 : UDPSocketParent::RecvConnect(const UDPAddressInfo& aAddressInfo)
     243             : {
     244           0 :   nsCOMPtr<nsIEventTarget> target = GetCurrentThreadEventTarget();
     245             :   Unused <<
     246           0 :     NS_WARN_IF(NS_FAILED(GetSTSThread()->Dispatch(WrapRunnable(
     247             :                                                     RefPtr<UDPSocketParent>(this),
     248             :                                                     &UDPSocketParent::DoConnect,
     249             :                                                     mSocket,
     250             :                                                     target,
     251             :                                                     aAddressInfo),
     252             :                                                   NS_DISPATCH_NORMAL)));
     253           0 :   return IPC_OK();
     254             : }
     255             : 
     256             : void
     257           0 : UDPSocketParent::DoSendConnectResponse(const UDPAddressInfo& aAddressInfo)
     258             : {
     259             :   // can't use directly with WrapRunnable due to warnings
     260           0 :   mozilla::Unused << SendCallbackConnected(aAddressInfo);
     261           0 : }
     262             : 
     263             : void
     264           0 : UDPSocketParent::SendConnectResponse(nsIEventTarget *aThread,
     265             :                                      const UDPAddressInfo& aAddressInfo)
     266             : {
     267             :   Unused <<
     268           0 :     NS_WARN_IF(NS_FAILED(aThread->Dispatch(WrapRunnable(
     269             :                                              RefPtr<UDPSocketParent>(this),
     270             :                                              &UDPSocketParent::DoSendConnectResponse,
     271             :                                              aAddressInfo),
     272             :                                            NS_DISPATCH_NORMAL)));
     273           0 : }
     274             : 
     275             : // Runs on STS thread
     276             : void
     277           0 : UDPSocketParent::DoConnect(nsCOMPtr<nsIUDPSocket>& aSocket,
     278             :                            nsCOMPtr<nsIEventTarget>& aReturnThread,
     279             :                            const UDPAddressInfo& aAddressInfo)
     280             : {
     281           0 :   UDPSOCKET_LOG(("%s: %s:%u", __FUNCTION__, aAddressInfo.addr().get(), aAddressInfo.port()));
     282           0 :   if (NS_FAILED(ConnectInternal(aAddressInfo.addr(), aAddressInfo.port()))) {
     283           0 :     SendInternalError(aReturnThread, __LINE__);
     284           0 :     return;
     285             :   }
     286           0 :   CheckSTSThread();
     287             : 
     288           0 :   nsCOMPtr<nsINetAddr> localAddr;
     289           0 :   aSocket->GetLocalAddr(getter_AddRefs(localAddr));
     290             : 
     291           0 :   nsCString addr;
     292           0 :   if (NS_FAILED(localAddr->GetAddress(addr))) {
     293           0 :     SendInternalError(aReturnThread, __LINE__);
     294           0 :     return;
     295             :   }
     296             : 
     297             :   uint16_t port;
     298           0 :   if (NS_FAILED(localAddr->GetPort(&port))) {
     299           0 :     SendInternalError(aReturnThread, __LINE__);
     300           0 :     return;
     301             :   }
     302             : 
     303           0 :   UDPSOCKET_LOG(("%s: SendConnectResponse: %s:%u", __FUNCTION__, addr.get(), port));
     304           0 :   SendConnectResponse(aReturnThread, UDPAddressInfo(addr, port));
     305             : }
     306             : 
     307             : nsresult
     308           0 : UDPSocketParent::ConnectInternal(const nsCString& aHost, const uint16_t& aPort)
     309             : {
     310             :   nsresult rv;
     311             : 
     312           0 :   UDPSOCKET_LOG(("%s: %s:%u", __FUNCTION__, nsCString(aHost).get(), aPort));
     313             : 
     314           0 :   if (!mSocket) {
     315           0 :     return NS_ERROR_NOT_AVAILABLE;
     316             :   }
     317             : 
     318             :   PRNetAddr prAddr;
     319           0 :   memset(&prAddr, 0, sizeof(prAddr));
     320           0 :   PR_InitializeNetAddr(PR_IpAddrAny, aPort, &prAddr);
     321           0 :   PRStatus status = PR_StringToNetAddr(aHost.BeginReading(), &prAddr);
     322           0 :   if (status != PR_SUCCESS) {
     323           0 :     return NS_ERROR_FAILURE;
     324             :   }
     325             : 
     326             :   mozilla::net::NetAddr addr;
     327           0 :   PRNetAddrToNetAddr(&prAddr, &addr);
     328             : 
     329           0 :   rv = mSocket->Connect(&addr);
     330           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     331           0 :     return rv;
     332             :   }
     333             : 
     334           0 :   return NS_OK;
     335             : }
     336             : 
     337             : mozilla::ipc::IPCResult
     338           0 : UDPSocketParent::RecvOutgoingData(const UDPData& aData,
     339             :                                   const UDPSocketAddr& aAddr)
     340             : {
     341           0 :   if (!mSocket) {
     342           0 :     NS_WARNING("sending socket is closed");
     343           0 :     FireInternalError(__LINE__);
     344           0 :     return IPC_OK();
     345             :   }
     346             : 
     347             :   nsresult rv;
     348           0 :   if (mFilter) {
     349           0 :     if (aAddr.type() != UDPSocketAddr::TNetAddr) {
     350           0 :       return IPC_OK();
     351             :     }
     352             : 
     353             :     // TODO, Packet filter doesn't support input stream yet.
     354           0 :     if (aData.type() != UDPData::TArrayOfuint8_t) {
     355           0 :       return IPC_OK();
     356             :     }
     357             : 
     358             :     bool allowed;
     359           0 :     const InfallibleTArray<uint8_t>& data(aData.get_ArrayOfuint8_t());
     360           0 :     rv = mFilter->FilterPacket(&aAddr.get_NetAddr(), data.Elements(),
     361           0 :                                data.Length(), nsISocketFilter::SF_OUTGOING,
     362           0 :                                &allowed);
     363             : 
     364             :     // Sending unallowed data, kill content.
     365           0 :     if (NS_WARN_IF(NS_FAILED(rv)) || !allowed) {
     366           0 :       return IPC_FAIL(this, "Content tried to send non STUN packet");
     367             :     }
     368             :   }
     369             : 
     370           0 :   switch(aData.type()) {
     371             :     case UDPData::TArrayOfuint8_t:
     372           0 :       Send(aData.get_ArrayOfuint8_t(), aAddr);
     373           0 :       break;
     374             :     case UDPData::TIPCStream:
     375           0 :       Send(aData.get_IPCStream(), aAddr);
     376           0 :       break;
     377             :     default:
     378           0 :       MOZ_ASSERT(false, "Invalid data type!");
     379             :       return IPC_OK();
     380             :   }
     381             : 
     382           0 :   return IPC_OK();
     383             : }
     384             : 
     385             : void
     386           0 : UDPSocketParent::Send(const InfallibleTArray<uint8_t>& aData,
     387             :                       const UDPSocketAddr& aAddr)
     388             : {
     389             :   nsresult rv;
     390             :   uint32_t count;
     391           0 :   switch(aAddr.type()) {
     392             :     case UDPSocketAddr::TUDPAddressInfo: {
     393           0 :       const UDPAddressInfo& addrInfo(aAddr.get_UDPAddressInfo());
     394           0 :       rv = mSocket->Send(addrInfo.addr(), addrInfo.port(),
     395           0 :                          aData.Elements(), aData.Length(), &count);
     396           0 :       break;
     397             :     }
     398             :     case UDPSocketAddr::TNetAddr: {
     399           0 :       const NetAddr& addr(aAddr.get_NetAddr());
     400           0 :       rv = mSocket->SendWithAddress(&addr, aData.Elements(),
     401           0 :                                     aData.Length(), &count);
     402           0 :       break;
     403             :     }
     404             :     default:
     405           0 :       MOZ_ASSERT(false, "Invalid address type!");
     406             :       return;
     407             :   }
     408             : 
     409           0 :   if (NS_WARN_IF(NS_FAILED(rv)) || count == 0) {
     410           0 :     FireInternalError(__LINE__);
     411             :   }
     412           0 : }
     413             : 
     414             : void
     415           0 : UDPSocketParent::Send(const IPCStream& aStream,
     416             :                       const UDPSocketAddr& aAddr)
     417             : {
     418           0 :   nsCOMPtr<nsIInputStream> stream = DeserializeIPCStream(aStream);
     419             : 
     420           0 :   if (NS_WARN_IF(!stream)) {
     421           0 :     return;
     422             :   }
     423             : 
     424             :   nsresult rv;
     425           0 :   switch(aAddr.type()) {
     426             :     case UDPSocketAddr::TUDPAddressInfo: {
     427           0 :       const UDPAddressInfo& addrInfo(aAddr.get_UDPAddressInfo());
     428           0 :       rv = mSocket->SendBinaryStream(addrInfo.addr(), addrInfo.port(), stream);
     429           0 :       break;
     430             :     }
     431             :     case UDPSocketAddr::TNetAddr: {
     432           0 :       const NetAddr& addr(aAddr.get_NetAddr());
     433           0 :       rv = mSocket->SendBinaryStreamWithAddress(&addr, stream);
     434           0 :       break;
     435             :     }
     436             :     default:
     437           0 :       MOZ_ASSERT(false, "Invalid address type!");
     438             :       return;
     439             :   }
     440             : 
     441           0 :   if (NS_FAILED(rv)) {
     442           0 :     FireInternalError(__LINE__);
     443             :   }
     444             : }
     445             : 
     446             : mozilla::ipc::IPCResult
     447           0 : UDPSocketParent::RecvJoinMulticast(const nsCString& aMulticastAddress,
     448             :                                    const nsCString& aInterface)
     449             : {
     450           0 :   nsresult rv = mSocket->JoinMulticast(aMulticastAddress, aInterface);
     451             : 
     452           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     453           0 :     FireInternalError(__LINE__);
     454             :   }
     455             : 
     456           0 :   return IPC_OK();
     457             : }
     458             : 
     459             : mozilla::ipc::IPCResult
     460           0 : UDPSocketParent::RecvLeaveMulticast(const nsCString& aMulticastAddress,
     461             :                                     const nsCString& aInterface)
     462             : {
     463           0 :   nsresult rv = mSocket->LeaveMulticast(aMulticastAddress, aInterface);
     464             : 
     465           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     466           0 :     FireInternalError(__LINE__);
     467             :   }
     468             : 
     469           0 :   return IPC_OK();
     470             : }
     471             : 
     472             : mozilla::ipc::IPCResult
     473           0 : UDPSocketParent::RecvClose()
     474             : {
     475           0 :   if (!mSocket) {
     476           0 :     return IPC_OK();
     477             :   }
     478             : 
     479           0 :   nsresult rv = mSocket->Close();
     480           0 :   mSocket = nullptr;
     481             : 
     482           0 :   mozilla::Unused << NS_WARN_IF(NS_FAILED(rv));
     483             : 
     484           0 :   return IPC_OK();
     485             : }
     486             : 
     487             : mozilla::ipc::IPCResult
     488           0 : UDPSocketParent::RecvRequestDelete()
     489             : {
     490           0 :   mozilla::Unused << Send__delete__(this);
     491           0 :   return IPC_OK();
     492             : }
     493             : 
     494             : void
     495           0 : UDPSocketParent::ActorDestroy(ActorDestroyReason why)
     496             : {
     497           0 :   MOZ_ASSERT(mIPCOpen);
     498           0 :   mIPCOpen = false;
     499           0 :   if (mSocket) {
     500           0 :     mSocket->Close();
     501             :   }
     502           0 :   mSocket = nullptr;
     503           0 : }
     504             : 
     505             : // nsIUDPSocketListener
     506             : 
     507             : NS_IMETHODIMP
     508           0 : UDPSocketParent::OnPacketReceived(nsIUDPSocket* aSocket, nsIUDPMessage* aMessage)
     509             : {
     510             :   // receiving packet from remote host, forward the message content to child process
     511           0 :   if (!mIPCOpen) {
     512           0 :     return NS_OK;
     513             :   }
     514             : 
     515             :   uint16_t port;
     516           0 :   nsCString ip;
     517           0 :   nsCOMPtr<nsINetAddr> fromAddr;
     518           0 :   aMessage->GetFromAddr(getter_AddRefs(fromAddr));
     519           0 :   fromAddr->GetPort(&port);
     520           0 :   fromAddr->GetAddress(ip);
     521             : 
     522           0 :   nsCString data;
     523           0 :   aMessage->GetData(data);
     524             : 
     525           0 :   const char* buffer = data.get();
     526           0 :   uint32_t len = data.Length();
     527           0 :   UDPSOCKET_LOG(("%s: %s:%u, length %u", __FUNCTION__, ip.get(), port, len));
     528             : 
     529           0 :   if (mFilter) {
     530             :     bool allowed;
     531             :     mozilla::net::NetAddr addr;
     532           0 :     fromAddr->GetNetAddr(&addr);
     533           0 :     nsresult rv = mFilter->FilterPacket(&addr,
     534             :                                         (const uint8_t*)buffer, len,
     535             :                                         nsISocketFilter::SF_INCOMING,
     536           0 :                                         &allowed);
     537             :     // Receiving unallowed data, drop.
     538           0 :     if (NS_WARN_IF(NS_FAILED(rv)) || !allowed) {
     539           0 :       if (!allowed) {
     540           0 :         UDPSOCKET_LOG(("%s: not allowed", __FUNCTION__));
     541             :       }
     542           0 :       return NS_OK;
     543             :     }
     544             :   }
     545             : 
     546           0 :   FallibleTArray<uint8_t> fallibleArray;
     547           0 :   if (!fallibleArray.InsertElementsAt(0, buffer, len, fallible)) {
     548           0 :     FireInternalError(__LINE__);
     549           0 :     return NS_ERROR_OUT_OF_MEMORY;
     550             :   }
     551           0 :   InfallibleTArray<uint8_t> infallibleArray;
     552           0 :   infallibleArray.SwapElements(fallibleArray);
     553             : 
     554             :   // compose callback
     555           0 :   mozilla::Unused << SendCallbackReceivedData(UDPAddressInfo(ip, port), infallibleArray);
     556             : 
     557           0 :   return NS_OK;
     558             : }
     559             : 
     560             : NS_IMETHODIMP
     561           0 : UDPSocketParent::OnStopListening(nsIUDPSocket* aSocket, nsresult aStatus)
     562             : {
     563             :   // underlying socket is dead, send state update to child process
     564           0 :   if (mIPCOpen) {
     565           0 :     mozilla::Unused << SendCallbackClosed();
     566             :   }
     567           0 :   return NS_OK;
     568             : }
     569             : 
     570             : void
     571           0 : UDPSocketParent::FireInternalError(uint32_t aLineNo)
     572             : {
     573           0 :   if (!mIPCOpen) {
     574           0 :     return;
     575             :   }
     576             : 
     577           0 :   mozilla::Unused << SendCallbackError(NS_LITERAL_CSTRING("Internal error"),
     578           0 :                                        NS_LITERAL_CSTRING(__FILE__), aLineNo);
     579             : }
     580             : 
     581             : void
     582           0 : UDPSocketParent::SendInternalError(nsIEventTarget *aThread,
     583             :                                    uint32_t aLineNo)
     584             : {
     585           0 :   UDPSOCKET_LOG(("SendInternalError: %u", aLineNo));
     586             :   Unused <<
     587           0 :     NS_WARN_IF(NS_FAILED(aThread->Dispatch(WrapRunnable(
     588             :                                              RefPtr<UDPSocketParent>(this),
     589             :                                              &UDPSocketParent::FireInternalError,
     590             :                                              aLineNo),
     591             :                                            NS_DISPATCH_NORMAL)));
     592           0 : }
     593             : 
     594             : } // namespace dom
     595             : } // namespace mozilla

Generated by: LCOV version 1.13