blob: e65492f3d68afb53927e01810aec9d1727a8f866 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2012 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/core/quic_connection.h"
6
7#include <string.h>
8#include <sys/types.h>
9
10#include <algorithm>
11#include <iterator>
12#include <limits>
13#include <memory>
14#include <set>
vasilvv872e7a32019-03-12 16:42:44 -070015#include <string>
QUICHE teama6ef0a62019-03-07 20:34:33 -050016#include <utility>
17
QUICHE teama6ef0a62019-03-07 20:34:33 -050018#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
dschinazi244f6dc2019-05-06 15:45:16 -070019#include "net/third_party/quiche/src/quic/core/crypto/crypto_utils.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050020#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
21#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
dschinazi56fb53e2019-06-21 15:30:04 -070022#include "net/third_party/quiche/src/quic/core/proto/cached_network_parameters_proto.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050023#include "net/third_party/quiche/src/quic/core/quic_bandwidth.h"
24#include "net/third_party/quiche/src/quic/core/quic_config.h"
QUICHE teamc65d1d12019-03-19 20:58:04 -070025#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
ianswettdc1e7ab2019-05-03 16:10:44 -070026#include "net/third_party/quiche/src/quic/core/quic_error_codes.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050027#include "net/third_party/quiche/src/quic/core/quic_packet_generator.h"
28#include "net/third_party/quiche/src/quic/core/quic_pending_retransmission.h"
29#include "net/third_party/quiche/src/quic/core/quic_types.h"
30#include "net/third_party/quiche/src/quic/core/quic_utils.h"
31#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
32#include "net/third_party/quiche/src/quic/platform/api/quic_client_stats.h"
33#include "net/third_party/quiche/src/quic/platform/api/quic_error_code_wrappers.h"
34#include "net/third_party/quiche/src/quic/platform/api/quic_exported_stats.h"
35#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
36#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
37#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
38#include "net/third_party/quiche/src/quic/platform/api/quic_map_util.h"
39#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050040#include "net/third_party/quiche/src/quic/platform/api/quic_string_utils.h"
41#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h"
42
43namespace quic {
44
45class QuicDecrypter;
46class QuicEncrypter;
47
48namespace {
49
50// Maximum number of consecutive sent nonretransmittable packets.
51const QuicPacketCount kMaxConsecutiveNonRetransmittablePackets = 19;
52
QUICHE teama6ef0a62019-03-07 20:34:33 -050053// The minimum release time into future in ms.
54const int kMinReleaseTimeIntoFutureMs = 1;
55
QUICHE teama6ef0a62019-03-07 20:34:33 -050056// An alarm that is scheduled to send an ack if a timeout occurs.
57class AckAlarmDelegate : public QuicAlarm::Delegate {
58 public:
59 explicit AckAlarmDelegate(QuicConnection* connection)
60 : connection_(connection) {}
61 AckAlarmDelegate(const AckAlarmDelegate&) = delete;
62 AckAlarmDelegate& operator=(const AckAlarmDelegate&) = delete;
63
64 void OnAlarm() override {
65 DCHECK(connection_->ack_frame_updated());
fayanga4b37b22019-06-18 13:37:47 -070066 QuicConnection::ScopedPacketFlusher flusher(connection_);
67 if (connection_->SupportsMultiplePacketNumberSpaces()) {
68 connection_->SendAllPendingAcks();
69 } else {
70 DCHECK(!connection_->GetUpdatedAckFrame().ack_frame->packets.Empty());
71 connection_->SendAck();
QUICHE teama6ef0a62019-03-07 20:34:33 -050072 }
73 }
74
75 private:
76 QuicConnection* connection_;
77};
78
79// This alarm will be scheduled any time a data-bearing packet is sent out.
80// When the alarm goes off, the connection checks to see if the oldest packets
81// have been acked, and retransmit them if they have not.
82class RetransmissionAlarmDelegate : public QuicAlarm::Delegate {
83 public:
84 explicit RetransmissionAlarmDelegate(QuicConnection* connection)
85 : connection_(connection) {}
86 RetransmissionAlarmDelegate(const RetransmissionAlarmDelegate&) = delete;
87 RetransmissionAlarmDelegate& operator=(const RetransmissionAlarmDelegate&) =
88 delete;
89
90 void OnAlarm() override { connection_->OnRetransmissionTimeout(); }
91
92 private:
93 QuicConnection* connection_;
94};
95
96// An alarm that is scheduled when the SentPacketManager requires a delay
97// before sending packets and fires when the packet may be sent.
98class SendAlarmDelegate : public QuicAlarm::Delegate {
99 public:
100 explicit SendAlarmDelegate(QuicConnection* connection)
101 : connection_(connection) {}
102 SendAlarmDelegate(const SendAlarmDelegate&) = delete;
103 SendAlarmDelegate& operator=(const SendAlarmDelegate&) = delete;
104
105 void OnAlarm() override { connection_->WriteAndBundleAcksIfNotBlocked(); }
106
107 private:
108 QuicConnection* connection_;
109};
110
111class PathDegradingAlarmDelegate : public QuicAlarm::Delegate {
112 public:
113 explicit PathDegradingAlarmDelegate(QuicConnection* connection)
114 : connection_(connection) {}
115 PathDegradingAlarmDelegate(const PathDegradingAlarmDelegate&) = delete;
116 PathDegradingAlarmDelegate& operator=(const PathDegradingAlarmDelegate&) =
117 delete;
118
119 void OnAlarm() override { connection_->OnPathDegradingTimeout(); }
120
121 private:
122 QuicConnection* connection_;
123};
124
125class TimeoutAlarmDelegate : public QuicAlarm::Delegate {
126 public:
127 explicit TimeoutAlarmDelegate(QuicConnection* connection)
128 : connection_(connection) {}
129 TimeoutAlarmDelegate(const TimeoutAlarmDelegate&) = delete;
130 TimeoutAlarmDelegate& operator=(const TimeoutAlarmDelegate&) = delete;
131
132 void OnAlarm() override { connection_->CheckForTimeout(); }
133
134 private:
135 QuicConnection* connection_;
136};
137
138class PingAlarmDelegate : public QuicAlarm::Delegate {
139 public:
140 explicit PingAlarmDelegate(QuicConnection* connection)
141 : connection_(connection) {}
142 PingAlarmDelegate(const PingAlarmDelegate&) = delete;
143 PingAlarmDelegate& operator=(const PingAlarmDelegate&) = delete;
144
145 void OnAlarm() override { connection_->OnPingTimeout(); }
146
147 private:
148 QuicConnection* connection_;
149};
150
151class MtuDiscoveryAlarmDelegate : public QuicAlarm::Delegate {
152 public:
153 explicit MtuDiscoveryAlarmDelegate(QuicConnection* connection)
154 : connection_(connection) {}
155 MtuDiscoveryAlarmDelegate(const MtuDiscoveryAlarmDelegate&) = delete;
156 MtuDiscoveryAlarmDelegate& operator=(const MtuDiscoveryAlarmDelegate&) =
157 delete;
158
159 void OnAlarm() override { connection_->DiscoverMtu(); }
160
161 private:
162 QuicConnection* connection_;
163};
164
QUICHE teama6ef0a62019-03-07 20:34:33 -0500165class ProcessUndecryptablePacketsAlarmDelegate : public QuicAlarm::Delegate {
166 public:
167 explicit ProcessUndecryptablePacketsAlarmDelegate(QuicConnection* connection)
168 : connection_(connection) {}
169 ProcessUndecryptablePacketsAlarmDelegate(
170 const ProcessUndecryptablePacketsAlarmDelegate&) = delete;
171 ProcessUndecryptablePacketsAlarmDelegate& operator=(
172 const ProcessUndecryptablePacketsAlarmDelegate&) = delete;
173
rch2af16b12019-03-22 13:52:39 -0700174 void OnAlarm() override {
fayanga4b37b22019-06-18 13:37:47 -0700175 QuicConnection::ScopedPacketFlusher flusher(connection_);
rch2af16b12019-03-22 13:52:39 -0700176 connection_->MaybeProcessUndecryptablePackets();
177 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500178
179 private:
180 QuicConnection* connection_;
181};
182
QUICHE teamc65d1d12019-03-19 20:58:04 -0700183// Whether this incoming packet is allowed to replace our connection ID.
184bool PacketCanReplaceConnectionId(const QuicPacketHeader& header,
185 Perspective perspective) {
186 return perspective == Perspective::IS_CLIENT &&
187 header.form == IETF_QUIC_LONG_HEADER_PACKET &&
188 QuicUtils::VariableLengthConnectionIdAllowedForVersion(
189 header.version.transport_version) &&
190 (header.long_packet_type == INITIAL ||
191 header.long_packet_type == RETRY);
192}
193
wubd06ad102019-07-09 15:38:24 -0700194CongestionControlType GetDefaultCongestionControlType() {
195 if (GetQuicReloadableFlag(quic_default_to_bbr_v2)) {
196 return kBBRv2;
197 }
198
199 if (GetQuicReloadableFlag(quic_default_to_bbr)) {
200 return kBBR;
201 }
202
203 return kCubicBytes;
204}
205
QUICHE teama6ef0a62019-03-07 20:34:33 -0500206} // namespace
207
208#define ENDPOINT \
209 (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ")
210
211QuicConnection::QuicConnection(
dschinazi7b9278c2019-05-20 07:36:21 -0700212 QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500213 QuicSocketAddress initial_peer_address,
214 QuicConnectionHelperInterface* helper,
215 QuicAlarmFactory* alarm_factory,
216 QuicPacketWriter* writer,
217 bool owns_writer,
218 Perspective perspective,
219 const ParsedQuicVersionVector& supported_versions)
220 : framer_(supported_versions,
221 helper->GetClock()->ApproximateNow(),
222 perspective,
dschinazi7b9278c2019-05-20 07:36:21 -0700223 server_connection_id.length()),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500224 current_packet_content_(NO_FRAMES_RECEIVED),
225 is_current_packet_connectivity_probing_(false),
226 current_effective_peer_migration_type_(NO_CHANGE),
227 helper_(helper),
228 alarm_factory_(alarm_factory),
229 per_packet_options_(nullptr),
230 writer_(writer),
231 owns_writer_(owns_writer),
QUICHE team6987b4a2019-03-15 16:23:04 -0700232 encryption_level_(ENCRYPTION_INITIAL),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500233 clock_(helper->GetClock()),
234 random_generator_(helper->GetRandomGenerator()),
dschinazi7b9278c2019-05-20 07:36:21 -0700235 server_connection_id_(server_connection_id),
dschinazi346b7ce2019-06-05 01:38:18 -0700236 client_connection_id_(EmptyQuicConnectionId()),
237 client_connection_id_is_set_(false),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500238 peer_address_(initial_peer_address),
239 direct_peer_address_(initial_peer_address),
240 active_effective_peer_migration_type_(NO_CHANGE),
241 last_packet_decrypted_(false),
242 last_size_(0),
243 current_packet_data_(nullptr),
QUICHE team6987b4a2019-03-15 16:23:04 -0700244 last_decrypted_packet_level_(ENCRYPTION_INITIAL),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500245 should_last_packet_instigate_acks_(false),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500246 max_undecryptable_packets_(0),
fayanga0727f92019-07-16 13:49:46 -0700247 max_tracked_packets_(GetQuicFlag(FLAGS_quic_max_tracked_packet_count)),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500248 pending_version_negotiation_packet_(false),
249 send_ietf_version_negotiation_packet_(false),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500250 idle_timeout_connection_close_behavior_(
251 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET),
252 close_connection_after_five_rtos_(false),
QUICHE teamb23daa72019-03-21 08:37:48 -0700253 uber_received_packet_manager_(&stats_),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500254 stop_waiting_count_(0),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500255 pending_retransmission_alarm_(false),
256 defer_send_in_response_to_packets_(false),
257 ping_timeout_(QuicTime::Delta::FromSeconds(kPingTimeoutSecs)),
258 retransmittable_on_wire_timeout_(QuicTime::Delta::Infinite()),
259 arena_(),
260 ack_alarm_(alarm_factory_->CreateAlarm(arena_.New<AckAlarmDelegate>(this),
261 &arena_)),
262 retransmission_alarm_(alarm_factory_->CreateAlarm(
263 arena_.New<RetransmissionAlarmDelegate>(this),
264 &arena_)),
265 send_alarm_(
266 alarm_factory_->CreateAlarm(arena_.New<SendAlarmDelegate>(this),
267 &arena_)),
268 timeout_alarm_(
269 alarm_factory_->CreateAlarm(arena_.New<TimeoutAlarmDelegate>(this),
270 &arena_)),
271 ping_alarm_(
272 alarm_factory_->CreateAlarm(arena_.New<PingAlarmDelegate>(this),
273 &arena_)),
274 mtu_discovery_alarm_(alarm_factory_->CreateAlarm(
275 arena_.New<MtuDiscoveryAlarmDelegate>(this),
276 &arena_)),
277 path_degrading_alarm_(alarm_factory_->CreateAlarm(
278 arena_.New<PathDegradingAlarmDelegate>(this),
279 &arena_)),
280 process_undecryptable_packets_alarm_(alarm_factory_->CreateAlarm(
281 arena_.New<ProcessUndecryptablePacketsAlarmDelegate>(this),
282 &arena_)),
283 visitor_(nullptr),
284 debug_visitor_(nullptr),
dschinazi7b9278c2019-05-20 07:36:21 -0700285 packet_generator_(server_connection_id_,
286 &framer_,
287 random_generator_,
288 this),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500289 idle_network_timeout_(QuicTime::Delta::Infinite()),
290 handshake_timeout_(QuicTime::Delta::Infinite()),
zhongyic1cab062019-06-19 12:02:24 -0700291 time_of_first_packet_sent_after_receiving_(QuicTime::Zero()),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500292 time_of_last_received_packet_(clock_->ApproximateNow()),
wubd06ad102019-07-09 15:38:24 -0700293 sent_packet_manager_(perspective,
294 clock_,
295 random_generator_,
296 &stats_,
297 GetDefaultCongestionControlType(),
298 kNack),
fayang8aba1ff2019-06-21 12:00:54 -0700299 version_negotiated_(false),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500300 perspective_(perspective),
301 connected_(true),
302 can_truncate_connection_ids_(perspective == Perspective::IS_SERVER),
303 mtu_discovery_target_(0),
304 mtu_probe_count_(0),
305 packets_between_mtu_probes_(kPacketsBetweenMtuProbesBase),
306 next_mtu_probe_at_(kPacketsBetweenMtuProbesBase),
307 largest_received_packet_size_(0),
308 write_error_occurred_(false),
fayangd4291e42019-05-30 10:31:21 -0700309 no_stop_waiting_frames_(
310 VersionHasIetfInvariantHeader(transport_version())),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500311 consecutive_num_packets_with_no_retransmittable_frames_(0),
312 max_consecutive_num_packets_with_no_retransmittable_frames_(
313 kMaxConsecutiveNonRetransmittablePackets),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500314 fill_up_link_during_probing_(false),
315 probing_retransmission_pending_(false),
316 stateless_reset_token_received_(false),
317 received_stateless_reset_token_(0),
318 last_control_frame_id_(kInvalidControlFrameId),
319 is_path_degrading_(false),
320 processing_ack_frame_(false),
321 supports_release_time_(false),
322 release_time_into_future_(QuicTime::Delta::Zero()),
fayang5f464302019-06-20 12:57:33 -0700323 retry_has_been_parsed_(false) {
dschinazi8ff74822019-05-28 16:37:20 -0700324 QUIC_DLOG(INFO) << ENDPOINT << "Created connection with server connection ID "
dschinazi7b9278c2019-05-20 07:36:21 -0700325 << server_connection_id
zhongyi546cc452019-04-12 15:27:49 -0700326 << " and version: " << ParsedQuicVersionToString(version());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500327
dschinazi7b9278c2019-05-20 07:36:21 -0700328 QUIC_BUG_IF(!QuicUtils::IsConnectionIdValidForVersion(server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500329 transport_version()))
dschinazi7b9278c2019-05-20 07:36:21 -0700330 << "QuicConnection: attempted to use server connection ID "
331 << server_connection_id << " which is invalid with version "
QUICHE teama6ef0a62019-03-07 20:34:33 -0500332 << QuicVersionToString(transport_version());
333
334 framer_.set_visitor(this);
335 stats_.connection_creation_time = clock_->ApproximateNow();
336 // TODO(ianswett): Supply the NetworkChangeVisitor as a constructor argument
337 // and make it required non-null, because it's always used.
338 sent_packet_manager_.SetNetworkChangeVisitor(this);
339 if (GetQuicRestartFlag(quic_offload_pacing_to_usps2)) {
340 sent_packet_manager_.SetPacingAlarmGranularity(QuicTime::Delta::Zero());
341 release_time_into_future_ =
342 QuicTime::Delta::FromMilliseconds(kMinReleaseTimeIntoFutureMs);
343 }
344 // Allow the packet writer to potentially reduce the packet size to a value
345 // even smaller than kDefaultMaxPacketSize.
346 SetMaxPacketLength(perspective_ == Perspective::IS_SERVER
347 ? kDefaultServerMaxPacketSize
348 : kDefaultMaxPacketSize);
fayang5f464302019-06-20 12:57:33 -0700349 uber_received_packet_manager_.set_max_ack_ranges(255);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500350 MaybeEnableSessionDecidesWhatToWrite();
QUICHE teamcd098022019-03-22 18:49:55 -0700351 MaybeEnableMultiplePacketNumberSpacesSupport();
fayang8aba1ff2019-06-21 12:00:54 -0700352 DCHECK(perspective_ == Perspective::IS_CLIENT ||
QUICHE teama6ef0a62019-03-07 20:34:33 -0500353 supported_versions.size() == 1);
dschinazi5c030852019-07-11 15:45:53 -0700354 InstallInitialCrypters(server_connection_id_);
dschinazi6ece5002019-05-22 06:35:49 -0700355}
356
dschinazi5c030852019-07-11 15:45:53 -0700357void QuicConnection::InstallInitialCrypters(QuicConnectionId connection_id) {
dschinazi6ece5002019-05-22 06:35:49 -0700358 if (version().handshake_protocol != PROTOCOL_TLS1_3) {
359 // Initial crypters are currently only supported with TLS.
360 return;
361 }
362 CrypterPair crypters;
363 CryptoUtils::CreateTlsInitialCrypters(perspective_, transport_version(),
dschinazi5c030852019-07-11 15:45:53 -0700364 connection_id, &crypters);
dschinazi6ece5002019-05-22 06:35:49 -0700365 SetEncrypter(ENCRYPTION_INITIAL, std::move(crypters.encrypter));
366 InstallDecrypter(ENCRYPTION_INITIAL, std::move(crypters.decrypter));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500367}
368
369QuicConnection::~QuicConnection() {
370 if (owns_writer_) {
371 delete writer_;
372 }
373 ClearQueuedPackets();
374}
375
376void QuicConnection::ClearQueuedPackets() {
377 for (auto it = queued_packets_.begin(); it != queued_packets_.end(); ++it) {
378 // Delete the buffer before calling ClearSerializedPacket, which sets
379 // encrypted_buffer to nullptr.
380 delete[] it->encrypted_buffer;
381 ClearSerializedPacket(&(*it));
382 }
383 queued_packets_.clear();
384}
385
386void QuicConnection::SetFromConfig(const QuicConfig& config) {
387 if (config.negotiated()) {
388 // Handshake complete, set handshake timeout to Infinite.
389 SetNetworkTimeouts(QuicTime::Delta::Infinite(),
390 config.IdleNetworkTimeout());
391 if (config.SilentClose()) {
392 idle_timeout_connection_close_behavior_ =
393 ConnectionCloseBehavior::SILENT_CLOSE;
394 }
395 } else {
396 SetNetworkTimeouts(config.max_time_before_crypto_handshake(),
397 config.max_idle_time_before_crypto_handshake());
398 }
399
400 sent_packet_manager_.SetFromConfig(config);
401 if (config.HasReceivedBytesForConnectionId() &&
402 can_truncate_connection_ids_) {
dschinazi7b9278c2019-05-20 07:36:21 -0700403 packet_generator_.SetServerConnectionIdLength(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500404 config.ReceivedBytesForConnectionId());
405 }
406 max_undecryptable_packets_ = config.max_undecryptable_packets();
407
408 if (config.HasClientSentConnectionOption(kMTUH, perspective_)) {
409 SetMtuDiscoveryTarget(kMtuDiscoveryTargetPacketSizeHigh);
410 }
411 if (config.HasClientSentConnectionOption(kMTUL, perspective_)) {
412 SetMtuDiscoveryTarget(kMtuDiscoveryTargetPacketSizeLow);
413 }
414 if (debug_visitor_ != nullptr) {
415 debug_visitor_->OnSetFromConfig(config);
416 }
fayang5f464302019-06-20 12:57:33 -0700417 uber_received_packet_manager_.SetFromConfig(config, perspective_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500418 if (config.HasClientSentConnectionOption(k5RTO, perspective_)) {
419 close_connection_after_five_rtos_ = true;
420 }
421 if (config.HasClientSentConnectionOption(kNSTP, perspective_)) {
422 no_stop_waiting_frames_ = true;
423 }
424 if (config.HasReceivedStatelessResetToken()) {
425 stateless_reset_token_received_ = true;
426 received_stateless_reset_token_ = config.ReceivedStatelessResetToken();
427 }
fkastenholz4dc4ba32019-07-30 09:55:25 -0700428 if (config.HasReceivedAckDelayExponent()) {
429 framer_.set_peer_ack_delay_exponent(config.ReceivedAckDelayExponent());
430 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500431 if (GetQuicReloadableFlag(quic_send_timestamps) &&
432 config.HasClientSentConnectionOption(kSTMP, perspective_)) {
433 QUIC_RELOADABLE_FLAG_COUNT(quic_send_timestamps);
434 framer_.set_process_timestamps(true);
fayang5f464302019-06-20 12:57:33 -0700435 uber_received_packet_manager_.set_save_timestamps(true);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500436 }
437
438 supports_release_time_ =
439 writer_ != nullptr && writer_->SupportsReleaseTime() &&
440 !config.HasClientSentConnectionOption(kNPCO, perspective_);
441
442 if (supports_release_time_) {
443 UpdateReleaseTimeIntoFuture();
444 }
445}
446
447void QuicConnection::OnSendConnectionState(
448 const CachedNetworkParameters& cached_network_params) {
449 if (debug_visitor_ != nullptr) {
450 debug_visitor_->OnSendConnectionState(cached_network_params);
451 }
452}
453
454void QuicConnection::OnReceiveConnectionState(
455 const CachedNetworkParameters& cached_network_params) {
456 if (debug_visitor_ != nullptr) {
457 debug_visitor_->OnReceiveConnectionState(cached_network_params);
458 }
459}
460
461void QuicConnection::ResumeConnectionState(
462 const CachedNetworkParameters& cached_network_params,
463 bool max_bandwidth_resumption) {
464 sent_packet_manager_.ResumeConnectionState(cached_network_params,
465 max_bandwidth_resumption);
466}
467
468void QuicConnection::SetMaxPacingRate(QuicBandwidth max_pacing_rate) {
469 sent_packet_manager_.SetMaxPacingRate(max_pacing_rate);
470}
471
472void QuicConnection::AdjustNetworkParameters(QuicBandwidth bandwidth,
fayangf1b99dc2019-05-14 06:29:18 -0700473 QuicTime::Delta rtt,
474 bool allow_cwnd_to_decrease) {
475 sent_packet_manager_.AdjustNetworkParameters(bandwidth, rtt,
476 allow_cwnd_to_decrease);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500477}
478
479QuicBandwidth QuicConnection::MaxPacingRate() const {
480 return sent_packet_manager_.MaxPacingRate();
481}
482
483bool QuicConnection::SelectMutualVersion(
484 const ParsedQuicVersionVector& available_versions) {
485 // Try to find the highest mutual version by iterating over supported
486 // versions, starting with the highest, and breaking out of the loop once we
487 // find a matching version in the provided available_versions vector.
488 const ParsedQuicVersionVector& supported_versions =
489 framer_.supported_versions();
490 for (size_t i = 0; i < supported_versions.size(); ++i) {
491 const ParsedQuicVersion& version = supported_versions[i];
492 if (QuicContainsValue(available_versions, version)) {
493 framer_.set_version(version);
494 return true;
495 }
496 }
497
498 return false;
499}
500
501void QuicConnection::OnError(QuicFramer* framer) {
502 // Packets that we can not or have not decrypted are dropped.
503 // TODO(rch): add stats to measure this.
504 if (!connected_ || last_packet_decrypted_ == false) {
505 return;
506 }
507 CloseConnection(framer->error(), framer->detailed_error(),
508 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
509}
510
511void QuicConnection::OnPacket() {
512 last_packet_decrypted_ = false;
513}
514
515void QuicConnection::OnPublicResetPacket(const QuicPublicResetPacket& packet) {
516 // Check that any public reset packet with a different connection ID that was
517 // routed to this QuicConnection has been redirected before control reaches
518 // here. (Check for a bug regression.)
dschinazi7b9278c2019-05-20 07:36:21 -0700519 DCHECK_EQ(server_connection_id_, packet.connection_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500520 DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
521 if (debug_visitor_ != nullptr) {
522 debug_visitor_->OnPublicResetPacket(packet);
523 }
vasilvvc48c8712019-03-11 13:38:16 -0700524 std::string error_details = "Received public reset.";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500525 if (perspective_ == Perspective::IS_CLIENT && !packet.endpoint_id.empty()) {
526 QuicStrAppend(&error_details, " From ", packet.endpoint_id, ".");
527 }
528 QUIC_DLOG(INFO) << ENDPOINT << error_details;
529 QUIC_CODE_COUNT(quic_tear_down_local_connection_on_public_reset);
530 TearDownLocalConnectionState(QUIC_PUBLIC_RESET, error_details,
531 ConnectionCloseSource::FROM_PEER);
532}
533
534bool QuicConnection::OnProtocolVersionMismatch(
fayang8aba1ff2019-06-21 12:00:54 -0700535 ParsedQuicVersion received_version) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500536 QUIC_DLOG(INFO) << ENDPOINT << "Received packet with mismatched version "
537 << ParsedQuicVersionToString(received_version);
538 if (perspective_ == Perspective::IS_CLIENT) {
vasilvvc48c8712019-03-11 13:38:16 -0700539 const std::string error_details = "Protocol version mismatch.";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500540 QUIC_BUG << ENDPOINT << error_details;
fkastenholz85f18902019-05-28 12:47:00 -0700541 CloseConnection(QUIC_INTERNAL_ERROR, error_details,
542 ConnectionCloseBehavior::SILENT_CLOSE);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500543 }
544
fayang8aba1ff2019-06-21 12:00:54 -0700545 // Server drops old packets that were sent by the client before the version
546 // was negotiated.
547 return false;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500548}
549
550// Handles version negotiation for client connection.
551void QuicConnection::OnVersionNegotiationPacket(
552 const QuicVersionNegotiationPacket& packet) {
553 // Check that any public reset packet with a different connection ID that was
554 // routed to this QuicConnection has been redirected before control reaches
555 // here. (Check for a bug regression.)
dschinazi7b9278c2019-05-20 07:36:21 -0700556 DCHECK_EQ(server_connection_id_, packet.connection_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500557 if (perspective_ == Perspective::IS_SERVER) {
vasilvvc48c8712019-03-11 13:38:16 -0700558 const std::string error_details =
dschinazi5a354c92019-05-09 12:18:53 -0700559 "Server received version negotiation packet.";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500560 QUIC_BUG << error_details;
561 QUIC_CODE_COUNT(quic_tear_down_local_connection_on_version_negotiation);
fkastenholz85f18902019-05-28 12:47:00 -0700562 CloseConnection(QUIC_INTERNAL_ERROR, error_details,
563 ConnectionCloseBehavior::SILENT_CLOSE);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500564 return;
565 }
566 if (debug_visitor_ != nullptr) {
567 debug_visitor_->OnVersionNegotiationPacket(packet);
568 }
569
fayang8aba1ff2019-06-21 12:00:54 -0700570 if (version_negotiated_) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500571 // Possibly a duplicate version negotiation packet.
572 return;
573 }
574
575 if (QuicContainsValue(packet.versions, version())) {
dschinazic8579862019-07-24 18:20:20 -0700576 const std::string error_details = QuicStrCat(
577 "Server already supports client's version ",
578 ParsedQuicVersionToString(version()),
579 " and should have accepted the connection instead of sending {",
580 ParsedQuicVersionVectorToString(packet.versions), "}.");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500581 QUIC_DLOG(WARNING) << error_details;
fkastenholz85f18902019-05-28 12:47:00 -0700582 CloseConnection(QUIC_INVALID_VERSION_NEGOTIATION_PACKET, error_details,
583 ConnectionCloseBehavior::SILENT_CLOSE);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500584 return;
585 }
586
587 server_supported_versions_ = packet.versions;
fayang9ed391a2019-06-20 11:16:59 -0700588 CloseConnection(
589 QUIC_INVALID_VERSION,
590 QuicStrCat(
591 "Client may support one of the versions in the server's list, but "
592 "it's going to close the connection anyway. Supported versions: {",
593 ParsedQuicVersionVectorToString(framer_.supported_versions()),
594 "}, peer supported versions: {",
595 ParsedQuicVersionVectorToString(packet.versions), "}"),
596 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500597}
598
dschinazi244f6dc2019-05-06 15:45:16 -0700599// Handles retry for client connection.
600void QuicConnection::OnRetryPacket(QuicConnectionId original_connection_id,
601 QuicConnectionId new_connection_id,
602 QuicStringPiece retry_token) {
dschinazi6ece5002019-05-22 06:35:49 -0700603 DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
dschinazi7b9278c2019-05-20 07:36:21 -0700604 if (original_connection_id != server_connection_id_) {
dschinazi244f6dc2019-05-06 15:45:16 -0700605 QUIC_DLOG(ERROR) << "Ignoring RETRY with original connection ID "
606 << original_connection_id << " not matching expected "
dschinazi7b9278c2019-05-20 07:36:21 -0700607 << server_connection_id_ << " token "
dschinazi244f6dc2019-05-06 15:45:16 -0700608 << QuicTextUtils::HexEncode(retry_token);
609 return;
610 }
611 if (retry_has_been_parsed_) {
612 QUIC_DLOG(ERROR) << "Ignoring non-first RETRY with token "
613 << QuicTextUtils::HexEncode(retry_token);
614 return;
615 }
616 retry_has_been_parsed_ = true;
617 QUIC_DLOG(INFO) << "Received RETRY, replacing connection ID "
dschinazi7b9278c2019-05-20 07:36:21 -0700618 << server_connection_id_ << " with " << new_connection_id
dschinazi244f6dc2019-05-06 15:45:16 -0700619 << ", received token "
620 << QuicTextUtils::HexEncode(retry_token);
dschinazi7b9278c2019-05-20 07:36:21 -0700621 server_connection_id_ = new_connection_id;
622 packet_generator_.SetServerConnectionId(server_connection_id_);
dschinazi244f6dc2019-05-06 15:45:16 -0700623 packet_generator_.SetRetryToken(retry_token);
624
625 // Reinstall initial crypters because the connection ID changed.
dschinazi5c030852019-07-11 15:45:53 -0700626 InstallInitialCrypters(server_connection_id_);
dschinazi244f6dc2019-05-06 15:45:16 -0700627}
628
QUICHE teamc65d1d12019-03-19 20:58:04 -0700629bool QuicConnection::HasIncomingConnectionId(QuicConnectionId connection_id) {
630 for (QuicConnectionId const& incoming_connection_id :
631 incoming_connection_ids_) {
632 if (incoming_connection_id == connection_id) {
633 return true;
634 }
635 }
636 return false;
637}
638
639void QuicConnection::AddIncomingConnectionId(QuicConnectionId connection_id) {
640 if (HasIncomingConnectionId(connection_id)) {
641 return;
642 }
643 incoming_connection_ids_.push_back(connection_id);
644}
645
QUICHE teama6ef0a62019-03-07 20:34:33 -0500646bool QuicConnection::OnUnauthenticatedPublicHeader(
647 const QuicPacketHeader& header) {
QUICHE team2252b702019-05-14 23:55:14 -0400648 QuicConnectionId server_connection_id =
649 GetServerConnectionIdAsRecipient(header, perspective_);
650
dschinazi346b7ce2019-06-05 01:38:18 -0700651 if (server_connection_id != server_connection_id_ &&
652 !HasIncomingConnectionId(server_connection_id)) {
653 if (PacketCanReplaceConnectionId(header, perspective_)) {
654 QUIC_DLOG(INFO) << ENDPOINT << "Accepting packet with new connection ID "
655 << server_connection_id << " instead of "
656 << server_connection_id_;
657 return true;
658 }
659
660 ++stats_.packets_dropped;
661 QUIC_DLOG(INFO) << ENDPOINT
662 << "Ignoring packet from unexpected server connection ID "
663 << server_connection_id << " instead of "
664 << server_connection_id_;
665 if (debug_visitor_ != nullptr) {
666 debug_visitor_->OnIncorrectConnectionId(server_connection_id);
667 }
668 // If this is a server, the dispatcher routes each packet to the
669 // QuicConnection responsible for the packet's connection ID. So if control
670 // arrives here and this is a server, the dispatcher must be malfunctioning.
671 DCHECK_NE(Perspective::IS_SERVER, perspective_);
672 return false;
673 }
674
675 if (!version().SupportsClientConnectionIds()) {
QUICHE teamc65d1d12019-03-19 20:58:04 -0700676 return true;
677 }
678
dschinazi346b7ce2019-06-05 01:38:18 -0700679 QuicConnectionId client_connection_id =
680 GetClientConnectionIdAsRecipient(header, perspective_);
681
682 if (client_connection_id == client_connection_id_) {
683 return true;
684 }
685
686 if (!client_connection_id_is_set_ && perspective_ == Perspective::IS_SERVER) {
687 QUIC_DLOG(INFO) << ENDPOINT
688 << "Setting client connection ID from first packet to "
689 << client_connection_id;
690 set_client_connection_id(client_connection_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500691 return true;
692 }
693
694 ++stats_.packets_dropped;
695 QUIC_DLOG(INFO) << ENDPOINT
dschinazi346b7ce2019-06-05 01:38:18 -0700696 << "Ignoring packet from unexpected client connection ID "
697 << client_connection_id << " instead of "
698 << client_connection_id_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500699 return false;
700}
701
702bool QuicConnection::OnUnauthenticatedHeader(const QuicPacketHeader& header) {
703 if (debug_visitor_ != nullptr) {
704 debug_visitor_->OnUnauthenticatedHeader(header);
705 }
706
707 // Check that any public reset packet with a different connection ID that was
708 // routed to this QuicConnection has been redirected before control reaches
709 // here.
QUICHE team2252b702019-05-14 23:55:14 -0400710 DCHECK(GetServerConnectionIdAsRecipient(header, perspective_) ==
dschinazi7b9278c2019-05-20 07:36:21 -0700711 server_connection_id_ ||
QUICHE team2252b702019-05-14 23:55:14 -0400712 HasIncomingConnectionId(
713 GetServerConnectionIdAsRecipient(header, perspective_)) ||
QUICHE teamc65d1d12019-03-19 20:58:04 -0700714 PacketCanReplaceConnectionId(header, perspective_));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500715
fayang914fbe12019-07-11 06:23:55 -0700716 if (packet_generator_.HasPendingFrames()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500717 // Incoming packets may change a queued ACK frame.
vasilvvc48c8712019-03-11 13:38:16 -0700718 const std::string error_details =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500719 "Pending frames must be serialized before incoming packets are "
720 "processed.";
721 QUIC_BUG << error_details << ", received header: " << header;
722 CloseConnection(QUIC_INTERNAL_ERROR, error_details,
723 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
724 return false;
725 }
726
fayang8aba1ff2019-06-21 12:00:54 -0700727 if (!version_negotiated_ && perspective_ == Perspective::IS_SERVER) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500728 if (!header.version_flag) {
729 // Packets should have the version flag till version negotiation is
730 // done.
vasilvvc48c8712019-03-11 13:38:16 -0700731 std::string error_details =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500732 QuicStrCat(ENDPOINT, "Packet ", header.packet_number.ToUint64(),
733 " without version flag before version negotiated.");
734 QUIC_DLOG(WARNING) << error_details;
735 CloseConnection(QUIC_INVALID_VERSION, error_details,
736 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
737 return false;
738 } else {
739 DCHECK_EQ(header.version, version());
fayang8aba1ff2019-06-21 12:00:54 -0700740 version_negotiated_ = true;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500741 framer_.InferPacketHeaderTypeFromVersion();
742 visitor_->OnSuccessfulVersionNegotiation(version());
743 if (debug_visitor_ != nullptr) {
744 debug_visitor_->OnSuccessfulVersionNegotiation(version());
745 }
746 }
fayang8aba1ff2019-06-21 12:00:54 -0700747 DCHECK(version_negotiated_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500748 }
749
750 return true;
751}
752
753void QuicConnection::OnDecryptedPacket(EncryptionLevel level) {
754 last_decrypted_packet_level_ = level;
755 last_packet_decrypted_ = true;
756
757 // Once the server receives a forward secure packet, the handshake is
758 // confirmed.
759 if (level == ENCRYPTION_FORWARD_SECURE &&
760 perspective_ == Perspective::IS_SERVER) {
761 sent_packet_manager_.SetHandshakeConfirmed();
fayangbf3d2862019-06-20 14:13:44 -0700762 // This may have changed the retransmission timer, so re-arm it.
763 SetRetransmissionAlarm();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500764 }
765}
766
767QuicSocketAddress QuicConnection::GetEffectivePeerAddressFromCurrentPacket()
768 const {
769 // By default, the connection is not proxied, and the effective peer address
770 // is the packet's source address, i.e. the direct peer address.
771 return last_packet_source_address_;
772}
773
774bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) {
775 if (debug_visitor_ != nullptr) {
776 debug_visitor_->OnPacketHeader(header);
777 }
778
779 // Will be decremented below if we fall through to return true.
780 ++stats_.packets_dropped;
781
782 if (!ProcessValidatedPacket(header)) {
783 return false;
784 }
785
786 // Initialize the current packet content state.
787 current_packet_content_ = NO_FRAMES_RECEIVED;
788 is_current_packet_connectivity_probing_ = false;
789 current_effective_peer_migration_type_ = NO_CHANGE;
790
791 if (perspective_ == Perspective::IS_CLIENT) {
QUICHE team1f3de242019-03-20 07:24:48 -0700792 if (!GetLargestReceivedPacket().IsInitialized() ||
793 header.packet_number > GetLargestReceivedPacket()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500794 // Update peer_address_ and effective_peer_address_ immediately for
795 // client connections.
QUICHE team1f3de242019-03-20 07:24:48 -0700796 // TODO(fayang): only change peer addresses in application data packet
797 // number space.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500798 direct_peer_address_ = last_packet_source_address_;
799 effective_peer_address_ = GetEffectivePeerAddressFromCurrentPacket();
800 }
801 } else {
802 // At server, remember the address change type of effective_peer_address
803 // in current_effective_peer_migration_type_. But this variable alone
804 // doesn't necessarily starts a migration. A migration will be started
805 // later, once the current packet is confirmed to meet the following
806 // conditions:
807 // 1) current_effective_peer_migration_type_ is not NO_CHANGE.
808 // 2) The current packet is not a connectivity probing.
809 // 3) The current packet is not reordered, i.e. its packet number is the
810 // largest of this connection so far.
811 // Once the above conditions are confirmed, a new migration will start
812 // even if there is an active migration underway.
813 current_effective_peer_migration_type_ =
814 QuicUtils::DetermineAddressChangeType(
815 effective_peer_address_,
816 GetEffectivePeerAddressFromCurrentPacket());
817
818 QUIC_DLOG_IF(INFO, current_effective_peer_migration_type_ != NO_CHANGE)
819 << ENDPOINT << "Effective peer's ip:port changed from "
820 << effective_peer_address_.ToString() << " to "
821 << GetEffectivePeerAddressFromCurrentPacket().ToString()
822 << ", active_effective_peer_migration_type is "
823 << active_effective_peer_migration_type_;
824 }
825
826 --stats_.packets_dropped;
827 QUIC_DVLOG(1) << ENDPOINT << "Received packet header: " << header;
828 last_header_ = header;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500829
830 // Record packet receipt to populate ack info before processing stream
831 // frames, since the processing may result in sending a bundled ack.
fayang5f464302019-06-20 12:57:33 -0700832 uber_received_packet_manager_.RecordPacketReceived(
833 last_decrypted_packet_level_, last_header_,
834 time_of_last_received_packet_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500835 DCHECK(connected_);
836 return true;
837}
838
839bool QuicConnection::OnStreamFrame(const QuicStreamFrame& frame) {
840 DCHECK(connected_);
841
842 // Since a stream frame was received, this is not a connectivity probe.
843 // A probe only contains a PING and full padding.
844 UpdatePacketContent(NOT_PADDED_PING);
845
846 if (debug_visitor_ != nullptr) {
847 debug_visitor_->OnStreamFrame(frame);
848 }
nharper46833c32019-05-15 21:33:05 -0700849 if (!QuicUtils::IsCryptoStreamId(transport_version(), frame.stream_id) &&
QUICHE team6987b4a2019-03-15 16:23:04 -0700850 last_decrypted_packet_level_ == ENCRYPTION_INITIAL) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500851 if (MaybeConsiderAsMemoryCorruption(frame)) {
852 CloseConnection(QUIC_MAYBE_CORRUPTED_MEMORY,
853 "Received crypto frame on non crypto stream.",
854 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
855 return false;
856 }
857
858 QUIC_PEER_BUG << ENDPOINT
859 << "Received an unencrypted data frame: closing connection"
860 << " packet_number:" << last_header_.packet_number
QUICHE teamb23daa72019-03-21 08:37:48 -0700861 << " stream_id:" << frame.stream_id
fayang21ffb712019-05-16 08:39:26 -0700862 << " received_packets:" << ack_frame();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500863 CloseConnection(QUIC_UNENCRYPTED_STREAM_DATA,
864 "Unencrypted stream data seen.",
865 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
866 return false;
867 }
868 visitor_->OnStreamFrame(frame);
869 stats_.stream_bytes_received += frame.data_length;
870 should_last_packet_instigate_acks_ = true;
871 return connected_;
872}
873
874bool QuicConnection::OnCryptoFrame(const QuicCryptoFrame& frame) {
875 DCHECK(connected_);
876
877 // Since a CRYPTO frame was received, this is not a connectivity probe.
878 // A probe only contains a PING and full padding.
879 UpdatePacketContent(NOT_PADDED_PING);
880
881 visitor_->OnCryptoFrame(frame);
882 should_last_packet_instigate_acks_ = true;
883 return connected_;
884}
885
886bool QuicConnection::OnAckFrameStart(QuicPacketNumber largest_acked,
887 QuicTime::Delta ack_delay_time) {
888 DCHECK(connected_);
889
890 if (processing_ack_frame_) {
891 CloseConnection(QUIC_INVALID_ACK_DATA,
892 "Received a new ack while processing an ack frame.",
893 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
894 return false;
895 }
896
897 // Since an ack frame was received, this is not a connectivity probe.
898 // A probe only contains a PING and full padding.
899 UpdatePacketContent(NOT_PADDED_PING);
900
901 QUIC_DVLOG(1) << ENDPOINT
902 << "OnAckFrameStart, largest_acked: " << largest_acked;
903
QUICHE team76e1c622019-03-19 14:36:39 -0700904 if (GetLargestReceivedPacketWithAck().IsInitialized() &&
905 last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500906 QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
907 return true;
908 }
909
QUICHE team76e1c622019-03-19 14:36:39 -0700910 if (!GetLargestSentPacket().IsInitialized() ||
911 largest_acked > GetLargestSentPacket()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500912 QUIC_DLOG(WARNING) << ENDPOINT
913 << "Peer's observed unsent packet:" << largest_acked
QUICHE team76e1c622019-03-19 14:36:39 -0700914 << " vs " << GetLargestSentPacket();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500915 // We got an ack for data we have not sent.
916 CloseConnection(QUIC_INVALID_ACK_DATA, "Largest observed too high.",
917 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
918 return false;
919 }
920
QUICHE team76e1c622019-03-19 14:36:39 -0700921 if (!GetLargestAckedPacket().IsInitialized() ||
922 largest_acked > GetLargestAckedPacket()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500923 visitor_->OnForwardProgressConfirmed();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500924 }
925 processing_ack_frame_ = true;
926 sent_packet_manager_.OnAckFrameStart(largest_acked, ack_delay_time,
927 time_of_last_received_packet_);
928 return true;
929}
930
931bool QuicConnection::OnAckRange(QuicPacketNumber start, QuicPacketNumber end) {
932 DCHECK(connected_);
933 QUIC_DVLOG(1) << ENDPOINT << "OnAckRange: [" << start << ", " << end << ")";
934
QUICHE team76e1c622019-03-19 14:36:39 -0700935 if (GetLargestReceivedPacketWithAck().IsInitialized() &&
936 last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500937 QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
938 return true;
939 }
940
941 sent_packet_manager_.OnAckRange(start, end);
942 return true;
943}
944
945bool QuicConnection::OnAckTimestamp(QuicPacketNumber packet_number,
946 QuicTime timestamp) {
947 DCHECK(connected_);
948 QUIC_DVLOG(1) << ENDPOINT << "OnAckTimestamp: [" << packet_number << ", "
949 << timestamp.ToDebuggingValue() << ")";
950
QUICHE team76e1c622019-03-19 14:36:39 -0700951 if (GetLargestReceivedPacketWithAck().IsInitialized() &&
952 last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500953 QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
954 return true;
955 }
956
957 sent_packet_manager_.OnAckTimestamp(packet_number, timestamp);
958 return true;
959}
960
961bool QuicConnection::OnAckFrameEnd(QuicPacketNumber start) {
962 DCHECK(connected_);
963 QUIC_DVLOG(1) << ENDPOINT << "OnAckFrameEnd, start: " << start;
964
QUICHE team76e1c622019-03-19 14:36:39 -0700965 if (GetLargestReceivedPacketWithAck().IsInitialized() &&
966 last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500967 QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
968 return true;
969 }
fayang3eb82212019-04-16 12:05:46 -0700970 const AckResult ack_result = sent_packet_manager_.OnAckFrameEnd(
fayangf8e918b2019-07-16 13:03:16 -0700971 time_of_last_received_packet_, last_header_.packet_number,
972 last_decrypted_packet_level_);
fayang3eb82212019-04-16 12:05:46 -0700973 if (ack_result != PACKETS_NEWLY_ACKED &&
974 ack_result != NO_PACKETS_NEWLY_ACKED) {
975 // Error occurred (e.g., this ACK tries to ack packets in wrong packet
976 // number space), and this would cause the connection to be closed.
977 QUIC_DLOG(ERROR) << ENDPOINT
978 << "Error occurred when processing an ACK frame: "
979 << QuicUtils::AckResultToString(ack_result);
980 return false;
981 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500982 // Cancel the send alarm because new packets likely have been acked, which
983 // may change the congestion window and/or pacing rate. Canceling the alarm
984 // causes CanWrite to recalculate the next send time.
985 if (send_alarm_->IsSet()) {
986 send_alarm_->Cancel();
987 }
988 if (supports_release_time_) {
989 // Update pace time into future because smoothed RTT is likely updated.
990 UpdateReleaseTimeIntoFuture();
991 }
QUICHE team76e1c622019-03-19 14:36:39 -0700992 SetLargestReceivedPacketWithAck(last_header_.packet_number);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500993 // If the incoming ack's packets set expresses missing packets: peer is still
994 // waiting for a packet lower than a packet that we are no longer planning to
995 // send.
996 // If the incoming ack's packets set expresses received packets: peer is still
997 // acking packets which we never care about.
998 // Send an ack to raise the high water mark.
fayange8b0cab2019-07-17 14:23:07 -0700999 bool send_stop_waiting = GetLeastUnacked() > start;
1000 if (GetQuicReloadableFlag(quic_simplify_stop_waiting) &&
1001 no_stop_waiting_frames_) {
1002 QUIC_RELOADABLE_FLAG_COUNT(quic_simplify_stop_waiting);
1003 send_stop_waiting = false;
1004 }
fayang03916692019-05-22 17:57:18 -07001005 PostProcessAfterAckFrame(send_stop_waiting,
fayang3eb82212019-04-16 12:05:46 -07001006 ack_result == PACKETS_NEWLY_ACKED);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001007 processing_ack_frame_ = false;
1008
1009 return connected_;
1010}
1011
1012bool QuicConnection::OnStopWaitingFrame(const QuicStopWaitingFrame& frame) {
1013 DCHECK(connected_);
1014
1015 // Since a stop waiting frame was received, this is not a connectivity probe.
1016 // A probe only contains a PING and full padding.
1017 UpdatePacketContent(NOT_PADDED_PING);
1018
1019 if (no_stop_waiting_frames_) {
1020 return true;
1021 }
1022 if (largest_seen_packet_with_stop_waiting_.IsInitialized() &&
1023 last_header_.packet_number <= largest_seen_packet_with_stop_waiting_) {
1024 QUIC_DLOG(INFO) << ENDPOINT
1025 << "Received an old stop waiting frame: ignoring";
1026 return true;
1027 }
1028
1029 const char* error = ValidateStopWaitingFrame(frame);
1030 if (error != nullptr) {
1031 CloseConnection(QUIC_INVALID_STOP_WAITING_DATA, error,
1032 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
1033 return false;
1034 }
1035
1036 if (debug_visitor_ != nullptr) {
1037 debug_visitor_->OnStopWaitingFrame(frame);
1038 }
1039
1040 largest_seen_packet_with_stop_waiting_ = last_header_.packet_number;
fayang5f464302019-06-20 12:57:33 -07001041 uber_received_packet_manager_.DontWaitForPacketsBefore(
1042 last_decrypted_packet_level_, frame.least_unacked);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001043 return connected_;
1044}
1045
1046bool QuicConnection::OnPaddingFrame(const QuicPaddingFrame& frame) {
1047 DCHECK(connected_);
1048 UpdatePacketContent(SECOND_FRAME_IS_PADDING);
1049
1050 if (debug_visitor_ != nullptr) {
1051 debug_visitor_->OnPaddingFrame(frame);
1052 }
1053 return true;
1054}
1055
1056bool QuicConnection::OnPingFrame(const QuicPingFrame& frame) {
1057 DCHECK(connected_);
1058 UpdatePacketContent(FIRST_FRAME_IS_PING);
1059
1060 if (debug_visitor_ != nullptr) {
1061 debug_visitor_->OnPingFrame(frame);
1062 }
1063 should_last_packet_instigate_acks_ = true;
1064 return true;
1065}
1066
QUICHE teama6ef0a62019-03-07 20:34:33 -05001067const char* QuicConnection::ValidateStopWaitingFrame(
1068 const QuicStopWaitingFrame& stop_waiting) {
QUICHE teamb23daa72019-03-21 08:37:48 -07001069 const QuicPacketNumber peer_least_packet_awaiting_ack =
fayang5f464302019-06-20 12:57:33 -07001070 uber_received_packet_manager_.peer_least_packet_awaiting_ack();
QUICHE teamb23daa72019-03-21 08:37:48 -07001071 if (peer_least_packet_awaiting_ack.IsInitialized() &&
1072 stop_waiting.least_unacked < peer_least_packet_awaiting_ack) {
1073 QUIC_DLOG(ERROR) << ENDPOINT << "Peer's sent low least_unacked: "
1074 << stop_waiting.least_unacked << " vs "
1075 << peer_least_packet_awaiting_ack;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001076 // We never process old ack frames, so this number should only increase.
1077 return "Least unacked too small.";
1078 }
1079
1080 if (stop_waiting.least_unacked > last_header_.packet_number) {
1081 QUIC_DLOG(ERROR) << ENDPOINT
1082 << "Peer sent least_unacked:" << stop_waiting.least_unacked
1083 << " greater than the enclosing packet number:"
1084 << last_header_.packet_number;
1085 return "Least unacked too large.";
1086 }
1087
1088 return nullptr;
1089}
1090
1091bool QuicConnection::OnRstStreamFrame(const QuicRstStreamFrame& frame) {
1092 DCHECK(connected_);
1093
1094 // Since a reset stream frame was received, this is not a connectivity probe.
1095 // A probe only contains a PING and full padding.
1096 UpdatePacketContent(NOT_PADDED_PING);
1097
1098 if (debug_visitor_ != nullptr) {
1099 debug_visitor_->OnRstStreamFrame(frame);
1100 }
1101 QUIC_DLOG(INFO) << ENDPOINT
1102 << "RST_STREAM_FRAME received for stream: " << frame.stream_id
1103 << " with error: "
1104 << QuicRstStreamErrorCodeToString(frame.error_code);
1105 visitor_->OnRstStream(frame);
1106 should_last_packet_instigate_acks_ = true;
1107 return connected_;
1108}
1109
QUICHE teama6ef0a62019-03-07 20:34:33 -05001110bool QuicConnection::OnStopSendingFrame(const QuicStopSendingFrame& frame) {
1111 DCHECK(connected_);
1112
1113 // Since a reset stream frame was received, this is not a connectivity probe.
1114 // A probe only contains a PING and full padding.
1115 UpdatePacketContent(NOT_PADDED_PING);
1116
1117 if (debug_visitor_ != nullptr) {
1118 debug_visitor_->OnStopSendingFrame(frame);
1119 }
1120
1121 QUIC_DLOG(INFO) << ENDPOINT << "STOP_SENDING frame received for stream: "
1122 << frame.stream_id
1123 << " with error: " << frame.application_error_code;
1124
1125 visitor_->OnStopSendingFrame(frame);
1126 return connected_;
1127}
1128
1129bool QuicConnection::OnPathChallengeFrame(const QuicPathChallengeFrame& frame) {
1130 // Save the path challenge's payload, for later use in generating the
1131 // response.
1132 received_path_challenge_payloads_.push_back(frame.data_buffer);
1133
1134 // For VERSION 99 we define a "Padded PATH CHALLENGE" to be the same thing
1135 // as a PADDED PING -- it will start a connectivity check and prevent
1136 // connection migration. Insofar as the connectivity check and connection
1137 // migration are concerned, logically the PATH CHALLENGE is the same as the
1138 // PING, so as a stopgap, tell the FSM that determines whether we have a
1139 // Padded PING or not that we received a PING.
1140 UpdatePacketContent(FIRST_FRAME_IS_PING);
1141 should_last_packet_instigate_acks_ = true;
1142 return true;
1143}
1144
1145bool QuicConnection::OnPathResponseFrame(const QuicPathResponseFrame& frame) {
1146 should_last_packet_instigate_acks_ = true;
1147 if (!transmitted_connectivity_probe_payload_ ||
1148 *transmitted_connectivity_probe_payload_ != frame.data_buffer) {
1149 // Is not for the probe we sent, ignore it.
1150 return true;
1151 }
1152 // Have received the matching PATH RESPONSE, saved payload no longer valid.
1153 transmitted_connectivity_probe_payload_ = nullptr;
1154 UpdatePacketContent(FIRST_FRAME_IS_PING);
1155 return true;
1156}
1157
1158bool QuicConnection::OnConnectionCloseFrame(
1159 const QuicConnectionCloseFrame& frame) {
1160 DCHECK(connected_);
1161
1162 // Since a connection close frame was received, this is not a connectivity
1163 // probe. A probe only contains a PING and full padding.
1164 UpdatePacketContent(NOT_PADDED_PING);
1165
1166 if (debug_visitor_ != nullptr) {
1167 debug_visitor_->OnConnectionCloseFrame(frame);
1168 }
1169 QUIC_DLOG(INFO) << ENDPOINT << "Received ConnectionClose for connection: "
fkastenholze9d71a82019-04-09 05:12:13 -07001170 << connection_id() << ", with error: "
1171 << QuicErrorCodeToString(frame.quic_error_code) << " ("
1172 << frame.error_details << ")";
1173 if (frame.close_type == GOOGLE_QUIC_CONNECTION_CLOSE &&
1174 frame.quic_error_code == QUIC_BAD_MULTIPATH_FLAG) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001175 QUIC_LOG_FIRST_N(ERROR, 10) << "Unexpected QUIC_BAD_MULTIPATH_FLAG error."
1176 << " last_received_header: " << last_header_
1177 << " encryption_level: " << encryption_level_;
1178 }
fkastenholze9d71a82019-04-09 05:12:13 -07001179 TearDownLocalConnectionState(frame.quic_error_code, frame.error_details,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001180 ConnectionCloseSource::FROM_PEER);
1181 return connected_;
1182}
1183
fkastenholz3c4eabf2019-04-22 07:49:59 -07001184bool QuicConnection::OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) {
1185 return visitor_->OnMaxStreamsFrame(frame);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001186}
1187
fkastenholz3c4eabf2019-04-22 07:49:59 -07001188bool QuicConnection::OnStreamsBlockedFrame(
1189 const QuicStreamsBlockedFrame& frame) {
1190 return visitor_->OnStreamsBlockedFrame(frame);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001191}
1192
1193bool QuicConnection::OnGoAwayFrame(const QuicGoAwayFrame& frame) {
1194 DCHECK(connected_);
1195
1196 // Since a go away frame was received, this is not a connectivity probe.
1197 // A probe only contains a PING and full padding.
1198 UpdatePacketContent(NOT_PADDED_PING);
1199
1200 if (debug_visitor_ != nullptr) {
1201 debug_visitor_->OnGoAwayFrame(frame);
1202 }
1203 QUIC_DLOG(INFO) << ENDPOINT << "GOAWAY_FRAME received with last good stream: "
1204 << frame.last_good_stream_id
1205 << " and error: " << QuicErrorCodeToString(frame.error_code)
1206 << " and reason: " << frame.reason_phrase;
1207
1208 visitor_->OnGoAway(frame);
1209 should_last_packet_instigate_acks_ = true;
1210 return connected_;
1211}
1212
1213bool QuicConnection::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
1214 DCHECK(connected_);
1215
1216 // Since a window update frame was received, this is not a connectivity probe.
1217 // A probe only contains a PING and full padding.
1218 UpdatePacketContent(NOT_PADDED_PING);
1219
1220 if (debug_visitor_ != nullptr) {
1221 debug_visitor_->OnWindowUpdateFrame(frame, time_of_last_received_packet_);
1222 }
1223 QUIC_DLOG(INFO) << ENDPOINT << "WINDOW_UPDATE_FRAME received for stream: "
1224 << frame.stream_id
1225 << " with byte offset: " << frame.byte_offset;
1226 visitor_->OnWindowUpdateFrame(frame);
1227 should_last_packet_instigate_acks_ = true;
1228 return connected_;
1229}
1230
1231bool QuicConnection::OnNewConnectionIdFrame(
dschinazi17d42422019-06-18 16:35:07 -07001232 const QuicNewConnectionIdFrame& /*frame*/) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001233 return true;
1234}
1235
1236bool QuicConnection::OnRetireConnectionIdFrame(
dschinazi17d42422019-06-18 16:35:07 -07001237 const QuicRetireConnectionIdFrame& /*frame*/) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001238 return true;
1239}
1240
dschinazi17d42422019-06-18 16:35:07 -07001241bool QuicConnection::OnNewTokenFrame(const QuicNewTokenFrame& /*frame*/) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001242 return true;
1243}
1244
1245bool QuicConnection::OnMessageFrame(const QuicMessageFrame& frame) {
1246 DCHECK(connected_);
1247
1248 // Since a message frame was received, this is not a connectivity probe.
1249 // A probe only contains a PING and full padding.
1250 UpdatePacketContent(NOT_PADDED_PING);
1251
1252 if (debug_visitor_ != nullptr) {
1253 debug_visitor_->OnMessageFrame(frame);
1254 }
1255 visitor_->OnMessageReceived(
1256 QuicStringPiece(frame.data, frame.message_length));
1257 should_last_packet_instigate_acks_ = true;
1258 return connected_;
1259}
1260
1261bool QuicConnection::OnBlockedFrame(const QuicBlockedFrame& frame) {
1262 DCHECK(connected_);
1263
1264 // Since a blocked frame was received, this is not a connectivity probe.
1265 // A probe only contains a PING and full padding.
1266 UpdatePacketContent(NOT_PADDED_PING);
1267
1268 if (debug_visitor_ != nullptr) {
1269 debug_visitor_->OnBlockedFrame(frame);
1270 }
1271 QUIC_DLOG(INFO) << ENDPOINT
1272 << "BLOCKED_FRAME received for stream: " << frame.stream_id;
1273 visitor_->OnBlockedFrame(frame);
1274 stats_.blocked_frames_received++;
1275 should_last_packet_instigate_acks_ = true;
1276 return connected_;
1277}
1278
1279void QuicConnection::OnPacketComplete() {
1280 // Don't do anything if this packet closed the connection.
1281 if (!connected_) {
1282 ClearLastFrames();
1283 return;
1284 }
1285
1286 if (IsCurrentPacketConnectivityProbing()) {
1287 ++stats_.num_connectivity_probing_received;
1288 }
1289
1290 QUIC_DVLOG(1) << ENDPOINT << "Got packet " << last_header_.packet_number
QUICHE team2252b702019-05-14 23:55:14 -04001291 << " for "
1292 << GetServerConnectionIdAsRecipient(last_header_, perspective_);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001293
1294 QUIC_DLOG_IF(INFO, current_packet_content_ == SECOND_FRAME_IS_PADDING)
1295 << ENDPOINT << "Received a padded PING packet. is_probing: "
1296 << IsCurrentPacketConnectivityProbing();
1297
1298 if (perspective_ == Perspective::IS_CLIENT) {
1299 QUIC_DVLOG(1) << ENDPOINT
1300 << "Received a speculative connectivity probing packet for "
QUICHE team2252b702019-05-14 23:55:14 -04001301 << GetServerConnectionIdAsRecipient(last_header_,
1302 perspective_)
QUICHE teama6ef0a62019-03-07 20:34:33 -05001303 << " from ip:port: " << last_packet_source_address_.ToString()
1304 << " to ip:port: "
1305 << last_packet_destination_address_.ToString();
1306 // TODO(zhongyi): change the method name.
1307 visitor_->OnConnectivityProbeReceived(last_packet_destination_address_,
1308 last_packet_source_address_);
1309 } else if (IsCurrentPacketConnectivityProbing()) {
1310 // This node is not a client (is a server) AND the received packet was
1311 // connectivity-probing, send an appropriate response.
1312 QUIC_DVLOG(1) << ENDPOINT << "Received a connectivity probing packet for "
QUICHE team2252b702019-05-14 23:55:14 -04001313 << GetServerConnectionIdAsRecipient(last_header_,
1314 perspective_)
QUICHE teama6ef0a62019-03-07 20:34:33 -05001315 << " from ip:port: " << last_packet_source_address_.ToString()
1316 << " to ip:port: "
1317 << last_packet_destination_address_.ToString();
1318 visitor_->OnConnectivityProbeReceived(last_packet_destination_address_,
1319 last_packet_source_address_);
1320 } else {
1321 // This node is not a client (is a server) AND the received packet was
1322 // NOT connectivity-probing. If the packet had PATH CHALLENGES, send
1323 // appropriate RESPONSE. Then deal with possible peer migration.
fkastenholz305e1732019-06-18 05:01:22 -07001324 if (VersionHasIetfQuicFrames(transport_version()) &&
QUICHE teama6ef0a62019-03-07 20:34:33 -05001325 !received_path_challenge_payloads_.empty()) {
1326 // If a PATH CHALLENGE was in a "Padded PING (or PATH CHALLENGE)"
1327 // then it is taken care of above. This handles the case where a PATH
1328 // CHALLENGE appeared someplace else (eg, the peer randomly added a PATH
1329 // CHALLENGE frame to some other packet.
1330 // There was at least one PATH CHALLENGE in the received packet,
1331 // Generate the required PATH RESPONSE.
1332 SendGenericPathProbePacket(nullptr, last_packet_source_address_,
1333 /* is_response= */ true);
1334 }
1335
QUICHE team1f3de242019-03-20 07:24:48 -07001336 if (last_header_.packet_number == GetLargestReceivedPacket()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001337 direct_peer_address_ = last_packet_source_address_;
1338 if (current_effective_peer_migration_type_ != NO_CHANGE) {
QUICHE team1f3de242019-03-20 07:24:48 -07001339 // TODO(fayang): When multiple packet number spaces is supported, only
1340 // start peer migration for the application data.
QUICHE teama6ef0a62019-03-07 20:34:33 -05001341 StartEffectivePeerMigration(current_effective_peer_migration_type_);
1342 }
1343 }
1344 }
1345
1346 current_effective_peer_migration_type_ = NO_CHANGE;
1347
fayang5f464302019-06-20 12:57:33 -07001348 // Some encryption levels share a packet number space, it is therefore
1349 // possible for us to want to ack some packets even though we do not yet
1350 // have the appropriate keys to encrypt the acks. In this scenario we
1351 // do not update the ACK timeout. This can happen for example with
1352 // IETF QUIC on the server when we receive 0-RTT packets and do not yet
1353 // have 1-RTT keys (0-RTT packets are acked at the 1-RTT level).
1354 // Note that this could cause slight performance degradations in the edge
1355 // case where one packet is received, then the encrypter is installed,
1356 // then a second packet is received; as that could cause the ACK for the
1357 // second packet to be delayed instead of immediate. This is currently
1358 // considered to be small enough of an edge case to not be optimized for.
1359 if (!SupportsMultiplePacketNumberSpaces() ||
1360 framer_.HasEncrypterOfEncryptionLevel(QuicUtils::GetEncryptionLevel(
1361 QuicUtils::GetPacketNumberSpace(last_decrypted_packet_level_)))) {
1362 uber_received_packet_manager_.MaybeUpdateAckTimeout(
1363 should_last_packet_instigate_acks_, last_decrypted_packet_level_,
1364 last_header_.packet_number, time_of_last_received_packet_,
1365 clock_->ApproximateNow(), sent_packet_manager_.GetRttStats(),
fkastenholz59c653b2019-07-15 09:55:53 -07001366 sent_packet_manager_.local_max_ack_delay());
fayang5f464302019-06-20 12:57:33 -07001367 } else {
1368 QUIC_DLOG(INFO) << ENDPOINT << "Not updating ACK timeout for "
1369 << QuicUtils::EncryptionLevelToString(
1370 last_decrypted_packet_level_)
1371 << " as we do not have the corresponding encrypter";
QUICHE teama6ef0a62019-03-07 20:34:33 -05001372 }
1373
1374 ClearLastFrames();
1375 CloseIfTooManyOutstandingSentPackets();
1376}
1377
1378bool QuicConnection::IsValidStatelessResetToken(QuicUint128 token) const {
1379 return stateless_reset_token_received_ &&
1380 token == received_stateless_reset_token_;
1381}
1382
1383void QuicConnection::OnAuthenticatedIetfStatelessResetPacket(
dschinazi17d42422019-06-18 16:35:07 -07001384 const QuicIetfStatelessResetPacket& /*packet*/) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001385 // TODO(fayang): Add OnAuthenticatedIetfStatelessResetPacket to
1386 // debug_visitor_.
vasilvvc48c8712019-03-11 13:38:16 -07001387 const std::string error_details = "Received stateless reset.";
QUICHE teama6ef0a62019-03-07 20:34:33 -05001388 QUIC_CODE_COUNT(quic_tear_down_local_connection_on_stateless_reset);
1389 TearDownLocalConnectionState(QUIC_PUBLIC_RESET, error_details,
1390 ConnectionCloseSource::FROM_PEER);
1391}
1392
QUICHE teama6ef0a62019-03-07 20:34:33 -05001393void QuicConnection::ClearLastFrames() {
1394 should_last_packet_instigate_acks_ = false;
1395}
1396
1397void QuicConnection::CloseIfTooManyOutstandingSentPackets() {
1398 // This occurs if we don't discard old packets we've seen fast enough. It's
1399 // possible largest observed is less than leaset unacked.
1400 if (sent_packet_manager_.GetLargestObserved().IsInitialized() &&
1401 sent_packet_manager_.GetLargestObserved() >
1402 sent_packet_manager_.GetLeastUnacked() + max_tracked_packets_) {
1403 CloseConnection(
1404 QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS,
fayang75d23962019-06-03 08:35:49 -07001405 QuicStrCat(
1406 "More than ", max_tracked_packets_, " outstanding, least_unacked: ",
1407 sent_packet_manager_.GetLeastUnacked().ToUint64(),
1408 ", packets_processed: ", stats_.packets_processed,
1409 ", last_decrypted_packet_level: ",
1410 QuicUtils::EncryptionLevelToString(last_decrypted_packet_level_)),
QUICHE teama6ef0a62019-03-07 20:34:33 -05001411 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
1412 }
1413}
1414
1415const QuicFrame QuicConnection::GetUpdatedAckFrame() {
fayang5f464302019-06-20 12:57:33 -07001416 return uber_received_packet_manager_.GetUpdatedAckFrame(
1417 QuicUtils::GetPacketNumberSpace(encryption_level_),
1418 clock_->ApproximateNow());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001419}
1420
1421void QuicConnection::PopulateStopWaitingFrame(
1422 QuicStopWaitingFrame* stop_waiting) {
1423 stop_waiting->least_unacked = GetLeastUnacked();
1424}
1425
1426QuicPacketNumber QuicConnection::GetLeastUnacked() const {
1427 return sent_packet_manager_.GetLeastUnacked();
1428}
1429
1430bool QuicConnection::HandleWriteBlocked() {
1431 if (!writer_->IsWriteBlocked()) {
1432 return false;
1433 }
1434
1435 visitor_->OnWriteBlocked();
1436 return true;
1437}
1438
1439void QuicConnection::MaybeSendInResponseToPacket() {
1440 if (!connected_) {
1441 return;
1442 }
1443
1444 // If the writer is blocked, don't attempt to send packets now or in the send
1445 // alarm. When the writer unblocks, OnCanWrite() will be called for this
1446 // connection to send.
1447 if (HandleWriteBlocked()) {
1448 return;
1449 }
1450
1451 // Now that we have received an ack, we might be able to send packets which
1452 // are queued locally, or drain streams which are blocked.
1453 if (defer_send_in_response_to_packets_) {
1454 send_alarm_->Update(clock_->ApproximateNow(), QuicTime::Delta::Zero());
1455 } else {
1456 WriteAndBundleAcksIfNotBlocked();
1457 }
1458}
1459
1460void QuicConnection::SendVersionNegotiationPacket(bool ietf_quic) {
1461 pending_version_negotiation_packet_ = true;
1462 send_ietf_version_negotiation_packet_ = ietf_quic;
1463
1464 if (HandleWriteBlocked()) {
1465 return;
1466 }
1467
1468 QUIC_DLOG(INFO) << ENDPOINT << "Sending version negotiation packet: {"
1469 << ParsedQuicVersionVectorToString(
1470 framer_.supported_versions())
dschinazi965ce092019-05-23 06:29:01 -07001471 << "}, " << (ietf_quic ? "" : "!") << "ietf_quic";
QUICHE teama6ef0a62019-03-07 20:34:33 -05001472 std::unique_ptr<QuicEncryptedPacket> version_packet(
1473 packet_generator_.SerializeVersionNegotiationPacket(
1474 ietf_quic, framer_.supported_versions()));
dschinazi965ce092019-05-23 06:29:01 -07001475 QUIC_DVLOG(2) << ENDPOINT << "Sending version negotiation packet: {"
1476 << ParsedQuicVersionVectorToString(framer_.supported_versions())
1477 << "}, " << (ietf_quic ? "" : "!") << "ietf_quic:" << std::endl
1478 << QuicTextUtils::HexDump(QuicStringPiece(
1479 version_packet->data(), version_packet->length()));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001480 WriteResult result = writer_->WritePacket(
1481 version_packet->data(), version_packet->length(), self_address().host(),
1482 peer_address(), per_packet_options_);
1483
1484 if (IsWriteError(result.status)) {
1485 OnWriteError(result.error_code);
1486 return;
1487 }
1488 if (IsWriteBlockedStatus(result.status)) {
1489 visitor_->OnWriteBlocked();
1490 if (result.status == WRITE_STATUS_BLOCKED_DATA_BUFFERED) {
1491 pending_version_negotiation_packet_ = false;
1492 }
1493 return;
1494 }
1495
1496 pending_version_negotiation_packet_ = false;
1497}
1498
1499size_t QuicConnection::SendCryptoData(EncryptionLevel level,
1500 size_t write_length,
1501 QuicStreamOffset offset) {
1502 if (write_length == 0) {
1503 QUIC_BUG << "Attempt to send empty crypto frame";
1504 return 0;
1505 }
1506
fayanga4b37b22019-06-18 13:37:47 -07001507 ScopedPacketFlusher flusher(this);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001508 return packet_generator_.ConsumeCryptoData(level, write_length, offset);
1509}
1510
1511QuicConsumedData QuicConnection::SendStreamData(QuicStreamId id,
1512 size_t write_length,
1513 QuicStreamOffset offset,
1514 StreamSendingState state) {
1515 if (state == NO_FIN && write_length == 0) {
1516 QUIC_BUG << "Attempt to send empty stream frame";
1517 return QuicConsumedData(0, false);
1518 }
1519
1520 // Opportunistically bundle an ack with every outgoing packet.
1521 // Particularly, we want to bundle with handshake packets since we don't know
1522 // which decrypter will be used on an ack packet following a handshake
1523 // packet (a handshake packet from client to server could result in a REJ or a
1524 // SHLO from the server, leading to two different decrypters at the server.)
fayanga4b37b22019-06-18 13:37:47 -07001525 ScopedPacketFlusher flusher(this);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001526 return packet_generator_.ConsumeData(id, write_length, offset, state);
1527}
1528
1529bool QuicConnection::SendControlFrame(const QuicFrame& frame) {
fayanga4b37b22019-06-18 13:37:47 -07001530 ScopedPacketFlusher flusher(this);
fayang3203f252019-05-03 06:00:03 -07001531 const bool consumed =
1532 packet_generator_.ConsumeRetransmittableControlFrame(frame);
fayang914fbe12019-07-11 06:23:55 -07001533 if (!consumed) {
fayang3203f252019-05-03 06:00:03 -07001534 QUIC_DVLOG(1) << ENDPOINT << "Failed to send control frame: " << frame;
1535 return false;
1536 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001537 if (frame.type == PING_FRAME) {
1538 // Flush PING frame immediately.
1539 packet_generator_.FlushAllQueuedFrames();
1540 if (debug_visitor_ != nullptr) {
1541 debug_visitor_->OnPingSent();
1542 }
1543 }
1544 if (frame.type == BLOCKED_FRAME) {
1545 stats_.blocked_frames_sent++;
1546 }
1547 return true;
1548}
1549
1550void QuicConnection::OnStreamReset(QuicStreamId id,
1551 QuicRstStreamErrorCode error) {
1552 if (error == QUIC_STREAM_NO_ERROR) {
1553 // All data for streams which are reset with QUIC_STREAM_NO_ERROR must
1554 // be received by the peer.
1555 return;
1556 }
1557 // Flush stream frames of reset stream.
1558 if (packet_generator_.HasPendingStreamFramesOfStream(id)) {
fayanga4b37b22019-06-18 13:37:47 -07001559 ScopedPacketFlusher flusher(this);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001560 packet_generator_.FlushAllQueuedFrames();
1561 }
1562
1563 sent_packet_manager_.CancelRetransmissionsForStream(id);
1564 // Remove all queued packets which only contain data for the reset stream.
1565 // TODO(fayang): consider removing this because it should be rarely executed.
1566 auto packet_iterator = queued_packets_.begin();
1567 while (packet_iterator != queued_packets_.end()) {
1568 QuicFrames* retransmittable_frames =
1569 &packet_iterator->retransmittable_frames;
1570 if (retransmittable_frames->empty()) {
1571 ++packet_iterator;
1572 continue;
1573 }
1574 // NOTE THAT RemoveFramesForStream removes only STREAM frames
1575 // for the specified stream.
1576 RemoveFramesForStream(retransmittable_frames, id);
1577 if (!retransmittable_frames->empty()) {
1578 ++packet_iterator;
1579 continue;
1580 }
1581 delete[] packet_iterator->encrypted_buffer;
1582 ClearSerializedPacket(&(*packet_iterator));
1583 packet_iterator = queued_packets_.erase(packet_iterator);
1584 }
1585 // TODO(ianswett): Consider checking for 3 RTOs when the last stream is
1586 // cancelled as well.
1587}
1588
1589const QuicConnectionStats& QuicConnection::GetStats() {
1590 const RttStats* rtt_stats = sent_packet_manager_.GetRttStats();
1591
1592 // Update rtt and estimated bandwidth.
1593 QuicTime::Delta min_rtt = rtt_stats->min_rtt();
1594 if (min_rtt.IsZero()) {
1595 // If min RTT has not been set, use initial RTT instead.
1596 min_rtt = rtt_stats->initial_rtt();
1597 }
1598 stats_.min_rtt_us = min_rtt.ToMicroseconds();
1599
1600 QuicTime::Delta srtt = rtt_stats->SmoothedOrInitialRtt();
1601 stats_.srtt_us = srtt.ToMicroseconds();
1602
1603 stats_.estimated_bandwidth = sent_packet_manager_.BandwidthEstimate();
1604 stats_.max_packet_size = packet_generator_.GetCurrentMaxPacketLength();
1605 stats_.max_received_packet_size = largest_received_packet_size_;
1606 return stats_;
1607}
1608
1609void QuicConnection::OnCoalescedPacket(const QuicEncryptedPacket& packet) {
1610 QueueCoalescedPacket(packet);
1611}
1612
1613void QuicConnection::ProcessUdpPacket(const QuicSocketAddress& self_address,
1614 const QuicSocketAddress& peer_address,
1615 const QuicReceivedPacket& packet) {
1616 if (!connected_) {
1617 return;
1618 }
dschinazid9467b52019-04-03 16:47:08 -07001619 QUIC_DVLOG(2) << ENDPOINT << "Received encrypted " << packet.length()
1620 << " bytes:" << std::endl
1621 << QuicTextUtils::HexDump(
1622 QuicStringPiece(packet.data(), packet.length()));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001623 QUIC_BUG_IF(current_packet_data_ != nullptr)
1624 << "ProcessUdpPacket must not be called while processing a packet.";
1625 if (debug_visitor_ != nullptr) {
1626 debug_visitor_->OnPacketReceived(self_address, peer_address, packet);
1627 }
1628 last_size_ = packet.length();
1629 current_packet_data_ = packet.data();
1630
1631 last_packet_destination_address_ = self_address;
1632 last_packet_source_address_ = peer_address;
1633 if (!self_address_.IsInitialized()) {
1634 self_address_ = last_packet_destination_address_;
1635 }
1636
1637 if (!direct_peer_address_.IsInitialized()) {
1638 direct_peer_address_ = last_packet_source_address_;
1639 }
1640
1641 if (!effective_peer_address_.IsInitialized()) {
1642 const QuicSocketAddress effective_peer_addr =
1643 GetEffectivePeerAddressFromCurrentPacket();
1644
1645 // effective_peer_address_ must be initialized at the beginning of the
1646 // first packet processed(here). If effective_peer_addr is uninitialized,
1647 // just set effective_peer_address_ to the direct peer address.
1648 effective_peer_address_ = effective_peer_addr.IsInitialized()
1649 ? effective_peer_addr
1650 : direct_peer_address_;
1651 }
1652
1653 stats_.bytes_received += packet.length();
1654 ++stats_.packets_received;
1655
1656 // Ensure the time coming from the packet reader is within 2 minutes of now.
1657 if (std::abs((packet.receipt_time() - clock_->ApproximateNow()).ToSeconds()) >
1658 2 * 60) {
1659 QUIC_BUG << "Packet receipt time:"
1660 << packet.receipt_time().ToDebuggingValue()
1661 << " too far from current time:"
1662 << clock_->ApproximateNow().ToDebuggingValue();
1663 }
1664 time_of_last_received_packet_ = packet.receipt_time();
1665 QUIC_DVLOG(1) << ENDPOINT << "time of last received packet: "
1666 << time_of_last_received_packet_.ToDebuggingValue();
1667
fayanga4b37b22019-06-18 13:37:47 -07001668 ScopedPacketFlusher flusher(this);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001669 if (!framer_.ProcessPacket(packet)) {
1670 // If we are unable to decrypt this packet, it might be
1671 // because the CHLO or SHLO packet was lost.
1672 if (framer_.error() == QUIC_DECRYPTION_FAILURE) {
dschinazi6ece5002019-05-22 06:35:49 -07001673 ++stats_.undecryptable_packets_received;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001674 if (encryption_level_ != ENCRYPTION_FORWARD_SECURE &&
1675 undecryptable_packets_.size() < max_undecryptable_packets_) {
1676 QueueUndecryptablePacket(packet);
1677 } else if (debug_visitor_ != nullptr) {
1678 debug_visitor_->OnUndecryptablePacket();
1679 }
1680 }
1681 QUIC_DVLOG(1) << ENDPOINT
1682 << "Unable to process packet. Last packet processed: "
1683 << last_header_.packet_number;
1684 current_packet_data_ = nullptr;
1685 is_current_packet_connectivity_probing_ = false;
1686
1687 MaybeProcessCoalescedPackets();
1688 return;
1689 }
1690
1691 ++stats_.packets_processed;
1692
1693 QUIC_DLOG_IF(INFO, active_effective_peer_migration_type_ != NO_CHANGE)
1694 << "sent_packet_manager_.GetLargestObserved() = "
1695 << sent_packet_manager_.GetLargestObserved()
1696 << ", highest_packet_sent_before_effective_peer_migration_ = "
1697 << highest_packet_sent_before_effective_peer_migration_;
1698 if (active_effective_peer_migration_type_ != NO_CHANGE &&
1699 sent_packet_manager_.GetLargestObserved().IsInitialized() &&
1700 (!highest_packet_sent_before_effective_peer_migration_.IsInitialized() ||
1701 sent_packet_manager_.GetLargestObserved() >
1702 highest_packet_sent_before_effective_peer_migration_)) {
1703 if (perspective_ == Perspective::IS_SERVER) {
1704 OnEffectivePeerMigrationValidated();
1705 }
1706 }
1707
1708 MaybeProcessCoalescedPackets();
1709 MaybeProcessUndecryptablePackets();
1710 MaybeSendInResponseToPacket();
1711 SetPingAlarm();
1712 current_packet_data_ = nullptr;
1713 is_current_packet_connectivity_probing_ = false;
1714}
1715
1716void QuicConnection::OnBlockedWriterCanWrite() {
1717 writer_->SetWritable();
1718 OnCanWrite();
1719}
1720
1721void QuicConnection::OnCanWrite() {
fayang0f0c4e62019-07-16 08:55:54 -07001722 if (!connected_) {
fayang40ec3ac2019-06-05 09:07:54 -07001723 return;
1724 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001725 DCHECK(!writer_->IsWriteBlocked());
1726
1727 // Add a flusher to ensure the connection is marked app-limited.
fayanga4b37b22019-06-18 13:37:47 -07001728 ScopedPacketFlusher flusher(this);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001729
1730 WriteQueuedPackets();
fayangf477f732019-06-20 07:03:06 -07001731 const QuicTime ack_timeout =
fayang5f464302019-06-20 12:57:33 -07001732 uber_received_packet_manager_.GetEarliestAckTimeout();
fayangf477f732019-06-20 07:03:06 -07001733 if (ack_timeout.IsInitialized() && ack_timeout <= clock_->ApproximateNow()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001734 // Send an ACK now because either 1) we were write blocked when we last
fayangf477f732019-06-20 07:03:06 -07001735 // tried to send an ACK, or 2) both ack alarm and send alarm were set to
1736 // go off together.
1737 if (SupportsMultiplePacketNumberSpaces()) {
1738 SendAllPendingAcks();
1739 } else {
1740 SendAck();
1741 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001742 }
1743 if (!session_decides_what_to_write()) {
1744 WritePendingRetransmissions();
1745 }
1746
1747 WriteNewData();
1748}
1749
1750void QuicConnection::WriteNewData() {
1751 // Sending queued packets may have caused the socket to become write blocked,
1752 // or the congestion manager to prohibit sending. If we've sent everything
1753 // we had queued and we're still not blocked, let the visitor know it can
1754 // write more.
1755 if (!CanWrite(HAS_RETRANSMITTABLE_DATA)) {
1756 return;
1757 }
1758
1759 {
fayanga4b37b22019-06-18 13:37:47 -07001760 ScopedPacketFlusher flusher(this);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001761 visitor_->OnCanWrite();
1762 }
1763
1764 // After the visitor writes, it may have caused the socket to become write
1765 // blocked or the congestion manager to prohibit sending, so check again.
1766 if (visitor_->WillingAndAbleToWrite() && !send_alarm_->IsSet() &&
1767 CanWrite(HAS_RETRANSMITTABLE_DATA)) {
1768 // We're not write blocked, but some stream didn't write out all of its
1769 // bytes. Register for 'immediate' resumption so we'll keep writing after
1770 // other connections and events have had a chance to use the thread.
1771 send_alarm_->Set(clock_->ApproximateNow());
1772 }
1773}
1774
1775void QuicConnection::WriteIfNotBlocked() {
1776 if (!HandleWriteBlocked()) {
1777 OnCanWrite();
1778 }
1779}
1780
1781void QuicConnection::WriteAndBundleAcksIfNotBlocked() {
1782 if (!HandleWriteBlocked()) {
fayanga4b37b22019-06-18 13:37:47 -07001783 ScopedPacketFlusher flusher(this);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001784 WriteIfNotBlocked();
1785 }
1786}
1787
1788bool QuicConnection::ProcessValidatedPacket(const QuicPacketHeader& header) {
1789 if (perspective_ == Perspective::IS_SERVER && self_address_.IsInitialized() &&
1790 last_packet_destination_address_.IsInitialized() &&
1791 self_address_ != last_packet_destination_address_) {
1792 // Allow change between pure IPv4 and equivalent mapped IPv4 address.
1793 if (self_address_.port() != last_packet_destination_address_.port() ||
1794 self_address_.host().Normalized() !=
1795 last_packet_destination_address_.host().Normalized()) {
1796 if (!visitor_->AllowSelfAddressChange()) {
1797 CloseConnection(
1798 QUIC_ERROR_MIGRATING_ADDRESS,
1799 "Self address migration is not supported at the server.",
1800 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
1801 return false;
1802 }
1803 }
1804 self_address_ = last_packet_destination_address_;
1805 }
1806
QUICHE teamc65d1d12019-03-19 20:58:04 -07001807 if (PacketCanReplaceConnectionId(header, perspective_) &&
dschinazi7b9278c2019-05-20 07:36:21 -07001808 server_connection_id_ != header.source_connection_id) {
1809 QUIC_DLOG(INFO) << ENDPOINT << "Replacing connection ID "
1810 << server_connection_id_ << " with "
1811 << header.source_connection_id;
1812 server_connection_id_ = header.source_connection_id;
1813 packet_generator_.SetServerConnectionId(server_connection_id_);
QUICHE teamc65d1d12019-03-19 20:58:04 -07001814 }
1815
QUICHE teamd791e2c2019-03-15 10:28:21 -07001816 if (!ValidateReceivedPacketNumber(header.packet_number)) {
1817 return false;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001818 }
1819
fayang8aba1ff2019-06-21 12:00:54 -07001820 if (!version_negotiated_) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001821 if (perspective_ == Perspective::IS_CLIENT) {
1822 DCHECK(!header.version_flag || header.form != GOOGLE_QUIC_PACKET);
fayangd4291e42019-05-30 10:31:21 -07001823 if (!VersionHasIetfInvariantHeader(framer_.transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001824 // If the client gets a packet without the version flag from the server
1825 // it should stop sending version since the version negotiation is done.
1826 // IETF QUIC stops sending version once encryption level switches to
1827 // forward secure.
1828 packet_generator_.StopSendingVersion();
1829 }
fayang8aba1ff2019-06-21 12:00:54 -07001830 version_negotiated_ = true;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001831 visitor_->OnSuccessfulVersionNegotiation(version());
1832 if (debug_visitor_ != nullptr) {
1833 debug_visitor_->OnSuccessfulVersionNegotiation(version());
1834 }
1835 }
1836 }
1837
1838 if (last_size_ > largest_received_packet_size_) {
1839 largest_received_packet_size_ = last_size_;
1840 }
1841
1842 if (perspective_ == Perspective::IS_SERVER &&
QUICHE team6987b4a2019-03-15 16:23:04 -07001843 encryption_level_ == ENCRYPTION_INITIAL &&
QUICHE teama6ef0a62019-03-07 20:34:33 -05001844 last_size_ > packet_generator_.GetCurrentMaxPacketLength()) {
1845 SetMaxPacketLength(last_size_);
1846 }
1847 return true;
1848}
1849
QUICHE teamd791e2c2019-03-15 10:28:21 -07001850bool QuicConnection::ValidateReceivedPacketNumber(
1851 QuicPacketNumber packet_number) {
fayang08878bd2019-06-20 09:21:43 -07001852 // If this packet has already been seen, or the sender has told us that it
1853 // will not be retransmitted, then stop processing the packet.
fayang5f464302019-06-20 12:57:33 -07001854 if (!uber_received_packet_manager_.IsAwaitingPacket(
1855 last_decrypted_packet_level_, packet_number)) {
1856 QUIC_DLOG(INFO) << ENDPOINT << "Packet " << packet_number
1857 << " no longer being waited for at level "
1858 << static_cast<int>(last_decrypted_packet_level_)
1859 << ". Discarding.";
fayang08878bd2019-06-20 09:21:43 -07001860 if (debug_visitor_ != nullptr) {
1861 debug_visitor_->OnDuplicatePacket(packet_number);
1862 }
1863 return false;
QUICHE team692750b2019-03-17 17:57:46 -07001864 }
1865
fayang6dba4902019-06-17 10:04:23 -07001866 return true;
QUICHE teamd791e2c2019-03-15 10:28:21 -07001867}
1868
QUICHE teama6ef0a62019-03-07 20:34:33 -05001869void QuicConnection::WriteQueuedPackets() {
1870 DCHECK(!writer_->IsWriteBlocked());
1871
1872 if (pending_version_negotiation_packet_) {
1873 SendVersionNegotiationPacket(send_ietf_version_negotiation_packet_);
1874 }
1875
1876 QUIC_CLIENT_HISTOGRAM_COUNTS("QuicSession.NumQueuedPacketsBeforeWrite",
1877 queued_packets_.size(), 1, 1000, 50, "");
1878 while (!queued_packets_.empty()) {
1879 // WritePacket() can potentially clear all queued packets, so we need to
1880 // save the first queued packet to a local variable before calling it.
1881 SerializedPacket packet(std::move(queued_packets_.front()));
1882 queued_packets_.pop_front();
1883
1884 const bool write_result = WritePacket(&packet);
1885
1886 if (connected_ && !write_result) {
1887 // Write failed but connection is open, re-insert |packet| into the
1888 // front of the queue, it will be retried later.
1889 queued_packets_.emplace_front(std::move(packet));
1890 break;
1891 }
1892
1893 delete[] packet.encrypted_buffer;
1894 ClearSerializedPacket(&packet);
1895 if (!connected_) {
1896 DCHECK(queued_packets_.empty()) << "Queued packets should have been "
1897 "cleared while closing connection";
1898 break;
1899 }
1900
1901 // Continue to send the next packet in queue.
1902 }
1903}
1904
1905void QuicConnection::WritePendingRetransmissions() {
1906 DCHECK(!session_decides_what_to_write());
1907 // Keep writing as long as there's a pending retransmission which can be
1908 // written.
1909 while (sent_packet_manager_.HasPendingRetransmissions() &&
1910 CanWrite(HAS_RETRANSMITTABLE_DATA)) {
1911 const QuicPendingRetransmission pending =
1912 sent_packet_manager_.NextPendingRetransmission();
1913
1914 // Re-packetize the frames with a new packet number for retransmission.
1915 // Retransmitted packets use the same packet number length as the
1916 // original.
1917 // Flush the packet generator before making a new packet.
1918 // TODO(ianswett): Implement ReserializeAllFrames as a separate path that
1919 // does not require the creator to be flushed.
1920 // TODO(fayang): FlushAllQueuedFrames should only be called once, and should
1921 // be moved outside of the loop. Also, CanWrite is not checked after the
1922 // generator is flushed.
1923 {
fayanga4b37b22019-06-18 13:37:47 -07001924 ScopedPacketFlusher flusher(this);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001925 packet_generator_.FlushAllQueuedFrames();
1926 }
fayang914fbe12019-07-11 06:23:55 -07001927 DCHECK(!packet_generator_.HasPendingFrames());
dschinazi66dea072019-04-09 11:41:06 -07001928 char buffer[kMaxOutgoingPacketSize];
1929 packet_generator_.ReserializeAllFrames(pending, buffer,
1930 kMaxOutgoingPacketSize);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001931 }
1932}
1933
1934void QuicConnection::SendProbingRetransmissions() {
1935 while (sent_packet_manager_.GetSendAlgorithm()->ShouldSendProbingPacket() &&
1936 CanWrite(HAS_RETRANSMITTABLE_DATA)) {
QUICHE teamb8343252019-04-29 13:58:01 -07001937 if (!visitor_->SendProbingData()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001938 QUIC_DVLOG(1)
1939 << "Cannot send probing retransmissions: nothing to retransmit.";
1940 break;
1941 }
1942
1943 if (!session_decides_what_to_write()) {
1944 DCHECK(sent_packet_manager_.HasPendingRetransmissions());
1945 WritePendingRetransmissions();
1946 }
1947 }
1948}
1949
1950void QuicConnection::RetransmitUnackedPackets(
1951 TransmissionType retransmission_type) {
1952 sent_packet_manager_.RetransmitUnackedPackets(retransmission_type);
1953
1954 WriteIfNotBlocked();
1955}
1956
1957void QuicConnection::NeuterUnencryptedPackets() {
1958 sent_packet_manager_.NeuterUnencryptedPackets();
1959 // This may have changed the retransmission timer, so re-arm it.
1960 SetRetransmissionAlarm();
1961}
1962
1963bool QuicConnection::ShouldGeneratePacket(
1964 HasRetransmittableData retransmittable,
1965 IsHandshake handshake) {
1966 // We should serialize handshake packets immediately to ensure that they
1967 // end up sent at the right encryption level.
1968 if (handshake == IS_HANDSHAKE) {
1969 return true;
1970 }
1971
1972 return CanWrite(retransmittable);
1973}
1974
1975const QuicFrames QuicConnection::MaybeBundleAckOpportunistically() {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001976 QuicFrames frames;
fayang5f464302019-06-20 12:57:33 -07001977 const bool has_pending_ack =
1978 uber_received_packet_manager_
1979 .GetAckTimeout(QuicUtils::GetPacketNumberSpace(encryption_level_))
1980 .IsInitialized();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001981 if (!has_pending_ack && stop_waiting_count_ <= 1) {
1982 // No need to send an ACK.
1983 return frames;
1984 }
1985 ResetAckStates();
1986
1987 QUIC_DVLOG(1) << ENDPOINT << "Bundle an ACK opportunistically";
dschinazi8cf087e2019-05-23 05:27:48 -07001988 QuicFrame updated_ack_frame = GetUpdatedAckFrame();
1989 QUIC_BUG_IF(updated_ack_frame.ack_frame->packets.Empty())
1990 << ENDPOINT << "Attempted to opportunistically bundle an empty "
1991 << QuicUtils::EncryptionLevelToString(encryption_level_) << " ACK, "
1992 << (has_pending_ack ? "" : "!") << "has_pending_ack, stop_waiting_count_ "
1993 << stop_waiting_count_;
1994 frames.push_back(updated_ack_frame);
1995
QUICHE teama6ef0a62019-03-07 20:34:33 -05001996 if (!no_stop_waiting_frames_) {
1997 QuicStopWaitingFrame stop_waiting;
1998 PopulateStopWaitingFrame(&stop_waiting);
1999 frames.push_back(QuicFrame(stop_waiting));
2000 }
2001 return frames;
2002}
2003
2004bool QuicConnection::CanWrite(HasRetransmittableData retransmittable) {
2005 if (!connected_) {
2006 return false;
2007 }
2008
2009 if (session_decides_what_to_write() &&
2010 sent_packet_manager_.pending_timer_transmission_count() > 0) {
2011 // Force sending the retransmissions for HANDSHAKE, TLP, RTO, PROBING cases.
2012 return true;
2013 }
2014
2015 if (HandleWriteBlocked()) {
2016 return false;
2017 }
2018
2019 // Allow acks to be sent immediately.
2020 if (retransmittable == NO_RETRANSMITTABLE_DATA) {
2021 return true;
2022 }
2023 // If the send alarm is set, wait for it to fire.
2024 if (send_alarm_->IsSet()) {
2025 return false;
2026 }
2027
2028 QuicTime now = clock_->Now();
2029 QuicTime::Delta delay = sent_packet_manager_.TimeUntilSend(now);
2030 if (delay.IsInfinite()) {
2031 send_alarm_->Cancel();
2032 return false;
2033 }
2034
2035 // Scheduler requires a delay.
2036 if (!delay.IsZero()) {
2037 if (delay <= release_time_into_future_) {
2038 // Required delay is within pace time into future, send now.
2039 return true;
2040 }
2041 // Cannot send packet now because delay is too far in the future.
2042 send_alarm_->Update(now + delay, QuicTime::Delta::FromMilliseconds(1));
2043 QUIC_DVLOG(1) << ENDPOINT << "Delaying sending " << delay.ToMilliseconds()
2044 << "ms";
2045 return false;
2046 }
2047 return true;
2048}
2049
2050bool QuicConnection::WritePacket(SerializedPacket* packet) {
2051 if (ShouldDiscardPacket(*packet)) {
2052 ++stats_.packets_discarded;
2053 return true;
2054 }
2055 if (sent_packet_manager_.GetLargestSentPacket().IsInitialized() &&
2056 packet->packet_number < sent_packet_manager_.GetLargestSentPacket()) {
2057 QUIC_BUG << "Attempt to write packet:" << packet->packet_number
2058 << " after:" << sent_packet_manager_.GetLargestSentPacket();
2059 QUIC_CLIENT_HISTOGRAM_COUNTS("QuicSession.NumQueuedPacketsAtOutOfOrder",
2060 queued_packets_.size(), 1, 1000, 50, "");
2061 CloseConnection(QUIC_INTERNAL_ERROR, "Packet written out of order.",
2062 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
2063 return true;
2064 }
2065 // Termination packets are encrypted and saved, so don't exit early.
2066 const bool is_termination_packet = IsTerminationPacket(*packet);
2067 if (HandleWriteBlocked() && !is_termination_packet) {
2068 return false;
2069 }
2070
2071 QuicPacketNumber packet_number = packet->packet_number;
2072
2073 QuicPacketLength encrypted_length = packet->encrypted_length;
2074 // Termination packets are eventually owned by TimeWaitListManager.
2075 // Others are deleted at the end of this call.
2076 if (is_termination_packet) {
2077 if (termination_packets_ == nullptr) {
2078 termination_packets_.reset(
2079 new std::vector<std::unique_ptr<QuicEncryptedPacket>>);
2080 }
2081 // Copy the buffer so it's owned in the future.
2082 char* buffer_copy = CopyBuffer(*packet);
2083 termination_packets_->emplace_back(
2084 new QuicEncryptedPacket(buffer_copy, encrypted_length, true));
2085 // This assures we won't try to write *forced* packets when blocked.
2086 // Return true to stop processing.
2087 if (HandleWriteBlocked()) {
2088 return true;
2089 }
2090 }
2091
dschinazi66dea072019-04-09 11:41:06 -07002092 DCHECK_LE(encrypted_length, kMaxOutgoingPacketSize);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002093 DCHECK_LE(encrypted_length, packet_generator_.GetCurrentMaxPacketLength());
2094 QUIC_DVLOG(1) << ENDPOINT << "Sending packet " << packet_number << " : "
2095 << (IsRetransmittable(*packet) == HAS_RETRANSMITTABLE_DATA
2096 ? "data bearing "
2097 : " ack only ")
2098 << ", encryption level: "
2099 << QuicUtils::EncryptionLevelToString(packet->encryption_level)
2100 << ", encrypted length:" << encrypted_length;
2101 QUIC_DVLOG(2) << ENDPOINT << "packet(" << packet_number << "): " << std::endl
2102 << QuicTextUtils::HexDump(QuicStringPiece(
2103 packet->encrypted_buffer, encrypted_length));
2104
2105 // Measure the RTT from before the write begins to avoid underestimating the
2106 // min_rtt_, especially in cases where the thread blocks or gets swapped out
2107 // during the WritePacket below.
2108 QuicTime packet_send_time = clock_->Now();
2109 if (supports_release_time_ && per_packet_options_ != nullptr) {
2110 QuicTime next_release_time = sent_packet_manager_.GetNextReleaseTime();
2111 QuicTime::Delta release_time_delay = QuicTime::Delta::Zero();
2112 QuicTime now = packet_send_time;
2113 if (next_release_time > now) {
2114 release_time_delay = next_release_time - now;
2115 // Set packet_send_time to the future to make the RTT estimation accurate.
2116 packet_send_time = next_release_time;
2117 }
2118 per_packet_options_->release_time_delay = release_time_delay;
2119 }
2120 WriteResult result = writer_->WritePacket(
2121 packet->encrypted_buffer, encrypted_length, self_address().host(),
2122 peer_address(), per_packet_options_);
2123
2124 QUIC_HISTOGRAM_ENUM(
2125 "QuicConnection.WritePacketStatus", result.status,
2126 WRITE_STATUS_NUM_VALUES,
2127 "Status code returned by writer_->WritePacket() in QuicConnection.");
2128
2129 if (IsWriteBlockedStatus(result.status)) {
2130 // Ensure the writer is still write blocked, otherwise QUIC may continue
2131 // trying to write when it will not be able to.
2132 DCHECK(writer_->IsWriteBlocked());
2133 visitor_->OnWriteBlocked();
2134 // If the socket buffers the data, then the packet should not
2135 // be queued and sent again, which would result in an unnecessary
2136 // duplicate packet being sent. The helper must call OnCanWrite
2137 // when the write completes, and OnWriteError if an error occurs.
2138 if (result.status != WRITE_STATUS_BLOCKED_DATA_BUFFERED) {
2139 return false;
2140 }
2141 }
2142
2143 // In some cases, an MTU probe can cause EMSGSIZE. This indicates that the
2144 // MTU discovery is permanently unsuccessful.
2145 if (IsMsgTooBig(result) && packet->retransmittable_frames.empty() &&
2146 packet->encrypted_length > long_term_mtu_) {
2147 mtu_discovery_target_ = 0;
2148 mtu_discovery_alarm_->Cancel();
2149 // The write failed, but the writer is not blocked, so return true.
2150 return true;
2151 }
2152
2153 if (IsWriteError(result.status)) {
2154 OnWriteError(result.error_code);
2155 QUIC_LOG_FIRST_N(ERROR, 10)
2156 << ENDPOINT << "failed writing " << encrypted_length
2157 << " bytes from host " << self_address().host().ToString()
2158 << " to address " << peer_address().ToString() << " with error code "
2159 << result.error_code;
2160 return false;
2161 }
2162
2163 if (debug_visitor_ != nullptr) {
2164 // Pass the write result to the visitor.
2165 debug_visitor_->OnPacketSent(*packet, packet->original_packet_number,
2166 packet->transmission_type, packet_send_time);
2167 }
2168 if (IsRetransmittable(*packet) == HAS_RETRANSMITTABLE_DATA) {
2169 if (!is_path_degrading_ && !path_degrading_alarm_->IsSet()) {
2170 // This is the first retransmittable packet on the working path.
2171 // Start the path degrading alarm to detect new path degrading.
2172 SetPathDegradingAlarm();
2173 }
2174
zhongyic1cab062019-06-19 12:02:24 -07002175 // Update |time_of_first_packet_sent_after_receiving_| if this is the
2176 // first packet sent after the last packet was received. If it were
2177 // updated on every sent packet, then sending into a black hole might
2178 // never timeout.
2179 if (time_of_first_packet_sent_after_receiving_ <
2180 time_of_last_received_packet_) {
2181 time_of_first_packet_sent_after_receiving_ = packet_send_time;
QUICHE teama6ef0a62019-03-07 20:34:33 -05002182 }
2183 }
2184
2185 MaybeSetMtuAlarm(packet_number);
2186 QUIC_DVLOG(1) << ENDPOINT << "time we began writing last sent packet: "
2187 << packet_send_time.ToDebuggingValue();
2188
2189 bool reset_retransmission_alarm = sent_packet_manager_.OnPacketSent(
2190 packet, packet->original_packet_number, packet_send_time,
2191 packet->transmission_type, IsRetransmittable(*packet));
2192
2193 if (reset_retransmission_alarm || !retransmission_alarm_->IsSet()) {
2194 SetRetransmissionAlarm();
2195 }
2196 SetPingAlarm();
2197
2198 // The packet number length must be updated after OnPacketSent, because it
2199 // may change the packet number length in packet.
2200 packet_generator_.UpdatePacketNumberLength(
2201 sent_packet_manager_.GetLeastUnacked(),
2202 sent_packet_manager_.EstimateMaxPacketsInFlight(max_packet_length()));
2203
2204 stats_.bytes_sent += result.bytes_written;
2205 ++stats_.packets_sent;
2206 if (packet->transmission_type != NOT_RETRANSMISSION) {
2207 stats_.bytes_retransmitted += result.bytes_written;
2208 ++stats_.packets_retransmitted;
2209 }
2210
2211 return true;
2212}
2213
2214void QuicConnection::FlushPackets() {
2215 if (!connected_) {
2216 return;
2217 }
2218
2219 if (!writer_->IsBatchMode()) {
2220 return;
2221 }
2222
2223 if (HandleWriteBlocked()) {
2224 QUIC_DLOG(INFO) << ENDPOINT << "FlushPackets called while blocked.";
2225 return;
2226 }
2227
2228 WriteResult result = writer_->Flush();
2229
2230 if (HandleWriteBlocked()) {
2231 DCHECK_EQ(WRITE_STATUS_BLOCKED, result.status)
2232 << "Unexpected flush result:" << result;
2233 QUIC_DLOG(INFO) << ENDPOINT << "Write blocked in FlushPackets.";
2234 return;
2235 }
2236
2237 if (IsWriteError(result.status)) {
2238 OnWriteError(result.error_code);
2239 }
2240}
2241
2242bool QuicConnection::IsMsgTooBig(const WriteResult& result) {
2243 return (result.status == WRITE_STATUS_MSG_TOO_BIG) ||
2244 (IsWriteError(result.status) && result.error_code == QUIC_EMSGSIZE);
2245}
2246
2247bool QuicConnection::ShouldDiscardPacket(const SerializedPacket& packet) {
2248 if (!connected_) {
2249 QUIC_DLOG(INFO) << ENDPOINT
2250 << "Not sending packet as connection is disconnected.";
2251 return true;
2252 }
2253
2254 QuicPacketNumber packet_number = packet.packet_number;
2255 if (encryption_level_ == ENCRYPTION_FORWARD_SECURE &&
QUICHE team6987b4a2019-03-15 16:23:04 -07002256 packet.encryption_level == ENCRYPTION_INITIAL) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002257 // Drop packets that are NULL encrypted since the peer won't accept them
2258 // anymore.
2259 QUIC_DLOG(INFO) << ENDPOINT
2260 << "Dropping NULL encrypted packet: " << packet_number
2261 << " since the connection is forward secure.";
2262 return true;
2263 }
2264
2265 return false;
2266}
2267
2268void QuicConnection::OnWriteError(int error_code) {
2269 if (write_error_occurred_) {
2270 // A write error already occurred. The connection is being closed.
2271 return;
2272 }
2273 write_error_occurred_ = true;
2274
vasilvvc48c8712019-03-11 13:38:16 -07002275 const std::string error_details = QuicStrCat(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002276 "Write failed with error: ", error_code, " (", strerror(error_code), ")");
2277 QUIC_LOG_FIRST_N(ERROR, 2) << ENDPOINT << error_details;
2278 switch (error_code) {
2279 case QUIC_EMSGSIZE:
ianswettdc1e7ab2019-05-03 16:10:44 -07002280 CloseConnection(QUIC_PACKET_WRITE_ERROR, error_details,
2281 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002282 break;
2283 default:
2284 // We can't send an error as the socket is presumably borked.
fayangd4291e42019-05-30 10:31:21 -07002285 if (VersionHasIetfInvariantHeader(transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002286 QUIC_CODE_COUNT(quic_tear_down_local_connection_on_write_error_ietf);
2287 } else {
2288 QUIC_CODE_COUNT(
2289 quic_tear_down_local_connection_on_write_error_non_ietf);
2290 }
fkastenholz85f18902019-05-28 12:47:00 -07002291 CloseConnection(QUIC_PACKET_WRITE_ERROR, error_details,
2292 ConnectionCloseBehavior::SILENT_CLOSE);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002293 }
2294}
2295
2296char* QuicConnection::GetPacketBuffer() {
2297 return writer_->GetNextWriteLocation(self_address().host(), peer_address());
2298}
2299
2300void QuicConnection::OnSerializedPacket(SerializedPacket* serialized_packet) {
2301 if (serialized_packet->encrypted_buffer == nullptr) {
2302 // We failed to serialize the packet, so close the connection.
fkastenholz85f18902019-05-28 12:47:00 -07002303 // Specify that the close is silent, that no packet be sent, so no infinite
QUICHE teama6ef0a62019-03-07 20:34:33 -05002304 // loop here.
2305 // TODO(ianswett): This is actually an internal error, not an
2306 // encryption failure.
fayangd4291e42019-05-30 10:31:21 -07002307 if (VersionHasIetfInvariantHeader(transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002308 QUIC_CODE_COUNT(
2309 quic_tear_down_local_connection_on_serialized_packet_ietf);
2310 } else {
2311 QUIC_CODE_COUNT(
2312 quic_tear_down_local_connection_on_serialized_packet_non_ietf);
2313 }
fkastenholz85f18902019-05-28 12:47:00 -07002314 CloseConnection(QUIC_ENCRYPTION_FAILURE,
2315 "Serialized packet does not have an encrypted buffer.",
2316 ConnectionCloseBehavior::SILENT_CLOSE);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002317 return;
2318 }
2319
2320 if (serialized_packet->retransmittable_frames.empty() &&
2321 !serialized_packet->original_packet_number.IsInitialized()) {
2322 // Increment consecutive_num_packets_with_no_retransmittable_frames_ if
2323 // this packet is a new transmission with no retransmittable frames.
2324 ++consecutive_num_packets_with_no_retransmittable_frames_;
2325 } else {
2326 consecutive_num_packets_with_no_retransmittable_frames_ = 0;
2327 }
2328 SendOrQueuePacket(serialized_packet);
2329}
2330
2331void QuicConnection::OnUnrecoverableError(QuicErrorCode error,
fkastenholz85f18902019-05-28 12:47:00 -07002332 const std::string& error_details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002333 // The packet creator or generator encountered an unrecoverable error: tear
2334 // down local connection state immediately.
fayangd4291e42019-05-30 10:31:21 -07002335 if (VersionHasIetfInvariantHeader(transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002336 QUIC_CODE_COUNT(
2337 quic_tear_down_local_connection_on_unrecoverable_error_ietf);
2338 } else {
2339 QUIC_CODE_COUNT(
2340 quic_tear_down_local_connection_on_unrecoverable_error_non_ietf);
2341 }
fkastenholz85f18902019-05-28 12:47:00 -07002342 CloseConnection(error, error_details, ConnectionCloseBehavior::SILENT_CLOSE);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002343}
2344
2345void QuicConnection::OnCongestionChange() {
2346 visitor_->OnCongestionWindowChange(clock_->ApproximateNow());
2347
2348 // Uses the connection's smoothed RTT. If zero, uses initial_rtt.
2349 QuicTime::Delta rtt = sent_packet_manager_.GetRttStats()->smoothed_rtt();
2350 if (rtt.IsZero()) {
2351 rtt = sent_packet_manager_.GetRttStats()->initial_rtt();
2352 }
2353
2354 if (debug_visitor_ != nullptr) {
2355 debug_visitor_->OnRttChanged(rtt);
2356 }
2357}
2358
2359void QuicConnection::OnPathMtuIncreased(QuicPacketLength packet_size) {
2360 if (packet_size > max_packet_length()) {
2361 SetMaxPacketLength(packet_size);
2362 }
2363}
2364
2365void QuicConnection::OnHandshakeComplete() {
2366 sent_packet_manager_.SetHandshakeConfirmed();
fayangbf3d2862019-06-20 14:13:44 -07002367 // This may have changed the retransmission timer, so re-arm it.
2368 SetRetransmissionAlarm();
QUICHE teama6ef0a62019-03-07 20:34:33 -05002369 // The client should immediately ack the SHLO to confirm the handshake is
2370 // complete with the server.
fayanga4b37b22019-06-18 13:37:47 -07002371 if (perspective_ == Perspective::IS_CLIENT && ack_frame_updated()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002372 ack_alarm_->Update(clock_->ApproximateNow(), QuicTime::Delta::Zero());
2373 }
2374}
2375
2376void QuicConnection::SendOrQueuePacket(SerializedPacket* packet) {
2377 // The caller of this function is responsible for checking CanWrite().
2378 if (packet->encrypted_buffer == nullptr) {
2379 QUIC_BUG << "packet.encrypted_buffer == nullptr in to SendOrQueuePacket";
2380 return;
2381 }
2382 // If there are already queued packets, queue this one immediately to ensure
2383 // it's written in sequence number order.
2384 if (!queued_packets_.empty() || !WritePacket(packet)) {
2385 // Take ownership of the underlying encrypted packet.
2386 packet->encrypted_buffer = CopyBuffer(*packet);
2387 queued_packets_.push_back(*packet);
2388 packet->retransmittable_frames.clear();
2389 }
2390
2391 ClearSerializedPacket(packet);
2392}
2393
2394void QuicConnection::OnPingTimeout() {
2395 if (!retransmission_alarm_->IsSet()) {
2396 visitor_->SendPing();
2397 }
2398}
2399
2400void QuicConnection::SendAck() {
QUICHE teamcd098022019-03-22 18:49:55 -07002401 DCHECK(!SupportsMultiplePacketNumberSpaces());
fayanga4b37b22019-06-18 13:37:47 -07002402 QUIC_DVLOG(1) << ENDPOINT << "Sending an ACK proactively";
2403 QuicFrames frames;
2404 frames.push_back(GetUpdatedAckFrame());
2405 if (!no_stop_waiting_frames_) {
2406 QuicStopWaitingFrame stop_waiting;
2407 PopulateStopWaitingFrame(&stop_waiting);
2408 frames.push_back(QuicFrame(stop_waiting));
2409 }
fayangf477f732019-06-20 07:03:06 -07002410 if (!packet_generator_.FlushAckFrame(frames)) {
2411 return;
QUICHE teama6ef0a62019-03-07 20:34:33 -05002412 }
fayangf477f732019-06-20 07:03:06 -07002413 ResetAckStates();
QUICHE teama6ef0a62019-03-07 20:34:33 -05002414 if (consecutive_num_packets_with_no_retransmittable_frames_ <
2415 max_consecutive_num_packets_with_no_retransmittable_frames_) {
2416 return;
2417 }
2418 consecutive_num_packets_with_no_retransmittable_frames_ = 0;
2419 if (packet_generator_.HasRetransmittableFrames() ||
2420 visitor_->WillingAndAbleToWrite()) {
2421 // There are pending retransmittable frames.
2422 return;
2423 }
2424
2425 visitor_->OnAckNeedsRetransmittableFrame();
2426}
2427
2428void QuicConnection::OnPathDegradingTimeout() {
2429 is_path_degrading_ = true;
2430 visitor_->OnPathDegrading();
2431}
2432
2433void QuicConnection::OnRetransmissionTimeout() {
2434 DCHECK(!sent_packet_manager_.unacked_packets().empty());
fayanga29eb242019-07-16 12:25:38 -07002435 const QuicPacketNumber previous_created_packet_number =
2436 packet_generator_.packet_number();
2437 const size_t previous_crypto_retransmit_count =
2438 stats_.crypto_retransmit_count;
2439 const size_t previous_loss_timeout_count = stats_.loss_timeout_count;
2440 const size_t previous_tlp_count = stats_.tlp_count;
2441 const size_t pervious_rto_count = stats_.rto_count;
QUICHE teama6ef0a62019-03-07 20:34:33 -05002442 if (close_connection_after_five_rtos_ &&
2443 sent_packet_manager_.GetConsecutiveRtoCount() >= 4) {
2444 // Close on the 5th consecutive RTO, so after 4 previous RTOs have occurred.
2445 CloseConnection(QUIC_TOO_MANY_RTOS, "5 consecutive retransmission timeouts",
2446 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
2447 return;
2448 }
2449
2450 sent_packet_manager_.OnRetransmissionTimeout();
2451 WriteIfNotBlocked();
2452
2453 // A write failure can result in the connection being closed, don't attempt to
2454 // write further packets, or to set alarms.
2455 if (!connected_) {
2456 return;
2457 }
2458
2459 // In the TLP case, the SentPacketManager gives the connection the opportunity
2460 // to send new data before retransmitting.
2461 if (sent_packet_manager_.MaybeRetransmitTailLossProbe()) {
2462 // Send the pending retransmission now that it's been queued.
2463 WriteIfNotBlocked();
2464 }
2465
fayanga29eb242019-07-16 12:25:38 -07002466 if (sent_packet_manager_.fix_rto_retransmission()) {
2467 // Making sure at least one packet is created when retransmission timer
2468 // fires in TLP, RTO or HANDSHAKE mode. It is possible that loss algorithm
2469 // invokes timer based loss but the packet does not need to be
2470 // retransmitted.
2471 QUIC_BUG_IF(stats_.loss_timeout_count == previous_loss_timeout_count &&
2472 packet_generator_.packet_number() ==
2473 previous_created_packet_number)
2474 << "previous_crypto_retransmit_count: "
2475 << previous_crypto_retransmit_count
2476 << ", crypto_retransmit_count: " << stats_.crypto_retransmit_count
2477 << ", previous_loss_timeout_count: " << previous_loss_timeout_count
2478 << ", loss_timeout_count: " << stats_.loss_timeout_count
2479 << ", previous_tlp_count: " << previous_tlp_count
2480 << ", tlp_count: " << stats_.tlp_count
2481 << ", pervious_rto_count: " << pervious_rto_count
2482 << ", rto_count: " << stats_.rto_count
2483 << ", previous_created_packet_number: "
2484 << previous_created_packet_number
2485 << ", packet_number: " << packet_generator_.packet_number()
2486 << ", session has data to write: " << visitor_->WillingAndAbleToWrite();
2487 }
2488
QUICHE teama6ef0a62019-03-07 20:34:33 -05002489 // Ensure the retransmission alarm is always set if there are unacked packets
2490 // and nothing waiting to be sent.
2491 // This happens if the loss algorithm invokes a timer based loss, but the
2492 // packet doesn't need to be retransmitted.
2493 if (!HasQueuedData() && !retransmission_alarm_->IsSet()) {
2494 SetRetransmissionAlarm();
2495 }
2496}
2497
2498void QuicConnection::SetEncrypter(EncryptionLevel level,
2499 std::unique_ptr<QuicEncrypter> encrypter) {
2500 packet_generator_.SetEncrypter(level, std::move(encrypter));
2501}
2502
2503void QuicConnection::SetDiversificationNonce(
2504 const DiversificationNonce& nonce) {
2505 DCHECK_EQ(Perspective::IS_SERVER, perspective_);
2506 packet_generator_.SetDiversificationNonce(nonce);
2507}
2508
2509void QuicConnection::SetDefaultEncryptionLevel(EncryptionLevel level) {
fayang914fbe12019-07-11 06:23:55 -07002510 if (level != encryption_level_ && packet_generator_.HasPendingFrames()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002511 // Flush all queued frames when encryption level changes.
fayanga4b37b22019-06-18 13:37:47 -07002512 ScopedPacketFlusher flusher(this);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002513 packet_generator_.FlushAllQueuedFrames();
2514 }
2515 encryption_level_ = level;
2516 packet_generator_.set_encryption_level(level);
2517}
2518
2519void QuicConnection::SetDecrypter(EncryptionLevel level,
2520 std::unique_ptr<QuicDecrypter> decrypter) {
2521 framer_.SetDecrypter(level, std::move(decrypter));
2522
2523 if (!undecryptable_packets_.empty() &&
2524 !process_undecryptable_packets_alarm_->IsSet()) {
2525 process_undecryptable_packets_alarm_->Set(clock_->ApproximateNow());
2526 }
2527}
2528
2529void QuicConnection::SetAlternativeDecrypter(
2530 EncryptionLevel level,
2531 std::unique_ptr<QuicDecrypter> decrypter,
2532 bool latch_once_used) {
2533 framer_.SetAlternativeDecrypter(level, std::move(decrypter), latch_once_used);
2534
2535 if (!undecryptable_packets_.empty() &&
2536 !process_undecryptable_packets_alarm_->IsSet()) {
2537 process_undecryptable_packets_alarm_->Set(clock_->ApproximateNow());
2538 }
2539}
2540
zhongyi546cc452019-04-12 15:27:49 -07002541void QuicConnection::InstallDecrypter(
2542 EncryptionLevel level,
2543 std::unique_ptr<QuicDecrypter> decrypter) {
2544 framer_.InstallDecrypter(level, std::move(decrypter));
2545 if (!undecryptable_packets_.empty() &&
2546 !process_undecryptable_packets_alarm_->IsSet()) {
2547 process_undecryptable_packets_alarm_->Set(clock_->ApproximateNow());
2548 }
2549}
2550
2551void QuicConnection::RemoveDecrypter(EncryptionLevel level) {
2552 framer_.RemoveDecrypter(level);
2553}
2554
QUICHE teama6ef0a62019-03-07 20:34:33 -05002555const QuicDecrypter* QuicConnection::decrypter() const {
2556 return framer_.decrypter();
2557}
2558
2559const QuicDecrypter* QuicConnection::alternative_decrypter() const {
2560 return framer_.alternative_decrypter();
2561}
2562
2563void QuicConnection::QueueUndecryptablePacket(
2564 const QuicEncryptedPacket& packet) {
2565 QUIC_DVLOG(1) << ENDPOINT << "Queueing undecryptable packet.";
2566 undecryptable_packets_.push_back(packet.Clone());
2567}
2568
2569void QuicConnection::MaybeProcessUndecryptablePackets() {
2570 process_undecryptable_packets_alarm_->Cancel();
2571
QUICHE team6987b4a2019-03-15 16:23:04 -07002572 if (undecryptable_packets_.empty() ||
2573 encryption_level_ == ENCRYPTION_INITIAL) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002574 return;
2575 }
2576
2577 while (connected_ && !undecryptable_packets_.empty()) {
2578 // Making sure there is no pending frames when processing next undecrypted
2579 // packet because the queued ack frame may change.
2580 packet_generator_.FlushAllQueuedFrames();
2581 if (!connected_) {
2582 return;
2583 }
2584 QUIC_DVLOG(1) << ENDPOINT << "Attempting to process undecryptable packet";
2585 QuicEncryptedPacket* packet = undecryptable_packets_.front().get();
2586 if (!framer_.ProcessPacket(*packet) &&
2587 framer_.error() == QUIC_DECRYPTION_FAILURE) {
2588 QUIC_DVLOG(1) << ENDPOINT << "Unable to process undecryptable packet...";
2589 break;
2590 }
2591 QUIC_DVLOG(1) << ENDPOINT << "Processed undecryptable packet!";
2592 ++stats_.packets_processed;
2593 undecryptable_packets_.pop_front();
2594 }
2595
2596 // Once forward secure encryption is in use, there will be no
2597 // new keys installed and hence any undecryptable packets will
2598 // never be able to be decrypted.
2599 if (encryption_level_ == ENCRYPTION_FORWARD_SECURE) {
2600 if (debug_visitor_ != nullptr) {
2601 // TODO(rtenneti): perhaps more efficient to pass the number of
2602 // undecryptable packets as the argument to OnUndecryptablePacket so that
2603 // we just need to call OnUndecryptablePacket once?
2604 for (size_t i = 0; i < undecryptable_packets_.size(); ++i) {
2605 debug_visitor_->OnUndecryptablePacket();
2606 }
2607 }
2608 undecryptable_packets_.clear();
2609 }
2610}
2611
2612void QuicConnection::QueueCoalescedPacket(const QuicEncryptedPacket& packet) {
2613 QUIC_DVLOG(1) << ENDPOINT << "Queueing coalesced packet.";
2614 coalesced_packets_.push_back(packet.Clone());
2615}
2616
2617void QuicConnection::MaybeProcessCoalescedPackets() {
2618 bool processed = false;
2619 for (const auto& packet : coalesced_packets_) {
2620 if (!connected_) {
2621 return;
2622 }
2623
2624 // }
2625 // while (connected_ && !coalesced_packets_.empty()) {
2626 QUIC_DVLOG(1) << ENDPOINT << "Processing coalesced packet";
2627 // QuicEncryptedPacket* packet = coalesced_packets_.front().get();
2628 if (framer_.ProcessPacket(*packet)) {
2629 processed = true;
2630 } else {
2631 // If we are unable to decrypt this packet, it might be
2632 // because the CHLO or SHLO packet was lost.
2633 if (framer_.error() == QUIC_DECRYPTION_FAILURE) {
dschinazi6ece5002019-05-22 06:35:49 -07002634 ++stats_.undecryptable_packets_received;
QUICHE teama6ef0a62019-03-07 20:34:33 -05002635 if (encryption_level_ != ENCRYPTION_FORWARD_SECURE &&
2636 undecryptable_packets_.size() < max_undecryptable_packets_) {
2637 QueueUndecryptablePacket(*packet);
2638 } else if (debug_visitor_ != nullptr) {
2639 debug_visitor_->OnUndecryptablePacket();
2640 }
2641 }
2642 }
2643 // coalesced_packets_.pop_front();
2644 }
2645 coalesced_packets_.clear();
2646 if (processed) {
2647 MaybeProcessUndecryptablePackets();
2648 }
2649}
2650
2651void QuicConnection::CloseConnection(
2652 QuicErrorCode error,
vasilvvc48c8712019-03-11 13:38:16 -07002653 const std::string& error_details,
QUICHE teama6ef0a62019-03-07 20:34:33 -05002654 ConnectionCloseBehavior connection_close_behavior) {
2655 DCHECK(!error_details.empty());
2656 if (!connected_) {
2657 QUIC_DLOG(INFO) << "Connection is already closed.";
2658 return;
2659 }
2660
2661 QUIC_DLOG(INFO) << ENDPOINT << "Closing connection: " << connection_id()
2662 << ", with error: " << QuicErrorCodeToString(error) << " ("
2663 << error << "), and details: " << error_details;
2664
ianswettdc1e7ab2019-05-03 16:10:44 -07002665 if (connection_close_behavior != ConnectionCloseBehavior::SILENT_CLOSE) {
2666 SendConnectionClosePacket(error, error_details);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002667 }
2668
wub5f64ec42019-06-06 07:31:19 -07002669 TearDownLocalConnectionState(error, error_details,
2670 ConnectionCloseSource::FROM_SELF);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002671}
2672
2673void QuicConnection::SendConnectionClosePacket(QuicErrorCode error,
ianswettdc1e7ab2019-05-03 16:10:44 -07002674 const std::string& details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002675 QUIC_DLOG(INFO) << ENDPOINT << "Sending connection close packet.";
QUICHE team2252b702019-05-14 23:55:14 -04002676 SetDefaultEncryptionLevel(GetConnectionCloseEncryptionLevel());
QUICHE teama6ef0a62019-03-07 20:34:33 -05002677 ClearQueuedPackets();
ianswettdc1e7ab2019-05-03 16:10:44 -07002678 // If there was a packet write error, write the smallest close possible.
fayanga4b37b22019-06-18 13:37:47 -07002679 ScopedPacketFlusher flusher(this);
QUICHE teamcd098022019-03-22 18:49:55 -07002680 // When multiple packet number spaces is supported, an ACK frame will be
2681 // bundled when connection is not write blocked.
2682 if (!SupportsMultiplePacketNumberSpaces() &&
fayanga4b37b22019-06-18 13:37:47 -07002683 error != QUIC_PACKET_WRITE_ERROR &&
QUICHE teama6ef0a62019-03-07 20:34:33 -05002684 !GetUpdatedAckFrame().ack_frame->packets.Empty()) {
2685 SendAck();
2686 }
fkastenholze9d71a82019-04-09 05:12:13 -07002687 QuicConnectionCloseFrame* frame =
2688 new QuicConnectionCloseFrame(error, details);
fkastenholz04bd4f32019-04-16 12:24:38 -07002689 // If version99/IETF QUIC set the close type. Default close type is Google
2690 // QUIC.
fkastenholz305e1732019-06-18 05:01:22 -07002691 if (VersionHasIetfQuicFrames(transport_version())) {
fkastenholz72f509b2019-04-10 09:17:49 -07002692 frame->close_type = IETF_QUIC_TRANSPORT_CONNECTION_CLOSE;
2693 }
fayang3203f252019-05-03 06:00:03 -07002694 packet_generator_.ConsumeRetransmittableControlFrame(QuicFrame(frame));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002695 packet_generator_.FlushAllQueuedFrames();
nharperef468962019-07-02 14:15:38 -07002696 if (GetQuicReloadableFlag(quic_clear_queued_packets_on_connection_close)) {
2697 QUIC_RELOADABLE_FLAG_COUNT(quic_clear_queued_packets_on_connection_close);
2698 ClearQueuedPackets();
2699 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002700}
2701
2702void QuicConnection::TearDownLocalConnectionState(
2703 QuicErrorCode error,
vasilvvc48c8712019-03-11 13:38:16 -07002704 const std::string& error_details,
QUICHE teama6ef0a62019-03-07 20:34:33 -05002705 ConnectionCloseSource source) {
2706 if (!connected_) {
2707 QUIC_DLOG(INFO) << "Connection is already closed.";
2708 return;
2709 }
2710
2711 // If we are using a batch writer, flush packets queued in it, if any.
2712 FlushPackets();
2713 connected_ = false;
2714 DCHECK(visitor_ != nullptr);
fkastenholz5d880a92019-06-21 09:01:56 -07002715 // TODO(fkastenholz): When the IETF Transport Connection Close information
2716 // gets plumbed in, expand this constructor to include that information.
2717 QuicConnectionCloseFrame frame(error, error_details);
2718 visitor_->OnConnectionClosed(frame, source);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002719 if (debug_visitor_ != nullptr) {
fkastenholzac11db02019-06-24 06:22:04 -07002720 debug_visitor_->OnConnectionClosed(frame, source);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002721 }
2722 // Cancel the alarms so they don't trigger any action now that the
2723 // connection is closed.
2724 CancelAllAlarms();
2725}
2726
2727void QuicConnection::CancelAllAlarms() {
2728 QUIC_DVLOG(1) << "Cancelling all QuicConnection alarms.";
2729
2730 ack_alarm_->Cancel();
2731 ping_alarm_->Cancel();
2732 retransmission_alarm_->Cancel();
2733 send_alarm_->Cancel();
2734 timeout_alarm_->Cancel();
2735 mtu_discovery_alarm_->Cancel();
2736 path_degrading_alarm_->Cancel();
renjietang11e4a3d2019-05-03 11:27:26 -07002737 process_undecryptable_packets_alarm_->Cancel();
QUICHE teama6ef0a62019-03-07 20:34:33 -05002738}
2739
2740QuicByteCount QuicConnection::max_packet_length() const {
2741 return packet_generator_.GetCurrentMaxPacketLength();
2742}
2743
2744void QuicConnection::SetMaxPacketLength(QuicByteCount length) {
2745 long_term_mtu_ = length;
2746 packet_generator_.SetMaxPacketLength(GetLimitedMaxPacketSize(length));
2747}
2748
2749bool QuicConnection::HasQueuedData() const {
2750 return pending_version_negotiation_packet_ || !queued_packets_.empty() ||
fayang914fbe12019-07-11 06:23:55 -07002751 packet_generator_.HasPendingFrames();
QUICHE teama6ef0a62019-03-07 20:34:33 -05002752}
2753
QUICHE teama6ef0a62019-03-07 20:34:33 -05002754bool QuicConnection::CanWriteStreamData() {
2755 // Don't write stream data if there are negotiation or queued data packets
2756 // to send. Otherwise, continue and bundle as many frames as possible.
2757 if (pending_version_negotiation_packet_ || !queued_packets_.empty()) {
2758 return false;
2759 }
2760
2761 IsHandshake pending_handshake =
2762 visitor_->HasPendingHandshake() ? IS_HANDSHAKE : NOT_HANDSHAKE;
2763 // Sending queued packets may have caused the socket to become write blocked,
2764 // or the congestion manager to prohibit sending. If we've sent everything
2765 // we had queued and we're still not blocked, let the visitor know it can
2766 // write more.
2767 return ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA, pending_handshake);
2768}
2769
2770void QuicConnection::SetNetworkTimeouts(QuicTime::Delta handshake_timeout,
2771 QuicTime::Delta idle_timeout) {
2772 QUIC_BUG_IF(idle_timeout > handshake_timeout)
2773 << "idle_timeout:" << idle_timeout.ToMilliseconds()
2774 << " handshake_timeout:" << handshake_timeout.ToMilliseconds();
2775 // Adjust the idle timeout on client and server to prevent clients from
2776 // sending requests to servers which have already closed the connection.
2777 if (perspective_ == Perspective::IS_SERVER) {
2778 idle_timeout = idle_timeout + QuicTime::Delta::FromSeconds(3);
2779 } else if (idle_timeout > QuicTime::Delta::FromSeconds(1)) {
2780 idle_timeout = idle_timeout - QuicTime::Delta::FromSeconds(1);
2781 }
2782 handshake_timeout_ = handshake_timeout;
2783 idle_network_timeout_ = idle_timeout;
2784
2785 SetTimeoutAlarm();
2786}
2787
2788void QuicConnection::CheckForTimeout() {
2789 QuicTime now = clock_->ApproximateNow();
2790 QuicTime time_of_last_packet =
2791 std::max(time_of_last_received_packet_,
2792 time_of_first_packet_sent_after_receiving_);
2793
2794 // |delta| can be < 0 as |now| is approximate time but |time_of_last_packet|
2795 // is accurate time. However, this should not change the behavior of
2796 // timeout handling.
2797 QuicTime::Delta idle_duration = now - time_of_last_packet;
2798 QUIC_DVLOG(1) << ENDPOINT << "last packet "
2799 << time_of_last_packet.ToDebuggingValue()
2800 << " now:" << now.ToDebuggingValue()
2801 << " idle_duration:" << idle_duration.ToMicroseconds()
2802 << " idle_network_timeout: "
2803 << idle_network_timeout_.ToMicroseconds();
2804 if (idle_duration >= idle_network_timeout_) {
vasilvvc48c8712019-03-11 13:38:16 -07002805 const std::string error_details = "No recent network activity.";
QUICHE teama6ef0a62019-03-07 20:34:33 -05002806 QUIC_DVLOG(1) << ENDPOINT << error_details;
2807 if ((sent_packet_manager_.GetConsecutiveTlpCount() > 0 ||
2808 sent_packet_manager_.GetConsecutiveRtoCount() > 0 ||
2809 visitor_->ShouldKeepConnectionAlive())) {
2810 CloseConnection(QUIC_NETWORK_IDLE_TIMEOUT, error_details,
2811 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
2812 } else {
2813 CloseConnection(QUIC_NETWORK_IDLE_TIMEOUT, error_details,
2814 idle_timeout_connection_close_behavior_);
2815 }
2816 return;
2817 }
2818
2819 if (!handshake_timeout_.IsInfinite()) {
2820 QuicTime::Delta connected_duration = now - stats_.connection_creation_time;
2821 QUIC_DVLOG(1) << ENDPOINT
2822 << "connection time: " << connected_duration.ToMicroseconds()
2823 << " handshake timeout: "
2824 << handshake_timeout_.ToMicroseconds();
2825 if (connected_duration >= handshake_timeout_) {
vasilvvc48c8712019-03-11 13:38:16 -07002826 const std::string error_details = "Handshake timeout expired.";
QUICHE teama6ef0a62019-03-07 20:34:33 -05002827 QUIC_DVLOG(1) << ENDPOINT << error_details;
2828 CloseConnection(QUIC_HANDSHAKE_TIMEOUT, error_details,
2829 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
2830 return;
2831 }
2832 }
2833
2834 SetTimeoutAlarm();
2835}
2836
2837void QuicConnection::SetTimeoutAlarm() {
2838 QuicTime time_of_last_packet =
2839 std::max(time_of_last_received_packet_,
2840 time_of_first_packet_sent_after_receiving_);
2841
2842 QuicTime deadline = time_of_last_packet + idle_network_timeout_;
2843 if (!handshake_timeout_.IsInfinite()) {
2844 deadline = std::min(deadline,
2845 stats_.connection_creation_time + handshake_timeout_);
2846 }
2847
2848 timeout_alarm_->Update(deadline, QuicTime::Delta::Zero());
2849}
2850
2851void QuicConnection::SetPingAlarm() {
2852 if (perspective_ == Perspective::IS_SERVER) {
ianswettb7f7cd22019-05-01 08:04:16 -07002853 // Only clients send pings to avoid NATs from timing out.
QUICHE teama6ef0a62019-03-07 20:34:33 -05002854 return;
2855 }
2856 if (!visitor_->ShouldKeepConnectionAlive()) {
2857 ping_alarm_->Cancel();
ianswettb7f7cd22019-05-01 08:04:16 -07002858 // Don't send a ping unless the application (ie: HTTP/3) says to, usually
2859 // because it is expecting a response from the server.
QUICHE teama6ef0a62019-03-07 20:34:33 -05002860 return;
2861 }
2862 if (retransmittable_on_wire_timeout_.IsInfinite() ||
2863 sent_packet_manager_.HasInFlightPackets()) {
2864 // Extend the ping alarm.
2865 ping_alarm_->Update(clock_->ApproximateNow() + ping_timeout_,
2866 QuicTime::Delta::FromSeconds(1));
2867 return;
2868 }
2869 DCHECK_LT(retransmittable_on_wire_timeout_, ping_timeout_);
2870 // If it's already set to an earlier time, then don't update it.
2871 if (ping_alarm_->IsSet() &&
2872 ping_alarm_->deadline() <
2873 clock_->ApproximateNow() + retransmittable_on_wire_timeout_) {
2874 return;
2875 }
2876 // Use a shorter timeout if there are open streams, but nothing on the wire.
2877 ping_alarm_->Update(
2878 clock_->ApproximateNow() + retransmittable_on_wire_timeout_,
2879 QuicTime::Delta::FromMilliseconds(1));
2880}
2881
2882void QuicConnection::SetRetransmissionAlarm() {
2883 if (packet_generator_.PacketFlusherAttached()) {
2884 pending_retransmission_alarm_ = true;
2885 return;
2886 }
2887 QuicTime retransmission_time = sent_packet_manager_.GetRetransmissionTime();
2888 retransmission_alarm_->Update(retransmission_time,
2889 QuicTime::Delta::FromMilliseconds(1));
2890}
2891
2892void QuicConnection::SetPathDegradingAlarm() {
2893 if (perspective_ == Perspective::IS_SERVER) {
2894 return;
2895 }
2896 const QuicTime::Delta delay = sent_packet_manager_.GetPathDegradingDelay();
2897 path_degrading_alarm_->Update(clock_->ApproximateNow() + delay,
2898 QuicTime::Delta::FromMilliseconds(1));
2899}
2900
2901void QuicConnection::MaybeSetMtuAlarm(QuicPacketNumber sent_packet_number) {
2902 // Do not set the alarm if the target size is less than the current size.
2903 // This covers the case when |mtu_discovery_target_| is at its default value,
2904 // zero.
2905 if (mtu_discovery_target_ <= max_packet_length()) {
2906 return;
2907 }
2908
2909 if (mtu_probe_count_ >= kMtuDiscoveryAttempts) {
2910 return;
2911 }
2912
2913 if (mtu_discovery_alarm_->IsSet()) {
2914 return;
2915 }
2916
2917 if (sent_packet_number >= next_mtu_probe_at_) {
2918 // Use an alarm to send the MTU probe to ensure that no ScopedPacketFlushers
2919 // are active.
2920 mtu_discovery_alarm_->Set(clock_->ApproximateNow());
2921 }
2922}
2923
2924void QuicConnection::MaybeSetAckAlarmTo(QuicTime time) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002925 if (!ack_alarm_->IsSet() || ack_alarm_->deadline() > time) {
2926 ack_alarm_->Update(time, QuicTime::Delta::Zero());
2927 }
2928}
2929
2930QuicConnection::ScopedPacketFlusher::ScopedPacketFlusher(
fayanga4b37b22019-06-18 13:37:47 -07002931 QuicConnection* connection)
QUICHE teama6ef0a62019-03-07 20:34:33 -05002932 : connection_(connection),
2933 flush_and_set_pending_retransmission_alarm_on_delete_(false) {
2934 if (connection_ == nullptr) {
2935 return;
2936 }
2937
2938 if (!connection_->packet_generator_.PacketFlusherAttached()) {
2939 flush_and_set_pending_retransmission_alarm_on_delete_ = true;
2940 connection->packet_generator_.AttachPacketFlusher();
2941 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002942}
2943
2944QuicConnection::ScopedPacketFlusher::~ScopedPacketFlusher() {
fayang0f0c4e62019-07-16 08:55:54 -07002945 if (connection_ == nullptr || !connection_->connected()) {
fayang40ec3ac2019-06-05 09:07:54 -07002946 return;
2947 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002948
2949 if (flush_and_set_pending_retransmission_alarm_on_delete_) {
fayangf477f732019-06-20 07:03:06 -07002950 const QuicTime ack_timeout =
fayang5f464302019-06-20 12:57:33 -07002951 connection_->uber_received_packet_manager_.GetEarliestAckTimeout();
fayangf477f732019-06-20 07:03:06 -07002952 if (ack_timeout.IsInitialized()) {
2953 if (ack_timeout <= connection_->clock_->ApproximateNow() &&
2954 !connection_->CanWrite(NO_RETRANSMITTABLE_DATA)) {
2955 // Cancel ACK alarm if connection is write blocked, and ACK will be
2956 // sent when connection gets unblocked.
2957 connection_->ack_alarm_->Cancel();
2958 } else {
2959 connection_->MaybeSetAckAlarmTo(ack_timeout);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002960 }
fayanga4b37b22019-06-18 13:37:47 -07002961 }
2962 if (connection_->ack_alarm_->IsSet() &&
2963 connection_->ack_alarm_->deadline() <=
2964 connection_->clock_->ApproximateNow()) {
2965 // An ACK needs to be sent right now. This ACK did not get bundled
2966 // because either there was no data to write or packets were marked as
2967 // received after frames were queued in the generator.
2968 if (connection_->send_alarm_->IsSet() &&
2969 connection_->send_alarm_->deadline() <=
QUICHE teama6ef0a62019-03-07 20:34:33 -05002970 connection_->clock_->ApproximateNow()) {
fayanga4b37b22019-06-18 13:37:47 -07002971 // If send alarm will go off soon, let send alarm send the ACK.
2972 connection_->ack_alarm_->Cancel();
fayanga4b37b22019-06-18 13:37:47 -07002973 } else if (connection_->SupportsMultiplePacketNumberSpaces()) {
2974 connection_->SendAllPendingAcks();
2975 } else {
2976 connection_->SendAck();
QUICHE teama6ef0a62019-03-07 20:34:33 -05002977 }
2978 }
2979 connection_->packet_generator_.Flush();
2980 connection_->FlushPackets();
2981 if (connection_->session_decides_what_to_write()) {
2982 // Reset transmission type.
2983 connection_->SetTransmissionType(NOT_RETRANSMISSION);
2984 }
2985
2986 // Once all transmissions are done, check if there is any outstanding data
2987 // to send and notify the congestion controller if not.
2988 //
2989 // Note that this means that the application limited check will happen as
2990 // soon as the last flusher gets destroyed, which is typically after a
2991 // single stream write is finished. This means that if all the data from a
2992 // single write goes through the connection, the application-limited signal
2993 // will fire even if the caller does a write operation immediately after.
2994 // There are two important approaches to remedy this situation:
2995 // (1) Instantiate ScopedPacketFlusher before performing multiple subsequent
2996 // writes, thus deferring this check until all writes are done.
2997 // (2) Write data in chunks sufficiently large so that they cause the
2998 // connection to be limited by the congestion control. Typically, this
2999 // would mean writing chunks larger than the product of the current
3000 // pacing rate and the pacer granularity. So, for instance, if the
3001 // pacing rate of the connection is 1 Gbps, and the pacer granularity is
3002 // 1 ms, the caller should send at least 125k bytes in order to not
3003 // be marked as application-limited.
3004 connection_->CheckIfApplicationLimited();
3005
3006 if (connection_->pending_retransmission_alarm_) {
3007 connection_->SetRetransmissionAlarm();
3008 connection_->pending_retransmission_alarm_ = false;
3009 }
3010 }
3011 DCHECK_EQ(flush_and_set_pending_retransmission_alarm_on_delete_,
3012 !connection_->packet_generator_.PacketFlusherAttached());
3013}
3014
3015HasRetransmittableData QuicConnection::IsRetransmittable(
3016 const SerializedPacket& packet) {
3017 // Retransmitted packets retransmittable frames are owned by the unacked
3018 // packet map, but are not present in the serialized packet.
3019 if (packet.transmission_type != NOT_RETRANSMISSION ||
3020 !packet.retransmittable_frames.empty()) {
3021 return HAS_RETRANSMITTABLE_DATA;
3022 } else {
3023 return NO_RETRANSMITTABLE_DATA;
3024 }
3025}
3026
3027bool QuicConnection::IsTerminationPacket(const SerializedPacket& packet) {
3028 if (packet.retransmittable_frames.empty()) {
3029 return false;
3030 }
3031 for (const QuicFrame& frame : packet.retransmittable_frames) {
3032 if (frame.type == CONNECTION_CLOSE_FRAME) {
3033 return true;
3034 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05003035 }
3036 return false;
3037}
3038
3039void QuicConnection::SetMtuDiscoveryTarget(QuicByteCount target) {
3040 mtu_discovery_target_ = GetLimitedMaxPacketSize(target);
3041}
3042
3043QuicByteCount QuicConnection::GetLimitedMaxPacketSize(
3044 QuicByteCount suggested_max_packet_size) {
3045 if (!peer_address_.IsInitialized()) {
3046 QUIC_BUG << "Attempted to use a connection without a valid peer address";
3047 return suggested_max_packet_size;
3048 }
3049
3050 const QuicByteCount writer_limit = writer_->GetMaxPacketSize(peer_address());
3051
3052 QuicByteCount max_packet_size = suggested_max_packet_size;
3053 if (max_packet_size > writer_limit) {
3054 max_packet_size = writer_limit;
3055 }
dschinazi66dea072019-04-09 11:41:06 -07003056 if (max_packet_size > kMaxOutgoingPacketSize) {
3057 max_packet_size = kMaxOutgoingPacketSize;
QUICHE teama6ef0a62019-03-07 20:34:33 -05003058 }
3059 return max_packet_size;
3060}
3061
3062void QuicConnection::SendMtuDiscoveryPacket(QuicByteCount target_mtu) {
3063 // Currently, this limit is ensured by the caller.
3064 DCHECK_EQ(target_mtu, GetLimitedMaxPacketSize(target_mtu));
3065
3066 // Send the probe.
3067 packet_generator_.GenerateMtuDiscoveryPacket(target_mtu);
3068}
3069
3070// TODO(zhongyi): change this method to generate a connectivity probing packet
3071// and let the caller to call writer to write the packet and handle write
3072// status.
3073bool QuicConnection::SendConnectivityProbingPacket(
3074 QuicPacketWriter* probing_writer,
3075 const QuicSocketAddress& peer_address) {
3076 return SendGenericPathProbePacket(probing_writer, peer_address,
3077 /* is_response= */ false);
3078}
3079
3080void QuicConnection::SendConnectivityProbingResponsePacket(
3081 const QuicSocketAddress& peer_address) {
3082 SendGenericPathProbePacket(nullptr, peer_address,
3083 /* is_response= */ true);
3084}
3085
3086bool QuicConnection::SendGenericPathProbePacket(
3087 QuicPacketWriter* probing_writer,
3088 const QuicSocketAddress& peer_address,
3089 bool is_response) {
3090 DCHECK(peer_address.IsInitialized());
3091 if (!connected_) {
3092 QUIC_BUG << "Not sending connectivity probing packet as connection is "
3093 << "disconnected.";
3094 return false;
3095 }
3096 if (perspective_ == Perspective::IS_SERVER && probing_writer == nullptr) {
3097 // Server can use default packet writer to write packet.
3098 probing_writer = writer_;
3099 }
3100 DCHECK(probing_writer);
3101
3102 if (probing_writer->IsWriteBlocked()) {
3103 QUIC_DLOG(INFO)
3104 << ENDPOINT
3105 << "Writer blocked when sending connectivity probing packet.";
3106 if (probing_writer == writer_) {
3107 // Visitor should not be write blocked if the probing writer is not the
3108 // default packet writer.
3109 visitor_->OnWriteBlocked();
3110 }
3111 return true;
3112 }
3113
3114 QUIC_DLOG(INFO) << ENDPOINT
3115 << "Sending path probe packet for connection_id = "
dschinazi7b9278c2019-05-20 07:36:21 -07003116 << server_connection_id_;
QUICHE teama6ef0a62019-03-07 20:34:33 -05003117
3118 OwningSerializedPacketPointer probing_packet;
fkastenholz305e1732019-06-18 05:01:22 -07003119 if (!VersionHasIetfQuicFrames(transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003120 // Non-IETF QUIC, generate a padded ping regardless of whether this is a
3121 // request or a response.
3122 probing_packet = packet_generator_.SerializeConnectivityProbingPacket();
3123 } else {
3124 if (is_response) {
3125 // Respond using IETF QUIC PATH_RESPONSE frame
3126 if (IsCurrentPacketConnectivityProbing()) {
3127 // Pad the response if the request was a google connectivity probe
3128 // (padded).
3129 probing_packet =
3130 packet_generator_.SerializePathResponseConnectivityProbingPacket(
3131 received_path_challenge_payloads_, /* is_padded = */ true);
3132 received_path_challenge_payloads_.clear();
3133 } else {
3134 // Do not pad the response if the path challenge was not a google
3135 // connectivity probe.
3136 probing_packet =
3137 packet_generator_.SerializePathResponseConnectivityProbingPacket(
3138 received_path_challenge_payloads_,
3139 /* is_padded = */ false);
3140 received_path_challenge_payloads_.clear();
3141 }
3142 } else {
3143 // Request using IETF QUIC PATH_CHALLENGE frame
3144 transmitted_connectivity_probe_payload_ =
3145 QuicMakeUnique<QuicPathFrameBuffer>();
3146 probing_packet =
3147 packet_generator_.SerializePathChallengeConnectivityProbingPacket(
3148 transmitted_connectivity_probe_payload_.get());
3149 if (!probing_packet) {
3150 transmitted_connectivity_probe_payload_ = nullptr;
3151 }
3152 }
3153 }
3154
3155 DCHECK_EQ(IsRetransmittable(*probing_packet), NO_RETRANSMITTABLE_DATA);
3156
3157 const QuicTime packet_send_time = clock_->Now();
dschinazi965ce092019-05-23 06:29:01 -07003158 QUIC_DVLOG(2) << ENDPOINT
3159 << "Sending path probe packet for server connection ID "
3160 << server_connection_id_ << std::endl
3161 << QuicTextUtils::HexDump(
3162 QuicStringPiece(probing_packet->encrypted_buffer,
3163 probing_packet->encrypted_length));
QUICHE teama6ef0a62019-03-07 20:34:33 -05003164 WriteResult result = probing_writer->WritePacket(
3165 probing_packet->encrypted_buffer, probing_packet->encrypted_length,
3166 self_address().host(), peer_address, per_packet_options_);
3167
3168 // If using a batch writer and the probing packet is buffered, flush it.
3169 if (probing_writer->IsBatchMode() && result.status == WRITE_STATUS_OK &&
3170 result.bytes_written == 0) {
3171 result = probing_writer->Flush();
3172 }
3173
3174 if (IsWriteError(result.status)) {
3175 // Write error for any connectivity probe should not affect the connection
3176 // as it is sent on a different path.
3177 QUIC_DLOG(INFO) << ENDPOINT << "Write probing packet failed with error = "
3178 << result.error_code;
3179 return false;
3180 }
3181
3182 if (debug_visitor_ != nullptr) {
3183 debug_visitor_->OnPacketSent(
3184 *probing_packet, probing_packet->original_packet_number,
3185 probing_packet->transmission_type, packet_send_time);
3186 }
3187
3188 // Call OnPacketSent regardless of the write result.
3189 sent_packet_manager_.OnPacketSent(
3190 probing_packet.get(), probing_packet->original_packet_number,
3191 packet_send_time, probing_packet->transmission_type,
3192 NO_RETRANSMITTABLE_DATA);
3193
3194 if (IsWriteBlockedStatus(result.status)) {
3195 if (probing_writer == writer_) {
3196 // Visitor should not be write blocked if the probing writer is not the
3197 // default packet writer.
3198 visitor_->OnWriteBlocked();
3199 }
3200 if (result.status == WRITE_STATUS_BLOCKED_DATA_BUFFERED) {
3201 QUIC_DLOG(INFO) << ENDPOINT << "Write probing packet blocked";
3202 }
3203 }
3204
3205 return true;
3206}
3207
3208void QuicConnection::DiscoverMtu() {
3209 DCHECK(!mtu_discovery_alarm_->IsSet());
3210
3211 // Check if the MTU has been already increased.
3212 if (mtu_discovery_target_ <= max_packet_length()) {
3213 return;
3214 }
3215
3216 // Calculate the packet number of the next probe *before* sending the current
3217 // one. Otherwise, when SendMtuDiscoveryPacket() is called,
3218 // MaybeSetMtuAlarm() will not realize that the probe has been just sent, and
3219 // will reschedule this probe again.
3220 packets_between_mtu_probes_ *= 2;
3221 next_mtu_probe_at_ = sent_packet_manager_.GetLargestSentPacket() +
3222 packets_between_mtu_probes_ + 1;
3223 ++mtu_probe_count_;
3224
3225 QUIC_DVLOG(2) << "Sending a path MTU discovery packet #" << mtu_probe_count_;
3226 SendMtuDiscoveryPacket(mtu_discovery_target_);
3227
3228 DCHECK(!mtu_discovery_alarm_->IsSet());
3229}
3230
3231void QuicConnection::OnEffectivePeerMigrationValidated() {
3232 if (active_effective_peer_migration_type_ == NO_CHANGE) {
3233 QUIC_BUG << "No migration underway.";
3234 return;
3235 }
3236 highest_packet_sent_before_effective_peer_migration_.Clear();
3237 active_effective_peer_migration_type_ = NO_CHANGE;
3238}
3239
3240void QuicConnection::StartEffectivePeerMigration(AddressChangeType type) {
3241 // TODO(fayang): Currently, all peer address change type are allowed. Need to
3242 // add a method ShouldAllowPeerAddressChange(PeerAddressChangeType type) to
3243 // determine whether |type| is allowed.
3244 if (type == NO_CHANGE) {
3245 QUIC_BUG << "EffectivePeerMigration started without address change.";
3246 return;
3247 }
3248 QUIC_DLOG(INFO) << ENDPOINT << "Effective peer's ip:port changed from "
3249 << effective_peer_address_.ToString() << " to "
3250 << GetEffectivePeerAddressFromCurrentPacket().ToString()
3251 << ", address change type is " << type
3252 << ", migrating connection.";
3253
3254 highest_packet_sent_before_effective_peer_migration_ =
3255 sent_packet_manager_.GetLargestSentPacket();
3256 effective_peer_address_ = GetEffectivePeerAddressFromCurrentPacket();
3257 active_effective_peer_migration_type_ = type;
3258
3259 // TODO(wub): Move these calls to OnEffectivePeerMigrationValidated.
3260 OnConnectionMigration(type);
3261}
3262
3263void QuicConnection::OnConnectionMigration(AddressChangeType addr_change_type) {
3264 visitor_->OnConnectionMigration(addr_change_type);
3265 sent_packet_manager_.OnConnectionMigration(addr_change_type);
3266}
3267
3268bool QuicConnection::IsCurrentPacketConnectivityProbing() const {
3269 return is_current_packet_connectivity_probing_;
3270}
3271
3272bool QuicConnection::ack_frame_updated() const {
fayang5f464302019-06-20 12:57:33 -07003273 return uber_received_packet_manager_.IsAckFrameUpdated();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003274}
3275
3276QuicStringPiece QuicConnection::GetCurrentPacket() {
3277 if (current_packet_data_ == nullptr) {
3278 return QuicStringPiece();
3279 }
3280 return QuicStringPiece(current_packet_data_, last_size_);
3281}
3282
3283bool QuicConnection::MaybeConsiderAsMemoryCorruption(
3284 const QuicStreamFrame& frame) {
nharper46833c32019-05-15 21:33:05 -07003285 if (QuicUtils::IsCryptoStreamId(transport_version(), frame.stream_id) ||
QUICHE team6987b4a2019-03-15 16:23:04 -07003286 last_decrypted_packet_level_ != ENCRYPTION_INITIAL) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003287 return false;
3288 }
3289
3290 if (perspective_ == Perspective::IS_SERVER &&
3291 frame.data_length >= sizeof(kCHLO) &&
3292 strncmp(frame.data_buffer, reinterpret_cast<const char*>(&kCHLO),
3293 sizeof(kCHLO)) == 0) {
3294 return true;
3295 }
3296
3297 if (perspective_ == Perspective::IS_CLIENT &&
3298 frame.data_length >= sizeof(kREJ) &&
3299 strncmp(frame.data_buffer, reinterpret_cast<const char*>(&kREJ),
3300 sizeof(kREJ)) == 0) {
3301 return true;
3302 }
3303
3304 return false;
3305}
3306
3307void QuicConnection::MaybeSendProbingRetransmissions() {
3308 DCHECK(fill_up_link_during_probing_);
3309
3310 // Don't send probing retransmissions until the handshake has completed.
3311 if (!sent_packet_manager_.handshake_confirmed() ||
3312 sent_packet_manager().HasUnackedCryptoPackets()) {
3313 return;
3314 }
3315
3316 if (probing_retransmission_pending_) {
3317 QUIC_BUG << "MaybeSendProbingRetransmissions is called while another call "
3318 "to it is already in progress";
3319 return;
3320 }
3321
3322 probing_retransmission_pending_ = true;
3323 SendProbingRetransmissions();
3324 probing_retransmission_pending_ = false;
3325}
3326
3327void QuicConnection::CheckIfApplicationLimited() {
3328 if (session_decides_what_to_write() && probing_retransmission_pending_) {
3329 return;
3330 }
3331
3332 bool application_limited =
3333 queued_packets_.empty() &&
3334 !sent_packet_manager_.HasPendingRetransmissions() &&
3335 !visitor_->WillingAndAbleToWrite();
3336
3337 if (!application_limited) {
3338 return;
3339 }
3340
3341 if (fill_up_link_during_probing_) {
3342 MaybeSendProbingRetransmissions();
3343 if (!CanWrite(HAS_RETRANSMITTABLE_DATA)) {
3344 return;
3345 }
3346 }
3347
3348 sent_packet_manager_.OnApplicationLimited();
3349}
3350
3351void QuicConnection::UpdatePacketContent(PacketContent type) {
3352 if (current_packet_content_ == NOT_PADDED_PING) {
3353 // We have already learned the current packet is not a connectivity
3354 // probing packet. Peer migration should have already been started earlier
3355 // if needed.
3356 return;
3357 }
3358
3359 if (type == NO_FRAMES_RECEIVED) {
3360 return;
3361 }
3362
3363 if (type == FIRST_FRAME_IS_PING) {
3364 if (current_packet_content_ == NO_FRAMES_RECEIVED) {
3365 current_packet_content_ = FIRST_FRAME_IS_PING;
3366 return;
3367 }
3368 }
3369
3370 // In Google QUIC we look for a packet with just a PING and PADDING.
3371 // For IETF QUIC, the packet must consist of just a PATH_CHALLENGE frame,
3372 // followed by PADDING. If the condition is met, mark things as
3373 // connectivity-probing, causing later processing to generate the correct
3374 // response.
3375 if (type == SECOND_FRAME_IS_PADDING &&
3376 current_packet_content_ == FIRST_FRAME_IS_PING) {
3377 current_packet_content_ = SECOND_FRAME_IS_PADDING;
3378 if (perspective_ == Perspective::IS_SERVER) {
3379 is_current_packet_connectivity_probing_ =
3380 current_effective_peer_migration_type_ != NO_CHANGE;
3381 } else {
3382 is_current_packet_connectivity_probing_ =
3383 (last_packet_source_address_ != peer_address_) ||
3384 (last_packet_destination_address_ != self_address_);
3385 }
3386 return;
3387 }
3388
3389 current_packet_content_ = NOT_PADDED_PING;
QUICHE team1f3de242019-03-20 07:24:48 -07003390 if (GetLargestReceivedPacket().IsInitialized() &&
3391 last_header_.packet_number == GetLargestReceivedPacket()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003392 direct_peer_address_ = last_packet_source_address_;
3393 if (current_effective_peer_migration_type_ != NO_CHANGE) {
3394 // Start effective peer migration immediately when the current packet is
3395 // confirmed not a connectivity probing packet.
QUICHE team1f3de242019-03-20 07:24:48 -07003396 // TODO(fayang): When multiple packet number spaces is supported, only
3397 // start peer migration for the application data.
QUICHE teama6ef0a62019-03-07 20:34:33 -05003398 StartEffectivePeerMigration(current_effective_peer_migration_type_);
3399 }
3400 }
3401 current_effective_peer_migration_type_ = NO_CHANGE;
3402}
3403
3404void QuicConnection::MaybeEnableSessionDecidesWhatToWrite() {
3405 // Only enable session decides what to write code path for version 42+,
3406 // because it needs the receiver to allow receiving overlapping stream data.
3407 const bool enable_session_decides_what_to_write =
3408 transport_version() > QUIC_VERSION_39;
3409 sent_packet_manager_.SetSessionDecideWhatToWrite(
3410 enable_session_decides_what_to_write);
3411 packet_generator_.SetCanSetTransmissionType(
3412 enable_session_decides_what_to_write);
3413}
3414
3415void QuicConnection::PostProcessAfterAckFrame(bool send_stop_waiting,
3416 bool acked_new_packet) {
3417 if (no_stop_waiting_frames_) {
fayang5f464302019-06-20 12:57:33 -07003418 uber_received_packet_manager_.DontWaitForPacketsBefore(
3419 last_decrypted_packet_level_,
fayang39915f92019-07-11 13:08:40 -07003420 SupportsMultiplePacketNumberSpaces()
3421 ? sent_packet_manager_.GetLargestPacketPeerKnowsIsAcked(
3422 last_decrypted_packet_level_)
3423 : sent_packet_manager_.largest_packet_peer_knows_is_acked());
QUICHE teama6ef0a62019-03-07 20:34:33 -05003424 }
3425 // Always reset the retransmission alarm when an ack comes in, since we now
3426 // have a better estimate of the current rtt than when it was set.
3427 SetRetransmissionAlarm();
3428 MaybeSetPathDegradingAlarm(acked_new_packet);
3429
QUICHE teama6ef0a62019-03-07 20:34:33 -05003430 if (send_stop_waiting) {
3431 ++stop_waiting_count_;
3432 } else {
3433 stop_waiting_count_ = 0;
3434 }
3435}
3436
3437void QuicConnection::MaybeSetPathDegradingAlarm(bool acked_new_packet) {
3438 if (!sent_packet_manager_.HasInFlightPackets()) {
3439 // There are no retransmittable packets on the wire, so it's impossible to
3440 // say if the connection has degraded.
3441 path_degrading_alarm_->Cancel();
3442 } else if (acked_new_packet) {
3443 // A previously-unacked packet has been acked, which means forward progress
3444 // has been made. Unset |is_path_degrading| if the path was considered as
3445 // degrading previously. Set/update the path degrading alarm.
3446 is_path_degrading_ = false;
3447 SetPathDegradingAlarm();
3448 }
3449}
3450
3451void QuicConnection::SetSessionNotifier(
3452 SessionNotifierInterface* session_notifier) {
3453 sent_packet_manager_.SetSessionNotifier(session_notifier);
3454}
3455
3456void QuicConnection::SetDataProducer(
3457 QuicStreamFrameDataProducer* data_producer) {
3458 framer_.set_data_producer(data_producer);
3459}
3460
3461void QuicConnection::SetTransmissionType(TransmissionType type) {
3462 packet_generator_.SetTransmissionType(type);
3463}
3464
3465bool QuicConnection::session_decides_what_to_write() const {
3466 return sent_packet_manager_.session_decides_what_to_write();
3467}
3468
3469void QuicConnection::UpdateReleaseTimeIntoFuture() {
3470 DCHECK(supports_release_time_);
3471
3472 release_time_into_future_ = std::max(
3473 QuicTime::Delta::FromMilliseconds(kMinReleaseTimeIntoFutureMs),
3474 std::min(
3475 QuicTime::Delta::FromMilliseconds(
3476 GetQuicFlag(FLAGS_quic_max_pace_time_into_future_ms)),
3477 sent_packet_manager_.GetRttStats()->SmoothedOrInitialRtt() *
3478 GetQuicFlag(FLAGS_quic_pace_time_into_future_srtt_fraction)));
3479}
3480
3481void QuicConnection::ResetAckStates() {
3482 ack_alarm_->Cancel();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003483 stop_waiting_count_ = 0;
fayang5f464302019-06-20 12:57:33 -07003484 uber_received_packet_manager_.ResetAckStates(encryption_level_);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003485}
3486
3487MessageStatus QuicConnection::SendMessage(QuicMessageId message_id,
3488 QuicMemSliceSpan message) {
fayangd4291e42019-05-30 10:31:21 -07003489 if (!VersionSupportsMessageFrames(transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003490 QUIC_BUG << "MESSAGE frame is not supported for version "
3491 << transport_version();
3492 return MESSAGE_STATUS_UNSUPPORTED;
3493 }
ianswettb239f862019-04-05 09:15:06 -07003494 if (message.total_length() > GetCurrentLargestMessagePayload()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003495 return MESSAGE_STATUS_TOO_LARGE;
3496 }
3497 if (!CanWrite(HAS_RETRANSMITTABLE_DATA)) {
3498 return MESSAGE_STATUS_BLOCKED;
3499 }
fayanga4b37b22019-06-18 13:37:47 -07003500 ScopedPacketFlusher flusher(this);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003501 return packet_generator_.AddMessageFrame(message_id, message);
3502}
3503
ianswettb239f862019-04-05 09:15:06 -07003504QuicPacketLength QuicConnection::GetCurrentLargestMessagePayload() const {
3505 return packet_generator_.GetCurrentLargestMessagePayload();
3506}
3507
3508QuicPacketLength QuicConnection::GetGuaranteedLargestMessagePayload() const {
3509 return packet_generator_.GetGuaranteedLargestMessagePayload();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003510}
3511
zhongyi546cc452019-04-12 15:27:49 -07003512uint32_t QuicConnection::cipher_id() const {
3513 if (version().KnowsWhichDecrypterToUse()) {
3514 return framer_.GetDecrypter(last_decrypted_packet_level_)->cipher_id();
3515 }
3516 return framer_.decrypter()->cipher_id();
3517}
3518
QUICHE teama6ef0a62019-03-07 20:34:33 -05003519EncryptionLevel QuicConnection::GetConnectionCloseEncryptionLevel() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003520 if (perspective_ == Perspective::IS_CLIENT) {
3521 return encryption_level_;
3522 }
3523 if (sent_packet_manager_.handshake_confirmed()) {
3524 // A forward secure packet has been received.
dschinazi965ce092019-05-23 06:29:01 -07003525 QUIC_BUG_IF(encryption_level_ != ENCRYPTION_FORWARD_SECURE)
3526 << ENDPOINT << "Unexpected connection close encryption level "
3527 << QuicUtils::EncryptionLevelToString(encryption_level_);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003528 return ENCRYPTION_FORWARD_SECURE;
3529 }
3530 if (framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_ZERO_RTT)) {
3531 if (encryption_level_ != ENCRYPTION_ZERO_RTT) {
fayangd4291e42019-05-30 10:31:21 -07003532 if (VersionHasIetfInvariantHeader(transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003533 QUIC_CODE_COUNT(quic_wrong_encryption_level_connection_close_ietf);
3534 } else {
3535 QUIC_CODE_COUNT(quic_wrong_encryption_level_connection_close);
3536 }
3537 }
3538 return ENCRYPTION_ZERO_RTT;
3539 }
QUICHE team6987b4a2019-03-15 16:23:04 -07003540 return ENCRYPTION_INITIAL;
QUICHE teama6ef0a62019-03-07 20:34:33 -05003541}
3542
QUICHE teamcd098022019-03-22 18:49:55 -07003543void QuicConnection::SendAllPendingAcks() {
3544 DCHECK(SupportsMultiplePacketNumberSpaces());
3545 QUIC_DVLOG(1) << ENDPOINT << "Trying to send all pending ACKs";
3546 // Latches current encryption level.
3547 const EncryptionLevel current_encryption_level = encryption_level_;
3548 for (int8_t i = INITIAL_DATA; i <= APPLICATION_DATA; ++i) {
3549 const QuicTime ack_timeout = uber_received_packet_manager_.GetAckTimeout(
3550 static_cast<PacketNumberSpace>(i));
3551 if (!ack_timeout.IsInitialized() ||
3552 ack_timeout > clock_->ApproximateNow()) {
3553 continue;
3554 }
dschinazi05e62b12019-04-18 15:43:41 -07003555 if (!framer_.HasEncrypterOfEncryptionLevel(
3556 QuicUtils::GetEncryptionLevel(static_cast<PacketNumberSpace>(i)))) {
3557 QUIC_BUG << ENDPOINT << "Cannot send ACKs for packet number space "
3558 << static_cast<uint32_t>(i)
3559 << " without corresponding encrypter";
3560 continue;
3561 }
QUICHE teamcd098022019-03-22 18:49:55 -07003562 QUIC_DVLOG(1) << ENDPOINT << "Sending ACK of packet number space: "
3563 << static_cast<uint32_t>(i);
3564 // Switch to the appropriate encryption level.
3565 SetDefaultEncryptionLevel(
3566 QuicUtils::GetEncryptionLevel(static_cast<PacketNumberSpace>(i)));
3567 QuicFrames frames;
3568 frames.push_back(uber_received_packet_manager_.GetUpdatedAckFrame(
3569 static_cast<PacketNumberSpace>(i), clock_->ApproximateNow()));
3570 const bool flushed = packet_generator_.FlushAckFrame(frames);
3571 if (!flushed) {
3572 // Connection is write blocked.
QUICHE teamdb061532019-03-23 18:23:05 -07003573 QUIC_BUG_IF(!writer_->IsWriteBlocked())
3574 << "Writer not blocked, but ACK not flushed for packet space:" << i;
QUICHE teamcd098022019-03-22 18:49:55 -07003575 break;
3576 }
3577 ResetAckStates();
3578 }
3579 // Restores encryption level.
3580 SetDefaultEncryptionLevel(current_encryption_level);
3581
3582 const QuicTime timeout =
3583 uber_received_packet_manager_.GetEarliestAckTimeout();
3584 if (timeout.IsInitialized()) {
3585 // If there are ACKs pending, re-arm ack alarm.
3586 ack_alarm_->Set(timeout);
3587 }
3588 // Only try to bundle retransmittable data with ACK frame if default
3589 // encryption level is forward secure.
3590 if (encryption_level_ != ENCRYPTION_FORWARD_SECURE ||
3591 consecutive_num_packets_with_no_retransmittable_frames_ <
3592 max_consecutive_num_packets_with_no_retransmittable_frames_) {
3593 return;
3594 }
3595 consecutive_num_packets_with_no_retransmittable_frames_ = 0;
3596 if (packet_generator_.HasRetransmittableFrames() ||
3597 visitor_->WillingAndAbleToWrite()) {
3598 // There are pending retransmittable frames.
3599 return;
3600 }
3601
3602 visitor_->OnAckNeedsRetransmittableFrame();
3603}
3604
3605void QuicConnection::MaybeEnableMultiplePacketNumberSpacesSupport() {
fayangbf3d2862019-06-20 14:13:44 -07003606 if (version().handshake_protocol != PROTOCOL_TLS1_3) {
QUICHE teamcd098022019-03-22 18:49:55 -07003607 return;
3608 }
3609 QUIC_DVLOG(1) << ENDPOINT << "connection " << connection_id()
3610 << " supports multiple packet number spaces";
3611 framer_.EnableMultiplePacketNumberSpacesSupport();
3612 sent_packet_manager_.EnableMultiplePacketNumberSpacesSupport();
3613 uber_received_packet_manager_.EnableMultiplePacketNumberSpacesSupport();
3614}
3615
3616bool QuicConnection::SupportsMultiplePacketNumberSpaces() const {
3617 return sent_packet_manager_.supports_multiple_packet_number_spaces();
3618}
3619
QUICHE team76e1c622019-03-19 14:36:39 -07003620void QuicConnection::SetLargestReceivedPacketWithAck(
3621 QuicPacketNumber new_value) {
QUICHE teamcd098022019-03-22 18:49:55 -07003622 if (SupportsMultiplePacketNumberSpaces()) {
3623 largest_seen_packets_with_ack_[QuicUtils::GetPacketNumberSpace(
3624 last_decrypted_packet_level_)] = new_value;
3625 } else {
3626 largest_seen_packet_with_ack_ = new_value;
3627 }
QUICHE team76e1c622019-03-19 14:36:39 -07003628}
3629
3630QuicPacketNumber QuicConnection::GetLargestReceivedPacketWithAck() const {
QUICHE teamcd098022019-03-22 18:49:55 -07003631 if (SupportsMultiplePacketNumberSpaces()) {
3632 return largest_seen_packets_with_ack_[QuicUtils::GetPacketNumberSpace(
3633 last_decrypted_packet_level_)];
3634 }
QUICHE team76e1c622019-03-19 14:36:39 -07003635 return largest_seen_packet_with_ack_;
3636}
3637
3638QuicPacketNumber QuicConnection::GetLargestSentPacket() const {
QUICHE teamcd098022019-03-22 18:49:55 -07003639 if (SupportsMultiplePacketNumberSpaces()) {
3640 return sent_packet_manager_.GetLargestSentPacket(
3641 last_decrypted_packet_level_);
3642 }
QUICHE team76e1c622019-03-19 14:36:39 -07003643 return sent_packet_manager_.GetLargestSentPacket();
3644}
3645
3646QuicPacketNumber QuicConnection::GetLargestAckedPacket() const {
QUICHE teamcd098022019-03-22 18:49:55 -07003647 if (SupportsMultiplePacketNumberSpaces()) {
3648 return sent_packet_manager_.GetLargestAckedPacket(
3649 last_decrypted_packet_level_);
3650 }
QUICHE team76e1c622019-03-19 14:36:39 -07003651 return sent_packet_manager_.GetLargestObserved();
3652}
3653
QUICHE team1f3de242019-03-20 07:24:48 -07003654QuicPacketNumber QuicConnection::GetLargestReceivedPacket() const {
fayang5f464302019-06-20 12:57:33 -07003655 return uber_received_packet_manager_.GetLargestObserved(
3656 last_decrypted_packet_level_);
QUICHE team1f3de242019-03-20 07:24:48 -07003657}
3658
QUICHE teama6ef0a62019-03-07 20:34:33 -05003659size_t QuicConnection::min_received_before_ack_decimation() const {
fayang5f464302019-06-20 12:57:33 -07003660 return uber_received_packet_manager_.min_received_before_ack_decimation();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003661}
3662
3663void QuicConnection::set_min_received_before_ack_decimation(size_t new_value) {
fayang5f464302019-06-20 12:57:33 -07003664 uber_received_packet_manager_.set_min_received_before_ack_decimation(
3665 new_value);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003666}
3667
3668size_t QuicConnection::ack_frequency_before_ack_decimation() const {
fayang5f464302019-06-20 12:57:33 -07003669 return uber_received_packet_manager_.ack_frequency_before_ack_decimation();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003670}
3671
3672void QuicConnection::set_ack_frequency_before_ack_decimation(size_t new_value) {
3673 DCHECK_GT(new_value, 0u);
fayang5f464302019-06-20 12:57:33 -07003674 uber_received_packet_manager_.set_ack_frequency_before_ack_decimation(
3675 new_value);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003676}
3677
fayang21ffb712019-05-16 08:39:26 -07003678const QuicAckFrame& QuicConnection::ack_frame() const {
3679 if (SupportsMultiplePacketNumberSpaces()) {
3680 return uber_received_packet_manager_.GetAckFrame(
3681 QuicUtils::GetPacketNumberSpace(last_decrypted_packet_level_));
3682 }
fayang5f464302019-06-20 12:57:33 -07003683 return uber_received_packet_manager_.ack_frame();
fayang21ffb712019-05-16 08:39:26 -07003684}
3685
dschinazi346b7ce2019-06-05 01:38:18 -07003686void QuicConnection::set_client_connection_id(
3687 QuicConnectionId client_connection_id) {
3688 if (!version().SupportsClientConnectionIds()) {
3689 QUIC_BUG_IF(!client_connection_id.IsEmpty())
3690 << ENDPOINT << "Attempted to use client connection ID "
3691 << client_connection_id << " with unsupported version " << version();
3692 return;
3693 }
3694 client_connection_id_ = client_connection_id;
3695 client_connection_id_is_set_ = true;
3696 QUIC_DLOG(INFO) << ENDPOINT << "setting client connection ID to "
3697 << client_connection_id_
3698 << " for connection with server connection ID "
3699 << server_connection_id_;
3700 packet_generator_.SetClientConnectionId(client_connection_id_);
3701 framer_.SetExpectedClientConnectionIdLength(client_connection_id_.length());
3702}
3703
QUICHE teama6ef0a62019-03-07 20:34:33 -05003704#undef ENDPOINT // undef for jumbo builds
3705} // namespace quic