tor-browser

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

nsHttpConnectionInfo.h (12713B)


      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 #ifndef nsHttpConnectionInfo_h__
      8 #define nsHttpConnectionInfo_h__
      9 
     10 #include "nsHttp.h"
     11 #include "nsProxyInfo.h"
     12 #include "nsCOMPtr.h"
     13 #include "nsStringFwd.h"
     14 #include "mozilla/Logging.h"
     15 #include "mozilla/BasePrincipal.h"
     16 #include "mozilla/AlreadyAddRefed.h"
     17 #include "ARefBase.h"
     18 #include "nsIRequest.h"
     19 
     20 //-----------------------------------------------------------------------------
     21 // nsHttpConnectionInfo - holds the properties of a connection
     22 //-----------------------------------------------------------------------------
     23 
     24 // http:// uris through a proxy will all share the same CI, because they can
     25 // all use the same connection. (modulo pb and anonymous flags). They just use
     26 // the proxy as the origin host name.
     27 // however, https:// uris tunnel through the proxy so they will have different
     28 // CIs - the CI reflects both the proxy and the origin.
     29 // however, proxy conenctions made with http/2 (or spdy) can tunnel to the
     30 // origin and multiplex non tunneled transactions at the same time, so they have
     31 // a special wildcard CI that accepts all origins through that proxy.
     32 
     33 class nsISVCBRecord;
     34 
     35 namespace mozilla {
     36 namespace net {
     37 
     38 extern LazyLogModule gHttpLog;
     39 class HttpConnectionInfoCloneArgs;
     40 class nsHttpTransaction;
     41 
     42 class nsHttpConnectionInfo final : public ARefBase {
     43 public:
     44  nsHttpConnectionInfo(const nsACString& originHost, int32_t originPort,
     45                       const nsACString& npnToken, const nsACString& username,
     46                       nsProxyInfo* proxyInfo,
     47                       const OriginAttributes& originAttributes,
     48                       bool endToEndSSL = false, bool aIsHttp3 = false,
     49                       bool aWebTransport = false);
     50 
     51  // this version must use TLS and you may supply separate
     52  // connection (aka routing) information than the authenticated
     53  // origin information
     54  nsHttpConnectionInfo(const nsACString& originHost, int32_t originPort,
     55                       const nsACString& npnToken, const nsACString& username,
     56                       nsProxyInfo* proxyInfo,
     57                       const OriginAttributes& originAttributes,
     58                       const nsACString& routedHost, int32_t routedPort,
     59                       bool aIsHttp3, bool aWebTransport = false);
     60 
     61  static void SerializeHttpConnectionInfo(nsHttpConnectionInfo* aInfo,
     62                                          HttpConnectionInfoCloneArgs& aArgs);
     63  static already_AddRefed<nsHttpConnectionInfo>
     64  DeserializeHttpConnectionInfoCloneArgs(
     65      const HttpConnectionInfoCloneArgs& aInfoArgs);
     66 
     67  static void BuildOriginFrameHashKey(nsACString& newKey,
     68                                      nsHttpConnectionInfo* ci,
     69                                      const nsACString& host, int32_t port);
     70 
     71 private:
     72  virtual ~nsHttpConnectionInfo() {
     73    MOZ_LOG(gHttpLog, LogLevel::Debug,
     74            ("Destroying nsHttpConnectionInfo @%p\n", this));
     75  }
     76 
     77  void BuildHashKey();
     78  void RebuildHashKey();
     79 
     80  // See comments in nsHttpConnectionInfo::BuildHashKey for the meaning of each
     81  // field.
     82  enum class HashKeyIndex : uint32_t {
     83    Proxy = 0,
     84    EndToEndSSL,
     85    Anonymous,
     86    Private,
     87    InsecureScheme,
     88    NoSpdy,
     89    BeConservative,
     90    AnonymousAllowClientCert,
     91    FallbackConnection,
     92    WebTransport,
     93    End,
     94  };
     95  constexpr inline auto UnderlyingIndex(HashKeyIndex aIndex) const {
     96    return std::underlying_type_t<HashKeyIndex>(aIndex);
     97  }
     98 
     99 public:
    100  const nsCString& HashKey() const { return mHashKey; }
    101 
    102  const nsCString& GetOrigin() const { return mOrigin; }
    103  const char* Origin() const { return mOrigin.get(); }
    104  int32_t OriginPort() const { return mOriginPort; }
    105 
    106  const nsCString& GetRoutedHost() const { return mRoutedHost; }
    107  const char* RoutedHost() const { return mRoutedHost.get(); }
    108  int32_t RoutedPort() const { return mRoutedPort; }
    109 
    110  // OK to treat these as an infalible allocation
    111  already_AddRefed<nsHttpConnectionInfo> Clone() const;
    112  // This main prupose of this function is to clone this connection info, but
    113  // replace mRoutedHost with SvcDomainName in the given SVCB record. Note that
    114  // if SvcParamKeyPort and SvcParamKeyAlpn are presented in the SVCB record,
    115  // mRoutedPort and mNPNToken will be replaced as well.
    116  already_AddRefed<nsHttpConnectionInfo> CloneAndAdoptHTTPSSVCRecord(
    117      nsISVCBRecord* aRecord) const;
    118  void CloneAsDirectRoute(nsHttpConnectionInfo** outCI,
    119                          nsProxyInfo* aProxyInfo = nullptr);
    120 
    121  already_AddRefed<nsHttpConnectionInfo> CreateConnectUDPFallbackConnInfo();
    122 
    123  [[nodiscard]] nsresult CreateWildCard(nsHttpConnectionInfo** outParam);
    124 
    125  const char* ProxyHost() const {
    126    return mProxyInfo ? mProxyInfo->Host().get() : nullptr;
    127  }
    128  int32_t ProxyPort() const { return mProxyInfo ? mProxyInfo->Port() : -1; }
    129  const char* ProxyType() const {
    130    return mProxyInfo ? mProxyInfo->Type() : nullptr;
    131  }
    132  const char* ProxyUsername() const {
    133    return mProxyInfo ? mProxyInfo->Username().get() : nullptr;
    134  }
    135  const char* ProxyPassword() const {
    136    return mProxyInfo ? mProxyInfo->Password().get() : nullptr;
    137  }
    138  uint32_t ProxyFlag() const {
    139    uint32_t flags = 0;
    140    if (mProxyInfo) {
    141      mProxyInfo->GetFlags(&flags);
    142    }
    143    return flags;
    144  }
    145 
    146  const nsCString& ProxyAuthorizationHeader() const {
    147    return mProxyInfo ? mProxyInfo->ProxyAuthorizationHeader() : EmptyCString();
    148  }
    149  const nsCString& ConnectionIsolationKey() const {
    150    return mProxyInfo ? mProxyInfo->ConnectionIsolationKey() : EmptyCString();
    151  }
    152 
    153  // Compare this connection info to another...
    154  // Two connections are 'equal' if they end up talking the same
    155  // protocol to the same server. This is needed to properly manage
    156  // persistent connections to proxies
    157  // Note that we don't care about transparent proxies -
    158  // it doesn't matter if we're talking via socks or not, since
    159  // a request will end up at the same host.
    160  bool Equals(const nsHttpConnectionInfo* info) {
    161    return mHashKey.Equals(info->HashKey());
    162  }
    163 
    164  const char* Username() const { return mUsername.get(); }
    165  nsProxyInfo* ProxyInfo() const { return mProxyInfo; }
    166  int32_t DefaultPort() const {
    167    return mEndToEndSSL ? NS_HTTPS_DEFAULT_PORT : NS_HTTP_DEFAULT_PORT;
    168  }
    169  void SetAnonymous(bool anon) {
    170    SetHashCharAt(anon ? 'A' : '.', HashKeyIndex::Anonymous);
    171  }
    172  bool GetAnonymous() const {
    173    return GetHashCharAt(HashKeyIndex::Anonymous) == 'A';
    174  }
    175  void SetPrivate(bool priv) {
    176    SetHashCharAt(priv ? 'P' : '.', HashKeyIndex::Private);
    177  }
    178  bool GetPrivate() const {
    179    return GetHashCharAt(HashKeyIndex::Private) == 'P';
    180  }
    181  void SetInsecureScheme(bool insecureScheme) {
    182    SetHashCharAt(insecureScheme ? 'I' : '.', HashKeyIndex::InsecureScheme);
    183  }
    184  bool GetInsecureScheme() const {
    185    return GetHashCharAt(HashKeyIndex::InsecureScheme) == 'I';
    186  }
    187 
    188  void SetNoSpdy(bool aNoSpdy) {
    189    SetHashCharAt(aNoSpdy ? 'X' : '.', HashKeyIndex::NoSpdy);
    190    if (aNoSpdy && mNPNToken == "h2"_ns) {
    191      mNPNToken.Truncate();
    192      RebuildHashKey();
    193    }
    194  }
    195  bool GetNoSpdy() const { return GetHashCharAt(HashKeyIndex::NoSpdy) == 'X'; }
    196 
    197  void SetBeConservative(bool aBeConservative) {
    198    SetHashCharAt(aBeConservative ? 'C' : '.', HashKeyIndex::BeConservative);
    199  }
    200  bool GetBeConservative() const {
    201    return GetHashCharAt(HashKeyIndex::BeConservative) == 'C';
    202  }
    203 
    204  void SetAnonymousAllowClientCert(bool anon) {
    205    SetHashCharAt(anon ? 'B' : '.', HashKeyIndex::AnonymousAllowClientCert);
    206  }
    207  bool GetAnonymousAllowClientCert() const {
    208    return GetHashCharAt(HashKeyIndex::AnonymousAllowClientCert) == 'B';
    209  }
    210 
    211  void SetFallbackConnection(bool aFallback) {
    212    SetHashCharAt(aFallback ? 'F' : '.', HashKeyIndex::FallbackConnection);
    213  }
    214  bool GetFallbackConnection() const {
    215    return GetHashCharAt(HashKeyIndex::FallbackConnection) == 'F';
    216  }
    217 
    218  void SetTlsFlags(uint32_t aTlsFlags);
    219  uint32_t GetTlsFlags() const { return mTlsFlags; }
    220 
    221  // IsTrrServiceChannel means that this connection is used to send TRR requests
    222  // over
    223  void SetIsTrrServiceChannel(bool aIsTRRChannel) {
    224    mIsTrrServiceChannel = aIsTRRChannel;
    225  }
    226  bool GetIsTrrServiceChannel() const { return mIsTrrServiceChannel; }
    227 
    228  void SetTRRMode(nsIRequest::TRRMode aTRRMode);
    229  nsIRequest::TRRMode GetTRRMode() const { return mTRRMode; }
    230 
    231  void SetIPv4Disabled(bool aNoIPv4);
    232  bool GetIPv4Disabled() const { return mIPv4Disabled; }
    233 
    234  void SetIPv6Disabled(bool aNoIPv6);
    235  bool GetIPv6Disabled() const { return mIPv6Disabled; }
    236 
    237  void SetWebTransport(bool aWebTransport);
    238  bool GetWebTransport() const { return mWebTransport; }
    239 
    240  void SetWebTransportId(uint64_t id);
    241  uint32_t GetWebTransportId() const { return mWebTransportId; };
    242 
    243  const nsCString& GetNPNToken() const { return mNPNToken; }
    244  const nsCString& GetProxyNPNToken() const { return mProxyNPNToken; }
    245  const nsCString& GetUsername() { return mUsername; }
    246 
    247  const OriginAttributes& GetOriginAttributes() { return mOriginAttributes; }
    248 
    249  // Returns true for any kind of proxy (http, socks, https, etc..)
    250  bool UsingProxy();
    251 
    252  // Returns true when proxying over HTTP or HTTPS
    253  bool UsingHttpProxy() const { return mUsingHttpProxy || mUsingHttpsProxy; }
    254 
    255  // Returns true when only proxying over HTTP
    256  bool UsingOnlyHttpProxy() const { return mUsingHttpProxy; }
    257 
    258  // Returns true when proxying over HTTPS
    259  bool UsingHttpsProxy() const { return mUsingHttpsProxy; }
    260 
    261  // Returns true when a resource is in SSL end to end (e.g. https:// uri)
    262  bool EndToEndSSL() const { return mEndToEndSSL; }
    263 
    264  // Returns true when at least first hop is SSL (e.g. proxy over https or https
    265  // uri)
    266  bool FirstHopSSL() const { return mEndToEndSSL || mUsingHttpsProxy; }
    267 
    268  // Returns true when CONNECT is used to tunnel through the proxy (e.g.
    269  // https:// or ws://)
    270  bool UsingConnect() const { return mUsingConnect; }
    271 
    272  // Returns true when origin/proxy is an RFC1918 literal.
    273  bool HostIsLocalIPLiteral() const;
    274 
    275  bool GetLessThanTls13() const { return mLessThanTls13; }
    276  void SetLessThanTls13(bool aLessThanTls13) {
    277    mLessThanTls13 = aLessThanTls13;
    278  }
    279 
    280  bool IsHttp3() const { return mIsHttp3; }
    281  bool IsHttp3ProxyConnection() const { return mIsHttp3ProxyConnection; }
    282 
    283  void SetHasIPHintAddress(bool aHasIPHint) { mHasIPHintAddress = aHasIPHint; }
    284  bool HasIPHintAddress() const { return mHasIPHintAddress; }
    285 
    286  void SetEchConfig(const nsACString& aEchConfig) { mEchConfig = aEchConfig; }
    287  const nsCString& GetEchConfig() const { return mEchConfig; }
    288 
    289  static uint64_t GenerateNewWebTransportId();
    290 
    291 private:
    292  void Init(const nsACString& host, int32_t port, const nsACString& npnToken,
    293            const nsACString& username, nsProxyInfo* proxyInfo,
    294            const OriginAttributes& originAttributes, bool e2eSSL,
    295            bool aIsHttp3, bool aWebTransport);
    296  void SetOriginServer(const nsACString& host, int32_t port);
    297  nsCString::char_type GetHashCharAt(HashKeyIndex aIndex) const {
    298    return mHashKey.CharAt(UnderlyingIndex(aIndex));
    299  }
    300  void SetHashCharAt(nsCString::char_type aValue, HashKeyIndex aIndex) {
    301    mHashKey.SetCharAt(aValue, UnderlyingIndex(aIndex));
    302  }
    303 
    304  nsCString mOrigin;
    305  int32_t mOriginPort = 0;
    306  nsCString mRoutedHost;
    307  int32_t mRoutedPort;
    308 
    309  nsCString mHashKey;
    310  nsCString mUsername;
    311  nsCOMPtr<nsProxyInfo> mProxyInfo;
    312  bool mUsingHttpProxy = false;
    313  bool mUsingHttpsProxy = false;
    314  bool mEndToEndSSL = false;
    315  // if will use CONNECT with http proxy
    316  bool mUsingConnect = false;
    317  nsCString mNPNToken;
    318  nsCString mProxyNPNToken;
    319  OriginAttributes mOriginAttributes;
    320  nsIRequest::TRRMode mTRRMode;
    321 
    322  uint32_t mTlsFlags = 0;
    323  uint16_t mIsTrrServiceChannel : 1;
    324  uint16_t mIPv4Disabled : 1;
    325  uint16_t mIPv6Disabled : 1;
    326 
    327  bool mLessThanTls13;  // This will be set to true if we negotiate less than
    328                        // tls1.3. If the tls version is till not know or it
    329                        // is 1.3 or greater the value will be false.
    330  bool mIsHttp3 = false;
    331  bool mIsHttp3ProxyConnection = false;
    332  bool mWebTransport = false;
    333 
    334  bool mHasIPHintAddress = false;
    335  nsCString mEchConfig;
    336 
    337  uint64_t mWebTransportId = 0;  // current dedicated Id only used for
    338                                 // Webtransport, zero means not dedicated
    339 
    340  // for RefPtr
    341  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsHttpConnectionInfo, override)
    342 };
    343 
    344 }  // namespace net
    345 }  // namespace mozilla
    346 
    347 #endif  // nsHttpConnectionInfo_h__