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

Unified Diff: net/dns/dns_transaction.cc

Issue 9190031: DnsClient refactoring + features (timeout, suffix search, server rotation). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added comments. Fixed tests. Created 8 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: net/dns/dns_transaction.cc
diff --git a/net/dns/dns_transaction.cc b/net/dns/dns_transaction.cc
deleted file mode 100644
index 6d711b4a5a97cbcd3fe4d3b88cf1192a962a3177..0000000000000000000000000000000000000000
--- a/net/dns/dns_transaction.cc
+++ /dev/null
@@ -1,278 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/dns/dns_transaction.h"
-
-#include "base/bind.h"
-#include "base/rand_util.h"
-#include "base/values.h"
-#include "net/base/io_buffer.h"
-#include "net/base/net_errors.h"
-#include "net/dns/dns_protocol.h"
-#include "net/dns/dns_query.h"
-#include "net/dns/dns_response.h"
-#include "net/dns/dns_session.h"
-#include "net/socket/client_socket_factory.h"
-#include "net/udp/datagram_client_socket.h"
-
-namespace net {
-
-namespace {
-
-class DnsTransactionStartParameters : public NetLog::EventParameters {
- public:
- DnsTransactionStartParameters(const IPEndPoint& dns_server,
- const base::StringPiece& qname,
- uint16 qtype,
- const NetLog::Source& source)
- : dns_server_(dns_server),
- qname_(qname.data(), qname.length()),
- qtype_(qtype),
- source_(source) {}
-
- virtual Value* ToValue() const {
- DictionaryValue* dict = new DictionaryValue();
- dict->SetString("dns_server", dns_server_.ToString());
- dict->SetString("hostname", qname_);
- dict->SetInteger("query_type", qtype_);
- if (source_.is_valid())
- dict->Set("source_dependency", source_.ToValue());
- return dict;
- }
-
- private:
- IPEndPoint dns_server_;
- std::string qname_;
- uint16 qtype_;
- const NetLog::Source source_;
-};
-
-class DnsTransactionFinishParameters : public NetLog::EventParameters {
- public:
- // TODO(szym): add rcode ?
- DnsTransactionFinishParameters(int net_error, int answer_count)
- : net_error_(net_error), answer_count_(answer_count) {}
-
- virtual Value* ToValue() const {
- DictionaryValue* dict = new DictionaryValue();
- if (net_error_)
- dict->SetInteger("net_error", net_error_);
- dict->SetInteger("answer_count", answer_count_);
- return dict;
- }
-
- private:
- const int net_error_;
- const int answer_count_;
-};
-
-class DnsTransactionRetryParameters : public NetLog::EventParameters {
- public:
- DnsTransactionRetryParameters(int attempt_number,
- const NetLog::Source& source)
- : attempt_number_(attempt_number), source_(source) {}
-
- virtual Value* ToValue() const {
- DictionaryValue* dict = new DictionaryValue();
- dict->SetInteger("attempt_number", attempt_number_);
- dict->Set("source_dependency", source_.ToValue());
- return dict;
- }
-
- private:
- const int attempt_number_;
- const NetLog::Source source_;
-};
-
-} // namespace
-
-
-DnsTransaction::DnsTransaction(DnsSession* session,
- const base::StringPiece& qname,
- uint16 qtype,
- const ResultCallback& callback,
- const BoundNetLog& source_net_log)
- : session_(session),
- dns_server_(session->NextServer()),
- query_(new DnsQuery(session->NextId(), qname, qtype)),
- callback_(callback),
- attempts_(0),
- next_state_(STATE_NONE),
- net_log_(BoundNetLog::Make(session->net_log(),
- NetLog::SOURCE_DNS_TRANSACTION)) {
- net_log_.BeginEvent(
- NetLog::TYPE_DNS_TRANSACTION,
- make_scoped_refptr(
- new DnsTransactionStartParameters(dns_server_,
- qname,
- qtype,
- source_net_log.source())));
-}
-
-DnsTransaction::~DnsTransaction() {}
-
-int DnsTransaction::Start() {
- DCHECK_EQ(STATE_NONE, next_state_);
- next_state_ = STATE_CONNECT;
- return DoLoop(OK);
-}
-
-int DnsTransaction::DoLoop(int result) {
- DCHECK_NE(STATE_NONE, next_state_);
- int rv = result;
- do {
- State state = next_state_;
- next_state_ = STATE_NONE;
- switch (state) {
- case STATE_CONNECT:
- rv = DoConnect();
- break;
- case STATE_CONNECT_COMPLETE:
- rv = DoConnectComplete(rv);
- break;
- case STATE_SEND_QUERY:
- rv = DoSendQuery();
- break;
- case STATE_SEND_QUERY_COMPLETE:
- rv = DoSendQueryComplete(rv);
- break;
- case STATE_READ_RESPONSE:
- rv = DoReadResponse();
- break;
- case STATE_READ_RESPONSE_COMPLETE:
- rv = DoReadResponseComplete(rv);
- break;
- default:
- NOTREACHED();
- break;
- }
- } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
-
- return rv;
-}
-
-void DnsTransaction::DoCallback(int result) {
- DCHECK_NE(result, ERR_IO_PENDING);
- int answer_count = (result == OK) ? response()->answer_count() : 0;
- net_log_.EndEvent(
- NetLog::TYPE_DNS_TRANSACTION,
- make_scoped_refptr(
- new DnsTransactionFinishParameters(result, answer_count)));
- callback_.Run(this, result);
-}
-
-void DnsTransaction::OnIOComplete(int result) {
- int rv = DoLoop(result);
- if (rv != ERR_IO_PENDING)
- DoCallback(rv);
-}
-
-int DnsTransaction::DoConnect() {
- next_state_ = STATE_CONNECT_COMPLETE;
-
- StartTimer(session_->NextTimeout(attempts_));
- ++attempts_;
-
- // TODO(szym): keep all sockets around in case the server responds
- // after its timeout; state machine will need to change to handle that.
- // The current plan is to move socket management out to DnsSession.
- // Hence also move retransmissions to DnsClient::Request.
- socket_.reset(session_->socket_factory()->CreateDatagramClientSocket(
- DatagramSocket::RANDOM_BIND,
- base::Bind(&base::RandInt),
- net_log_.net_log(),
- net_log_.source()));
-
- net_log_.AddEvent(
- NetLog::TYPE_DNS_TRANSACTION_ATTEMPT_STARTED,
- make_scoped_refptr(
- new DnsTransactionRetryParameters(attempts_,
- socket_->NetLog().source())));
-
- return socket_->Connect(dns_server_);
-}
-
-int DnsTransaction::DoConnectComplete(int rv) {
- if (rv < 0)
- return rv;
- next_state_ = STATE_SEND_QUERY;
- return OK;
-}
-
-int DnsTransaction::DoSendQuery() {
- next_state_ = STATE_SEND_QUERY_COMPLETE;
- return socket_->Write(query_->io_buffer(),
- query_->io_buffer()->size(),
- base::Bind(&DnsTransaction::OnIOComplete,
- base::Unretained(this)));
-}
-
-int DnsTransaction::DoSendQueryComplete(int rv) {
- if (rv < 0)
- return rv;
-
- // Writing to UDP should not result in a partial datagram.
- if (rv != query_->io_buffer()->size())
- return ERR_MSG_TOO_BIG;
-
- next_state_ = STATE_READ_RESPONSE;
- return OK;
-}
-
-int DnsTransaction::DoReadResponse() {
- next_state_ = STATE_READ_RESPONSE_COMPLETE;
- response_.reset(new DnsResponse());
- return socket_->Read(response_->io_buffer(),
- response_->io_buffer()->size(),
- base::Bind(&DnsTransaction::OnIOComplete,
- base::Unretained(this)));
-}
-
-int DnsTransaction::DoReadResponseComplete(int rv) {
- DCHECK_NE(ERR_IO_PENDING, rv);
- RevokeTimer();
- if (rv < 0)
- return rv;
-
- DCHECK(rv);
- if (!response_->InitParse(rv, *query_))
- return ERR_DNS_MALFORMED_RESPONSE;
- // TODO(szym): define this flag value in dns_protocol
- if (response_->flags1() & 2)
- return ERR_DNS_SERVER_REQUIRES_TCP;
- // TODO(szym): move this handling out of DnsTransaction?
- if (response_->rcode() != dns_protocol::kRcodeNOERROR &&
- response_->rcode() != dns_protocol::kRcodeNXDOMAIN) {
- return ERR_DNS_SERVER_FAILED;
- }
- // TODO(szym): add ERR_DNS_RR_NOT_FOUND?
- if (response_->answer_count() == 0)
- return ERR_NAME_NOT_RESOLVED;
-
- return OK;
-}
-
-void DnsTransaction::StartTimer(base::TimeDelta delay) {
- timer_.Start(FROM_HERE, delay, this, &DnsTransaction::OnTimeout);
-}
-
-void DnsTransaction::RevokeTimer() {
- timer_.Stop();
-}
-
-void DnsTransaction::OnTimeout() {
- DCHECK(next_state_ == STATE_SEND_QUERY_COMPLETE ||
- next_state_ == STATE_READ_RESPONSE_COMPLETE);
- if (attempts_ == session_->config().attempts) {
- DoCallback(ERR_DNS_TIMED_OUT);
- return;
- }
- next_state_ = STATE_CONNECT;
- query_.reset(query_->CloneWithNewId(session_->NextId()));
- int rv = DoLoop(OK);
- if (rv != ERR_IO_PENDING)
- DoCallback(rv);
-}
-
-} // namespace net

Powered by Google App Engine
This is Rietveld 408576698