| 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 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 visitor_(nullptr), | 297 visitor_(nullptr), |
| 298 debug_visitor_(nullptr), | 298 debug_visitor_(nullptr), |
| 299 packet_generator_(connection_id_, | 299 packet_generator_(connection_id_, |
| 300 &framer_, | 300 &framer_, |
| 301 random_generator_, | 301 random_generator_, |
| 302 helper->GetBufferAllocator(), | 302 helper->GetBufferAllocator(), |
| 303 this), | 303 this), |
| 304 fec_alarm_(helper->CreateAlarm(arena_.New<FecAlarm>(&packet_generator_), | 304 fec_alarm_(helper->CreateAlarm(arena_.New<FecAlarm>(&packet_generator_), |
| 305 &arena_)), | 305 &arena_)), |
| 306 idle_network_timeout_(QuicTime::Delta::Infinite()), | 306 idle_network_timeout_(QuicTime::Delta::Infinite()), |
| 307 overall_connection_timeout_(QuicTime::Delta::Infinite()), | 307 handshake_timeout_(QuicTime::Delta::Infinite()), |
| 308 time_of_last_received_packet_(clock_->ApproximateNow()), | 308 time_of_last_received_packet_(clock_->ApproximateNow()), |
| 309 time_of_last_sent_new_packet_(clock_->ApproximateNow()), | 309 time_of_last_sent_new_packet_(clock_->ApproximateNow()), |
| 310 last_send_for_timeout_(clock_->ApproximateNow()), | 310 last_send_for_timeout_(clock_->ApproximateNow()), |
| 311 packet_number_of_last_sent_packet_(0), | 311 packet_number_of_last_sent_packet_(0), |
| 312 sent_packet_manager_( | 312 sent_packet_manager_( |
| 313 perspective, | 313 perspective, |
| 314 kDefaultPathId, | 314 kDefaultPathId, |
| 315 clock_, | 315 clock_, |
| 316 &stats_, | 316 &stats_, |
| 317 FLAGS_quic_use_bbr_congestion_control ? kBBR : kCubic, | 317 FLAGS_quic_use_bbr_congestion_control ? kBBR : kCubic, |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 void QuicConnection::ClearQueuedPackets() { | 362 void QuicConnection::ClearQueuedPackets() { |
| 363 for (QueuedPacketList::iterator it = queued_packets_.begin(); | 363 for (QueuedPacketList::iterator it = queued_packets_.begin(); |
| 364 it != queued_packets_.end(); ++it) { | 364 it != queued_packets_.end(); ++it) { |
| 365 QuicUtils::ClearSerializedPacket(&(*it)); | 365 QuicUtils::ClearSerializedPacket(&(*it)); |
| 366 } | 366 } |
| 367 queued_packets_.clear(); | 367 queued_packets_.clear(); |
| 368 } | 368 } |
| 369 | 369 |
| 370 void QuicConnection::SetFromConfig(const QuicConfig& config) { | 370 void QuicConnection::SetFromConfig(const QuicConfig& config) { |
| 371 if (config.negotiated()) { | 371 if (config.negotiated()) { |
| 372 // Handshake complete, set handshake timeout to Infinite. |
| 372 SetNetworkTimeouts(QuicTime::Delta::Infinite(), | 373 SetNetworkTimeouts(QuicTime::Delta::Infinite(), |
| 373 config.IdleConnectionStateLifetime()); | 374 config.IdleConnectionStateLifetime()); |
| 374 if (config.SilentClose()) { | 375 if (config.SilentClose()) { |
| 375 silent_close_enabled_ = true; | 376 silent_close_enabled_ = true; |
| 376 } | 377 } |
| 377 if (FLAGS_quic_enable_multipath && config.MultipathEnabled()) { | 378 if (FLAGS_quic_enable_multipath && config.MultipathEnabled()) { |
| 378 multipath_enabled_ = true; | 379 multipath_enabled_ = true; |
| 379 } | 380 } |
| 380 } else { | 381 } else { |
| 381 SetNetworkTimeouts(config.max_time_before_crypto_handshake(), | 382 SetNetworkTimeouts(config.max_time_before_crypto_handshake(), |
| (...skipping 1669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2051 } | 2052 } |
| 2052 | 2053 |
| 2053 void QuicConnection::SendConnectionClosePacket(QuicErrorCode error, | 2054 void QuicConnection::SendConnectionClosePacket(QuicErrorCode error, |
| 2054 const string& details) { | 2055 const string& details) { |
| 2055 DVLOG(1) << ENDPOINT << "Force closing " << connection_id() << " with error " | 2056 DVLOG(1) << ENDPOINT << "Force closing " << connection_id() << " with error " |
| 2056 << QuicUtils::ErrorToString(error) << " (" << error << ") " | 2057 << QuicUtils::ErrorToString(error) << " (" << error << ") " |
| 2057 << details; | 2058 << details; |
| 2058 // Don't send explicit connection close packets for timeouts. | 2059 // Don't send explicit connection close packets for timeouts. |
| 2059 // This is particularly important on mobile, where connections are short. | 2060 // This is particularly important on mobile, where connections are short. |
| 2060 if (silent_close_enabled_ && | 2061 if (silent_close_enabled_ && |
| 2061 error == QuicErrorCode::QUIC_CONNECTION_TIMED_OUT) { | 2062 error == QuicErrorCode::QUIC_NETWORK_IDLE_TIMEOUT) { |
| 2062 return; | 2063 return; |
| 2063 } | 2064 } |
| 2064 ClearQueuedPackets(); | 2065 ClearQueuedPackets(); |
| 2065 ScopedPacketBundler ack_bundler(this, SEND_ACK); | 2066 ScopedPacketBundler ack_bundler(this, SEND_ACK); |
| 2066 QuicConnectionCloseFrame* frame = new QuicConnectionCloseFrame(); | 2067 QuicConnectionCloseFrame* frame = new QuicConnectionCloseFrame(); |
| 2067 frame->error_code = error; | 2068 frame->error_code = error; |
| 2068 frame->error_details = details; | 2069 frame->error_details = details; |
| 2069 packet_generator_.AddControlFrame(QuicFrame(frame)); | 2070 packet_generator_.AddControlFrame(QuicFrame(frame)); |
| 2070 packet_generator_.FlushAllQueuedFrames(); | 2071 packet_generator_.FlushAllQueuedFrames(); |
| 2071 } | 2072 } |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2164 | 2165 |
| 2165 IsHandshake pending_handshake = | 2166 IsHandshake pending_handshake = |
| 2166 visitor_->HasPendingHandshake() ? IS_HANDSHAKE : NOT_HANDSHAKE; | 2167 visitor_->HasPendingHandshake() ? IS_HANDSHAKE : NOT_HANDSHAKE; |
| 2167 // Sending queued packets may have caused the socket to become write blocked, | 2168 // Sending queued packets may have caused the socket to become write blocked, |
| 2168 // or the congestion manager to prohibit sending. If we've sent everything | 2169 // or the congestion manager to prohibit sending. If we've sent everything |
| 2169 // we had queued and we're still not blocked, let the visitor know it can | 2170 // we had queued and we're still not blocked, let the visitor know it can |
| 2170 // write more. | 2171 // write more. |
| 2171 return ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA, pending_handshake); | 2172 return ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA, pending_handshake); |
| 2172 } | 2173 } |
| 2173 | 2174 |
| 2174 void QuicConnection::SetNetworkTimeouts(QuicTime::Delta overall_timeout, | 2175 void QuicConnection::SetNetworkTimeouts(QuicTime::Delta handshake_timeout, |
| 2175 QuicTime::Delta idle_timeout) { | 2176 QuicTime::Delta idle_timeout) { |
| 2176 QUIC_BUG_IF(idle_timeout > overall_timeout) | 2177 QUIC_BUG_IF(idle_timeout > handshake_timeout) |
| 2177 << "idle_timeout:" << idle_timeout.ToMilliseconds() | 2178 << "idle_timeout:" << idle_timeout.ToMilliseconds() |
| 2178 << " overall_timeout:" << overall_timeout.ToMilliseconds(); | 2179 << " handshake_timeout:" << handshake_timeout.ToMilliseconds(); |
| 2179 // Adjust the idle timeout on client and server to prevent clients from | 2180 // Adjust the idle timeout on client and server to prevent clients from |
| 2180 // sending requests to servers which have already closed the connection. | 2181 // sending requests to servers which have already closed the connection. |
| 2181 if (perspective_ == Perspective::IS_SERVER) { | 2182 if (perspective_ == Perspective::IS_SERVER) { |
| 2182 idle_timeout = idle_timeout.Add(QuicTime::Delta::FromSeconds(3)); | 2183 idle_timeout = idle_timeout.Add(QuicTime::Delta::FromSeconds(3)); |
| 2183 } else if (idle_timeout > QuicTime::Delta::FromSeconds(1)) { | 2184 } else if (idle_timeout > QuicTime::Delta::FromSeconds(1)) { |
| 2184 idle_timeout = idle_timeout.Subtract(QuicTime::Delta::FromSeconds(1)); | 2185 idle_timeout = idle_timeout.Subtract(QuicTime::Delta::FromSeconds(1)); |
| 2185 } | 2186 } |
| 2186 overall_connection_timeout_ = overall_timeout; | 2187 handshake_timeout_ = handshake_timeout; |
| 2187 idle_network_timeout_ = idle_timeout; | 2188 idle_network_timeout_ = idle_timeout; |
| 2188 | 2189 |
| 2189 SetTimeoutAlarm(); | 2190 SetTimeoutAlarm(); |
| 2190 } | 2191 } |
| 2191 | 2192 |
| 2192 void QuicConnection::CheckForTimeout() { | 2193 void QuicConnection::CheckForTimeout() { |
| 2193 QuicTime now = clock_->ApproximateNow(); | 2194 QuicTime now = clock_->ApproximateNow(); |
| 2194 QuicTime time_of_last_packet = QuicTime::Zero(); | 2195 QuicTime time_of_last_packet = QuicTime::Zero(); |
| 2195 if (!FLAGS_quic_use_new_idle_timeout) { | 2196 if (!FLAGS_quic_use_new_idle_timeout) { |
| 2196 time_of_last_packet = | 2197 time_of_last_packet = |
| 2197 max(time_of_last_received_packet_, time_of_last_sent_new_packet_); | 2198 max(time_of_last_received_packet_, time_of_last_sent_new_packet_); |
| 2198 } else { | 2199 } else { |
| 2199 time_of_last_packet = | 2200 time_of_last_packet = |
| 2200 max(time_of_last_received_packet_, last_send_for_timeout_); | 2201 max(time_of_last_received_packet_, last_send_for_timeout_); |
| 2201 } | 2202 } |
| 2202 | 2203 |
| 2203 // |delta| can be < 0 as |now| is approximate time but |time_of_last_packet| | 2204 // |delta| can be < 0 as |now| is approximate time but |time_of_last_packet| |
| 2204 // is accurate time. However, this should not change the behavior of | 2205 // is accurate time. However, this should not change the behavior of |
| 2205 // timeout handling. | 2206 // timeout handling. |
| 2206 QuicTime::Delta idle_duration = now.Subtract(time_of_last_packet); | 2207 QuicTime::Delta idle_duration = now.Subtract(time_of_last_packet); |
| 2207 DVLOG(1) << ENDPOINT << "last packet " | 2208 DVLOG(1) << ENDPOINT << "last packet " |
| 2208 << time_of_last_packet.ToDebuggingValue() | 2209 << time_of_last_packet.ToDebuggingValue() |
| 2209 << " now:" << now.ToDebuggingValue() | 2210 << " now:" << now.ToDebuggingValue() |
| 2210 << " idle_duration:" << idle_duration.ToMicroseconds() | 2211 << " idle_duration:" << idle_duration.ToMicroseconds() |
| 2211 << " idle_network_timeout: " | 2212 << " idle_network_timeout: " |
| 2212 << idle_network_timeout_.ToMicroseconds(); | 2213 << idle_network_timeout_.ToMicroseconds(); |
| 2213 if (idle_duration >= idle_network_timeout_) { | 2214 if (idle_duration >= idle_network_timeout_) { |
| 2214 DVLOG(1) << ENDPOINT << "Connection timedout due to no network activity."; | 2215 DVLOG(1) << ENDPOINT << "Connection timedout due to no network activity."; |
| 2215 SendConnectionCloseWithDetails(QUIC_CONNECTION_TIMED_OUT, | 2216 SendConnectionCloseWithDetails(QUIC_NETWORK_IDLE_TIMEOUT, |
| 2216 "No recent network activity"); | 2217 "No recent network activity"); |
| 2217 return; | 2218 return; |
| 2218 } | 2219 } |
| 2219 | 2220 |
| 2220 if (!overall_connection_timeout_.IsInfinite()) { | 2221 if (!handshake_timeout_.IsInfinite()) { |
| 2221 QuicTime::Delta connected_duration = | 2222 QuicTime::Delta connected_duration = |
| 2222 now.Subtract(stats_.connection_creation_time); | 2223 now.Subtract(stats_.connection_creation_time); |
| 2223 DVLOG(1) << ENDPOINT | 2224 DVLOG(1) << ENDPOINT |
| 2224 << "connection time: " << connected_duration.ToMicroseconds() | 2225 << "connection time: " << connected_duration.ToMicroseconds() |
| 2225 << " overall timeout: " | 2226 << " handshake timeout: " << handshake_timeout_.ToMicroseconds(); |
| 2226 << overall_connection_timeout_.ToMicroseconds(); | 2227 if (connected_duration >= handshake_timeout_) { |
| 2227 if (connected_duration >= overall_connection_timeout_) { | 2228 DVLOG(1) << ENDPOINT << "Connection timedout due to handshake timeout."; |
| 2228 DVLOG(1) << ENDPOINT | 2229 SendConnectionCloseWithDetails(QUIC_HANDSHAKE_TIMEOUT, |
| 2229 << "Connection timedout due to overall connection timeout."; | 2230 "Handshake timeout expired"); |
| 2230 SendConnectionCloseWithDetails(QUIC_CONNECTION_OVERALL_TIMED_OUT, | |
| 2231 "Overall timeout expired"); | |
| 2232 return; | 2231 return; |
| 2233 } | 2232 } |
| 2234 } | 2233 } |
| 2235 | 2234 |
| 2236 SetTimeoutAlarm(); | 2235 SetTimeoutAlarm(); |
| 2237 } | 2236 } |
| 2238 | 2237 |
| 2239 void QuicConnection::SetTimeoutAlarm() { | 2238 void QuicConnection::SetTimeoutAlarm() { |
| 2240 QuicTime time_of_last_packet = | 2239 QuicTime time_of_last_packet = |
| 2241 max(time_of_last_received_packet_, time_of_last_sent_new_packet_); | 2240 max(time_of_last_received_packet_, time_of_last_sent_new_packet_); |
| 2242 | 2241 |
| 2243 QuicTime deadline = time_of_last_packet.Add(idle_network_timeout_); | 2242 QuicTime deadline = time_of_last_packet.Add(idle_network_timeout_); |
| 2244 if (!overall_connection_timeout_.IsInfinite()) { | 2243 if (!handshake_timeout_.IsInfinite()) { |
| 2245 deadline = | 2244 deadline = |
| 2246 min(deadline, | 2245 min(deadline, stats_.connection_creation_time.Add(handshake_timeout_)); |
| 2247 stats_.connection_creation_time.Add(overall_connection_timeout_)); | |
| 2248 } | 2246 } |
| 2249 | 2247 |
| 2250 timeout_alarm_->Cancel(); | 2248 timeout_alarm_->Cancel(); |
| 2251 timeout_alarm_->Set(deadline); | 2249 timeout_alarm_->Set(deadline); |
| 2252 } | 2250 } |
| 2253 | 2251 |
| 2254 void QuicConnection::SetPingAlarm() { | 2252 void QuicConnection::SetPingAlarm() { |
| 2255 if (perspective_ == Perspective::IS_SERVER) { | 2253 if (perspective_ == Perspective::IS_SERVER) { |
| 2256 // Only clients send pings. | 2254 // Only clients send pings. |
| 2257 return; | 2255 return; |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2536 void QuicConnection::OnPathClosed(QuicPathId path_id) { | 2534 void QuicConnection::OnPathClosed(QuicPathId path_id) { |
| 2537 // Stop receiving packets on this path. | 2535 // Stop receiving packets on this path. |
| 2538 framer_.OnPathClosed(path_id); | 2536 framer_.OnPathClosed(path_id); |
| 2539 } | 2537 } |
| 2540 | 2538 |
| 2541 bool QuicConnection::ack_frame_updated() const { | 2539 bool QuicConnection::ack_frame_updated() const { |
| 2542 return received_packet_manager_.ack_frame_updated(); | 2540 return received_packet_manager_.ack_frame_updated(); |
| 2543 } | 2541 } |
| 2544 | 2542 |
| 2545 } // namespace net | 2543 } // namespace net |
| OLD | NEW |