Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(120)

Side by Side Diff: net/quic/quic_connection.cc

Issue 182523002: Land Recent QUIC Changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixed rch's comments in Patch set 1 of CL 181463007 Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/quic/quic_connection.h ('k') | net/quic/quic_connection_logger.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « net/quic/quic_connection.h ('k') | net/quic/quic_connection_logger.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698