• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef NET_QUIC_QUIC_CONTEXT_H_
6 #define NET_QUIC_QUIC_CONTEXT_H_
7 
8 #include <memory>
9 
10 #include "base/containers/contains.h"
11 #include "base/feature_list.h"
12 #include "base/time/time.h"
13 #include "net/base/features.h"
14 #include "net/base/host_port_pair.h"
15 #include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_crypto_client_config.h"
16 #include "net/third_party/quiche/src/quiche/quic/core/quic_connection.h"
17 
18 namespace net {
19 
20 // Default QUIC supported versions used in absence of any external
21 // configuration.
22 inline NET_EXPORT_PRIVATE quic::ParsedQuicVersionVector
DefaultSupportedQuicVersions()23 DefaultSupportedQuicVersions() {
24   // The ordering of this list does not matter for Chrome because it respects
25   // the ordering received from the server via Alt-Svc. However, cronet offers
26   // an addQuicHint() API which uses the first version from this list until
27   // it receives Alt-Svc from the server.
28   return quic::ParsedQuicVersionVector{quic::ParsedQuicVersion::RFCv1()};
29 }
30 
31 // Return the QUIC version to be used for connections to proxies, for which
32 // there is currently no other way to determine QUIC version.
33 inline NET_EXPORT_PRIVATE quic::ParsedQuicVersion
SupportedQuicVersionForProxying()34 SupportedQuicVersionForProxying() {
35   // Assume that all QUIC proxies use RFCv1, as the current support for proxy
36   // configuration does not allow any way to indicate what version they
37   // support. RFCv1 is commonly supported and is valid for IP Protection
38   // proxies, but this may not be true more broadly.
39   return quic::ParsedQuicVersion::RFCv1();
40 }
41 
42 // Obsolete QUIC supported versions are versions that are supported by the
43 // QUIC shared code but that Chrome refuses to use because modern clients
44 // should only use versions at least as recent as the oldest default version.
ObsoleteQuicVersions()45 inline NET_EXPORT_PRIVATE quic::ParsedQuicVersionVector ObsoleteQuicVersions() {
46   return quic::ParsedQuicVersionVector{quic::ParsedQuicVersion::Q046(),
47                                        quic::ParsedQuicVersion::Draft29()};
48 }
49 
50 // All of the QUIC versions that Chrome can support. This is the subset of
51 // QUIC versions that the QUIC shared code supports that are not on the list
52 // of versions that Chrome considers obsolete.
53 inline NET_EXPORT_PRIVATE quic::ParsedQuicVersionVector
AllSupportedQuicVersions()54 AllSupportedQuicVersions() {
55   quic::ParsedQuicVersionVector obsolete_versions = ObsoleteQuicVersions();
56   quic::ParsedQuicVersionVector all_supported_versions =
57       quic::AllSupportedVersions();
58   quic::ParsedQuicVersionVector filtered_versions;
59   for (const auto& version : all_supported_versions) {
60     if (!base::Contains(obsolete_versions, version)) {
61       filtered_versions.push_back(version);
62     }
63   }
64   return filtered_versions;
65 }
66 
67 // When a connection is idle for 30 seconds it will be closed.
68 inline constexpr base::TimeDelta kIdleConnectionTimeout = base::Seconds(30);
69 
70 // Sessions can migrate if they have been idle for less than this period.
71 constexpr base::TimeDelta kDefaultIdleSessionMigrationPeriod =
72     base::Seconds(30);
73 
74 // The default maximum time allowed to have no retransmittable packets on the
75 // wire (after sending the first retransmittable packet) if
76 // |migrate_session_early_v2_| is true. PING frames will be sent as needed to
77 // enforce this.
78 constexpr base::TimeDelta kDefaultRetransmittableOnWireTimeout =
79     base::Milliseconds(200);
80 
81 // The default maximum time QUIC session could be on non-default network before
82 // migrate back to default network.
83 inline constexpr base::TimeDelta kMaxTimeOnNonDefaultNetwork =
84     base::Seconds(128);
85 
86 // The default maximum number of migrations to non default network on write
87 // error per network.
88 const int64_t kMaxMigrationsToNonDefaultNetworkOnWriteError = 5;
89 
90 // The default maximum number of migrations to non default network on path
91 // degrading per network.
92 const int64_t kMaxMigrationsToNonDefaultNetworkOnPathDegrading = 5;
93 
94 // QUIC's socket receive buffer size.
95 // We should adaptively set this buffer size, but for now, we'll use a size
96 // that seems large enough to receive data at line rate for most connections,
97 // and does not consume "too much" memory.
98 const int32_t kQuicSocketReceiveBufferSize = 1024 * 1024;  // 1MB
99 
100 // Structure containing simple configuration options and experiments for QUIC.
101 struct NET_EXPORT QuicParams {
102   QuicParams();
103   QuicParams(const QuicParams& other);
104   ~QuicParams();
105 
106   // QUIC runtime configuration options.
107 
108   // Versions of QUIC which may be used.
109   quic::ParsedQuicVersionVector supported_versions =
110       DefaultSupportedQuicVersions();
111   // Limit on the size of QUIC packets.
112   size_t max_packet_length = quic::kDefaultMaxPacketSize;
113   // Additional packet size to use for QUIC connections used to carry
114   // proxy traffic.  This is required for QUIC connections tunneled via
115   // CONNECT-UDP, as the tunneled connection's packets must fit within the
116   // datagram frames of the tunnel connection, and all QUIC connections require
117   // an MTU of 1200. See https://crbug.com/331221745.
118   size_t additional_proxy_packet_length = 100;
119   // Maximum number of server configs that are to be stored in
120   // HttpServerProperties, instead of the disk cache.
121   size_t max_server_configs_stored_in_properties = 0u;
122   // QUIC will be used for all connections in this set.
123   std::set<HostPortPair> origins_to_force_quic_on;
124   // WebTransport developer mode disables the requirement that all QUIC
125   // connections are anchored to a system certificate root, but only for
126   // WebTransport connections.
127   bool webtransport_developer_mode = false;
128   // Set of QUIC tags to send in the handshake's connection options.
129   quic::QuicTagVector connection_options;
130   // Set of QUIC tags to send in the handshake's connection options that only
131   // affect the client.
132   quic::QuicTagVector client_connection_options;
133   // Enables experimental optimization for receiving data in UDPSocket.
134   bool enable_socket_recv_optimization = false;
135 
136   // Active QUIC experiments
137 
138   // Retry requests which fail with QUIC_PROTOCOL_ERROR, and mark QUIC
139   // broken if the retry succeeds.
140   bool retry_without_alt_svc_on_quic_errors = true;
141   // If true, all QUIC sessions are closed when any local IP address changes.
142   bool close_sessions_on_ip_change = false;
143   // If true, all QUIC sessions are marked as goaway when any local IP address
144   // changes.
145   bool goaway_sessions_on_ip_change = false;
146   // Specifies QUIC idle connection state lifetime.
147   base::TimeDelta idle_connection_timeout = kIdleConnectionTimeout;
148   // Specifies the reduced ping timeout subsequent connections should use when
149   // a connection was timed out with open streams.
150   base::TimeDelta reduced_ping_timeout = base::Seconds(quic::kPingTimeoutSecs);
151   // Maximum time that a session can have no retransmittable packets on the
152   // wire. Set to zero if not specified and no retransmittable PING will be
153   // sent to peer when the wire has no retransmittable packets.
154   base::TimeDelta retransmittable_on_wire_timeout;
155   // Maximum time the session can be alive before crypto handshake is
156   // finished.
157   base::TimeDelta max_time_before_crypto_handshake =
158       base::Seconds(quic::kMaxTimeForCryptoHandshakeSecs);
159   // Maximum idle time before the crypto handshake has completed.
160   base::TimeDelta max_idle_time_before_crypto_handshake =
161       base::Seconds(quic::kInitialIdleTimeoutSecs);
162   // If true, connection migration v2 will be used to migrate existing
163   // sessions to network when the platform indicates that the default network
164   // is changing.
165   // Use the value of the flag as the default value. This is needed because unit
166   // tests does not go through network_session_configuration which causes
167   // discrepancy.
168   bool migrate_sessions_on_network_change_v2 =
169       base::FeatureList::IsEnabled(features::kMigrateSessionsOnNetworkChangeV2);
170   // If true, connection migration v2 may be used to migrate active QUIC
171   // sessions to alternative network if current network connectivity is poor.
172   bool migrate_sessions_early_v2 = false;
173   // If true, a new connection may be kicked off on an alternate network when
174   // a connection fails on the default network before handshake is confirmed.
175   bool retry_on_alternate_network_before_handshake = false;
176   // If true, an idle session will be migrated within the idle migration
177   // period.
178   bool migrate_idle_sessions = false;
179   // If true, sessions with open streams will attempt to migrate to a different
180   // port when the current path is poor.
181   bool allow_port_migration = true;
182   // A session can be migrated if its idle time is within this period.
183   base::TimeDelta idle_session_migration_period =
184       kDefaultIdleSessionMigrationPeriod;
185   // Probing frequency for the multi-port alt path, represented in the number of
186   // seconds. When this param is 0, quiche will ignore it and use its own
187   // default.
188   int multi_port_probing_interval = 0;
189   // Maximum time the session could be on the non-default network before
190   // migrates back to default network. Defaults to
191   // kMaxTimeOnNonDefaultNetwork.
192   base::TimeDelta max_time_on_non_default_network = kMaxTimeOnNonDefaultNetwork;
193   // Maximum number of migrations to the non-default network on write error
194   // per network for each session.
195   int max_migrations_to_non_default_network_on_write_error =
196       kMaxMigrationsToNonDefaultNetworkOnWriteError;
197   // Maximum number of migrations to the non-default network on path
198   // degrading per network for each session.
199   int max_migrations_to_non_default_network_on_path_degrading =
200       kMaxMigrationsToNonDefaultNetworkOnPathDegrading;
201   // If true, allows migration of QUIC connections to a server-specified
202   // alternate server address.
203   bool allow_server_migration = true;
204   // If true, allows QUIC to use alternative services with a different
205   // hostname from the origin.
206   bool allow_remote_alt_svc = true;
207   // If true, estimate the initial RTT for QUIC connections based on network.
208   bool estimate_initial_rtt = false;
209   // The initial rtt that will be used in crypto handshake if no cached
210   // smoothed rtt is present.
211   base::TimeDelta initial_rtt_for_handshake;
212   // If true, QUIC with TLS will not try 0-RTT connection.
213   bool disable_tls_zero_rtt = false;
214   // If true, gQUIC requests will always require confirmation.
215   bool disable_gquic_zero_rtt = false;
216   // Network Service Type of the socket for iOS. Default is NET_SERVICE_TYPE_BE
217   // (best effort).
218   int ios_network_service_type = 0;
219   // Delay for the 1st time the alternative service is marked broken.
220   std::optional<base::TimeDelta> initial_delay_for_broken_alternative_service;
221   // If true, the delay for broke alternative service would be initial_delay *
222   // (1 << broken_count). Otherwise, the delay would be initial_delay, 5min,
223   // 10min and so on.
224   std::optional<bool> exponential_backoff_on_initial_delay;
225   // If true, delay main job even the request can be sent immediately on an
226   // available SPDY session.
227   bool delay_main_job_with_available_spdy_session = false;
228 
229   // If true, ALPS uses new codepoint to negotiates application settings.
230   bool use_new_alps_codepoint = false;
231 
232   // If true, read Explicit Congestion Notification (ECN) marks from QUIC
233   // sockets and report them to the peer.
234   bool report_ecn = false;
235 
236   // If true, parse received ORIGIN frame.
237   bool enable_origin_frame = true;
238 
239   // If true, skip DNS resolution for a hostname if the ORIGIN frame received
240   // during an ongoing session encompasses that hostname.
241   bool skip_dns_with_origin_frame = true;
242 
243   // If true, a request will be sent on the existing session iff the hostname
244   // matches the certificate presented during the handshake.
245   bool ignore_ip_matching_when_finding_existing_sessions = false;
246 };
247 
248 // QuicContext contains QUIC-related variables that are shared across all of the
249 // QUIC connections, both HTTP and non-HTTP ones.
250 class NET_EXPORT_PRIVATE QuicContext {
251  public:
252   QuicContext();
253   explicit QuicContext(
254       std::unique_ptr<quic::QuicConnectionHelperInterface> helper);
255   virtual ~QuicContext();
256 
helper()257   quic::QuicConnectionHelperInterface* helper() { return helper_.get(); }
clock()258   const quic::QuicClock* clock() { return helper_->GetClock(); }
random_generator()259   quic::QuicRandom* random_generator() { return helper_->GetRandomGenerator(); }
260 
params()261   QuicParams* params() { return &params_; }
GetDefaultVersion()262   quic::ParsedQuicVersion GetDefaultVersion() {
263     return params_.supported_versions[0];
264   }
supported_versions()265   const quic::ParsedQuicVersionVector& supported_versions() {
266     return params_.supported_versions;
267   }
268 
269   // Returns the first quic::ParsedQuicVersion that has been advertised in
270   // `advertised_versions` and is supported, following the order of
271   // `advertised_versions`.  If no mutually supported version is found,
272   // quic::ParsedQuicVersion::Unsupported() will be returned.
273   quic::ParsedQuicVersion SelectQuicVersion(
274       const quic::ParsedQuicVersionVector& advertised_versions);
275 
SetHelperForTesting(std::unique_ptr<quic::QuicConnectionHelperInterface> helper)276   void SetHelperForTesting(
277       std::unique_ptr<quic::QuicConnectionHelperInterface> helper) {
278     helper_ = std::move(helper);
279   }
280 
281  private:
282   std::unique_ptr<quic::QuicConnectionHelperInterface> helper_;
283 
284   QuicParams params_;
285 };
286 
287 // Initializes QuicConfig based on the specified parameters.
288 quic::QuicConfig InitializeQuicConfig(const QuicParams& params);
289 
290 // Configures QuicCryptoClientConfig with Chromium-specific settings.
291 void ConfigureQuicCryptoClientConfig(
292     quic::QuicCryptoClientConfig& crypto_config);
293 
294 }  // namespace net
295 
296 #endif  // NET_QUIC_QUIC_CONTEXT_H_
297