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

Side by Side Diff: net/dns/dns_transaction.cc

Issue 422323004: DNS: Don't spin on unexpected EOF reading TCP response (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add unit tests, remove histograms Created 6 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | net/dns/dns_transaction_unittest.cc » ('j') | net/dns/dns_transaction_unittest.cc » ('J')
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/dns/dns_transaction.h" 5 #include "net/dns/dns_transaction.h"
6 6
7 #include <deque> 7 #include <deque>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 331
332 virtual const BoundNetLog& GetSocketNetLog() const OVERRIDE { 332 virtual const BoundNetLog& GetSocketNetLog() const OVERRIDE {
333 return socket_->NetLog(); 333 return socket_->NetLog();
334 } 334 }
335 335
336 private: 336 private:
337 enum State { 337 enum State {
338 STATE_CONNECT_COMPLETE, 338 STATE_CONNECT_COMPLETE,
339 STATE_SEND_LENGTH, 339 STATE_SEND_LENGTH,
340 STATE_SEND_QUERY, 340 STATE_SEND_QUERY,
341 STATE_START_READING_LENGTH,
341 STATE_READ_LENGTH, 342 STATE_READ_LENGTH,
343 STATE_START_READING_RESPONSE,
342 STATE_READ_RESPONSE, 344 STATE_READ_RESPONSE,
343 STATE_NONE, 345 STATE_NONE,
344 }; 346 };
345 347
346 int DoLoop(int result) { 348 int DoLoop(int result) {
347 CHECK_NE(STATE_NONE, next_state_); 349 CHECK_NE(STATE_NONE, next_state_);
348 int rv = result; 350 int rv = result;
349 do { 351 do {
350 State state = next_state_; 352 State state = next_state_;
351 next_state_ = STATE_NONE; 353 next_state_ = STATE_NONE;
352 switch (state) { 354 switch (state) {
353 case STATE_CONNECT_COMPLETE: 355 case STATE_CONNECT_COMPLETE:
354 rv = DoConnectComplete(rv); 356 rv = DoConnectComplete(rv);
355 break; 357 break;
356 case STATE_SEND_LENGTH: 358 case STATE_SEND_LENGTH:
357 rv = DoSendLength(rv); 359 rv = DoSendLength(rv);
358 break; 360 break;
359 case STATE_SEND_QUERY: 361 case STATE_SEND_QUERY:
360 rv = DoSendQuery(rv); 362 rv = DoSendQuery(rv);
361 break; 363 break;
364 case STATE_START_READING_LENGTH:
365 rv = DoStartReadingLength(rv);
366 break;
362 case STATE_READ_LENGTH: 367 case STATE_READ_LENGTH:
363 rv = DoReadLength(rv); 368 rv = DoReadLength(rv);
364 break; 369 break;
370 case STATE_START_READING_RESPONSE:
371 rv = DoStartReadingResponse(rv);
372 break;
365 case STATE_READ_RESPONSE: 373 case STATE_READ_RESPONSE:
366 rv = DoReadResponse(rv); 374 rv = DoReadResponse(rv);
367 break; 375 break;
368 default: 376 default:
369 NOTREACHED(); 377 NOTREACHED();
370 break; 378 break;
371 } 379 }
372 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); 380 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
373 381
374 set_result(rv); 382 set_result(rv);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 buffer_->DidConsume(rv); 431 buffer_->DidConsume(rv);
424 if (buffer_->BytesRemaining() > 0) { 432 if (buffer_->BytesRemaining() > 0) {
425 next_state_ = STATE_SEND_QUERY; 433 next_state_ = STATE_SEND_QUERY;
426 return socket_->Write( 434 return socket_->Write(
427 buffer_.get(), 435 buffer_.get(),
428 buffer_->BytesRemaining(), 436 buffer_->BytesRemaining(),
429 base::Bind(&DnsTCPAttempt::OnIOComplete, base::Unretained(this))); 437 base::Bind(&DnsTCPAttempt::OnIOComplete, base::Unretained(this)));
430 } 438 }
431 buffer_ = 439 buffer_ =
432 new DrainableIOBuffer(length_buffer_.get(), length_buffer_->size()); 440 new DrainableIOBuffer(length_buffer_.get(), length_buffer_->size());
441 next_state_ = STATE_START_READING_LENGTH;
442 return OK;
443 }
444
445 int DoStartReadingLength(int rv) {
446 DCHECK_NE(ERR_IO_PENDING, rv);
447 if (rv < 0)
448 return rv;
449
433 next_state_ = STATE_READ_LENGTH; 450 next_state_ = STATE_READ_LENGTH;
434 return OK; 451 return ReadIntoBuffer();
435 } 452 }
436 453
437 int DoReadLength(int rv) { 454 int DoReadLength(int rv) {
438 DCHECK_NE(ERR_IO_PENDING, rv); 455 DCHECK_NE(ERR_IO_PENDING, rv);
439 if (rv < 0) 456 if (rv < 0)
440 return rv; 457 return rv;
458 if (rv == 0)
459 return ERR_CONNECTION_CLOSED;
441 460
442 buffer_->DidConsume(rv); 461 buffer_->DidConsume(rv);
443 if (buffer_->BytesRemaining() > 0) { 462 if (buffer_->BytesRemaining() > 0) {
444 next_state_ = STATE_READ_LENGTH; 463 next_state_ = STATE_READ_LENGTH;
445 return socket_->Read( 464 return ReadIntoBuffer();
446 buffer_.get(),
447 buffer_->BytesRemaining(),
448 base::Bind(&DnsTCPAttempt::OnIOComplete, base::Unretained(this)));
449 } 465 }
466
450 base::ReadBigEndian<uint16>(length_buffer_->data(), &response_length_); 467 base::ReadBigEndian<uint16>(length_buffer_->data(), &response_length_);
451 // Check if advertised response is too short. (Optimization only.) 468 // Check if advertised response is too short. (Optimization only.)
452 if (response_length_ < query_->io_buffer()->size()) 469 if (response_length_ < query_->io_buffer()->size())
453 return ERR_DNS_MALFORMED_RESPONSE; 470 return ERR_DNS_MALFORMED_RESPONSE;
454 // Allocate more space so that DnsResponse::InitParse sanity check passes. 471 // Allocate more space so that DnsResponse::InitParse sanity check passes.
455 response_.reset(new DnsResponse(response_length_ + 1)); 472 response_.reset(new DnsResponse(response_length_ + 1));
456 buffer_ = new DrainableIOBuffer(response_->io_buffer(), response_length_); 473 buffer_ = new DrainableIOBuffer(response_->io_buffer(), response_length_);
474 next_state_ = STATE_START_READING_RESPONSE;
475 return OK;
476 }
477
478 int DoStartReadingResponse(int rv) {
479 DCHECK_NE(ERR_IO_PENDING, rv);
480 if (rv < 0)
481 return rv;
482
457 next_state_ = STATE_READ_RESPONSE; 483 next_state_ = STATE_READ_RESPONSE;
458 return OK; 484 return ReadIntoBuffer();
459 } 485 }
460 486
461 int DoReadResponse(int rv) { 487 int DoReadResponse(int rv) {
462 DCHECK_NE(ERR_IO_PENDING, rv); 488 DCHECK_NE(ERR_IO_PENDING, rv);
463 if (rv < 0) 489 if (rv < 0)
464 return rv; 490 return rv;
491 if (rv == 0)
492 return ERR_CONNECTION_CLOSED;
465 493
466 buffer_->DidConsume(rv); 494 buffer_->DidConsume(rv);
467 if (buffer_->BytesRemaining() > 0) { 495 if (buffer_->BytesRemaining() > 0) {
468 next_state_ = STATE_READ_RESPONSE; 496 next_state_ = STATE_READ_RESPONSE;
469 return socket_->Read( 497 return ReadIntoBuffer();
mmenke 2014/08/01 15:38:42 I think this would be much clearer with: // Note
Deprecated (see juliatuttle) 2014/08/01 22:01:10 Done.
470 buffer_.get(),
471 buffer_->BytesRemaining(),
472 base::Bind(&DnsTCPAttempt::OnIOComplete, base::Unretained(this)));
473 } 498 }
499
474 if (!response_->InitParse(buffer_->BytesConsumed(), *query_)) 500 if (!response_->InitParse(buffer_->BytesConsumed(), *query_))
475 return ERR_DNS_MALFORMED_RESPONSE; 501 return ERR_DNS_MALFORMED_RESPONSE;
476 if (response_->flags() & dns_protocol::kFlagTC) 502 if (response_->flags() & dns_protocol::kFlagTC)
477 return ERR_UNEXPECTED; 503 return ERR_UNEXPECTED;
478 // TODO(szym): Frankly, none of these are expected. 504 // TODO(szym): Frankly, none of these are expected.
479 if (response_->rcode() == dns_protocol::kRcodeNXDOMAIN) 505 if (response_->rcode() == dns_protocol::kRcodeNXDOMAIN)
480 return ERR_NAME_NOT_RESOLVED; 506 return ERR_NAME_NOT_RESOLVED;
481 if (response_->rcode() != dns_protocol::kRcodeNOERROR) 507 if (response_->rcode() != dns_protocol::kRcodeNOERROR)
482 return ERR_DNS_SERVER_FAILED; 508 return ERR_DNS_SERVER_FAILED;
483 509
484 return OK; 510 return OK;
485 } 511 }
486 512
487 void OnIOComplete(int rv) { 513 void OnIOComplete(int rv) {
488 rv = DoLoop(rv); 514 rv = DoLoop(rv);
489 if (rv != ERR_IO_PENDING) 515 if (rv != ERR_IO_PENDING)
490 callback_.Run(rv); 516 callback_.Run(rv);
491 } 517 }
492 518
519 int ReadIntoBuffer() {
520 int rv = socket_->Read(
521 buffer_.get(),
522 buffer_->BytesRemaining(),
523 base::Bind(&DnsTCPAttempt::OnIOComplete, base::Unretained(this)));
524 return (rv != 0) ? rv : ERR_CONNECTION_CLOSED;
525 }
526
493 State next_state_; 527 State next_state_;
494 base::TimeTicks start_time_; 528 base::TimeTicks start_time_;
495 529
496 scoped_ptr<StreamSocket> socket_; 530 scoped_ptr<StreamSocket> socket_;
497 scoped_ptr<DnsQuery> query_; 531 scoped_ptr<DnsQuery> query_;
498 scoped_refptr<IOBufferWithSize> length_buffer_; 532 scoped_refptr<IOBufferWithSize> length_buffer_;
499 scoped_refptr<DrainableIOBuffer> buffer_; 533 scoped_refptr<DrainableIOBuffer> buffer_;
500 534
501 uint16 response_length_; 535 uint16 response_length_;
502 scoped_ptr<DnsResponse> response_; 536 scoped_ptr<DnsResponse> response_;
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
955 } // namespace 989 } // namespace
956 990
957 // static 991 // static
958 scoped_ptr<DnsTransactionFactory> DnsTransactionFactory::CreateFactory( 992 scoped_ptr<DnsTransactionFactory> DnsTransactionFactory::CreateFactory(
959 DnsSession* session) { 993 DnsSession* session) {
960 return scoped_ptr<DnsTransactionFactory>( 994 return scoped_ptr<DnsTransactionFactory>(
961 new DnsTransactionFactoryImpl(session)); 995 new DnsTransactionFactoryImpl(session));
962 } 996 }
963 997
964 } // namespace net 998 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | net/dns/dns_transaction_unittest.cc » ('j') | net/dns/dns_transaction_unittest.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698