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" |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 // in OnAuthenticatedHeader. | 176 // in OnAuthenticatedHeader. |
177 framer_.ProcessPacket(packet); | 177 framer_.ProcessPacket(packet); |
178 // TODO(rjshade): Return a status describing if/why a packet was dropped, | 178 // TODO(rjshade): Return a status describing if/why a packet was dropped, |
179 // and log somehow. Maybe expose as a varz. | 179 // and log somehow. Maybe expose as a varz. |
180 } | 180 } |
181 | 181 |
182 bool QuicDispatcher::OnUnauthenticatedPublicHeader( | 182 bool QuicDispatcher::OnUnauthenticatedPublicHeader( |
183 const QuicPacketPublicHeader& header) { | 183 const QuicPacketPublicHeader& header) { |
184 QuicSession* session = NULL; | 184 QuicSession* session = NULL; |
185 | 185 |
186 QuicGuid guid = header.guid; | 186 QuicConnectionId connection_id = header.connection_id; |
187 SessionMap::iterator it = session_map_.find(guid); | 187 SessionMap::iterator it = session_map_.find(connection_id); |
188 if (it == session_map_.end()) { | 188 if (it == session_map_.end()) { |
189 if (header.reset_flag) { | 189 if (header.reset_flag) { |
190 return false; | 190 return false; |
191 } | 191 } |
192 if (time_wait_list_manager_->IsGuidInTimeWait(guid)) { | 192 if (time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)) { |
193 return HandlePacketForTimeWait(header); | 193 return HandlePacketForTimeWait(header); |
194 } | 194 } |
195 | 195 |
196 // Ensure the packet has a version negotiation bit set before creating a new | 196 // Ensure the packet has a version negotiation bit set before creating a new |
197 // session for it. All initial packets for a new connection are required to | 197 // session for it. All initial packets for a new connection are required to |
198 // have the flag set. Otherwise it may be a stray packet. | 198 // have the flag set. Otherwise it may be a stray packet. |
199 if (header.version_flag) { | 199 if (header.version_flag) { |
200 session = CreateQuicSession(guid, current_server_address_, | 200 session = CreateQuicSession(connection_id, current_server_address_, |
201 current_client_address_); | 201 current_client_address_); |
202 } | 202 } |
203 | 203 |
204 if (session == NULL) { | 204 if (session == NULL) { |
205 DVLOG(1) << "Failed to create session for " << guid; | 205 DVLOG(1) << "Failed to create session for " << connection_id; |
206 // Add this guid fo the time-wait state, to safely reject future packets. | 206 // Add this connection_id fo the time-wait state, to safely reject future |
| 207 // packets. |
207 | 208 |
208 if (header.version_flag && | 209 if (header.version_flag && |
209 !framer_.IsSupportedVersion(header.versions.front())) { | 210 !framer_.IsSupportedVersion(header.versions.front())) { |
210 // TODO(ianswett): Produce a no-version version negotiation packet. | 211 // TODO(ianswett): Produce a no-version version negotiation packet. |
211 return false; | 212 return false; |
212 } | 213 } |
213 | 214 |
214 // Use the version in the packet if possible, otherwise assume the latest. | 215 // Use the version in the packet if possible, otherwise assume the latest. |
215 QuicVersion version = header.version_flag ? header.versions.front() : | 216 QuicVersion version = header.version_flag ? header.versions.front() : |
216 supported_versions_.front(); | 217 supported_versions_.front(); |
217 time_wait_list_manager_->AddGuidToTimeWait(guid, version, NULL); | 218 time_wait_list_manager_->AddConnectionIdToTimeWait( |
218 DCHECK(time_wait_list_manager_->IsGuidInTimeWait(guid)); | 219 connection_id, version, NULL); |
| 220 DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); |
219 return HandlePacketForTimeWait(header); | 221 return HandlePacketForTimeWait(header); |
220 } | 222 } |
221 DVLOG(1) << "Created new session for " << guid; | 223 DVLOG(1) << "Created new session for " << connection_id; |
222 session_map_.insert(make_pair(guid, session)); | 224 session_map_.insert(make_pair(connection_id, session)); |
223 } else { | 225 } else { |
224 session = it->second; | 226 session = it->second; |
225 } | 227 } |
226 | 228 |
227 session->connection()->ProcessUdpPacket( | 229 session->connection()->ProcessUdpPacket( |
228 current_server_address_, current_client_address_, *current_packet_); | 230 current_server_address_, current_client_address_, *current_packet_); |
229 | 231 |
230 // Do not parse the packet further. The session will process it completely. | 232 // Do not parse the packet further. The session will process it completely. |
231 return false; | 233 return false; |
232 } | 234 } |
233 | 235 |
234 void QuicDispatcher::OnUnauthenticatedHeader(const QuicPacketHeader& header) { | 236 void QuicDispatcher::OnUnauthenticatedHeader(const QuicPacketHeader& header) { |
235 DCHECK(time_wait_list_manager_->IsGuidInTimeWait(header.public_header.guid)); | 237 DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait( |
| 238 header.public_header.connection_id)); |
236 time_wait_list_manager_->ProcessPacket(current_server_address_, | 239 time_wait_list_manager_->ProcessPacket(current_server_address_, |
237 current_client_address_, | 240 current_client_address_, |
238 header.public_header.guid, | 241 header.public_header.connection_id, |
239 header.packet_sequence_number); | 242 header.packet_sequence_number); |
240 } | 243 } |
241 | 244 |
242 void QuicDispatcher::CleanUpSession(SessionMap::iterator it) { | 245 void QuicDispatcher::CleanUpSession(SessionMap::iterator it) { |
243 QuicConnection* connection = it->second->connection(); | 246 QuicConnection* connection = it->second->connection(); |
244 QuicEncryptedPacket* connection_close_packet = | 247 QuicEncryptedPacket* connection_close_packet = |
245 connection->ReleaseConnectionClosePacket(); | 248 connection->ReleaseConnectionClosePacket(); |
246 write_blocked_list_.erase(connection); | 249 write_blocked_list_.erase(connection); |
247 time_wait_list_manager_->AddGuidToTimeWait(it->first, | 250 time_wait_list_manager_->AddConnectionIdToTimeWait(it->first, |
248 connection->version(), | 251 connection->version(), |
249 connection_close_packet); | 252 connection_close_packet); |
250 session_map_.erase(it); | 253 session_map_.erase(it); |
251 } | 254 } |
252 | 255 |
253 void QuicDispatcher::DeleteSessions() { | 256 void QuicDispatcher::DeleteSessions() { |
254 STLDeleteElements(&closed_session_list_); | 257 STLDeleteElements(&closed_session_list_); |
255 } | 258 } |
256 | 259 |
257 void QuicDispatcher::OnCanWrite() { | 260 void QuicDispatcher::OnCanWrite() { |
258 // We got an EPOLLOUT: the socket should not be blocked. | 261 // We got an EPOLLOUT: the socket should not be blocked. |
259 writer_->SetWritable(); | 262 writer_->SetWritable(); |
(...skipping 23 matching lines...) Expand all Loading... |
283 void QuicDispatcher::Shutdown() { | 286 void QuicDispatcher::Shutdown() { |
284 while (!session_map_.empty()) { | 287 while (!session_map_.empty()) { |
285 QuicSession* session = session_map_.begin()->second; | 288 QuicSession* session = session_map_.begin()->second; |
286 session->connection()->SendConnectionClose(QUIC_PEER_GOING_AWAY); | 289 session->connection()->SendConnectionClose(QUIC_PEER_GOING_AWAY); |
287 // Validate that the session removes itself from the session map on close. | 290 // Validate that the session removes itself from the session map on close. |
288 DCHECK(session_map_.empty() || session_map_.begin()->second != session); | 291 DCHECK(session_map_.empty() || session_map_.begin()->second != session); |
289 } | 292 } |
290 DeleteSessions(); | 293 DeleteSessions(); |
291 } | 294 } |
292 | 295 |
293 void QuicDispatcher::OnConnectionClosed(QuicGuid guid, QuicErrorCode error) { | 296 void QuicDispatcher::OnConnectionClosed(QuicConnectionId connection_id, |
294 SessionMap::iterator it = session_map_.find(guid); | 297 QuicErrorCode error) { |
| 298 SessionMap::iterator it = session_map_.find(connection_id); |
295 if (it == session_map_.end()) { | 299 if (it == session_map_.end()) { |
296 LOG(DFATAL) << "GUID " << guid << " does not exist in the session map. " | 300 LOG(DFATAL) << "ConnectionId " << connection_id |
| 301 << " does not exist in the session map. " |
297 << "Error: " << QuicUtils::ErrorToString(error); | 302 << "Error: " << QuicUtils::ErrorToString(error); |
298 LOG(DFATAL) << base::debug::StackTrace().ToString(); | 303 LOG(DFATAL) << base::debug::StackTrace().ToString(); |
299 return; | 304 return; |
300 } | 305 } |
301 | 306 |
302 DLOG_IF(INFO, error != QUIC_NO_ERROR) << "Closing connection (" << guid | 307 DLOG_IF(INFO, error != QUIC_NO_ERROR) << "Closing connection (" |
| 308 << connection_id |
303 << ") due to error: " | 309 << ") due to error: " |
304 << QuicUtils::ErrorToString(error); | 310 << QuicUtils::ErrorToString(error); |
305 | 311 |
306 if (closed_session_list_.empty()) { | 312 if (closed_session_list_.empty()) { |
307 epoll_server_->RegisterAlarmApproximateDelta( | 313 epoll_server_->RegisterAlarmApproximateDelta( |
308 0, delete_sessions_alarm_.get()); | 314 0, delete_sessions_alarm_.get()); |
309 } | 315 } |
310 closed_session_list_.push_back(it->second); | 316 closed_session_list_.push_back(it->second); |
311 CleanUpSession(it); | 317 CleanUpSession(it); |
312 } | 318 } |
313 | 319 |
314 void QuicDispatcher::OnWriteBlocked(QuicBlockedWriterInterface* writer) { | 320 void QuicDispatcher::OnWriteBlocked(QuicBlockedWriterInterface* writer) { |
315 DCHECK(writer_->IsWriteBlocked()); | 321 DCHECK(writer_->IsWriteBlocked()); |
316 write_blocked_list_.insert(make_pair(writer, true)); | 322 write_blocked_list_.insert(make_pair(writer, true)); |
317 } | 323 } |
318 | 324 |
319 QuicPacketWriter* QuicDispatcher::CreateWriter(int fd) { | 325 QuicPacketWriter* QuicDispatcher::CreateWriter(int fd) { |
320 return new QuicDefaultPacketWriter(fd); | 326 return new QuicDefaultPacketWriter(fd); |
321 } | 327 } |
322 | 328 |
323 QuicPacketWriterWrapper* QuicDispatcher::CreateWriterWrapper( | 329 QuicPacketWriterWrapper* QuicDispatcher::CreateWriterWrapper( |
324 QuicPacketWriter* writer) { | 330 QuicPacketWriter* writer) { |
325 return new QuicPacketWriterWrapper(writer); | 331 return new QuicPacketWriterWrapper(writer); |
326 } | 332 } |
327 | 333 |
328 QuicSession* QuicDispatcher::CreateQuicSession( | 334 QuicSession* QuicDispatcher::CreateQuicSession( |
329 QuicGuid guid, | 335 QuicConnectionId connection_id, |
330 const IPEndPoint& server_address, | 336 const IPEndPoint& server_address, |
331 const IPEndPoint& client_address) { | 337 const IPEndPoint& client_address) { |
332 QuicServerSession* session = new QuicServerSession( | 338 QuicServerSession* session = new QuicServerSession( |
333 config_, | 339 config_, |
334 CreateQuicConnection(guid, server_address, client_address), | 340 CreateQuicConnection(connection_id, server_address, client_address), |
335 this); | 341 this); |
336 session->InitializeSession(crypto_config_); | 342 session->InitializeSession(crypto_config_); |
337 return session; | 343 return session; |
338 } | 344 } |
339 | 345 |
340 QuicConnection* QuicDispatcher::CreateQuicConnection( | 346 QuicConnection* QuicDispatcher::CreateQuicConnection( |
341 QuicGuid guid, | 347 QuicConnectionId connection_id, |
342 const IPEndPoint& server_address, | 348 const IPEndPoint& server_address, |
343 const IPEndPoint& client_address) { | 349 const IPEndPoint& client_address) { |
344 return new QuicConnection(guid, client_address, helper_.get(), writer_.get(), | 350 return new QuicConnection(connection_id, client_address, helper_.get(), |
345 true, supported_versions_); | 351 writer_.get(), true, supported_versions_); |
346 } | 352 } |
347 | 353 |
348 void QuicDispatcher::set_writer(QuicPacketWriter* writer) { | 354 void QuicDispatcher::set_writer(QuicPacketWriter* writer) { |
349 writer_->set_writer(writer); | 355 writer_->set_writer(writer); |
350 } | 356 } |
351 | 357 |
352 bool QuicDispatcher::HandlePacketForTimeWait( | 358 bool QuicDispatcher::HandlePacketForTimeWait( |
353 const QuicPacketPublicHeader& header) { | 359 const QuicPacketPublicHeader& header) { |
354 if (header.reset_flag) { | 360 if (header.reset_flag) { |
355 // Public reset packets do not have sequence numbers, so ignore the packet. | 361 // Public reset packets do not have sequence numbers, so ignore the packet. |
356 return false; | 362 return false; |
357 } | 363 } |
358 | 364 |
359 // Switch the framer to the correct version, so that the sequence number can | 365 // Switch the framer to the correct version, so that the sequence number can |
360 // be parsed correctly. | 366 // be parsed correctly. |
361 framer_.set_version(time_wait_list_manager_->GetQuicVersionFromGuid( | 367 framer_.set_version(time_wait_list_manager_->GetQuicVersionFromConnectionId( |
362 header.guid)); | 368 header.connection_id)); |
363 | 369 |
364 // Continue parsing the packet to extract the sequence number. Then | 370 // Continue parsing the packet to extract the sequence number. Then |
365 // send it to the time wait manager in OnUnathenticatedHeader. | 371 // send it to the time wait manager in OnUnathenticatedHeader. |
366 return true; | 372 return true; |
367 } | 373 } |
368 | 374 |
369 } // namespace tools | 375 } // namespace tools |
370 } // namespace net | 376 } // namespace net |
OLD | NEW |