summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorszym@chromium.org <szym@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-07 10:09:54 +0000
committerszym@chromium.org <szym@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-07 10:09:54 +0000
commit9d22312b9a3fb1a7040687aa65102ea21fca8ca5 (patch)
tree5e5887f3408294dd6a46abf888339ae6fc4f3e3c
parent99fd314f33f3843d2ef523f71aabdda830cef30b (diff)
downloadchromium_src-9d22312b9a3fb1a7040687aa65102ea21fca8ca5.zip
chromium_src-9d22312b9a3fb1a7040687aa65102ea21fca8ca5.tar.gz
chromium_src-9d22312b9a3fb1a7040687aa65102ea21fca8ca5.tar.bz2
[net/dns] Handle synchronous completions of DnsUDPAttempt.
BUG=120976 TEST=./net_unittests --gtest_filter=DnsTransactionTest.Sync* Review URL: https://chromiumcodereview.appspot.com/9958082 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@131271 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--net/dns/dns_test_util.h8
-rw-r--r--net/dns/dns_transaction.cc177
-rw-r--r--net/dns/dns_transaction_unittest.cc240
3 files changed, 272 insertions, 153 deletions
diff --git a/net/dns/dns_test_util.h b/net/dns/dns_test_util.h
index 019dba8..e7bd457 100644
--- a/net/dns/dns_test_util.h
+++ b/net/dns/dns_test_util.h
@@ -51,6 +51,8 @@ static const char* const kT0IpAddresses[] = {
};
static const char kT0CanonName[] = "www.l.google.com";
static const int kT0TTL = 0x000000e4;
+// +1 for the CNAME record.
+static const unsigned kT0RecordCount = arraysize(kT0IpAddresses) + 1;
//-----------------------------------------------------------------------------
// Query/response set for codereview.chromium.org, ID is fixed to 1.
@@ -83,6 +85,8 @@ static const char* const kT1IpAddresses[] = {
};
static const char kT1CanonName[] = "ghs.l.google.com";
static const int kT1TTL = 0x0000010b;
+// +1 for the CNAME record.
+static const unsigned kT1RecordCount = arraysize(kT1IpAddresses) + 1;
//-----------------------------------------------------------------------------
// Query/response set for www.ccs.neu.edu, ID is fixed to 2.
@@ -114,6 +118,8 @@ static const char* const kT2IpAddresses[] = {
};
static const char kT2CanonName[] = "vulcan.ccs.neu.edu";
static const int kT2TTL = 0x0000012c;
+// +1 for the CNAME record.
+static const unsigned kT2RecordCount = arraysize(kT2IpAddresses) + 1;
//-----------------------------------------------------------------------------
// Query/response set for www.google.az, ID is fixed to 3.
@@ -157,6 +163,8 @@ static const char* const kT3IpAddresses[] = {
};
static const char kT3CanonName[] = "www.l.google.com";
static const int kT3TTL = 0x00000015;
+// +2 for the CNAME records.
+static const unsigned kT3RecordCount = arraysize(kT3IpAddresses) + 2;
class DnsClient;
// Creates mock DnsClient for testing HostResolverImpl.
diff --git a/net/dns/dns_transaction.cc b/net/dns/dns_transaction.cc
index 6dd939e..dd7b659 100644
--- a/net/dns/dns_transaction.cc
+++ b/net/dns/dns_transaction.cc
@@ -301,32 +301,35 @@ class DnsTransactionImpl : public DnsTransaction,
net_log_.BeginEvent(NetLog::TYPE_DNS_TRANSACTION, make_scoped_refptr(
new StartParameters(hostname_, qtype_)));
int rv = PrepareSearch();
- if (rv == OK)
- rv = StartQuery();
if (rv == OK) {
- DnsUDPAttempt* attempt = attempts_->back();
- CHECK(attempt->response());
-
- // In the very unlikely case that we immediately received the response, we
- // cannot simply return OK nor run the callback, but instead complete
- // asynchronously.
- MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&DnsTransactionImpl::DoCallback,
- AsWeakPtr(),
- OK,
- attempt->response()));
- return ERR_IO_PENDING;
+ AttemptResult result = FinishAttempt(StartQuery());
+ if (result.rv == OK) {
+ // DnsTransaction must never succeed synchronously.
+ MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&DnsTransactionImpl::DoCallback, AsWeakPtr(), result));
+ return ERR_IO_PENDING;
+ }
+ rv = result.rv;
}
if (rv != ERR_IO_PENDING) {
- // Clear |callback_| to catch re-starts.
callback_.Reset();
net_log_.EndEventWithNetErrorCode(NetLog::TYPE_DNS_TRANSACTION, rv);
}
+ DCHECK_NE(OK, rv);
return rv;
}
private:
+ // Wrapper for the result of a DnsUDPAttempt.
+ struct AttemptResult {
+ AttemptResult(int rv, const DnsUDPAttempt* attempt)
+ : rv(rv), attempt(attempt) {}
+
+ int rv;
+ const DnsUDPAttempt* attempt;
+ };
+
// Prepares |qnames_| according to the DnsConfig.
int PrepareSearch() {
const DnsConfig& config = session_->config();
@@ -375,23 +378,25 @@ class DnsTransactionImpl : public DnsTransaction,
return qnames_.empty() ? ERR_NAME_NOT_RESOLVED : OK;
}
- void DoCallback(int rv, const DnsResponse* response) {
- if (callback_.is_null())
- return;
- DCHECK_NE(ERR_IO_PENDING, rv);
- CHECK(rv != OK || response != NULL);
+ void DoCallback(AttemptResult result) {
+ DCHECK(!callback_.is_null());
+ DCHECK_NE(ERR_IO_PENDING, result.rv);
+ const DnsResponse* response = result.attempt ?
+ result.attempt->response() : NULL;
+ CHECK(result.rv != OK || response != NULL);
+
+ timer_.Stop();
DnsTransactionFactory::CallbackType callback = callback_;
callback_.Reset();
- net_log_.EndEventWithNetErrorCode(NetLog::TYPE_DNS_TRANSACTION, rv);
- callback.Run(this,
- rv,
- response);
+
+ net_log_.EndEventWithNetErrorCode(NetLog::TYPE_DNS_TRANSACTION, result.rv);
+ callback.Run(this, result.rv, response);
}
// Makes another attempt at the current name, |qnames_.front()|, using the
// next nameserver.
- int MakeAttempt() {
+ AttemptResult MakeAttempt() {
unsigned attempt_number = attempts_.size();
#if defined(OS_WIN)
@@ -434,14 +439,19 @@ class DnsTransactionImpl : public DnsTransaction,
base::Unretained(this),
attempt_number));
- base::TimeDelta timeout = session_->NextTimeout(attempt_number);
- timer_.Start(FROM_HERE, timeout, this, &DnsTransactionImpl::OnTimeout);
attempts_.push_back(attempt);
- return attempt->Start();
+
+ int rv = attempt->Start();
+ if (rv == ERR_IO_PENDING) {
+ timer_.Stop();
+ base::TimeDelta timeout = session_->NextTimeout(attempt_number);
+ timer_.Start(FROM_HERE, timeout, this, &DnsTransactionImpl::OnTimeout);
+ }
+ return AttemptResult(rv, attempt);
}
// Begins query for the current name. Makes the first attempt.
- int StartQuery() {
+ AttemptResult StartQuery() {
std::string dotted_qname = DNSDomainToString(qnames_.front());
net_log_.BeginEvent(
NetLog::TYPE_DNS_TRANSACTION_QUERY,
@@ -454,12 +464,17 @@ class DnsTransactionImpl : public DnsTransaction,
}
void OnAttemptComplete(unsigned attempt_number, int rv) {
+ if (callback_.is_null())
+ return;
DCHECK_LT(attempt_number, attempts_.size());
- timer_.Stop();
-
const DnsUDPAttempt* attempt = attempts_[attempt_number];
+ AttemptResult result = FinishAttempt(AttemptResult(rv, attempt));
+ if (result.rv != ERR_IO_PENDING)
+ DoCallback(result);
+ }
- if (attempt->response()) {
+ void LogResponse(const DnsUDPAttempt* attempt) {
+ if (attempt && attempt->response()) {
net_log_.AddEvent(
NetLog::TYPE_DNS_TRANSACTION_RESPONSE,
make_scoped_refptr(
@@ -467,55 +482,75 @@ class DnsTransactionImpl : public DnsTransaction,
attempt->response()->answer_count(),
attempt->socket()->NetLog().source())));
}
+ }
+
+ bool MoreAttemptsAllowed() const {
+ const DnsConfig& config = session_->config();
+ return attempts_.size() < config.attempts * config.nameservers.size();
+ }
- net_log_.EndEventWithNetErrorCode(NetLog::TYPE_DNS_TRANSACTION_QUERY, rv);
-
- switch (rv) {
- case ERR_NAME_NOT_RESOLVED:
- // Try next suffix.
- qnames_.pop_front();
- if (qnames_.empty())
- rv = ERR_NAME_NOT_RESOLVED;
- else
- rv = StartQuery();
- break;
- case OK:
- DoCallback(rv, attempt->response());
- return;
- default:
- // Some nameservers could fail so try the next one.
- const DnsConfig& config = session_->config();
- if (attempts_.size() < config.attempts * config.nameservers.size()) {
- rv = MakeAttempt();
- } else {
- // TODO(szym): Should this be different than the timeout case?
- rv = ERR_DNS_SERVER_FAILED;
- }
- break;
+ // Resolves the result of a DnsUDPAttempt until a terminal result is reached
+ // or it will complete asynchronously (ERR_IO_PENDING).
+ AttemptResult FinishAttempt(AttemptResult result) {
+ while (result.rv != ERR_IO_PENDING) {
+ LogResponse(result.attempt);
+
+ switch (result.rv) {
+ case OK:
+ net_log_.EndEventWithNetErrorCode(
+ NetLog::TYPE_DNS_TRANSACTION_QUERY, result.rv);
+ DCHECK(result.attempt);
+ DCHECK(result.attempt->response());
+ return result;
+ case ERR_NAME_NOT_RESOLVED:
+ net_log_.EndEventWithNetErrorCode(
+ NetLog::TYPE_DNS_TRANSACTION_QUERY, result.rv);
+ // Try next suffix.
+ qnames_.pop_front();
+ if (qnames_.empty()) {
+ return AttemptResult(ERR_NAME_NOT_RESOLVED, NULL);
+ } else {
+ result = StartQuery();
+ }
+ break;
+ case ERR_DNS_TIMED_OUT:
+ if (MoreAttemptsAllowed()) {
+ result = MakeAttempt();
+ } else {
+ return result;
+ }
+ break;
+ default:
+ // Server failure.
+ DCHECK(result.attempt);
+ if (result.attempt != attempts_->back()) {
+ // This attempt already timed out. Ignore it.
+ return AttemptResult(ERR_IO_PENDING, NULL);
+ }
+ if (MoreAttemptsAllowed()) {
+ result = MakeAttempt();
+ } else {
+ return AttemptResult(ERR_DNS_SERVER_FAILED, NULL);
+ }
+ break;
+ }
}
- // TODO(szym): The next step might be to make another attempt.
- // http://crbug.com/121717
- if (rv != ERR_IO_PENDING)
- DoCallback(rv, attempts_->back()->response());
+ return result;
}
void OnTimeout() {
- const DnsConfig& config = session_->config();
- if (attempts_.size() == config.attempts * config.nameservers.size()) {
- DoCallback(ERR_DNS_TIMED_OUT, NULL);
+ if (callback_.is_null())
return;
- }
- int rv = MakeAttempt();
- // TODO(szym): The next step might be to make another attempt.
- // http://crbug.com/121717
- if (rv != ERR_IO_PENDING)
- DoCallback(rv, attempts_->back()->response());
+ AttemptResult result = FinishAttempt(
+ AttemptResult(ERR_DNS_TIMED_OUT, NULL));
+ if (result.rv != ERR_IO_PENDING)
+ DoCallback(result);
}
scoped_refptr<DnsSession> session_;
std::string hostname_;
uint16 qtype_;
- // Set to null once the transaction completes.
+ // Cleared in DoCallback.
DnsTransactionFactory::CallbackType callback_;
BoundNetLog net_log_;
diff --git a/net/dns/dns_transaction_unittest.cc b/net/dns/dns_transaction_unittest.cc
index ab9cb69..33ac404 100644
--- a/net/dns/dns_transaction_unittest.cc
+++ b/net/dns/dns_transaction_unittest.cc
@@ -231,7 +231,8 @@ class DnsTransactionTest : public testing::Test {
uint16 qtype,
uint16 id,
const char* data,
- size_t data_length) {
+ size_t data_length,
+ IoMode mode) {
CHECK(socket_factory_.get());
DnsQuery* query = new DnsQuery(id, DomainFromDot(dotted_name), qtype);
queries_.push_back(query);
@@ -240,16 +241,24 @@ class DnsTransactionTest : public testing::Test {
DnsResponse* response = new DnsResponse(data, data_length, 0);
responses_.push_back(response);
- writes_.push_back(MockWrite(ASYNC,
+ writes_.push_back(MockWrite(mode,
query->io_buffer()->data(),
query->io_buffer()->size()));
- reads_.push_back(MockRead(ASYNC,
+ reads_.push_back(MockRead(mode,
response->io_buffer()->data(),
data_length));
transaction_ids_.push_back(id);
}
+ void AddAsyncResponse(const std::string& dotted_name,
+ uint16 qtype,
+ uint16 id,
+ const char* data,
+ size_t data_length) {
+ AddResponse(dotted_name, qtype, id, data, data_length, ASYNC);
+ }
+
// Add expected query of |dotted_name| and |qtype| and no response.
void AddTimeout(const char* dotted_name, uint16 qtype) {
CHECK(socket_factory_.get());
@@ -267,7 +276,7 @@ class DnsTransactionTest : public testing::Test {
// Add expected query of |dotted_name| and |qtype| and response with no answer
// and rcode set to |rcode|.
- void AddRcode(const char* dotted_name, uint16 qtype, int rcode) {
+ void AddRcode(const char* dotted_name, uint16 qtype, int rcode, IoMode mode) {
CHECK(socket_factory_.get());
CHECK_NE(dns_protocol::kRcodeNOERROR, rcode);
uint16 id = base::RandInt(0, kuint16max);
@@ -282,15 +291,19 @@ class DnsTransactionTest : public testing::Test {
header->flags |= base::HostToNet16(dns_protocol::kFlagResponse | rcode);
responses_.push_back(response);
- writes_.push_back(MockWrite(ASYNC,
+ writes_.push_back(MockWrite(mode,
query->io_buffer()->data(),
query->io_buffer()->size()));
- reads_.push_back(MockRead(ASYNC,
+ reads_.push_back(MockRead(mode,
response->io_buffer()->data(),
query->io_buffer()->size()));
transaction_ids_.push_back(id);
}
+ void AddAsyncRcode(const char* dotted_name, uint16 qtype, int rcode) {
+ AddRcode(dotted_name, qtype, rcode, ASYNC);
+ }
+
// Call after all Add* calls to prepare data for |socket_factory_|.
// This separation is necessary because the |reads_| and |writes_| vectors
// could reallocate their data during those calls.
@@ -366,41 +379,41 @@ class DnsTransactionTest : public testing::Test {
};
TEST_F(DnsTransactionTest, Lookup) {
- AddResponse(kT0HostName,
- kT0Qtype,
- 0 /* id */,
- reinterpret_cast<const char*>(kT0ResponseDatagram),
- arraysize(kT0ResponseDatagram));
+ AddAsyncResponse(kT0HostName,
+ kT0Qtype,
+ 0 /* id */,
+ reinterpret_cast<const char*>(kT0ResponseDatagram),
+ arraysize(kT0ResponseDatagram));
PrepareSockets();
TransactionHelper helper0(kT0HostName,
kT0Qtype,
- arraysize(kT0IpAddresses) + 1);
+ kT0RecordCount);
EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
}
// Concurrent lookup tests assume that DnsTransaction::Start immediately
// consumes a socket from ClientSocketFactory.
TEST_F(DnsTransactionTest, ConcurrentLookup) {
- AddResponse(kT0HostName,
- kT0Qtype,
- 0 /* id */,
- reinterpret_cast<const char*>(kT0ResponseDatagram),
- arraysize(kT0ResponseDatagram));
- AddResponse(kT1HostName,
- kT1Qtype,
- 1 /* id */,
- reinterpret_cast<const char*>(kT1ResponseDatagram),
- arraysize(kT1ResponseDatagram));
+ AddAsyncResponse(kT0HostName,
+ kT0Qtype,
+ 0 /* id */,
+ reinterpret_cast<const char*>(kT0ResponseDatagram),
+ arraysize(kT0ResponseDatagram));
+ AddAsyncResponse(kT1HostName,
+ kT1Qtype,
+ 1 /* id */,
+ reinterpret_cast<const char*>(kT1ResponseDatagram),
+ arraysize(kT1ResponseDatagram));
PrepareSockets();
TransactionHelper helper0(kT0HostName,
kT0Qtype,
- arraysize(kT0IpAddresses) + 1);
+ kT0RecordCount);
helper0.StartTransaction(transaction_factory_.get());
TransactionHelper helper1(kT1HostName,
kT1Qtype,
- arraysize(kT1IpAddresses) + 1);
+ kT1RecordCount);
helper1.StartTransaction(transaction_factory_.get());
MessageLoop::current()->RunAllPending();
@@ -410,25 +423,25 @@ TEST_F(DnsTransactionTest, ConcurrentLookup) {
}
TEST_F(DnsTransactionTest, CancelLookup) {
- AddResponse(kT0HostName,
- kT0Qtype,
- 0 /* id */,
- reinterpret_cast<const char*>(kT0ResponseDatagram),
- arraysize(kT0ResponseDatagram));
- AddResponse(kT1HostName,
- kT1Qtype,
- 1 /* id */,
- reinterpret_cast<const char*>(kT1ResponseDatagram),
- arraysize(kT1ResponseDatagram));
+ AddAsyncResponse(kT0HostName,
+ kT0Qtype,
+ 0 /* id */,
+ reinterpret_cast<const char*>(kT0ResponseDatagram),
+ arraysize(kT0ResponseDatagram));
+ AddAsyncResponse(kT1HostName,
+ kT1Qtype,
+ 1 /* id */,
+ reinterpret_cast<const char*>(kT1ResponseDatagram),
+ arraysize(kT1ResponseDatagram));
PrepareSockets();
TransactionHelper helper0(kT0HostName,
kT0Qtype,
- arraysize(kT0IpAddresses) + 1);
+ kT0RecordCount);
helper0.StartTransaction(transaction_factory_.get());
TransactionHelper helper1(kT1HostName,
kT1Qtype,
- arraysize(kT1IpAddresses) + 1);
+ kT1RecordCount);
helper1.StartTransaction(transaction_factory_.get());
helper0.Cancel();
@@ -440,16 +453,16 @@ TEST_F(DnsTransactionTest, CancelLookup) {
}
TEST_F(DnsTransactionTest, DestroyFactory) {
- AddResponse(kT0HostName,
- kT0Qtype,
- 0 /* id */,
- reinterpret_cast<const char*>(kT0ResponseDatagram),
- arraysize(kT0ResponseDatagram));
+ AddAsyncResponse(kT0HostName,
+ kT0Qtype,
+ 0 /* id */,
+ reinterpret_cast<const char*>(kT0ResponseDatagram),
+ arraysize(kT0ResponseDatagram));
PrepareSockets();
TransactionHelper helper0(kT0HostName,
kT0Qtype,
- arraysize(kT0IpAddresses) + 1);
+ kT0RecordCount);
helper0.StartTransaction(transaction_factory_.get());
// Destroying the client does not affect running requests.
@@ -461,22 +474,22 @@ TEST_F(DnsTransactionTest, DestroyFactory) {
}
TEST_F(DnsTransactionTest, CancelFromCallback) {
- AddResponse(kT0HostName,
- kT0Qtype,
- 0 /* id */,
- reinterpret_cast<const char*>(kT0ResponseDatagram),
- arraysize(kT0ResponseDatagram));
+ AddAsyncResponse(kT0HostName,
+ kT0Qtype,
+ 0 /* id */,
+ reinterpret_cast<const char*>(kT0ResponseDatagram),
+ arraysize(kT0ResponseDatagram));
PrepareSockets();
TransactionHelper helper0(kT0HostName,
kT0Qtype,
- arraysize(kT0IpAddresses) + 1);
+ kT0RecordCount);
helper0.set_cancel_in_callback();
EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
}
TEST_F(DnsTransactionTest, ServerFail) {
- AddRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeSERVFAIL);
+ AddAsyncRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeSERVFAIL);
PrepareSockets();
TransactionHelper helper0(kT0HostName,
@@ -486,7 +499,7 @@ TEST_F(DnsTransactionTest, ServerFail) {
}
TEST_F(DnsTransactionTest, NoDomain) {
- AddRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeNXDOMAIN);
+ AddAsyncRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeNXDOMAIN);
PrepareSockets();
TransactionHelper helper0(kT0HostName,
@@ -527,13 +540,13 @@ TEST_F(DnsTransactionTest, ServerFallbackAndRotate) {
// Responses for first request.
AddTimeout(kT0HostName, kT0Qtype);
- AddRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeSERVFAIL);
+ AddAsyncRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeSERVFAIL);
AddTimeout(kT0HostName, kT0Qtype);
- AddRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeSERVFAIL);
- AddRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeNXDOMAIN);
+ AddAsyncRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeSERVFAIL);
+ AddAsyncRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeNXDOMAIN);
// Responses for second request.
- AddRcode(kT1HostName, kT1Qtype, dns_protocol::kRcodeSERVFAIL);
- AddRcode(kT1HostName, kT1Qtype, dns_protocol::kRcodeNXDOMAIN);
+ AddAsyncRcode(kT1HostName, kT1Qtype, dns_protocol::kRcodeSERVFAIL);
+ AddAsyncRcode(kT1HostName, kT1Qtype, dns_protocol::kRcodeNXDOMAIN);
PrepareSockets();
TransactionHelper helper0(kT0HostName,
@@ -562,10 +575,10 @@ TEST_F(DnsTransactionTest, SuffixSearchAboveNdots) {
ConfigureNumServers(2);
ConfigureFactory();
- AddRcode("x.y.z", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
- AddRcode("x.y.z.a", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
- AddRcode("x.y.z.b", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
- AddRcode("x.y.z.c", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
+ AddAsyncRcode("x.y.z", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
+ AddAsyncRcode("x.y.z.a", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
+ AddAsyncRcode("x.y.z.b", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
+ AddAsyncRcode("x.y.z.c", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
PrepareSockets();
TransactionHelper helper0("x.y.z",
@@ -587,16 +600,16 @@ TEST_F(DnsTransactionTest, SuffixSearchBelowNdots) {
ConfigureFactory();
// Responses for first transaction.
- AddRcode("x.y.a", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
- AddRcode("x.y.b", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
- AddRcode("x.y.c", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
- AddRcode("x.y", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
+ AddAsyncRcode("x.y.a", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
+ AddAsyncRcode("x.y.b", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
+ AddAsyncRcode("x.y.c", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
+ AddAsyncRcode("x.y", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
// Responses for second transaction.
- AddRcode("x.a", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
- AddRcode("x.b", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
- AddRcode("x.c", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
+ AddAsyncRcode("x.a", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
+ AddAsyncRcode("x.b", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
+ AddAsyncRcode("x.c", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
// Responses for third transaction.
- AddRcode("x", dns_protocol::kTypeAAAA, dns_protocol::kRcodeNXDOMAIN);
+ AddAsyncRcode("x", dns_protocol::kTypeAAAA, dns_protocol::kRcodeNXDOMAIN);
PrepareSockets();
TransactionHelper helper0("x.y",
@@ -621,10 +634,8 @@ TEST_F(DnsTransactionTest, SuffixSearchBelowNdots) {
}
TEST_F(DnsTransactionTest, EmptySuffixSearch) {
- ConfigureFactory();
-
// Responses for first transaction.
- AddRcode("x", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
+ AddAsyncRcode("x", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
PrepareSockets();
// A fully-qualified name.
@@ -651,13 +662,13 @@ TEST_F(DnsTransactionTest, DontAppendToMultiLabelName) {
ConfigureFactory();
// Responses for first transaction.
- AddRcode("x.y.z", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
+ AddAsyncRcode("x.y.z", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
// Responses for second transaction.
- AddRcode("x.y", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
+ AddAsyncRcode("x.y", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
// Responses for third transaction.
- AddRcode("x.a", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
- AddRcode("x.b", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
- AddRcode("x.c", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
+ AddAsyncRcode("x.a", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
+ AddAsyncRcode("x.b", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
+ AddAsyncRcode("x.c", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
PrepareSockets();
TransactionHelper helper0("x.y.z",
@@ -698,13 +709,13 @@ TEST_F(DnsTransactionTest, SuffixSearchStop) {
config_.search.push_back("c");
ConfigureFactory();
- AddRcode("x.y.z", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
- AddRcode("x.y.z.a", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
- AddResponse("x.y.z.b",
- dns_protocol::kTypeA,
- 0 /* id */,
- reinterpret_cast<const char*>(kResponseNoData),
- arraysize(kResponseNoData));
+ AddAsyncRcode("x.y.z", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
+ AddAsyncRcode("x.y.z.a", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN);
+ AddAsyncResponse("x.y.z.b",
+ dns_protocol::kTypeA,
+ 0 /* id */,
+ reinterpret_cast<const char*>(kResponseNoData),
+ arraysize(kResponseNoData));
PrepareSockets();
TransactionHelper helper0("x.y.z", dns_protocol::kTypeA, 0 /* answers */);
@@ -712,6 +723,71 @@ TEST_F(DnsTransactionTest, SuffixSearchStop) {
EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
}
+TEST_F(DnsTransactionTest, SyncFirstQuery) {
+ config_.search.push_back("lab.ccs.neu.edu");
+ config_.search.push_back("ccs.neu.edu");
+ ConfigureFactory();
+
+ AddResponse(kT0HostName,
+ kT0Qtype,
+ 0 /* id */,
+ reinterpret_cast<const char*>(kT0ResponseDatagram),
+ arraysize(kT0ResponseDatagram),
+ SYNCHRONOUS);
+ PrepareSockets();
+
+ TransactionHelper helper0(kT0HostName,
+ kT0Qtype,
+ kT0RecordCount);
+ EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
+}
+
+TEST_F(DnsTransactionTest, SyncFirstQueryWithSearch) {
+ config_.search.push_back("lab.ccs.neu.edu");
+ config_.search.push_back("ccs.neu.edu");
+ ConfigureFactory();
+
+ AddRcode("www.lab.ccs.neu.edu",
+ kT2Qtype,
+ dns_protocol::kRcodeNXDOMAIN,
+ SYNCHRONOUS);
+ AddResponse(kT2HostName, // "www.ccs.neu.edu"
+ kT2Qtype,
+ 2 /* id */,
+ reinterpret_cast<const char*>(kT2ResponseDatagram),
+ arraysize(kT2ResponseDatagram),
+ ASYNC);
+ PrepareSockets();
+
+ TransactionHelper helper0("www",
+ kT2Qtype,
+ kT2RecordCount);
+ EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
+}
+
+TEST_F(DnsTransactionTest, SyncSearchQuery) {
+ config_.search.push_back("lab.ccs.neu.edu");
+ config_.search.push_back("ccs.neu.edu");
+ ConfigureFactory();
+
+ AddRcode("www.lab.ccs.neu.edu",
+ dns_protocol::kTypeA,
+ dns_protocol::kRcodeNXDOMAIN,
+ ASYNC);
+ AddResponse(kT2HostName,
+ kT2Qtype,
+ 2 /* id */,
+ reinterpret_cast<const char*>(kT2ResponseDatagram),
+ arraysize(kT2ResponseDatagram),
+ SYNCHRONOUS);
+ PrepareSockets();
+
+ TransactionHelper helper0("www",
+ kT2Qtype,
+ kT2RecordCount);
+ EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
+}
+
} // namespace
} // namespace net