OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/quic_connection.h" | 5 #include "net/quic/quic_connection.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 #include <sys/types.h> | 8 #include <sys/types.h> |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <iterator> | 10 #include <iterator> |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 ack_queued_(false), | 209 ack_queued_(false), |
210 num_packets_received_since_last_ack_sent_(0), | 210 num_packets_received_since_last_ack_sent_(0), |
211 stop_waiting_count_(0), | 211 stop_waiting_count_(0), |
212 ack_alarm_(helper->CreateAlarm(new AckAlarm(this))), | 212 ack_alarm_(helper->CreateAlarm(new AckAlarm(this))), |
213 retransmission_alarm_(helper->CreateAlarm(new RetransmissionAlarm(this))), | 213 retransmission_alarm_(helper->CreateAlarm(new RetransmissionAlarm(this))), |
214 send_alarm_(helper->CreateAlarm(new SendAlarm(this))), | 214 send_alarm_(helper->CreateAlarm(new SendAlarm(this))), |
215 resume_writes_alarm_(helper->CreateAlarm(new SendAlarm(this))), | 215 resume_writes_alarm_(helper->CreateAlarm(new SendAlarm(this))), |
216 timeout_alarm_(helper->CreateAlarm(new TimeoutAlarm(this))), | 216 timeout_alarm_(helper->CreateAlarm(new TimeoutAlarm(this))), |
217 ping_alarm_(helper->CreateAlarm(new PingAlarm(this))), | 217 ping_alarm_(helper->CreateAlarm(new PingAlarm(this))), |
218 packet_generator_(connection_id_, &framer_, random_generator_, this), | 218 packet_generator_(connection_id_, &framer_, random_generator_, this), |
219 idle_network_timeout_( | 219 idle_network_timeout_(FLAGS_quic_unified_timeouts ? |
220 QuicTime::Delta::FromSeconds(kDefaultInitialTimeoutSecs)), | 220 QuicTime::Delta::Infinite() : |
| 221 QuicTime::Delta::FromSeconds(kDefaultIdleTimeoutSecs)), |
221 overall_connection_timeout_(QuicTime::Delta::Infinite()), | 222 overall_connection_timeout_(QuicTime::Delta::Infinite()), |
222 time_of_last_received_packet_(clock_->ApproximateNow()), | 223 time_of_last_received_packet_(clock_->ApproximateNow()), |
223 time_of_last_sent_new_packet_(clock_->ApproximateNow()), | 224 time_of_last_sent_new_packet_(clock_->ApproximateNow()), |
224 sequence_number_of_last_sent_packet_(0), | 225 sequence_number_of_last_sent_packet_(0), |
225 sent_packet_manager_( | 226 sent_packet_manager_( |
226 is_server, clock_, &stats_, | 227 is_server, clock_, &stats_, |
227 FLAGS_quic_use_bbr_congestion_control ? kBBR : kCubic, | 228 FLAGS_quic_use_bbr_congestion_control ? kBBR : kCubic, |
228 FLAGS_quic_use_time_loss_detection ? kTime : kNack), | 229 FLAGS_quic_use_time_loss_detection ? kTime : kNack), |
229 version_negotiation_state_(START_NEGOTIATION), | 230 version_negotiation_state_(START_NEGOTIATION), |
230 is_server_(is_server), | 231 is_server_(is_server), |
231 connected_(true), | 232 connected_(true), |
232 peer_ip_changed_(false), | 233 peer_ip_changed_(false), |
233 peer_port_changed_(false), | 234 peer_port_changed_(false), |
234 self_ip_changed_(false), | 235 self_ip_changed_(false), |
235 self_port_changed_(false) { | 236 self_port_changed_(false) { |
236 #if 0 | |
237 // TODO(rtenneti): Should we enable this code in chromium? | |
238 if (!is_server_) { | |
239 // Pacing will be enabled if the client negotiates it. | |
240 sent_packet_manager_.MaybeEnablePacing(); | |
241 } | |
242 #endif | |
243 DVLOG(1) << ENDPOINT << "Created connection with connection_id: " | 237 DVLOG(1) << ENDPOINT << "Created connection with connection_id: " |
244 << connection_id; | 238 << connection_id; |
245 timeout_alarm_->Set(clock_->ApproximateNow().Add(idle_network_timeout_)); | 239 if (!FLAGS_quic_unified_timeouts) { |
| 240 timeout_alarm_->Set(clock_->ApproximateNow().Add(idle_network_timeout_)); |
| 241 } |
246 framer_.set_visitor(this); | 242 framer_.set_visitor(this); |
247 framer_.set_received_entropy_calculator(&received_packet_manager_); | 243 framer_.set_received_entropy_calculator(&received_packet_manager_); |
248 stats_.connection_creation_time = clock_->ApproximateNow(); | 244 stats_.connection_creation_time = clock_->ApproximateNow(); |
249 sent_packet_manager_.set_network_change_visitor(this); | 245 sent_packet_manager_.set_network_change_visitor(this); |
250 } | 246 } |
251 | 247 |
252 QuicConnection::~QuicConnection() { | 248 QuicConnection::~QuicConnection() { |
253 if (owns_writer_) { | 249 if (owns_writer_) { |
254 delete writer_; | 250 delete writer_; |
255 } | 251 } |
256 STLDeleteElements(&undecryptable_packets_); | 252 STLDeleteElements(&undecryptable_packets_); |
257 STLDeleteValues(&group_map_); | 253 STLDeleteValues(&group_map_); |
258 for (QueuedPacketList::iterator it = queued_packets_.begin(); | 254 for (QueuedPacketList::iterator it = queued_packets_.begin(); |
259 it != queued_packets_.end(); ++it) { | 255 it != queued_packets_.end(); ++it) { |
260 delete it->serialized_packet.retransmittable_frames; | 256 delete it->serialized_packet.retransmittable_frames; |
261 delete it->serialized_packet.packet; | 257 delete it->serialized_packet.packet; |
262 } | 258 } |
263 } | 259 } |
264 | 260 |
265 void QuicConnection::SetFromConfig(const QuicConfig& config) { | 261 void QuicConnection::SetFromConfig(const QuicConfig& config) { |
266 SetIdleNetworkTimeout(config.idle_connection_state_lifetime()); | 262 if (FLAGS_quic_unified_timeouts) { |
| 263 if (config.negotiated()) { |
| 264 SetNetworkTimeouts(QuicTime::Delta::Infinite(), |
| 265 config.IdleConnectionStateLifetime()); |
| 266 } else { |
| 267 SetNetworkTimeouts(config.max_time_before_crypto_handshake(), |
| 268 config.max_idle_time_before_crypto_handshake()); |
| 269 } |
| 270 } else { |
| 271 SetIdleNetworkTimeout(config.IdleConnectionStateLifetime()); |
| 272 } |
267 sent_packet_manager_.SetFromConfig(config); | 273 sent_packet_manager_.SetFromConfig(config); |
268 } | 274 } |
269 | 275 |
270 bool QuicConnection::SelectMutualVersion( | 276 bool QuicConnection::SelectMutualVersion( |
271 const QuicVersionVector& available_versions) { | 277 const QuicVersionVector& available_versions) { |
272 // Try to find the highest mutual version by iterating over supported | 278 // Try to find the highest mutual version by iterating over supported |
273 // versions, starting with the highest, and breaking out of the loop once we | 279 // versions, starting with the highest, and breaking out of the loop once we |
274 // find a matching version in the provided available_versions vector. | 280 // find a matching version in the provided available_versions vector. |
275 const QuicVersionVector& supported_versions = framer_.supported_versions(); | 281 const QuicVersionVector& supported_versions = framer_.supported_versions(); |
276 for (size_t i = 0; i < supported_versions.size(); ++i) { | 282 for (size_t i = 0; i < supported_versions.size(); ++i) { |
(...skipping 1062 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1339 ++stats_.packets_discarded; | 1345 ++stats_.packets_discarded; |
1340 return true; | 1346 return true; |
1341 } | 1347 } |
1342 // Connection close packets are encrypted and saved, so don't exit early. | 1348 // Connection close packets are encrypted and saved, so don't exit early. |
1343 if (writer_->IsWriteBlocked() && !IsConnectionClose(*packet)) { | 1349 if (writer_->IsWriteBlocked() && !IsConnectionClose(*packet)) { |
1344 return false; | 1350 return false; |
1345 } | 1351 } |
1346 | 1352 |
1347 QuicPacketSequenceNumber sequence_number = | 1353 QuicPacketSequenceNumber sequence_number = |
1348 packet->serialized_packet.sequence_number; | 1354 packet->serialized_packet.sequence_number; |
1349 // Some encryption algorithms require the packet sequence numbers not be | |
1350 // repeated. | |
1351 DCHECK_LE(sequence_number_of_last_sent_packet_, sequence_number); | 1355 DCHECK_LE(sequence_number_of_last_sent_packet_, sequence_number); |
1352 sequence_number_of_last_sent_packet_ = sequence_number; | 1356 sequence_number_of_last_sent_packet_ = sequence_number; |
1353 | 1357 |
1354 QuicEncryptedPacket* encrypted = framer_.EncryptPacket( | 1358 QuicEncryptedPacket* encrypted = framer_.EncryptPacket( |
1355 packet->encryption_level, | 1359 packet->encryption_level, |
1356 sequence_number, | 1360 sequence_number, |
1357 *packet->serialized_packet.packet); | 1361 *packet->serialized_packet.packet); |
1358 if (encrypted == NULL) { | 1362 if (encrypted == NULL) { |
1359 LOG(DFATAL) << ENDPOINT << "Failed to encrypt packet number " | 1363 LOG(DFATAL) << ENDPOINT << "Failed to encrypt packet number " |
1360 << sequence_number; | 1364 << sequence_number; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1400 WriteResult result = writer_->WritePacket(encrypted->data(), | 1404 WriteResult result = writer_->WritePacket(encrypted->data(), |
1401 encrypted->length(), | 1405 encrypted->length(), |
1402 self_address().address(), | 1406 self_address().address(), |
1403 peer_address()); | 1407 peer_address()); |
1404 if (result.error_code == ERR_IO_PENDING) { | 1408 if (result.error_code == ERR_IO_PENDING) { |
1405 DCHECK_EQ(WRITE_STATUS_BLOCKED, result.status); | 1409 DCHECK_EQ(WRITE_STATUS_BLOCKED, result.status); |
1406 } | 1410 } |
1407 if (debug_visitor_.get() != NULL) { | 1411 if (debug_visitor_.get() != NULL) { |
1408 // Pass the write result to the visitor. | 1412 // Pass the write result to the visitor. |
1409 debug_visitor_->OnPacketSent(sequence_number, | 1413 debug_visitor_->OnPacketSent(sequence_number, |
| 1414 packet->original_sequence_number, |
1410 packet->encryption_level, | 1415 packet->encryption_level, |
1411 packet->transmission_type, | 1416 packet->transmission_type, |
1412 *encrypted, | 1417 *encrypted, |
1413 result); | 1418 result); |
1414 } | 1419 } |
1415 | 1420 |
1416 if (result.status == WRITE_STATUS_BLOCKED) { | 1421 if (result.status == WRITE_STATUS_BLOCKED) { |
1417 visitor_->OnWriteBlocked(); | 1422 visitor_->OnWriteBlocked(); |
1418 // If the socket buffers the the data, then the packet should not | 1423 // If the socket buffers the the data, then the packet should not |
1419 // be queued and sent again, which would result in an unnecessary | 1424 // be queued and sent again, which would result in an unnecessary |
(...skipping 11 matching lines...) Expand all Loading... |
1431 DVLOG(1) << ENDPOINT << "time of last sent packet: " | 1436 DVLOG(1) << ENDPOINT << "time of last sent packet: " |
1432 << now.ToDebuggingValue(); | 1437 << now.ToDebuggingValue(); |
1433 | 1438 |
1434 // TODO(ianswett): Change the sequence number length and other packet creator | 1439 // TODO(ianswett): Change the sequence number length and other packet creator |
1435 // options by a more explicit API than setting a struct value directly, | 1440 // options by a more explicit API than setting a struct value directly, |
1436 // perhaps via the NetworkChangeVisitor. | 1441 // perhaps via the NetworkChangeVisitor. |
1437 packet_generator_.UpdateSequenceNumberLength( | 1442 packet_generator_.UpdateSequenceNumberLength( |
1438 sent_packet_manager_.least_packet_awaited_by_peer(), | 1443 sent_packet_manager_.least_packet_awaited_by_peer(), |
1439 sent_packet_manager_.GetCongestionWindow()); | 1444 sent_packet_manager_.GetCongestionWindow()); |
1440 | 1445 |
1441 if (packet->original_sequence_number != 0 && debug_visitor_.get() != NULL) { | |
1442 debug_visitor_->OnPacketRetransmitted( | |
1443 packet->original_sequence_number, sequence_number); | |
1444 } | |
1445 bool reset_retransmission_alarm = sent_packet_manager_.OnPacketSent( | 1446 bool reset_retransmission_alarm = sent_packet_manager_.OnPacketSent( |
1446 &packet->serialized_packet, | 1447 &packet->serialized_packet, |
1447 packet->original_sequence_number, | 1448 packet->original_sequence_number, |
1448 now, | 1449 now, |
1449 encrypted->length(), | 1450 encrypted->length(), |
1450 packet->transmission_type, | 1451 packet->transmission_type, |
1451 IsRetransmittable(*packet)); | 1452 IsRetransmittable(*packet)); |
1452 | 1453 |
1453 if (reset_retransmission_alarm || !retransmission_alarm_->IsSet()) { | 1454 if (reset_retransmission_alarm || !retransmission_alarm_->IsSet()) { |
1454 retransmission_alarm_->Update(sent_packet_manager_.GetRetransmissionTime(), | 1455 retransmission_alarm_->Update(sent_packet_manager_.GetRetransmissionTime(), |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1547 void QuicConnection::UpdateStopWaiting(QuicStopWaitingFrame* stop_waiting) { | 1548 void QuicConnection::UpdateStopWaiting(QuicStopWaitingFrame* stop_waiting) { |
1548 stop_waiting->least_unacked = GetLeastUnacked(); | 1549 stop_waiting->least_unacked = GetLeastUnacked(); |
1549 stop_waiting->entropy_hash = sent_entropy_manager_.GetCumulativeEntropy( | 1550 stop_waiting->entropy_hash = sent_entropy_manager_.GetCumulativeEntropy( |
1550 stop_waiting->least_unacked - 1); | 1551 stop_waiting->least_unacked - 1); |
1551 } | 1552 } |
1552 | 1553 |
1553 void QuicConnection::SendPing() { | 1554 void QuicConnection::SendPing() { |
1554 if (retransmission_alarm_->IsSet()) { | 1555 if (retransmission_alarm_->IsSet()) { |
1555 return; | 1556 return; |
1556 } | 1557 } |
1557 if (version() == QUIC_VERSION_16) { | 1558 packet_generator_.AddControlFrame(QuicFrame(new QuicPingFrame)); |
1558 // TODO(rch): remove this when we remove version 15 and 16. | |
1559 // This is a horrible hideous hack which we should not support. | |
1560 IOVector data; | |
1561 char c_data[] = "C"; | |
1562 data.Append(c_data, 1); | |
1563 QuicConsumedData consumed_data = | |
1564 packet_generator_.ConsumeData(kCryptoStreamId, data, 0, false, | |
1565 MAY_FEC_PROTECT, NULL); | |
1566 if (consumed_data.bytes_consumed == 0) { | |
1567 DLOG(ERROR) << "Unable to send ping!?"; | |
1568 } | |
1569 } else { | |
1570 packet_generator_.AddControlFrame(QuicFrame(new QuicPingFrame)); | |
1571 } | |
1572 } | 1559 } |
1573 | 1560 |
1574 void QuicConnection::SendAck() { | 1561 void QuicConnection::SendAck() { |
1575 ack_alarm_->Cancel(); | 1562 ack_alarm_->Cancel(); |
1576 stop_waiting_count_ = 0; | 1563 stop_waiting_count_ = 0; |
1577 num_packets_received_since_last_ack_sent_ = 0; | 1564 num_packets_received_since_last_ack_sent_ = 0; |
1578 bool send_feedback = false; | 1565 bool send_feedback = false; |
1579 | 1566 |
1580 // Deprecating the Congestion Feedback Frame after QUIC_VERSION_22. | 1567 // Deprecating the Congestion Feedback Frame after QUIC_VERSION_22. |
1581 if (version() <= QUIC_VERSION_22) { | 1568 if (version() <= QUIC_VERSION_22) { |
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1892 if (FLAGS_quic_timeouts_only_from_alarms) { | 1879 if (FLAGS_quic_timeouts_only_from_alarms) { |
1893 SetTimeoutAlarm(); | 1880 SetTimeoutAlarm(); |
1894 } else { | 1881 } else { |
1895 CheckForTimeout(); | 1882 CheckForTimeout(); |
1896 } | 1883 } |
1897 } else { | 1884 } else { |
1898 overall_connection_timeout_ = timeout; | 1885 overall_connection_timeout_ = timeout; |
1899 } | 1886 } |
1900 } | 1887 } |
1901 | 1888 |
| 1889 void QuicConnection::SetNetworkTimeouts(QuicTime::Delta overall_timeout, |
| 1890 QuicTime::Delta idle_timeout) { |
| 1891 LOG_IF(DFATAL, idle_timeout > overall_timeout) |
| 1892 << "idle_timeout:" << idle_timeout.ToMilliseconds() |
| 1893 << " overall_timeout:" << overall_timeout.ToMilliseconds(); |
| 1894 // Adjust the idle timeout on client and server to prevent clients from |
| 1895 // sending requests to servers which have already closed the connection. |
| 1896 if (is_server_) { |
| 1897 idle_timeout = idle_timeout.Add(QuicTime::Delta::FromSeconds(1)); |
| 1898 } else if (idle_timeout > QuicTime::Delta::FromSeconds(1)) { |
| 1899 idle_timeout = idle_timeout.Subtract(QuicTime::Delta::FromSeconds(1)); |
| 1900 } |
| 1901 overall_connection_timeout_ = overall_timeout; |
| 1902 idle_network_timeout_ = idle_timeout; |
| 1903 |
| 1904 SetTimeoutAlarm(); |
| 1905 } |
| 1906 |
1902 void QuicConnection::CheckForTimeout() { | 1907 void QuicConnection::CheckForTimeout() { |
1903 QuicTime now = clock_->ApproximateNow(); | 1908 QuicTime now = clock_->ApproximateNow(); |
1904 QuicTime time_of_last_packet = max(time_of_last_received_packet_, | 1909 QuicTime time_of_last_packet = max(time_of_last_received_packet_, |
1905 time_of_last_sent_new_packet_); | 1910 time_of_last_sent_new_packet_); |
1906 | 1911 |
1907 // |delta| can be < 0 as |now| is approximate time but |time_of_last_packet| | 1912 // |delta| can be < 0 as |now| is approximate time but |time_of_last_packet| |
1908 // is accurate time. However, this should not change the behavior of | 1913 // is accurate time. However, this should not change the behavior of |
1909 // timeout handling. | 1914 // timeout handling. |
1910 QuicTime::Delta idle_duration = now.Subtract(time_of_last_packet); | 1915 QuicTime::Delta idle_duration = now.Subtract(time_of_last_packet); |
1911 DVLOG(1) << ENDPOINT << "last packet " | 1916 DVLOG(1) << ENDPOINT << "last packet " |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2026 } | 2031 } |
2027 for (size_t i = 0; i < retransmittable_frames->frames().size(); ++i) { | 2032 for (size_t i = 0; i < retransmittable_frames->frames().size(); ++i) { |
2028 if (retransmittable_frames->frames()[i].type == CONNECTION_CLOSE_FRAME) { | 2033 if (retransmittable_frames->frames()[i].type == CONNECTION_CLOSE_FRAME) { |
2029 return true; | 2034 return true; |
2030 } | 2035 } |
2031 } | 2036 } |
2032 return false; | 2037 return false; |
2033 } | 2038 } |
2034 | 2039 |
2035 } // namespace net | 2040 } // namespace net |
OLD | NEW |