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 |