diff options
author | szym@chromium.org <szym@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-07 10:09:54 +0000 |
---|---|---|
committer | szym@chromium.org <szym@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-07 10:09:54 +0000 |
commit | 9d22312b9a3fb1a7040687aa65102ea21fca8ca5 (patch) | |
tree | 5e5887f3408294dd6a46abf888339ae6fc4f3e3c | |
parent | 99fd314f33f3843d2ef523f71aabdda830cef30b (diff) | |
download | chromium_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.h | 8 | ||||
-rw-r--r-- | net/dns/dns_transaction.cc | 177 | ||||
-rw-r--r-- | net/dns/dns_transaction_unittest.cc | 240 |
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 |