blob: 06871a2fe9744d5658f5ebed608b2a8d043c2316 [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() {
54 // Fixes behavior of StopReading() with level-triggered stream sequencers.
55 SetQuicReloadableFlag(quic_stop_reading_when_level_triggered, true);
56
57 // Fix b/110259444.
58 SetQuicReloadableFlag(quic_fix_spurious_ack_alarm, true);
59
QUICHE teamb740f7a2019-03-27 15:24:01 -070060 // Enable version 46 to enable SendMessage API and 'quic bit' per draft 17.
QUICHE teama6ef0a62019-03-07 20:34:33 -050061 SetQuicReloadableFlag(quic_enable_version_46, true);
62
QUICHE teamb740f7a2019-03-27 15:24:01 -070063 // Enable version 47 to enable variable-length connection ids.
64 SetQuicReloadableFlag(quic_enable_version_47, true);
65
QUICHE teama6ef0a62019-03-07 20:34:33 -050066 // Fix for inconsistent reporting of crypto handshake.
67 SetQuicReloadableFlag(quic_fix_has_pending_crypto_data, true);
68
69 // Ensure that we don't drop data because QUIC streams refuse to buffer it.
70 // TODO(b/120099046): Replace this with correct handling of WriteMemSlices().
wub49855982019-05-01 14:16:26 -070071 SetQuicFlag(FLAGS_quic_buffered_data_threshold,
QUICHE teama6ef0a62019-03-07 20:34:33 -050072 std::numeric_limits<int>::max());
73
QUICHE teama6ef0a62019-03-07 20:34:33 -050074 // Enable and request QUIC to include receive timestamps in ACK frames.
75 SetQuicReloadableFlag(quic_send_timestamps, true);
76
77 // Enable ACK_DECIMATION_WITH_REORDERING. It requires ack_decimation to be
78 // false.
79 SetQuicReloadableFlag(quic_enable_ack_decimation, false);
80
81 // Note: flag settings have no effect for Exoblaze builds since
82 // SetQuicReloadableFlag() gets stubbed out.
83 SetQuicReloadableFlag(quic_bbr_less_probe_rtt, true); // Enable BBR6,7,8.
84 SetQuicReloadableFlag(quic_unified_iw_options, true); // Enable IWXX opts.
85 SetQuicReloadableFlag(quic_bbr_slower_startup3, true); // Enable BBQX opts.
86 SetQuicReloadableFlag(quic_bbr_flexible_app_limited, true); // Enable BBR9.
87}
88
89QuicConfig CreateQuicConfig(const QuartcSessionConfig& quartc_session_config) {
90 // TODO(b/124398962): Figure out a better way to initialize QUIC flags.
91 // Creating a config shouldn't have global side-effects on flags. However,
92 // this has the advantage of ensuring that flag values stay in sync with the
93 // options requested by configs, so simply splitting the config and flag
94 // settings doesn't seem preferable.
95 ConfigureGlobalQuicSettings();
96
97 // In exoblaze this may return false. DCHECK to avoid problems caused by
98 // incorrect flags configuration.
99 DCHECK(GetQuicReloadableFlag(quic_enable_version_46))
100 << "Your build does not support quic reloadable flags and shouldn't "
101 "place Quartc calls";
102
103 QuicTagVector copt;
104 copt.push_back(kNSTP);
105
106 // Enable and request QUIC to include receive timestamps in ACK frames.
107 copt.push_back(kSTMP);
108
109 // Enable ACK_DECIMATION_WITH_REORDERING. It requires ack_decimation to be
110 // false.
111 copt.push_back(kAKD2);
112
113 // Use unlimited decimation in order to reduce number of unbundled ACKs.
114 copt.push_back(kAKDU);
115
116 // Enable time-based loss detection.
117 copt.push_back(kTIME);
118
119 copt.push_back(kBBR3); // Stay in low-gain until in-flight < BDP.
120 copt.push_back(kBBR5); // 40 RTT ack aggregation.
121 copt.push_back(kBBR6); // Use a 0.75 * BDP cwnd during PROBE_RTT.
122 copt.push_back(kBBR8); // Skip PROBE_RTT if app-limited.
123 copt.push_back(kBBR9); // Ignore app-limited if enough data is in flight.
124 copt.push_back(kBBQ1); // 2.773 pacing gain in STARTUP.
125 copt.push_back(kBBQ2); // 2.0 CWND gain in STARTUP.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500126 copt.push_back(k1RTT); // Exit STARTUP after 1 RTT with no gains.
127 copt.push_back(kIW10); // 10-packet (14600 byte) initial cwnd.
128
129 if (!quartc_session_config.enable_tail_loss_probe) {
130 copt.push_back(kNTLP);
131 }
132
133 // TODO(b/112192153): Test and possible enable slower startup when pipe
134 // filling is ready to use. Slower startup is kBBRS.
135
136 QuicConfig quic_config;
137
138 // Use the limits for the session & stream flow control. The default 16KB
139 // limit leads to significantly undersending (not reaching BWE on the outgoing
140 // bitrate) due to blocked frames, and it leads to high latency (and one-way
141 // delay). Setting it to its limits is not going to cause issues (our streams
142 // are small generally, and if we were to buffer 24MB it wouldn't be the end
143 // of the world). We can consider setting different limits in future (e.g. 1MB
144 // stream, 1.5MB session). It's worth noting that on 1mbps bitrate, limit of
145 // 24MB can capture approx 4 minutes of the call, and the default increase in
146 // size of the window (half of the window size) is approximately 2 minutes of
147 // the call.
148 quic_config.SetInitialSessionFlowControlWindowToSend(
149 kSessionReceiveWindowLimit);
150 quic_config.SetInitialStreamFlowControlWindowToSend(
151 kStreamReceiveWindowLimit);
152 quic_config.SetConnectionOptionsToSend(copt);
153 quic_config.SetClientConnectionOptions(copt);
154 if (quartc_session_config.max_time_before_crypto_handshake >
155 QuicTime::Delta::Zero()) {
156 quic_config.set_max_time_before_crypto_handshake(
157 quartc_session_config.max_time_before_crypto_handshake);
158 }
159 if (quartc_session_config.max_idle_time_before_crypto_handshake >
160 QuicTime::Delta::Zero()) {
161 quic_config.set_max_idle_time_before_crypto_handshake(
162 quartc_session_config.max_idle_time_before_crypto_handshake);
163 }
164 if (quartc_session_config.idle_network_timeout > QuicTime::Delta::Zero()) {
165 quic_config.SetIdleNetworkTimeout(
166 quartc_session_config.idle_network_timeout,
167 quartc_session_config.idle_network_timeout);
168 }
169
170 // The ICE transport provides a unique 5-tuple for each connection. Save
171 // overhead by omitting the connection id.
172 quic_config.SetBytesForConnectionIdToSend(0);
173
174 // Allow up to 1000 incoming streams at once. Quartc streams typically contain
175 // one audio or video frame and close immediately. However, when a video frame
176 // becomes larger than one packet, there is some delay between the start and
177 // end of each stream. The default maximum of 100 only leaves about 1 second
178 // of headroom (Quartc sends ~30 video frames per second) before QUIC starts
179 // to refuse incoming streams. Back-pressure should clear backlogs of
180 // incomplete streams, but targets 1 second for recovery. Increasing the
181 // number of open streams gives sufficient headroom to recover before QUIC
182 // refuses new streams.
fkastenholzd3a1de92019-05-15 07:00:07 -0700183 quic_config.SetMaxIncomingBidirectionalStreamsToSend(1000);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500184
185 return quic_config;
186}
187
QUICHE teama6ef0a62019-03-07 20:34:33 -0500188std::unique_ptr<QuicConnection> CreateQuicConnection(
189 QuicConnectionId connection_id,
190 const QuicSocketAddress& peer_address,
191 QuicConnectionHelperInterface* connection_helper,
192 QuicAlarmFactory* alarm_factory,
193 QuicPacketWriter* packet_writer,
194 Perspective perspective,
195 ParsedQuicVersionVector supported_versions) {
196 auto quic_connection = QuicMakeUnique<QuicConnection>(
197 connection_id, peer_address, connection_helper, alarm_factory,
198 packet_writer,
199 /*owns_writer=*/false, perspective, supported_versions);
QUICHE team9e75db12019-04-02 17:21:31 -0400200 quic_connection->SetMaxPacketLength(
201 packet_writer->GetMaxPacketSize(peer_address));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500202
203 QuicSentPacketManager& sent_packet_manager =
204 quic_connection->sent_packet_manager();
205
206 // Default delayed ack time is 25ms.
207 // If data packets are sent less often (e.g. because p-time was modified),
208 // we would force acks to be sent every 25ms regardless, increasing
209 // overhead. Since generally we guarantee a packet every 20ms, changing
210 // this value should have miniscule effect on quality on good connections,
211 // but on poor connections, changing this number significantly reduced the
212 // number of ack-only packets.
213 // The p-time can go up to as high as 120ms, and when it does, it's
214 // when the low overhead is the most important thing. Ideally it should be
215 // above 120ms, but it cannot be higher than 0.5*RTO, which equals to 100ms.
216 sent_packet_manager.set_delayed_ack_time(
217 QuicTime::Delta::FromMilliseconds(100));
218
219 quic_connection->set_fill_up_link_during_probing(true);
220
221 // We start ack decimation after 15 packets. Typically, we would see
222 // 1-2 crypto handshake packets, one media packet, and 10 probing packets.
223 // We want to get acks for the probing packets as soon as possible,
224 // but we can start using ack decimation right after first probing completes.
225 // The default was to not start ack decimation for the first 100 packets.
226 quic_connection->set_min_received_before_ack_decimation(15);
227
228 return quic_connection;
229}
230
QUICHE teama6ef0a62019-03-07 20:34:33 -0500231} // namespace quic