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__