| 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/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 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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_READ_LENGTH, | 341 STATE_READ_LENGTH, |
| 342 STATE_READ_LENGTH_COMPLETE, |
| 342 STATE_READ_RESPONSE, | 343 STATE_READ_RESPONSE, |
| 344 STATE_READ_RESPONSE_COMPLETE, |
| 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; |
| 362 case STATE_READ_LENGTH: | 364 case STATE_READ_LENGTH: |
| 363 rv = DoReadLength(rv); | 365 rv = DoReadLength(rv); |
| 364 break; | 366 break; |
| 367 case STATE_READ_LENGTH_COMPLETE: |
| 368 rv = DoReadLengthComplete(rv); |
| 369 break; |
| 365 case STATE_READ_RESPONSE: | 370 case STATE_READ_RESPONSE: |
| 366 rv = DoReadResponse(rv); | 371 rv = DoReadResponse(rv); |
| 367 break; | 372 break; |
| 373 case STATE_READ_RESPONSE_COMPLETE: |
| 374 rv = DoReadResponseComplete(rv); |
| 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); |
| 375 if (rv == OK) { | 383 if (rv == OK) { |
| 376 DCHECK_EQ(STATE_NONE, next_state_); | 384 DCHECK_EQ(STATE_NONE, next_state_); |
| 377 DNS_HISTOGRAM("AsyncDNS.TCPAttemptSuccess", | 385 DNS_HISTOGRAM("AsyncDNS.TCPAttemptSuccess", |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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()); |
| 433 next_state_ = STATE_READ_LENGTH; | 441 next_state_ = STATE_READ_LENGTH; |
| 434 return OK; | 442 return OK; |
| 435 } | 443 } |
| 436 | 444 |
| 437 int DoReadLength(int rv) { | 445 int DoReadLength(int rv) { |
| 446 DCHECK_EQ(OK, rv); |
| 447 |
| 448 next_state_ = STATE_READ_LENGTH_COMPLETE; |
| 449 return ReadIntoBuffer(); |
| 450 } |
| 451 |
| 452 int DoReadLengthComplete(int rv) { |
| 438 DCHECK_NE(ERR_IO_PENDING, rv); | 453 DCHECK_NE(ERR_IO_PENDING, rv); |
| 439 if (rv < 0) | 454 if (rv < 0) |
| 440 return rv; | 455 return rv; |
| 456 if (rv == 0) |
| 457 return ERR_CONNECTION_CLOSED; |
| 441 | 458 |
| 442 buffer_->DidConsume(rv); | 459 buffer_->DidConsume(rv); |
| 443 if (buffer_->BytesRemaining() > 0) { | 460 if (buffer_->BytesRemaining() > 0) { |
| 444 next_state_ = STATE_READ_LENGTH; | 461 next_state_ = STATE_READ_LENGTH; |
| 445 return socket_->Read( | 462 return OK; |
| 446 buffer_.get(), | |
| 447 buffer_->BytesRemaining(), | |
| 448 base::Bind(&DnsTCPAttempt::OnIOComplete, base::Unretained(this))); | |
| 449 } | 463 } |
| 464 |
| 450 base::ReadBigEndian<uint16>(length_buffer_->data(), &response_length_); | 465 base::ReadBigEndian<uint16>(length_buffer_->data(), &response_length_); |
| 451 // Check if advertised response is too short. (Optimization only.) | 466 // Check if advertised response is too short. (Optimization only.) |
| 452 if (response_length_ < query_->io_buffer()->size()) | 467 if (response_length_ < query_->io_buffer()->size()) |
| 453 return ERR_DNS_MALFORMED_RESPONSE; | 468 return ERR_DNS_MALFORMED_RESPONSE; |
| 454 // Allocate more space so that DnsResponse::InitParse sanity check passes. | 469 // Allocate more space so that DnsResponse::InitParse sanity check passes. |
| 455 response_.reset(new DnsResponse(response_length_ + 1)); | 470 response_.reset(new DnsResponse(response_length_ + 1)); |
| 456 buffer_ = new DrainableIOBuffer(response_->io_buffer(), response_length_); | 471 buffer_ = new DrainableIOBuffer(response_->io_buffer(), response_length_); |
| 457 next_state_ = STATE_READ_RESPONSE; | 472 next_state_ = STATE_READ_RESPONSE; |
| 458 return OK; | 473 return OK; |
| 459 } | 474 } |
| 460 | 475 |
| 461 int DoReadResponse(int rv) { | 476 int DoReadResponse(int rv) { |
| 477 DCHECK_EQ(OK, rv); |
| 478 |
| 479 next_state_ = STATE_READ_RESPONSE_COMPLETE; |
| 480 return ReadIntoBuffer(); |
| 481 } |
| 482 |
| 483 int DoReadResponseComplete(int rv) { |
| 462 DCHECK_NE(ERR_IO_PENDING, rv); | 484 DCHECK_NE(ERR_IO_PENDING, rv); |
| 463 if (rv < 0) | 485 if (rv < 0) |
| 464 return rv; | 486 return rv; |
| 487 if (rv == 0) |
| 488 return ERR_CONNECTION_CLOSED; |
| 465 | 489 |
| 466 buffer_->DidConsume(rv); | 490 buffer_->DidConsume(rv); |
| 467 if (buffer_->BytesRemaining() > 0) { | 491 if (buffer_->BytesRemaining() > 0) { |
| 468 next_state_ = STATE_READ_RESPONSE; | 492 next_state_ = STATE_READ_RESPONSE; |
| 469 return socket_->Read( | 493 return OK; |
| 470 buffer_.get(), | |
| 471 buffer_->BytesRemaining(), | |
| 472 base::Bind(&DnsTCPAttempt::OnIOComplete, base::Unretained(this))); | |
| 473 } | 494 } |
| 495 |
| 474 if (!response_->InitParse(buffer_->BytesConsumed(), *query_)) | 496 if (!response_->InitParse(buffer_->BytesConsumed(), *query_)) |
| 475 return ERR_DNS_MALFORMED_RESPONSE; | 497 return ERR_DNS_MALFORMED_RESPONSE; |
| 476 if (response_->flags() & dns_protocol::kFlagTC) | 498 if (response_->flags() & dns_protocol::kFlagTC) |
| 477 return ERR_UNEXPECTED; | 499 return ERR_UNEXPECTED; |
| 478 // TODO(szym): Frankly, none of these are expected. | 500 // TODO(szym): Frankly, none of these are expected. |
| 479 if (response_->rcode() == dns_protocol::kRcodeNXDOMAIN) | 501 if (response_->rcode() == dns_protocol::kRcodeNXDOMAIN) |
| 480 return ERR_NAME_NOT_RESOLVED; | 502 return ERR_NAME_NOT_RESOLVED; |
| 481 if (response_->rcode() != dns_protocol::kRcodeNOERROR) | 503 if (response_->rcode() != dns_protocol::kRcodeNOERROR) |
| 482 return ERR_DNS_SERVER_FAILED; | 504 return ERR_DNS_SERVER_FAILED; |
| 483 | 505 |
| 484 return OK; | 506 return OK; |
| 485 } | 507 } |
| 486 | 508 |
| 487 void OnIOComplete(int rv) { | 509 void OnIOComplete(int rv) { |
| 488 rv = DoLoop(rv); | 510 rv = DoLoop(rv); |
| 489 if (rv != ERR_IO_PENDING) | 511 if (rv != ERR_IO_PENDING) |
| 490 callback_.Run(rv); | 512 callback_.Run(rv); |
| 491 } | 513 } |
| 492 | 514 |
| 515 int ReadIntoBuffer() { |
| 516 return socket_->Read( |
| 517 buffer_.get(), |
| 518 buffer_->BytesRemaining(), |
| 519 base::Bind(&DnsTCPAttempt::OnIOComplete, base::Unretained(this))); |
| 520 } |
| 521 |
| 493 State next_state_; | 522 State next_state_; |
| 494 base::TimeTicks start_time_; | 523 base::TimeTicks start_time_; |
| 495 | 524 |
| 496 scoped_ptr<StreamSocket> socket_; | 525 scoped_ptr<StreamSocket> socket_; |
| 497 scoped_ptr<DnsQuery> query_; | 526 scoped_ptr<DnsQuery> query_; |
| 498 scoped_refptr<IOBufferWithSize> length_buffer_; | 527 scoped_refptr<IOBufferWithSize> length_buffer_; |
| 499 scoped_refptr<DrainableIOBuffer> buffer_; | 528 scoped_refptr<DrainableIOBuffer> buffer_; |
| 500 | 529 |
| 501 uint16 response_length_; | 530 uint16 response_length_; |
| 502 scoped_ptr<DnsResponse> response_; | 531 scoped_ptr<DnsResponse> response_; |
| (...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 955 } // namespace | 984 } // namespace |
| 956 | 985 |
| 957 // static | 986 // static |
| 958 scoped_ptr<DnsTransactionFactory> DnsTransactionFactory::CreateFactory( | 987 scoped_ptr<DnsTransactionFactory> DnsTransactionFactory::CreateFactory( |
| 959 DnsSession* session) { | 988 DnsSession* session) { |
| 960 return scoped_ptr<DnsTransactionFactory>( | 989 return scoped_ptr<DnsTransactionFactory>( |
| 961 new DnsTransactionFactoryImpl(session)); | 990 new DnsTransactionFactoryImpl(session)); |
| 962 } | 991 } |
| 963 | 992 |
| 964 } // namespace net | 993 } // namespace net |
| OLD | NEW |