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/tools/quic/quic_dispatcher.h" | 5 #include "net/tools/quic/quic_dispatcher.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 | 8 |
9 #include "base/debug/stack_trace.h" | 9 #include "base/debug/stack_trace.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
12 #include "net/quic/quic_blocked_writer_interface.h" | 12 #include "net/quic/quic_blocked_writer_interface.h" |
13 #include "net/quic/quic_flags.h" | 13 #include "net/quic/quic_flags.h" |
14 #include "net/quic/quic_utils.h" | 14 #include "net/quic/quic_utils.h" |
15 #include "net/tools/quic/quic_default_packet_writer.h" | 15 #include "net/tools/quic/quic_default_packet_writer.h" |
16 #include "net/tools/quic/quic_epoll_connection_helper.h" | 16 #include "net/tools/quic/quic_epoll_connection_helper.h" |
17 #include "net/tools/quic/quic_socket_utils.h" | 17 #include "net/tools/quic/quic_socket_utils.h" |
18 #include "net/tools/quic/quic_time_wait_list_manager.h" | 18 #include "net/tools/quic/quic_time_wait_list_manager.h" |
19 | 19 |
20 namespace net { | 20 namespace net { |
21 | 21 |
22 namespace tools { | 22 namespace tools { |
23 | 23 |
24 using base::StringPiece; | 24 using base::StringPiece; |
25 using std::make_pair; | 25 using std::make_pair; |
26 | 26 |
27 class DeleteSessionsAlarm : public EpollAlarm { | 27 class DeleteSessionsAlarm : public EpollAlarm { |
28 public: | 28 public: |
29 explicit DeleteSessionsAlarm(QuicDispatcher* dispatcher) | 29 explicit DeleteSessionsAlarm(QuicDispatcher* dispatcher) |
30 : dispatcher_(dispatcher) { | 30 : dispatcher_(dispatcher) {} |
31 } | |
32 | 31 |
33 virtual int64 OnAlarm() OVERRIDE { | 32 virtual int64 OnAlarm() OVERRIDE { |
34 EpollAlarm::OnAlarm(); | 33 EpollAlarm::OnAlarm(); |
35 dispatcher_->DeleteSessions(); | 34 dispatcher_->DeleteSessions(); |
36 return 0; | 35 return 0; |
37 } | 36 } |
38 | 37 |
39 private: | 38 private: |
40 QuicDispatcher* dispatcher_; | 39 QuicDispatcher* dispatcher_; |
41 }; | 40 }; |
42 | 41 |
43 class QuicDispatcher::QuicFramerVisitor : public QuicFramerVisitorInterface { | 42 class QuicDispatcher::QuicFramerVisitor : public QuicFramerVisitorInterface { |
44 public: | 43 public: |
45 explicit QuicFramerVisitor(QuicDispatcher* dispatcher) | 44 explicit QuicFramerVisitor(QuicDispatcher* dispatcher) |
46 : dispatcher_(dispatcher), | 45 : dispatcher_(dispatcher), connection_id_(0) {} |
47 connection_id_(0) {} | |
48 | 46 |
49 // QuicFramerVisitorInterface implementation | 47 // QuicFramerVisitorInterface implementation |
50 virtual void OnPacket() OVERRIDE {} | 48 virtual void OnPacket() OVERRIDE {} |
51 virtual bool OnUnauthenticatedPublicHeader( | 49 virtual bool OnUnauthenticatedPublicHeader( |
52 const QuicPacketPublicHeader& header) OVERRIDE { | 50 const QuicPacketPublicHeader& header) OVERRIDE { |
53 connection_id_ = header.connection_id; | 51 connection_id_ = header.connection_id; |
54 return dispatcher_->OnUnauthenticatedPublicHeader(header); | 52 return dispatcher_->OnUnauthenticatedPublicHeader(header); |
55 } | 53 } |
56 virtual bool OnUnauthenticatedHeader( | 54 virtual bool OnUnauthenticatedHeader( |
57 const QuicPacketHeader& header) OVERRIDE { | 55 const QuicPacketHeader& header) OVERRIDE { |
(...skipping 29 matching lines...) Expand all Loading... |
87 const QuicVersionNegotiationPacket& /*packet*/) OVERRIDE { | 85 const QuicVersionNegotiationPacket& /*packet*/) OVERRIDE { |
88 DCHECK(false); | 86 DCHECK(false); |
89 } | 87 } |
90 virtual void OnDecryptedPacket(EncryptionLevel level) OVERRIDE { | 88 virtual void OnDecryptedPacket(EncryptionLevel level) OVERRIDE { |
91 DCHECK(false); | 89 DCHECK(false); |
92 } | 90 } |
93 virtual bool OnPacketHeader(const QuicPacketHeader& /*header*/) OVERRIDE { | 91 virtual bool OnPacketHeader(const QuicPacketHeader& /*header*/) OVERRIDE { |
94 DCHECK(false); | 92 DCHECK(false); |
95 return false; | 93 return false; |
96 } | 94 } |
97 virtual void OnRevivedPacket() OVERRIDE { | 95 virtual void OnRevivedPacket() OVERRIDE { DCHECK(false); } |
98 DCHECK(false); | |
99 } | |
100 virtual void OnFecProtectedPayload(StringPiece /*payload*/) OVERRIDE { | 96 virtual void OnFecProtectedPayload(StringPiece /*payload*/) OVERRIDE { |
101 DCHECK(false); | 97 DCHECK(false); |
102 } | 98 } |
103 virtual bool OnStreamFrame(const QuicStreamFrame& /*frame*/) OVERRIDE { | 99 virtual bool OnStreamFrame(const QuicStreamFrame& /*frame*/) OVERRIDE { |
104 DCHECK(false); | 100 DCHECK(false); |
105 return false; | 101 return false; |
106 } | 102 } |
107 virtual bool OnAckFrame(const QuicAckFrame& /*frame*/) OVERRIDE { | 103 virtual bool OnAckFrame(const QuicAckFrame& /*frame*/) OVERRIDE { |
108 DCHECK(false); | 104 DCHECK(false); |
109 return false; | 105 return false; |
(...skipping 10 matching lines...) Expand all Loading... |
120 } | 116 } |
121 virtual bool OnPingFrame(const QuicPingFrame& /*frame*/) OVERRIDE { | 117 virtual bool OnPingFrame(const QuicPingFrame& /*frame*/) OVERRIDE { |
122 DCHECK(false); | 118 DCHECK(false); |
123 return false; | 119 return false; |
124 } | 120 } |
125 virtual bool OnRstStreamFrame(const QuicRstStreamFrame& /*frame*/) OVERRIDE { | 121 virtual bool OnRstStreamFrame(const QuicRstStreamFrame& /*frame*/) OVERRIDE { |
126 DCHECK(false); | 122 DCHECK(false); |
127 return false; | 123 return false; |
128 } | 124 } |
129 virtual bool OnConnectionCloseFrame( | 125 virtual bool OnConnectionCloseFrame( |
130 const QuicConnectionCloseFrame & /*frame*/) OVERRIDE { | 126 const QuicConnectionCloseFrame& /*frame*/) OVERRIDE { |
131 DCHECK(false); | 127 DCHECK(false); |
132 return false; | 128 return false; |
133 } | 129 } |
134 virtual bool OnGoAwayFrame(const QuicGoAwayFrame& /*frame*/) OVERRIDE { | 130 virtual bool OnGoAwayFrame(const QuicGoAwayFrame& /*frame*/) OVERRIDE { |
135 DCHECK(false); | 131 DCHECK(false); |
136 return false; | 132 return false; |
137 } | 133 } |
138 virtual bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& /*frame*/) | 134 virtual bool OnWindowUpdateFrame( |
139 OVERRIDE { | 135 const QuicWindowUpdateFrame& /*frame*/) OVERRIDE { |
140 DCHECK(false); | 136 DCHECK(false); |
141 return false; | 137 return false; |
142 } | 138 } |
143 virtual bool OnBlockedFrame(const QuicBlockedFrame& frame) OVERRIDE { | 139 virtual bool OnBlockedFrame(const QuicBlockedFrame& frame) OVERRIDE { |
144 DCHECK(false); | 140 DCHECK(false); |
145 return false; | 141 return false; |
146 } | 142 } |
147 virtual void OnFecData(const QuicFecData& /*fec*/) OVERRIDE { | 143 virtual void OnFecData(const QuicFecData& /*fec*/) OVERRIDE { DCHECK(false); } |
148 DCHECK(false); | 144 virtual void OnPacketComplete() OVERRIDE { DCHECK(false); } |
149 } | |
150 virtual void OnPacketComplete() OVERRIDE { | |
151 DCHECK(false); | |
152 } | |
153 | 145 |
154 private: | 146 private: |
155 QuicDispatcher* dispatcher_; | 147 QuicDispatcher* dispatcher_; |
156 | 148 |
157 // Latched in OnUnauthenticatedPublicHeader for use later. | 149 // Latched in OnUnauthenticatedPublicHeader for use later. |
158 QuicConnectionId connection_id_; | 150 QuicConnectionId connection_id_; |
159 }; | 151 }; |
160 | 152 |
161 QuicDispatcher::QuicDispatcher(const QuicConfig& config, | 153 QuicDispatcher::QuicDispatcher(const QuicConfig& config, |
162 const QuicCryptoServerConfig& crypto_config, | 154 const QuicCryptoServerConfig& crypto_config, |
(...skipping 21 matching lines...) Expand all Loading... |
184 | 176 |
185 void QuicDispatcher::Initialize(int fd) { | 177 void QuicDispatcher::Initialize(int fd) { |
186 DCHECK(writer_ == NULL); | 178 DCHECK(writer_ == NULL); |
187 writer_.reset(CreateWriter(fd)); | 179 writer_.reset(CreateWriter(fd)); |
188 time_wait_list_manager_.reset(CreateQuicTimeWaitListManager()); | 180 time_wait_list_manager_.reset(CreateQuicTimeWaitListManager()); |
189 | 181 |
190 // Remove all versions > QUIC_VERSION_16 from the | 182 // Remove all versions > QUIC_VERSION_16 from the |
191 // supported_versions_no_flow_control_ vector. | 183 // supported_versions_no_flow_control_ vector. |
192 QuicVersionVector::iterator it = | 184 QuicVersionVector::iterator it = |
193 find(supported_versions_no_flow_control_.begin(), | 185 find(supported_versions_no_flow_control_.begin(), |
194 supported_versions_no_flow_control_.end(), QUIC_VERSION_17); | 186 supported_versions_no_flow_control_.end(), |
| 187 QUIC_VERSION_17); |
195 if (it != supported_versions_no_flow_control_.end()) { | 188 if (it != supported_versions_no_flow_control_.end()) { |
196 supported_versions_no_flow_control_.erase( | 189 supported_versions_no_flow_control_.erase( |
197 supported_versions_no_flow_control_.begin(), it + 1); | 190 supported_versions_no_flow_control_.begin(), it + 1); |
198 } | 191 } |
199 CHECK(!supported_versions_no_flow_control_.empty()); | 192 CHECK(!supported_versions_no_flow_control_.empty()); |
200 } | 193 } |
201 | 194 |
202 void QuicDispatcher::ProcessPacket(const IPEndPoint& server_address, | 195 void QuicDispatcher::ProcessPacket(const IPEndPoint& server_address, |
203 const IPEndPoint& client_address, | 196 const IPEndPoint& client_address, |
204 const QuicEncryptedPacket& packet) { | 197 const QuicEncryptedPacket& packet) { |
(...skipping 19 matching lines...) Expand all Loading... |
224 return false; | 217 return false; |
225 } | 218 } |
226 if (time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)) { | 219 if (time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)) { |
227 return HandlePacketForTimeWait(header); | 220 return HandlePacketForTimeWait(header); |
228 } | 221 } |
229 | 222 |
230 // Ensure the packet has a version negotiation bit set before creating a new | 223 // Ensure the packet has a version negotiation bit set before creating a new |
231 // session for it. All initial packets for a new connection are required to | 224 // session for it. All initial packets for a new connection are required to |
232 // have the flag set. Otherwise it may be a stray packet. | 225 // have the flag set. Otherwise it may be a stray packet. |
233 if (header.version_flag) { | 226 if (header.version_flag) { |
234 session = CreateQuicSession(connection_id, current_server_address_, | 227 session = CreateQuicSession( |
235 current_client_address_); | 228 connection_id, current_server_address_, current_client_address_); |
236 } | 229 } |
237 | 230 |
238 if (session == NULL) { | 231 if (session == NULL) { |
239 DVLOG(1) << "Failed to create session for " << connection_id; | 232 DVLOG(1) << "Failed to create session for " << connection_id; |
240 // Add this connection_id fo the time-wait state, to safely reject future | 233 // Add this connection_id fo the time-wait state, to safely reject future |
241 // packets. | 234 // packets. |
242 | 235 |
243 if (header.version_flag && | 236 if (header.version_flag && |
244 !framer_.IsSupportedVersion(header.versions.front())) { | 237 !framer_.IsSupportedVersion(header.versions.front())) { |
245 // TODO(ianswett): Produce a no-version version negotiation packet. | 238 // TODO(ianswett): Produce a no-version version negotiation packet. |
246 return false; | 239 return false; |
247 } | 240 } |
248 | 241 |
249 // Use the version in the packet if possible, otherwise assume the latest. | 242 // Use the version in the packet if possible, otherwise assume the latest. |
250 QuicVersion version = header.version_flag ? header.versions.front() : | 243 QuicVersion version = header.version_flag ? header.versions.front() |
251 supported_versions_.front(); | 244 : supported_versions_.front(); |
252 time_wait_list_manager_->AddConnectionIdToTimeWait( | 245 time_wait_list_manager_->AddConnectionIdToTimeWait( |
253 connection_id, version, NULL); | 246 connection_id, version, NULL); |
254 DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); | 247 DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); |
255 return HandlePacketForTimeWait(header); | 248 return HandlePacketForTimeWait(header); |
256 } | 249 } |
257 DVLOG(1) << "Created new session for " << connection_id; | 250 DVLOG(1) << "Created new session for " << connection_id; |
258 session_map_.insert(make_pair(connection_id, session)); | 251 session_map_.insert(make_pair(connection_id, session)); |
259 } else { | 252 } else { |
260 session = it->second; | 253 session = it->second; |
261 } | 254 } |
(...skipping 11 matching lines...) Expand all Loading... |
273 time_wait_list_manager_->ProcessPacket(current_server_address_, | 266 time_wait_list_manager_->ProcessPacket(current_server_address_, |
274 current_client_address_, | 267 current_client_address_, |
275 header.public_header.connection_id, | 268 header.public_header.connection_id, |
276 header.packet_sequence_number, | 269 header.packet_sequence_number, |
277 *current_packet_); | 270 *current_packet_); |
278 } | 271 } |
279 | 272 |
280 void QuicDispatcher::CleanUpSession(SessionMap::iterator it) { | 273 void QuicDispatcher::CleanUpSession(SessionMap::iterator it) { |
281 QuicConnection* connection = it->second->connection(); | 274 QuicConnection* connection = it->second->connection(); |
282 QuicEncryptedPacket* connection_close_packet = | 275 QuicEncryptedPacket* connection_close_packet = |
283 connection->ReleaseConnectionClosePacket(); | 276 connection->ReleaseConnectionClosePacket(); |
284 write_blocked_list_.erase(connection); | 277 write_blocked_list_.erase(connection); |
285 time_wait_list_manager_->AddConnectionIdToTimeWait(it->first, | 278 time_wait_list_manager_->AddConnectionIdToTimeWait( |
286 connection->version(), | 279 it->first, connection->version(), connection_close_packet); |
287 connection_close_packet); | |
288 session_map_.erase(it); | 280 session_map_.erase(it); |
289 } | 281 } |
290 | 282 |
291 void QuicDispatcher::DeleteSessions() { | 283 void QuicDispatcher::DeleteSessions() { |
292 STLDeleteElements(&closed_session_list_); | 284 STLDeleteElements(&closed_session_list_); |
293 } | 285 } |
294 | 286 |
295 void QuicDispatcher::OnCanWrite() { | 287 void QuicDispatcher::OnCanWrite() { |
296 // We got an EPOLLOUT: the socket should not be blocked. | 288 // We got an EPOLLOUT: the socket should not be blocked. |
297 writer_->SetWritable(); | 289 writer_->SetWritable(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 QuicErrorCode error) { | 324 QuicErrorCode error) { |
333 SessionMap::iterator it = session_map_.find(connection_id); | 325 SessionMap::iterator it = session_map_.find(connection_id); |
334 if (it == session_map_.end()) { | 326 if (it == session_map_.end()) { |
335 LOG(DFATAL) << "ConnectionId " << connection_id | 327 LOG(DFATAL) << "ConnectionId " << connection_id |
336 << " does not exist in the session map. " | 328 << " does not exist in the session map. " |
337 << "Error: " << QuicUtils::ErrorToString(error); | 329 << "Error: " << QuicUtils::ErrorToString(error); |
338 LOG(DFATAL) << base::debug::StackTrace().ToString(); | 330 LOG(DFATAL) << base::debug::StackTrace().ToString(); |
339 return; | 331 return; |
340 } | 332 } |
341 | 333 |
342 DLOG_IF(INFO, error != QUIC_NO_ERROR) << "Closing connection (" | 334 DLOG_IF(INFO, error != QUIC_NO_ERROR) |
343 << connection_id | 335 << "Closing connection (" << connection_id |
344 << ") due to error: " | 336 << ") due to error: " << QuicUtils::ErrorToString(error); |
345 << QuicUtils::ErrorToString(error); | |
346 | 337 |
347 if (closed_session_list_.empty()) { | 338 if (closed_session_list_.empty()) { |
348 epoll_server_->RegisterAlarmApproximateDelta( | 339 epoll_server_->RegisterAlarmApproximateDelta(0, |
349 0, delete_sessions_alarm_.get()); | 340 delete_sessions_alarm_.get()); |
350 } | 341 } |
351 closed_session_list_.push_back(it->second); | 342 closed_session_list_.push_back(it->second); |
352 CleanUpSession(it); | 343 CleanUpSession(it); |
353 } | 344 } |
354 | 345 |
355 void QuicDispatcher::OnWriteBlocked(QuicBlockedWriterInterface* writer) { | 346 void QuicDispatcher::OnWriteBlocked(QuicBlockedWriterInterface* writer) { |
356 DCHECK(writer_->IsWriteBlocked()); | 347 DCHECK(writer_->IsWriteBlocked()); |
357 write_blocked_list_.insert(make_pair(writer, true)); | 348 write_blocked_list_.insert(make_pair(writer, true)); |
358 } | 349 } |
359 | 350 |
(...skipping 17 matching lines...) Expand all Loading... |
377 } | 368 } |
378 | 369 |
379 QuicConnection* QuicDispatcher::CreateQuicConnection( | 370 QuicConnection* QuicDispatcher::CreateQuicConnection( |
380 QuicConnectionId connection_id, | 371 QuicConnectionId connection_id, |
381 const IPEndPoint& server_address, | 372 const IPEndPoint& server_address, |
382 const IPEndPoint& client_address, | 373 const IPEndPoint& client_address, |
383 uint32 initial_flow_control_window) { | 374 uint32 initial_flow_control_window) { |
384 // If we have disabled per-stream flow control, then don't allow new | 375 // If we have disabled per-stream flow control, then don't allow new |
385 // connections to talk QUIC_VERSION_17 or higher. | 376 // connections to talk QUIC_VERSION_17 or higher. |
386 if (FLAGS_enable_quic_stream_flow_control_2) { | 377 if (FLAGS_enable_quic_stream_flow_control_2) { |
387 return new QuicConnection(connection_id, client_address, helper_.get(), | 378 return new QuicConnection(connection_id, |
388 writer_.get(), true, supported_versions_, | 379 client_address, |
| 380 helper_.get(), |
| 381 writer_.get(), |
| 382 true, |
| 383 supported_versions_, |
389 initial_flow_control_window_bytes_); | 384 initial_flow_control_window_bytes_); |
390 } else { | 385 } else { |
391 DVLOG(1) | 386 DVLOG(1) |
392 << "Flow control disabled, creating QuicDispatcher WITHOUT version 17"; | 387 << "Flow control disabled, creating QuicDispatcher WITHOUT version 17"; |
393 return new QuicConnection(connection_id, client_address, helper_.get(), | 388 return new QuicConnection(connection_id, |
394 writer_.get(), true, | 389 client_address, |
| 390 helper_.get(), |
| 391 writer_.get(), |
| 392 true, |
395 supported_versions_no_flow_control_, | 393 supported_versions_no_flow_control_, |
396 initial_flow_control_window_bytes_); | 394 initial_flow_control_window_bytes_); |
397 } | 395 } |
398 } | 396 } |
399 | 397 |
400 QuicTimeWaitListManager* QuicDispatcher::CreateQuicTimeWaitListManager() { | 398 QuicTimeWaitListManager* QuicDispatcher::CreateQuicTimeWaitListManager() { |
401 return new QuicTimeWaitListManager( | 399 return new QuicTimeWaitListManager( |
402 writer_.get(), this, epoll_server(), supported_versions()); | 400 writer_.get(), this, epoll_server(), supported_versions()); |
403 } | 401 } |
404 | 402 |
405 bool QuicDispatcher::HandlePacketForTimeWait( | 403 bool QuicDispatcher::HandlePacketForTimeWait( |
406 const QuicPacketPublicHeader& header) { | 404 const QuicPacketPublicHeader& header) { |
407 if (header.reset_flag) { | 405 if (header.reset_flag) { |
408 // Public reset packets do not have sequence numbers, so ignore the packet. | 406 // Public reset packets do not have sequence numbers, so ignore the packet. |
409 return false; | 407 return false; |
410 } | 408 } |
411 | 409 |
412 // Switch the framer to the correct version, so that the sequence number can | 410 // Switch the framer to the correct version, so that the sequence number can |
413 // be parsed correctly. | 411 // be parsed correctly. |
414 framer_.set_version(time_wait_list_manager_->GetQuicVersionFromConnectionId( | 412 framer_.set_version(time_wait_list_manager_->GetQuicVersionFromConnectionId( |
415 header.connection_id)); | 413 header.connection_id)); |
416 | 414 |
417 // Continue parsing the packet to extract the sequence number. Then | 415 // Continue parsing the packet to extract the sequence number. Then |
418 // send it to the time wait manager in OnUnathenticatedHeader. | 416 // send it to the time wait manager in OnUnathenticatedHeader. |
419 return true; | 417 return true; |
420 } | 418 } |
421 | 419 |
422 } // namespace tools | 420 } // namespace tools |
423 } // namespace net | 421 } // namespace net |
OLD | NEW |