LCOV - code coverage report
Current view: top level - netwerk/dns - DNSRequestChild.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 120 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 28 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 sw=2 ts=8 et 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
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "mozilla/dom/ContentChild.h"
       8             : #include "mozilla/net/ChildDNSService.h"
       9             : #include "mozilla/net/DNSRequestChild.h"
      10             : #include "mozilla/net/NeckoChild.h"
      11             : #include "mozilla/SystemGroup.h"
      12             : #include "mozilla/Unused.h"
      13             : #include "nsIDNSRecord.h"
      14             : #include "nsHostResolver.h"
      15             : #include "nsTArray.h"
      16             : #include "nsNetAddr.h"
      17             : #include "nsIThread.h"
      18             : #include "nsThreadUtils.h"
      19             : 
      20             : using namespace mozilla::ipc;
      21             : 
      22             : namespace mozilla {
      23             : namespace net {
      24             : 
      25             : //-----------------------------------------------------------------------------
      26             : // ChildDNSRecord:
      27             : // A simple class to provide nsIDNSRecord on the child
      28             : //-----------------------------------------------------------------------------
      29             : 
      30             : class ChildDNSRecord : public nsIDNSRecord
      31             : {
      32             : public:
      33             :   NS_DECL_THREADSAFE_ISUPPORTS
      34             :   NS_DECL_NSIDNSRECORD
      35             : 
      36             :   ChildDNSRecord(const DNSRecord& reply, uint16_t flags);
      37             : 
      38             : private:
      39             :   virtual ~ChildDNSRecord();
      40             : 
      41             :   nsCString mCanonicalName;
      42             :   nsTArray<NetAddr> mAddresses;
      43             :   uint32_t mCurrent; // addr iterator
      44             :   uint32_t mLength;  // number of addrs
      45             :   uint16_t mFlags;
      46             : };
      47             : 
      48           0 : NS_IMPL_ISUPPORTS(ChildDNSRecord, nsIDNSRecord)
      49             : 
      50           0 : ChildDNSRecord::ChildDNSRecord(const DNSRecord& reply, uint16_t flags)
      51             :   : mCurrent(0)
      52           0 :   , mFlags(flags)
      53             : {
      54           0 :   mCanonicalName = reply.canonicalName();
      55             : 
      56             :   // A shame IPDL gives us no way to grab ownership of array: so copy it.
      57           0 :   const nsTArray<NetAddr>& addrs = reply.addrs();
      58           0 :   uint32_t i = 0;
      59           0 :   mLength = addrs.Length();
      60           0 :   for (; i < mLength; i++) {
      61           0 :     mAddresses.AppendElement(addrs[i]);
      62             :   }
      63           0 : }
      64             : 
      65           0 : ChildDNSRecord::~ChildDNSRecord()
      66             : {
      67           0 : }
      68             : 
      69             : //-----------------------------------------------------------------------------
      70             : // ChildDNSRecord::nsIDNSRecord
      71             : //-----------------------------------------------------------------------------
      72             : 
      73             : NS_IMETHODIMP
      74           0 : ChildDNSRecord::GetCanonicalName(nsACString &result)
      75             : {
      76           0 :   if (!(mFlags & nsHostResolver::RES_CANON_NAME)) {
      77           0 :     return NS_ERROR_NOT_AVAILABLE;
      78             :   }
      79             : 
      80           0 :   result = mCanonicalName;
      81           0 :   return NS_OK;
      82             : }
      83             : 
      84             : NS_IMETHODIMP
      85           0 : ChildDNSRecord::GetNextAddr(uint16_t port, NetAddr *addr)
      86             : {
      87           0 :   if (mCurrent >= mLength) {
      88           0 :     return NS_ERROR_NOT_AVAILABLE;
      89             :   }
      90             : 
      91           0 :   memcpy(addr, &mAddresses[mCurrent++], sizeof(NetAddr));
      92             : 
      93             :   // both Ipv4/6 use same bits for port, so safe to just use ipv4's field
      94           0 :   addr->inet.port = htons(port);
      95             : 
      96           0 :   return NS_OK;
      97             : }
      98             : 
      99             : NS_IMETHODIMP
     100           0 : ChildDNSRecord::GetAddresses(nsTArray<NetAddr> & aAddressArray)
     101             : {
     102           0 :   aAddressArray = mAddresses;
     103           0 :   return NS_OK;
     104             : }
     105             : 
     106             : // shamelessly copied from nsDNSRecord
     107             : NS_IMETHODIMP
     108           0 : ChildDNSRecord::GetScriptableNextAddr(uint16_t port, nsINetAddr **result)
     109             : {
     110             :   NetAddr addr;
     111           0 :   nsresult rv = GetNextAddr(port, &addr);
     112           0 :   if (NS_FAILED(rv)) return rv;
     113             : 
     114           0 :   NS_ADDREF(*result = new nsNetAddr(&addr));
     115             : 
     116           0 :   return NS_OK;
     117             : }
     118             : 
     119             : // also copied from nsDNSRecord
     120             : NS_IMETHODIMP
     121           0 : ChildDNSRecord::GetNextAddrAsString(nsACString &result)
     122             : {
     123             :   NetAddr addr;
     124           0 :   nsresult rv = GetNextAddr(0, &addr);
     125           0 :   if (NS_FAILED(rv)) {
     126           0 :     return rv;
     127             :   }
     128             : 
     129             :   char buf[kIPv6CStrBufSize];
     130           0 :   if (NetAddrToString(&addr, buf, sizeof(buf))) {
     131           0 :     result.Assign(buf);
     132           0 :     return NS_OK;
     133             :   }
     134           0 :   NS_ERROR("NetAddrToString failed unexpectedly");
     135           0 :   return NS_ERROR_FAILURE; // conversion failed for some reason
     136             : }
     137             : 
     138             : NS_IMETHODIMP
     139           0 : ChildDNSRecord::HasMore(bool *result)
     140             : {
     141           0 :   *result = mCurrent < mLength;
     142           0 :   return NS_OK;
     143             : }
     144             : 
     145             : NS_IMETHODIMP
     146           0 : ChildDNSRecord::Rewind()
     147             : {
     148           0 :   mCurrent = 0;
     149           0 :   return NS_OK;
     150             : }
     151             : 
     152             : NS_IMETHODIMP
     153           0 : ChildDNSRecord::ReportUnusable(uint16_t aPort)
     154             : {
     155             :   // "We thank you for your feedback" == >/dev/null
     156             :   // TODO: we could send info back to parent.
     157           0 :   return NS_OK;
     158             : }
     159             : 
     160             : //-----------------------------------------------------------------------------
     161             : // CancelDNSRequestEvent
     162             : //-----------------------------------------------------------------------------
     163             : 
     164           0 : class CancelDNSRequestEvent : public Runnable
     165             : {
     166             : public:
     167           0 :   CancelDNSRequestEvent(DNSRequestChild* aDnsReq, nsresult aReason)
     168           0 :     : Runnable("net::CancelDNSRequestEvent")
     169             :     , mDnsRequest(aDnsReq)
     170           0 :     , mReasonForCancel(aReason)
     171           0 :   {}
     172             : 
     173           0 :   NS_IMETHOD Run() override
     174             :   {
     175           0 :     if (mDnsRequest->mIPCOpen) {
     176             :       // Send request to Parent process.
     177           0 :       mDnsRequest->SendCancelDNSRequest(mDnsRequest->mHost,
     178           0 :                                         mDnsRequest->mOriginAttributes,
     179           0 :                                         mDnsRequest->mFlags,
     180           0 :                                         mDnsRequest->mNetworkInterface,
     181           0 :                                         mReasonForCancel);
     182             :     }
     183           0 :     return NS_OK;
     184             :   }
     185             : private:
     186             :   RefPtr<DNSRequestChild> mDnsRequest;
     187             :   nsresult mReasonForCancel;
     188             : };
     189             : 
     190             : //-----------------------------------------------------------------------------
     191             : // DNSRequestChild
     192             : //-----------------------------------------------------------------------------
     193             : 
     194           0 : DNSRequestChild::DNSRequestChild(const nsCString& aHost,
     195             :                                  const OriginAttributes& aOriginAttributes,
     196             :                                  const uint32_t& aFlags,
     197             :                                  const nsCString& aNetworkInterface,
     198             :                                  nsIDNSListener *aListener,
     199           0 :                                  nsIEventTarget *target)
     200             :   : mListener(aListener)
     201             :   , mTarget(target)
     202             :   , mResultStatus(NS_OK)
     203             :   , mHost(aHost)
     204             :   , mOriginAttributes(aOriginAttributes)
     205             :   , mFlags(aFlags)
     206             :   , mNetworkInterface(aNetworkInterface)
     207           0 :   , mIPCOpen(false)
     208             : {
     209           0 : }
     210             : 
     211             : void
     212           0 : DNSRequestChild::StartRequest()
     213             : {
     214             :   // we can only do IPDL on the main thread
     215           0 :   if (!NS_IsMainThread()) {
     216           0 :     SystemGroup::Dispatch(
     217             :       "StartDNSRequestChild",
     218             :       TaskCategory::Other,
     219           0 :       NewRunnableMethod("net::DNSRequestChild::StartRequest",
     220             :                         this,
     221           0 :                         &DNSRequestChild::StartRequest));
     222           0 :     return;
     223             :   }
     224             : 
     225             :   nsCOMPtr<nsIEventTarget> systemGroupEventTarget
     226           0 :     = SystemGroup::EventTargetFor(TaskCategory::Other);
     227             : 
     228           0 :   gNeckoChild->SetEventTargetForActor(this, systemGroupEventTarget);
     229             : 
     230             :   mozilla::dom::ContentChild* cc =
     231           0 :     static_cast<mozilla::dom::ContentChild*>(gNeckoChild->Manager());
     232           0 :   if (cc->IsShuttingDown()) {
     233           0 :     return;
     234             :   }
     235             : 
     236             :   // Send request to Parent process.
     237           0 :   gNeckoChild->SendPDNSRequestConstructor(this, mHost, mOriginAttributes,
     238           0 :                                           mFlags, mNetworkInterface);
     239           0 :   mIPCOpen = true;
     240             : 
     241             :   // IPDL holds a reference until IPDL channel gets destroyed
     242           0 :   AddIPDLReference();
     243             : }
     244             : 
     245             : void
     246           0 : DNSRequestChild::CallOnLookupComplete()
     247             : {
     248           0 :   MOZ_ASSERT(mListener);
     249           0 :   mListener->OnLookupComplete(this, mResultRecord, mResultStatus);
     250           0 : }
     251             : 
     252             : mozilla::ipc::IPCResult
     253           0 : DNSRequestChild::RecvLookupCompleted(const DNSRequestResponse& reply)
     254             : {
     255           0 :   mIPCOpen = false;
     256           0 :   MOZ_ASSERT(mListener);
     257             : 
     258           0 :   switch (reply.type()) {
     259             :   case DNSRequestResponse::TDNSRecord: {
     260           0 :     mResultRecord = new ChildDNSRecord(reply.get_DNSRecord(), mFlags);
     261           0 :     break;
     262             :   }
     263             :   case DNSRequestResponse::Tnsresult: {
     264           0 :     mResultStatus = reply.get_nsresult();
     265           0 :     break;
     266             :   }
     267             :   default:
     268           0 :     NS_NOTREACHED("unknown type");
     269           0 :     return IPC_FAIL_NO_REASON(this);
     270             :   }
     271             : 
     272           0 :   MOZ_ASSERT(NS_IsMainThread());
     273             : 
     274           0 :   bool targetIsMain = false;
     275           0 :   if (!mTarget) {
     276           0 :     targetIsMain = true;
     277             :   } else {
     278           0 :     mTarget->IsOnCurrentThread(&targetIsMain);
     279             :   }
     280             : 
     281           0 :   if (targetIsMain) {
     282           0 :     CallOnLookupComplete();
     283             :   } else {
     284             :     nsCOMPtr<nsIRunnable> event =
     285           0 :       NewRunnableMethod("net::DNSRequestChild::CallOnLookupComplete",
     286             :                         this,
     287           0 :                         &DNSRequestChild::CallOnLookupComplete);
     288           0 :     mTarget->Dispatch(event, NS_DISPATCH_NORMAL);
     289             :   }
     290             : 
     291           0 :   Unused << Send__delete__(this);
     292             : 
     293           0 :   return IPC_OK();
     294             : }
     295             : 
     296             : void
     297           0 : DNSRequestChild::ReleaseIPDLReference()
     298             : {
     299             :   // Request is done or destroyed. Remove it from the hash table.
     300             :   RefPtr<ChildDNSService> dnsServiceChild =
     301           0 :     dont_AddRef(ChildDNSService::GetSingleton());
     302           0 :   dnsServiceChild->NotifyRequestDone(this);
     303             : 
     304           0 :   Release();
     305           0 : }
     306             : 
     307             : void
     308           0 : DNSRequestChild::ActorDestroy(ActorDestroyReason why)
     309             : {
     310           0 :   mIPCOpen = false;
     311           0 : }
     312             : 
     313             : //-----------------------------------------------------------------------------
     314             : // DNSRequestChild::nsISupports
     315             : //-----------------------------------------------------------------------------
     316             : 
     317           0 : NS_IMPL_ISUPPORTS(DNSRequestChild,
     318             :                   nsICancelable)
     319             : 
     320             : //-----------------------------------------------------------------------------
     321             : // DNSRequestChild::nsICancelable
     322             : //-----------------------------------------------------------------------------
     323             : 
     324             : NS_IMETHODIMP
     325           0 : DNSRequestChild::Cancel(nsresult reason)
     326             : {
     327           0 :   if(mIPCOpen) {
     328             :     // We can only do IPDL on the main thread
     329           0 :     nsCOMPtr<nsIRunnable> runnable = new CancelDNSRequestEvent(this, reason);
     330             :     SystemGroup::Dispatch("CancelDNSRequest",
     331             :                           TaskCategory::Other,
     332           0 :                           runnable.forget());
     333             :   }
     334           0 :   return NS_OK;
     335             : }
     336             : 
     337             : //------------------------------------------------------------------------------
     338             : } // namespace net
     339             : } // namespace mozilla

Generated by: LCOV version 1.13