| Index: net/dns/dns_transaction.cc
|
| diff --git a/net/dns/dns_transaction.cc b/net/dns/dns_transaction.cc
|
| index 130922c6025620f821e6662d5ebfb318da00fb89..0424d48b048085ea68676c4a5e5a66c54e2fe6c9 100644
|
| --- a/net/dns/dns_transaction.cc
|
| +++ b/net/dns/dns_transaction.cc
|
| @@ -339,7 +339,9 @@ class DnsTCPAttempt : public DnsAttempt {
|
| STATE_SEND_LENGTH,
|
| STATE_SEND_QUERY,
|
| STATE_READ_LENGTH,
|
| + STATE_READ_LENGTH_COMPLETE,
|
| STATE_READ_RESPONSE,
|
| + STATE_READ_RESPONSE_COMPLETE,
|
| STATE_NONE,
|
| };
|
|
|
| @@ -362,9 +364,15 @@ class DnsTCPAttempt : public DnsAttempt {
|
| case STATE_READ_LENGTH:
|
| rv = DoReadLength(rv);
|
| break;
|
| + case STATE_READ_LENGTH_COMPLETE:
|
| + rv = DoReadLengthComplete(rv);
|
| + break;
|
| case STATE_READ_RESPONSE:
|
| rv = DoReadResponse(rv);
|
| break;
|
| + case STATE_READ_RESPONSE_COMPLETE:
|
| + rv = DoReadResponseComplete(rv);
|
| + break;
|
| default:
|
| NOTREACHED();
|
| break;
|
| @@ -435,18 +443,25 @@ class DnsTCPAttempt : public DnsAttempt {
|
| }
|
|
|
| int DoReadLength(int rv) {
|
| + DCHECK_EQ(OK, rv);
|
| +
|
| + next_state_ = STATE_READ_LENGTH_COMPLETE;
|
| + return ReadIntoBuffer();
|
| + }
|
| +
|
| + int DoReadLengthComplete(int rv) {
|
| DCHECK_NE(ERR_IO_PENDING, rv);
|
| if (rv < 0)
|
| return rv;
|
| + if (rv == 0)
|
| + return ERR_CONNECTION_CLOSED;
|
|
|
| buffer_->DidConsume(rv);
|
| if (buffer_->BytesRemaining() > 0) {
|
| next_state_ = STATE_READ_LENGTH;
|
| - return socket_->Read(
|
| - buffer_.get(),
|
| - buffer_->BytesRemaining(),
|
| - base::Bind(&DnsTCPAttempt::OnIOComplete, base::Unretained(this)));
|
| + return OK;
|
| }
|
| +
|
| base::ReadBigEndian<uint16>(length_buffer_->data(), &response_length_);
|
| // Check if advertised response is too short. (Optimization only.)
|
| if (response_length_ < query_->io_buffer()->size())
|
| @@ -459,18 +474,25 @@ class DnsTCPAttempt : public DnsAttempt {
|
| }
|
|
|
| int DoReadResponse(int rv) {
|
| + DCHECK_EQ(OK, rv);
|
| +
|
| + next_state_ = STATE_READ_RESPONSE_COMPLETE;
|
| + return ReadIntoBuffer();
|
| + }
|
| +
|
| + int DoReadResponseComplete(int rv) {
|
| DCHECK_NE(ERR_IO_PENDING, rv);
|
| if (rv < 0)
|
| return rv;
|
| + if (rv == 0)
|
| + return ERR_CONNECTION_CLOSED;
|
|
|
| buffer_->DidConsume(rv);
|
| if (buffer_->BytesRemaining() > 0) {
|
| next_state_ = STATE_READ_RESPONSE;
|
| - return socket_->Read(
|
| - buffer_.get(),
|
| - buffer_->BytesRemaining(),
|
| - base::Bind(&DnsTCPAttempt::OnIOComplete, base::Unretained(this)));
|
| + return OK;
|
| }
|
| +
|
| if (!response_->InitParse(buffer_->BytesConsumed(), *query_))
|
| return ERR_DNS_MALFORMED_RESPONSE;
|
| if (response_->flags() & dns_protocol::kFlagTC)
|
| @@ -490,6 +512,13 @@ class DnsTCPAttempt : public DnsAttempt {
|
| callback_.Run(rv);
|
| }
|
|
|
| + int ReadIntoBuffer() {
|
| + return socket_->Read(
|
| + buffer_.get(),
|
| + buffer_->BytesRemaining(),
|
| + base::Bind(&DnsTCPAttempt::OnIOComplete, base::Unretained(this)));
|
| + }
|
| +
|
| State next_state_;
|
| base::TimeTicks start_time_;
|
|
|
|
|