blob: b75244c0db27863201764c61cbe61c4078cd7c6d [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/third_party/quiche/src/quic/quartc/quartc_factory.h"
6
7#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
8#include "net/third_party/quiche/src/quic/core/quic_utils.h"
9#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h"
10#include "net/third_party/quiche/src/quic/core/tls_server_handshaker.h"
11#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
12#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
13#include "net/third_party/quiche/src/quic/quartc/quartc_connection_helper.h"
14#include "net/third_party/quiche/src/quic/quartc/quartc_crypto_helpers.h"
15#include "net/third_party/quiche/src/quic/quartc/quartc_session.h"
16
17namespace quic {
18
QUICHE teamb1140922019-03-22 05:24:05 -070019std::unique_ptr<QuartcSession> CreateQuartcClientSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -050020 const QuartcSessionConfig& quartc_session_config,
QUICHE teamb1140922019-03-22 05:24:05 -070021 const QuicClock* clock,
22 QuicAlarmFactory* alarm_factory,
23 QuicConnectionHelperInterface* connection_helper,
QUICHE teama6ef0a62019-03-07 20:34:33 -050024 const ParsedQuicVersionVector& supported_versions,
25 QuicStringPiece server_crypto_config,
26 QuartcPacketTransport* packet_transport) {
27 DCHECK(packet_transport);
28
29 // QuartcSession will eventually own both |writer| and |quic_connection|.
30 auto writer = QuicMakeUnique<QuartcPacketWriter>(
31 packet_transport, quartc_session_config.max_packet_size);
32
33 // While the QuicConfig is not directly used by the connection, creating it
34 // also sets flag values which must be set before creating the connection.
35 QuicConfig quic_config = CreateQuicConfig(quartc_session_config);
QUICHE teamb1140922019-03-22 05:24:05 -070036
37 // |dummy_id| and |dummy_address| are used because Quartc network layer will
38 // not use these two.
39 QuicConnectionId dummy_id = QuicUtils::CreateZeroConnectionId(
40 supported_versions[0].transport_version);
41 QuicSocketAddress dummy_address(QuicIpAddress::Any4(), /*port=*/0);
QUICHE teama6ef0a62019-03-07 20:34:33 -050042 std::unique_ptr<QuicConnection> quic_connection = CreateQuicConnection(
QUICHE teamb1140922019-03-22 05:24:05 -070043 dummy_id, dummy_address, connection_helper, alarm_factory, writer.get(),
44 Perspective::IS_CLIENT, supported_versions);
QUICHE teama6ef0a62019-03-07 20:34:33 -050045
46 return QuicMakeUnique<QuartcClientSession>(
QUICHE teamb1140922019-03-22 05:24:05 -070047 std::move(quic_connection), quic_config, supported_versions, clock,
QUICHE teama6ef0a62019-03-07 20:34:33 -050048 std::move(writer),
49 CreateCryptoClientConfig(quartc_session_config.pre_shared_key),
50 server_crypto_config);
51}
52
53void ConfigureGlobalQuicSettings() {
QUICHE team5cf62a02019-05-30 15:13:01 -070054 // TODO(b/134054062): quic_optimize_inflight_check is incompatible with
55 // datagram/message-only flows. Remove this if/when the optimization is
56 // fixed.
57 SetQuicReloadableFlag(quic_optimize_inflight_check, false);
58
QUICHE teama6ef0a62019-03-07 20:34:33 -050059 // Fixes behavior of StopReading() with level-triggered stream sequencers.
60 SetQuicReloadableFlag(quic_stop_reading_when_level_triggered, true);
61
62 // Fix b/110259444.
63 SetQuicReloadableFlag(quic_fix_spurious_ack_alarm, true);
64
fayangc5b0e2e2019-06-06 09:58:35 -070065 // Enable version 46 to enable SendMessage API and 'quic bit' per draft 17.
66 SetQuicReloadableFlag(quic_enable_version_46, true);
67
QUICHE teamb740f7a2019-03-27 15:24:01 -070068 // Enable version 47 to enable variable-length connection ids.
69 SetQuicReloadableFlag(quic_enable_version_47, true);
70
QUICHE teama6ef0a62019-03-07 20:34:33 -050071 // Fix for inconsistent reporting of crypto handshake.
72 SetQuicReloadableFlag(quic_fix_has_pending_crypto_data, true);
73
74 // Ensure that we don't drop data because QUIC streams refuse to buffer it.
75 // TODO(b/120099046): Replace this with correct handling of WriteMemSlices().
wub49855982019-05-01 14:16:26 -070076 SetQuicFlag(FLAGS_quic_buffered_data_threshold,
QUICHE teama6ef0a62019-03-07 20:34:33 -050077 std::numeric_limits<int>::max());
78
QUICHE teama6ef0a62019-03-07 20:34:33 -050079 // Enable and request QUIC to include receive timestamps in ACK frames.
80 SetQuicReloadableFlag(quic_send_timestamps, true);
81
82 // Enable ACK_DECIMATION_WITH_REORDERING. It requires ack_decimation to be
83 // false.
84 SetQuicReloadableFlag(quic_enable_ack_decimation, false);
85
86 // Note: flag settings have no effect for Exoblaze builds since
87 // SetQuicReloadableFlag() gets stubbed out.
88 SetQuicReloadableFlag(quic_bbr_less_probe_rtt, true); // Enable BBR6,7,8.
89 SetQuicReloadableFlag(quic_unified_iw_options, true); // Enable IWXX opts.
90 SetQuicReloadableFlag(quic_bbr_slower_startup3, true); // Enable BBQX opts.
91 SetQuicReloadableFlag(quic_bbr_flexible_app_limited, true); // Enable BBR9.
92}
93
94QuicConfig CreateQuicConfig(const QuartcSessionConfig& quartc_session_config) {
95 // TODO(b/124398962): Figure out a better way to initialize QUIC flags.
96 // Creating a config shouldn't have global side-effects on flags. However,
97 // this has the advantage of ensuring that flag values stay in sync with the
98 // options requested by configs, so simply splitting the config and flag
99 // settings doesn't seem preferable.
100 ConfigureGlobalQuicSettings();
101
fayangc5b0e2e2019-06-06 09:58:35 -0700102 // In exoblaze this may return false. DCHECK to avoid problems caused by
103 // incorrect flags configuration.
104 DCHECK(GetQuicReloadableFlag(quic_enable_version_46))
105 << "Your build does not support quic reloadable flags and shouldn't "
106 "place Quartc calls";
107
QUICHE teama6ef0a62019-03-07 20:34:33 -0500108 QuicTagVector copt;
109 copt.push_back(kNSTP);
110
111 // Enable and request QUIC to include receive timestamps in ACK frames.
112 copt.push_back(kSTMP);
113
114 // Enable ACK_DECIMATION_WITH_REORDERING. It requires ack_decimation to be
115 // false.
116 copt.push_back(kAKD2);
117
118 // Use unlimited decimation in order to reduce number of unbundled ACKs.
119 copt.push_back(kAKDU);
120
121 // Enable time-based loss detection.
122 copt.push_back(kTIME);
123
124 copt.push_back(kBBR3); // Stay in low-gain until in-flight < BDP.
125 copt.push_back(kBBR5); // 40 RTT ack aggregation.
126 copt.push_back(kBBR6); // Use a 0.75 * BDP cwnd during PROBE_RTT.
127 copt.push_back(kBBR8); // Skip PROBE_RTT if app-limited.
128 copt.push_back(kBBR9); // Ignore app-limited if enough data is in flight.
129 copt.push_back(kBBQ1); // 2.773 pacing gain in STARTUP.
130 copt.push_back(kBBQ2); // 2.0 CWND gain in STARTUP.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500131 copt.push_back(k1RTT); // Exit STARTUP after 1 RTT with no gains.
132 copt.push_back(kIW10); // 10-packet (14600 byte) initial cwnd.
133
134 if (!quartc_session_config.enable_tail_loss_probe) {
135 copt.push_back(kNTLP);
136 }
137
138 // TODO(b/112192153): Test and possible enable slower startup when pipe
139 // filling is ready to use. Slower startup is kBBRS.
140
141 QuicConfig quic_config;
142
143 // Use the limits for the session & stream flow control. The default 16KB
144 // limit leads to significantly undersending (not reaching BWE on the outgoing
145 // bitrate) due to blocked frames, and it leads to high latency (and one-way
146 // delay). Setting it to its limits is not going to cause issues (our streams
147 // are small generally, and if we were to buffer 24MB it wouldn't be the end
148 // of the world). We can consider setting different limits in future (e.g. 1MB
149 // stream, 1.5MB session). It's worth noting that on 1mbps bitrate, limit of
150 // 24MB can capture approx 4 minutes of the call, and the default increase in
151 // size of the window (half of the window size) is approximately 2 minutes of
152 // the call.
153 quic_config.SetInitialSessionFlowControlWindowToSend(
154 kSessionReceiveWindowLimit);
155 quic_config.SetInitialStreamFlowControlWindowToSend(
156 kStreamReceiveWindowLimit);
157 quic_config.SetConnectionOptionsToSend(copt);
158 quic_config.SetClientConnectionOptions(copt);
159 if (quartc_session_config.max_time_before_crypto_handshake >
160 QuicTime::Delta::Zero()) {
161 quic_config.set_max_time_before_crypto_handshake(
162 quartc_session_config.max_time_before_crypto_handshake);
163 }
164 if (quartc_session_config.max_idle_time_before_crypto_handshake >
165 QuicTime::Delta::Zero()) {
166 quic_config.set_max_idle_time_before_crypto_handshake(
167 quartc_session_config.max_idle_time_before_crypto_handshake);
168 }
169 if (quartc_session_config.idle_network_timeout > QuicTime::Delta::Zero()) {
170 quic_config.SetIdleNetworkTimeout(
171 quartc_session_config.idle_network_timeout,
172 quartc_session_config.idle_network_timeout);
173 }
174
175 // The ICE transport provides a unique 5-tuple for each connection. Save
176 // overhead by omitting the connection id.
177 quic_config.SetBytesForConnectionIdToSend(0);
178
179 // Allow up to 1000 incoming streams at once. Quartc streams typically contain
180 // one audio or video frame and close immediately. However, when a video frame
181 // becomes larger than one packet, there is some delay between the start and
182 // end of each stream. The default maximum of 100 only leaves about 1 second
183 // of headroom (Quartc sends ~30 video frames per second) before QUIC starts
184 // to refuse incoming streams. Back-pressure should clear backlogs of
185 // incomplete streams, but targets 1 second for recovery. Increasing the
186 // number of open streams gives sufficient headroom to recover before QUIC
187 // refuses new streams.
fkastenholzd3a1de92019-05-15 07:00:07 -0700188 quic_config.SetMaxIncomingBidirectionalStreamsToSend(1000);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500189
190 return quic_config;
191}
192
QUICHE teama6ef0a62019-03-07 20:34:33 -0500193std::unique_ptr<QuicConnection> CreateQuicConnection(
194 QuicConnectionId connection_id,
195 const QuicSocketAddress& peer_address,
196 QuicConnectionHelperInterface* connection_helper,
197 QuicAlarmFactory* alarm_factory,
198 QuicPacketWriter* packet_writer,
199 Perspective perspective,
200 ParsedQuicVersionVector supported_versions) {
201 auto quic_connection = QuicMakeUnique<QuicConnection>(
202 connection_id, peer_address, connection_helper, alarm_factory,
203 packet_writer,
204 /*owns_writer=*/false, perspective, supported_versions);
QUICHE team9e75db12019-04-02 17:21:31 -0400205 quic_connection->SetMaxPacketLength(
206 packet_writer->GetMaxPacketSize(peer_address));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500207
208 QuicSentPacketManager& sent_packet_manager =
209 quic_connection->sent_packet_manager();
210
211 // Default delayed ack time is 25ms.
212 // If data packets are sent less often (e.g. because p-time was modified),
213 // we would force acks to be sent every 25ms regardless, increasing
214 // overhead. Since generally we guarantee a packet every 20ms, changing
215 // this value should have miniscule effect on quality on good connections,
216 // but on poor connections, changing this number significantly reduced the
217 // number of ack-only packets.
218 // The p-time can go up to as high as 120ms, and when it does, it's
219 // when the low overhead is the most important thing. Ideally it should be
220 // above 120ms, but it cannot be higher than 0.5*RTO, which equals to 100ms.
221 sent_packet_manager.set_delayed_ack_time(
222 QuicTime::Delta::FromMilliseconds(100));
223
224 quic_connection->set_fill_up_link_during_probing(true);
225
226 // We start ack decimation after 15 packets. Typically, we would see
227 // 1-2 crypto handshake packets, one media packet, and 10 probing packets.
228 // We want to get acks for the probing packets as soon as possible,
229 // but we can start using ack decimation right after first probing completes.
230 // The default was to not start ack decimation for the first 100 packets.
231 quic_connection->set_min_received_before_ack_decimation(15);
232
233 return quic_connection;
234}
235
QUICHE teama6ef0a62019-03-07 20:34:33 -0500236} // namespace quic