blob: 6742b895b33e3d4e2c0830c8adcc9393c60b12da [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"
ianswett309987e2019-08-02 13:16:26 -070011#include "net/third_party/quiche/src/quic/core/uber_received_packet_manager.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050012#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
13#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
14#include "net/third_party/quiche/src/quic/quartc/quartc_connection_helper.h"
15#include "net/third_party/quiche/src/quic/quartc/quartc_crypto_helpers.h"
16#include "net/third_party/quiche/src/quic/quartc/quartc_session.h"
17
18namespace quic {
19
QUICHE teamb1140922019-03-22 05:24:05 -070020std::unique_ptr<QuartcSession> CreateQuartcClientSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -050021 const QuartcSessionConfig& quartc_session_config,
QUICHE teamb1140922019-03-22 05:24:05 -070022 const QuicClock* clock,
23 QuicAlarmFactory* alarm_factory,
24 QuicConnectionHelperInterface* connection_helper,
QUICHE teama6ef0a62019-03-07 20:34:33 -050025 const ParsedQuicVersionVector& supported_versions,
26 QuicStringPiece server_crypto_config,
27 QuartcPacketTransport* packet_transport) {
28 DCHECK(packet_transport);
29
30 // QuartcSession will eventually own both |writer| and |quic_connection|.
31 auto writer = QuicMakeUnique<QuartcPacketWriter>(
32 packet_transport, quartc_session_config.max_packet_size);
33
34 // While the QuicConfig is not directly used by the connection, creating it
35 // also sets flag values which must be set before creating the connection.
36 QuicConfig quic_config = CreateQuicConfig(quartc_session_config);
QUICHE teamb1140922019-03-22 05:24:05 -070037
38 // |dummy_id| and |dummy_address| are used because Quartc network layer will
39 // not use these two.
40 QuicConnectionId dummy_id = QuicUtils::CreateZeroConnectionId(
41 supported_versions[0].transport_version);
42 QuicSocketAddress dummy_address(QuicIpAddress::Any4(), /*port=*/0);
QUICHE teama6ef0a62019-03-07 20:34:33 -050043 std::unique_ptr<QuicConnection> quic_connection = CreateQuicConnection(
QUICHE teamb1140922019-03-22 05:24:05 -070044 dummy_id, dummy_address, connection_helper, alarm_factory, writer.get(),
45 Perspective::IS_CLIENT, supported_versions);
QUICHE teama6ef0a62019-03-07 20:34:33 -050046
fkastenholz4c7303c2019-07-29 08:17:07 -070047 // Quartc sets its own ack delay; get that ack delay and copy it over
48 // to the QuicConfig so that it can be properly advertised to the peer
49 // via transport parameter negotiation.
ianswett309987e2019-08-02 13:16:26 -070050 quic_config.SetMaxAckDelayToSendMs(quic_connection->received_packet_manager()
51 .max_ack_delay()
fkastenholz4c7303c2019-07-29 08:17:07 -070052 .ToMilliseconds());
53
QUICHE teama6ef0a62019-03-07 20:34:33 -050054 return QuicMakeUnique<QuartcClientSession>(
QUICHE teamb1140922019-03-22 05:24:05 -070055 std::move(quic_connection), quic_config, supported_versions, clock,
QUICHE teama6ef0a62019-03-07 20:34:33 -050056 std::move(writer),
57 CreateCryptoClientConfig(quartc_session_config.pre_shared_key),
58 server_crypto_config);
59}
60
61void ConfigureGlobalQuicSettings() {
62 // Fixes behavior of StopReading() with level-triggered stream sequencers.
63 SetQuicReloadableFlag(quic_stop_reading_when_level_triggered, true);
64
QUICHE teamb740f7a2019-03-27 15:24:01 -070065 // Enable version 47 to enable variable-length connection ids.
66 SetQuicReloadableFlag(quic_enable_version_47, true);
67
QUICHE teama6ef0a62019-03-07 20:34:33 -050068 // Ensure that we don't drop data because QUIC streams refuse to buffer it.
69 // TODO(b/120099046): Replace this with correct handling of WriteMemSlices().
wub49855982019-05-01 14:16:26 -070070 SetQuicFlag(FLAGS_quic_buffered_data_threshold,
QUICHE teama6ef0a62019-03-07 20:34:33 -050071 std::numeric_limits<int>::max());
72
QUICHE teama6ef0a62019-03-07 20:34:33 -050073 // Enable and request QUIC to include receive timestamps in ACK frames.
74 SetQuicReloadableFlag(quic_send_timestamps, true);
75
76 // Enable ACK_DECIMATION_WITH_REORDERING. It requires ack_decimation to be
77 // false.
78 SetQuicReloadableFlag(quic_enable_ack_decimation, false);
79
80 // Note: flag settings have no effect for Exoblaze builds since
81 // SetQuicReloadableFlag() gets stubbed out.
82 SetQuicReloadableFlag(quic_bbr_less_probe_rtt, true); // Enable BBR6,7,8.
83 SetQuicReloadableFlag(quic_unified_iw_options, true); // Enable IWXX opts.
QUICHE teama6ef0a62019-03-07 20:34:33 -050084 SetQuicReloadableFlag(quic_bbr_flexible_app_limited, true); // Enable BBR9.
nharperd43f1d62019-07-01 15:18:20 -070085
86 // Fix GetPacketHeaderSize
87 SetQuicReloadableFlag(quic_fix_get_packet_header_size, true);
QUICHE teama6ef0a62019-03-07 20:34:33 -050088}
89
90QuicConfig CreateQuicConfig(const QuartcSessionConfig& quartc_session_config) {
91 // TODO(b/124398962): Figure out a better way to initialize QUIC flags.
92 // Creating a config shouldn't have global side-effects on flags. However,
93 // this has the advantage of ensuring that flag values stay in sync with the
94 // options requested by configs, so simply splitting the config and flag
95 // settings doesn't seem preferable.
96 ConfigureGlobalQuicSettings();
97
fayangc5b0e2e2019-06-06 09:58:35 -070098 // In exoblaze this may return false. DCHECK to avoid problems caused by
99 // incorrect flags configuration.
fayang3294e742019-06-12 13:10:15 -0700100 DCHECK(GetQuicReloadableFlag(quic_enable_version_47))
fayangc5b0e2e2019-06-06 09:58:35 -0700101 << "Your build does not support quic reloadable flags and shouldn't "
102 "place Quartc calls";
103
QUICHE teama6ef0a62019-03-07 20:34:33 -0500104 QuicTagVector copt;
105 copt.push_back(kNSTP);
106
107 // Enable and request QUIC to include receive timestamps in ACK frames.
108 copt.push_back(kSTMP);
109
110 // Enable ACK_DECIMATION_WITH_REORDERING. It requires ack_decimation to be
111 // false.
112 copt.push_back(kAKD2);
113
114 // Use unlimited decimation in order to reduce number of unbundled ACKs.
115 copt.push_back(kAKDU);
116
117 // Enable time-based loss detection.
118 copt.push_back(kTIME);
119
120 copt.push_back(kBBR3); // Stay in low-gain until in-flight < BDP.
121 copt.push_back(kBBR5); // 40 RTT ack aggregation.
122 copt.push_back(kBBR6); // Use a 0.75 * BDP cwnd during PROBE_RTT.
123 copt.push_back(kBBR8); // Skip PROBE_RTT if app-limited.
124 copt.push_back(kBBR9); // Ignore app-limited if enough data is in flight.
125 copt.push_back(kBBQ1); // 2.773 pacing gain in STARTUP.
126 copt.push_back(kBBQ2); // 2.0 CWND gain in STARTUP.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500127 copt.push_back(k1RTT); // Exit STARTUP after 1 RTT with no gains.
128 copt.push_back(kIW10); // 10-packet (14600 byte) initial cwnd.
129
130 if (!quartc_session_config.enable_tail_loss_probe) {
131 copt.push_back(kNTLP);
132 }
133
134 // TODO(b/112192153): Test and possible enable slower startup when pipe
135 // filling is ready to use. Slower startup is kBBRS.
136
137 QuicConfig quic_config;
138
139 // Use the limits for the session & stream flow control. The default 16KB
140 // limit leads to significantly undersending (not reaching BWE on the outgoing
141 // bitrate) due to blocked frames, and it leads to high latency (and one-way
142 // delay). Setting it to its limits is not going to cause issues (our streams
143 // are small generally, and if we were to buffer 24MB it wouldn't be the end
144 // of the world). We can consider setting different limits in future (e.g. 1MB
145 // stream, 1.5MB session). It's worth noting that on 1mbps bitrate, limit of
146 // 24MB can capture approx 4 minutes of the call, and the default increase in
147 // size of the window (half of the window size) is approximately 2 minutes of
148 // the call.
149 quic_config.SetInitialSessionFlowControlWindowToSend(
150 kSessionReceiveWindowLimit);
151 quic_config.SetInitialStreamFlowControlWindowToSend(
152 kStreamReceiveWindowLimit);
153 quic_config.SetConnectionOptionsToSend(copt);
154 quic_config.SetClientConnectionOptions(copt);
155 if (quartc_session_config.max_time_before_crypto_handshake >
156 QuicTime::Delta::Zero()) {
157 quic_config.set_max_time_before_crypto_handshake(
158 quartc_session_config.max_time_before_crypto_handshake);
159 }
160 if (quartc_session_config.max_idle_time_before_crypto_handshake >
161 QuicTime::Delta::Zero()) {
162 quic_config.set_max_idle_time_before_crypto_handshake(
163 quartc_session_config.max_idle_time_before_crypto_handshake);
164 }
165 if (quartc_session_config.idle_network_timeout > QuicTime::Delta::Zero()) {
166 quic_config.SetIdleNetworkTimeout(
167 quartc_session_config.idle_network_timeout,
168 quartc_session_config.idle_network_timeout);
169 }
170
171 // The ICE transport provides a unique 5-tuple for each connection. Save
172 // overhead by omitting the connection id.
173 quic_config.SetBytesForConnectionIdToSend(0);
174
175 // Allow up to 1000 incoming streams at once. Quartc streams typically contain
176 // one audio or video frame and close immediately. However, when a video frame
177 // becomes larger than one packet, there is some delay between the start and
178 // end of each stream. The default maximum of 100 only leaves about 1 second
179 // of headroom (Quartc sends ~30 video frames per second) before QUIC starts
180 // to refuse incoming streams. Back-pressure should clear backlogs of
181 // incomplete streams, but targets 1 second for recovery. Increasing the
182 // number of open streams gives sufficient headroom to recover before QUIC
183 // refuses new streams.
fkastenholzd3a1de92019-05-15 07:00:07 -0700184 quic_config.SetMaxIncomingBidirectionalStreamsToSend(1000);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500185
186 return quic_config;
187}
188
QUICHE teama6ef0a62019-03-07 20:34:33 -0500189std::unique_ptr<QuicConnection> CreateQuicConnection(
190 QuicConnectionId connection_id,
191 const QuicSocketAddress& peer_address,
192 QuicConnectionHelperInterface* connection_helper,
193 QuicAlarmFactory* alarm_factory,
194 QuicPacketWriter* packet_writer,
195 Perspective perspective,
196 ParsedQuicVersionVector supported_versions) {
197 auto quic_connection = QuicMakeUnique<QuicConnection>(
198 connection_id, peer_address, connection_helper, alarm_factory,
199 packet_writer,
200 /*owns_writer=*/false, perspective, supported_versions);
QUICHE team9e75db12019-04-02 17:21:31 -0400201 quic_connection->SetMaxPacketLength(
202 packet_writer->GetMaxPacketSize(peer_address));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500203
204 QuicSentPacketManager& sent_packet_manager =
205 quic_connection->sent_packet_manager();
ianswett309987e2019-08-02 13:16:26 -0700206 UberReceivedPacketManager& received_packet_manager =
207 quic_connection->received_packet_manager();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500208
209 // Default delayed ack time is 25ms.
210 // If data packets are sent less often (e.g. because p-time was modified),
211 // we would force acks to be sent every 25ms regardless, increasing
212 // overhead. Since generally we guarantee a packet every 20ms, changing
213 // this value should have miniscule effect on quality on good connections,
214 // but on poor connections, changing this number significantly reduced the
215 // number of ack-only packets.
216 // The p-time can go up to as high as 120ms, and when it does, it's
217 // when the low overhead is the most important thing. Ideally it should be
218 // above 120ms, but it cannot be higher than 0.5*RTO, which equals to 100ms.
ianswett309987e2019-08-02 13:16:26 -0700219 received_packet_manager.set_max_ack_delay(
fkastenholz59c653b2019-07-15 09:55:53 -0700220 QuicTime::Delta::FromMilliseconds(100));
221 sent_packet_manager.set_peer_max_ack_delay(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500222 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