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_; |