| 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/debug/stack_trace.h" |
| 17 #include "base/logging.h" | 17 #include "base/logging.h" |
| 18 #include "base/stl_util.h" | 18 #include "base/stl_util.h" |
| 19 #include "net/base/net_errors.h" | 19 #include "net/base/net_errors.h" |
| 20 #include "net/quic/crypto/quic_decrypter.h" | 20 #include "net/quic/crypto/quic_decrypter.h" |
| 21 #include "net/quic/crypto/quic_encrypter.h" | 21 #include "net/quic/crypto/quic_encrypter.h" |
| 22 #include "net/quic/iovector.h" | 22 #include "net/quic/iovector.h" |
| 23 #include "net/quic/quic_bandwidth.h" | 23 #include "net/quic/quic_bandwidth.h" |
| 24 #include "net/quic/quic_config.h" | 24 #include "net/quic/quic_config.h" |
| 25 #include "net/quic/quic_flags.h" | 25 #include "net/quic/quic_flags.h" |
| 26 #include "net/quic/quic_flow_controller.h" | |
| 27 #include "net/quic/quic_utils.h" | 26 #include "net/quic/quic_utils.h" |
| 28 | 27 |
| 29 using base::hash_map; | 28 using base::hash_map; |
| 30 using base::hash_set; | 29 using base::hash_set; |
| 31 using base::StringPiece; | 30 using base::StringPiece; |
| 32 using std::list; | 31 using std::list; |
| 33 using std::make_pair; | 32 using std::make_pair; |
| 34 using std::min; | 33 using std::min; |
| 35 using std::max; | 34 using std::max; |
| 36 using std::numeric_limits; | 35 using std::numeric_limits; |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 length(packet.packet->length()) { | 185 length(packet.packet->length()) { |
| 187 } | 186 } |
| 188 | 187 |
| 189 #define ENDPOINT (is_server_ ? "Server: " : " Client: ") | 188 #define ENDPOINT (is_server_ ? "Server: " : " Client: ") |
| 190 | 189 |
| 191 QuicConnection::QuicConnection(QuicConnectionId connection_id, | 190 QuicConnection::QuicConnection(QuicConnectionId connection_id, |
| 192 IPEndPoint address, | 191 IPEndPoint address, |
| 193 QuicConnectionHelperInterface* helper, | 192 QuicConnectionHelperInterface* helper, |
| 194 QuicPacketWriter* writer, | 193 QuicPacketWriter* writer, |
| 195 bool is_server, | 194 bool is_server, |
| 196 const QuicVersionVector& supported_versions, | 195 const QuicVersionVector& supported_versions) |
| 197 uint32 max_flow_control_receive_window_bytes) | |
| 198 : framer_(supported_versions, helper->GetClock()->ApproximateNow(), | 196 : framer_(supported_versions, helper->GetClock()->ApproximateNow(), |
| 199 is_server), | 197 is_server), |
| 200 helper_(helper), | 198 helper_(helper), |
| 201 writer_(writer), | 199 writer_(writer), |
| 202 encryption_level_(ENCRYPTION_NONE), | 200 encryption_level_(ENCRYPTION_NONE), |
| 203 clock_(helper->GetClock()), | 201 clock_(helper->GetClock()), |
| 204 random_generator_(helper->GetRandomGenerator()), | 202 random_generator_(helper->GetRandomGenerator()), |
| 205 connection_id_(connection_id), | 203 connection_id_(connection_id), |
| 206 peer_address_(address), | 204 peer_address_(address), |
| 207 migrating_peer_port_(0), | 205 migrating_peer_port_(0), |
| (...skipping 23 matching lines...) Expand all Loading... |
| 231 sequence_number_of_last_sent_packet_(0), | 229 sequence_number_of_last_sent_packet_(0), |
| 232 sent_packet_manager_( | 230 sent_packet_manager_( |
| 233 is_server, clock_, &stats_, kTCP, | 231 is_server, clock_, &stats_, kTCP, |
| 234 FLAGS_quic_use_time_loss_detection ? kTime : kNack), | 232 FLAGS_quic_use_time_loss_detection ? kTime : kNack), |
| 235 version_negotiation_state_(START_NEGOTIATION), | 233 version_negotiation_state_(START_NEGOTIATION), |
| 236 is_server_(is_server), | 234 is_server_(is_server), |
| 237 connected_(true), | 235 connected_(true), |
| 238 peer_ip_changed_(false), | 236 peer_ip_changed_(false), |
| 239 peer_port_changed_(false), | 237 peer_port_changed_(false), |
| 240 self_ip_changed_(false), | 238 self_ip_changed_(false), |
| 241 self_port_changed_(false), | 239 self_port_changed_(false) { |
| 242 max_flow_control_receive_window_bytes_( | |
| 243 max_flow_control_receive_window_bytes) { | |
| 244 if (max_flow_control_receive_window_bytes_ < kDefaultFlowControlSendWindow) { | |
| 245 DLOG(ERROR) << "Initial receive window (" | |
| 246 << max_flow_control_receive_window_bytes_ | |
| 247 << ") cannot be set lower than default (" | |
| 248 << kDefaultFlowControlSendWindow << ")."; | |
| 249 max_flow_control_receive_window_bytes_ = kDefaultFlowControlSendWindow; | |
| 250 } | |
| 251 | |
| 252 flow_controller_.reset(new QuicFlowController( | |
| 253 supported_versions.front(), 0, is_server_, | |
| 254 kDefaultFlowControlSendWindow, max_flow_control_receive_window_bytes_, | |
| 255 max_flow_control_receive_window_bytes_)); | |
| 256 | |
| 257 if (!is_server_) { | 240 if (!is_server_) { |
| 258 // Pacing will be enabled if the client negotiates it. | 241 // Pacing will be enabled if the client negotiates it. |
| 259 sent_packet_manager_.MaybeEnablePacing(); | 242 sent_packet_manager_.MaybeEnablePacing(); |
| 260 } | 243 } |
| 261 DVLOG(1) << ENDPOINT << "Created connection with connection_id: " | 244 DVLOG(1) << ENDPOINT << "Created connection with connection_id: " |
| 262 << connection_id; | 245 << connection_id; |
| 263 timeout_alarm_->Set(clock_->ApproximateNow().Add(idle_network_timeout_)); | 246 timeout_alarm_->Set(clock_->ApproximateNow().Add(idle_network_timeout_)); |
| 264 framer_.set_visitor(this); | 247 framer_.set_visitor(this); |
| 265 framer_.set_received_entropy_calculator(&received_packet_manager_); | 248 framer_.set_received_entropy_calculator(&received_packet_manager_); |
| 266 stats_.connection_creation_time = clock_->ApproximateNow(); | 249 stats_.connection_creation_time = clock_->ApproximateNow(); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 DCHECK(false); | 351 DCHECK(false); |
| 369 } | 352 } |
| 370 | 353 |
| 371 version_negotiation_state_ = NEGOTIATED_VERSION; | 354 version_negotiation_state_ = NEGOTIATED_VERSION; |
| 372 visitor_->OnSuccessfulVersionNegotiation(received_version); | 355 visitor_->OnSuccessfulVersionNegotiation(received_version); |
| 373 DVLOG(1) << ENDPOINT << "version negotiated " << received_version; | 356 DVLOG(1) << ENDPOINT << "version negotiated " << received_version; |
| 374 | 357 |
| 375 // Store the new version. | 358 // Store the new version. |
| 376 framer_.set_version(received_version); | 359 framer_.set_version(received_version); |
| 377 | 360 |
| 378 if (received_version < QUIC_VERSION_19) { | |
| 379 flow_controller_->Disable(); | |
| 380 } | |
| 381 | |
| 382 // TODO(satyamshekhar): Store the sequence number of this packet and close the | 361 // TODO(satyamshekhar): Store the sequence number of this packet and close the |
| 383 // connection if we ever received a packet with incorrect version and whose | 362 // connection if we ever received a packet with incorrect version and whose |
| 384 // sequence number is greater. | 363 // sequence number is greater. |
| 385 return true; | 364 return true; |
| 386 } | 365 } |
| 387 | 366 |
| 388 // Handles version negotiation for client connection. | 367 // Handles version negotiation for client connection. |
| 389 void QuicConnection::OnVersionNegotiationPacket( | 368 void QuicConnection::OnVersionNegotiationPacket( |
| 390 const QuicVersionNegotiationPacket& packet) { | 369 const QuicVersionNegotiationPacket& packet) { |
| 391 if (is_server_) { | 370 if (is_server_) { |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 487 << " without version flag before version negotiated."; | 466 << " without version flag before version negotiated."; |
| 488 // Packets should have the version flag till version negotiation is | 467 // Packets should have the version flag till version negotiation is |
| 489 // done. | 468 // done. |
| 490 CloseConnection(QUIC_INVALID_VERSION, false); | 469 CloseConnection(QUIC_INVALID_VERSION, false); |
| 491 return false; | 470 return false; |
| 492 } else { | 471 } else { |
| 493 DCHECK_EQ(1u, header.public_header.versions.size()); | 472 DCHECK_EQ(1u, header.public_header.versions.size()); |
| 494 DCHECK_EQ(header.public_header.versions[0], version()); | 473 DCHECK_EQ(header.public_header.versions[0], version()); |
| 495 version_negotiation_state_ = NEGOTIATED_VERSION; | 474 version_negotiation_state_ = NEGOTIATED_VERSION; |
| 496 visitor_->OnSuccessfulVersionNegotiation(version()); | 475 visitor_->OnSuccessfulVersionNegotiation(version()); |
| 497 if (version() < QUIC_VERSION_19) { | |
| 498 flow_controller_->Disable(); | |
| 499 } | |
| 500 } | 476 } |
| 501 } else { | 477 } else { |
| 502 DCHECK(!header.public_header.version_flag); | 478 DCHECK(!header.public_header.version_flag); |
| 503 // If the client gets a packet without the version flag from the server | 479 // If the client gets a packet without the version flag from the server |
| 504 // it should stop sending version since the version negotiation is done. | 480 // it should stop sending version since the version negotiation is done. |
| 505 packet_creator_.StopSendingVersion(); | 481 packet_creator_.StopSendingVersion(); |
| 506 version_negotiation_state_ = NEGOTIATED_VERSION; | 482 version_negotiation_state_ = NEGOTIATED_VERSION; |
| 507 visitor_->OnSuccessfulVersionNegotiation(version()); | 483 visitor_->OnSuccessfulVersionNegotiation(version()); |
| 508 if (version() < QUIC_VERSION_19) { | |
| 509 flow_controller_->Disable(); | |
| 510 } | |
| 511 } | 484 } |
| 512 } | 485 } |
| 513 | 486 |
| 514 DCHECK_EQ(NEGOTIATED_VERSION, version_negotiation_state_); | 487 DCHECK_EQ(NEGOTIATED_VERSION, version_negotiation_state_); |
| 515 | 488 |
| 516 --stats_.packets_dropped; | 489 --stats_.packets_dropped; |
| 517 DVLOG(1) << ENDPOINT << "Received packet header: " << header; | 490 DVLOG(1) << ENDPOINT << "Received packet header: " << header; |
| 518 last_header_ = header; | 491 last_header_ = header; |
| 519 DCHECK(connected_); | 492 DCHECK(connected_); |
| 520 return true; | 493 return true; |
| (...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1177 } | 1150 } |
| 1178 | 1151 |
| 1179 { // Limit the scope of the bundler. | 1152 { // Limit the scope of the bundler. |
| 1180 // Set |include_ack| to false in bundler; ack inclusion happens elsewhere. | 1153 // Set |include_ack| to false in bundler; ack inclusion happens elsewhere. |
| 1181 ScopedPacketBundler bundler(this, NO_ACK); | 1154 ScopedPacketBundler bundler(this, NO_ACK); |
| 1182 visitor_->OnCanWrite(); | 1155 visitor_->OnCanWrite(); |
| 1183 } | 1156 } |
| 1184 | 1157 |
| 1185 // After the visitor writes, it may have caused the socket to become write | 1158 // After the visitor writes, it may have caused the socket to become write |
| 1186 // blocked or the congestion manager to prohibit sending, so check again. | 1159 // blocked or the congestion manager to prohibit sending, so check again. |
| 1187 if (visitor_->HasPendingWrites() && !resume_writes_alarm_->IsSet() && | 1160 if (visitor_->WillingAndAbleToWrite() && |
| 1161 !resume_writes_alarm_->IsSet() && |
| 1188 CanWrite(NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA)) { | 1162 CanWrite(NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA)) { |
| 1189 // We're not write blocked, but some stream didn't write out all of its | 1163 // We're not write blocked, but some stream didn't write out all of its |
| 1190 // bytes. Register for 'immediate' resumption so we'll keep writing after | 1164 // bytes. Register for 'immediate' resumption so we'll keep writing after |
| 1191 // other connections and events have had a chance to use the thread. | 1165 // other connections and events have had a chance to use the thread. |
| 1192 resume_writes_alarm_->Set(clock_->ApproximateNow()); | 1166 resume_writes_alarm_->Set(clock_->ApproximateNow()); |
| 1193 } | 1167 } |
| 1194 } | 1168 } |
| 1195 | 1169 |
| 1196 void QuicConnection::WriteIfNotBlocked() { | 1170 void QuicConnection::WriteIfNotBlocked() { |
| 1197 if (!writer_->IsWriteBlocked()) { | 1171 if (!writer_->IsWriteBlocked()) { |
| (...skipping 791 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1989 // If we changed the generator's batch state, restore original batch state. | 1963 // If we changed the generator's batch state, restore original batch state. |
| 1990 if (!already_in_batch_mode_) { | 1964 if (!already_in_batch_mode_) { |
| 1991 DVLOG(1) << "Leaving Batch Mode."; | 1965 DVLOG(1) << "Leaving Batch Mode."; |
| 1992 connection_->packet_generator_.FinishBatchOperations(); | 1966 connection_->packet_generator_.FinishBatchOperations(); |
| 1993 } | 1967 } |
| 1994 DCHECK_EQ(already_in_batch_mode_, | 1968 DCHECK_EQ(already_in_batch_mode_, |
| 1995 connection_->packet_generator_.InBatchMode()); | 1969 connection_->packet_generator_.InBatchMode()); |
| 1996 } | 1970 } |
| 1997 | 1971 |
| 1998 } // namespace net | 1972 } // namespace net |
| OLD | NEW |