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> |
11 #include <limits> | 11 #include <limits> |
12 #include <memory> | 12 #include <memory> |
13 #include <set> | 13 #include <set> |
14 #include <utility> | 14 #include <utility> |
15 | 15 |
| 16 #include "base/debug/stack_trace.h" |
16 #include "base/logging.h" | 17 #include "base/logging.h" |
17 #include "base/stl_util.h" | 18 #include "base/stl_util.h" |
18 #include "net/base/net_errors.h" | 19 #include "net/base/net_errors.h" |
19 #include "net/quic/crypto/quic_decrypter.h" | 20 #include "net/quic/crypto/quic_decrypter.h" |
20 #include "net/quic/crypto/quic_encrypter.h" | 21 #include "net/quic/crypto/quic_encrypter.h" |
21 #include "net/quic/iovector.h" | 22 #include "net/quic/iovector.h" |
22 #include "net/quic/quic_bandwidth.h" | 23 #include "net/quic/quic_bandwidth.h" |
23 #include "net/quic/quic_config.h" | 24 #include "net/quic/quic_config.h" |
24 #include "net/quic/quic_utils.h" | 25 #include "net/quic/quic_utils.h" |
25 | 26 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 packet.retransmittable_frames != NULL) ? | 156 packet.retransmittable_frames != NULL) ? |
156 HAS_RETRANSMITTABLE_DATA : NO_RETRANSMITTABLE_DATA), | 157 HAS_RETRANSMITTABLE_DATA : NO_RETRANSMITTABLE_DATA), |
157 handshake(packet.retransmittable_frames == NULL ? | 158 handshake(packet.retransmittable_frames == NULL ? |
158 NOT_HANDSHAKE : packet.retransmittable_frames->HasCryptoHandshake()), | 159 NOT_HANDSHAKE : packet.retransmittable_frames->HasCryptoHandshake()), |
159 type(GetPacketType(packet.retransmittable_frames)), | 160 type(GetPacketType(packet.retransmittable_frames)), |
160 length(packet.packet->length()) { | 161 length(packet.packet->length()) { |
161 } | 162 } |
162 | 163 |
163 #define ENDPOINT (is_server_ ? "Server: " : " Client: ") | 164 #define ENDPOINT (is_server_ ? "Server: " : " Client: ") |
164 | 165 |
165 QuicConnection::QuicConnection(QuicGuid guid, | 166 QuicConnection::QuicConnection(QuicConnectionId connection_id, |
166 IPEndPoint address, | 167 IPEndPoint address, |
167 QuicConnectionHelperInterface* helper, | 168 QuicConnectionHelperInterface* helper, |
168 QuicPacketWriter* writer, | 169 QuicPacketWriter* writer, |
169 bool is_server, | 170 bool is_server, |
170 const QuicVersionVector& supported_versions) | 171 const QuicVersionVector& supported_versions) |
171 : framer_(supported_versions, | 172 : framer_(supported_versions, |
172 helper->GetClock()->ApproximateNow(), | 173 helper->GetClock()->ApproximateNow(), |
173 is_server), | 174 is_server), |
174 helper_(helper), | 175 helper_(helper), |
175 writer_(writer), | 176 writer_(writer), |
176 encryption_level_(ENCRYPTION_NONE), | 177 encryption_level_(ENCRYPTION_NONE), |
177 clock_(helper->GetClock()), | 178 clock_(helper->GetClock()), |
178 random_generator_(helper->GetRandomGenerator()), | 179 random_generator_(helper->GetRandomGenerator()), |
179 guid_(guid), | 180 connection_id_(connection_id), |
180 peer_address_(address), | 181 peer_address_(address), |
181 largest_seen_packet_with_ack_(0), | 182 largest_seen_packet_with_ack_(0), |
182 largest_seen_packet_with_stop_waiting_(0), | 183 largest_seen_packet_with_stop_waiting_(0), |
183 pending_version_negotiation_packet_(false), | 184 pending_version_negotiation_packet_(false), |
184 received_packet_manager_(kTCP), | 185 received_packet_manager_(kTCP), |
185 ack_queued_(false), | 186 ack_queued_(false), |
186 stop_waiting_count_(0), | 187 stop_waiting_count_(0), |
187 ack_alarm_(helper->CreateAlarm(new AckAlarm(this))), | 188 ack_alarm_(helper->CreateAlarm(new AckAlarm(this))), |
188 retransmission_alarm_(helper->CreateAlarm(new RetransmissionAlarm(this))), | 189 retransmission_alarm_(helper->CreateAlarm(new RetransmissionAlarm(this))), |
189 send_alarm_(helper->CreateAlarm(new SendAlarm(this))), | 190 send_alarm_(helper->CreateAlarm(new SendAlarm(this))), |
190 resume_writes_alarm_(helper->CreateAlarm(new SendAlarm(this))), | 191 resume_writes_alarm_(helper->CreateAlarm(new SendAlarm(this))), |
191 timeout_alarm_(helper->CreateAlarm(new TimeoutAlarm(this))), | 192 timeout_alarm_(helper->CreateAlarm(new TimeoutAlarm(this))), |
192 debug_visitor_(NULL), | 193 debug_visitor_(NULL), |
193 packet_creator_(guid_, &framer_, random_generator_, is_server), | 194 packet_creator_(connection_id_, &framer_, random_generator_, is_server), |
194 packet_generator_(this, NULL, &packet_creator_), | 195 packet_generator_(this, NULL, &packet_creator_), |
195 idle_network_timeout_( | 196 idle_network_timeout_( |
196 QuicTime::Delta::FromSeconds(kDefaultInitialTimeoutSecs)), | 197 QuicTime::Delta::FromSeconds(kDefaultInitialTimeoutSecs)), |
197 overall_connection_timeout_(QuicTime::Delta::Infinite()), | 198 overall_connection_timeout_(QuicTime::Delta::Infinite()), |
198 creation_time_(clock_->ApproximateNow()), | 199 creation_time_(clock_->ApproximateNow()), |
199 time_of_last_received_packet_(clock_->ApproximateNow()), | 200 time_of_last_received_packet_(clock_->ApproximateNow()), |
200 time_of_last_sent_new_packet_(clock_->ApproximateNow()), | 201 time_of_last_sent_new_packet_(clock_->ApproximateNow()), |
201 sequence_number_of_last_sent_packet_(0), | 202 sequence_number_of_last_sent_packet_(0), |
202 sent_packet_manager_(is_server, clock_, &stats_, kTCP), | 203 sent_packet_manager_(is_server, clock_, &stats_, kTCP), |
203 version_negotiation_state_(START_NEGOTIATION), | 204 version_negotiation_state_(START_NEGOTIATION), |
204 is_server_(is_server), | 205 is_server_(is_server), |
205 connected_(true), | 206 connected_(true), |
206 address_migrating_(false) { | 207 address_migrating_(false) { |
207 if (!is_server_) { | 208 if (!is_server_) { |
208 // Pacing will be enabled if the client negotiates it. | 209 // Pacing will be enabled if the client negotiates it. |
209 sent_packet_manager_.MaybeEnablePacing(); | 210 sent_packet_manager_.MaybeEnablePacing(); |
210 } | 211 } |
211 DVLOG(1) << ENDPOINT << "Created connection with guid: " << guid; | 212 DVLOG(1) << ENDPOINT << "Created connection with connection_id: " |
| 213 << connection_id; |
212 timeout_alarm_->Set(clock_->ApproximateNow().Add(idle_network_timeout_)); | 214 timeout_alarm_->Set(clock_->ApproximateNow().Add(idle_network_timeout_)); |
213 framer_.set_visitor(this); | 215 framer_.set_visitor(this); |
214 framer_.set_received_entropy_calculator(&received_packet_manager_); | 216 framer_.set_received_entropy_calculator(&received_packet_manager_); |
215 } | 217 } |
216 | 218 |
217 QuicConnection::~QuicConnection() { | 219 QuicConnection::~QuicConnection() { |
218 STLDeleteElements(&undecryptable_packets_); | 220 STLDeleteElements(&undecryptable_packets_); |
219 STLDeleteValues(&group_map_); | 221 STLDeleteValues(&group_map_); |
220 for (QueuedPacketList::iterator it = queued_packets_.begin(); | 222 for (QueuedPacketList::iterator it = queued_packets_.begin(); |
221 it != queued_packets_.end(); ++it) { | 223 it != queued_packets_.end(); ++it) { |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 return false; | 394 return false; |
393 } | 395 } |
394 | 396 |
395 if (!ProcessValidatedPacket()) { | 397 if (!ProcessValidatedPacket()) { |
396 return false; | 398 return false; |
397 } | 399 } |
398 | 400 |
399 // Will be decrement below if we fall through to return true; | 401 // Will be decrement below if we fall through to return true; |
400 ++stats_.packets_dropped; | 402 ++stats_.packets_dropped; |
401 | 403 |
402 if (header.public_header.guid != guid_) { | 404 if (header.public_header.connection_id != connection_id_) { |
403 DVLOG(1) << ENDPOINT << "Ignoring packet from unexpected GUID: " | 405 DVLOG(1) << ENDPOINT << "Ignoring packet from unexpected ConnectionId: " |
404 << header.public_header.guid << " instead of " << guid_; | 406 << header.public_header.connection_id << " instead of " |
| 407 << connection_id_; |
405 return false; | 408 return false; |
406 } | 409 } |
407 | 410 |
408 if (!Near(header.packet_sequence_number, | 411 if (!Near(header.packet_sequence_number, |
409 last_header_.packet_sequence_number)) { | 412 last_header_.packet_sequence_number)) { |
410 DVLOG(1) << ENDPOINT << "Packet " << header.packet_sequence_number | 413 DVLOG(1) << ENDPOINT << "Packet " << header.packet_sequence_number |
411 << " out of bounds. Discarding"; | 414 << " out of bounds. Discarding"; |
412 SendConnectionCloseWithDetails(QUIC_INVALID_PACKET_HEADER, | 415 SendConnectionCloseWithDetails(QUIC_INVALID_PACKET_HEADER, |
413 "Packet sequence number out of bounds"); | 416 "Packet sequence number out of bounds"); |
414 return false; | 417 return false; |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
670 last_rst_frames_.push_back(frame); | 673 last_rst_frames_.push_back(frame); |
671 return connected_; | 674 return connected_; |
672 } | 675 } |
673 | 676 |
674 bool QuicConnection::OnConnectionCloseFrame( | 677 bool QuicConnection::OnConnectionCloseFrame( |
675 const QuicConnectionCloseFrame& frame) { | 678 const QuicConnectionCloseFrame& frame) { |
676 DCHECK(connected_); | 679 DCHECK(connected_); |
677 if (debug_visitor_) { | 680 if (debug_visitor_) { |
678 debug_visitor_->OnConnectionCloseFrame(frame); | 681 debug_visitor_->OnConnectionCloseFrame(frame); |
679 } | 682 } |
680 DVLOG(1) << ENDPOINT << "Connection " << guid() << " closed with error " | 683 DVLOG(1) << ENDPOINT << "Connection " << connection_id() |
| 684 << " closed with error " |
681 << QuicUtils::ErrorToString(frame.error_code) | 685 << QuicUtils::ErrorToString(frame.error_code) |
682 << " " << frame.error_details; | 686 << " " << frame.error_details; |
683 last_close_frames_.push_back(frame); | 687 last_close_frames_.push_back(frame); |
684 return connected_; | 688 return connected_; |
685 } | 689 } |
686 | 690 |
687 bool QuicConnection::OnGoAwayFrame(const QuicGoAwayFrame& frame) { | 691 bool QuicConnection::OnGoAwayFrame(const QuicGoAwayFrame& frame) { |
688 DCHECK(connected_); | 692 DCHECK(connected_); |
689 DVLOG(1) << ENDPOINT << "Go away received with error " | 693 DVLOG(1) << ENDPOINT << "Go away received with error " |
690 << QuicUtils::ErrorToString(frame.error_code) | 694 << QuicUtils::ErrorToString(frame.error_code) |
(...skipping 29 matching lines...) Expand all Loading... |
720 << " packet " << last_header_.packet_sequence_number | 724 << " packet " << last_header_.packet_sequence_number |
721 << " with " << last_ack_frames_.size() << " acks, " | 725 << " with " << last_ack_frames_.size() << " acks, " |
722 << last_congestion_frames_.size() << " congestions, " | 726 << last_congestion_frames_.size() << " congestions, " |
723 << last_stop_waiting_frames_.size() << " stop_waiting, " | 727 << last_stop_waiting_frames_.size() << " stop_waiting, " |
724 << last_goaway_frames_.size() << " goaways, " | 728 << last_goaway_frames_.size() << " goaways, " |
725 << last_window_update_frames_.size() << " window updates, " | 729 << last_window_update_frames_.size() << " window updates, " |
726 << last_blocked_frames_.size() << " blocked, " | 730 << last_blocked_frames_.size() << " blocked, " |
727 << last_rst_frames_.size() << " rsts, " | 731 << last_rst_frames_.size() << " rsts, " |
728 << last_close_frames_.size() << " closes, " | 732 << last_close_frames_.size() << " closes, " |
729 << last_stream_frames_.size() | 733 << last_stream_frames_.size() |
730 << " stream frames for " << last_header_.public_header.guid; | 734 << " stream frames for " |
| 735 << last_header_.public_header.connection_id; |
731 | 736 |
732 MaybeQueueAck(); | 737 MaybeQueueAck(); |
733 | 738 |
734 // Discard the packet if the visitor fails to process the stream frames. | 739 // Discard the packet if the visitor fails to process the stream frames. |
735 if (!last_stream_frames_.empty() && | 740 if (!last_stream_frames_.empty() && |
736 !visitor_->OnStreamFrames(last_stream_frames_)) { | 741 !visitor_->OnStreamFrames(last_stream_frames_)) { |
737 return; | 742 return; |
738 } | 743 } |
739 | 744 |
740 if (last_packet_revived_) { | 745 if (last_packet_revived_) { |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
962 | 967 |
963 void QuicConnection::SendRstStream(QuicStreamId id, | 968 void QuicConnection::SendRstStream(QuicStreamId id, |
964 QuicRstStreamErrorCode error, | 969 QuicRstStreamErrorCode error, |
965 QuicStreamOffset bytes_written) { | 970 QuicStreamOffset bytes_written) { |
966 // Opportunistically bundle an ack with this outgoing packet. | 971 // Opportunistically bundle an ack with this outgoing packet. |
967 ScopedPacketBundler ack_bundler(this, BUNDLE_PENDING_ACK); | 972 ScopedPacketBundler ack_bundler(this, BUNDLE_PENDING_ACK); |
968 packet_generator_.AddControlFrame( | 973 packet_generator_.AddControlFrame( |
969 QuicFrame(new QuicRstStreamFrame(id, error, bytes_written))); | 974 QuicFrame(new QuicRstStreamFrame(id, error, bytes_written))); |
970 } | 975 } |
971 | 976 |
| 977 void QuicConnection::SendWindowUpdate(QuicStreamId id, |
| 978 QuicStreamOffset byte_offset) { |
| 979 // Opportunistically bundle an ack with this outgoing packet. |
| 980 ScopedPacketBundler ack_bundler(this, BUNDLE_PENDING_ACK); |
| 981 packet_generator_.AddControlFrame( |
| 982 QuicFrame(new QuicWindowUpdateFrame(id, byte_offset))); |
| 983 } |
| 984 |
| 985 void QuicConnection::SendBlocked(QuicStreamId id) { |
| 986 // Opportunistically bundle an ack with this outgoing packet. |
| 987 ScopedPacketBundler ack_bundler(this, BUNDLE_PENDING_ACK); |
| 988 packet_generator_.AddControlFrame(QuicFrame(new QuicBlockedFrame(id))); |
| 989 } |
| 990 |
972 const QuicConnectionStats& QuicConnection::GetStats() { | 991 const QuicConnectionStats& QuicConnection::GetStats() { |
973 // Update rtt and estimated bandwidth. | 992 // Update rtt and estimated bandwidth. |
974 stats_.rtt = sent_packet_manager_.SmoothedRtt().ToMicroseconds(); | 993 stats_.rtt = sent_packet_manager_.SmoothedRtt().ToMicroseconds(); |
975 stats_.estimated_bandwidth = | 994 stats_.estimated_bandwidth = |
976 sent_packet_manager_.BandwidthEstimate().ToBytesPerSecond(); | 995 sent_packet_manager_.BandwidthEstimate().ToBytesPerSecond(); |
977 return stats_; | 996 return stats_; |
978 } | 997 } |
979 | 998 |
980 void QuicConnection::ProcessUdpPacket(const IPEndPoint& self_address, | 999 void QuicConnection::ProcessUdpPacket(const IPEndPoint& self_address, |
981 const IPEndPoint& peer_address, | 1000 const IPEndPoint& peer_address, |
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1542 } | 1561 } |
1543 | 1562 |
1544 void QuicConnection::MaybeProcessRevivedPacket() { | 1563 void QuicConnection::MaybeProcessRevivedPacket() { |
1545 QuicFecGroup* group = GetFecGroup(); | 1564 QuicFecGroup* group = GetFecGroup(); |
1546 if (!connected_ || group == NULL || !group->CanRevive()) { | 1565 if (!connected_ || group == NULL || !group->CanRevive()) { |
1547 return; | 1566 return; |
1548 } | 1567 } |
1549 QuicPacketHeader revived_header; | 1568 QuicPacketHeader revived_header; |
1550 char revived_payload[kMaxPacketSize]; | 1569 char revived_payload[kMaxPacketSize]; |
1551 size_t len = group->Revive(&revived_header, revived_payload, kMaxPacketSize); | 1570 size_t len = group->Revive(&revived_header, revived_payload, kMaxPacketSize); |
1552 revived_header.public_header.guid = guid_; | 1571 revived_header.public_header.connection_id = connection_id_; |
1553 revived_header.public_header.version_flag = false; | 1572 revived_header.public_header.version_flag = false; |
1554 revived_header.public_header.reset_flag = false; | 1573 revived_header.public_header.reset_flag = false; |
1555 revived_header.fec_flag = false; | 1574 revived_header.fec_flag = false; |
1556 revived_header.is_in_fec_group = NOT_IN_FEC_GROUP; | 1575 revived_header.is_in_fec_group = NOT_IN_FEC_GROUP; |
1557 revived_header.fec_group = 0; | 1576 revived_header.fec_group = 0; |
1558 group_map_.erase(last_header_.fec_group); | 1577 group_map_.erase(last_header_.fec_group); |
1559 delete group; | 1578 delete group; |
1560 | 1579 |
1561 last_packet_revived_ = true; | 1580 last_packet_revived_ = true; |
1562 if (debug_visitor_) { | 1581 if (debug_visitor_) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1597 void QuicConnection::SendConnectionCloseWithDetails(QuicErrorCode error, | 1616 void QuicConnection::SendConnectionCloseWithDetails(QuicErrorCode error, |
1598 const string& details) { | 1617 const string& details) { |
1599 // If we're write blocked, WritePacket() will not send, but will capture the | 1618 // If we're write blocked, WritePacket() will not send, but will capture the |
1600 // serialized packet. | 1619 // serialized packet. |
1601 SendConnectionClosePacket(error, details); | 1620 SendConnectionClosePacket(error, details); |
1602 CloseConnection(error, false); | 1621 CloseConnection(error, false); |
1603 } | 1622 } |
1604 | 1623 |
1605 void QuicConnection::SendConnectionClosePacket(QuicErrorCode error, | 1624 void QuicConnection::SendConnectionClosePacket(QuicErrorCode error, |
1606 const string& details) { | 1625 const string& details) { |
1607 DVLOG(1) << ENDPOINT << "Force closing " << guid() << " with error " | 1626 DVLOG(1) << ENDPOINT << "Force closing " << connection_id() |
1608 << QuicUtils::ErrorToString(error) << " (" << error << ") " | 1627 << " with error " << QuicUtils::ErrorToString(error) |
1609 << details; | 1628 << " (" << error << ") " << details; |
1610 ScopedPacketBundler ack_bundler(this, SEND_ACK); | 1629 ScopedPacketBundler ack_bundler(this, SEND_ACK); |
1611 QuicConnectionCloseFrame* frame = new QuicConnectionCloseFrame(); | 1630 QuicConnectionCloseFrame* frame = new QuicConnectionCloseFrame(); |
1612 frame->error_code = error; | 1631 frame->error_code = error; |
1613 frame->error_details = details; | 1632 frame->error_details = details; |
1614 packet_generator_.AddControlFrame(QuicFrame(frame)); | 1633 packet_generator_.AddControlFrame(QuicFrame(frame)); |
1615 Flush(); | 1634 Flush(); |
1616 } | 1635 } |
1617 | 1636 |
1618 void QuicConnection::CloseConnection(QuicErrorCode error, bool from_peer) { | 1637 void QuicConnection::CloseConnection(QuicErrorCode error, bool from_peer) { |
1619 DCHECK(connected_); | |
1620 if (!connected_) { | 1638 if (!connected_) { |
| 1639 DLOG(DFATAL) << "Error: attempt to close an already closed connection" |
| 1640 << base::debug::StackTrace().ToString(); |
1621 return; | 1641 return; |
1622 } | 1642 } |
1623 connected_ = false; | 1643 connected_ = false; |
1624 visitor_->OnConnectionClosed(error, from_peer); | 1644 visitor_->OnConnectionClosed(error, from_peer); |
1625 // Cancel the alarms so they don't trigger any action now that the | 1645 // Cancel the alarms so they don't trigger any action now that the |
1626 // connection is closed. | 1646 // connection is closed. |
1627 ack_alarm_->Cancel(); | 1647 ack_alarm_->Cancel(); |
1628 resume_writes_alarm_->Cancel(); | 1648 resume_writes_alarm_->Cancel(); |
1629 retransmission_alarm_->Cancel(); | 1649 retransmission_alarm_->Cancel(); |
1630 send_alarm_->Cancel(); | 1650 send_alarm_->Cancel(); |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1782 // If we changed the generator's batch state, restore original batch state. | 1802 // If we changed the generator's batch state, restore original batch state. |
1783 if (!already_in_batch_mode_) { | 1803 if (!already_in_batch_mode_) { |
1784 DVLOG(1) << "Leaving Batch Mode."; | 1804 DVLOG(1) << "Leaving Batch Mode."; |
1785 connection_->packet_generator_.FinishBatchOperations(); | 1805 connection_->packet_generator_.FinishBatchOperations(); |
1786 } | 1806 } |
1787 DCHECK_EQ(already_in_batch_mode_, | 1807 DCHECK_EQ(already_in_batch_mode_, |
1788 connection_->packet_generator_.InBatchMode()); | 1808 connection_->packet_generator_.InBatchMode()); |
1789 } | 1809 } |
1790 | 1810 |
1791 } // namespace net | 1811 } // namespace net |
OLD | NEW |