blob: ecab75136f0f15b670d6df8347059889f740265e [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 }
428 if (GetQuicReloadableFlag(quic_send_timestamps) &&
429 config.HasClientSentConnectionOption(kSTMP, perspective_)) {
430 QUIC_RELOADABLE_FLAG_COUNT(quic_send_timestamps);
431 framer_.set_process_timestamps(true);
fayang5f464302019-06-20 12:57:33 -0700432 uber_received_packet_manager_.set_save_timestamps(true);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500433 }
434
435 supports_release_time_ =
436 writer_ != nullptr && writer_->SupportsReleaseTime() &&
437 !config.HasClientSentConnectionOption(kNPCO, perspective_);
438
439 if (supports_release_time_) {
440 UpdateReleaseTimeIntoFuture();
441 }
442}
443
444void QuicConnection::OnSendConnectionState(
445 const CachedNetworkParameters& cached_network_params) {
446 if (debug_visitor_ != nullptr) {
447 debug_visitor_->OnSendConnectionState(cached_network_params);
448 }
449}
450
451void QuicConnection::OnReceiveConnectionState(
452 const CachedNetworkParameters& cached_network_params) {
453 if (debug_visitor_ != nullptr) {
454 debug_visitor_->OnReceiveConnectionState(cached_network_params);
455 }
456}
457
458void QuicConnection::ResumeConnectionState(
459 const CachedNetworkParameters& cached_network_params,
460 bool max_bandwidth_resumption) {
461 sent_packet_manager_.ResumeConnectionState(cached_network_params,
462 max_bandwidth_resumption);
463}
464
465void QuicConnection::SetMaxPacingRate(QuicBandwidth max_pacing_rate) {
466 sent_packet_manager_.SetMaxPacingRate(max_pacing_rate);
467}
468
469void QuicConnection::AdjustNetworkParameters(QuicBandwidth bandwidth,
fayangf1b99dc2019-05-14 06:29:18 -0700470 QuicTime::Delta rtt,
471 bool allow_cwnd_to_decrease) {
472 sent_packet_manager_.AdjustNetworkParameters(bandwidth, rtt,
473 allow_cwnd_to_decrease);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500474}
475
476QuicBandwidth QuicConnection::MaxPacingRate() const {
477 return sent_packet_manager_.MaxPacingRate();
478}
479
480bool QuicConnection::SelectMutualVersion(
481 const ParsedQuicVersionVector& available_versions) {
482 // Try to find the highest mutual version by iterating over supported
483 // versions, starting with the highest, and breaking out of the loop once we
484 // find a matching version in the provided available_versions vector.
485 const ParsedQuicVersionVector& supported_versions =
486 framer_.supported_versions();
487 for (size_t i = 0; i < supported_versions.size(); ++i) {
488 const ParsedQuicVersion& version = supported_versions[i];
489 if (QuicContainsValue(available_versions, version)) {
490 framer_.set_version(version);
491 return true;
492 }
493 }
494
495 return false;
496}
497
498void QuicConnection::OnError(QuicFramer* framer) {
499 // Packets that we can not or have not decrypted are dropped.
500 // TODO(rch): add stats to measure this.
501 if (!connected_ || last_packet_decrypted_ == false) {
502 return;
503 }
504 CloseConnection(framer->error(), framer->detailed_error(),
505 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
506}
507
508void QuicConnection::OnPacket() {
509 last_packet_decrypted_ = false;
510}
511
512void QuicConnection::OnPublicResetPacket(const QuicPublicResetPacket& packet) {
513 // Check that any public reset packet with a different connection ID that was
514 // routed to this QuicConnection has been redirected before control reaches
515 // here. (Check for a bug regression.)
dschinazi7b9278c2019-05-20 07:36:21 -0700516 DCHECK_EQ(server_connection_id_, packet.connection_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500517 DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
518 if (debug_visitor_ != nullptr) {
519 debug_visitor_->OnPublicResetPacket(packet);
520 }
vasilvvc48c8712019-03-11 13:38:16 -0700521 std::string error_details = "Received public reset.";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500522 if (perspective_ == Perspective::IS_CLIENT && !packet.endpoint_id.empty()) {
523 QuicStrAppend(&error_details, " From ", packet.endpoint_id, ".");
524 }
525 QUIC_DLOG(INFO) << ENDPOINT << error_details;
526 QUIC_CODE_COUNT(quic_tear_down_local_connection_on_public_reset);
527 TearDownLocalConnectionState(QUIC_PUBLIC_RESET, error_details,
528 ConnectionCloseSource::FROM_PEER);
529}
530
531bool QuicConnection::OnProtocolVersionMismatch(
fayang8aba1ff2019-06-21 12:00:54 -0700532 ParsedQuicVersion received_version) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500533 QUIC_DLOG(INFO) << ENDPOINT << "Received packet with mismatched version "
534 << ParsedQuicVersionToString(received_version);
535 if (perspective_ == Perspective::IS_CLIENT) {
vasilvvc48c8712019-03-11 13:38:16 -0700536 const std::string error_details = "Protocol version mismatch.";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500537 QUIC_BUG << ENDPOINT << error_details;
fkastenholz85f18902019-05-28 12:47:00 -0700538 CloseConnection(QUIC_INTERNAL_ERROR, error_details,
539 ConnectionCloseBehavior::SILENT_CLOSE);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500540 }
541
fayang8aba1ff2019-06-21 12:00:54 -0700542 // Server drops old packets that were sent by the client before the version
543 // was negotiated.
544 return false;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500545}
546
547// Handles version negotiation for client connection.
548void QuicConnection::OnVersionNegotiationPacket(
549 const QuicVersionNegotiationPacket& packet) {
550 // Check that any public reset packet with a different connection ID that was
551 // routed to this QuicConnection has been redirected before control reaches
552 // here. (Check for a bug regression.)
dschinazi7b9278c2019-05-20 07:36:21 -0700553 DCHECK_EQ(server_connection_id_, packet.connection_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500554 if (perspective_ == Perspective::IS_SERVER) {
vasilvvc48c8712019-03-11 13:38:16 -0700555 const std::string error_details =
dschinazi5a354c92019-05-09 12:18:53 -0700556 "Server received version negotiation packet.";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500557 QUIC_BUG << error_details;
558 QUIC_CODE_COUNT(quic_tear_down_local_connection_on_version_negotiation);
fkastenholz85f18902019-05-28 12:47:00 -0700559 CloseConnection(QUIC_INTERNAL_ERROR, error_details,
560 ConnectionCloseBehavior::SILENT_CLOSE);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500561 return;
562 }
563 if (debug_visitor_ != nullptr) {
564 debug_visitor_->OnVersionNegotiationPacket(packet);
565 }
566
fayang8aba1ff2019-06-21 12:00:54 -0700567 if (version_negotiated_) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500568 // Possibly a duplicate version negotiation packet.
569 return;
570 }
571
572 if (QuicContainsValue(packet.versions, version())) {
vasilvvc48c8712019-03-11 13:38:16 -0700573 const std::string error_details =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500574 "Server already supports client's version and should have accepted the "
575 "connection.";
576 QUIC_DLOG(WARNING) << error_details;
fkastenholz85f18902019-05-28 12:47:00 -0700577 CloseConnection(QUIC_INVALID_VERSION_NEGOTIATION_PACKET, error_details,
578 ConnectionCloseBehavior::SILENT_CLOSE);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500579 return;
580 }
581
582 server_supported_versions_ = packet.versions;
fayang9ed391a2019-06-20 11:16:59 -0700583 CloseConnection(
584 QUIC_INVALID_VERSION,
585 QuicStrCat(
586 "Client may support one of the versions in the server's list, but "
587 "it's going to close the connection anyway. Supported versions: {",
588 ParsedQuicVersionVectorToString(framer_.supported_versions()),
589 "}, peer supported versions: {",
590 ParsedQuicVersionVectorToString(packet.versions), "}"),
591 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500592}
593
dschinazi244f6dc2019-05-06 15:45:16 -0700594// Handles retry for client connection.
595void QuicConnection::OnRetryPacket(QuicConnectionId original_connection_id,
596 QuicConnectionId new_connection_id,
597 QuicStringPiece retry_token) {
dschinazi6ece5002019-05-22 06:35:49 -0700598 DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
dschinazi7b9278c2019-05-20 07:36:21 -0700599 if (original_connection_id != server_connection_id_) {
dschinazi244f6dc2019-05-06 15:45:16 -0700600 QUIC_DLOG(ERROR) << "Ignoring RETRY with original connection ID "
601 << original_connection_id << " not matching expected "
dschinazi7b9278c2019-05-20 07:36:21 -0700602 << server_connection_id_ << " token "
dschinazi244f6dc2019-05-06 15:45:16 -0700603 << QuicTextUtils::HexEncode(retry_token);
604 return;
605 }
606 if (retry_has_been_parsed_) {
607 QUIC_DLOG(ERROR) << "Ignoring non-first RETRY with token "
608 << QuicTextUtils::HexEncode(retry_token);
609 return;
610 }
611 retry_has_been_parsed_ = true;
612 QUIC_DLOG(INFO) << "Received RETRY, replacing connection ID "
dschinazi7b9278c2019-05-20 07:36:21 -0700613 << server_connection_id_ << " with " << new_connection_id
dschinazi244f6dc2019-05-06 15:45:16 -0700614 << ", received token "
615 << QuicTextUtils::HexEncode(retry_token);
dschinazi7b9278c2019-05-20 07:36:21 -0700616 server_connection_id_ = new_connection_id;
617 packet_generator_.SetServerConnectionId(server_connection_id_);
dschinazi244f6dc2019-05-06 15:45:16 -0700618 packet_generator_.SetRetryToken(retry_token);
619
620 // Reinstall initial crypters because the connection ID changed.
dschinazi5c030852019-07-11 15:45:53 -0700621 InstallInitialCrypters(server_connection_id_);
dschinazi244f6dc2019-05-06 15:45:16 -0700622}
623
QUICHE teamc65d1d12019-03-19 20:58:04 -0700624bool QuicConnection::HasIncomingConnectionId(QuicConnectionId connection_id) {
625 for (QuicConnectionId const& incoming_connection_id :
626 incoming_connection_ids_) {
627 if (incoming_connection_id == connection_id) {
628 return true;
629 }
630 }
631 return false;
632}
633
634void QuicConnection::AddIncomingConnectionId(QuicConnectionId connection_id) {
635 if (HasIncomingConnectionId(connection_id)) {
636 return;
637 }
638 incoming_connection_ids_.push_back(connection_id);
639}
640
QUICHE teama6ef0a62019-03-07 20:34:33 -0500641bool QuicConnection::OnUnauthenticatedPublicHeader(
642 const QuicPacketHeader& header) {
QUICHE team2252b702019-05-14 23:55:14 -0400643 QuicConnectionId server_connection_id =
644 GetServerConnectionIdAsRecipient(header, perspective_);
645
dschinazi346b7ce2019-06-05 01:38:18 -0700646 if (server_connection_id != server_connection_id_ &&
647 !HasIncomingConnectionId(server_connection_id)) {
648 if (PacketCanReplaceConnectionId(header, perspective_)) {
649 QUIC_DLOG(INFO) << ENDPOINT << "Accepting packet with new connection ID "
650 << server_connection_id << " instead of "
651 << server_connection_id_;
652 return true;
653 }
654
655 ++stats_.packets_dropped;
656 QUIC_DLOG(INFO) << ENDPOINT
657 << "Ignoring packet from unexpected server connection ID "
658 << server_connection_id << " instead of "
659 << server_connection_id_;
660 if (debug_visitor_ != nullptr) {
661 debug_visitor_->OnIncorrectConnectionId(server_connection_id);
662 }
663 // If this is a server, the dispatcher routes each packet to the
664 // QuicConnection responsible for the packet's connection ID. So if control
665 // arrives here and this is a server, the dispatcher must be malfunctioning.
666 DCHECK_NE(Perspective::IS_SERVER, perspective_);
667 return false;
668 }
669
670 if (!version().SupportsClientConnectionIds()) {
QUICHE teamc65d1d12019-03-19 20:58:04 -0700671 return true;
672 }
673
dschinazi346b7ce2019-06-05 01:38:18 -0700674 QuicConnectionId client_connection_id =
675 GetClientConnectionIdAsRecipient(header, perspective_);
676
677 if (client_connection_id == client_connection_id_) {
678 return true;
679 }
680
681 if (!client_connection_id_is_set_ && perspective_ == Perspective::IS_SERVER) {
682 QUIC_DLOG(INFO) << ENDPOINT
683 << "Setting client connection ID from first packet to "
684 << client_connection_id;
685 set_client_connection_id(client_connection_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500686 return true;
687 }
688
689 ++stats_.packets_dropped;
690 QUIC_DLOG(INFO) << ENDPOINT
dschinazi346b7ce2019-06-05 01:38:18 -0700691 << "Ignoring packet from unexpected client connection ID "
692 << client_connection_id << " instead of "
693 << client_connection_id_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500694 return false;
695}
696
697bool QuicConnection::OnUnauthenticatedHeader(const QuicPacketHeader& header) {
698 if (debug_visitor_ != nullptr) {
699 debug_visitor_->OnUnauthenticatedHeader(header);
700 }
701
702 // Check that any public reset packet with a different connection ID that was
703 // routed to this QuicConnection has been redirected before control reaches
704 // here.
QUICHE team2252b702019-05-14 23:55:14 -0400705 DCHECK(GetServerConnectionIdAsRecipient(header, perspective_) ==
dschinazi7b9278c2019-05-20 07:36:21 -0700706 server_connection_id_ ||
QUICHE team2252b702019-05-14 23:55:14 -0400707 HasIncomingConnectionId(
708 GetServerConnectionIdAsRecipient(header, perspective_)) ||
QUICHE teamc65d1d12019-03-19 20:58:04 -0700709 PacketCanReplaceConnectionId(header, perspective_));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500710
fayang914fbe12019-07-11 06:23:55 -0700711 if (packet_generator_.HasPendingFrames()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500712 // Incoming packets may change a queued ACK frame.
vasilvvc48c8712019-03-11 13:38:16 -0700713 const std::string error_details =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500714 "Pending frames must be serialized before incoming packets are "
715 "processed.";
716 QUIC_BUG << error_details << ", received header: " << header;
717 CloseConnection(QUIC_INTERNAL_ERROR, error_details,
718 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
719 return false;
720 }
721
fayang8aba1ff2019-06-21 12:00:54 -0700722 if (!version_negotiated_ && perspective_ == Perspective::IS_SERVER) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500723 if (!header.version_flag) {
724 // Packets should have the version flag till version negotiation is
725 // done.
vasilvvc48c8712019-03-11 13:38:16 -0700726 std::string error_details =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500727 QuicStrCat(ENDPOINT, "Packet ", header.packet_number.ToUint64(),
728 " without version flag before version negotiated.");
729 QUIC_DLOG(WARNING) << error_details;
730 CloseConnection(QUIC_INVALID_VERSION, error_details,
731 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
732 return false;
733 } else {
734 DCHECK_EQ(header.version, version());
fayang8aba1ff2019-06-21 12:00:54 -0700735 version_negotiated_ = true;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500736 framer_.InferPacketHeaderTypeFromVersion();
737 visitor_->OnSuccessfulVersionNegotiation(version());
738 if (debug_visitor_ != nullptr) {
739 debug_visitor_->OnSuccessfulVersionNegotiation(version());
740 }
741 }
fayang8aba1ff2019-06-21 12:00:54 -0700742 DCHECK(version_negotiated_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500743 }
744
745 return true;
746}
747
748void QuicConnection::OnDecryptedPacket(EncryptionLevel level) {
749 last_decrypted_packet_level_ = level;
750 last_packet_decrypted_ = true;
751
752 // Once the server receives a forward secure packet, the handshake is
753 // confirmed.
754 if (level == ENCRYPTION_FORWARD_SECURE &&
755 perspective_ == Perspective::IS_SERVER) {
756 sent_packet_manager_.SetHandshakeConfirmed();
fayangbf3d2862019-06-20 14:13:44 -0700757 // This may have changed the retransmission timer, so re-arm it.
758 SetRetransmissionAlarm();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500759 }
760}
761
762QuicSocketAddress QuicConnection::GetEffectivePeerAddressFromCurrentPacket()
763 const {
764 // By default, the connection is not proxied, and the effective peer address
765 // is the packet's source address, i.e. the direct peer address.
766 return last_packet_source_address_;
767}
768
769bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) {
770 if (debug_visitor_ != nullptr) {
771 debug_visitor_->OnPacketHeader(header);
772 }
773
774 // Will be decremented below if we fall through to return true.
775 ++stats_.packets_dropped;
776
777 if (!ProcessValidatedPacket(header)) {
778 return false;
779 }
780
781 // Initialize the current packet content state.
782 current_packet_content_ = NO_FRAMES_RECEIVED;
783 is_current_packet_connectivity_probing_ = false;
784 current_effective_peer_migration_type_ = NO_CHANGE;
785
786 if (perspective_ == Perspective::IS_CLIENT) {
QUICHE team1f3de242019-03-20 07:24:48 -0700787 if (!GetLargestReceivedPacket().IsInitialized() ||
788 header.packet_number > GetLargestReceivedPacket()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500789 // Update peer_address_ and effective_peer_address_ immediately for
790 // client connections.
QUICHE team1f3de242019-03-20 07:24:48 -0700791 // TODO(fayang): only change peer addresses in application data packet
792 // number space.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500793 direct_peer_address_ = last_packet_source_address_;
794 effective_peer_address_ = GetEffectivePeerAddressFromCurrentPacket();
795 }
796 } else {
797 // At server, remember the address change type of effective_peer_address
798 // in current_effective_peer_migration_type_. But this variable alone
799 // doesn't necessarily starts a migration. A migration will be started
800 // later, once the current packet is confirmed to meet the following
801 // conditions:
802 // 1) current_effective_peer_migration_type_ is not NO_CHANGE.
803 // 2) The current packet is not a connectivity probing.
804 // 3) The current packet is not reordered, i.e. its packet number is the
805 // largest of this connection so far.
806 // Once the above conditions are confirmed, a new migration will start
807 // even if there is an active migration underway.
808 current_effective_peer_migration_type_ =
809 QuicUtils::DetermineAddressChangeType(
810 effective_peer_address_,
811 GetEffectivePeerAddressFromCurrentPacket());
812
813 QUIC_DLOG_IF(INFO, current_effective_peer_migration_type_ != NO_CHANGE)
814 << ENDPOINT << "Effective peer's ip:port changed from "
815 << effective_peer_address_.ToString() << " to "
816 << GetEffectivePeerAddressFromCurrentPacket().ToString()
817 << ", active_effective_peer_migration_type is "
818 << active_effective_peer_migration_type_;
819 }
820
821 --stats_.packets_dropped;
822 QUIC_DVLOG(1) << ENDPOINT << "Received packet header: " << header;
823 last_header_ = header;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500824
825 // Record packet receipt to populate ack info before processing stream
826 // frames, since the processing may result in sending a bundled ack.
fayang5f464302019-06-20 12:57:33 -0700827 uber_received_packet_manager_.RecordPacketReceived(
828 last_decrypted_packet_level_, last_header_,
829 time_of_last_received_packet_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500830 DCHECK(connected_);
831 return true;
832}
833
834bool QuicConnection::OnStreamFrame(const QuicStreamFrame& frame) {
835 DCHECK(connected_);
836
837 // Since a stream frame was received, this is not a connectivity probe.
838 // A probe only contains a PING and full padding.
839 UpdatePacketContent(NOT_PADDED_PING);
840
841 if (debug_visitor_ != nullptr) {
842 debug_visitor_->OnStreamFrame(frame);
843 }
nharper46833c32019-05-15 21:33:05 -0700844 if (!QuicUtils::IsCryptoStreamId(transport_version(), frame.stream_id) &&
QUICHE team6987b4a2019-03-15 16:23:04 -0700845 last_decrypted_packet_level_ == ENCRYPTION_INITIAL) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500846 if (MaybeConsiderAsMemoryCorruption(frame)) {
847 CloseConnection(QUIC_MAYBE_CORRUPTED_MEMORY,
848 "Received crypto frame on non crypto stream.",
849 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
850 return false;
851 }
852
853 QUIC_PEER_BUG << ENDPOINT
854 << "Received an unencrypted data frame: closing connection"
855 << " packet_number:" << last_header_.packet_number
QUICHE teamb23daa72019-03-21 08:37:48 -0700856 << " stream_id:" << frame.stream_id
fayang21ffb712019-05-16 08:39:26 -0700857 << " received_packets:" << ack_frame();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500858 CloseConnection(QUIC_UNENCRYPTED_STREAM_DATA,
859 "Unencrypted stream data seen.",
860 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
861 return false;
862 }
863 visitor_->OnStreamFrame(frame);
864 stats_.stream_bytes_received += frame.data_length;
865 should_last_packet_instigate_acks_ = true;
866 return connected_;
867}
868
869bool QuicConnection::OnCryptoFrame(const QuicCryptoFrame& frame) {
870 DCHECK(connected_);
871
872 // Since a CRYPTO frame was received, this is not a connectivity probe.
873 // A probe only contains a PING and full padding.
874 UpdatePacketContent(NOT_PADDED_PING);
875
876 visitor_->OnCryptoFrame(frame);
877 should_last_packet_instigate_acks_ = true;
878 return connected_;
879}
880
881bool QuicConnection::OnAckFrameStart(QuicPacketNumber largest_acked,
882 QuicTime::Delta ack_delay_time) {
883 DCHECK(connected_);
884
885 if (processing_ack_frame_) {
886 CloseConnection(QUIC_INVALID_ACK_DATA,
887 "Received a new ack while processing an ack frame.",
888 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
889 return false;
890 }
891
892 // Since an ack frame was received, this is not a connectivity probe.
893 // A probe only contains a PING and full padding.
894 UpdatePacketContent(NOT_PADDED_PING);
895
896 QUIC_DVLOG(1) << ENDPOINT
897 << "OnAckFrameStart, largest_acked: " << largest_acked;
898
QUICHE team76e1c622019-03-19 14:36:39 -0700899 if (GetLargestReceivedPacketWithAck().IsInitialized() &&
900 last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500901 QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
902 return true;
903 }
904
QUICHE team76e1c622019-03-19 14:36:39 -0700905 if (!GetLargestSentPacket().IsInitialized() ||
906 largest_acked > GetLargestSentPacket()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500907 QUIC_DLOG(WARNING) << ENDPOINT
908 << "Peer's observed unsent packet:" << largest_acked
QUICHE team76e1c622019-03-19 14:36:39 -0700909 << " vs " << GetLargestSentPacket();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500910 // We got an ack for data we have not sent.
911 CloseConnection(QUIC_INVALID_ACK_DATA, "Largest observed too high.",
912 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
913 return false;
914 }
915
QUICHE team76e1c622019-03-19 14:36:39 -0700916 if (!GetLargestAckedPacket().IsInitialized() ||
917 largest_acked > GetLargestAckedPacket()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500918 visitor_->OnForwardProgressConfirmed();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500919 }
920 processing_ack_frame_ = true;
921 sent_packet_manager_.OnAckFrameStart(largest_acked, ack_delay_time,
922 time_of_last_received_packet_);
923 return true;
924}
925
926bool QuicConnection::OnAckRange(QuicPacketNumber start, QuicPacketNumber end) {
927 DCHECK(connected_);
928 QUIC_DVLOG(1) << ENDPOINT << "OnAckRange: [" << start << ", " << end << ")";
929
QUICHE team76e1c622019-03-19 14:36:39 -0700930 if (GetLargestReceivedPacketWithAck().IsInitialized() &&
931 last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500932 QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
933 return true;
934 }
935
936 sent_packet_manager_.OnAckRange(start, end);
937 return true;
938}
939
940bool QuicConnection::OnAckTimestamp(QuicPacketNumber packet_number,
941 QuicTime timestamp) {
942 DCHECK(connected_);
943 QUIC_DVLOG(1) << ENDPOINT << "OnAckTimestamp: [" << packet_number << ", "
944 << timestamp.ToDebuggingValue() << ")";
945
QUICHE team76e1c622019-03-19 14:36:39 -0700946 if (GetLargestReceivedPacketWithAck().IsInitialized() &&
947 last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500948 QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
949 return true;
950 }
951
952 sent_packet_manager_.OnAckTimestamp(packet_number, timestamp);
953 return true;
954}
955
956bool QuicConnection::OnAckFrameEnd(QuicPacketNumber start) {
957 DCHECK(connected_);
958 QUIC_DVLOG(1) << ENDPOINT << "OnAckFrameEnd, start: " << start;
959
QUICHE team76e1c622019-03-19 14:36:39 -0700960 if (GetLargestReceivedPacketWithAck().IsInitialized() &&
961 last_header_.packet_number <= GetLargestReceivedPacketWithAck()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500962 QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
963 return true;
964 }
fayang3eb82212019-04-16 12:05:46 -0700965 const AckResult ack_result = sent_packet_manager_.OnAckFrameEnd(
fayangf8e918b2019-07-16 13:03:16 -0700966 time_of_last_received_packet_, last_header_.packet_number,
967 last_decrypted_packet_level_);
fayang3eb82212019-04-16 12:05:46 -0700968 if (ack_result != PACKETS_NEWLY_ACKED &&
969 ack_result != NO_PACKETS_NEWLY_ACKED) {
970 // Error occurred (e.g., this ACK tries to ack packets in wrong packet
971 // number space), and this would cause the connection to be closed.
972 QUIC_DLOG(ERROR) << ENDPOINT
973 << "Error occurred when processing an ACK frame: "
974 << QuicUtils::AckResultToString(ack_result);
975 return false;
976 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500977 // Cancel the send alarm because new packets likely have been acked, which
978 // may change the congestion window and/or pacing rate. Canceling the alarm
979 // causes CanWrite to recalculate the next send time.
980 if (send_alarm_->IsSet()) {
981 send_alarm_->Cancel();
982 }
983 if (supports_release_time_) {
984 // Update pace time into future because smoothed RTT is likely updated.
985 UpdateReleaseTimeIntoFuture();
986 }
QUICHE team76e1c622019-03-19 14:36:39 -0700987 SetLargestReceivedPacketWithAck(last_header_.packet_number);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500988 // If the incoming ack's packets set expresses missing packets: peer is still
989 // waiting for a packet lower than a packet that we are no longer planning to
990 // send.
991 // If the incoming ack's packets set expresses received packets: peer is still
992 // acking packets which we never care about.
993 // Send an ack to raise the high water mark.
fayangd317e3a2019-07-08 10:33:40 -0700994 const bool send_stop_waiting =
995 no_stop_waiting_frames_ ? false : GetLeastUnacked() > start;
fayang03916692019-05-22 17:57:18 -0700996 PostProcessAfterAckFrame(send_stop_waiting,
fayang3eb82212019-04-16 12:05:46 -0700997 ack_result == PACKETS_NEWLY_ACKED);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500998 processing_ack_frame_ = false;
999
1000 return connected_;
1001}
1002
1003bool QuicConnection::OnStopWaitingFrame(const QuicStopWaitingFrame& frame) {
1004 DCHECK(connected_);
1005
1006 // Since a stop waiting frame was received, this is not a connectivity probe.
1007 // A probe only contains a PING and full padding.
1008 UpdatePacketContent(NOT_PADDED_PING);
1009
1010 if (no_stop_waiting_frames_) {
1011 return true;
1012 }
1013 if (largest_seen_packet_with_stop_waiting_.IsInitialized() &&
1014 last_header_.packet_number <= largest_seen_packet_with_stop_waiting_) {
1015 QUIC_DLOG(INFO) << ENDPOINT
1016 << "Received an old stop waiting frame: ignoring";
1017 return true;
1018 }
1019
1020 const char* error = ValidateStopWaitingFrame(frame);
1021 if (error != nullptr) {
1022 CloseConnection(QUIC_INVALID_STOP_WAITING_DATA, error,
1023 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
1024 return false;
1025 }
1026
1027 if (debug_visitor_ != nullptr) {
1028 debug_visitor_->OnStopWaitingFrame(frame);
1029 }
1030
1031 largest_seen_packet_with_stop_waiting_ = last_header_.packet_number;
fayang5f464302019-06-20 12:57:33 -07001032 uber_received_packet_manager_.DontWaitForPacketsBefore(
1033 last_decrypted_packet_level_, frame.least_unacked);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001034 return connected_;
1035}
1036
1037bool QuicConnection::OnPaddingFrame(const QuicPaddingFrame& frame) {
1038 DCHECK(connected_);
1039 UpdatePacketContent(SECOND_FRAME_IS_PADDING);
1040
1041 if (debug_visitor_ != nullptr) {
1042 debug_visitor_->OnPaddingFrame(frame);
1043 }
1044 return true;
1045}
1046
1047bool QuicConnection::OnPingFrame(const QuicPingFrame& frame) {
1048 DCHECK(connected_);
1049 UpdatePacketContent(FIRST_FRAME_IS_PING);
1050
1051 if (debug_visitor_ != nullptr) {
1052 debug_visitor_->OnPingFrame(frame);
1053 }
1054 should_last_packet_instigate_acks_ = true;
1055 return true;
1056}
1057
QUICHE teama6ef0a62019-03-07 20:34:33 -05001058const char* QuicConnection::ValidateStopWaitingFrame(
1059 const QuicStopWaitingFrame& stop_waiting) {
QUICHE teamb23daa72019-03-21 08:37:48 -07001060 const QuicPacketNumber peer_least_packet_awaiting_ack =
fayang5f464302019-06-20 12:57:33 -07001061 uber_received_packet_manager_.peer_least_packet_awaiting_ack();
QUICHE teamb23daa72019-03-21 08:37:48 -07001062 if (peer_least_packet_awaiting_ack.IsInitialized() &&
1063 stop_waiting.least_unacked < peer_least_packet_awaiting_ack) {
1064 QUIC_DLOG(ERROR) << ENDPOINT << "Peer's sent low least_unacked: "
1065 << stop_waiting.least_unacked << " vs "
1066 << peer_least_packet_awaiting_ack;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001067 // We never process old ack frames, so this number should only increase.
1068 return "Least unacked too small.";
1069 }
1070
1071 if (stop_waiting.least_unacked > last_header_.packet_number) {
1072 QUIC_DLOG(ERROR) << ENDPOINT
1073 << "Peer sent least_unacked:" << stop_waiting.least_unacked
1074 << " greater than the enclosing packet number:"
1075 << last_header_.packet_number;
1076 return "Least unacked too large.";
1077 }
1078
1079 return nullptr;
1080}
1081
1082bool QuicConnection::OnRstStreamFrame(const QuicRstStreamFrame& frame) {
1083 DCHECK(connected_);
1084
1085 // Since a reset stream frame was received, this is not a connectivity probe.
1086 // A probe only contains a PING and full padding.
1087 UpdatePacketContent(NOT_PADDED_PING);
1088
1089 if (debug_visitor_ != nullptr) {
1090 debug_visitor_->OnRstStreamFrame(frame);
1091 }
1092 QUIC_DLOG(INFO) << ENDPOINT
1093 << "RST_STREAM_FRAME received for stream: " << frame.stream_id
1094 << " with error: "
1095 << QuicRstStreamErrorCodeToString(frame.error_code);
1096 visitor_->OnRstStream(frame);
1097 should_last_packet_instigate_acks_ = true;
1098 return connected_;
1099}
1100
QUICHE teama6ef0a62019-03-07 20:34:33 -05001101bool QuicConnection::OnStopSendingFrame(const QuicStopSendingFrame& frame) {
1102 DCHECK(connected_);
1103
1104 // Since a reset stream frame was received, this is not a connectivity probe.
1105 // A probe only contains a PING and full padding.
1106 UpdatePacketContent(NOT_PADDED_PING);
1107
1108 if (debug_visitor_ != nullptr) {
1109 debug_visitor_->OnStopSendingFrame(frame);
1110 }
1111
1112 QUIC_DLOG(INFO) << ENDPOINT << "STOP_SENDING frame received for stream: "
1113 << frame.stream_id
1114 << " with error: " << frame.application_error_code;
1115
1116 visitor_->OnStopSendingFrame(frame);
1117 return connected_;
1118}
1119
1120bool QuicConnection::OnPathChallengeFrame(const QuicPathChallengeFrame& frame) {
1121 // Save the path challenge's payload, for later use in generating the
1122 // response.
1123 received_path_challenge_payloads_.push_back(frame.data_buffer);
1124
1125 // For VERSION 99 we define a "Padded PATH CHALLENGE" to be the same thing
1126 // as a PADDED PING -- it will start a connectivity check and prevent
1127 // connection migration. Insofar as the connectivity check and connection
1128 // migration are concerned, logically the PATH CHALLENGE is the same as the
1129 // PING, so as a stopgap, tell the FSM that determines whether we have a
1130 // Padded PING or not that we received a PING.
1131 UpdatePacketContent(FIRST_FRAME_IS_PING);
1132 should_last_packet_instigate_acks_ = true;
1133 return true;
1134}
1135
1136bool QuicConnection::OnPathResponseFrame(const QuicPathResponseFrame& frame) {
1137 should_last_packet_instigate_acks_ = true;
1138 if (!transmitted_connectivity_probe_payload_ ||
1139 *transmitted_connectivity_probe_payload_ != frame.data_buffer) {
1140 // Is not for the probe we sent, ignore it.
1141 return true;
1142 }
1143 // Have received the matching PATH RESPONSE, saved payload no longer valid.
1144 transmitted_connectivity_probe_payload_ = nullptr;
1145 UpdatePacketContent(FIRST_FRAME_IS_PING);
1146 return true;
1147}
1148
1149bool QuicConnection::OnConnectionCloseFrame(
1150 const QuicConnectionCloseFrame& frame) {
1151 DCHECK(connected_);
1152
1153 // Since a connection close frame was received, this is not a connectivity
1154 // probe. A probe only contains a PING and full padding.
1155 UpdatePacketContent(NOT_PADDED_PING);
1156
1157 if (debug_visitor_ != nullptr) {
1158 debug_visitor_->OnConnectionCloseFrame(frame);
1159 }
1160 QUIC_DLOG(INFO) << ENDPOINT << "Received ConnectionClose for connection: "
fkastenholze9d71a82019-04-09 05:12:13 -07001161 << connection_id() << ", with error: "
1162 << QuicErrorCodeToString(frame.quic_error_code) << " ("
1163 << frame.error_details << ")";
1164 if (frame.close_type == GOOGLE_QUIC_CONNECTION_CLOSE &&
1165 frame.quic_error_code == QUIC_BAD_MULTIPATH_FLAG) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001166 QUIC_LOG_FIRST_N(ERROR, 10) << "Unexpected QUIC_BAD_MULTIPATH_FLAG error."
1167 << " last_received_header: " << last_header_
1168 << " encryption_level: " << encryption_level_;
1169 }
fkastenholze9d71a82019-04-09 05:12:13 -07001170 TearDownLocalConnectionState(frame.quic_error_code, frame.error_details,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001171 ConnectionCloseSource::FROM_PEER);
1172 return connected_;
1173}
1174
fkastenholz3c4eabf2019-04-22 07:49:59 -07001175bool QuicConnection::OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) {
1176 return visitor_->OnMaxStreamsFrame(frame);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001177}
1178
fkastenholz3c4eabf2019-04-22 07:49:59 -07001179bool QuicConnection::OnStreamsBlockedFrame(
1180 const QuicStreamsBlockedFrame& frame) {
1181 return visitor_->OnStreamsBlockedFrame(frame);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001182}
1183
1184bool QuicConnection::OnGoAwayFrame(const QuicGoAwayFrame& frame) {
1185 DCHECK(connected_);
1186
1187 // Since a go away frame was received, this is not a connectivity probe.
1188 // A probe only contains a PING and full padding.
1189 UpdatePacketContent(NOT_PADDED_PING);
1190
1191 if (debug_visitor_ != nullptr) {
1192 debug_visitor_->OnGoAwayFrame(frame);
1193 }
1194 QUIC_DLOG(INFO) << ENDPOINT << "GOAWAY_FRAME received with last good stream: "
1195 << frame.last_good_stream_id
1196 << " and error: " << QuicErrorCodeToString(frame.error_code)
1197 << " and reason: " << frame.reason_phrase;
1198
1199 visitor_->OnGoAway(frame);
1200 should_last_packet_instigate_acks_ = true;
1201 return connected_;
1202}
1203
1204bool QuicConnection::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
1205 DCHECK(connected_);
1206
1207 // Since a window update frame was received, this is not a connectivity probe.
1208 // A probe only contains a PING and full padding.
1209 UpdatePacketContent(NOT_PADDED_PING);
1210
1211 if (debug_visitor_ != nullptr) {
1212 debug_visitor_->OnWindowUpdateFrame(frame, time_of_last_received_packet_);
1213 }
1214 QUIC_DLOG(INFO) << ENDPOINT << "WINDOW_UPDATE_FRAME received for stream: "
1215 << frame.stream_id
1216 << " with byte offset: " << frame.byte_offset;
1217 visitor_->OnWindowUpdateFrame(frame);
1218 should_last_packet_instigate_acks_ = true;
1219 return connected_;
1220}
1221
1222bool QuicConnection::OnNewConnectionIdFrame(
dschinazi17d42422019-06-18 16:35:07 -07001223 const QuicNewConnectionIdFrame& /*frame*/) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001224 return true;
1225}
1226
1227bool QuicConnection::OnRetireConnectionIdFrame(
dschinazi17d42422019-06-18 16:35:07 -07001228 const QuicRetireConnectionIdFrame& /*frame*/) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001229 return true;
1230}
1231
dschinazi17d42422019-06-18 16:35:07 -07001232bool QuicConnection::OnNewTokenFrame(const QuicNewTokenFrame& /*frame*/) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001233 return true;
1234}
1235
1236bool QuicConnection::OnMessageFrame(const QuicMessageFrame& frame) {
1237 DCHECK(connected_);
1238
1239 // Since a message frame was received, this is not a connectivity probe.
1240 // A probe only contains a PING and full padding.
1241 UpdatePacketContent(NOT_PADDED_PING);
1242
1243 if (debug_visitor_ != nullptr) {
1244 debug_visitor_->OnMessageFrame(frame);
1245 }
1246 visitor_->OnMessageReceived(
1247 QuicStringPiece(frame.data, frame.message_length));
1248 should_last_packet_instigate_acks_ = true;
1249 return connected_;
1250}
1251
1252bool QuicConnection::OnBlockedFrame(const QuicBlockedFrame& frame) {
1253 DCHECK(connected_);
1254
1255 // Since a blocked frame was received, this is not a connectivity probe.
1256 // A probe only contains a PING and full padding.
1257 UpdatePacketContent(NOT_PADDED_PING);
1258
1259 if (debug_visitor_ != nullptr) {
1260 debug_visitor_->OnBlockedFrame(frame);
1261 }
1262 QUIC_DLOG(INFO) << ENDPOINT
1263 << "BLOCKED_FRAME received for stream: " << frame.stream_id;
1264 visitor_->OnBlockedFrame(frame);
1265 stats_.blocked_frames_received++;
1266 should_last_packet_instigate_acks_ = true;
1267 return connected_;
1268}
1269
1270void QuicConnection::OnPacketComplete() {
1271 // Don't do anything if this packet closed the connection.
1272 if (!connected_) {
1273 ClearLastFrames();
1274 return;
1275 }
1276
1277 if (IsCurrentPacketConnectivityProbing()) {
1278 ++stats_.num_connectivity_probing_received;
1279 }
1280
1281 QUIC_DVLOG(1) << ENDPOINT << "Got packet " << last_header_.packet_number
QUICHE team2252b702019-05-14 23:55:14 -04001282 << " for "
1283 << GetServerConnectionIdAsRecipient(last_header_, perspective_);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001284
1285 QUIC_DLOG_IF(INFO, current_packet_content_ == SECOND_FRAME_IS_PADDING)
1286 << ENDPOINT << "Received a padded PING packet. is_probing: "
1287 << IsCurrentPacketConnectivityProbing();
1288
1289 if (perspective_ == Perspective::IS_CLIENT) {
1290 QUIC_DVLOG(1) << ENDPOINT
1291 << "Received a speculative connectivity probing packet for "
QUICHE team2252b702019-05-14 23:55:14 -04001292 << GetServerConnectionIdAsRecipient(last_header_,
1293 perspective_)
QUICHE teama6ef0a62019-03-07 20:34:33 -05001294 << " from ip:port: " << last_packet_source_address_.ToString()
1295 << " to ip:port: "
1296 << last_packet_destination_address_.ToString();
1297 // TODO(zhongyi): change the method name.
1298 visitor_->OnConnectivityProbeReceived(last_packet_destination_address_,
1299 last_packet_source_address_);
1300 } else if (IsCurrentPacketConnectivityProbing()) {
1301 // This node is not a client (is a server) AND the received packet was
1302 // connectivity-probing, send an appropriate response.
1303 QUIC_DVLOG(1) << ENDPOINT << "Received a connectivity probing packet for "
QUICHE team2252b702019-05-14 23:55:14 -04001304 << GetServerConnectionIdAsRecipient(last_header_,
1305 perspective_)
QUICHE teama6ef0a62019-03-07 20:34:33 -05001306 << " from ip:port: " << last_packet_source_address_.ToString()
1307 << " to ip:port: "
1308 << last_packet_destination_address_.ToString();
1309 visitor_->OnConnectivityProbeReceived(last_packet_destination_address_,
1310 last_packet_source_address_);
1311 } else {
1312 // This node is not a client (is a server) AND the received packet was
1313 // NOT connectivity-probing. If the packet had PATH CHALLENGES, send
1314 // appropriate RESPONSE. Then deal with possible peer migration.
fkastenholz305e1732019-06-18 05:01:22 -07001315 if (VersionHasIetfQuicFrames(transport_version()) &&
QUICHE teama6ef0a62019-03-07 20:34:33 -05001316 !received_path_challenge_payloads_.empty()) {
1317 // If a PATH CHALLENGE was in a "Padded PING (or PATH CHALLENGE)"
1318 // then it is taken care of above. This handles the case where a PATH
1319 // CHALLENGE appeared someplace else (eg, the peer randomly added a PATH
1320 // CHALLENGE frame to some other packet.
1321 // There was at least one PATH CHALLENGE in the received packet,
1322 // Generate the required PATH RESPONSE.
1323 SendGenericPathProbePacket(nullptr, last_packet_source_address_,
1324 /* is_response= */ true);
1325 }
1326
QUICHE team1f3de242019-03-20 07:24:48 -07001327 if (last_header_.packet_number == GetLargestReceivedPacket()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001328 direct_peer_address_ = last_packet_source_address_;
1329 if (current_effective_peer_migration_type_ != NO_CHANGE) {
QUICHE team1f3de242019-03-20 07:24:48 -07001330 // TODO(fayang): When multiple packet number spaces is supported, only
1331 // start peer migration for the application data.
QUICHE teama6ef0a62019-03-07 20:34:33 -05001332 StartEffectivePeerMigration(current_effective_peer_migration_type_);
1333 }
1334 }
1335 }
1336
1337 current_effective_peer_migration_type_ = NO_CHANGE;
1338
fayang5f464302019-06-20 12:57:33 -07001339 // Some encryption levels share a packet number space, it is therefore
1340 // possible for us to want to ack some packets even though we do not yet
1341 // have the appropriate keys to encrypt the acks. In this scenario we
1342 // do not update the ACK timeout. This can happen for example with
1343 // IETF QUIC on the server when we receive 0-RTT packets and do not yet
1344 // have 1-RTT keys (0-RTT packets are acked at the 1-RTT level).
1345 // Note that this could cause slight performance degradations in the edge
1346 // case where one packet is received, then the encrypter is installed,
1347 // then a second packet is received; as that could cause the ACK for the
1348 // second packet to be delayed instead of immediate. This is currently
1349 // considered to be small enough of an edge case to not be optimized for.
1350 if (!SupportsMultiplePacketNumberSpaces() ||
1351 framer_.HasEncrypterOfEncryptionLevel(QuicUtils::GetEncryptionLevel(
1352 QuicUtils::GetPacketNumberSpace(last_decrypted_packet_level_)))) {
1353 uber_received_packet_manager_.MaybeUpdateAckTimeout(
1354 should_last_packet_instigate_acks_, last_decrypted_packet_level_,
1355 last_header_.packet_number, time_of_last_received_packet_,
1356 clock_->ApproximateNow(), sent_packet_manager_.GetRttStats(),
fkastenholz59c653b2019-07-15 09:55:53 -07001357 sent_packet_manager_.local_max_ack_delay());
fayang5f464302019-06-20 12:57:33 -07001358 } else {
1359 QUIC_DLOG(INFO) << ENDPOINT << "Not updating ACK timeout for "
1360 << QuicUtils::EncryptionLevelToString(
1361 last_decrypted_packet_level_)
1362 << " as we do not have the corresponding encrypter";
QUICHE teama6ef0a62019-03-07 20:34:33 -05001363 }
1364
1365 ClearLastFrames();
1366 CloseIfTooManyOutstandingSentPackets();
1367}
1368
1369bool QuicConnection::IsValidStatelessResetToken(QuicUint128 token) const {
1370 return stateless_reset_token_received_ &&
1371 token == received_stateless_reset_token_;
1372}
1373
1374void QuicConnection::OnAuthenticatedIetfStatelessResetPacket(
dschinazi17d42422019-06-18 16:35:07 -07001375 const QuicIetfStatelessResetPacket& /*packet*/) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001376 // TODO(fayang): Add OnAuthenticatedIetfStatelessResetPacket to
1377 // debug_visitor_.
vasilvvc48c8712019-03-11 13:38:16 -07001378 const std::string error_details = "Received stateless reset.";
QUICHE teama6ef0a62019-03-07 20:34:33 -05001379 QUIC_CODE_COUNT(quic_tear_down_local_connection_on_stateless_reset);
1380 TearDownLocalConnectionState(QUIC_PUBLIC_RESET, error_details,
1381 ConnectionCloseSource::FROM_PEER);
1382}
1383
QUICHE teama6ef0a62019-03-07 20:34:33 -05001384void QuicConnection::ClearLastFrames() {
1385 should_last_packet_instigate_acks_ = false;
1386}
1387
1388void QuicConnection::CloseIfTooManyOutstandingSentPackets() {
1389 // This occurs if we don't discard old packets we've seen fast enough. It's
1390 // possible largest observed is less than leaset unacked.
1391 if (sent_packet_manager_.GetLargestObserved().IsInitialized() &&
1392 sent_packet_manager_.GetLargestObserved() >
1393 sent_packet_manager_.GetLeastUnacked() + max_tracked_packets_) {
1394 CloseConnection(
1395 QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS,
fayang75d23962019-06-03 08:35:49 -07001396 QuicStrCat(
1397 "More than ", max_tracked_packets_, " outstanding, least_unacked: ",
1398 sent_packet_manager_.GetLeastUnacked().ToUint64(),
1399 ", packets_processed: ", stats_.packets_processed,
1400 ", last_decrypted_packet_level: ",
1401 QuicUtils::EncryptionLevelToString(last_decrypted_packet_level_)),
QUICHE teama6ef0a62019-03-07 20:34:33 -05001402 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
1403 }
1404}
1405
1406const QuicFrame QuicConnection::GetUpdatedAckFrame() {
fayang5f464302019-06-20 12:57:33 -07001407 return uber_received_packet_manager_.GetUpdatedAckFrame(
1408 QuicUtils::GetPacketNumberSpace(encryption_level_),
1409 clock_->ApproximateNow());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001410}
1411
1412void QuicConnection::PopulateStopWaitingFrame(
1413 QuicStopWaitingFrame* stop_waiting) {
1414 stop_waiting->least_unacked = GetLeastUnacked();
1415}
1416
1417QuicPacketNumber QuicConnection::GetLeastUnacked() const {
1418 return sent_packet_manager_.GetLeastUnacked();
1419}
1420
1421bool QuicConnection::HandleWriteBlocked() {
1422 if (!writer_->IsWriteBlocked()) {
1423 return false;
1424 }
1425
1426 visitor_->OnWriteBlocked();
1427 return true;
1428}
1429
1430void QuicConnection::MaybeSendInResponseToPacket() {
1431 if (!connected_) {
1432 return;
1433 }
1434
1435 // If the writer is blocked, don't attempt to send packets now or in the send
1436 // alarm. When the writer unblocks, OnCanWrite() will be called for this
1437 // connection to send.
1438 if (HandleWriteBlocked()) {
1439 return;
1440 }
1441
1442 // Now that we have received an ack, we might be able to send packets which
1443 // are queued locally, or drain streams which are blocked.
1444 if (defer_send_in_response_to_packets_) {
1445 send_alarm_->Update(clock_->ApproximateNow(), QuicTime::Delta::Zero());
1446 } else {
1447 WriteAndBundleAcksIfNotBlocked();
1448 }
1449}
1450
1451void QuicConnection::SendVersionNegotiationPacket(bool ietf_quic) {
1452 pending_version_negotiation_packet_ = true;
1453 send_ietf_version_negotiation_packet_ = ietf_quic;
1454
1455 if (HandleWriteBlocked()) {
1456 return;
1457 }
1458
1459 QUIC_DLOG(INFO) << ENDPOINT << "Sending version negotiation packet: {"
1460 << ParsedQuicVersionVectorToString(
1461 framer_.supported_versions())
dschinazi965ce092019-05-23 06:29:01 -07001462 << "}, " << (ietf_quic ? "" : "!") << "ietf_quic";
QUICHE teama6ef0a62019-03-07 20:34:33 -05001463 std::unique_ptr<QuicEncryptedPacket> version_packet(
1464 packet_generator_.SerializeVersionNegotiationPacket(
1465 ietf_quic, framer_.supported_versions()));
dschinazi965ce092019-05-23 06:29:01 -07001466 QUIC_DVLOG(2) << ENDPOINT << "Sending version negotiation packet: {"
1467 << ParsedQuicVersionVectorToString(framer_.supported_versions())
1468 << "}, " << (ietf_quic ? "" : "!") << "ietf_quic:" << std::endl
1469 << QuicTextUtils::HexDump(QuicStringPiece(
1470 version_packet->data(), version_packet->length()));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001471 WriteResult result = writer_->WritePacket(
1472 version_packet->data(), version_packet->length(), self_address().host(),
1473 peer_address(), per_packet_options_);
1474
1475 if (IsWriteError(result.status)) {
1476 OnWriteError(result.error_code);
1477 return;
1478 }
1479 if (IsWriteBlockedStatus(result.status)) {
1480 visitor_->OnWriteBlocked();
1481 if (result.status == WRITE_STATUS_BLOCKED_DATA_BUFFERED) {
1482 pending_version_negotiation_packet_ = false;
1483 }
1484 return;
1485 }
1486
1487 pending_version_negotiation_packet_ = false;
1488}
1489
1490size_t QuicConnection::SendCryptoData(EncryptionLevel level,
1491 size_t write_length,
1492 QuicStreamOffset offset) {
1493 if (write_length == 0) {
1494 QUIC_BUG << "Attempt to send empty crypto frame";
1495 return 0;
1496 }
1497
fayanga4b37b22019-06-18 13:37:47 -07001498 ScopedPacketFlusher flusher(this);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001499 return packet_generator_.ConsumeCryptoData(level, write_length, offset);
1500}
1501
1502QuicConsumedData QuicConnection::SendStreamData(QuicStreamId id,
1503 size_t write_length,
1504 QuicStreamOffset offset,
1505 StreamSendingState state) {
1506 if (state == NO_FIN && write_length == 0) {
1507 QUIC_BUG << "Attempt to send empty stream frame";
1508 return QuicConsumedData(0, false);
1509 }
1510
1511 // Opportunistically bundle an ack with every outgoing packet.
1512 // Particularly, we want to bundle with handshake packets since we don't know
1513 // which decrypter will be used on an ack packet following a handshake
1514 // packet (a handshake packet from client to server could result in a REJ or a
1515 // SHLO from the server, leading to two different decrypters at the server.)
fayanga4b37b22019-06-18 13:37:47 -07001516 ScopedPacketFlusher flusher(this);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001517 return packet_generator_.ConsumeData(id, write_length, offset, state);
1518}
1519
1520bool QuicConnection::SendControlFrame(const QuicFrame& frame) {
fayanga4b37b22019-06-18 13:37:47 -07001521 ScopedPacketFlusher flusher(this);
fayang3203f252019-05-03 06:00:03 -07001522 const bool consumed =
1523 packet_generator_.ConsumeRetransmittableControlFrame(frame);
fayang914fbe12019-07-11 06:23:55 -07001524 if (!consumed) {
fayang3203f252019-05-03 06:00:03 -07001525 QUIC_DVLOG(1) << ENDPOINT << "Failed to send control frame: " << frame;
1526 return false;
1527 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001528 if (frame.type == PING_FRAME) {
1529 // Flush PING frame immediately.
1530 packet_generator_.FlushAllQueuedFrames();
1531 if (debug_visitor_ != nullptr) {
1532 debug_visitor_->OnPingSent();
1533 }
1534 }
1535 if (frame.type == BLOCKED_FRAME) {
1536 stats_.blocked_frames_sent++;
1537 }
1538 return true;
1539}
1540
1541void QuicConnection::OnStreamReset(QuicStreamId id,
1542 QuicRstStreamErrorCode error) {
1543 if (error == QUIC_STREAM_NO_ERROR) {
1544 // All data for streams which are reset with QUIC_STREAM_NO_ERROR must
1545 // be received by the peer.
1546 return;
1547 }
1548 // Flush stream frames of reset stream.
1549 if (packet_generator_.HasPendingStreamFramesOfStream(id)) {
fayanga4b37b22019-06-18 13:37:47 -07001550 ScopedPacketFlusher flusher(this);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001551 packet_generator_.FlushAllQueuedFrames();
1552 }
1553
1554 sent_packet_manager_.CancelRetransmissionsForStream(id);
1555 // Remove all queued packets which only contain data for the reset stream.
1556 // TODO(fayang): consider removing this because it should be rarely executed.
1557 auto packet_iterator = queued_packets_.begin();
1558 while (packet_iterator != queued_packets_.end()) {
1559 QuicFrames* retransmittable_frames =
1560 &packet_iterator->retransmittable_frames;
1561 if (retransmittable_frames->empty()) {
1562 ++packet_iterator;
1563 continue;
1564 }
1565 // NOTE THAT RemoveFramesForStream removes only STREAM frames
1566 // for the specified stream.
1567 RemoveFramesForStream(retransmittable_frames, id);
1568 if (!retransmittable_frames->empty()) {
1569 ++packet_iterator;
1570 continue;
1571 }
1572 delete[] packet_iterator->encrypted_buffer;
1573 ClearSerializedPacket(&(*packet_iterator));
1574 packet_iterator = queued_packets_.erase(packet_iterator);
1575 }
1576 // TODO(ianswett): Consider checking for 3 RTOs when the last stream is
1577 // cancelled as well.
1578}
1579
1580const QuicConnectionStats& QuicConnection::GetStats() {
1581 const RttStats* rtt_stats = sent_packet_manager_.GetRttStats();
1582
1583 // Update rtt and estimated bandwidth.
1584 QuicTime::Delta min_rtt = rtt_stats->min_rtt();
1585 if (min_rtt.IsZero()) {
1586 // If min RTT has not been set, use initial RTT instead.
1587 min_rtt = rtt_stats->initial_rtt();
1588 }
1589 stats_.min_rtt_us = min_rtt.ToMicroseconds();
1590
1591 QuicTime::Delta srtt = rtt_stats->SmoothedOrInitialRtt();
1592 stats_.srtt_us = srtt.ToMicroseconds();
1593
1594 stats_.estimated_bandwidth = sent_packet_manager_.BandwidthEstimate();
1595 stats_.max_packet_size = packet_generator_.GetCurrentMaxPacketLength();
1596 stats_.max_received_packet_size = largest_received_packet_size_;
1597 return stats_;
1598}
1599
1600void QuicConnection::OnCoalescedPacket(const QuicEncryptedPacket& packet) {
1601 QueueCoalescedPacket(packet);
1602}
1603
1604void QuicConnection::ProcessUdpPacket(const QuicSocketAddress& self_address,
1605 const QuicSocketAddress& peer_address,
1606 const QuicReceivedPacket& packet) {
1607 if (!connected_) {
1608 return;
1609 }
dschinazid9467b52019-04-03 16:47:08 -07001610 QUIC_DVLOG(2) << ENDPOINT << "Received encrypted " << packet.length()
1611 << " bytes:" << std::endl
1612 << QuicTextUtils::HexDump(
1613 QuicStringPiece(packet.data(), packet.length()));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001614 QUIC_BUG_IF(current_packet_data_ != nullptr)
1615 << "ProcessUdpPacket must not be called while processing a packet.";
1616 if (debug_visitor_ != nullptr) {
1617 debug_visitor_->OnPacketReceived(self_address, peer_address, packet);
1618 }
1619 last_size_ = packet.length();
1620 current_packet_data_ = packet.data();
1621
1622 last_packet_destination_address_ = self_address;
1623 last_packet_source_address_ = peer_address;
1624 if (!self_address_.IsInitialized()) {
1625 self_address_ = last_packet_destination_address_;
1626 }
1627
1628 if (!direct_peer_address_.IsInitialized()) {
1629 direct_peer_address_ = last_packet_source_address_;
1630 }
1631
1632 if (!effective_peer_address_.IsInitialized()) {
1633 const QuicSocketAddress effective_peer_addr =
1634 GetEffectivePeerAddressFromCurrentPacket();
1635
1636 // effective_peer_address_ must be initialized at the beginning of the
1637 // first packet processed(here). If effective_peer_addr is uninitialized,
1638 // just set effective_peer_address_ to the direct peer address.
1639 effective_peer_address_ = effective_peer_addr.IsInitialized()
1640 ? effective_peer_addr
1641 : direct_peer_address_;
1642 }
1643
1644 stats_.bytes_received += packet.length();
1645 ++stats_.packets_received;
1646
1647 // Ensure the time coming from the packet reader is within 2 minutes of now.
1648 if (std::abs((packet.receipt_time() - clock_->ApproximateNow()).ToSeconds()) >
1649 2 * 60) {
1650 QUIC_BUG << "Packet receipt time:"
1651 << packet.receipt_time().ToDebuggingValue()
1652 << " too far from current time:"
1653 << clock_->ApproximateNow().ToDebuggingValue();
1654 }
1655 time_of_last_received_packet_ = packet.receipt_time();
1656 QUIC_DVLOG(1) << ENDPOINT << "time of last received packet: "
1657 << time_of_last_received_packet_.ToDebuggingValue();
1658
fayanga4b37b22019-06-18 13:37:47 -07001659 ScopedPacketFlusher flusher(this);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001660 if (!framer_.ProcessPacket(packet)) {
1661 // If we are unable to decrypt this packet, it might be
1662 // because the CHLO or SHLO packet was lost.
1663 if (framer_.error() == QUIC_DECRYPTION_FAILURE) {
dschinazi6ece5002019-05-22 06:35:49 -07001664 ++stats_.undecryptable_packets_received;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001665 if (encryption_level_ != ENCRYPTION_FORWARD_SECURE &&
1666 undecryptable_packets_.size() < max_undecryptable_packets_) {
1667 QueueUndecryptablePacket(packet);
1668 } else if (debug_visitor_ != nullptr) {
1669 debug_visitor_->OnUndecryptablePacket();
1670 }
1671 }
1672 QUIC_DVLOG(1) << ENDPOINT
1673 << "Unable to process packet. Last packet processed: "
1674 << last_header_.packet_number;
1675 current_packet_data_ = nullptr;
1676 is_current_packet_connectivity_probing_ = false;
1677
1678 MaybeProcessCoalescedPackets();
1679 return;
1680 }
1681
1682 ++stats_.packets_processed;
1683
1684 QUIC_DLOG_IF(INFO, active_effective_peer_migration_type_ != NO_CHANGE)
1685 << "sent_packet_manager_.GetLargestObserved() = "
1686 << sent_packet_manager_.GetLargestObserved()
1687 << ", highest_packet_sent_before_effective_peer_migration_ = "
1688 << highest_packet_sent_before_effective_peer_migration_;
1689 if (active_effective_peer_migration_type_ != NO_CHANGE &&
1690 sent_packet_manager_.GetLargestObserved().IsInitialized() &&
1691 (!highest_packet_sent_before_effective_peer_migration_.IsInitialized() ||
1692 sent_packet_manager_.GetLargestObserved() >
1693 highest_packet_sent_before_effective_peer_migration_)) {
1694 if (perspective_ == Perspective::IS_SERVER) {
1695 OnEffectivePeerMigrationValidated();
1696 }
1697 }
1698
1699 MaybeProcessCoalescedPackets();
1700 MaybeProcessUndecryptablePackets();
1701 MaybeSendInResponseToPacket();
1702 SetPingAlarm();
1703 current_packet_data_ = nullptr;
1704 is_current_packet_connectivity_probing_ = false;
1705}
1706
1707void QuicConnection::OnBlockedWriterCanWrite() {
1708 writer_->SetWritable();
1709 OnCanWrite();
1710}
1711
1712void QuicConnection::OnCanWrite() {
fayang0f0c4e62019-07-16 08:55:54 -07001713 if (!connected_) {
fayang40ec3ac2019-06-05 09:07:54 -07001714 return;
1715 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001716 DCHECK(!writer_->IsWriteBlocked());
1717
1718 // Add a flusher to ensure the connection is marked app-limited.
fayanga4b37b22019-06-18 13:37:47 -07001719 ScopedPacketFlusher flusher(this);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001720
1721 WriteQueuedPackets();
fayangf477f732019-06-20 07:03:06 -07001722 const QuicTime ack_timeout =
fayang5f464302019-06-20 12:57:33 -07001723 uber_received_packet_manager_.GetEarliestAckTimeout();
fayangf477f732019-06-20 07:03:06 -07001724 if (ack_timeout.IsInitialized() && ack_timeout <= clock_->ApproximateNow()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001725 // Send an ACK now because either 1) we were write blocked when we last
fayangf477f732019-06-20 07:03:06 -07001726 // tried to send an ACK, or 2) both ack alarm and send alarm were set to
1727 // go off together.
1728 if (SupportsMultiplePacketNumberSpaces()) {
1729 SendAllPendingAcks();
1730 } else {
1731 SendAck();
1732 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001733 }
1734 if (!session_decides_what_to_write()) {
1735 WritePendingRetransmissions();
1736 }
1737
1738 WriteNewData();
1739}
1740
1741void QuicConnection::WriteNewData() {
1742 // Sending queued packets may have caused the socket to become write blocked,
1743 // or the congestion manager to prohibit sending. If we've sent everything
1744 // we had queued and we're still not blocked, let the visitor know it can
1745 // write more.
1746 if (!CanWrite(HAS_RETRANSMITTABLE_DATA)) {
1747 return;
1748 }
1749
1750 {
fayanga4b37b22019-06-18 13:37:47 -07001751 ScopedPacketFlusher flusher(this);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001752 visitor_->OnCanWrite();
1753 }
1754
1755 // After the visitor writes, it may have caused the socket to become write
1756 // blocked or the congestion manager to prohibit sending, so check again.
1757 if (visitor_->WillingAndAbleToWrite() && !send_alarm_->IsSet() &&
1758 CanWrite(HAS_RETRANSMITTABLE_DATA)) {
1759 // We're not write blocked, but some stream didn't write out all of its
1760 // bytes. Register for 'immediate' resumption so we'll keep writing after
1761 // other connections and events have had a chance to use the thread.
1762 send_alarm_->Set(clock_->ApproximateNow());
1763 }
1764}
1765
1766void QuicConnection::WriteIfNotBlocked() {
1767 if (!HandleWriteBlocked()) {
1768 OnCanWrite();
1769 }
1770}
1771
1772void QuicConnection::WriteAndBundleAcksIfNotBlocked() {
1773 if (!HandleWriteBlocked()) {
fayanga4b37b22019-06-18 13:37:47 -07001774 ScopedPacketFlusher flusher(this);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001775 WriteIfNotBlocked();
1776 }
1777}
1778
1779bool QuicConnection::ProcessValidatedPacket(const QuicPacketHeader& header) {
1780 if (perspective_ == Perspective::IS_SERVER && self_address_.IsInitialized() &&
1781 last_packet_destination_address_.IsInitialized() &&
1782 self_address_ != last_packet_destination_address_) {
1783 // Allow change between pure IPv4 and equivalent mapped IPv4 address.
1784 if (self_address_.port() != last_packet_destination_address_.port() ||
1785 self_address_.host().Normalized() !=
1786 last_packet_destination_address_.host().Normalized()) {
1787 if (!visitor_->AllowSelfAddressChange()) {
1788 CloseConnection(
1789 QUIC_ERROR_MIGRATING_ADDRESS,
1790 "Self address migration is not supported at the server.",
1791 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
1792 return false;
1793 }
1794 }
1795 self_address_ = last_packet_destination_address_;
1796 }
1797
QUICHE teamc65d1d12019-03-19 20:58:04 -07001798 if (PacketCanReplaceConnectionId(header, perspective_) &&
dschinazi7b9278c2019-05-20 07:36:21 -07001799 server_connection_id_ != header.source_connection_id) {
1800 QUIC_DLOG(INFO) << ENDPOINT << "Replacing connection ID "
1801 << server_connection_id_ << " with "
1802 << header.source_connection_id;
1803 server_connection_id_ = header.source_connection_id;
1804 packet_generator_.SetServerConnectionId(server_connection_id_);
QUICHE teamc65d1d12019-03-19 20:58:04 -07001805 }
1806
QUICHE teamd791e2c2019-03-15 10:28:21 -07001807 if (!ValidateReceivedPacketNumber(header.packet_number)) {
1808 return false;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001809 }
1810
fayang8aba1ff2019-06-21 12:00:54 -07001811 if (!version_negotiated_) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001812 if (perspective_ == Perspective::IS_CLIENT) {
1813 DCHECK(!header.version_flag || header.form != GOOGLE_QUIC_PACKET);
fayangd4291e42019-05-30 10:31:21 -07001814 if (!VersionHasIetfInvariantHeader(framer_.transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001815 // If the client gets a packet without the version flag from the server
1816 // it should stop sending version since the version negotiation is done.
1817 // IETF QUIC stops sending version once encryption level switches to
1818 // forward secure.
1819 packet_generator_.StopSendingVersion();
1820 }
fayang8aba1ff2019-06-21 12:00:54 -07001821 version_negotiated_ = true;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001822 visitor_->OnSuccessfulVersionNegotiation(version());
1823 if (debug_visitor_ != nullptr) {
1824 debug_visitor_->OnSuccessfulVersionNegotiation(version());
1825 }
1826 }
1827 }
1828
1829 if (last_size_ > largest_received_packet_size_) {
1830 largest_received_packet_size_ = last_size_;
1831 }
1832
1833 if (perspective_ == Perspective::IS_SERVER &&
QUICHE team6987b4a2019-03-15 16:23:04 -07001834 encryption_level_ == ENCRYPTION_INITIAL &&
QUICHE teama6ef0a62019-03-07 20:34:33 -05001835 last_size_ > packet_generator_.GetCurrentMaxPacketLength()) {
1836 SetMaxPacketLength(last_size_);
1837 }
1838 return true;
1839}
1840
QUICHE teamd791e2c2019-03-15 10:28:21 -07001841bool QuicConnection::ValidateReceivedPacketNumber(
1842 QuicPacketNumber packet_number) {
fayang08878bd2019-06-20 09:21:43 -07001843 // If this packet has already been seen, or the sender has told us that it
1844 // will not be retransmitted, then stop processing the packet.
fayang5f464302019-06-20 12:57:33 -07001845 if (!uber_received_packet_manager_.IsAwaitingPacket(
1846 last_decrypted_packet_level_, packet_number)) {
1847 QUIC_DLOG(INFO) << ENDPOINT << "Packet " << packet_number
1848 << " no longer being waited for at level "
1849 << static_cast<int>(last_decrypted_packet_level_)
1850 << ". Discarding.";
fayang08878bd2019-06-20 09:21:43 -07001851 if (debug_visitor_ != nullptr) {
1852 debug_visitor_->OnDuplicatePacket(packet_number);
1853 }
1854 return false;
QUICHE team692750b2019-03-17 17:57:46 -07001855 }
1856
fayang6dba4902019-06-17 10:04:23 -07001857 return true;
QUICHE teamd791e2c2019-03-15 10:28:21 -07001858}
1859
QUICHE teama6ef0a62019-03-07 20:34:33 -05001860void QuicConnection::WriteQueuedPackets() {
1861 DCHECK(!writer_->IsWriteBlocked());
1862
1863 if (pending_version_negotiation_packet_) {
1864 SendVersionNegotiationPacket(send_ietf_version_negotiation_packet_);
1865 }
1866
1867 QUIC_CLIENT_HISTOGRAM_COUNTS("QuicSession.NumQueuedPacketsBeforeWrite",
1868 queued_packets_.size(), 1, 1000, 50, "");
1869 while (!queued_packets_.empty()) {
1870 // WritePacket() can potentially clear all queued packets, so we need to
1871 // save the first queued packet to a local variable before calling it.
1872 SerializedPacket packet(std::move(queued_packets_.front()));
1873 queued_packets_.pop_front();
1874
1875 const bool write_result = WritePacket(&packet);
1876
1877 if (connected_ && !write_result) {
1878 // Write failed but connection is open, re-insert |packet| into the
1879 // front of the queue, it will be retried later.
1880 queued_packets_.emplace_front(std::move(packet));
1881 break;
1882 }
1883
1884 delete[] packet.encrypted_buffer;
1885 ClearSerializedPacket(&packet);
1886 if (!connected_) {
1887 DCHECK(queued_packets_.empty()) << "Queued packets should have been "
1888 "cleared while closing connection";
1889 break;
1890 }
1891
1892 // Continue to send the next packet in queue.
1893 }
1894}
1895
1896void QuicConnection::WritePendingRetransmissions() {
1897 DCHECK(!session_decides_what_to_write());
1898 // Keep writing as long as there's a pending retransmission which can be
1899 // written.
1900 while (sent_packet_manager_.HasPendingRetransmissions() &&
1901 CanWrite(HAS_RETRANSMITTABLE_DATA)) {
1902 const QuicPendingRetransmission pending =
1903 sent_packet_manager_.NextPendingRetransmission();
1904
1905 // Re-packetize the frames with a new packet number for retransmission.
1906 // Retransmitted packets use the same packet number length as the
1907 // original.
1908 // Flush the packet generator before making a new packet.
1909 // TODO(ianswett): Implement ReserializeAllFrames as a separate path that
1910 // does not require the creator to be flushed.
1911 // TODO(fayang): FlushAllQueuedFrames should only be called once, and should
1912 // be moved outside of the loop. Also, CanWrite is not checked after the
1913 // generator is flushed.
1914 {
fayanga4b37b22019-06-18 13:37:47 -07001915 ScopedPacketFlusher flusher(this);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001916 packet_generator_.FlushAllQueuedFrames();
1917 }
fayang914fbe12019-07-11 06:23:55 -07001918 DCHECK(!packet_generator_.HasPendingFrames());
dschinazi66dea072019-04-09 11:41:06 -07001919 char buffer[kMaxOutgoingPacketSize];
1920 packet_generator_.ReserializeAllFrames(pending, buffer,
1921 kMaxOutgoingPacketSize);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001922 }
1923}
1924
1925void QuicConnection::SendProbingRetransmissions() {
1926 while (sent_packet_manager_.GetSendAlgorithm()->ShouldSendProbingPacket() &&
1927 CanWrite(HAS_RETRANSMITTABLE_DATA)) {
QUICHE teamb8343252019-04-29 13:58:01 -07001928 if (!visitor_->SendProbingData()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001929 QUIC_DVLOG(1)
1930 << "Cannot send probing retransmissions: nothing to retransmit.";
1931 break;
1932 }
1933
1934 if (!session_decides_what_to_write()) {
1935 DCHECK(sent_packet_manager_.HasPendingRetransmissions());
1936 WritePendingRetransmissions();
1937 }
1938 }
1939}
1940
1941void QuicConnection::RetransmitUnackedPackets(
1942 TransmissionType retransmission_type) {
1943 sent_packet_manager_.RetransmitUnackedPackets(retransmission_type);
1944
1945 WriteIfNotBlocked();
1946}
1947
1948void QuicConnection::NeuterUnencryptedPackets() {
1949 sent_packet_manager_.NeuterUnencryptedPackets();
1950 // This may have changed the retransmission timer, so re-arm it.
1951 SetRetransmissionAlarm();
1952}
1953
1954bool QuicConnection::ShouldGeneratePacket(
1955 HasRetransmittableData retransmittable,
1956 IsHandshake handshake) {
1957 // We should serialize handshake packets immediately to ensure that they
1958 // end up sent at the right encryption level.
1959 if (handshake == IS_HANDSHAKE) {
1960 return true;
1961 }
1962
1963 return CanWrite(retransmittable);
1964}
1965
1966const QuicFrames QuicConnection::MaybeBundleAckOpportunistically() {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001967 QuicFrames frames;
fayang5f464302019-06-20 12:57:33 -07001968 const bool has_pending_ack =
1969 uber_received_packet_manager_
1970 .GetAckTimeout(QuicUtils::GetPacketNumberSpace(encryption_level_))
1971 .IsInitialized();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001972 if (!has_pending_ack && stop_waiting_count_ <= 1) {
1973 // No need to send an ACK.
1974 return frames;
1975 }
1976 ResetAckStates();
1977
1978 QUIC_DVLOG(1) << ENDPOINT << "Bundle an ACK opportunistically";
dschinazi8cf087e2019-05-23 05:27:48 -07001979 QuicFrame updated_ack_frame = GetUpdatedAckFrame();
1980 QUIC_BUG_IF(updated_ack_frame.ack_frame->packets.Empty())
1981 << ENDPOINT << "Attempted to opportunistically bundle an empty "
1982 << QuicUtils::EncryptionLevelToString(encryption_level_) << " ACK, "
1983 << (has_pending_ack ? "" : "!") << "has_pending_ack, stop_waiting_count_ "
1984 << stop_waiting_count_;
1985 frames.push_back(updated_ack_frame);
1986
QUICHE teama6ef0a62019-03-07 20:34:33 -05001987 if (!no_stop_waiting_frames_) {
1988 QuicStopWaitingFrame stop_waiting;
1989 PopulateStopWaitingFrame(&stop_waiting);
1990 frames.push_back(QuicFrame(stop_waiting));
1991 }
1992 return frames;
1993}
1994
1995bool QuicConnection::CanWrite(HasRetransmittableData retransmittable) {
1996 if (!connected_) {
1997 return false;
1998 }
1999
2000 if (session_decides_what_to_write() &&
2001 sent_packet_manager_.pending_timer_transmission_count() > 0) {
2002 // Force sending the retransmissions for HANDSHAKE, TLP, RTO, PROBING cases.
2003 return true;
2004 }
2005
2006 if (HandleWriteBlocked()) {
2007 return false;
2008 }
2009
2010 // Allow acks to be sent immediately.
2011 if (retransmittable == NO_RETRANSMITTABLE_DATA) {
2012 return true;
2013 }
2014 // If the send alarm is set, wait for it to fire.
2015 if (send_alarm_->IsSet()) {
2016 return false;
2017 }
2018
2019 QuicTime now = clock_->Now();
2020 QuicTime::Delta delay = sent_packet_manager_.TimeUntilSend(now);
2021 if (delay.IsInfinite()) {
2022 send_alarm_->Cancel();
2023 return false;
2024 }
2025
2026 // Scheduler requires a delay.
2027 if (!delay.IsZero()) {
2028 if (delay <= release_time_into_future_) {
2029 // Required delay is within pace time into future, send now.
2030 return true;
2031 }
2032 // Cannot send packet now because delay is too far in the future.
2033 send_alarm_->Update(now + delay, QuicTime::Delta::FromMilliseconds(1));
2034 QUIC_DVLOG(1) << ENDPOINT << "Delaying sending " << delay.ToMilliseconds()
2035 << "ms";
2036 return false;
2037 }
2038 return true;
2039}
2040
2041bool QuicConnection::WritePacket(SerializedPacket* packet) {
2042 if (ShouldDiscardPacket(*packet)) {
2043 ++stats_.packets_discarded;
2044 return true;
2045 }
2046 if (sent_packet_manager_.GetLargestSentPacket().IsInitialized() &&
2047 packet->packet_number < sent_packet_manager_.GetLargestSentPacket()) {
2048 QUIC_BUG << "Attempt to write packet:" << packet->packet_number
2049 << " after:" << sent_packet_manager_.GetLargestSentPacket();
2050 QUIC_CLIENT_HISTOGRAM_COUNTS("QuicSession.NumQueuedPacketsAtOutOfOrder",
2051 queued_packets_.size(), 1, 1000, 50, "");
2052 CloseConnection(QUIC_INTERNAL_ERROR, "Packet written out of order.",
2053 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
2054 return true;
2055 }
2056 // Termination packets are encrypted and saved, so don't exit early.
2057 const bool is_termination_packet = IsTerminationPacket(*packet);
2058 if (HandleWriteBlocked() && !is_termination_packet) {
2059 return false;
2060 }
2061
2062 QuicPacketNumber packet_number = packet->packet_number;
2063
2064 QuicPacketLength encrypted_length = packet->encrypted_length;
2065 // Termination packets are eventually owned by TimeWaitListManager.
2066 // Others are deleted at the end of this call.
2067 if (is_termination_packet) {
2068 if (termination_packets_ == nullptr) {
2069 termination_packets_.reset(
2070 new std::vector<std::unique_ptr<QuicEncryptedPacket>>);
2071 }
2072 // Copy the buffer so it's owned in the future.
2073 char* buffer_copy = CopyBuffer(*packet);
2074 termination_packets_->emplace_back(
2075 new QuicEncryptedPacket(buffer_copy, encrypted_length, true));
2076 // This assures we won't try to write *forced* packets when blocked.
2077 // Return true to stop processing.
2078 if (HandleWriteBlocked()) {
2079 return true;
2080 }
2081 }
2082
dschinazi66dea072019-04-09 11:41:06 -07002083 DCHECK_LE(encrypted_length, kMaxOutgoingPacketSize);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002084 DCHECK_LE(encrypted_length, packet_generator_.GetCurrentMaxPacketLength());
2085 QUIC_DVLOG(1) << ENDPOINT << "Sending packet " << packet_number << " : "
2086 << (IsRetransmittable(*packet) == HAS_RETRANSMITTABLE_DATA
2087 ? "data bearing "
2088 : " ack only ")
2089 << ", encryption level: "
2090 << QuicUtils::EncryptionLevelToString(packet->encryption_level)
2091 << ", encrypted length:" << encrypted_length;
2092 QUIC_DVLOG(2) << ENDPOINT << "packet(" << packet_number << "): " << std::endl
2093 << QuicTextUtils::HexDump(QuicStringPiece(
2094 packet->encrypted_buffer, encrypted_length));
2095
2096 // Measure the RTT from before the write begins to avoid underestimating the
2097 // min_rtt_, especially in cases where the thread blocks or gets swapped out
2098 // during the WritePacket below.
2099 QuicTime packet_send_time = clock_->Now();
2100 if (supports_release_time_ && per_packet_options_ != nullptr) {
2101 QuicTime next_release_time = sent_packet_manager_.GetNextReleaseTime();
2102 QuicTime::Delta release_time_delay = QuicTime::Delta::Zero();
2103 QuicTime now = packet_send_time;
2104 if (next_release_time > now) {
2105 release_time_delay = next_release_time - now;
2106 // Set packet_send_time to the future to make the RTT estimation accurate.
2107 packet_send_time = next_release_time;
2108 }
2109 per_packet_options_->release_time_delay = release_time_delay;
2110 }
2111 WriteResult result = writer_->WritePacket(
2112 packet->encrypted_buffer, encrypted_length, self_address().host(),
2113 peer_address(), per_packet_options_);
2114
2115 QUIC_HISTOGRAM_ENUM(
2116 "QuicConnection.WritePacketStatus", result.status,
2117 WRITE_STATUS_NUM_VALUES,
2118 "Status code returned by writer_->WritePacket() in QuicConnection.");
2119
2120 if (IsWriteBlockedStatus(result.status)) {
2121 // Ensure the writer is still write blocked, otherwise QUIC may continue
2122 // trying to write when it will not be able to.
2123 DCHECK(writer_->IsWriteBlocked());
2124 visitor_->OnWriteBlocked();
2125 // If the socket buffers the data, then the packet should not
2126 // be queued and sent again, which would result in an unnecessary
2127 // duplicate packet being sent. The helper must call OnCanWrite
2128 // when the write completes, and OnWriteError if an error occurs.
2129 if (result.status != WRITE_STATUS_BLOCKED_DATA_BUFFERED) {
2130 return false;
2131 }
2132 }
2133
2134 // In some cases, an MTU probe can cause EMSGSIZE. This indicates that the
2135 // MTU discovery is permanently unsuccessful.
2136 if (IsMsgTooBig(result) && packet->retransmittable_frames.empty() &&
2137 packet->encrypted_length > long_term_mtu_) {
2138 mtu_discovery_target_ = 0;
2139 mtu_discovery_alarm_->Cancel();
2140 // The write failed, but the writer is not blocked, so return true.
2141 return true;
2142 }
2143
2144 if (IsWriteError(result.status)) {
2145 OnWriteError(result.error_code);
2146 QUIC_LOG_FIRST_N(ERROR, 10)
2147 << ENDPOINT << "failed writing " << encrypted_length
2148 << " bytes from host " << self_address().host().ToString()
2149 << " to address " << peer_address().ToString() << " with error code "
2150 << result.error_code;
2151 return false;
2152 }
2153
2154 if (debug_visitor_ != nullptr) {
2155 // Pass the write result to the visitor.
2156 debug_visitor_->OnPacketSent(*packet, packet->original_packet_number,
2157 packet->transmission_type, packet_send_time);
2158 }
2159 if (IsRetransmittable(*packet) == HAS_RETRANSMITTABLE_DATA) {
2160 if (!is_path_degrading_ && !path_degrading_alarm_->IsSet()) {
2161 // This is the first retransmittable packet on the working path.
2162 // Start the path degrading alarm to detect new path degrading.
2163 SetPathDegradingAlarm();
2164 }
2165
zhongyic1cab062019-06-19 12:02:24 -07002166 // Update |time_of_first_packet_sent_after_receiving_| if this is the
2167 // first packet sent after the last packet was received. If it were
2168 // updated on every sent packet, then sending into a black hole might
2169 // never timeout.
2170 if (time_of_first_packet_sent_after_receiving_ <
2171 time_of_last_received_packet_) {
2172 time_of_first_packet_sent_after_receiving_ = packet_send_time;
QUICHE teama6ef0a62019-03-07 20:34:33 -05002173 }
2174 }
2175
2176 MaybeSetMtuAlarm(packet_number);
2177 QUIC_DVLOG(1) << ENDPOINT << "time we began writing last sent packet: "
2178 << packet_send_time.ToDebuggingValue();
2179
2180 bool reset_retransmission_alarm = sent_packet_manager_.OnPacketSent(
2181 packet, packet->original_packet_number, packet_send_time,
2182 packet->transmission_type, IsRetransmittable(*packet));
2183
2184 if (reset_retransmission_alarm || !retransmission_alarm_->IsSet()) {
2185 SetRetransmissionAlarm();
2186 }
2187 SetPingAlarm();
2188
2189 // The packet number length must be updated after OnPacketSent, because it
2190 // may change the packet number length in packet.
2191 packet_generator_.UpdatePacketNumberLength(
2192 sent_packet_manager_.GetLeastUnacked(),
2193 sent_packet_manager_.EstimateMaxPacketsInFlight(max_packet_length()));
2194
2195 stats_.bytes_sent += result.bytes_written;
2196 ++stats_.packets_sent;
2197 if (packet->transmission_type != NOT_RETRANSMISSION) {
2198 stats_.bytes_retransmitted += result.bytes_written;
2199 ++stats_.packets_retransmitted;
2200 }
2201
2202 return true;
2203}
2204
2205void QuicConnection::FlushPackets() {
2206 if (!connected_) {
2207 return;
2208 }
2209
2210 if (!writer_->IsBatchMode()) {
2211 return;
2212 }
2213
2214 if (HandleWriteBlocked()) {
2215 QUIC_DLOG(INFO) << ENDPOINT << "FlushPackets called while blocked.";
2216 return;
2217 }
2218
2219 WriteResult result = writer_->Flush();
2220
2221 if (HandleWriteBlocked()) {
2222 DCHECK_EQ(WRITE_STATUS_BLOCKED, result.status)
2223 << "Unexpected flush result:" << result;
2224 QUIC_DLOG(INFO) << ENDPOINT << "Write blocked in FlushPackets.";
2225 return;
2226 }
2227
2228 if (IsWriteError(result.status)) {
2229 OnWriteError(result.error_code);
2230 }
2231}
2232
2233bool QuicConnection::IsMsgTooBig(const WriteResult& result) {
2234 return (result.status == WRITE_STATUS_MSG_TOO_BIG) ||
2235 (IsWriteError(result.status) && result.error_code == QUIC_EMSGSIZE);
2236}
2237
2238bool QuicConnection::ShouldDiscardPacket(const SerializedPacket& packet) {
2239 if (!connected_) {
2240 QUIC_DLOG(INFO) << ENDPOINT
2241 << "Not sending packet as connection is disconnected.";
2242 return true;
2243 }
2244
2245 QuicPacketNumber packet_number = packet.packet_number;
2246 if (encryption_level_ == ENCRYPTION_FORWARD_SECURE &&
QUICHE team6987b4a2019-03-15 16:23:04 -07002247 packet.encryption_level == ENCRYPTION_INITIAL) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002248 // Drop packets that are NULL encrypted since the peer won't accept them
2249 // anymore.
2250 QUIC_DLOG(INFO) << ENDPOINT
2251 << "Dropping NULL encrypted packet: " << packet_number
2252 << " since the connection is forward secure.";
2253 return true;
2254 }
2255
2256 return false;
2257}
2258
2259void QuicConnection::OnWriteError(int error_code) {
2260 if (write_error_occurred_) {
2261 // A write error already occurred. The connection is being closed.
2262 return;
2263 }
2264 write_error_occurred_ = true;
2265
vasilvvc48c8712019-03-11 13:38:16 -07002266 const std::string error_details = QuicStrCat(
QUICHE teama6ef0a62019-03-07 20:34:33 -05002267 "Write failed with error: ", error_code, " (", strerror(error_code), ")");
2268 QUIC_LOG_FIRST_N(ERROR, 2) << ENDPOINT << error_details;
2269 switch (error_code) {
2270 case QUIC_EMSGSIZE:
ianswettdc1e7ab2019-05-03 16:10:44 -07002271 CloseConnection(QUIC_PACKET_WRITE_ERROR, error_details,
2272 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002273 break;
2274 default:
2275 // We can't send an error as the socket is presumably borked.
fayangd4291e42019-05-30 10:31:21 -07002276 if (VersionHasIetfInvariantHeader(transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002277 QUIC_CODE_COUNT(quic_tear_down_local_connection_on_write_error_ietf);
2278 } else {
2279 QUIC_CODE_COUNT(
2280 quic_tear_down_local_connection_on_write_error_non_ietf);
2281 }
fkastenholz85f18902019-05-28 12:47:00 -07002282 CloseConnection(QUIC_PACKET_WRITE_ERROR, error_details,
2283 ConnectionCloseBehavior::SILENT_CLOSE);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002284 }
2285}
2286
2287char* QuicConnection::GetPacketBuffer() {
2288 return writer_->GetNextWriteLocation(self_address().host(), peer_address());
2289}
2290
2291void QuicConnection::OnSerializedPacket(SerializedPacket* serialized_packet) {
2292 if (serialized_packet->encrypted_buffer == nullptr) {
2293 // We failed to serialize the packet, so close the connection.
fkastenholz85f18902019-05-28 12:47:00 -07002294 // Specify that the close is silent, that no packet be sent, so no infinite
QUICHE teama6ef0a62019-03-07 20:34:33 -05002295 // loop here.
2296 // TODO(ianswett): This is actually an internal error, not an
2297 // encryption failure.
fayangd4291e42019-05-30 10:31:21 -07002298 if (VersionHasIetfInvariantHeader(transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002299 QUIC_CODE_COUNT(
2300 quic_tear_down_local_connection_on_serialized_packet_ietf);
2301 } else {
2302 QUIC_CODE_COUNT(
2303 quic_tear_down_local_connection_on_serialized_packet_non_ietf);
2304 }
fkastenholz85f18902019-05-28 12:47:00 -07002305 CloseConnection(QUIC_ENCRYPTION_FAILURE,
2306 "Serialized packet does not have an encrypted buffer.",
2307 ConnectionCloseBehavior::SILENT_CLOSE);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002308 return;
2309 }
2310
2311 if (serialized_packet->retransmittable_frames.empty() &&
2312 !serialized_packet->original_packet_number.IsInitialized()) {
2313 // Increment consecutive_num_packets_with_no_retransmittable_frames_ if
2314 // this packet is a new transmission with no retransmittable frames.
2315 ++consecutive_num_packets_with_no_retransmittable_frames_;
2316 } else {
2317 consecutive_num_packets_with_no_retransmittable_frames_ = 0;
2318 }
2319 SendOrQueuePacket(serialized_packet);
2320}
2321
2322void QuicConnection::OnUnrecoverableError(QuicErrorCode error,
fkastenholz85f18902019-05-28 12:47:00 -07002323 const std::string& error_details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002324 // The packet creator or generator encountered an unrecoverable error: tear
2325 // down local connection state immediately.
fayangd4291e42019-05-30 10:31:21 -07002326 if (VersionHasIetfInvariantHeader(transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002327 QUIC_CODE_COUNT(
2328 quic_tear_down_local_connection_on_unrecoverable_error_ietf);
2329 } else {
2330 QUIC_CODE_COUNT(
2331 quic_tear_down_local_connection_on_unrecoverable_error_non_ietf);
2332 }
fkastenholz85f18902019-05-28 12:47:00 -07002333 CloseConnection(error, error_details, ConnectionCloseBehavior::SILENT_CLOSE);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002334}
2335
2336void QuicConnection::OnCongestionChange() {
2337 visitor_->OnCongestionWindowChange(clock_->ApproximateNow());
2338
2339 // Uses the connection's smoothed RTT. If zero, uses initial_rtt.
2340 QuicTime::Delta rtt = sent_packet_manager_.GetRttStats()->smoothed_rtt();
2341 if (rtt.IsZero()) {
2342 rtt = sent_packet_manager_.GetRttStats()->initial_rtt();
2343 }
2344
2345 if (debug_visitor_ != nullptr) {
2346 debug_visitor_->OnRttChanged(rtt);
2347 }
2348}
2349
2350void QuicConnection::OnPathMtuIncreased(QuicPacketLength packet_size) {
2351 if (packet_size > max_packet_length()) {
2352 SetMaxPacketLength(packet_size);
2353 }
2354}
2355
2356void QuicConnection::OnHandshakeComplete() {
2357 sent_packet_manager_.SetHandshakeConfirmed();
fayangbf3d2862019-06-20 14:13:44 -07002358 // This may have changed the retransmission timer, so re-arm it.
2359 SetRetransmissionAlarm();
QUICHE teama6ef0a62019-03-07 20:34:33 -05002360 // The client should immediately ack the SHLO to confirm the handshake is
2361 // complete with the server.
fayanga4b37b22019-06-18 13:37:47 -07002362 if (perspective_ == Perspective::IS_CLIENT && ack_frame_updated()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002363 ack_alarm_->Update(clock_->ApproximateNow(), QuicTime::Delta::Zero());
2364 }
2365}
2366
2367void QuicConnection::SendOrQueuePacket(SerializedPacket* packet) {
2368 // The caller of this function is responsible for checking CanWrite().
2369 if (packet->encrypted_buffer == nullptr) {
2370 QUIC_BUG << "packet.encrypted_buffer == nullptr in to SendOrQueuePacket";
2371 return;
2372 }
2373 // If there are already queued packets, queue this one immediately to ensure
2374 // it's written in sequence number order.
2375 if (!queued_packets_.empty() || !WritePacket(packet)) {
2376 // Take ownership of the underlying encrypted packet.
2377 packet->encrypted_buffer = CopyBuffer(*packet);
2378 queued_packets_.push_back(*packet);
2379 packet->retransmittable_frames.clear();
2380 }
2381
2382 ClearSerializedPacket(packet);
2383}
2384
2385void QuicConnection::OnPingTimeout() {
2386 if (!retransmission_alarm_->IsSet()) {
2387 visitor_->SendPing();
2388 }
2389}
2390
2391void QuicConnection::SendAck() {
QUICHE teamcd098022019-03-22 18:49:55 -07002392 DCHECK(!SupportsMultiplePacketNumberSpaces());
fayanga4b37b22019-06-18 13:37:47 -07002393 QUIC_DVLOG(1) << ENDPOINT << "Sending an ACK proactively";
2394 QuicFrames frames;
2395 frames.push_back(GetUpdatedAckFrame());
2396 if (!no_stop_waiting_frames_) {
2397 QuicStopWaitingFrame stop_waiting;
2398 PopulateStopWaitingFrame(&stop_waiting);
2399 frames.push_back(QuicFrame(stop_waiting));
2400 }
fayangf477f732019-06-20 07:03:06 -07002401 if (!packet_generator_.FlushAckFrame(frames)) {
2402 return;
QUICHE teama6ef0a62019-03-07 20:34:33 -05002403 }
fayangf477f732019-06-20 07:03:06 -07002404 ResetAckStates();
QUICHE teama6ef0a62019-03-07 20:34:33 -05002405 if (consecutive_num_packets_with_no_retransmittable_frames_ <
2406 max_consecutive_num_packets_with_no_retransmittable_frames_) {
2407 return;
2408 }
2409 consecutive_num_packets_with_no_retransmittable_frames_ = 0;
2410 if (packet_generator_.HasRetransmittableFrames() ||
2411 visitor_->WillingAndAbleToWrite()) {
2412 // There are pending retransmittable frames.
2413 return;
2414 }
2415
2416 visitor_->OnAckNeedsRetransmittableFrame();
2417}
2418
2419void QuicConnection::OnPathDegradingTimeout() {
2420 is_path_degrading_ = true;
2421 visitor_->OnPathDegrading();
2422}
2423
2424void QuicConnection::OnRetransmissionTimeout() {
2425 DCHECK(!sent_packet_manager_.unacked_packets().empty());
fayanga29eb242019-07-16 12:25:38 -07002426 const QuicPacketNumber previous_created_packet_number =
2427 packet_generator_.packet_number();
2428 const size_t previous_crypto_retransmit_count =
2429 stats_.crypto_retransmit_count;
2430 const size_t previous_loss_timeout_count = stats_.loss_timeout_count;
2431 const size_t previous_tlp_count = stats_.tlp_count;
2432 const size_t pervious_rto_count = stats_.rto_count;
QUICHE teama6ef0a62019-03-07 20:34:33 -05002433 if (close_connection_after_five_rtos_ &&
2434 sent_packet_manager_.GetConsecutiveRtoCount() >= 4) {
2435 // Close on the 5th consecutive RTO, so after 4 previous RTOs have occurred.
2436 CloseConnection(QUIC_TOO_MANY_RTOS, "5 consecutive retransmission timeouts",
2437 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
2438 return;
2439 }
2440
2441 sent_packet_manager_.OnRetransmissionTimeout();
2442 WriteIfNotBlocked();
2443
2444 // A write failure can result in the connection being closed, don't attempt to
2445 // write further packets, or to set alarms.
2446 if (!connected_) {
2447 return;
2448 }
2449
2450 // In the TLP case, the SentPacketManager gives the connection the opportunity
2451 // to send new data before retransmitting.
2452 if (sent_packet_manager_.MaybeRetransmitTailLossProbe()) {
2453 // Send the pending retransmission now that it's been queued.
2454 WriteIfNotBlocked();
2455 }
2456
fayanga29eb242019-07-16 12:25:38 -07002457 if (sent_packet_manager_.fix_rto_retransmission()) {
2458 // Making sure at least one packet is created when retransmission timer
2459 // fires in TLP, RTO or HANDSHAKE mode. It is possible that loss algorithm
2460 // invokes timer based loss but the packet does not need to be
2461 // retransmitted.
2462 QUIC_BUG_IF(stats_.loss_timeout_count == previous_loss_timeout_count &&
2463 packet_generator_.packet_number() ==
2464 previous_created_packet_number)
2465 << "previous_crypto_retransmit_count: "
2466 << previous_crypto_retransmit_count
2467 << ", crypto_retransmit_count: " << stats_.crypto_retransmit_count
2468 << ", previous_loss_timeout_count: " << previous_loss_timeout_count
2469 << ", loss_timeout_count: " << stats_.loss_timeout_count
2470 << ", previous_tlp_count: " << previous_tlp_count
2471 << ", tlp_count: " << stats_.tlp_count
2472 << ", pervious_rto_count: " << pervious_rto_count
2473 << ", rto_count: " << stats_.rto_count
2474 << ", previous_created_packet_number: "
2475 << previous_created_packet_number
2476 << ", packet_number: " << packet_generator_.packet_number()
2477 << ", session has data to write: " << visitor_->WillingAndAbleToWrite();
2478 }
2479
QUICHE teama6ef0a62019-03-07 20:34:33 -05002480 // Ensure the retransmission alarm is always set if there are unacked packets
2481 // and nothing waiting to be sent.
2482 // This happens if the loss algorithm invokes a timer based loss, but the
2483 // packet doesn't need to be retransmitted.
2484 if (!HasQueuedData() && !retransmission_alarm_->IsSet()) {
2485 SetRetransmissionAlarm();
2486 }
2487}
2488
2489void QuicConnection::SetEncrypter(EncryptionLevel level,
2490 std::unique_ptr<QuicEncrypter> encrypter) {
2491 packet_generator_.SetEncrypter(level, std::move(encrypter));
2492}
2493
2494void QuicConnection::SetDiversificationNonce(
2495 const DiversificationNonce& nonce) {
2496 DCHECK_EQ(Perspective::IS_SERVER, perspective_);
2497 packet_generator_.SetDiversificationNonce(nonce);
2498}
2499
2500void QuicConnection::SetDefaultEncryptionLevel(EncryptionLevel level) {
fayang914fbe12019-07-11 06:23:55 -07002501 if (level != encryption_level_ && packet_generator_.HasPendingFrames()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002502 // Flush all queued frames when encryption level changes.
fayanga4b37b22019-06-18 13:37:47 -07002503 ScopedPacketFlusher flusher(this);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002504 packet_generator_.FlushAllQueuedFrames();
2505 }
2506 encryption_level_ = level;
2507 packet_generator_.set_encryption_level(level);
2508}
2509
2510void QuicConnection::SetDecrypter(EncryptionLevel level,
2511 std::unique_ptr<QuicDecrypter> decrypter) {
2512 framer_.SetDecrypter(level, std::move(decrypter));
2513
2514 if (!undecryptable_packets_.empty() &&
2515 !process_undecryptable_packets_alarm_->IsSet()) {
2516 process_undecryptable_packets_alarm_->Set(clock_->ApproximateNow());
2517 }
2518}
2519
2520void QuicConnection::SetAlternativeDecrypter(
2521 EncryptionLevel level,
2522 std::unique_ptr<QuicDecrypter> decrypter,
2523 bool latch_once_used) {
2524 framer_.SetAlternativeDecrypter(level, std::move(decrypter), latch_once_used);
2525
2526 if (!undecryptable_packets_.empty() &&
2527 !process_undecryptable_packets_alarm_->IsSet()) {
2528 process_undecryptable_packets_alarm_->Set(clock_->ApproximateNow());
2529 }
2530}
2531
zhongyi546cc452019-04-12 15:27:49 -07002532void QuicConnection::InstallDecrypter(
2533 EncryptionLevel level,
2534 std::unique_ptr<QuicDecrypter> decrypter) {
2535 framer_.InstallDecrypter(level, std::move(decrypter));
2536 if (!undecryptable_packets_.empty() &&
2537 !process_undecryptable_packets_alarm_->IsSet()) {
2538 process_undecryptable_packets_alarm_->Set(clock_->ApproximateNow());
2539 }
2540}
2541
2542void QuicConnection::RemoveDecrypter(EncryptionLevel level) {
2543 framer_.RemoveDecrypter(level);
2544}
2545
QUICHE teama6ef0a62019-03-07 20:34:33 -05002546const QuicDecrypter* QuicConnection::decrypter() const {
2547 return framer_.decrypter();
2548}
2549
2550const QuicDecrypter* QuicConnection::alternative_decrypter() const {
2551 return framer_.alternative_decrypter();
2552}
2553
2554void QuicConnection::QueueUndecryptablePacket(
2555 const QuicEncryptedPacket& packet) {
2556 QUIC_DVLOG(1) << ENDPOINT << "Queueing undecryptable packet.";
2557 undecryptable_packets_.push_back(packet.Clone());
2558}
2559
2560void QuicConnection::MaybeProcessUndecryptablePackets() {
2561 process_undecryptable_packets_alarm_->Cancel();
2562
QUICHE team6987b4a2019-03-15 16:23:04 -07002563 if (undecryptable_packets_.empty() ||
2564 encryption_level_ == ENCRYPTION_INITIAL) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002565 return;
2566 }
2567
2568 while (connected_ && !undecryptable_packets_.empty()) {
2569 // Making sure there is no pending frames when processing next undecrypted
2570 // packet because the queued ack frame may change.
2571 packet_generator_.FlushAllQueuedFrames();
2572 if (!connected_) {
2573 return;
2574 }
2575 QUIC_DVLOG(1) << ENDPOINT << "Attempting to process undecryptable packet";
2576 QuicEncryptedPacket* packet = undecryptable_packets_.front().get();
2577 if (!framer_.ProcessPacket(*packet) &&
2578 framer_.error() == QUIC_DECRYPTION_FAILURE) {
2579 QUIC_DVLOG(1) << ENDPOINT << "Unable to process undecryptable packet...";
2580 break;
2581 }
2582 QUIC_DVLOG(1) << ENDPOINT << "Processed undecryptable packet!";
2583 ++stats_.packets_processed;
2584 undecryptable_packets_.pop_front();
2585 }
2586
2587 // Once forward secure encryption is in use, there will be no
2588 // new keys installed and hence any undecryptable packets will
2589 // never be able to be decrypted.
2590 if (encryption_level_ == ENCRYPTION_FORWARD_SECURE) {
2591 if (debug_visitor_ != nullptr) {
2592 // TODO(rtenneti): perhaps more efficient to pass the number of
2593 // undecryptable packets as the argument to OnUndecryptablePacket so that
2594 // we just need to call OnUndecryptablePacket once?
2595 for (size_t i = 0; i < undecryptable_packets_.size(); ++i) {
2596 debug_visitor_->OnUndecryptablePacket();
2597 }
2598 }
2599 undecryptable_packets_.clear();
2600 }
2601}
2602
2603void QuicConnection::QueueCoalescedPacket(const QuicEncryptedPacket& packet) {
2604 QUIC_DVLOG(1) << ENDPOINT << "Queueing coalesced packet.";
2605 coalesced_packets_.push_back(packet.Clone());
2606}
2607
2608void QuicConnection::MaybeProcessCoalescedPackets() {
2609 bool processed = false;
2610 for (const auto& packet : coalesced_packets_) {
2611 if (!connected_) {
2612 return;
2613 }
2614
2615 // }
2616 // while (connected_ && !coalesced_packets_.empty()) {
2617 QUIC_DVLOG(1) << ENDPOINT << "Processing coalesced packet";
2618 // QuicEncryptedPacket* packet = coalesced_packets_.front().get();
2619 if (framer_.ProcessPacket(*packet)) {
2620 processed = true;
2621 } else {
2622 // If we are unable to decrypt this packet, it might be
2623 // because the CHLO or SHLO packet was lost.
2624 if (framer_.error() == QUIC_DECRYPTION_FAILURE) {
dschinazi6ece5002019-05-22 06:35:49 -07002625 ++stats_.undecryptable_packets_received;
QUICHE teama6ef0a62019-03-07 20:34:33 -05002626 if (encryption_level_ != ENCRYPTION_FORWARD_SECURE &&
2627 undecryptable_packets_.size() < max_undecryptable_packets_) {
2628 QueueUndecryptablePacket(*packet);
2629 } else if (debug_visitor_ != nullptr) {
2630 debug_visitor_->OnUndecryptablePacket();
2631 }
2632 }
2633 }
2634 // coalesced_packets_.pop_front();
2635 }
2636 coalesced_packets_.clear();
2637 if (processed) {
2638 MaybeProcessUndecryptablePackets();
2639 }
2640}
2641
2642void QuicConnection::CloseConnection(
2643 QuicErrorCode error,
vasilvvc48c8712019-03-11 13:38:16 -07002644 const std::string& error_details,
QUICHE teama6ef0a62019-03-07 20:34:33 -05002645 ConnectionCloseBehavior connection_close_behavior) {
2646 DCHECK(!error_details.empty());
2647 if (!connected_) {
2648 QUIC_DLOG(INFO) << "Connection is already closed.";
2649 return;
2650 }
2651
2652 QUIC_DLOG(INFO) << ENDPOINT << "Closing connection: " << connection_id()
2653 << ", with error: " << QuicErrorCodeToString(error) << " ("
2654 << error << "), and details: " << error_details;
2655
ianswettdc1e7ab2019-05-03 16:10:44 -07002656 if (connection_close_behavior != ConnectionCloseBehavior::SILENT_CLOSE) {
2657 SendConnectionClosePacket(error, error_details);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002658 }
2659
wub5f64ec42019-06-06 07:31:19 -07002660 TearDownLocalConnectionState(error, error_details,
2661 ConnectionCloseSource::FROM_SELF);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002662}
2663
2664void QuicConnection::SendConnectionClosePacket(QuicErrorCode error,
ianswettdc1e7ab2019-05-03 16:10:44 -07002665 const std::string& details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002666 QUIC_DLOG(INFO) << ENDPOINT << "Sending connection close packet.";
QUICHE team2252b702019-05-14 23:55:14 -04002667 SetDefaultEncryptionLevel(GetConnectionCloseEncryptionLevel());
QUICHE teama6ef0a62019-03-07 20:34:33 -05002668 ClearQueuedPackets();
ianswettdc1e7ab2019-05-03 16:10:44 -07002669 // If there was a packet write error, write the smallest close possible.
fayanga4b37b22019-06-18 13:37:47 -07002670 ScopedPacketFlusher flusher(this);
QUICHE teamcd098022019-03-22 18:49:55 -07002671 // When multiple packet number spaces is supported, an ACK frame will be
2672 // bundled when connection is not write blocked.
2673 if (!SupportsMultiplePacketNumberSpaces() &&
fayanga4b37b22019-06-18 13:37:47 -07002674 error != QUIC_PACKET_WRITE_ERROR &&
QUICHE teama6ef0a62019-03-07 20:34:33 -05002675 !GetUpdatedAckFrame().ack_frame->packets.Empty()) {
2676 SendAck();
2677 }
fkastenholze9d71a82019-04-09 05:12:13 -07002678 QuicConnectionCloseFrame* frame =
2679 new QuicConnectionCloseFrame(error, details);
fkastenholz04bd4f32019-04-16 12:24:38 -07002680 // If version99/IETF QUIC set the close type. Default close type is Google
2681 // QUIC.
fkastenholz305e1732019-06-18 05:01:22 -07002682 if (VersionHasIetfQuicFrames(transport_version())) {
fkastenholz72f509b2019-04-10 09:17:49 -07002683 frame->close_type = IETF_QUIC_TRANSPORT_CONNECTION_CLOSE;
2684 }
fayang3203f252019-05-03 06:00:03 -07002685 packet_generator_.ConsumeRetransmittableControlFrame(QuicFrame(frame));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002686 packet_generator_.FlushAllQueuedFrames();
nharperef468962019-07-02 14:15:38 -07002687 if (GetQuicReloadableFlag(quic_clear_queued_packets_on_connection_close)) {
2688 QUIC_RELOADABLE_FLAG_COUNT(quic_clear_queued_packets_on_connection_close);
2689 ClearQueuedPackets();
2690 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002691}
2692
2693void QuicConnection::TearDownLocalConnectionState(
2694 QuicErrorCode error,
vasilvvc48c8712019-03-11 13:38:16 -07002695 const std::string& error_details,
QUICHE teama6ef0a62019-03-07 20:34:33 -05002696 ConnectionCloseSource source) {
2697 if (!connected_) {
2698 QUIC_DLOG(INFO) << "Connection is already closed.";
2699 return;
2700 }
2701
2702 // If we are using a batch writer, flush packets queued in it, if any.
2703 FlushPackets();
2704 connected_ = false;
2705 DCHECK(visitor_ != nullptr);
fkastenholz5d880a92019-06-21 09:01:56 -07002706 // TODO(fkastenholz): When the IETF Transport Connection Close information
2707 // gets plumbed in, expand this constructor to include that information.
2708 QuicConnectionCloseFrame frame(error, error_details);
2709 visitor_->OnConnectionClosed(frame, source);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002710 if (debug_visitor_ != nullptr) {
fkastenholzac11db02019-06-24 06:22:04 -07002711 debug_visitor_->OnConnectionClosed(frame, source);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002712 }
2713 // Cancel the alarms so they don't trigger any action now that the
2714 // connection is closed.
2715 CancelAllAlarms();
2716}
2717
2718void QuicConnection::CancelAllAlarms() {
2719 QUIC_DVLOG(1) << "Cancelling all QuicConnection alarms.";
2720
2721 ack_alarm_->Cancel();
2722 ping_alarm_->Cancel();
2723 retransmission_alarm_->Cancel();
2724 send_alarm_->Cancel();
2725 timeout_alarm_->Cancel();
2726 mtu_discovery_alarm_->Cancel();
2727 path_degrading_alarm_->Cancel();
renjietang11e4a3d2019-05-03 11:27:26 -07002728 process_undecryptable_packets_alarm_->Cancel();
QUICHE teama6ef0a62019-03-07 20:34:33 -05002729}
2730
2731QuicByteCount QuicConnection::max_packet_length() const {
2732 return packet_generator_.GetCurrentMaxPacketLength();
2733}
2734
2735void QuicConnection::SetMaxPacketLength(QuicByteCount length) {
2736 long_term_mtu_ = length;
2737 packet_generator_.SetMaxPacketLength(GetLimitedMaxPacketSize(length));
2738}
2739
2740bool QuicConnection::HasQueuedData() const {
2741 return pending_version_negotiation_packet_ || !queued_packets_.empty() ||
fayang914fbe12019-07-11 06:23:55 -07002742 packet_generator_.HasPendingFrames();
QUICHE teama6ef0a62019-03-07 20:34:33 -05002743}
2744
QUICHE teama6ef0a62019-03-07 20:34:33 -05002745bool QuicConnection::CanWriteStreamData() {
2746 // Don't write stream data if there are negotiation or queued data packets
2747 // to send. Otherwise, continue and bundle as many frames as possible.
2748 if (pending_version_negotiation_packet_ || !queued_packets_.empty()) {
2749 return false;
2750 }
2751
2752 IsHandshake pending_handshake =
2753 visitor_->HasPendingHandshake() ? IS_HANDSHAKE : NOT_HANDSHAKE;
2754 // Sending queued packets may have caused the socket to become write blocked,
2755 // or the congestion manager to prohibit sending. If we've sent everything
2756 // we had queued and we're still not blocked, let the visitor know it can
2757 // write more.
2758 return ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA, pending_handshake);
2759}
2760
2761void QuicConnection::SetNetworkTimeouts(QuicTime::Delta handshake_timeout,
2762 QuicTime::Delta idle_timeout) {
2763 QUIC_BUG_IF(idle_timeout > handshake_timeout)
2764 << "idle_timeout:" << idle_timeout.ToMilliseconds()
2765 << " handshake_timeout:" << handshake_timeout.ToMilliseconds();
2766 // Adjust the idle timeout on client and server to prevent clients from
2767 // sending requests to servers which have already closed the connection.
2768 if (perspective_ == Perspective::IS_SERVER) {
2769 idle_timeout = idle_timeout + QuicTime::Delta::FromSeconds(3);
2770 } else if (idle_timeout > QuicTime::Delta::FromSeconds(1)) {
2771 idle_timeout = idle_timeout - QuicTime::Delta::FromSeconds(1);
2772 }
2773 handshake_timeout_ = handshake_timeout;
2774 idle_network_timeout_ = idle_timeout;
2775
2776 SetTimeoutAlarm();
2777}
2778
2779void QuicConnection::CheckForTimeout() {
2780 QuicTime now = clock_->ApproximateNow();
2781 QuicTime time_of_last_packet =
2782 std::max(time_of_last_received_packet_,
2783 time_of_first_packet_sent_after_receiving_);
2784
2785 // |delta| can be < 0 as |now| is approximate time but |time_of_last_packet|
2786 // is accurate time. However, this should not change the behavior of
2787 // timeout handling.
2788 QuicTime::Delta idle_duration = now - time_of_last_packet;
2789 QUIC_DVLOG(1) << ENDPOINT << "last packet "
2790 << time_of_last_packet.ToDebuggingValue()
2791 << " now:" << now.ToDebuggingValue()
2792 << " idle_duration:" << idle_duration.ToMicroseconds()
2793 << " idle_network_timeout: "
2794 << idle_network_timeout_.ToMicroseconds();
2795 if (idle_duration >= idle_network_timeout_) {
vasilvvc48c8712019-03-11 13:38:16 -07002796 const std::string error_details = "No recent network activity.";
QUICHE teama6ef0a62019-03-07 20:34:33 -05002797 QUIC_DVLOG(1) << ENDPOINT << error_details;
2798 if ((sent_packet_manager_.GetConsecutiveTlpCount() > 0 ||
2799 sent_packet_manager_.GetConsecutiveRtoCount() > 0 ||
2800 visitor_->ShouldKeepConnectionAlive())) {
2801 CloseConnection(QUIC_NETWORK_IDLE_TIMEOUT, error_details,
2802 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
2803 } else {
2804 CloseConnection(QUIC_NETWORK_IDLE_TIMEOUT, error_details,
2805 idle_timeout_connection_close_behavior_);
2806 }
2807 return;
2808 }
2809
2810 if (!handshake_timeout_.IsInfinite()) {
2811 QuicTime::Delta connected_duration = now - stats_.connection_creation_time;
2812 QUIC_DVLOG(1) << ENDPOINT
2813 << "connection time: " << connected_duration.ToMicroseconds()
2814 << " handshake timeout: "
2815 << handshake_timeout_.ToMicroseconds();
2816 if (connected_duration >= handshake_timeout_) {
vasilvvc48c8712019-03-11 13:38:16 -07002817 const std::string error_details = "Handshake timeout expired.";
QUICHE teama6ef0a62019-03-07 20:34:33 -05002818 QUIC_DVLOG(1) << ENDPOINT << error_details;
2819 CloseConnection(QUIC_HANDSHAKE_TIMEOUT, error_details,
2820 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
2821 return;
2822 }
2823 }
2824
2825 SetTimeoutAlarm();
2826}
2827
2828void QuicConnection::SetTimeoutAlarm() {
2829 QuicTime time_of_last_packet =
2830 std::max(time_of_last_received_packet_,
2831 time_of_first_packet_sent_after_receiving_);
2832
2833 QuicTime deadline = time_of_last_packet + idle_network_timeout_;
2834 if (!handshake_timeout_.IsInfinite()) {
2835 deadline = std::min(deadline,
2836 stats_.connection_creation_time + handshake_timeout_);
2837 }
2838
2839 timeout_alarm_->Update(deadline, QuicTime::Delta::Zero());
2840}
2841
2842void QuicConnection::SetPingAlarm() {
2843 if (perspective_ == Perspective::IS_SERVER) {
ianswettb7f7cd22019-05-01 08:04:16 -07002844 // Only clients send pings to avoid NATs from timing out.
QUICHE teama6ef0a62019-03-07 20:34:33 -05002845 return;
2846 }
2847 if (!visitor_->ShouldKeepConnectionAlive()) {
2848 ping_alarm_->Cancel();
ianswettb7f7cd22019-05-01 08:04:16 -07002849 // Don't send a ping unless the application (ie: HTTP/3) says to, usually
2850 // because it is expecting a response from the server.
QUICHE teama6ef0a62019-03-07 20:34:33 -05002851 return;
2852 }
2853 if (retransmittable_on_wire_timeout_.IsInfinite() ||
2854 sent_packet_manager_.HasInFlightPackets()) {
2855 // Extend the ping alarm.
2856 ping_alarm_->Update(clock_->ApproximateNow() + ping_timeout_,
2857 QuicTime::Delta::FromSeconds(1));
2858 return;
2859 }
2860 DCHECK_LT(retransmittable_on_wire_timeout_, ping_timeout_);
2861 // If it's already set to an earlier time, then don't update it.
2862 if (ping_alarm_->IsSet() &&
2863 ping_alarm_->deadline() <
2864 clock_->ApproximateNow() + retransmittable_on_wire_timeout_) {
2865 return;
2866 }
2867 // Use a shorter timeout if there are open streams, but nothing on the wire.
2868 ping_alarm_->Update(
2869 clock_->ApproximateNow() + retransmittable_on_wire_timeout_,
2870 QuicTime::Delta::FromMilliseconds(1));
2871}
2872
2873void QuicConnection::SetRetransmissionAlarm() {
2874 if (packet_generator_.PacketFlusherAttached()) {
2875 pending_retransmission_alarm_ = true;
2876 return;
2877 }
2878 QuicTime retransmission_time = sent_packet_manager_.GetRetransmissionTime();
2879 retransmission_alarm_->Update(retransmission_time,
2880 QuicTime::Delta::FromMilliseconds(1));
2881}
2882
2883void QuicConnection::SetPathDegradingAlarm() {
2884 if (perspective_ == Perspective::IS_SERVER) {
2885 return;
2886 }
2887 const QuicTime::Delta delay = sent_packet_manager_.GetPathDegradingDelay();
2888 path_degrading_alarm_->Update(clock_->ApproximateNow() + delay,
2889 QuicTime::Delta::FromMilliseconds(1));
2890}
2891
2892void QuicConnection::MaybeSetMtuAlarm(QuicPacketNumber sent_packet_number) {
2893 // Do not set the alarm if the target size is less than the current size.
2894 // This covers the case when |mtu_discovery_target_| is at its default value,
2895 // zero.
2896 if (mtu_discovery_target_ <= max_packet_length()) {
2897 return;
2898 }
2899
2900 if (mtu_probe_count_ >= kMtuDiscoveryAttempts) {
2901 return;
2902 }
2903
2904 if (mtu_discovery_alarm_->IsSet()) {
2905 return;
2906 }
2907
2908 if (sent_packet_number >= next_mtu_probe_at_) {
2909 // Use an alarm to send the MTU probe to ensure that no ScopedPacketFlushers
2910 // are active.
2911 mtu_discovery_alarm_->Set(clock_->ApproximateNow());
2912 }
2913}
2914
2915void QuicConnection::MaybeSetAckAlarmTo(QuicTime time) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002916 if (!ack_alarm_->IsSet() || ack_alarm_->deadline() > time) {
2917 ack_alarm_->Update(time, QuicTime::Delta::Zero());
2918 }
2919}
2920
2921QuicConnection::ScopedPacketFlusher::ScopedPacketFlusher(
fayanga4b37b22019-06-18 13:37:47 -07002922 QuicConnection* connection)
QUICHE teama6ef0a62019-03-07 20:34:33 -05002923 : connection_(connection),
2924 flush_and_set_pending_retransmission_alarm_on_delete_(false) {
2925 if (connection_ == nullptr) {
2926 return;
2927 }
2928
2929 if (!connection_->packet_generator_.PacketFlusherAttached()) {
2930 flush_and_set_pending_retransmission_alarm_on_delete_ = true;
2931 connection->packet_generator_.AttachPacketFlusher();
2932 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002933}
2934
2935QuicConnection::ScopedPacketFlusher::~ScopedPacketFlusher() {
fayang0f0c4e62019-07-16 08:55:54 -07002936 if (connection_ == nullptr || !connection_->connected()) {
fayang40ec3ac2019-06-05 09:07:54 -07002937 return;
2938 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002939
2940 if (flush_and_set_pending_retransmission_alarm_on_delete_) {
fayangf477f732019-06-20 07:03:06 -07002941 const QuicTime ack_timeout =
fayang5f464302019-06-20 12:57:33 -07002942 connection_->uber_received_packet_manager_.GetEarliestAckTimeout();
fayangf477f732019-06-20 07:03:06 -07002943 if (ack_timeout.IsInitialized()) {
2944 if (ack_timeout <= connection_->clock_->ApproximateNow() &&
2945 !connection_->CanWrite(NO_RETRANSMITTABLE_DATA)) {
2946 // Cancel ACK alarm if connection is write blocked, and ACK will be
2947 // sent when connection gets unblocked.
2948 connection_->ack_alarm_->Cancel();
2949 } else {
2950 connection_->MaybeSetAckAlarmTo(ack_timeout);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002951 }
fayanga4b37b22019-06-18 13:37:47 -07002952 }
2953 if (connection_->ack_alarm_->IsSet() &&
2954 connection_->ack_alarm_->deadline() <=
2955 connection_->clock_->ApproximateNow()) {
2956 // An ACK needs to be sent right now. This ACK did not get bundled
2957 // because either there was no data to write or packets were marked as
2958 // received after frames were queued in the generator.
2959 if (connection_->send_alarm_->IsSet() &&
2960 connection_->send_alarm_->deadline() <=
QUICHE teama6ef0a62019-03-07 20:34:33 -05002961 connection_->clock_->ApproximateNow()) {
fayanga4b37b22019-06-18 13:37:47 -07002962 // If send alarm will go off soon, let send alarm send the ACK.
2963 connection_->ack_alarm_->Cancel();
fayanga4b37b22019-06-18 13:37:47 -07002964 } else if (connection_->SupportsMultiplePacketNumberSpaces()) {
2965 connection_->SendAllPendingAcks();
2966 } else {
2967 connection_->SendAck();
QUICHE teama6ef0a62019-03-07 20:34:33 -05002968 }
2969 }
2970 connection_->packet_generator_.Flush();
2971 connection_->FlushPackets();
2972 if (connection_->session_decides_what_to_write()) {
2973 // Reset transmission type.
2974 connection_->SetTransmissionType(NOT_RETRANSMISSION);
2975 }
2976
2977 // Once all transmissions are done, check if there is any outstanding data
2978 // to send and notify the congestion controller if not.
2979 //
2980 // Note that this means that the application limited check will happen as
2981 // soon as the last flusher gets destroyed, which is typically after a
2982 // single stream write is finished. This means that if all the data from a
2983 // single write goes through the connection, the application-limited signal
2984 // will fire even if the caller does a write operation immediately after.
2985 // There are two important approaches to remedy this situation:
2986 // (1) Instantiate ScopedPacketFlusher before performing multiple subsequent
2987 // writes, thus deferring this check until all writes are done.
2988 // (2) Write data in chunks sufficiently large so that they cause the
2989 // connection to be limited by the congestion control. Typically, this
2990 // would mean writing chunks larger than the product of the current
2991 // pacing rate and the pacer granularity. So, for instance, if the
2992 // pacing rate of the connection is 1 Gbps, and the pacer granularity is
2993 // 1 ms, the caller should send at least 125k bytes in order to not
2994 // be marked as application-limited.
2995 connection_->CheckIfApplicationLimited();
2996
2997 if (connection_->pending_retransmission_alarm_) {
2998 connection_->SetRetransmissionAlarm();
2999 connection_->pending_retransmission_alarm_ = false;
3000 }
3001 }
3002 DCHECK_EQ(flush_and_set_pending_retransmission_alarm_on_delete_,
3003 !connection_->packet_generator_.PacketFlusherAttached());
3004}
3005
3006HasRetransmittableData QuicConnection::IsRetransmittable(
3007 const SerializedPacket& packet) {
3008 // Retransmitted packets retransmittable frames are owned by the unacked
3009 // packet map, but are not present in the serialized packet.
3010 if (packet.transmission_type != NOT_RETRANSMISSION ||
3011 !packet.retransmittable_frames.empty()) {
3012 return HAS_RETRANSMITTABLE_DATA;
3013 } else {
3014 return NO_RETRANSMITTABLE_DATA;
3015 }
3016}
3017
3018bool QuicConnection::IsTerminationPacket(const SerializedPacket& packet) {
3019 if (packet.retransmittable_frames.empty()) {
3020 return false;
3021 }
3022 for (const QuicFrame& frame : packet.retransmittable_frames) {
3023 if (frame.type == CONNECTION_CLOSE_FRAME) {
3024 return true;
3025 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05003026 }
3027 return false;
3028}
3029
3030void QuicConnection::SetMtuDiscoveryTarget(QuicByteCount target) {
3031 mtu_discovery_target_ = GetLimitedMaxPacketSize(target);
3032}
3033
3034QuicByteCount QuicConnection::GetLimitedMaxPacketSize(
3035 QuicByteCount suggested_max_packet_size) {
3036 if (!peer_address_.IsInitialized()) {
3037 QUIC_BUG << "Attempted to use a connection without a valid peer address";
3038 return suggested_max_packet_size;
3039 }
3040
3041 const QuicByteCount writer_limit = writer_->GetMaxPacketSize(peer_address());
3042
3043 QuicByteCount max_packet_size = suggested_max_packet_size;
3044 if (max_packet_size > writer_limit) {
3045 max_packet_size = writer_limit;
3046 }
dschinazi66dea072019-04-09 11:41:06 -07003047 if (max_packet_size > kMaxOutgoingPacketSize) {
3048 max_packet_size = kMaxOutgoingPacketSize;
QUICHE teama6ef0a62019-03-07 20:34:33 -05003049 }
3050 return max_packet_size;
3051}
3052
3053void QuicConnection::SendMtuDiscoveryPacket(QuicByteCount target_mtu) {
3054 // Currently, this limit is ensured by the caller.
3055 DCHECK_EQ(target_mtu, GetLimitedMaxPacketSize(target_mtu));
3056
3057 // Send the probe.
3058 packet_generator_.GenerateMtuDiscoveryPacket(target_mtu);
3059}
3060
3061// TODO(zhongyi): change this method to generate a connectivity probing packet
3062// and let the caller to call writer to write the packet and handle write
3063// status.
3064bool QuicConnection::SendConnectivityProbingPacket(
3065 QuicPacketWriter* probing_writer,
3066 const QuicSocketAddress& peer_address) {
3067 return SendGenericPathProbePacket(probing_writer, peer_address,
3068 /* is_response= */ false);
3069}
3070
3071void QuicConnection::SendConnectivityProbingResponsePacket(
3072 const QuicSocketAddress& peer_address) {
3073 SendGenericPathProbePacket(nullptr, peer_address,
3074 /* is_response= */ true);
3075}
3076
3077bool QuicConnection::SendGenericPathProbePacket(
3078 QuicPacketWriter* probing_writer,
3079 const QuicSocketAddress& peer_address,
3080 bool is_response) {
3081 DCHECK(peer_address.IsInitialized());
3082 if (!connected_) {
3083 QUIC_BUG << "Not sending connectivity probing packet as connection is "
3084 << "disconnected.";
3085 return false;
3086 }
3087 if (perspective_ == Perspective::IS_SERVER && probing_writer == nullptr) {
3088 // Server can use default packet writer to write packet.
3089 probing_writer = writer_;
3090 }
3091 DCHECK(probing_writer);
3092
3093 if (probing_writer->IsWriteBlocked()) {
3094 QUIC_DLOG(INFO)
3095 << ENDPOINT
3096 << "Writer blocked when sending connectivity probing packet.";
3097 if (probing_writer == writer_) {
3098 // Visitor should not be write blocked if the probing writer is not the
3099 // default packet writer.
3100 visitor_->OnWriteBlocked();
3101 }
3102 return true;
3103 }
3104
3105 QUIC_DLOG(INFO) << ENDPOINT
3106 << "Sending path probe packet for connection_id = "
dschinazi7b9278c2019-05-20 07:36:21 -07003107 << server_connection_id_;
QUICHE teama6ef0a62019-03-07 20:34:33 -05003108
3109 OwningSerializedPacketPointer probing_packet;
fkastenholz305e1732019-06-18 05:01:22 -07003110 if (!VersionHasIetfQuicFrames(transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003111 // Non-IETF QUIC, generate a padded ping regardless of whether this is a
3112 // request or a response.
3113 probing_packet = packet_generator_.SerializeConnectivityProbingPacket();
3114 } else {
3115 if (is_response) {
3116 // Respond using IETF QUIC PATH_RESPONSE frame
3117 if (IsCurrentPacketConnectivityProbing()) {
3118 // Pad the response if the request was a google connectivity probe
3119 // (padded).
3120 probing_packet =
3121 packet_generator_.SerializePathResponseConnectivityProbingPacket(
3122 received_path_challenge_payloads_, /* is_padded = */ true);
3123 received_path_challenge_payloads_.clear();
3124 } else {
3125 // Do not pad the response if the path challenge was not a google
3126 // connectivity probe.
3127 probing_packet =
3128 packet_generator_.SerializePathResponseConnectivityProbingPacket(
3129 received_path_challenge_payloads_,
3130 /* is_padded = */ false);
3131 received_path_challenge_payloads_.clear();
3132 }
3133 } else {
3134 // Request using IETF QUIC PATH_CHALLENGE frame
3135 transmitted_connectivity_probe_payload_ =
3136 QuicMakeUnique<QuicPathFrameBuffer>();
3137 probing_packet =
3138 packet_generator_.SerializePathChallengeConnectivityProbingPacket(
3139 transmitted_connectivity_probe_payload_.get());
3140 if (!probing_packet) {
3141 transmitted_connectivity_probe_payload_ = nullptr;
3142 }
3143 }
3144 }
3145
3146 DCHECK_EQ(IsRetransmittable(*probing_packet), NO_RETRANSMITTABLE_DATA);
3147
3148 const QuicTime packet_send_time = clock_->Now();
dschinazi965ce092019-05-23 06:29:01 -07003149 QUIC_DVLOG(2) << ENDPOINT
3150 << "Sending path probe packet for server connection ID "
3151 << server_connection_id_ << std::endl
3152 << QuicTextUtils::HexDump(
3153 QuicStringPiece(probing_packet->encrypted_buffer,
3154 probing_packet->encrypted_length));
QUICHE teama6ef0a62019-03-07 20:34:33 -05003155 WriteResult result = probing_writer->WritePacket(
3156 probing_packet->encrypted_buffer, probing_packet->encrypted_length,
3157 self_address().host(), peer_address, per_packet_options_);
3158
3159 // If using a batch writer and the probing packet is buffered, flush it.
3160 if (probing_writer->IsBatchMode() && result.status == WRITE_STATUS_OK &&
3161 result.bytes_written == 0) {
3162 result = probing_writer->Flush();
3163 }
3164
3165 if (IsWriteError(result.status)) {
3166 // Write error for any connectivity probe should not affect the connection
3167 // as it is sent on a different path.
3168 QUIC_DLOG(INFO) << ENDPOINT << "Write probing packet failed with error = "
3169 << result.error_code;
3170 return false;
3171 }
3172
3173 if (debug_visitor_ != nullptr) {
3174 debug_visitor_->OnPacketSent(
3175 *probing_packet, probing_packet->original_packet_number,
3176 probing_packet->transmission_type, packet_send_time);
3177 }
3178
3179 // Call OnPacketSent regardless of the write result.
3180 sent_packet_manager_.OnPacketSent(
3181 probing_packet.get(), probing_packet->original_packet_number,
3182 packet_send_time, probing_packet->transmission_type,
3183 NO_RETRANSMITTABLE_DATA);
3184
3185 if (IsWriteBlockedStatus(result.status)) {
3186 if (probing_writer == writer_) {
3187 // Visitor should not be write blocked if the probing writer is not the
3188 // default packet writer.
3189 visitor_->OnWriteBlocked();
3190 }
3191 if (result.status == WRITE_STATUS_BLOCKED_DATA_BUFFERED) {
3192 QUIC_DLOG(INFO) << ENDPOINT << "Write probing packet blocked";
3193 }
3194 }
3195
3196 return true;
3197}
3198
3199void QuicConnection::DiscoverMtu() {
3200 DCHECK(!mtu_discovery_alarm_->IsSet());
3201
3202 // Check if the MTU has been already increased.
3203 if (mtu_discovery_target_ <= max_packet_length()) {
3204 return;
3205 }
3206
3207 // Calculate the packet number of the next probe *before* sending the current
3208 // one. Otherwise, when SendMtuDiscoveryPacket() is called,
3209 // MaybeSetMtuAlarm() will not realize that the probe has been just sent, and
3210 // will reschedule this probe again.
3211 packets_between_mtu_probes_ *= 2;
3212 next_mtu_probe_at_ = sent_packet_manager_.GetLargestSentPacket() +
3213 packets_between_mtu_probes_ + 1;
3214 ++mtu_probe_count_;
3215
3216 QUIC_DVLOG(2) << "Sending a path MTU discovery packet #" << mtu_probe_count_;
3217 SendMtuDiscoveryPacket(mtu_discovery_target_);
3218
3219 DCHECK(!mtu_discovery_alarm_->IsSet());
3220}
3221
3222void QuicConnection::OnEffectivePeerMigrationValidated() {
3223 if (active_effective_peer_migration_type_ == NO_CHANGE) {
3224 QUIC_BUG << "No migration underway.";
3225 return;
3226 }
3227 highest_packet_sent_before_effective_peer_migration_.Clear();
3228 active_effective_peer_migration_type_ = NO_CHANGE;
3229}
3230
3231void QuicConnection::StartEffectivePeerMigration(AddressChangeType type) {
3232 // TODO(fayang): Currently, all peer address change type are allowed. Need to
3233 // add a method ShouldAllowPeerAddressChange(PeerAddressChangeType type) to
3234 // determine whether |type| is allowed.
3235 if (type == NO_CHANGE) {
3236 QUIC_BUG << "EffectivePeerMigration started without address change.";
3237 return;
3238 }
3239 QUIC_DLOG(INFO) << ENDPOINT << "Effective peer's ip:port changed from "
3240 << effective_peer_address_.ToString() << " to "
3241 << GetEffectivePeerAddressFromCurrentPacket().ToString()
3242 << ", address change type is " << type
3243 << ", migrating connection.";
3244
3245 highest_packet_sent_before_effective_peer_migration_ =
3246 sent_packet_manager_.GetLargestSentPacket();
3247 effective_peer_address_ = GetEffectivePeerAddressFromCurrentPacket();
3248 active_effective_peer_migration_type_ = type;
3249
3250 // TODO(wub): Move these calls to OnEffectivePeerMigrationValidated.
3251 OnConnectionMigration(type);
3252}
3253
3254void QuicConnection::OnConnectionMigration(AddressChangeType addr_change_type) {
3255 visitor_->OnConnectionMigration(addr_change_type);
3256 sent_packet_manager_.OnConnectionMigration(addr_change_type);
3257}
3258
3259bool QuicConnection::IsCurrentPacketConnectivityProbing() const {
3260 return is_current_packet_connectivity_probing_;
3261}
3262
3263bool QuicConnection::ack_frame_updated() const {
fayang5f464302019-06-20 12:57:33 -07003264 return uber_received_packet_manager_.IsAckFrameUpdated();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003265}
3266
3267QuicStringPiece QuicConnection::GetCurrentPacket() {
3268 if (current_packet_data_ == nullptr) {
3269 return QuicStringPiece();
3270 }
3271 return QuicStringPiece(current_packet_data_, last_size_);
3272}
3273
3274bool QuicConnection::MaybeConsiderAsMemoryCorruption(
3275 const QuicStreamFrame& frame) {
nharper46833c32019-05-15 21:33:05 -07003276 if (QuicUtils::IsCryptoStreamId(transport_version(), frame.stream_id) ||
QUICHE team6987b4a2019-03-15 16:23:04 -07003277 last_decrypted_packet_level_ != ENCRYPTION_INITIAL) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003278 return false;
3279 }
3280
3281 if (perspective_ == Perspective::IS_SERVER &&
3282 frame.data_length >= sizeof(kCHLO) &&
3283 strncmp(frame.data_buffer, reinterpret_cast<const char*>(&kCHLO),
3284 sizeof(kCHLO)) == 0) {
3285 return true;
3286 }
3287
3288 if (perspective_ == Perspective::IS_CLIENT &&
3289 frame.data_length >= sizeof(kREJ) &&
3290 strncmp(frame.data_buffer, reinterpret_cast<const char*>(&kREJ),
3291 sizeof(kREJ)) == 0) {
3292 return true;
3293 }
3294
3295 return false;
3296}
3297
3298void QuicConnection::MaybeSendProbingRetransmissions() {
3299 DCHECK(fill_up_link_during_probing_);
3300
3301 // Don't send probing retransmissions until the handshake has completed.
3302 if (!sent_packet_manager_.handshake_confirmed() ||
3303 sent_packet_manager().HasUnackedCryptoPackets()) {
3304 return;
3305 }
3306
3307 if (probing_retransmission_pending_) {
3308 QUIC_BUG << "MaybeSendProbingRetransmissions is called while another call "
3309 "to it is already in progress";
3310 return;
3311 }
3312
3313 probing_retransmission_pending_ = true;
3314 SendProbingRetransmissions();
3315 probing_retransmission_pending_ = false;
3316}
3317
3318void QuicConnection::CheckIfApplicationLimited() {
3319 if (session_decides_what_to_write() && probing_retransmission_pending_) {
3320 return;
3321 }
3322
3323 bool application_limited =
3324 queued_packets_.empty() &&
3325 !sent_packet_manager_.HasPendingRetransmissions() &&
3326 !visitor_->WillingAndAbleToWrite();
3327
3328 if (!application_limited) {
3329 return;
3330 }
3331
3332 if (fill_up_link_during_probing_) {
3333 MaybeSendProbingRetransmissions();
3334 if (!CanWrite(HAS_RETRANSMITTABLE_DATA)) {
3335 return;
3336 }
3337 }
3338
3339 sent_packet_manager_.OnApplicationLimited();
3340}
3341
3342void QuicConnection::UpdatePacketContent(PacketContent type) {
3343 if (current_packet_content_ == NOT_PADDED_PING) {
3344 // We have already learned the current packet is not a connectivity
3345 // probing packet. Peer migration should have already been started earlier
3346 // if needed.
3347 return;
3348 }
3349
3350 if (type == NO_FRAMES_RECEIVED) {
3351 return;
3352 }
3353
3354 if (type == FIRST_FRAME_IS_PING) {
3355 if (current_packet_content_ == NO_FRAMES_RECEIVED) {
3356 current_packet_content_ = FIRST_FRAME_IS_PING;
3357 return;
3358 }
3359 }
3360
3361 // In Google QUIC we look for a packet with just a PING and PADDING.
3362 // For IETF QUIC, the packet must consist of just a PATH_CHALLENGE frame,
3363 // followed by PADDING. If the condition is met, mark things as
3364 // connectivity-probing, causing later processing to generate the correct
3365 // response.
3366 if (type == SECOND_FRAME_IS_PADDING &&
3367 current_packet_content_ == FIRST_FRAME_IS_PING) {
3368 current_packet_content_ = SECOND_FRAME_IS_PADDING;
3369 if (perspective_ == Perspective::IS_SERVER) {
3370 is_current_packet_connectivity_probing_ =
3371 current_effective_peer_migration_type_ != NO_CHANGE;
3372 } else {
3373 is_current_packet_connectivity_probing_ =
3374 (last_packet_source_address_ != peer_address_) ||
3375 (last_packet_destination_address_ != self_address_);
3376 }
3377 return;
3378 }
3379
3380 current_packet_content_ = NOT_PADDED_PING;
QUICHE team1f3de242019-03-20 07:24:48 -07003381 if (GetLargestReceivedPacket().IsInitialized() &&
3382 last_header_.packet_number == GetLargestReceivedPacket()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003383 direct_peer_address_ = last_packet_source_address_;
3384 if (current_effective_peer_migration_type_ != NO_CHANGE) {
3385 // Start effective peer migration immediately when the current packet is
3386 // confirmed not a connectivity probing packet.
QUICHE team1f3de242019-03-20 07:24:48 -07003387 // TODO(fayang): When multiple packet number spaces is supported, only
3388 // start peer migration for the application data.
QUICHE teama6ef0a62019-03-07 20:34:33 -05003389 StartEffectivePeerMigration(current_effective_peer_migration_type_);
3390 }
3391 }
3392 current_effective_peer_migration_type_ = NO_CHANGE;
3393}
3394
3395void QuicConnection::MaybeEnableSessionDecidesWhatToWrite() {
3396 // Only enable session decides what to write code path for version 42+,
3397 // because it needs the receiver to allow receiving overlapping stream data.
3398 const bool enable_session_decides_what_to_write =
3399 transport_version() > QUIC_VERSION_39;
3400 sent_packet_manager_.SetSessionDecideWhatToWrite(
3401 enable_session_decides_what_to_write);
3402 packet_generator_.SetCanSetTransmissionType(
3403 enable_session_decides_what_to_write);
3404}
3405
3406void QuicConnection::PostProcessAfterAckFrame(bool send_stop_waiting,
3407 bool acked_new_packet) {
3408 if (no_stop_waiting_frames_) {
fayang5f464302019-06-20 12:57:33 -07003409 uber_received_packet_manager_.DontWaitForPacketsBefore(
3410 last_decrypted_packet_level_,
fayang39915f92019-07-11 13:08:40 -07003411 SupportsMultiplePacketNumberSpaces()
3412 ? sent_packet_manager_.GetLargestPacketPeerKnowsIsAcked(
3413 last_decrypted_packet_level_)
3414 : sent_packet_manager_.largest_packet_peer_knows_is_acked());
QUICHE teama6ef0a62019-03-07 20:34:33 -05003415 }
3416 // Always reset the retransmission alarm when an ack comes in, since we now
3417 // have a better estimate of the current rtt than when it was set.
3418 SetRetransmissionAlarm();
3419 MaybeSetPathDegradingAlarm(acked_new_packet);
3420
QUICHE teama6ef0a62019-03-07 20:34:33 -05003421 if (send_stop_waiting) {
3422 ++stop_waiting_count_;
3423 } else {
3424 stop_waiting_count_ = 0;
3425 }
3426}
3427
3428void QuicConnection::MaybeSetPathDegradingAlarm(bool acked_new_packet) {
3429 if (!sent_packet_manager_.HasInFlightPackets()) {
3430 // There are no retransmittable packets on the wire, so it's impossible to
3431 // say if the connection has degraded.
3432 path_degrading_alarm_->Cancel();
3433 } else if (acked_new_packet) {
3434 // A previously-unacked packet has been acked, which means forward progress
3435 // has been made. Unset |is_path_degrading| if the path was considered as
3436 // degrading previously. Set/update the path degrading alarm.
3437 is_path_degrading_ = false;
3438 SetPathDegradingAlarm();
3439 }
3440}
3441
3442void QuicConnection::SetSessionNotifier(
3443 SessionNotifierInterface* session_notifier) {
3444 sent_packet_manager_.SetSessionNotifier(session_notifier);
3445}
3446
3447void QuicConnection::SetDataProducer(
3448 QuicStreamFrameDataProducer* data_producer) {
3449 framer_.set_data_producer(data_producer);
3450}
3451
3452void QuicConnection::SetTransmissionType(TransmissionType type) {
3453 packet_generator_.SetTransmissionType(type);
3454}
3455
3456bool QuicConnection::session_decides_what_to_write() const {
3457 return sent_packet_manager_.session_decides_what_to_write();
3458}
3459
3460void QuicConnection::UpdateReleaseTimeIntoFuture() {
3461 DCHECK(supports_release_time_);
3462
3463 release_time_into_future_ = std::max(
3464 QuicTime::Delta::FromMilliseconds(kMinReleaseTimeIntoFutureMs),
3465 std::min(
3466 QuicTime::Delta::FromMilliseconds(
3467 GetQuicFlag(FLAGS_quic_max_pace_time_into_future_ms)),
3468 sent_packet_manager_.GetRttStats()->SmoothedOrInitialRtt() *
3469 GetQuicFlag(FLAGS_quic_pace_time_into_future_srtt_fraction)));
3470}
3471
3472void QuicConnection::ResetAckStates() {
3473 ack_alarm_->Cancel();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003474 stop_waiting_count_ = 0;
fayang5f464302019-06-20 12:57:33 -07003475 uber_received_packet_manager_.ResetAckStates(encryption_level_);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003476}
3477
3478MessageStatus QuicConnection::SendMessage(QuicMessageId message_id,
3479 QuicMemSliceSpan message) {
fayangd4291e42019-05-30 10:31:21 -07003480 if (!VersionSupportsMessageFrames(transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003481 QUIC_BUG << "MESSAGE frame is not supported for version "
3482 << transport_version();
3483 return MESSAGE_STATUS_UNSUPPORTED;
3484 }
ianswettb239f862019-04-05 09:15:06 -07003485 if (message.total_length() > GetCurrentLargestMessagePayload()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003486 return MESSAGE_STATUS_TOO_LARGE;
3487 }
3488 if (!CanWrite(HAS_RETRANSMITTABLE_DATA)) {
3489 return MESSAGE_STATUS_BLOCKED;
3490 }
fayanga4b37b22019-06-18 13:37:47 -07003491 ScopedPacketFlusher flusher(this);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003492 return packet_generator_.AddMessageFrame(message_id, message);
3493}
3494
ianswettb239f862019-04-05 09:15:06 -07003495QuicPacketLength QuicConnection::GetCurrentLargestMessagePayload() const {
3496 return packet_generator_.GetCurrentLargestMessagePayload();
3497}
3498
3499QuicPacketLength QuicConnection::GetGuaranteedLargestMessagePayload() const {
3500 return packet_generator_.GetGuaranteedLargestMessagePayload();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003501}
3502
zhongyi546cc452019-04-12 15:27:49 -07003503uint32_t QuicConnection::cipher_id() const {
3504 if (version().KnowsWhichDecrypterToUse()) {
3505 return framer_.GetDecrypter(last_decrypted_packet_level_)->cipher_id();
3506 }
3507 return framer_.decrypter()->cipher_id();
3508}
3509
QUICHE teama6ef0a62019-03-07 20:34:33 -05003510EncryptionLevel QuicConnection::GetConnectionCloseEncryptionLevel() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003511 if (perspective_ == Perspective::IS_CLIENT) {
3512 return encryption_level_;
3513 }
3514 if (sent_packet_manager_.handshake_confirmed()) {
3515 // A forward secure packet has been received.
dschinazi965ce092019-05-23 06:29:01 -07003516 QUIC_BUG_IF(encryption_level_ != ENCRYPTION_FORWARD_SECURE)
3517 << ENDPOINT << "Unexpected connection close encryption level "
3518 << QuicUtils::EncryptionLevelToString(encryption_level_);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003519 return ENCRYPTION_FORWARD_SECURE;
3520 }
3521 if (framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_ZERO_RTT)) {
3522 if (encryption_level_ != ENCRYPTION_ZERO_RTT) {
fayangd4291e42019-05-30 10:31:21 -07003523 if (VersionHasIetfInvariantHeader(transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003524 QUIC_CODE_COUNT(quic_wrong_encryption_level_connection_close_ietf);
3525 } else {
3526 QUIC_CODE_COUNT(quic_wrong_encryption_level_connection_close);
3527 }
3528 }
3529 return ENCRYPTION_ZERO_RTT;
3530 }
QUICHE team6987b4a2019-03-15 16:23:04 -07003531 return ENCRYPTION_INITIAL;
QUICHE teama6ef0a62019-03-07 20:34:33 -05003532}
3533
QUICHE teamcd098022019-03-22 18:49:55 -07003534void QuicConnection::SendAllPendingAcks() {
3535 DCHECK(SupportsMultiplePacketNumberSpaces());
3536 QUIC_DVLOG(1) << ENDPOINT << "Trying to send all pending ACKs";
3537 // Latches current encryption level.
3538 const EncryptionLevel current_encryption_level = encryption_level_;
3539 for (int8_t i = INITIAL_DATA; i <= APPLICATION_DATA; ++i) {
3540 const QuicTime ack_timeout = uber_received_packet_manager_.GetAckTimeout(
3541 static_cast<PacketNumberSpace>(i));
3542 if (!ack_timeout.IsInitialized() ||
3543 ack_timeout > clock_->ApproximateNow()) {
3544 continue;
3545 }
dschinazi05e62b12019-04-18 15:43:41 -07003546 if (!framer_.HasEncrypterOfEncryptionLevel(
3547 QuicUtils::GetEncryptionLevel(static_cast<PacketNumberSpace>(i)))) {
3548 QUIC_BUG << ENDPOINT << "Cannot send ACKs for packet number space "
3549 << static_cast<uint32_t>(i)
3550 << " without corresponding encrypter";
3551 continue;
3552 }
QUICHE teamcd098022019-03-22 18:49:55 -07003553 QUIC_DVLOG(1) << ENDPOINT << "Sending ACK of packet number space: "
3554 << static_cast<uint32_t>(i);
3555 // Switch to the appropriate encryption level.
3556 SetDefaultEncryptionLevel(
3557 QuicUtils::GetEncryptionLevel(static_cast<PacketNumberSpace>(i)));
3558 QuicFrames frames;
3559 frames.push_back(uber_received_packet_manager_.GetUpdatedAckFrame(
3560 static_cast<PacketNumberSpace>(i), clock_->ApproximateNow()));
3561 const bool flushed = packet_generator_.FlushAckFrame(frames);
3562 if (!flushed) {
3563 // Connection is write blocked.
QUICHE teamdb061532019-03-23 18:23:05 -07003564 QUIC_BUG_IF(!writer_->IsWriteBlocked())
3565 << "Writer not blocked, but ACK not flushed for packet space:" << i;
QUICHE teamcd098022019-03-22 18:49:55 -07003566 break;
3567 }
3568 ResetAckStates();
3569 }
3570 // Restores encryption level.
3571 SetDefaultEncryptionLevel(current_encryption_level);
3572
3573 const QuicTime timeout =
3574 uber_received_packet_manager_.GetEarliestAckTimeout();
3575 if (timeout.IsInitialized()) {
3576 // If there are ACKs pending, re-arm ack alarm.
3577 ack_alarm_->Set(timeout);
3578 }
3579 // Only try to bundle retransmittable data with ACK frame if default
3580 // encryption level is forward secure.
3581 if (encryption_level_ != ENCRYPTION_FORWARD_SECURE ||
3582 consecutive_num_packets_with_no_retransmittable_frames_ <
3583 max_consecutive_num_packets_with_no_retransmittable_frames_) {
3584 return;
3585 }
3586 consecutive_num_packets_with_no_retransmittable_frames_ = 0;
3587 if (packet_generator_.HasRetransmittableFrames() ||
3588 visitor_->WillingAndAbleToWrite()) {
3589 // There are pending retransmittable frames.
3590 return;
3591 }
3592
3593 visitor_->OnAckNeedsRetransmittableFrame();
3594}
3595
3596void QuicConnection::MaybeEnableMultiplePacketNumberSpacesSupport() {
fayangbf3d2862019-06-20 14:13:44 -07003597 if (version().handshake_protocol != PROTOCOL_TLS1_3) {
QUICHE teamcd098022019-03-22 18:49:55 -07003598 return;
3599 }
3600 QUIC_DVLOG(1) << ENDPOINT << "connection " << connection_id()
3601 << " supports multiple packet number spaces";
3602 framer_.EnableMultiplePacketNumberSpacesSupport();
3603 sent_packet_manager_.EnableMultiplePacketNumberSpacesSupport();
3604 uber_received_packet_manager_.EnableMultiplePacketNumberSpacesSupport();
3605}
3606
3607bool QuicConnection::SupportsMultiplePacketNumberSpaces() const {
3608 return sent_packet_manager_.supports_multiple_packet_number_spaces();
3609}
3610
QUICHE team76e1c622019-03-19 14:36:39 -07003611void QuicConnection::SetLargestReceivedPacketWithAck(
3612 QuicPacketNumber new_value) {
QUICHE teamcd098022019-03-22 18:49:55 -07003613 if (SupportsMultiplePacketNumberSpaces()) {
3614 largest_seen_packets_with_ack_[QuicUtils::GetPacketNumberSpace(
3615 last_decrypted_packet_level_)] = new_value;
3616 } else {
3617 largest_seen_packet_with_ack_ = new_value;
3618 }
QUICHE team76e1c622019-03-19 14:36:39 -07003619}
3620
3621QuicPacketNumber QuicConnection::GetLargestReceivedPacketWithAck() const {
QUICHE teamcd098022019-03-22 18:49:55 -07003622 if (SupportsMultiplePacketNumberSpaces()) {
3623 return largest_seen_packets_with_ack_[QuicUtils::GetPacketNumberSpace(
3624 last_decrypted_packet_level_)];
3625 }
QUICHE team76e1c622019-03-19 14:36:39 -07003626 return largest_seen_packet_with_ack_;
3627}
3628
3629QuicPacketNumber QuicConnection::GetLargestSentPacket() const {
QUICHE teamcd098022019-03-22 18:49:55 -07003630 if (SupportsMultiplePacketNumberSpaces()) {
3631 return sent_packet_manager_.GetLargestSentPacket(
3632 last_decrypted_packet_level_);
3633 }
QUICHE team76e1c622019-03-19 14:36:39 -07003634 return sent_packet_manager_.GetLargestSentPacket();
3635}
3636
3637QuicPacketNumber QuicConnection::GetLargestAckedPacket() const {
QUICHE teamcd098022019-03-22 18:49:55 -07003638 if (SupportsMultiplePacketNumberSpaces()) {
3639 return sent_packet_manager_.GetLargestAckedPacket(
3640 last_decrypted_packet_level_);
3641 }
QUICHE team76e1c622019-03-19 14:36:39 -07003642 return sent_packet_manager_.GetLargestObserved();
3643}
3644
QUICHE team1f3de242019-03-20 07:24:48 -07003645QuicPacketNumber QuicConnection::GetLargestReceivedPacket() const {
fayang5f464302019-06-20 12:57:33 -07003646 return uber_received_packet_manager_.GetLargestObserved(
3647 last_decrypted_packet_level_);
QUICHE team1f3de242019-03-20 07:24:48 -07003648}
3649
QUICHE teama6ef0a62019-03-07 20:34:33 -05003650size_t QuicConnection::min_received_before_ack_decimation() const {
fayang5f464302019-06-20 12:57:33 -07003651 return uber_received_packet_manager_.min_received_before_ack_decimation();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003652}
3653
3654void QuicConnection::set_min_received_before_ack_decimation(size_t new_value) {
fayang5f464302019-06-20 12:57:33 -07003655 uber_received_packet_manager_.set_min_received_before_ack_decimation(
3656 new_value);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003657}
3658
3659size_t QuicConnection::ack_frequency_before_ack_decimation() const {
fayang5f464302019-06-20 12:57:33 -07003660 return uber_received_packet_manager_.ack_frequency_before_ack_decimation();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003661}
3662
3663void QuicConnection::set_ack_frequency_before_ack_decimation(size_t new_value) {
3664 DCHECK_GT(new_value, 0u);
fayang5f464302019-06-20 12:57:33 -07003665 uber_received_packet_manager_.set_ack_frequency_before_ack_decimation(
3666 new_value);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003667}
3668
fayang21ffb712019-05-16 08:39:26 -07003669const QuicAckFrame& QuicConnection::ack_frame() const {
3670 if (SupportsMultiplePacketNumberSpaces()) {
3671 return uber_received_packet_manager_.GetAckFrame(
3672 QuicUtils::GetPacketNumberSpace(last_decrypted_packet_level_));
3673 }
fayang5f464302019-06-20 12:57:33 -07003674 return uber_received_packet_manager_.ack_frame();
fayang21ffb712019-05-16 08:39:26 -07003675}
3676
dschinazi346b7ce2019-06-05 01:38:18 -07003677void QuicConnection::set_client_connection_id(
3678 QuicConnectionId client_connection_id) {
3679 if (!version().SupportsClientConnectionIds()) {
3680 QUIC_BUG_IF(!client_connection_id.IsEmpty())
3681 << ENDPOINT << "Attempted to use client connection ID "
3682 << client_connection_id << " with unsupported version " << version();
3683 return;
3684 }
3685 client_connection_id_ = client_connection_id;
3686 client_connection_id_is_set_ = true;
3687 QUIC_DLOG(INFO) << ENDPOINT << "setting client connection ID to "
3688 << client_connection_id_
3689 << " for connection with server connection ID "
3690 << server_connection_id_;
3691 packet_generator_.SetClientConnectionId(client_connection_id_);
3692 framer_.SetExpectedClientConnectionIdLength(client_connection_id_.length());
3693}
3694
QUICHE teama6ef0a62019-03-07 20:34:33 -05003695#undef ENDPOINT // undef for jumbo builds
3696} // namespace quic