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 // Obsolete QUIC supported versions are versions that are supported by the
32 // QUIC shared code but that Chrome refuses to use because modern clients
33 // should only use versions at least as recent as the oldest default version.
ObsoleteQuicVersions()34 inline NET_EXPORT_PRIVATE quic::ParsedQuicVersionVector ObsoleteQuicVersions() {
35 return quic::ParsedQuicVersionVector{quic::ParsedQuicVersion::Q046(),
36 quic::ParsedQuicVersion::Q050(),
37 quic::ParsedQuicVersion::Draft29()};
38 }
39
40 // All of the QUIC versions that Chrome can support. This is the subset of
41 // QUIC versions that the QUIC shared code supports that are not on the list
42 // of versions that Chrome considers obsolete.
43 inline NET_EXPORT_PRIVATE quic::ParsedQuicVersionVector
AllSupportedQuicVersions()44 AllSupportedQuicVersions() {
45 quic::ParsedQuicVersionVector obsolete_versions = ObsoleteQuicVersions();
46 quic::ParsedQuicVersionVector all_supported_versions =
47 quic::AllSupportedVersions();
48 quic::ParsedQuicVersionVector filtered_versions;
49 for (const auto& version : all_supported_versions) {
50 if (!base::Contains(obsolete_versions, version)) {
51 filtered_versions.push_back(version);
52 }
53 }
54 return filtered_versions;
55 }
56
57 // When a connection is idle for 30 seconds it will be closed.
58 constexpr base::TimeDelta kIdleConnectionTimeout = base::Seconds(30);
59
60 // Sessions can migrate if they have been idle for less than this period.
61 constexpr base::TimeDelta kDefaultIdleSessionMigrationPeriod =
62 base::Seconds(30);
63
64 // The default maximum time allowed to have no retransmittable packets on the
65 // wire (after sending the first retransmittable packet) if
66 // |migrate_session_early_v2_| is true. PING frames will be sent as needed to
67 // enforce this.
68 constexpr base::TimeDelta kDefaultRetransmittableOnWireTimeout =
69 base::Milliseconds(200);
70
71 // The default maximum time QUIC session could be on non-default network before
72 // migrate back to default network.
73 constexpr base::TimeDelta kMaxTimeOnNonDefaultNetwork = base::Seconds(128);
74
75 // The default maximum number of migrations to non default network on write
76 // error per network.
77 const int64_t kMaxMigrationsToNonDefaultNetworkOnWriteError = 5;
78
79 // The default maximum number of migrations to non default network on path
80 // degrading per network.
81 const int64_t kMaxMigrationsToNonDefaultNetworkOnPathDegrading = 5;
82
83 // QUIC's socket receive buffer size.
84 // We should adaptively set this buffer size, but for now, we'll use a size
85 // that seems large enough to receive data at line rate for most connections,
86 // and does not consume "too much" memory.
87 const int32_t kQuicSocketReceiveBufferSize = 1024 * 1024; // 1MB
88
89 // Structure containing simple configuration options and experiments for QUIC.
90 struct NET_EXPORT QuicParams {
91 QuicParams();
92 QuicParams(const QuicParams& other);
93 ~QuicParams();
94
95 // QUIC runtime configuration options.
96
97 // Versions of QUIC which may be used.
98 quic::ParsedQuicVersionVector supported_versions =
99 DefaultSupportedQuicVersions();
100 // Limit on the size of QUIC packets.
101 size_t max_packet_length = quic::kDefaultMaxPacketSize;
102 // Maximum number of server configs that are to be stored in
103 // HttpServerProperties, instead of the disk cache.
104 size_t max_server_configs_stored_in_properties = 0u;
105 // QUIC will be used for all connections in this set.
106 std::set<HostPortPair> origins_to_force_quic_on;
107 // WebTransport developer mode disables the requirement that all QUIC
108 // connections are anchored to a system certificate root, but only for
109 // WebTransport connections.
110 bool webtransport_developer_mode = false;
111 // Set of QUIC tags to send in the handshake's connection options.
112 quic::QuicTagVector connection_options;
113 // Set of QUIC tags to send in the handshake's connection options that only
114 // affect the client.
115 quic::QuicTagVector client_connection_options;
116 // Enables experimental optimization for receiving data in UDPSocket.
117 bool enable_socket_recv_optimization = false;
118
119 // Active QUIC experiments
120
121 // Retry requests which fail with QUIC_PROTOCOL_ERROR, and mark QUIC
122 // broken if the retry succeeds.
123 bool retry_without_alt_svc_on_quic_errors = true;
124 // If true, all QUIC sessions are closed when any local IP address changes.
125 bool close_sessions_on_ip_change = false;
126 // If true, all QUIC sessions are marked as goaway when any local IP address
127 // changes.
128 bool goaway_sessions_on_ip_change = false;
129 // Specifies QUIC idle connection state lifetime.
130 base::TimeDelta idle_connection_timeout = kIdleConnectionTimeout;
131 // Specifies the reduced ping timeout subsequent connections should use when
132 // a connection was timed out with open streams.
133 base::TimeDelta reduced_ping_timeout = base::Seconds(quic::kPingTimeoutSecs);
134 // Maximum time that a session can have no retransmittable packets on the
135 // wire. Set to zero if not specified and no retransmittable PING will be
136 // sent to peer when the wire has no retransmittable packets.
137 base::TimeDelta retransmittable_on_wire_timeout;
138 // Maximum time the session can be alive before crypto handshake is
139 // finished.
140 base::TimeDelta max_time_before_crypto_handshake =
141 base::Seconds(quic::kMaxTimeForCryptoHandshakeSecs);
142 // Maximum idle time before the crypto handshake has completed.
143 base::TimeDelta max_idle_time_before_crypto_handshake =
144 base::Seconds(quic::kInitialIdleTimeoutSecs);
145 // If true, connection migration v2 will be used to migrate existing
146 // sessions to network when the platform indicates that the default network
147 // is changing.
148 bool migrate_sessions_on_network_change_v2 =
149 base::FeatureList::IsEnabled(features::kMigrateSessionsOnNetworkChangeV2);
150 // If true, connection migration v2 may be used to migrate active QUIC
151 // sessions to alternative network if current network connectivity is poor.
152 bool migrate_sessions_early_v2 = false;
153 // If true, a new connection may be kicked off on an alternate network when
154 // a connection fails on the default network before handshake is confirmed.
155 bool retry_on_alternate_network_before_handshake = false;
156 // If true, an idle session will be migrated within the idle migration
157 // period.
158 bool migrate_idle_sessions = false;
159 // If true, sessions with open streams will attempt to migrate to a different
160 // port when the current path is poor.
161 bool allow_port_migration = true;
162 // A session can be migrated if its idle time is within this period.
163 base::TimeDelta idle_session_migration_period =
164 kDefaultIdleSessionMigrationPeriod;
165 // Probing frequency for the multi-port alt path, represented in the number of
166 // seconds. When this param is 0, quiche will ignore it and use its own
167 // default.
168 int multi_port_probing_interval = 0;
169 // Maximum time the session could be on the non-default network before
170 // migrates back to default network. Defaults to
171 // kMaxTimeOnNonDefaultNetwork.
172 base::TimeDelta max_time_on_non_default_network = kMaxTimeOnNonDefaultNetwork;
173 // Maximum number of migrations to the non-default network on write error
174 // per network for each session.
175 int max_migrations_to_non_default_network_on_write_error =
176 kMaxMigrationsToNonDefaultNetworkOnWriteError;
177 // Maximum number of migrations to the non-default network on path
178 // degrading per network for each session.
179 int max_migrations_to_non_default_network_on_path_degrading =
180 kMaxMigrationsToNonDefaultNetworkOnPathDegrading;
181 // If true, allows migration of QUIC connections to a server-specified
182 // alternate server address.
183 bool allow_server_migration = false;
184 // If true, allows QUIC to use alternative services with a different
185 // hostname from the origin.
186 bool allow_remote_alt_svc = true;
187 // If true, estimate the initial RTT for QUIC connections based on network.
188 bool estimate_initial_rtt = false;
189 // The initial rtt that will be used in crypto handshake if no cached
190 // smoothed rtt is present.
191 base::TimeDelta initial_rtt_for_handshake;
192 // If true, QUIC with TLS will not try 0-RTT connection.
193 bool disable_tls_zero_rtt = false;
194 // If true, gQUIC requests will always require confirmation.
195 bool disable_gquic_zero_rtt = false;
196 // Network Service Type of the socket for iOS. Default is NET_SERVICE_TYPE_BE
197 // (best effort).
198 int ios_network_service_type = 0;
199 // Delay for the 1st time the alternative service is marked broken.
200 absl::optional<base::TimeDelta> initial_delay_for_broken_alternative_service;
201 // If true, the delay for broke alternative service would be initial_delay *
202 // (1 << broken_count). Otherwise, the delay would be initial_delay, 5min,
203 // 10min and so on.
204 absl::optional<bool> exponential_backoff_on_initial_delay;
205 // If true, delay main job even the request can be sent immediately on an
206 // available SPDY session.
207 bool delay_main_job_with_available_spdy_session = false;
208 };
209
210 // QuicContext contains QUIC-related variables that are shared across all of the
211 // QUIC connections, both HTTP and non-HTTP ones.
212 class NET_EXPORT_PRIVATE QuicContext {
213 public:
214 QuicContext();
215 explicit QuicContext(
216 std::unique_ptr<quic::QuicConnectionHelperInterface> helper);
217 ~QuicContext();
218
helper()219 quic::QuicConnectionHelperInterface* helper() { return helper_.get(); }
clock()220 const quic::QuicClock* clock() { return helper_->GetClock(); }
random_generator()221 quic::QuicRandom* random_generator() { return helper_->GetRandomGenerator(); }
222
params()223 QuicParams* params() { return ¶ms_; }
GetDefaultVersion()224 quic::ParsedQuicVersion GetDefaultVersion() {
225 return params_.supported_versions[0];
226 }
supported_versions()227 const quic::ParsedQuicVersionVector& supported_versions() {
228 return params_.supported_versions;
229 }
230
SetHelperForTesting(std::unique_ptr<quic::QuicConnectionHelperInterface> helper)231 void SetHelperForTesting(
232 std::unique_ptr<quic::QuicConnectionHelperInterface> helper) {
233 helper_ = std::move(helper);
234 }
235
236 private:
237 std::unique_ptr<quic::QuicConnectionHelperInterface> helper_;
238
239 QuicParams params_;
240 };
241
242 // Initializes QuicConfig based on the specified parameters.
243 quic::QuicConfig InitializeQuicConfig(const QuicParams& params);
244
245 // Configures QuicCryptoClientConfig with Chromium-specific settings.
246 void ConfigureQuicCryptoClientConfig(
247 quic::QuicCryptoClientConfig& crypto_config);
248
249 } // namespace net
250
251 #endif // NET_QUIC_QUIC_CONTEXT_H_
252