| 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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 packet.retransmittable_frames != NULL) ? | 155 packet.retransmittable_frames != NULL) ? |
| 156 HAS_RETRANSMITTABLE_DATA : NO_RETRANSMITTABLE_DATA), | 156 HAS_RETRANSMITTABLE_DATA : NO_RETRANSMITTABLE_DATA), |
| 157 handshake(packet.retransmittable_frames == NULL ? | 157 handshake(packet.retransmittable_frames == NULL ? |
| 158 NOT_HANDSHAKE : packet.retransmittable_frames->HasCryptoHandshake()), | 158 NOT_HANDSHAKE : packet.retransmittable_frames->HasCryptoHandshake()), |
| 159 type(GetPacketType(packet.retransmittable_frames)), | 159 type(GetPacketType(packet.retransmittable_frames)), |
| 160 length(packet.packet->length()) { | 160 length(packet.packet->length()) { |
| 161 } | 161 } |
| 162 | 162 |
| 163 #define ENDPOINT (is_server_ ? "Server: " : " Client: ") | 163 #define ENDPOINT (is_server_ ? "Server: " : " Client: ") |
| 164 | 164 |
| 165 QuicConnection::QuicConnection(QuicGuid guid, | 165 QuicConnection::QuicConnection(QuicConnectionId connection_id, |
| 166 IPEndPoint address, | 166 IPEndPoint address, |
| 167 QuicConnectionHelperInterface* helper, | 167 QuicConnectionHelperInterface* helper, |
| 168 QuicPacketWriter* writer, | 168 QuicPacketWriter* writer, |
| 169 bool is_server, | 169 bool is_server, |
| 170 const QuicVersionVector& supported_versions) | 170 const QuicVersionVector& supported_versions) |
| 171 : framer_(supported_versions, | 171 : framer_(supported_versions, |
| 172 helper->GetClock()->ApproximateNow(), | 172 helper->GetClock()->ApproximateNow(), |
| 173 is_server), | 173 is_server), |
| 174 helper_(helper), | 174 helper_(helper), |
| 175 writer_(writer), | 175 writer_(writer), |
| 176 encryption_level_(ENCRYPTION_NONE), | 176 encryption_level_(ENCRYPTION_NONE), |
| 177 clock_(helper->GetClock()), | 177 clock_(helper->GetClock()), |
| 178 random_generator_(helper->GetRandomGenerator()), | 178 random_generator_(helper->GetRandomGenerator()), |
| 179 guid_(guid), | 179 connection_id_(connection_id), |
| 180 peer_address_(address), | 180 peer_address_(address), |
| 181 largest_seen_packet_with_ack_(0), | 181 largest_seen_packet_with_ack_(0), |
| 182 largest_seen_packet_with_stop_waiting_(0), | 182 largest_seen_packet_with_stop_waiting_(0), |
| 183 pending_version_negotiation_packet_(false), | 183 pending_version_negotiation_packet_(false), |
| 184 received_packet_manager_(kTCP), | 184 received_packet_manager_(kTCP), |
| 185 ack_queued_(false), | 185 ack_queued_(false), |
| 186 stop_waiting_count_(0), | 186 stop_waiting_count_(0), |
| 187 ack_alarm_(helper->CreateAlarm(new AckAlarm(this))), | 187 ack_alarm_(helper->CreateAlarm(new AckAlarm(this))), |
| 188 retransmission_alarm_(helper->CreateAlarm(new RetransmissionAlarm(this))), | 188 retransmission_alarm_(helper->CreateAlarm(new RetransmissionAlarm(this))), |
| 189 send_alarm_(helper->CreateAlarm(new SendAlarm(this))), | 189 send_alarm_(helper->CreateAlarm(new SendAlarm(this))), |
| 190 resume_writes_alarm_(helper->CreateAlarm(new SendAlarm(this))), | 190 resume_writes_alarm_(helper->CreateAlarm(new SendAlarm(this))), |
| 191 timeout_alarm_(helper->CreateAlarm(new TimeoutAlarm(this))), | 191 timeout_alarm_(helper->CreateAlarm(new TimeoutAlarm(this))), |
| 192 debug_visitor_(NULL), | 192 debug_visitor_(NULL), |
| 193 packet_creator_(guid_, &framer_, random_generator_, is_server), | 193 packet_creator_(connection_id_, &framer_, random_generator_, is_server), |
| 194 packet_generator_(this, NULL, &packet_creator_), | 194 packet_generator_(this, NULL, &packet_creator_), |
| 195 idle_network_timeout_( | 195 idle_network_timeout_( |
| 196 QuicTime::Delta::FromSeconds(kDefaultInitialTimeoutSecs)), | 196 QuicTime::Delta::FromSeconds(kDefaultInitialTimeoutSecs)), |
| 197 overall_connection_timeout_(QuicTime::Delta::Infinite()), | 197 overall_connection_timeout_(QuicTime::Delta::Infinite()), |
| 198 creation_time_(clock_->ApproximateNow()), | 198 creation_time_(clock_->ApproximateNow()), |
| 199 time_of_last_received_packet_(clock_->ApproximateNow()), | 199 time_of_last_received_packet_(clock_->ApproximateNow()), |
| 200 time_of_last_sent_new_packet_(clock_->ApproximateNow()), | 200 time_of_last_sent_new_packet_(clock_->ApproximateNow()), |
| 201 sequence_number_of_last_sent_packet_(0), | 201 sequence_number_of_last_sent_packet_(0), |
| 202 sent_packet_manager_(is_server, clock_, &stats_, kTCP), | 202 sent_packet_manager_(is_server, clock_, &stats_, kTCP), |
| 203 version_negotiation_state_(START_NEGOTIATION), | 203 version_negotiation_state_(START_NEGOTIATION), |
| 204 is_server_(is_server), | 204 is_server_(is_server), |
| 205 connected_(true), | 205 connected_(true), |
| 206 address_migrating_(false) { | 206 address_migrating_(false) { |
| 207 if (!is_server_) { | 207 if (!is_server_) { |
| 208 // Pacing will be enabled if the client negotiates it. | 208 // Pacing will be enabled if the client negotiates it. |
| 209 sent_packet_manager_.MaybeEnablePacing(); | 209 sent_packet_manager_.MaybeEnablePacing(); |
| 210 } | 210 } |
| 211 DVLOG(1) << ENDPOINT << "Created connection with guid: " << guid; | 211 DVLOG(1) << ENDPOINT << "Created connection with connection_id: " |
| 212 << connection_id; |
| 212 timeout_alarm_->Set(clock_->ApproximateNow().Add(idle_network_timeout_)); | 213 timeout_alarm_->Set(clock_->ApproximateNow().Add(idle_network_timeout_)); |
| 213 framer_.set_visitor(this); | 214 framer_.set_visitor(this); |
| 214 framer_.set_received_entropy_calculator(&received_packet_manager_); | 215 framer_.set_received_entropy_calculator(&received_packet_manager_); |
| 215 } | 216 } |
| 216 | 217 |
| 217 QuicConnection::~QuicConnection() { | 218 QuicConnection::~QuicConnection() { |
| 218 STLDeleteElements(&undecryptable_packets_); | 219 STLDeleteElements(&undecryptable_packets_); |
| 219 STLDeleteValues(&group_map_); | 220 STLDeleteValues(&group_map_); |
| 220 for (QueuedPacketList::iterator it = queued_packets_.begin(); | 221 for (QueuedPacketList::iterator it = queued_packets_.begin(); |
| 221 it != queued_packets_.end(); ++it) { | 222 it != queued_packets_.end(); ++it) { |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 return false; | 393 return false; |
| 393 } | 394 } |
| 394 | 395 |
| 395 if (!ProcessValidatedPacket()) { | 396 if (!ProcessValidatedPacket()) { |
| 396 return false; | 397 return false; |
| 397 } | 398 } |
| 398 | 399 |
| 399 // Will be decrement below if we fall through to return true; | 400 // Will be decrement below if we fall through to return true; |
| 400 ++stats_.packets_dropped; | 401 ++stats_.packets_dropped; |
| 401 | 402 |
| 402 if (header.public_header.guid != guid_) { | 403 if (header.public_header.connection_id != connection_id_) { |
| 403 DVLOG(1) << ENDPOINT << "Ignoring packet from unexpected GUID: " | 404 DVLOG(1) << ENDPOINT << "Ignoring packet from unexpected ConnectionId: " |
| 404 << header.public_header.guid << " instead of " << guid_; | 405 << header.public_header.connection_id << " instead of " |
| 406 << connection_id_; |
| 405 return false; | 407 return false; |
| 406 } | 408 } |
| 407 | 409 |
| 408 if (!Near(header.packet_sequence_number, | 410 if (!Near(header.packet_sequence_number, |
| 409 last_header_.packet_sequence_number)) { | 411 last_header_.packet_sequence_number)) { |
| 410 DVLOG(1) << ENDPOINT << "Packet " << header.packet_sequence_number | 412 DVLOG(1) << ENDPOINT << "Packet " << header.packet_sequence_number |
| 411 << " out of bounds. Discarding"; | 413 << " out of bounds. Discarding"; |
| 412 SendConnectionCloseWithDetails(QUIC_INVALID_PACKET_HEADER, | 414 SendConnectionCloseWithDetails(QUIC_INVALID_PACKET_HEADER, |
| 413 "Packet sequence number out of bounds"); | 415 "Packet sequence number out of bounds"); |
| 414 return false; | 416 return false; |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 670 last_rst_frames_.push_back(frame); | 672 last_rst_frames_.push_back(frame); |
| 671 return connected_; | 673 return connected_; |
| 672 } | 674 } |
| 673 | 675 |
| 674 bool QuicConnection::OnConnectionCloseFrame( | 676 bool QuicConnection::OnConnectionCloseFrame( |
| 675 const QuicConnectionCloseFrame& frame) { | 677 const QuicConnectionCloseFrame& frame) { |
| 676 DCHECK(connected_); | 678 DCHECK(connected_); |
| 677 if (debug_visitor_) { | 679 if (debug_visitor_) { |
| 678 debug_visitor_->OnConnectionCloseFrame(frame); | 680 debug_visitor_->OnConnectionCloseFrame(frame); |
| 679 } | 681 } |
| 680 DVLOG(1) << ENDPOINT << "Connection " << guid() << " closed with error " | 682 DVLOG(1) << ENDPOINT << "Connection " << connection_id() |
| 683 << " closed with error " |
| 681 << QuicUtils::ErrorToString(frame.error_code) | 684 << QuicUtils::ErrorToString(frame.error_code) |
| 682 << " " << frame.error_details; | 685 << " " << frame.error_details; |
| 683 last_close_frames_.push_back(frame); | 686 last_close_frames_.push_back(frame); |
| 684 return connected_; | 687 return connected_; |
| 685 } | 688 } |
| 686 | 689 |
| 687 bool QuicConnection::OnGoAwayFrame(const QuicGoAwayFrame& frame) { | 690 bool QuicConnection::OnGoAwayFrame(const QuicGoAwayFrame& frame) { |
| 688 DCHECK(connected_); | 691 DCHECK(connected_); |
| 689 DVLOG(1) << ENDPOINT << "Go away received with error " | 692 DVLOG(1) << ENDPOINT << "Go away received with error " |
| 690 << QuicUtils::ErrorToString(frame.error_code) | 693 << QuicUtils::ErrorToString(frame.error_code) |
| (...skipping 29 matching lines...) Expand all Loading... |
| 720 << " packet " << last_header_.packet_sequence_number | 723 << " packet " << last_header_.packet_sequence_number |
| 721 << " with " << last_ack_frames_.size() << " acks, " | 724 << " with " << last_ack_frames_.size() << " acks, " |
| 722 << last_congestion_frames_.size() << " congestions, " | 725 << last_congestion_frames_.size() << " congestions, " |
| 723 << last_stop_waiting_frames_.size() << " stop_waiting, " | 726 << last_stop_waiting_frames_.size() << " stop_waiting, " |
| 724 << last_goaway_frames_.size() << " goaways, " | 727 << last_goaway_frames_.size() << " goaways, " |
| 725 << last_window_update_frames_.size() << " window updates, " | 728 << last_window_update_frames_.size() << " window updates, " |
| 726 << last_blocked_frames_.size() << " blocked, " | 729 << last_blocked_frames_.size() << " blocked, " |
| 727 << last_rst_frames_.size() << " rsts, " | 730 << last_rst_frames_.size() << " rsts, " |
| 728 << last_close_frames_.size() << " closes, " | 731 << last_close_frames_.size() << " closes, " |
| 729 << last_stream_frames_.size() | 732 << last_stream_frames_.size() |
| 730 << " stream frames for " << last_header_.public_header.guid; | 733 << " stream frames for " |
| 734 << last_header_.public_header.connection_id; |
| 731 | 735 |
| 732 MaybeQueueAck(); | 736 MaybeQueueAck(); |
| 733 | 737 |
| 734 // Discard the packet if the visitor fails to process the stream frames. | 738 // Discard the packet if the visitor fails to process the stream frames. |
| 735 if (!last_stream_frames_.empty() && | 739 if (!last_stream_frames_.empty() && |
| 736 !visitor_->OnStreamFrames(last_stream_frames_)) { | 740 !visitor_->OnStreamFrames(last_stream_frames_)) { |
| 737 return; | 741 return; |
| 738 } | 742 } |
| 739 | 743 |
| 740 if (last_packet_revived_) { | 744 if (last_packet_revived_) { |
| (...skipping 815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1556 } | 1560 } |
| 1557 | 1561 |
| 1558 void QuicConnection::MaybeProcessRevivedPacket() { | 1562 void QuicConnection::MaybeProcessRevivedPacket() { |
| 1559 QuicFecGroup* group = GetFecGroup(); | 1563 QuicFecGroup* group = GetFecGroup(); |
| 1560 if (!connected_ || group == NULL || !group->CanRevive()) { | 1564 if (!connected_ || group == NULL || !group->CanRevive()) { |
| 1561 return; | 1565 return; |
| 1562 } | 1566 } |
| 1563 QuicPacketHeader revived_header; | 1567 QuicPacketHeader revived_header; |
| 1564 char revived_payload[kMaxPacketSize]; | 1568 char revived_payload[kMaxPacketSize]; |
| 1565 size_t len = group->Revive(&revived_header, revived_payload, kMaxPacketSize); | 1569 size_t len = group->Revive(&revived_header, revived_payload, kMaxPacketSize); |
| 1566 revived_header.public_header.guid = guid_; | 1570 revived_header.public_header.connection_id = connection_id_; |
| 1567 revived_header.public_header.version_flag = false; | 1571 revived_header.public_header.version_flag = false; |
| 1568 revived_header.public_header.reset_flag = false; | 1572 revived_header.public_header.reset_flag = false; |
| 1569 revived_header.fec_flag = false; | 1573 revived_header.fec_flag = false; |
| 1570 revived_header.is_in_fec_group = NOT_IN_FEC_GROUP; | 1574 revived_header.is_in_fec_group = NOT_IN_FEC_GROUP; |
| 1571 revived_header.fec_group = 0; | 1575 revived_header.fec_group = 0; |
| 1572 group_map_.erase(last_header_.fec_group); | 1576 group_map_.erase(last_header_.fec_group); |
| 1573 delete group; | 1577 delete group; |
| 1574 | 1578 |
| 1575 last_packet_revived_ = true; | 1579 last_packet_revived_ = true; |
| 1576 if (debug_visitor_) { | 1580 if (debug_visitor_) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1611 void QuicConnection::SendConnectionCloseWithDetails(QuicErrorCode error, | 1615 void QuicConnection::SendConnectionCloseWithDetails(QuicErrorCode error, |
| 1612 const string& details) { | 1616 const string& details) { |
| 1613 // If we're write blocked, WritePacket() will not send, but will capture the | 1617 // If we're write blocked, WritePacket() will not send, but will capture the |
| 1614 // serialized packet. | 1618 // serialized packet. |
| 1615 SendConnectionClosePacket(error, details); | 1619 SendConnectionClosePacket(error, details); |
| 1616 CloseConnection(error, false); | 1620 CloseConnection(error, false); |
| 1617 } | 1621 } |
| 1618 | 1622 |
| 1619 void QuicConnection::SendConnectionClosePacket(QuicErrorCode error, | 1623 void QuicConnection::SendConnectionClosePacket(QuicErrorCode error, |
| 1620 const string& details) { | 1624 const string& details) { |
| 1621 DVLOG(1) << ENDPOINT << "Force closing " << guid() << " with error " | 1625 DVLOG(1) << ENDPOINT << "Force closing " << connection_id() |
| 1622 << QuicUtils::ErrorToString(error) << " (" << error << ") " | 1626 << " with error " << QuicUtils::ErrorToString(error) |
| 1623 << details; | 1627 << " (" << error << ") " << details; |
| 1624 ScopedPacketBundler ack_bundler(this, SEND_ACK); | 1628 ScopedPacketBundler ack_bundler(this, SEND_ACK); |
| 1625 QuicConnectionCloseFrame* frame = new QuicConnectionCloseFrame(); | 1629 QuicConnectionCloseFrame* frame = new QuicConnectionCloseFrame(); |
| 1626 frame->error_code = error; | 1630 frame->error_code = error; |
| 1627 frame->error_details = details; | 1631 frame->error_details = details; |
| 1628 packet_generator_.AddControlFrame(QuicFrame(frame)); | 1632 packet_generator_.AddControlFrame(QuicFrame(frame)); |
| 1629 Flush(); | 1633 Flush(); |
| 1630 } | 1634 } |
| 1631 | 1635 |
| 1632 void QuicConnection::CloseConnection(QuicErrorCode error, bool from_peer) { | 1636 void QuicConnection::CloseConnection(QuicErrorCode error, bool from_peer) { |
| 1633 DCHECK(connected_); | 1637 DCHECK(connected_); |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1796 // If we changed the generator's batch state, restore original batch state. | 1800 // If we changed the generator's batch state, restore original batch state. |
| 1797 if (!already_in_batch_mode_) { | 1801 if (!already_in_batch_mode_) { |
| 1798 DVLOG(1) << "Leaving Batch Mode."; | 1802 DVLOG(1) << "Leaving Batch Mode."; |
| 1799 connection_->packet_generator_.FinishBatchOperations(); | 1803 connection_->packet_generator_.FinishBatchOperations(); |
| 1800 } | 1804 } |
| 1801 DCHECK_EQ(already_in_batch_mode_, | 1805 DCHECK_EQ(already_in_batch_mode_, |
| 1802 connection_->packet_generator_.InBatchMode()); | 1806 connection_->packet_generator_.InBatchMode()); |
| 1803 } | 1807 } |
| 1804 | 1808 |
| 1805 } // namespace net | 1809 } // namespace net |
| OLD | NEW |