tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsIOService.h (12123B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #ifndef nsIOService_h__
      7 #define nsIOService_h__
      8 
      9 #include "nsStringFwd.h"
     10 #include "nsIIOService.h"
     11 #include "nsTArray.h"
     12 #include "nsCOMPtr.h"
     13 #include "nsIObserver.h"
     14 #include "nsIWeakReferenceUtils.h"
     15 #include "nsILoadInfo.h"
     16 #include "nsINetUtil.h"
     17 #include "nsIChannelEventSink.h"
     18 #include "nsCategoryCache.h"
     19 #include "nsISpeculativeConnect.h"
     20 #include "nsWeakReference.h"
     21 #include "mozilla/Atomics.h"
     22 #include "mozilla/RWLock.h"
     23 #include "mozilla/net/ProtocolHandlerInfo.h"
     24 #include "prtime.h"
     25 #include "nsICaptivePortalService.h"
     26 #include "nsIObserverService.h"
     27 #include "nsTHashSet.h"
     28 #include "nsWeakReference.h"
     29 #include "nsNetCID.h"
     30 #include "SimpleURIUnknownSchemes.h"
     31 
     32 // We don't want to expose this observer topic.
     33 // Intended internal use only for remoting offline/inline events.
     34 // See Bug 552829
     35 #define NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC "ipc:network:set-offline"
     36 #define NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC "ipc:network:set-connectivity"
     37 
     38 class nsINetworkLinkService;
     39 class nsIPrefBranch;
     40 class nsIProtocolProxyService2;
     41 class nsIProxyInfo;
     42 class nsPISocketTransportService;
     43 namespace mozilla {
     44 class MemoryReportingProcess;
     45 namespace net {
     46 class NeckoChild;
     47 class nsAsyncRedirectVerifyHelper;
     48 class SocketProcessHost;
     49 class SocketProcessMemoryReporter;
     50 union NetAddr;
     51 
     52 class nsIOService final : public nsIIOService,
     53                          public nsIObserver,
     54                          public nsINetUtil,
     55                          public nsISpeculativeConnect,
     56                          public nsSupportsWeakReference,
     57                          public nsIIOServiceInternal,
     58                          public nsIObserverService {
     59 public:
     60  NS_DECL_THREADSAFE_ISUPPORTS
     61  NS_DECL_NSIIOSERVICE
     62  NS_DECL_NSIOBSERVER
     63  NS_DECL_NSINETUTIL
     64  NS_DECL_NSISPECULATIVECONNECT
     65  NS_DECL_NSIIOSERVICEINTERNAL
     66  NS_DECL_NSIOBSERVERSERVICE
     67 
     68  // Gets the singleton instance of the IO Service, creating it as needed
     69  // Returns nullptr on out of memory or failure to initialize.
     70  static already_AddRefed<nsIOService> GetInstance();
     71 
     72  nsresult Init();
     73  nsresult NewURI(const char* aSpec, nsIURI* aBaseURI, nsIURI** result,
     74                  nsIProtocolHandler** hdlrResult);
     75 
     76  // Called by channels before a redirect happens. This notifies the global
     77  // redirect observers.
     78  nsresult AsyncOnChannelRedirect(nsIChannel* oldChan, nsIChannel* newChan,
     79                                  uint32_t flags,
     80                                  nsAsyncRedirectVerifyHelper* helper);
     81 
     82  bool IsOffline() { return mOffline; }
     83  bool InSleepMode() { return mInSleepMode; }
     84  PRIntervalTime LastOfflineStateChange() { return mLastOfflineStateChange; }
     85  PRIntervalTime LastConnectivityChange() { return mLastConnectivityChange; }
     86  PRIntervalTime LastNetworkLinkChange() { return mLastNetworkLinkChange; }
     87  bool IsNetTearingDown() {
     88    return mShutdown || mOfflineForProfileChange ||
     89           mHttpHandlerAlreadyShutingDown;
     90  }
     91  PRIntervalTime NetTearingDownStarted() { return mNetTearingDownStarted; }
     92 
     93  // nsHttpHandler is going to call this function to inform nsIOService that
     94  // network is in process of tearing down. Moving nsHttpConnectionMgr::Shutdown
     95  // to nsIOService caused problems (bug 1242755) so we doing it in this way. As
     96  // soon as nsIOService gets notification that it is shutdown it is going to
     97  // reset mHttpHandlerAlreadyShutingDown.
     98  void SetHttpHandlerAlreadyShutingDown();
     99 
    100  bool IsLinkUp();
    101 
    102  // Converts an internal URI (e.g. one that has a username and password in
    103  // it) into one which we can expose to the user, for example on the URL bar.
    104  static already_AddRefed<nsIURI> CreateExposableURI(nsIURI*);
    105 
    106  // Used to count the total number of HTTP requests made
    107  void IncrementRequestNumber() { mTotalRequests++; }
    108  uint32_t GetTotalRequestNumber() { return mTotalRequests; }
    109  // Used to keep "race cache with network" stats
    110  void IncrementCacheWonRequestNumber() { mCacheWon++; }
    111  uint32_t GetCacheWonRequestNumber() { return mCacheWon; }
    112  void IncrementNetWonRequestNumber() { mNetWon++; }
    113  uint32_t GetNetWonRequestNumber() { return mNetWon; }
    114 
    115  // Used to trigger a recheck of the captive portal status
    116  nsresult RecheckCaptivePortal();
    117 
    118  void OnProcessLaunchComplete(SocketProcessHost* aHost, bool aSucceeded);
    119  void OnProcessUnexpectedShutdown(SocketProcessHost* aHost);
    120  bool SocketProcessReady();
    121  static void NotifySocketProcessPrefsChanged(const char* aName, void* aSelf);
    122  void NotifySocketProcessPrefsChanged(const char* aName);
    123  static bool UseSocketProcess(bool aCheckAgain = false);
    124 
    125  bool IsSocketProcessLaunchComplete();
    126 
    127  // Call func immediately if socket process is launched completely. Otherwise,
    128  // |func| will be queued and then executed in the *main thread* once socket
    129  // process is launced.
    130  void CallOrWaitForSocketProcess(const std::function<void()>& aFunc);
    131 
    132  int32_t SocketProcessPid();
    133  SocketProcessHost* SocketProcess() { return mSocketProcess; }
    134 
    135  friend SocketProcessMemoryReporter;
    136  RefPtr<MemoryReportingProcess> GetSocketProcessMemoryReporter();
    137 
    138  // Lookup the ProtocolHandlerInfo based on a given scheme.
    139  // Safe to call from any thread.
    140  ProtocolHandlerInfo LookupProtocolHandler(const nsACString& aScheme);
    141 
    142  static void OnTLSPrefChange(const char* aPref, void* aSelf);
    143 
    144  nsresult LaunchSocketProcess();
    145 
    146  static bool TooManySocketProcessCrash();
    147  static void IncreaseSocketProcessCrashCount();
    148 #ifdef MOZ_WIDGET_ANDROID
    149  static bool ShouldAddAdditionalSearchHeaders(nsIURI* aURI, bool* val);
    150 #endif
    151 
    152  // Returns true if this is an essential domain and a fallback domain
    153  // mapping exists.
    154  bool GetFallbackDomain(const nsACString& aDomain,
    155                         nsACString& aFallbackDomain);
    156 
    157  NS_IMETHODIMP GetOverridenIpAddressSpace(
    158      nsILoadInfo::IPAddressSpace* aIpAddressSpace, const NetAddr& aAddr);
    159 
    160  bool ShouldSkipDomainForLNA(const nsACString& aDomain);
    161 
    162 private:
    163  // These shouldn't be called directly:
    164  // - construct using GetInstance
    165  // - destroy using Release
    166  nsIOService();
    167  ~nsIOService();
    168  nsresult SetConnectivityInternal(bool aConnectivity);
    169 
    170  nsresult OnNetworkLinkEvent(const char* data);
    171 
    172  nsresult InitializeCaptivePortalService();
    173  nsresult RecheckCaptivePortalIfLocalRedirect(nsIChannel* newChan);
    174 
    175  // Prefs wrangling
    176  static void PrefsChanged(const char* pref, void* self);
    177  void PrefsChanged(const char* pref = nullptr);
    178  void ParsePortList(const char* pref, bool remove);
    179 
    180  nsresult InitializeSocketTransportService();
    181  nsresult InitializeNetworkLinkService();
    182  nsresult InitializeProtocolProxyService();
    183 
    184  // consolidated helper function
    185  void LookupProxyInfo(nsIURI* aURI, nsIURI* aProxyURI, uint32_t aProxyFlags,
    186                       nsCString* aScheme, nsIProxyInfo** outPI);
    187 
    188  nsresult NewChannelFromURIWithProxyFlagsInternal(
    189      nsIURI* aURI, nsIURI* aProxyURI, uint32_t aProxyFlags,
    190      nsINode* aLoadingNode, nsIPrincipal* aLoadingPrincipal,
    191      nsIPrincipal* aTriggeringPrincipal,
    192      const mozilla::Maybe<mozilla::dom::ClientInfo>& aLoadingClientInfo,
    193      const mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor>& aController,
    194      uint32_t aSecurityFlags, nsContentPolicyType aContentPolicyType,
    195      uint32_t aSandboxFlags, nsIChannel** result);
    196 
    197  nsresult NewChannelFromURIWithProxyFlagsInternal(nsIURI* aURI,
    198                                                   nsIURI* aProxyURI,
    199                                                   uint32_t aProxyFlags,
    200                                                   nsILoadInfo* aLoadInfo,
    201                                                   nsIChannel** result);
    202 
    203  nsresult SpeculativeConnectInternal(
    204      nsIURI* aURI, nsIPrincipal* aPrincipal,
    205      Maybe<OriginAttributes>&& aOriginAttributes,
    206      nsIInterfaceRequestor* aCallbacks, bool aAnonymous);
    207 
    208  void DestroySocketProcess();
    209 
    210  nsresult SetOfflineInternal(bool offline, bool notifySocketProcess = true);
    211 
    212  bool UsesExternalProtocolHandler(const nsACString& aScheme)
    213      MOZ_REQUIRES_SHARED(mLock);
    214 
    215  void UpdateAddressSpaceOverrideList(const char* aPrefName,
    216                                      nsTArray<nsCString>& aTargetList);
    217  void UpdateSkipDomainsList();
    218 
    219 private:
    220  mozilla::Atomic<bool, mozilla::Relaxed> mOffline{true};
    221  mozilla::Atomic<bool, mozilla::Relaxed> mOfflineForProfileChange{false};
    222  bool mManageLinkStatus{false};
    223  mozilla::Atomic<bool, mozilla::Relaxed> mConnectivity{true};
    224 
    225  // Used to handle SetOffline() reentrancy.  See the comment in
    226  // SetOffline() for more details.
    227  bool mSettingOffline{false};
    228  bool mSetOfflineValue{false};
    229 
    230  bool mSocketProcessLaunchComplete{false};
    231 
    232  mozilla::Atomic<bool, mozilla::Relaxed> mShutdown{false};
    233  mozilla::Atomic<bool, mozilla::Relaxed> mHttpHandlerAlreadyShutingDown{false};
    234  mozilla::Atomic<bool, mozilla::Relaxed> mInSleepMode{false};
    235 
    236  nsCOMPtr<nsPISocketTransportService> mSocketTransportService;
    237  nsCOMPtr<nsICaptivePortalService> mCaptivePortalService;
    238  nsCOMPtr<nsINetworkLinkService> mNetworkLinkService;
    239  bool mNetworkLinkServiceInitialized{false};
    240 
    241  // cached categories
    242  nsCategoryCache<nsIChannelEventSink> mChannelEventSinks{
    243      NS_CHANNEL_EVENT_SINK_CATEGORY};
    244 
    245  RWLock mLock{"nsIOService::mLock"};
    246  nsTArray<int32_t> mRestrictedPortList MOZ_GUARDED_BY(mLock);
    247  nsTArray<nsCString> mForceExternalSchemes MOZ_GUARDED_BY(mLock);
    248 
    249  nsTArray<nsCString> mPublicAddressSpaceOverridesList MOZ_GUARDED_BY(mLock);
    250  nsTArray<nsCString> mPrivateAddressSpaceOverridesList MOZ_GUARDED_BY(mLock);
    251  nsTArray<nsCString> mLocalAddressSpaceOverrideList MOZ_GUARDED_BY(mLock);
    252  nsTArray<nsCString> mLNASkipDomainsList MOZ_GUARDED_BY(mLock);
    253 
    254  nsTHashMap<nsCString, RuntimeProtocolHandler> mRuntimeProtocolHandlers
    255      MOZ_GUARDED_BY(mLock);
    256 
    257  uint32_t mTotalRequests{0};
    258  uint32_t mCacheWon{0};
    259  uint32_t mNetWon{0};
    260  static uint32_t sSocketProcessCrashedCount;
    261 
    262  // These timestamps are needed for collecting telemetry on PR_Connect,
    263  // PR_ConnectContinue and PR_Close blocking time.  If we spend very long
    264  // time in any of these functions we want to know if and what network
    265  // change has happened shortly before.
    266  mozilla::Atomic<PRIntervalTime> mLastOfflineStateChange;
    267  mozilla::Atomic<PRIntervalTime> mLastConnectivityChange;
    268  mozilla::Atomic<PRIntervalTime> mLastNetworkLinkChange;
    269 
    270  // Time a network tearing down started.
    271  mozilla::Atomic<PRIntervalTime> mNetTearingDownStarted{0};
    272 
    273  SocketProcessHost* mSocketProcess{nullptr};
    274 
    275  // Events should be executed after the socket process is launched. Will
    276  // dispatch these events while socket process fires OnProcessLaunchComplete.
    277  // Note: this array is accessed only on the main thread.
    278  nsTArray<std::function<void()>> mPendingEvents;
    279 
    280  // The observer notifications need to be forwarded to socket process.
    281  nsTHashSet<nsCString> mObserverTopicForSocketProcess;
    282  // Some noticications (e.g., NS_XPCOM_SHUTDOWN_OBSERVER_ID) are triggered in
    283  // socket process, so we should not send the notifications again.
    284  nsTHashSet<nsCString> mSocketProcessTopicBlockedList;
    285  // Used to store the topics that are already observed by IOService.
    286  nsTHashSet<nsCString> mIOServiceTopicList;
    287 
    288  nsCOMPtr<nsIObserverService> mObserverService;
    289 
    290  SimpleURIUnknownSchemes mSimpleURIUnknownSchemes;
    291 
    292  // Maps essential domains to a fallback domain that can be used
    293  // to retry that request when it fails.
    294  // Only accessible via main thread.
    295  nsTHashMap<nsCStringHashKey, nsCString> mEssentialDomainMapping;
    296 
    297 public:
    298  // Used for all default buffer sizes that necko allocates.
    299  static uint32_t gDefaultSegmentSize;
    300  static uint32_t gDefaultSegmentCount;
    301 };
    302 
    303 /**
    304 * Reference to the IO service singleton. May be null.
    305 */
    306 extern nsIOService* gIOService;
    307 
    308 }  // namespace net
    309 }  // namespace mozilla
    310 
    311 #endif  // nsIOService_h__