Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(148)

Side by Side Diff: net/tools/quic/quic_dispatcher.cc

Issue 981193003: Implement the "sanity checks" described in b/9509040: Incoming packets (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@Change_null_value_87819844
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/tools/quic/quic_dispatcher.h ('k') | net/tools/quic/quic_dispatcher_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 // ProcessPacket will cause the packet to be dispatched in 199 // ProcessPacket will cause the packet to be dispatched in
200 // OnUnauthenticatedPublicHeader, or sent to the time wait list manager 200 // OnUnauthenticatedPublicHeader, or sent to the time wait list manager
201 // in OnAuthenticatedHeader. 201 // in OnAuthenticatedHeader.
202 framer_.ProcessPacket(packet); 202 framer_.ProcessPacket(packet);
203 // TODO(rjshade): Return a status describing if/why a packet was dropped, 203 // TODO(rjshade): Return a status describing if/why a packet was dropped,
204 // and log somehow. Maybe expose as a varz. 204 // and log somehow. Maybe expose as a varz.
205 } 205 }
206 206
207 bool QuicDispatcher::OnUnauthenticatedPublicHeader( 207 bool QuicDispatcher::OnUnauthenticatedPublicHeader(
208 const QuicPacketPublicHeader& header) { 208 const QuicPacketPublicHeader& header) {
209 QuicSession* session = nullptr;
210
211 // Port zero is only allowed for unidirectional UDP, so is disallowed by QUIC. 209 // Port zero is only allowed for unidirectional UDP, so is disallowed by QUIC.
212 // Given that we can't even send a reply rejecting the packet, just black hole 210 // Given that we can't even send a reply rejecting the packet, just black hole
213 // it. 211 // it.
214 if (current_client_address_.port() == 0) { 212 if (current_client_address_.port() == 0) {
215 return false; 213 return false;
216 } 214 }
217 215
216 // The session that we have identified as the one to which this packet
217 // belongs.
218 QuicSession* session = nullptr;
218 QuicConnectionId connection_id = header.connection_id; 219 QuicConnectionId connection_id = header.connection_id;
219 SessionMap::iterator it = session_map_.find(connection_id); 220 SessionMap::iterator it = session_map_.find(connection_id);
220 if (it == session_map_.end()) { 221 if (it == session_map_.end()) {
221 if (header.reset_flag) {
222 return false;
223 }
224 if (time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)) { 222 if (time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)) {
225 return HandlePacketForTimeWait(header); 223 return HandlePacketForTimeWait(header);
226 } 224 }
227 225
228 // Ensure the packet has a version negotiation bit set before creating a new 226 // The packet has an unknown connection ID.
229 // session for it. All initial packets for a new connection are required to 227 // If the packet is a public reset, there is nothing we must do or can do.
230 // have the flag set. Otherwise it may be a stray packet. 228 if (header.reset_flag) {
231 if (header.version_flag) { 229 return false;
232 session = CreateQuicSession(connection_id, current_server_address_,
233 current_client_address_);
234 } 230 }
235 231
236 if (session == nullptr) { 232 // All packets within a connection sent by a client before receiving a
237 DVLOG(1) << "Failed to create session for " << connection_id; 233 // response from the server are required to have the version negotiation
234 // flag set. Since this may be a client continuing a connection we lost
235 // track of via server restart, send a rejection to fast-fail the
236 // connection.
237 if (!header.version_flag) {
238 DVLOG(1) << "Packet without version arrived for unknown connection ID "
239 << connection_id;
238 // Add this connection_id fo the time-wait state, to safely reject future 240 // Add this connection_id fo the time-wait state, to safely reject future
239 // packets. 241 // packets.
240 242 QuicVersion version = supported_versions_.front();
241 if (header.version_flag &&
242 !framer_.IsSupportedVersion(header.versions.front())) {
243 // TODO(ianswett): Produce a no-version version negotiation packet.
244 return false;
245 }
246
247 // Use the version in the packet if possible, otherwise assume the latest.
248 QuicVersion version = header.version_flag ? header.versions.front() :
249 supported_versions_.front();
250 time_wait_list_manager_->AddConnectionIdToTimeWait(connection_id, version, 243 time_wait_list_manager_->AddConnectionIdToTimeWait(connection_id, version,
251 nullptr); 244 nullptr);
252 DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)); 245 DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
253 return HandlePacketForTimeWait(header); 246 return HandlePacketForTimeWait(header);
254 } 247 }
255 DVLOG(1) << "Created new session for " << connection_id; 248
256 session_map_.insert(std::make_pair(connection_id, session)); 249 session = AdditionalValidityChecksThenCreateSession(header, connection_id);
250 if (session == nullptr) {
251 return false;
252 }
257 } else { 253 } else {
258 session = it->second; 254 session = it->second;
259 } 255 }
260 256
261 session->connection()->ProcessUdpPacket( 257 session->connection()->ProcessUdpPacket(
262 current_server_address_, current_client_address_, *current_packet_); 258 current_server_address_, current_client_address_, *current_packet_);
263 259
264 // Do not parse the packet further. The session will process it completely. 260 // Do not parse the packet further. The session methods called above have
261 // processed it completely.
265 return false; 262 return false;
266 } 263 }
267 264
265 QuicSession* QuicDispatcher::AdditionalValidityChecksThenCreateSession(
266 const QuicPacketPublicHeader& header,
267 QuicConnectionId connection_id) {
268 QuicSession* session = CreateQuicSession(
269 connection_id, current_server_address_, current_client_address_);
270
271 if (session == nullptr) {
272 DVLOG(1) << "Failed to create session for " << connection_id;
273
274 if (!framer_.IsSupportedVersion(header.versions.front())) {
275 // TODO(ianswett): Produce packet saying "no supported version".
276 return nullptr;
277 }
278
279 // Add this connection_id to the time-wait state, to safely reject future
280 // packets.
281 QuicVersion version = header.versions.front();
282 time_wait_list_manager_->AddConnectionIdToTimeWait(connection_id, version,
283 nullptr);
284 DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id));
285 HandlePacketForTimeWait(header);
286
287 return nullptr;
288 }
289
290 DVLOG(1) << "Created new session for " << connection_id;
291 session_map_.insert(std::make_pair(connection_id, session));
292
293 return session;
294 }
295
268 void QuicDispatcher::OnUnauthenticatedHeader(const QuicPacketHeader& header) { 296 void QuicDispatcher::OnUnauthenticatedHeader(const QuicPacketHeader& header) {
269 DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait( 297 DCHECK(time_wait_list_manager_->IsConnectionIdInTimeWait(
270 header.public_header.connection_id)); 298 header.public_header.connection_id));
271 time_wait_list_manager_->ProcessPacket(current_server_address_, 299 time_wait_list_manager_->ProcessPacket(current_server_address_,
272 current_client_address_, 300 current_client_address_,
273 header.public_header.connection_id, 301 header.public_header.connection_id,
274 header.packet_sequence_number, 302 header.packet_sequence_number,
275 *current_packet_); 303 *current_packet_);
276 } 304 }
277 305
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 framer_.set_version(time_wait_list_manager_->GetQuicVersionFromConnectionId( 428 framer_.set_version(time_wait_list_manager_->GetQuicVersionFromConnectionId(
401 header.connection_id)); 429 header.connection_id));
402 430
403 // Continue parsing the packet to extract the sequence number. Then 431 // Continue parsing the packet to extract the sequence number. Then
404 // send it to the time wait manager in OnUnathenticatedHeader. 432 // send it to the time wait manager in OnUnathenticatedHeader.
405 return true; 433 return true;
406 } 434 }
407 435
408 } // namespace tools 436 } // namespace tools
409 } // namespace net 437 } // namespace net
OLDNEW
« no previous file with comments | « net/tools/quic/quic_dispatcher.h ('k') | net/tools/quic/quic_dispatcher_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698