LCOV - code coverage report
Current view: top level - dom/network - UDPSocketChild.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 172 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 41 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 "UDPSocketChild.h"
       8             : #include "mozilla/SizePrintfMacros.h"
       9             : #include "mozilla/Unused.h"
      10             : #include "mozilla/ipc/IPCStreamUtils.h"
      11             : #include "mozilla/net/NeckoChild.h"
      12             : #include "mozilla/dom/ContentChild.h"
      13             : #include "mozilla/dom/PermissionMessageUtils.h"
      14             : #include "mozilla/ipc/BackgroundChild.h"
      15             : #include "mozilla/ipc/PBackgroundChild.h"
      16             : #include "mozilla/ipc/BackgroundUtils.h"
      17             : #include "mozilla/ipc/PBackgroundSharedTypes.h"
      18             : #include "nsIIPCBackgroundChildCreateCallback.h"
      19             : 
      20             : using mozilla::net::gNeckoChild;
      21             : 
      22             : namespace mozilla {
      23             : namespace dom {
      24             : 
      25           0 : NS_IMPL_ISUPPORTS(UDPSocketChildBase, nsIUDPSocketChild)
      26             : 
      27           0 : UDPSocketChildBase::UDPSocketChildBase()
      28           0 : : mIPCOpen(false)
      29             : {
      30           0 : }
      31             : 
      32           0 : UDPSocketChildBase::~UDPSocketChildBase()
      33             : {
      34           0 : }
      35             : 
      36             : void
      37           0 : UDPSocketChildBase::ReleaseIPDLReference()
      38             : {
      39           0 :   MOZ_ASSERT(mIPCOpen);
      40           0 :   mIPCOpen = false;
      41           0 :   mSocket = nullptr;
      42           0 :   this->Release();
      43           0 : }
      44             : 
      45             : void
      46           0 : UDPSocketChildBase::AddIPDLReference()
      47             : {
      48           0 :   MOZ_ASSERT(!mIPCOpen);
      49           0 :   mIPCOpen = true;
      50           0 :   this->AddRef();
      51           0 : }
      52             : 
      53           0 : NS_IMETHODIMP_(MozExternalRefCountType) UDPSocketChild::Release(void)
      54             : {
      55           0 :   nsrefcnt refcnt = UDPSocketChildBase::Release();
      56           0 :   if (refcnt == 1 && mIPCOpen) {
      57           0 :     PUDPSocketChild::SendRequestDelete();
      58           0 :     return 1;
      59             :   }
      60           0 :   return refcnt;
      61             : }
      62             : 
      63           0 : UDPSocketChild::UDPSocketChild()
      64             : :mBackgroundManager(nullptr)
      65           0 : ,mLocalPort(0)
      66             : {
      67           0 : }
      68             : 
      69           0 : UDPSocketChild::~UDPSocketChild()
      70             : {
      71           0 : }
      72             : 
      73             : class UDPSocketBackgroundChildCallback final :
      74             :   public nsIIPCBackgroundChildCreateCallback
      75             : {
      76             :   bool* mDone;
      77             : 
      78             : public:
      79           0 :   explicit UDPSocketBackgroundChildCallback(bool* aDone)
      80           0 :   : mDone(aDone)
      81             :   {
      82           0 :     MOZ_ASSERT(!NS_IsMainThread());
      83           0 :     MOZ_ASSERT(mDone);
      84           0 :     MOZ_ASSERT(!*mDone);
      85           0 :   }
      86             : 
      87             :   NS_DECL_ISUPPORTS
      88             : 
      89             : private:
      90           0 :   ~UDPSocketBackgroundChildCallback()
      91           0 :   { }
      92             : 
      93             :   virtual void
      94           0 :   ActorCreated(PBackgroundChild* aActor) override
      95             :   {
      96           0 :     *mDone = true;
      97           0 :   }
      98             : 
      99             :   virtual void
     100           0 :   ActorFailed() override
     101             :   {
     102           0 :     *mDone = true;
     103           0 :   }
     104             : };
     105             : 
     106           0 : NS_IMPL_ISUPPORTS(UDPSocketBackgroundChildCallback, nsIIPCBackgroundChildCreateCallback)
     107             : 
     108             : nsresult
     109           0 : UDPSocketChild::CreatePBackgroundSpinUntilDone()
     110             : {
     111             :   using mozilla::ipc::BackgroundChild;
     112             : 
     113             :   // Spinning the event loop in MainThread would be dangerous
     114           0 :   MOZ_ASSERT(!NS_IsMainThread());
     115           0 :   MOZ_ASSERT(!BackgroundChild::GetForCurrentThread());
     116             : 
     117           0 :   bool done = false;
     118             :   nsCOMPtr<nsIIPCBackgroundChildCreateCallback> callback =
     119           0 :     new UDPSocketBackgroundChildCallback(&done);
     120             : 
     121           0 :   if (NS_WARN_IF(!BackgroundChild::GetOrCreateForCurrentThread(callback))) {
     122           0 :     return NS_ERROR_FAILURE;
     123             :   }
     124             : 
     125           0 :   if (!SpinEventLoopUntil([&done]() { return done; })) {
     126           0 :     return NS_ERROR_FAILURE;
     127             :   }
     128             : 
     129           0 :   if (NS_WARN_IF(!BackgroundChild::GetForCurrentThread())) {
     130           0 :     return NS_ERROR_FAILURE;
     131             :   }
     132             : 
     133           0 :   return NS_OK;
     134             : }
     135             : 
     136             : // nsIUDPSocketChild Methods
     137             : 
     138             : NS_IMETHODIMP
     139           0 : UDPSocketChild::SetBackgroundSpinsEvents()
     140             : {
     141             :   using mozilla::ipc::BackgroundChild;
     142             : 
     143             :   PBackgroundChild* existingBackgroundChild =
     144           0 :     BackgroundChild::GetForCurrentThread();
     145             :   // If it's not spun up yet, block until it is, and retry
     146           0 :   if (!existingBackgroundChild) {
     147           0 :     nsresult rv = CreatePBackgroundSpinUntilDone();
     148           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     149           0 :       return rv;
     150             :     }
     151             :     existingBackgroundChild =
     152           0 :       BackgroundChild::GetForCurrentThread();
     153           0 :     MOZ_ASSERT(existingBackgroundChild);
     154             :   }
     155             :   // By now PBackground is guaranteed to be/have-been up
     156           0 :   mBackgroundManager = existingBackgroundChild;
     157           0 :   return NS_OK;
     158             : }
     159             : 
     160             : NS_IMETHODIMP
     161           0 : UDPSocketChild::Bind(nsIUDPSocketInternal* aSocket,
     162             :                      nsIPrincipal* aPrincipal,
     163             :                      const nsACString& aHost,
     164             :                      uint16_t aPort,
     165             :                      bool aAddressReuse,
     166             :                      bool aLoopback,
     167             :                      uint32_t recvBufferSize,
     168             :                      uint32_t sendBufferSize,
     169             :                      nsIEventTarget* aMainThreadEventTarget)
     170             : {
     171           0 :   UDPSOCKET_LOG(("%s: %s:%u", __FUNCTION__, PromiseFlatCString(aHost).get(), aPort));
     172             : 
     173           0 :   NS_ENSURE_ARG(aSocket);
     174             : 
     175           0 :   mSocket = aSocket;
     176           0 :   AddIPDLReference();
     177             : 
     178           0 :   if (mBackgroundManager) {
     179             :     // If we want to support a passed-in principal here we'd need to
     180             :     // convert it to a PrincipalInfo
     181           0 :     MOZ_ASSERT(!aPrincipal);
     182           0 :     mBackgroundManager->SendPUDPSocketConstructor(this, void_t(), mFilterName);
     183             :   } else {
     184           0 :     if (aMainThreadEventTarget) {
     185           0 :       gNeckoChild->SetEventTargetForActor(this, aMainThreadEventTarget);
     186             :     }
     187           0 :     gNeckoChild->SendPUDPSocketConstructor(this, IPC::Principal(aPrincipal),
     188           0 :                                            mFilterName);
     189             :   }
     190             : 
     191           0 :   SendBind(UDPAddressInfo(nsCString(aHost), aPort), aAddressReuse, aLoopback,
     192           0 :            recvBufferSize, sendBufferSize);
     193           0 :   return NS_OK;
     194             : }
     195             : 
     196             : NS_IMETHODIMP
     197           0 : UDPSocketChild::Connect(nsIUDPSocketInternal* aSocket, const nsACString & aHost, uint16_t aPort)
     198             : {
     199           0 :   UDPSOCKET_LOG(("%s: %s:%u", __FUNCTION__, PromiseFlatCString(aHost).get(), aPort));
     200             : 
     201           0 :   mSocket = aSocket;
     202             : 
     203           0 :   SendConnect(UDPAddressInfo(nsCString(aHost), aPort));
     204             : 
     205           0 :   return NS_OK;
     206             : }
     207             : 
     208             : NS_IMETHODIMP
     209           0 : UDPSocketChild::Close()
     210             : {
     211           0 :   SendClose();
     212           0 :   return NS_OK;
     213             : }
     214             : 
     215             : NS_IMETHODIMP
     216           0 : UDPSocketChild::Send(const nsACString& aHost,
     217             :                      uint16_t aPort,
     218             :                      const uint8_t* aData,
     219             :                      uint32_t aByteLength)
     220             : {
     221           0 :   NS_ENSURE_ARG(aData);
     222             : 
     223           0 :   UDPSOCKET_LOG(("%s: %s:%u - %u bytes", __FUNCTION__, PromiseFlatCString(aHost).get(), aPort, aByteLength));
     224           0 :   return SendDataInternal(UDPSocketAddr(UDPAddressInfo(nsCString(aHost), aPort)),
     225           0 :                           aData, aByteLength);
     226             : }
     227             : 
     228             : NS_IMETHODIMP
     229           0 : UDPSocketChild::SendWithAddr(nsINetAddr* aAddr,
     230             :                              const uint8_t* aData,
     231             :                              uint32_t aByteLength)
     232             : {
     233           0 :   NS_ENSURE_ARG(aAddr);
     234           0 :   NS_ENSURE_ARG(aData);
     235             : 
     236             :   NetAddr addr;
     237           0 :   aAddr->GetNetAddr(&addr);
     238             : 
     239           0 :   UDPSOCKET_LOG(("%s: %u bytes", __FUNCTION__, aByteLength));
     240           0 :   return SendDataInternal(UDPSocketAddr(addr), aData, aByteLength);
     241             : }
     242             : 
     243             : NS_IMETHODIMP
     244           0 : UDPSocketChild::SendWithAddress(const NetAddr* aAddr,
     245             :                                 const uint8_t* aData,
     246             :                                 uint32_t aByteLength)
     247             : {
     248           0 :   NS_ENSURE_ARG(aAddr);
     249           0 :   NS_ENSURE_ARG(aData);
     250             : 
     251           0 :   UDPSOCKET_LOG(("%s: %u bytes", __FUNCTION__, aByteLength));
     252           0 :   return SendDataInternal(UDPSocketAddr(*aAddr), aData, aByteLength);
     253             : }
     254             : 
     255             : nsresult
     256           0 : UDPSocketChild::SendDataInternal(const UDPSocketAddr& aAddr,
     257             :                                  const uint8_t* aData,
     258             :                                  const uint32_t aByteLength)
     259             : {
     260           0 :   NS_ENSURE_ARG(aData);
     261             : 
     262           0 :   FallibleTArray<uint8_t> fallibleArray;
     263           0 :   if (!fallibleArray.InsertElementsAt(0, aData, aByteLength, fallible)) {
     264           0 :     return NS_ERROR_OUT_OF_MEMORY;
     265             :   }
     266             : 
     267           0 :   InfallibleTArray<uint8_t> array;
     268           0 :   array.SwapElements(fallibleArray);
     269             : 
     270           0 :   SendOutgoingData(array, aAddr);
     271             : 
     272           0 :   return NS_OK;
     273             : }
     274             : 
     275             : NS_IMETHODIMP
     276           0 : UDPSocketChild::SendBinaryStream(const nsACString& aHost,
     277             :                                  uint16_t aPort,
     278             :                                  nsIInputStream* aStream)
     279             : {
     280           0 :   NS_ENSURE_ARG(aStream);
     281             : 
     282           0 :   mozilla::ipc::AutoIPCStream autoStream;
     283           0 :   autoStream.Serialize(aStream,
     284           0 :                        static_cast<mozilla::dom::ContentChild*>(gNeckoChild->Manager()));
     285             : 
     286           0 :   UDPSOCKET_LOG(("%s: %s:%u", __FUNCTION__, PromiseFlatCString(aHost).get(), aPort));
     287           0 :   SendOutgoingData(UDPData(autoStream.TakeOptionalValue()),
     288           0 :                    UDPSocketAddr(UDPAddressInfo(nsCString(aHost), aPort)));
     289             : 
     290           0 :   return NS_OK;
     291             : }
     292             : 
     293             : NS_IMETHODIMP
     294           0 : UDPSocketChild::JoinMulticast(const nsACString& aMulticastAddress,
     295             :                               const nsACString& aInterface)
     296             : {
     297           0 :   SendJoinMulticast(nsCString(aMulticastAddress), nsCString(aInterface));
     298           0 :   return NS_OK;
     299             : }
     300             : 
     301             : NS_IMETHODIMP
     302           0 : UDPSocketChild::LeaveMulticast(const nsACString& aMulticastAddress,
     303             :                                const nsACString& aInterface)
     304             : {
     305           0 :   SendLeaveMulticast(nsCString(aMulticastAddress), nsCString(aInterface));
     306           0 :   return NS_OK;
     307             : }
     308             : 
     309             : NS_IMETHODIMP
     310           0 : UDPSocketChild::GetLocalPort(uint16_t* aLocalPort)
     311             : {
     312           0 :   NS_ENSURE_ARG_POINTER(aLocalPort);
     313             : 
     314           0 :   *aLocalPort = mLocalPort;
     315           0 :   return NS_OK;
     316             : }
     317             : 
     318             : NS_IMETHODIMP
     319           0 : UDPSocketChild::GetLocalAddress(nsACString& aLocalAddress)
     320             : {
     321           0 :   aLocalAddress = mLocalAddress;
     322           0 :   return NS_OK;
     323             : }
     324             : 
     325             : NS_IMETHODIMP
     326           0 : UDPSocketChild::SetFilterName(const nsACString& aFilterName)
     327             : {
     328           0 :   if (!mFilterName.IsEmpty()) {
     329             :     // filter name can only be set once.
     330           0 :     return NS_ERROR_FAILURE;
     331             :   }
     332           0 :   mFilterName = aFilterName;
     333           0 :   return NS_OK;
     334             : }
     335             : 
     336             : NS_IMETHODIMP
     337           0 : UDPSocketChild::GetFilterName(nsACString& aFilterName)
     338             : {
     339           0 :   aFilterName = mFilterName;
     340           0 :   return NS_OK;
     341             : }
     342             : 
     343             : // PUDPSocketChild Methods
     344             : mozilla::ipc::IPCResult
     345           0 : UDPSocketChild::RecvCallbackOpened(const UDPAddressInfo& aAddressInfo)
     346             : {
     347           0 :   mLocalAddress = aAddressInfo.addr();
     348           0 :   mLocalPort = aAddressInfo.port();
     349             : 
     350           0 :   UDPSOCKET_LOG(("%s: %s:%u", __FUNCTION__, mLocalAddress.get(), mLocalPort));
     351           0 :   nsresult rv = mSocket->CallListenerOpened();
     352           0 :   mozilla::Unused << NS_WARN_IF(NS_FAILED(rv));
     353             : 
     354           0 :   return IPC_OK();
     355             : }
     356             : 
     357             : // PUDPSocketChild Methods
     358             : mozilla::ipc::IPCResult
     359           0 : UDPSocketChild::RecvCallbackConnected(const UDPAddressInfo& aAddressInfo)
     360             : {
     361           0 :   mLocalAddress = aAddressInfo.addr();
     362           0 :   mLocalPort = aAddressInfo.port();
     363             : 
     364           0 :   UDPSOCKET_LOG(("%s: %s:%u", __FUNCTION__, mLocalAddress.get(), mLocalPort));
     365           0 :   nsresult rv = mSocket->CallListenerConnected();
     366           0 :   mozilla::Unused << NS_WARN_IF(NS_FAILED(rv));
     367             : 
     368           0 :   return IPC_OK();
     369             : }
     370             : 
     371             : mozilla::ipc::IPCResult
     372           0 : UDPSocketChild::RecvCallbackClosed()
     373             : {
     374           0 :   nsresult rv = mSocket->CallListenerClosed();
     375           0 :   mozilla::Unused << NS_WARN_IF(NS_FAILED(rv));
     376             : 
     377           0 :   return IPC_OK();
     378             : }
     379             : 
     380             : mozilla::ipc::IPCResult
     381           0 : UDPSocketChild::RecvCallbackReceivedData(const UDPAddressInfo& aAddressInfo,
     382             :                                          InfallibleTArray<uint8_t>&& aData)
     383             : {
     384           0 :   UDPSOCKET_LOG(("%s: %s:%u length %" PRIuSIZE, __FUNCTION__,
     385             :                  aAddressInfo.addr().get(), aAddressInfo.port(), aData.Length()));
     386           0 :   nsresult rv = mSocket->CallListenerReceivedData(aAddressInfo.addr(), aAddressInfo.port(),
     387           0 :                                                   aData.Elements(), aData.Length());
     388           0 :   mozilla::Unused << NS_WARN_IF(NS_FAILED(rv));
     389             : 
     390           0 :   return IPC_OK();
     391             : }
     392             : 
     393             : mozilla::ipc::IPCResult
     394           0 : UDPSocketChild::RecvCallbackError(const nsCString& aMessage,
     395             :                                   const nsCString& aFilename,
     396             :                                   const uint32_t& aLineNumber)
     397             : {
     398           0 :   UDPSOCKET_LOG(("%s: %s:%s:%u", __FUNCTION__, aMessage.get(), aFilename.get(), aLineNumber));
     399           0 :   nsresult rv = mSocket->CallListenerError(aMessage, aFilename, aLineNumber);
     400           0 :   mozilla::Unused << NS_WARN_IF(NS_FAILED(rv));
     401             : 
     402           0 :   return IPC_OK();
     403             : }
     404             : 
     405             : } // namespace dom
     406             : } // namespace mozilla

Generated by: LCOV version 1.13