| 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 : connection_(connection) { | 68 : connection_(connection) { |
| 69 } | 69 } |
| 70 | 70 |
| 71 virtual QuicTime OnAlarm() OVERRIDE { | 71 virtual QuicTime OnAlarm() OVERRIDE { |
| 72 connection_->SendAck(); | 72 connection_->SendAck(); |
| 73 return QuicTime::Zero(); | 73 return QuicTime::Zero(); |
| 74 } | 74 } |
| 75 | 75 |
| 76 private: | 76 private: |
| 77 QuicConnection* connection_; | 77 QuicConnection* connection_; |
| 78 |
| 79 DISALLOW_COPY_AND_ASSIGN(AckAlarm); |
| 78 }; | 80 }; |
| 79 | 81 |
| 80 // This alarm will be scheduled any time a data-bearing packet is sent out. | 82 // This alarm will be scheduled any time a data-bearing packet is sent out. |
| 81 // When the alarm goes off, the connection checks to see if the oldest packets | 83 // When the alarm goes off, the connection checks to see if the oldest packets |
| 82 // have been acked, and retransmit them if they have not. | 84 // have been acked, and retransmit them if they have not. |
| 83 class RetransmissionAlarm : public QuicAlarm::Delegate { | 85 class RetransmissionAlarm : public QuicAlarm::Delegate { |
| 84 public: | 86 public: |
| 85 explicit RetransmissionAlarm(QuicConnection* connection) | 87 explicit RetransmissionAlarm(QuicConnection* connection) |
| 86 : connection_(connection) { | 88 : connection_(connection) { |
| 87 } | 89 } |
| 88 | 90 |
| 89 virtual QuicTime OnAlarm() OVERRIDE { | 91 virtual QuicTime OnAlarm() OVERRIDE { |
| 90 connection_->OnRetransmissionTimeout(); | 92 connection_->OnRetransmissionTimeout(); |
| 91 return QuicTime::Zero(); | 93 return QuicTime::Zero(); |
| 92 } | 94 } |
| 93 | 95 |
| 94 private: | 96 private: |
| 95 QuicConnection* connection_; | 97 QuicConnection* connection_; |
| 98 |
| 99 DISALLOW_COPY_AND_ASSIGN(RetransmissionAlarm); |
| 96 }; | 100 }; |
| 97 | 101 |
| 98 // An alarm that is scheduled when the sent scheduler requires a | 102 // An alarm that is scheduled when the sent scheduler requires a |
| 99 // a delay before sending packets and fires when the packet may be sent. | 103 // a delay before sending packets and fires when the packet may be sent. |
| 100 class SendAlarm : public QuicAlarm::Delegate { | 104 class SendAlarm : public QuicAlarm::Delegate { |
| 101 public: | 105 public: |
| 102 explicit SendAlarm(QuicConnection* connection) | 106 explicit SendAlarm(QuicConnection* connection) |
| 103 : connection_(connection) { | 107 : connection_(connection) { |
| 104 } | 108 } |
| 105 | 109 |
| 106 virtual QuicTime OnAlarm() OVERRIDE { | 110 virtual QuicTime OnAlarm() OVERRIDE { |
| 107 connection_->WriteIfNotBlocked(); | 111 connection_->WriteIfNotBlocked(); |
| 108 // Never reschedule the alarm, since CanWrite does that. | 112 // Never reschedule the alarm, since CanWrite does that. |
| 109 return QuicTime::Zero(); | 113 return QuicTime::Zero(); |
| 110 } | 114 } |
| 111 | 115 |
| 112 private: | 116 private: |
| 113 QuicConnection* connection_; | 117 QuicConnection* connection_; |
| 118 |
| 119 DISALLOW_COPY_AND_ASSIGN(SendAlarm); |
| 114 }; | 120 }; |
| 115 | 121 |
| 116 class TimeoutAlarm : public QuicAlarm::Delegate { | 122 class TimeoutAlarm : public QuicAlarm::Delegate { |
| 117 public: | 123 public: |
| 118 explicit TimeoutAlarm(QuicConnection* connection) | 124 explicit TimeoutAlarm(QuicConnection* connection) |
| 119 : connection_(connection) { | 125 : connection_(connection) { |
| 120 } | 126 } |
| 121 | 127 |
| 122 virtual QuicTime OnAlarm() OVERRIDE { | 128 virtual QuicTime OnAlarm() OVERRIDE { |
| 123 connection_->CheckForTimeout(); | 129 connection_->CheckForTimeout(); |
| 124 // Never reschedule the alarm, since CheckForTimeout does that. | 130 // Never reschedule the alarm, since CheckForTimeout does that. |
| 125 return QuicTime::Zero(); | 131 return QuicTime::Zero(); |
| 126 } | 132 } |
| 127 | 133 |
| 128 private: | 134 private: |
| 129 QuicConnection* connection_; | 135 QuicConnection* connection_; |
| 136 |
| 137 DISALLOW_COPY_AND_ASSIGN(TimeoutAlarm); |
| 138 }; |
| 139 |
| 140 class PingAlarm : public QuicAlarm::Delegate { |
| 141 public: |
| 142 explicit PingAlarm(QuicConnection* connection) |
| 143 : connection_(connection) { |
| 144 } |
| 145 |
| 146 virtual QuicTime OnAlarm() OVERRIDE { |
| 147 connection_->SendPing(); |
| 148 return QuicTime::Zero(); |
| 149 } |
| 150 |
| 151 private: |
| 152 QuicConnection* connection_; |
| 130 }; | 153 }; |
| 131 | 154 |
| 132 QuicConnection::PacketType GetPacketType( | 155 QuicConnection::PacketType GetPacketType( |
| 133 const RetransmittableFrames* retransmittable_frames) { | 156 const RetransmittableFrames* retransmittable_frames) { |
| 134 if (!retransmittable_frames) { | 157 if (!retransmittable_frames) { |
| 135 return QuicConnection::NORMAL; | 158 return QuicConnection::NORMAL; |
| 136 } | 159 } |
| 137 for (size_t i = 0; i < retransmittable_frames->frames().size(); ++i) { | 160 for (size_t i = 0; i < retransmittable_frames->frames().size(); ++i) { |
| 138 if (retransmittable_frames->frames()[i].type == CONNECTION_CLOSE_FRAME) { | 161 if (retransmittable_frames->frames()[i].type == CONNECTION_CLOSE_FRAME) { |
| 139 return QuicConnection::CONNECTION_CLOSE; | 162 return QuicConnection::CONNECTION_CLOSE; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 received_packet_manager_( | 207 received_packet_manager_( |
| 185 FLAGS_quic_congestion_control_inter_arrival ? kInterArrival : kTCP, | 208 FLAGS_quic_congestion_control_inter_arrival ? kInterArrival : kTCP, |
| 186 &stats_), | 209 &stats_), |
| 187 ack_queued_(false), | 210 ack_queued_(false), |
| 188 stop_waiting_count_(0), | 211 stop_waiting_count_(0), |
| 189 ack_alarm_(helper->CreateAlarm(new AckAlarm(this))), | 212 ack_alarm_(helper->CreateAlarm(new AckAlarm(this))), |
| 190 retransmission_alarm_(helper->CreateAlarm(new RetransmissionAlarm(this))), | 213 retransmission_alarm_(helper->CreateAlarm(new RetransmissionAlarm(this))), |
| 191 send_alarm_(helper->CreateAlarm(new SendAlarm(this))), | 214 send_alarm_(helper->CreateAlarm(new SendAlarm(this))), |
| 192 resume_writes_alarm_(helper->CreateAlarm(new SendAlarm(this))), | 215 resume_writes_alarm_(helper->CreateAlarm(new SendAlarm(this))), |
| 193 timeout_alarm_(helper->CreateAlarm(new TimeoutAlarm(this))), | 216 timeout_alarm_(helper->CreateAlarm(new TimeoutAlarm(this))), |
| 217 ping_alarm_(helper->CreateAlarm(new PingAlarm(this))), |
| 194 debug_visitor_(NULL), | 218 debug_visitor_(NULL), |
| 195 packet_creator_(connection_id_, &framer_, random_generator_, is_server), | 219 packet_creator_(connection_id_, &framer_, random_generator_, is_server), |
| 196 packet_generator_(this, NULL, &packet_creator_), | 220 packet_generator_(this, NULL, &packet_creator_), |
| 197 idle_network_timeout_( | 221 idle_network_timeout_( |
| 198 QuicTime::Delta::FromSeconds(kDefaultInitialTimeoutSecs)), | 222 QuicTime::Delta::FromSeconds(kDefaultInitialTimeoutSecs)), |
| 199 overall_connection_timeout_(QuicTime::Delta::Infinite()), | 223 overall_connection_timeout_(QuicTime::Delta::Infinite()), |
| 200 creation_time_(clock_->ApproximateNow()), | 224 creation_time_(clock_->ApproximateNow()), |
| 201 time_of_last_received_packet_(clock_->ApproximateNow()), | 225 time_of_last_received_packet_(clock_->ApproximateNow()), |
| 202 time_of_last_sent_new_packet_(clock_->ApproximateNow()), | 226 time_of_last_sent_new_packet_(clock_->ApproximateNow()), |
| 203 sequence_number_of_last_sent_packet_(0), | 227 sequence_number_of_last_sent_packet_(0), |
| (...skipping 849 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1053 QueueUndecryptablePacket(packet); | 1077 QueueUndecryptablePacket(packet); |
| 1054 } | 1078 } |
| 1055 DVLOG(1) << ENDPOINT << "Unable to process packet. Last packet processed: " | 1079 DVLOG(1) << ENDPOINT << "Unable to process packet. Last packet processed: " |
| 1056 << last_header_.packet_sequence_number; | 1080 << last_header_.packet_sequence_number; |
| 1057 return; | 1081 return; |
| 1058 } | 1082 } |
| 1059 | 1083 |
| 1060 MaybeProcessUndecryptablePackets(); | 1084 MaybeProcessUndecryptablePackets(); |
| 1061 MaybeProcessRevivedPacket(); | 1085 MaybeProcessRevivedPacket(); |
| 1062 MaybeSendInResponseToPacket(); | 1086 MaybeSendInResponseToPacket(); |
| 1087 SetPingAlarm(); |
| 1063 } | 1088 } |
| 1064 | 1089 |
| 1065 void QuicConnection::OnCanWrite() { | 1090 void QuicConnection::OnCanWrite() { |
| 1066 DCHECK(!writer_->IsWriteBlocked()); | 1091 DCHECK(!writer_->IsWriteBlocked()); |
| 1067 | 1092 |
| 1068 WriteQueuedPackets(); | 1093 WriteQueuedPackets(); |
| 1069 WritePendingRetransmissions(); | 1094 WritePendingRetransmissions(); |
| 1070 | 1095 |
| 1071 IsHandshake pending_handshake = visitor_->HasPendingHandshake() ? | 1096 IsHandshake pending_handshake = visitor_->HasPendingHandshake() ? |
| 1072 IS_HANDSHAKE : NOT_HANDSHAKE; | 1097 IS_HANDSHAKE : NOT_HANDSHAKE; |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1402 DVLOG(1) << "Write failed with error code: " << result.error_code; | 1427 DVLOG(1) << "Write failed with error code: " << result.error_code; |
| 1403 // We can't send an error as the socket is presumably borked. | 1428 // We can't send an error as the socket is presumably borked. |
| 1404 CloseConnection(QUIC_PACKET_WRITE_ERROR, false); | 1429 CloseConnection(QUIC_PACKET_WRITE_ERROR, false); |
| 1405 return false; | 1430 return false; |
| 1406 } | 1431 } |
| 1407 | 1432 |
| 1408 QuicTime now = clock_->Now(); | 1433 QuicTime now = clock_->Now(); |
| 1409 if (transmission_type == NOT_RETRANSMISSION) { | 1434 if (transmission_type == NOT_RETRANSMISSION) { |
| 1410 time_of_last_sent_new_packet_ = now; | 1435 time_of_last_sent_new_packet_ = now; |
| 1411 } | 1436 } |
| 1437 SetPingAlarm(); |
| 1412 DVLOG(1) << ENDPOINT << "time of last sent packet: " | 1438 DVLOG(1) << ENDPOINT << "time of last sent packet: " |
| 1413 << now.ToDebuggingValue(); | 1439 << now.ToDebuggingValue(); |
| 1414 | 1440 |
| 1415 // TODO(ianswett): Change the sequence number length and other packet creator | 1441 // TODO(ianswett): Change the sequence number length and other packet creator |
| 1416 // options by a more explicit API than setting a struct value directly. | 1442 // options by a more explicit API than setting a struct value directly. |
| 1417 packet_creator_.UpdateSequenceNumberLength( | 1443 packet_creator_.UpdateSequenceNumberLength( |
| 1418 received_packet_manager_.least_packet_awaited_by_peer(), | 1444 received_packet_manager_.least_packet_awaited_by_peer(), |
| 1419 sent_packet_manager_.GetCongestionWindow()); | 1445 sent_packet_manager_.GetCongestionWindow()); |
| 1420 | 1446 |
| 1421 bool reset_retransmission_alarm = | 1447 bool reset_retransmission_alarm = |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1477 queued_packets_.push_back(queued_packet); | 1503 queued_packets_.push_back(queued_packet); |
| 1478 return false; | 1504 return false; |
| 1479 } | 1505 } |
| 1480 | 1506 |
| 1481 void QuicConnection::UpdateStopWaiting(QuicStopWaitingFrame* stop_waiting) { | 1507 void QuicConnection::UpdateStopWaiting(QuicStopWaitingFrame* stop_waiting) { |
| 1482 stop_waiting->least_unacked = GetLeastUnacked(); | 1508 stop_waiting->least_unacked = GetLeastUnacked(); |
| 1483 stop_waiting->entropy_hash = sent_entropy_manager_.EntropyHash( | 1509 stop_waiting->entropy_hash = sent_entropy_manager_.EntropyHash( |
| 1484 stop_waiting->least_unacked - 1); | 1510 stop_waiting->least_unacked - 1); |
| 1485 } | 1511 } |
| 1486 | 1512 |
| 1513 void QuicConnection::SendPing() { |
| 1514 if (retransmission_alarm_->IsSet()) { |
| 1515 return; |
| 1516 } |
| 1517 if (version() <= QUIC_VERSION_17) { |
| 1518 // TODO(rch): remove this when we remove version 17. |
| 1519 // This is a horrible hideous hack which we should not support. |
| 1520 IOVector data; |
| 1521 char c_data[] = "C"; |
| 1522 data.Append(c_data, 1); |
| 1523 QuicConsumedData consumed_data = |
| 1524 packet_generator_.ConsumeData(kCryptoStreamId, data, 0, false, NULL); |
| 1525 if (consumed_data.bytes_consumed == 0) { |
| 1526 DLOG(ERROR) << "Unable to send ping!?"; |
| 1527 } |
| 1528 } else { |
| 1529 // TODO(rch): enable this when we merge version 18. |
| 1530 // packet_generator_.AddControlFrame(QuicFrame(new QuicPingFrame)); |
| 1531 } |
| 1532 } |
| 1533 |
| 1487 void QuicConnection::SendAck() { | 1534 void QuicConnection::SendAck() { |
| 1488 ack_alarm_->Cancel(); | 1535 ack_alarm_->Cancel(); |
| 1489 stop_waiting_count_ = 0; | 1536 stop_waiting_count_ = 0; |
| 1490 // TODO(rch): delay this until the CreateFeedbackFrame | 1537 // TODO(rch): delay this until the CreateFeedbackFrame |
| 1491 // method is invoked. This requires changes SetShouldSendAck | 1538 // method is invoked. This requires changes SetShouldSendAck |
| 1492 // to be a no-arg method, and re-jiggering its implementation. | 1539 // to be a no-arg method, and re-jiggering its implementation. |
| 1493 bool send_feedback = false; | 1540 bool send_feedback = false; |
| 1494 if (received_packet_manager_.GenerateCongestionFeedback( | 1541 if (received_packet_manager_.GenerateCongestionFeedback( |
| 1495 &outgoing_congestion_feedback_)) { | 1542 &outgoing_congestion_feedback_)) { |
| 1496 DVLOG(1) << ENDPOINT << "Sending feedback: " | 1543 DVLOG(1) << ENDPOINT << "Sending feedback: " |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1801 if (connection_timeout < timeout) { | 1848 if (connection_timeout < timeout) { |
| 1802 timeout = connection_timeout; | 1849 timeout = connection_timeout; |
| 1803 } | 1850 } |
| 1804 } | 1851 } |
| 1805 | 1852 |
| 1806 timeout_alarm_->Cancel(); | 1853 timeout_alarm_->Cancel(); |
| 1807 timeout_alarm_->Set(clock_->ApproximateNow().Add(timeout)); | 1854 timeout_alarm_->Set(clock_->ApproximateNow().Add(timeout)); |
| 1808 return false; | 1855 return false; |
| 1809 } | 1856 } |
| 1810 | 1857 |
| 1858 void QuicConnection::SetPingAlarm() { |
| 1859 if (is_server_) { |
| 1860 // Only clients send pings. |
| 1861 return; |
| 1862 } |
| 1863 ping_alarm_->Cancel(); |
| 1864 if (!visitor_->HasOpenDataStreams()) { |
| 1865 // Don't send a ping unless there are open streams. |
| 1866 return; |
| 1867 } |
| 1868 QuicTime::Delta ping_timeout = QuicTime::Delta::FromSeconds(kPingTimeoutSecs); |
| 1869 ping_alarm_->Set(clock_->ApproximateNow().Add(ping_timeout)); |
| 1870 } |
| 1871 |
| 1811 QuicConnection::ScopedPacketBundler::ScopedPacketBundler( | 1872 QuicConnection::ScopedPacketBundler::ScopedPacketBundler( |
| 1812 QuicConnection* connection, | 1873 QuicConnection* connection, |
| 1813 AckBundling send_ack) | 1874 AckBundling send_ack) |
| 1814 : connection_(connection), | 1875 : connection_(connection), |
| 1815 already_in_batch_mode_(connection->packet_generator_.InBatchMode()) { | 1876 already_in_batch_mode_(connection->packet_generator_.InBatchMode()) { |
| 1816 // Move generator into batch mode. If caller wants us to include an ack, | 1877 // Move generator into batch mode. If caller wants us to include an ack, |
| 1817 // check the delayed-ack timer to see if there's ack info to be sent. | 1878 // check the delayed-ack timer to see if there's ack info to be sent. |
| 1818 if (!already_in_batch_mode_) { | 1879 if (!already_in_batch_mode_) { |
| 1819 DVLOG(1) << "Entering Batch Mode."; | 1880 DVLOG(1) << "Entering Batch Mode."; |
| 1820 connection_->packet_generator_.StartBatchOperations(); | 1881 connection_->packet_generator_.StartBatchOperations(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1833 // If we changed the generator's batch state, restore original batch state. | 1894 // If we changed the generator's batch state, restore original batch state. |
| 1834 if (!already_in_batch_mode_) { | 1895 if (!already_in_batch_mode_) { |
| 1835 DVLOG(1) << "Leaving Batch Mode."; | 1896 DVLOG(1) << "Leaving Batch Mode."; |
| 1836 connection_->packet_generator_.FinishBatchOperations(); | 1897 connection_->packet_generator_.FinishBatchOperations(); |
| 1837 } | 1898 } |
| 1838 DCHECK_EQ(already_in_batch_mode_, | 1899 DCHECK_EQ(already_in_batch_mode_, |
| 1839 connection_->packet_generator_.InBatchMode()); | 1900 connection_->packet_generator_.InBatchMode()); |
| 1840 } | 1901 } |
| 1841 | 1902 |
| 1842 } // namespace net | 1903 } // namespace net |
| OLD | NEW |