| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/dns/dns_transaction.h" | 5 #include "net/dns/dns_transaction.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/memory/scoped_vector.h" | 9 #include "base/memory/scoped_vector.h" |
| 10 #include "base/rand_util.h" | 10 #include "base/rand_util.h" |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 DnsSocketData(uint16 id, | 37 DnsSocketData(uint16 id, |
| 38 const char* dotted_name, | 38 const char* dotted_name, |
| 39 uint16 qtype, | 39 uint16 qtype, |
| 40 IoMode mode, | 40 IoMode mode, |
| 41 bool use_tcp) | 41 bool use_tcp) |
| 42 : query_(new DnsQuery(id, DomainFromDot(dotted_name), qtype)), | 42 : query_(new DnsQuery(id, DomainFromDot(dotted_name), qtype)), |
| 43 use_tcp_(use_tcp) { | 43 use_tcp_(use_tcp) { |
| 44 if (use_tcp_) { | 44 if (use_tcp_) { |
| 45 scoped_ptr<uint16> length(new uint16); | 45 scoped_ptr<uint16> length(new uint16); |
| 46 *length = base::HostToNet16(query_->io_buffer()->size()); | 46 *length = base::HostToNet16(query_->io_buffer()->size()); |
| 47 writes_.push_back(MockWrite(mode, | 47 writes_.push_back(MockWrite( |
| 48 reinterpret_cast<const char*>(length.get()), | 48 mode, reinterpret_cast<const char*>(length.get()), sizeof(uint16))); |
| 49 sizeof(uint16))); | |
| 50 lengths_.push_back(length.release()); | 49 lengths_.push_back(length.release()); |
| 51 } | 50 } |
| 52 writes_.push_back(MockWrite(mode, | 51 writes_.push_back(MockWrite( |
| 53 query_->io_buffer()->data(), | 52 mode, query_->io_buffer()->data(), query_->io_buffer()->size())); |
| 54 query_->io_buffer()->size())); | |
| 55 } | 53 } |
| 56 ~DnsSocketData() {} | 54 ~DnsSocketData() {} |
| 57 | 55 |
| 58 // All responses must be added before GetProvider. | 56 // All responses must be added before GetProvider. |
| 59 | 57 |
| 60 // Adds pre-built DnsResponse. |tcp_length| will be used in TCP mode only. | 58 // Adds pre-built DnsResponse. |tcp_length| will be used in TCP mode only. |
| 61 void AddResponseWithLength(scoped_ptr<DnsResponse> response, IoMode mode, | 59 void AddResponseWithLength(scoped_ptr<DnsResponse> response, |
| 60 IoMode mode, |
| 62 uint16 tcp_length) { | 61 uint16 tcp_length) { |
| 63 CHECK(!provider_.get()); | 62 CHECK(!provider_.get()); |
| 64 if (use_tcp_) { | 63 if (use_tcp_) { |
| 65 scoped_ptr<uint16> length(new uint16); | 64 scoped_ptr<uint16> length(new uint16); |
| 66 *length = base::HostToNet16(tcp_length); | 65 *length = base::HostToNet16(tcp_length); |
| 67 reads_.push_back(MockRead(mode, | 66 reads_.push_back(MockRead( |
| 68 reinterpret_cast<const char*>(length.get()), | 67 mode, reinterpret_cast<const char*>(length.get()), sizeof(uint16))); |
| 69 sizeof(uint16))); | |
| 70 lengths_.push_back(length.release()); | 68 lengths_.push_back(length.release()); |
| 71 } | 69 } |
| 72 reads_.push_back(MockRead(mode, | 70 reads_.push_back(MockRead( |
| 73 response->io_buffer()->data(), | 71 mode, response->io_buffer()->data(), response->io_buffer()->size())); |
| 74 response->io_buffer()->size())); | |
| 75 responses_.push_back(response.release()); | 72 responses_.push_back(response.release()); |
| 76 } | 73 } |
| 77 | 74 |
| 78 // Adds pre-built DnsResponse. | 75 // Adds pre-built DnsResponse. |
| 79 void AddResponse(scoped_ptr<DnsResponse> response, IoMode mode) { | 76 void AddResponse(scoped_ptr<DnsResponse> response, IoMode mode) { |
| 80 uint16 tcp_length = response->io_buffer()->size(); | 77 uint16 tcp_length = response->io_buffer()->size(); |
| 81 AddResponseWithLength(response.Pass(), mode, tcp_length); | 78 AddResponseWithLength(response.Pass(), mode, tcp_length); |
| 82 } | 79 } |
| 83 | 80 |
| 84 // Adds pre-built response from |data| buffer. | 81 // Adds pre-built response from |data| buffer. |
| 85 void AddResponseData(const uint8* data, size_t length, IoMode mode) { | 82 void AddResponseData(const uint8* data, size_t length, IoMode mode) { |
| 86 CHECK(!provider_.get()); | 83 CHECK(!provider_.get()); |
| 87 AddResponse(make_scoped_ptr( | 84 AddResponse(make_scoped_ptr(new DnsResponse( |
| 88 new DnsResponse(reinterpret_cast<const char*>(data), length, 0)), mode); | 85 reinterpret_cast<const char*>(data), length, 0)), |
| 86 mode); |
| 89 } | 87 } |
| 90 | 88 |
| 91 // Add no-answer (RCODE only) response matching the query. | 89 // Add no-answer (RCODE only) response matching the query. |
| 92 void AddRcode(int rcode, IoMode mode) { | 90 void AddRcode(int rcode, IoMode mode) { |
| 93 scoped_ptr<DnsResponse> response( | 91 scoped_ptr<DnsResponse> response(new DnsResponse( |
| 94 new DnsResponse(query_->io_buffer()->data(), | 92 query_->io_buffer()->data(), query_->io_buffer()->size(), 0)); |
| 95 query_->io_buffer()->size(), | |
| 96 0)); | |
| 97 dns_protocol::Header* header = | 93 dns_protocol::Header* header = |
| 98 reinterpret_cast<dns_protocol::Header*>(response->io_buffer()->data()); | 94 reinterpret_cast<dns_protocol::Header*>(response->io_buffer()->data()); |
| 99 header->flags |= base::HostToNet16(dns_protocol::kFlagResponse | rcode); | 95 header->flags |= base::HostToNet16(dns_protocol::kFlagResponse | rcode); |
| 100 AddResponse(response.Pass(), mode); | 96 AddResponse(response.Pass(), mode); |
| 101 } | 97 } |
| 102 | 98 |
| 103 // Build, if needed, and return the SocketDataProvider. No new responses | 99 // Build, if needed, and return the SocketDataProvider. No new responses |
| 104 // should be added afterwards. | 100 // should be added afterwards. |
| 105 SocketDataProvider* GetProvider() { | 101 SocketDataProvider* GetProvider() { |
| 106 if (provider_.get()) | 102 if (provider_.get()) |
| 107 return provider_.get(); | 103 return provider_.get(); |
| 108 // Terminate the reads with ERR_IO_PENDING to prevent overrun and default to | 104 // Terminate the reads with ERR_IO_PENDING to prevent overrun and default to |
| 109 // timeout. | 105 // timeout. |
| 110 reads_.push_back(MockRead(ASYNC, ERR_IO_PENDING)); | 106 reads_.push_back(MockRead(ASYNC, ERR_IO_PENDING)); |
| 111 provider_.reset(new DelayedSocketData(1, &reads_[0], reads_.size(), | 107 provider_.reset(new DelayedSocketData( |
| 112 &writes_[0], writes_.size())); | 108 1, &reads_[0], reads_.size(), &writes_[0], writes_.size())); |
| 113 if (use_tcp_) { | 109 if (use_tcp_) { |
| 114 provider_->set_connect_data(MockConnect(reads_[0].mode, OK)); | 110 provider_->set_connect_data(MockConnect(reads_[0].mode, OK)); |
| 115 } | 111 } |
| 116 return provider_.get(); | 112 return provider_.get(); |
| 117 } | 113 } |
| 118 | 114 |
| 119 uint16 query_id() const { | 115 uint16 query_id() const { return query_->id(); } |
| 120 return query_->id(); | |
| 121 } | |
| 122 | 116 |
| 123 // Returns true if the expected query was written to the socket. | 117 // Returns true if the expected query was written to the socket. |
| 124 bool was_written() const { | 118 bool was_written() const { |
| 125 CHECK(provider_.get()); | 119 CHECK(provider_.get()); |
| 126 return provider_->write_index() > 0; | 120 return provider_->write_index() > 0; |
| 127 } | 121 } |
| 128 | 122 |
| 129 private: | 123 private: |
| 130 scoped_ptr<DnsQuery> query_; | 124 scoped_ptr<DnsQuery> query_; |
| 131 bool use_tcp_; | 125 bool use_tcp_; |
| 132 ScopedVector<uint16> lengths_; | 126 ScopedVector<uint16> lengths_; |
| 133 ScopedVector<DnsResponse> responses_; | 127 ScopedVector<DnsResponse> responses_; |
| 134 std::vector<MockWrite> writes_; | 128 std::vector<MockWrite> writes_; |
| 135 std::vector<MockRead> reads_; | 129 std::vector<MockRead> reads_; |
| 136 scoped_ptr<DelayedSocketData> provider_; | 130 scoped_ptr<DelayedSocketData> provider_; |
| 137 | 131 |
| 138 DISALLOW_COPY_AND_ASSIGN(DnsSocketData); | 132 DISALLOW_COPY_AND_ASSIGN(DnsSocketData); |
| 139 }; | 133 }; |
| 140 | 134 |
| 141 class TestSocketFactory; | 135 class TestSocketFactory; |
| 142 | 136 |
| 143 // A variant of MockUDPClientSocket which always fails to Connect. | 137 // A variant of MockUDPClientSocket which always fails to Connect. |
| 144 class FailingUDPClientSocket : public MockUDPClientSocket { | 138 class FailingUDPClientSocket : public MockUDPClientSocket { |
| 145 public: | 139 public: |
| 146 FailingUDPClientSocket(SocketDataProvider* data, | 140 FailingUDPClientSocket(SocketDataProvider* data, net::NetLog* net_log) |
| 147 net::NetLog* net_log) | 141 : MockUDPClientSocket(data, net_log) {} |
| 148 : MockUDPClientSocket(data, net_log) { | |
| 149 } | |
| 150 virtual ~FailingUDPClientSocket() {} | 142 virtual ~FailingUDPClientSocket() {} |
| 151 virtual int Connect(const IPEndPoint& endpoint) OVERRIDE { | 143 virtual int Connect(const IPEndPoint& endpoint) OVERRIDE { |
| 152 return ERR_CONNECTION_REFUSED; | 144 return ERR_CONNECTION_REFUSED; |
| 153 } | 145 } |
| 154 | 146 |
| 155 private: | 147 private: |
| 156 DISALLOW_COPY_AND_ASSIGN(FailingUDPClientSocket); | 148 DISALLOW_COPY_AND_ASSIGN(FailingUDPClientSocket); |
| 157 }; | 149 }; |
| 158 | 150 |
| 159 // A variant of MockUDPClientSocket which notifies the factory OnConnect. | 151 // A variant of MockUDPClientSocket which notifies the factory OnConnect. |
| 160 class TestUDPClientSocket : public MockUDPClientSocket { | 152 class TestUDPClientSocket : public MockUDPClientSocket { |
| 161 public: | 153 public: |
| 162 TestUDPClientSocket(TestSocketFactory* factory, | 154 TestUDPClientSocket(TestSocketFactory* factory, |
| 163 SocketDataProvider* data, | 155 SocketDataProvider* data, |
| 164 net::NetLog* net_log) | 156 net::NetLog* net_log) |
| 165 : MockUDPClientSocket(data, net_log), factory_(factory) { | 157 : MockUDPClientSocket(data, net_log), factory_(factory) {} |
| 166 } | |
| 167 virtual ~TestUDPClientSocket() {} | 158 virtual ~TestUDPClientSocket() {} |
| 168 virtual int Connect(const IPEndPoint& endpoint) OVERRIDE; | 159 virtual int Connect(const IPEndPoint& endpoint) OVERRIDE; |
| 169 | 160 |
| 170 private: | 161 private: |
| 171 TestSocketFactory* factory_; | 162 TestSocketFactory* factory_; |
| 172 | 163 |
| 173 DISALLOW_COPY_AND_ASSIGN(TestUDPClientSocket); | 164 DISALLOW_COPY_AND_ASSIGN(TestUDPClientSocket); |
| 174 }; | 165 }; |
| 175 | 166 |
| 176 // Creates TestUDPClientSockets and keeps endpoints reported via OnConnect. | 167 // Creates TestUDPClientSockets and keeps endpoints reported via OnConnect. |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 public: | 210 public: |
| 220 // If |expected_answer_count| < 0 then it is the expected net error. | 211 // If |expected_answer_count| < 0 then it is the expected net error. |
| 221 TransactionHelper(const char* hostname, | 212 TransactionHelper(const char* hostname, |
| 222 uint16 qtype, | 213 uint16 qtype, |
| 223 int expected_answer_count) | 214 int expected_answer_count) |
| 224 : hostname_(hostname), | 215 : hostname_(hostname), |
| 225 qtype_(qtype), | 216 qtype_(qtype), |
| 226 expected_answer_count_(expected_answer_count), | 217 expected_answer_count_(expected_answer_count), |
| 227 cancel_in_callback_(false), | 218 cancel_in_callback_(false), |
| 228 quit_in_callback_(false), | 219 quit_in_callback_(false), |
| 229 completed_(false) { | 220 completed_(false) {} |
| 230 } | |
| 231 | 221 |
| 232 // Mark that the transaction shall be destroyed immediately upon callback. | 222 // Mark that the transaction shall be destroyed immediately upon callback. |
| 233 void set_cancel_in_callback() { | 223 void set_cancel_in_callback() { cancel_in_callback_ = true; } |
| 234 cancel_in_callback_ = true; | |
| 235 } | |
| 236 | 224 |
| 237 // Mark to call MessageLoop::Quit() upon callback. | 225 // Mark to call MessageLoop::Quit() upon callback. |
| 238 void set_quit_in_callback() { | 226 void set_quit_in_callback() { quit_in_callback_ = true; } |
| 239 quit_in_callback_ = true; | |
| 240 } | |
| 241 | 227 |
| 242 void StartTransaction(DnsTransactionFactory* factory) { | 228 void StartTransaction(DnsTransactionFactory* factory) { |
| 243 EXPECT_EQ(NULL, transaction_.get()); | 229 EXPECT_EQ(NULL, transaction_.get()); |
| 244 transaction_ = factory->CreateTransaction( | 230 transaction_ = factory->CreateTransaction( |
| 245 hostname_, | 231 hostname_, |
| 246 qtype_, | 232 qtype_, |
| 247 base::Bind(&TransactionHelper::OnTransactionComplete, | 233 base::Bind(&TransactionHelper::OnTransactionComplete, |
| 248 base::Unretained(this)), | 234 base::Unretained(this)), |
| 249 BoundNetLog()); | 235 BoundNetLog()); |
| 250 EXPECT_EQ(hostname_, transaction_->GetHostname()); | 236 EXPECT_EQ(hostname_, transaction_->GetHostname()); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 DnsRecordParser parser = response->Parser(); | 270 DnsRecordParser parser = response->Parser(); |
| 285 DnsResourceRecord record; | 271 DnsResourceRecord record; |
| 286 for (int i = 0; i < expected_answer_count_; ++i) { | 272 for (int i = 0; i < expected_answer_count_; ++i) { |
| 287 EXPECT_TRUE(parser.ReadRecord(&record)); | 273 EXPECT_TRUE(parser.ReadRecord(&record)); |
| 288 } | 274 } |
| 289 } else { | 275 } else { |
| 290 EXPECT_EQ(expected_answer_count_, rv); | 276 EXPECT_EQ(expected_answer_count_, rv); |
| 291 } | 277 } |
| 292 } | 278 } |
| 293 | 279 |
| 294 bool has_completed() const { | 280 bool has_completed() const { return completed_; } |
| 295 return completed_; | |
| 296 } | |
| 297 | 281 |
| 298 // Shorthands for commonly used commands. | 282 // Shorthands for commonly used commands. |
| 299 | 283 |
| 300 bool Run(DnsTransactionFactory* factory) { | 284 bool Run(DnsTransactionFactory* factory) { |
| 301 StartTransaction(factory); | 285 StartTransaction(factory); |
| 302 base::MessageLoop::current()->RunUntilIdle(); | 286 base::MessageLoop::current()->RunUntilIdle(); |
| 303 return has_completed(); | 287 return has_completed(); |
| 304 } | 288 } |
| 305 | 289 |
| 306 // Use when some of the responses are timeouts. | 290 // Use when some of the responses are timeouts. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 330 void ConfigureNumServers(unsigned num_servers) { | 314 void ConfigureNumServers(unsigned num_servers) { |
| 331 CHECK_LE(num_servers, 255u); | 315 CHECK_LE(num_servers, 255u); |
| 332 config_.nameservers.clear(); | 316 config_.nameservers.clear(); |
| 333 IPAddressNumber dns_ip; | 317 IPAddressNumber dns_ip; |
| 334 { | 318 { |
| 335 bool rv = ParseIPLiteralToNumber("192.168.1.0", &dns_ip); | 319 bool rv = ParseIPLiteralToNumber("192.168.1.0", &dns_ip); |
| 336 EXPECT_TRUE(rv); | 320 EXPECT_TRUE(rv); |
| 337 } | 321 } |
| 338 for (unsigned i = 0; i < num_servers; ++i) { | 322 for (unsigned i = 0; i < num_servers; ++i) { |
| 339 dns_ip[3] = i; | 323 dns_ip[3] = i; |
| 340 config_.nameservers.push_back(IPEndPoint(dns_ip, | 324 config_.nameservers.push_back( |
| 341 dns_protocol::kDefaultPort)); | 325 IPEndPoint(dns_ip, dns_protocol::kDefaultPort)); |
| 342 } | 326 } |
| 343 } | 327 } |
| 344 | 328 |
| 345 // Called after fully configuring |config|. | 329 // Called after fully configuring |config|. |
| 346 void ConfigureFactory() { | 330 void ConfigureFactory() { |
| 347 socket_factory_.reset(new TestSocketFactory()); | 331 socket_factory_.reset(new TestSocketFactory()); |
| 348 session_ = new DnsSession( | 332 session_ = new DnsSession( |
| 349 config_, | 333 config_, |
| 350 DnsSocketPool::CreateNull(socket_factory_.get()), | 334 DnsSocketPool::CreateNull(socket_factory_.get()), |
| 351 base::Bind(&DnsTransactionTest::GetNextId, base::Unretained(this)), | 335 base::Bind(&DnsTransactionTest::GetNextId, base::Unretained(this)), |
| (...skipping 23 matching lines...) Expand all Loading... |
| 375 new DnsSocketData(id, dotted_name, qtype, mode, use_tcp)); | 359 new DnsSocketData(id, dotted_name, qtype, mode, use_tcp)); |
| 376 data->AddResponseData(response_data, response_length, mode); | 360 data->AddResponseData(response_data, response_length, mode); |
| 377 AddSocketData(data.Pass()); | 361 AddSocketData(data.Pass()); |
| 378 } | 362 } |
| 379 | 363 |
| 380 void AddAsyncQueryAndResponse(uint16 id, | 364 void AddAsyncQueryAndResponse(uint16 id, |
| 381 const char* dotted_name, | 365 const char* dotted_name, |
| 382 uint16 qtype, | 366 uint16 qtype, |
| 383 const uint8* data, | 367 const uint8* data, |
| 384 size_t data_length) { | 368 size_t data_length) { |
| 385 AddQueryAndResponse(id, dotted_name, qtype, data, data_length, ASYNC, | 369 AddQueryAndResponse( |
| 386 false); | 370 id, dotted_name, qtype, data, data_length, ASYNC, false); |
| 387 } | 371 } |
| 388 | 372 |
| 389 void AddSyncQueryAndResponse(uint16 id, | 373 void AddSyncQueryAndResponse(uint16 id, |
| 390 const char* dotted_name, | 374 const char* dotted_name, |
| 391 uint16 qtype, | 375 uint16 qtype, |
| 392 const uint8* data, | 376 const uint8* data, |
| 393 size_t data_length) { | 377 size_t data_length) { |
| 394 AddQueryAndResponse(id, dotted_name, qtype, data, data_length, SYNCHRONOUS, | 378 AddQueryAndResponse( |
| 395 false); | 379 id, dotted_name, qtype, data, data_length, SYNCHRONOUS, false); |
| 396 } | 380 } |
| 397 | 381 |
| 398 // Add expected query of |dotted_name| and |qtype| and no response. | 382 // Add expected query of |dotted_name| and |qtype| and no response. |
| 399 void AddQueryAndTimeout(const char* dotted_name, uint16 qtype) { | 383 void AddQueryAndTimeout(const char* dotted_name, uint16 qtype) { |
| 400 uint16 id = base::RandInt(0, kuint16max); | 384 uint16 id = base::RandInt(0, kuint16max); |
| 401 scoped_ptr<DnsSocketData> data( | 385 scoped_ptr<DnsSocketData> data( |
| 402 new DnsSocketData(id, dotted_name, qtype, ASYNC, false)); | 386 new DnsSocketData(id, dotted_name, qtype, ASYNC, false)); |
| 403 AddSocketData(data.Pass()); | 387 AddSocketData(data.Pass()); |
| 404 } | 388 } |
| 405 | 389 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 | 451 |
| 468 ScopedVector<DnsSocketData> socket_data_; | 452 ScopedVector<DnsSocketData> socket_data_; |
| 469 | 453 |
| 470 std::deque<int> transaction_ids_; | 454 std::deque<int> transaction_ids_; |
| 471 scoped_ptr<TestSocketFactory> socket_factory_; | 455 scoped_ptr<TestSocketFactory> socket_factory_; |
| 472 scoped_refptr<DnsSession> session_; | 456 scoped_refptr<DnsSession> session_; |
| 473 scoped_ptr<DnsTransactionFactory> transaction_factory_; | 457 scoped_ptr<DnsTransactionFactory> transaction_factory_; |
| 474 }; | 458 }; |
| 475 | 459 |
| 476 TEST_F(DnsTransactionTest, Lookup) { | 460 TEST_F(DnsTransactionTest, Lookup) { |
| 477 AddAsyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype, | 461 AddAsyncQueryAndResponse(0 /* id */, |
| 478 kT0ResponseDatagram, arraysize(kT0ResponseDatagram)); | 462 kT0HostName, |
| 463 kT0Qtype, |
| 464 kT0ResponseDatagram, |
| 465 arraysize(kT0ResponseDatagram)); |
| 479 | 466 |
| 480 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); | 467 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); |
| 481 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); | 468 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); |
| 482 } | 469 } |
| 483 | 470 |
| 484 // Concurrent lookup tests assume that DnsTransaction::Start immediately | 471 // Concurrent lookup tests assume that DnsTransaction::Start immediately |
| 485 // consumes a socket from ClientSocketFactory. | 472 // consumes a socket from ClientSocketFactory. |
| 486 TEST_F(DnsTransactionTest, ConcurrentLookup) { | 473 TEST_F(DnsTransactionTest, ConcurrentLookup) { |
| 487 AddAsyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype, | 474 AddAsyncQueryAndResponse(0 /* id */, |
| 488 kT0ResponseDatagram, arraysize(kT0ResponseDatagram)); | 475 kT0HostName, |
| 489 AddAsyncQueryAndResponse(1 /* id */, kT1HostName, kT1Qtype, | 476 kT0Qtype, |
| 490 kT1ResponseDatagram, arraysize(kT1ResponseDatagram)); | 477 kT0ResponseDatagram, |
| 478 arraysize(kT0ResponseDatagram)); |
| 479 AddAsyncQueryAndResponse(1 /* id */, |
| 480 kT1HostName, |
| 481 kT1Qtype, |
| 482 kT1ResponseDatagram, |
| 483 arraysize(kT1ResponseDatagram)); |
| 491 | 484 |
| 492 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); | 485 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); |
| 493 helper0.StartTransaction(transaction_factory_.get()); | 486 helper0.StartTransaction(transaction_factory_.get()); |
| 494 TransactionHelper helper1(kT1HostName, kT1Qtype, kT1RecordCount); | 487 TransactionHelper helper1(kT1HostName, kT1Qtype, kT1RecordCount); |
| 495 helper1.StartTransaction(transaction_factory_.get()); | 488 helper1.StartTransaction(transaction_factory_.get()); |
| 496 | 489 |
| 497 base::MessageLoop::current()->RunUntilIdle(); | 490 base::MessageLoop::current()->RunUntilIdle(); |
| 498 | 491 |
| 499 EXPECT_TRUE(helper0.has_completed()); | 492 EXPECT_TRUE(helper0.has_completed()); |
| 500 EXPECT_TRUE(helper1.has_completed()); | 493 EXPECT_TRUE(helper1.has_completed()); |
| 501 } | 494 } |
| 502 | 495 |
| 503 TEST_F(DnsTransactionTest, CancelLookup) { | 496 TEST_F(DnsTransactionTest, CancelLookup) { |
| 504 AddAsyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype, | 497 AddAsyncQueryAndResponse(0 /* id */, |
| 505 kT0ResponseDatagram, arraysize(kT0ResponseDatagram)); | 498 kT0HostName, |
| 506 AddAsyncQueryAndResponse(1 /* id */, kT1HostName, kT1Qtype, | 499 kT0Qtype, |
| 507 kT1ResponseDatagram, arraysize(kT1ResponseDatagram)); | 500 kT0ResponseDatagram, |
| 501 arraysize(kT0ResponseDatagram)); |
| 502 AddAsyncQueryAndResponse(1 /* id */, |
| 503 kT1HostName, |
| 504 kT1Qtype, |
| 505 kT1ResponseDatagram, |
| 506 arraysize(kT1ResponseDatagram)); |
| 508 | 507 |
| 509 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); | 508 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); |
| 510 helper0.StartTransaction(transaction_factory_.get()); | 509 helper0.StartTransaction(transaction_factory_.get()); |
| 511 TransactionHelper helper1(kT1HostName, kT1Qtype, kT1RecordCount); | 510 TransactionHelper helper1(kT1HostName, kT1Qtype, kT1RecordCount); |
| 512 helper1.StartTransaction(transaction_factory_.get()); | 511 helper1.StartTransaction(transaction_factory_.get()); |
| 513 | 512 |
| 514 helper0.Cancel(); | 513 helper0.Cancel(); |
| 515 | 514 |
| 516 base::MessageLoop::current()->RunUntilIdle(); | 515 base::MessageLoop::current()->RunUntilIdle(); |
| 517 | 516 |
| 518 EXPECT_FALSE(helper0.has_completed()); | 517 EXPECT_FALSE(helper0.has_completed()); |
| 519 EXPECT_TRUE(helper1.has_completed()); | 518 EXPECT_TRUE(helper1.has_completed()); |
| 520 } | 519 } |
| 521 | 520 |
| 522 TEST_F(DnsTransactionTest, DestroyFactory) { | 521 TEST_F(DnsTransactionTest, DestroyFactory) { |
| 523 AddAsyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype, | 522 AddAsyncQueryAndResponse(0 /* id */, |
| 524 kT0ResponseDatagram, arraysize(kT0ResponseDatagram)); | 523 kT0HostName, |
| 524 kT0Qtype, |
| 525 kT0ResponseDatagram, |
| 526 arraysize(kT0ResponseDatagram)); |
| 525 | 527 |
| 526 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); | 528 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); |
| 527 helper0.StartTransaction(transaction_factory_.get()); | 529 helper0.StartTransaction(transaction_factory_.get()); |
| 528 | 530 |
| 529 // Destroying the client does not affect running requests. | 531 // Destroying the client does not affect running requests. |
| 530 transaction_factory_.reset(NULL); | 532 transaction_factory_.reset(NULL); |
| 531 | 533 |
| 532 base::MessageLoop::current()->RunUntilIdle(); | 534 base::MessageLoop::current()->RunUntilIdle(); |
| 533 | 535 |
| 534 EXPECT_TRUE(helper0.has_completed()); | 536 EXPECT_TRUE(helper0.has_completed()); |
| 535 } | 537 } |
| 536 | 538 |
| 537 TEST_F(DnsTransactionTest, CancelFromCallback) { | 539 TEST_F(DnsTransactionTest, CancelFromCallback) { |
| 538 AddAsyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype, | 540 AddAsyncQueryAndResponse(0 /* id */, |
| 539 kT0ResponseDatagram, arraysize(kT0ResponseDatagram)); | 541 kT0HostName, |
| 542 kT0Qtype, |
| 543 kT0ResponseDatagram, |
| 544 arraysize(kT0ResponseDatagram)); |
| 540 | 545 |
| 541 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); | 546 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); |
| 542 helper0.set_cancel_in_callback(); | 547 helper0.set_cancel_in_callback(); |
| 543 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); | 548 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); |
| 544 } | 549 } |
| 545 | 550 |
| 546 TEST_F(DnsTransactionTest, MismatchedResponseSync) { | 551 TEST_F(DnsTransactionTest, MismatchedResponseSync) { |
| 547 config_.attempts = 2; | 552 config_.attempts = 2; |
| 548 config_.timeout = TestTimeouts::tiny_timeout(); | 553 config_.timeout = TestTimeouts::tiny_timeout(); |
| 549 ConfigureFactory(); | 554 ConfigureFactory(); |
| 550 | 555 |
| 551 // Attempt receives mismatched response followed by valid response. | 556 // Attempt receives mismatched response followed by valid response. |
| 552 scoped_ptr<DnsSocketData> data( | 557 scoped_ptr<DnsSocketData> data( |
| 553 new DnsSocketData(0 /* id */, kT0HostName, kT0Qtype, SYNCHRONOUS, false)); | 558 new DnsSocketData(0 /* id */, kT0HostName, kT0Qtype, SYNCHRONOUS, false)); |
| 554 data->AddResponseData(kT1ResponseDatagram, | 559 data->AddResponseData( |
| 555 arraysize(kT1ResponseDatagram), SYNCHRONOUS); | 560 kT1ResponseDatagram, arraysize(kT1ResponseDatagram), SYNCHRONOUS); |
| 556 data->AddResponseData(kT0ResponseDatagram, | 561 data->AddResponseData( |
| 557 arraysize(kT0ResponseDatagram), SYNCHRONOUS); | 562 kT0ResponseDatagram, arraysize(kT0ResponseDatagram), SYNCHRONOUS); |
| 558 AddSocketData(data.Pass()); | 563 AddSocketData(data.Pass()); |
| 559 | 564 |
| 560 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); | 565 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); |
| 561 EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get())); | 566 EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get())); |
| 562 } | 567 } |
| 563 | 568 |
| 564 TEST_F(DnsTransactionTest, MismatchedResponseAsync) { | 569 TEST_F(DnsTransactionTest, MismatchedResponseAsync) { |
| 565 config_.attempts = 2; | 570 config_.attempts = 2; |
| 566 config_.timeout = TestTimeouts::tiny_timeout(); | 571 config_.timeout = TestTimeouts::tiny_timeout(); |
| 567 ConfigureFactory(); | 572 ConfigureFactory(); |
| 568 | 573 |
| 569 // First attempt receives mismatched response followed by valid response. | 574 // First attempt receives mismatched response followed by valid response. |
| 570 // Second attempt times out. | 575 // Second attempt times out. |
| 571 scoped_ptr<DnsSocketData> data( | 576 scoped_ptr<DnsSocketData> data( |
| 572 new DnsSocketData(0 /* id */, kT0HostName, kT0Qtype, ASYNC, false)); | 577 new DnsSocketData(0 /* id */, kT0HostName, kT0Qtype, ASYNC, false)); |
| 573 data->AddResponseData(kT1ResponseDatagram, | 578 data->AddResponseData( |
| 574 arraysize(kT1ResponseDatagram), ASYNC); | 579 kT1ResponseDatagram, arraysize(kT1ResponseDatagram), ASYNC); |
| 575 data->AddResponseData(kT0ResponseDatagram, | 580 data->AddResponseData( |
| 576 arraysize(kT0ResponseDatagram), ASYNC); | 581 kT0ResponseDatagram, arraysize(kT0ResponseDatagram), ASYNC); |
| 577 AddSocketData(data.Pass()); | 582 AddSocketData(data.Pass()); |
| 578 AddQueryAndTimeout(kT0HostName, kT0Qtype); | 583 AddQueryAndTimeout(kT0HostName, kT0Qtype); |
| 579 | 584 |
| 580 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); | 585 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); |
| 581 EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get())); | 586 EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get())); |
| 582 } | 587 } |
| 583 | 588 |
| 584 TEST_F(DnsTransactionTest, MismatchedResponseFail) { | 589 TEST_F(DnsTransactionTest, MismatchedResponseFail) { |
| 585 config_.timeout = TestTimeouts::tiny_timeout(); | 590 config_.timeout = TestTimeouts::tiny_timeout(); |
| 586 ConfigureFactory(); | 591 ConfigureFactory(); |
| 587 | 592 |
| 588 // Attempt receives mismatched response but times out because only one attempt | 593 // Attempt receives mismatched response but times out because only one attempt |
| 589 // is allowed. | 594 // is allowed. |
| 590 AddAsyncQueryAndResponse(1 /* id */, kT0HostName, kT0Qtype, | 595 AddAsyncQueryAndResponse(1 /* id */, |
| 591 kT0ResponseDatagram, arraysize(kT0ResponseDatagram)); | 596 kT0HostName, |
| 597 kT0Qtype, |
| 598 kT0ResponseDatagram, |
| 599 arraysize(kT0ResponseDatagram)); |
| 592 | 600 |
| 593 TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_DNS_TIMED_OUT); | 601 TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_DNS_TIMED_OUT); |
| 594 EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get())); | 602 EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get())); |
| 595 } | 603 } |
| 596 | 604 |
| 597 TEST_F(DnsTransactionTest, ServerFail) { | 605 TEST_F(DnsTransactionTest, ServerFail) { |
| 598 AddAsyncQueryAndRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeSERVFAIL); | 606 AddAsyncQueryAndRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeSERVFAIL); |
| 599 | 607 |
| 600 TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_DNS_SERVER_FAILED); | 608 TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_DNS_SERVER_FAILED); |
| 601 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); | 609 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 644 AddAsyncQueryAndRcode(kT1HostName, kT1Qtype, dns_protocol::kRcodeSERVFAIL); | 652 AddAsyncQueryAndRcode(kT1HostName, kT1Qtype, dns_protocol::kRcodeSERVFAIL); |
| 645 AddAsyncQueryAndRcode(kT1HostName, kT1Qtype, dns_protocol::kRcodeNXDOMAIN); | 653 AddAsyncQueryAndRcode(kT1HostName, kT1Qtype, dns_protocol::kRcodeNXDOMAIN); |
| 646 | 654 |
| 647 TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_NAME_NOT_RESOLVED); | 655 TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_NAME_NOT_RESOLVED); |
| 648 TransactionHelper helper1(kT1HostName, kT1Qtype, ERR_NAME_NOT_RESOLVED); | 656 TransactionHelper helper1(kT1HostName, kT1Qtype, ERR_NAME_NOT_RESOLVED); |
| 649 | 657 |
| 650 EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get())); | 658 EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get())); |
| 651 EXPECT_TRUE(helper1.Run(transaction_factory_.get())); | 659 EXPECT_TRUE(helper1.Run(transaction_factory_.get())); |
| 652 | 660 |
| 653 unsigned kOrder[] = { | 661 unsigned kOrder[] = { |
| 654 0, 1, 2, 0, 1, // The first transaction. | 662 0, 1, 2, 0, 1, // The first transaction. |
| 655 1, 2, 0, // The second transaction starts from the next server. | 663 1, 2, 0, // The second transaction starts from the next server. |
| 656 }; | 664 }; |
| 657 CheckServerOrder(kOrder, arraysize(kOrder)); | 665 CheckServerOrder(kOrder, arraysize(kOrder)); |
| 658 } | 666 } |
| 659 | 667 |
| 660 TEST_F(DnsTransactionTest, SuffixSearchAboveNdots) { | 668 TEST_F(DnsTransactionTest, SuffixSearchAboveNdots) { |
| 661 config_.ndots = 2; | 669 config_.ndots = 2; |
| 662 config_.search.push_back("a"); | 670 config_.search.push_back("a"); |
| 663 config_.search.push_back("b"); | 671 config_.search.push_back("b"); |
| 664 config_.search.push_back("c"); | 672 config_.search.push_back("c"); |
| 665 config_.rotate = true; | 673 config_.rotate = true; |
| 666 ConfigureNumServers(2); | 674 ConfigureNumServers(2); |
| 667 ConfigureFactory(); | 675 ConfigureFactory(); |
| 668 | 676 |
| 669 AddAsyncQueryAndRcode("x.y.z", dns_protocol::kTypeA, | 677 AddAsyncQueryAndRcode( |
| 670 dns_protocol::kRcodeNXDOMAIN); | 678 "x.y.z", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); |
| 671 AddAsyncQueryAndRcode("x.y.z.a", dns_protocol::kTypeA, | 679 AddAsyncQueryAndRcode( |
| 672 dns_protocol::kRcodeNXDOMAIN); | 680 "x.y.z.a", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); |
| 673 AddAsyncQueryAndRcode("x.y.z.b", dns_protocol::kTypeA, | 681 AddAsyncQueryAndRcode( |
| 674 dns_protocol::kRcodeNXDOMAIN); | 682 "x.y.z.b", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); |
| 675 AddAsyncQueryAndRcode("x.y.z.c", dns_protocol::kTypeA, | 683 AddAsyncQueryAndRcode( |
| 676 dns_protocol::kRcodeNXDOMAIN); | 684 "x.y.z.c", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); |
| 677 | 685 |
| 678 TransactionHelper helper0("x.y.z", dns_protocol::kTypeA, | 686 TransactionHelper helper0( |
| 679 ERR_NAME_NOT_RESOLVED); | 687 "x.y.z", dns_protocol::kTypeA, ERR_NAME_NOT_RESOLVED); |
| 680 | 688 |
| 681 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); | 689 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); |
| 682 | 690 |
| 683 // Also check if suffix search causes server rotation. | 691 // Also check if suffix search causes server rotation. |
| 684 unsigned kOrder0[] = { 0, 1, 0, 1 }; | 692 unsigned kOrder0[] = {0, 1, 0, 1}; |
| 685 CheckServerOrder(kOrder0, arraysize(kOrder0)); | 693 CheckServerOrder(kOrder0, arraysize(kOrder0)); |
| 686 } | 694 } |
| 687 | 695 |
| 688 TEST_F(DnsTransactionTest, SuffixSearchBelowNdots) { | 696 TEST_F(DnsTransactionTest, SuffixSearchBelowNdots) { |
| 689 config_.ndots = 2; | 697 config_.ndots = 2; |
| 690 config_.search.push_back("a"); | 698 config_.search.push_back("a"); |
| 691 config_.search.push_back("b"); | 699 config_.search.push_back("b"); |
| 692 config_.search.push_back("c"); | 700 config_.search.push_back("c"); |
| 693 ConfigureFactory(); | 701 ConfigureFactory(); |
| 694 | 702 |
| 695 // Responses for first transaction. | 703 // Responses for first transaction. |
| 696 AddAsyncQueryAndRcode("x.y.a", dns_protocol::kTypeA, | 704 AddAsyncQueryAndRcode( |
| 697 dns_protocol::kRcodeNXDOMAIN); | 705 "x.y.a", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); |
| 698 AddAsyncQueryAndRcode("x.y.b", dns_protocol::kTypeA, | 706 AddAsyncQueryAndRcode( |
| 699 dns_protocol::kRcodeNXDOMAIN); | 707 "x.y.b", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); |
| 700 AddAsyncQueryAndRcode("x.y.c", dns_protocol::kTypeA, | 708 AddAsyncQueryAndRcode( |
| 701 dns_protocol::kRcodeNXDOMAIN); | 709 "x.y.c", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); |
| 702 AddAsyncQueryAndRcode("x.y", dns_protocol::kTypeA, | 710 AddAsyncQueryAndRcode( |
| 703 dns_protocol::kRcodeNXDOMAIN); | 711 "x.y", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); |
| 704 // Responses for second transaction. | 712 // Responses for second transaction. |
| 705 AddAsyncQueryAndRcode("x.a", dns_protocol::kTypeA, | 713 AddAsyncQueryAndRcode( |
| 706 dns_protocol::kRcodeNXDOMAIN); | 714 "x.a", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); |
| 707 AddAsyncQueryAndRcode("x.b", dns_protocol::kTypeA, | 715 AddAsyncQueryAndRcode( |
| 708 dns_protocol::kRcodeNXDOMAIN); | 716 "x.b", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); |
| 709 AddAsyncQueryAndRcode("x.c", dns_protocol::kTypeA, | 717 AddAsyncQueryAndRcode( |
| 710 dns_protocol::kRcodeNXDOMAIN); | 718 "x.c", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); |
| 711 // Responses for third transaction. | 719 // Responses for third transaction. |
| 712 AddAsyncQueryAndRcode("x", dns_protocol::kTypeAAAA, | 720 AddAsyncQueryAndRcode( |
| 713 dns_protocol::kRcodeNXDOMAIN); | 721 "x", dns_protocol::kTypeAAAA, dns_protocol::kRcodeNXDOMAIN); |
| 714 | 722 |
| 715 TransactionHelper helper0("x.y", dns_protocol::kTypeA, ERR_NAME_NOT_RESOLVED); | 723 TransactionHelper helper0("x.y", dns_protocol::kTypeA, ERR_NAME_NOT_RESOLVED); |
| 716 | 724 |
| 717 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); | 725 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); |
| 718 | 726 |
| 719 // A single-label name. | 727 // A single-label name. |
| 720 TransactionHelper helper1("x", dns_protocol::kTypeA, ERR_NAME_NOT_RESOLVED); | 728 TransactionHelper helper1("x", dns_protocol::kTypeA, ERR_NAME_NOT_RESOLVED); |
| 721 | 729 |
| 722 EXPECT_TRUE(helper1.Run(transaction_factory_.get())); | 730 EXPECT_TRUE(helper1.Run(transaction_factory_.get())); |
| 723 | 731 |
| 724 // A fully-qualified name. | 732 // A fully-qualified name. |
| 725 TransactionHelper helper2("x.", dns_protocol::kTypeAAAA, | 733 TransactionHelper helper2( |
| 726 ERR_NAME_NOT_RESOLVED); | 734 "x.", dns_protocol::kTypeAAAA, ERR_NAME_NOT_RESOLVED); |
| 727 | 735 |
| 728 EXPECT_TRUE(helper2.Run(transaction_factory_.get())); | 736 EXPECT_TRUE(helper2.Run(transaction_factory_.get())); |
| 729 } | 737 } |
| 730 | 738 |
| 731 TEST_F(DnsTransactionTest, EmptySuffixSearch) { | 739 TEST_F(DnsTransactionTest, EmptySuffixSearch) { |
| 732 // Responses for first transaction. | 740 // Responses for first transaction. |
| 733 AddAsyncQueryAndRcode("x", dns_protocol::kTypeA, | 741 AddAsyncQueryAndRcode( |
| 734 dns_protocol::kRcodeNXDOMAIN); | 742 "x", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); |
| 735 | 743 |
| 736 // A fully-qualified name. | 744 // A fully-qualified name. |
| 737 TransactionHelper helper0("x.", dns_protocol::kTypeA, ERR_NAME_NOT_RESOLVED); | 745 TransactionHelper helper0("x.", dns_protocol::kTypeA, ERR_NAME_NOT_RESOLVED); |
| 738 | 746 |
| 739 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); | 747 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); |
| 740 | 748 |
| 741 // A single label name is not even attempted. | 749 // A single label name is not even attempted. |
| 742 TransactionHelper helper1("singlelabel", dns_protocol::kTypeA, | 750 TransactionHelper helper1( |
| 743 ERR_DNS_SEARCH_EMPTY); | 751 "singlelabel", dns_protocol::kTypeA, ERR_DNS_SEARCH_EMPTY); |
| 744 | 752 |
| 745 helper1.Run(transaction_factory_.get()); | 753 helper1.Run(transaction_factory_.get()); |
| 746 EXPECT_TRUE(helper1.has_completed()); | 754 EXPECT_TRUE(helper1.has_completed()); |
| 747 } | 755 } |
| 748 | 756 |
| 749 TEST_F(DnsTransactionTest, DontAppendToMultiLabelName) { | 757 TEST_F(DnsTransactionTest, DontAppendToMultiLabelName) { |
| 750 config_.search.push_back("a"); | 758 config_.search.push_back("a"); |
| 751 config_.search.push_back("b"); | 759 config_.search.push_back("b"); |
| 752 config_.search.push_back("c"); | 760 config_.search.push_back("c"); |
| 753 config_.append_to_multi_label_name = false; | 761 config_.append_to_multi_label_name = false; |
| 754 ConfigureFactory(); | 762 ConfigureFactory(); |
| 755 | 763 |
| 756 // Responses for first transaction. | 764 // Responses for first transaction. |
| 757 AddAsyncQueryAndRcode("x.y.z", dns_protocol::kTypeA, | 765 AddAsyncQueryAndRcode( |
| 758 dns_protocol::kRcodeNXDOMAIN); | 766 "x.y.z", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); |
| 759 // Responses for second transaction. | 767 // Responses for second transaction. |
| 760 AddAsyncQueryAndRcode("x.y", dns_protocol::kTypeA, | 768 AddAsyncQueryAndRcode( |
| 761 dns_protocol::kRcodeNXDOMAIN); | 769 "x.y", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); |
| 762 // Responses for third transaction. | 770 // Responses for third transaction. |
| 763 AddAsyncQueryAndRcode("x.a", dns_protocol::kTypeA, | 771 AddAsyncQueryAndRcode( |
| 764 dns_protocol::kRcodeNXDOMAIN); | 772 "x.a", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); |
| 765 AddAsyncQueryAndRcode("x.b", dns_protocol::kTypeA, | 773 AddAsyncQueryAndRcode( |
| 766 dns_protocol::kRcodeNXDOMAIN); | 774 "x.b", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); |
| 767 AddAsyncQueryAndRcode("x.c", dns_protocol::kTypeA, | 775 AddAsyncQueryAndRcode( |
| 768 dns_protocol::kRcodeNXDOMAIN); | 776 "x.c", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); |
| 769 | 777 |
| 770 TransactionHelper helper0("x.y.z", dns_protocol::kTypeA, | 778 TransactionHelper helper0( |
| 771 ERR_NAME_NOT_RESOLVED); | 779 "x.y.z", dns_protocol::kTypeA, ERR_NAME_NOT_RESOLVED); |
| 772 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); | 780 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); |
| 773 | 781 |
| 774 TransactionHelper helper1("x.y", dns_protocol::kTypeA, ERR_NAME_NOT_RESOLVED); | 782 TransactionHelper helper1("x.y", dns_protocol::kTypeA, ERR_NAME_NOT_RESOLVED); |
| 775 EXPECT_TRUE(helper1.Run(transaction_factory_.get())); | 783 EXPECT_TRUE(helper1.Run(transaction_factory_.get())); |
| 776 | 784 |
| 777 TransactionHelper helper2("x", dns_protocol::kTypeA, ERR_NAME_NOT_RESOLVED); | 785 TransactionHelper helper2("x", dns_protocol::kTypeA, ERR_NAME_NOT_RESOLVED); |
| 778 EXPECT_TRUE(helper2.Run(transaction_factory_.get())); | 786 EXPECT_TRUE(helper2.Run(transaction_factory_.get())); |
| 779 } | 787 } |
| 780 | 788 |
| 781 const uint8 kResponseNoData[] = { | 789 const uint8 kResponseNoData[] = { |
| 782 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, | 790 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, |
| 783 // Question | 791 // Question |
| 784 0x01, 'x', 0x01, 'y', 0x01, 'z', 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01, | 792 0x01, 'x', 0x01, 'y', 0x01, 'z', 0x01, 'b', 0x00, 0x00, 0x01, 0x00, |
| 785 // Authority section, SOA record, TTL 0x3E6 | 793 0x01, |
| 786 0x01, 'z', 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x03, 0xE6, | 794 // Authority section, SOA record, TTL 0x3E6 |
| 787 // Minimal RDATA, 18 bytes | 795 0x01, 'z', 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x03, 0xE6, |
| 788 0x00, 0x12, | 796 // Minimal RDATA, 18 bytes |
| 789 0x00, 0x00, | 797 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 790 0x00, 0x00, 0x00, 0x00, | 798 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 791 0x00, 0x00, 0x00, 0x00, | |
| 792 0x00, 0x00, 0x00, 0x00, | |
| 793 0x00, 0x00, 0x00, 0x00, | |
| 794 }; | 799 }; |
| 795 | 800 |
| 796 TEST_F(DnsTransactionTest, SuffixSearchStop) { | 801 TEST_F(DnsTransactionTest, SuffixSearchStop) { |
| 797 config_.ndots = 2; | 802 config_.ndots = 2; |
| 798 config_.search.push_back("a"); | 803 config_.search.push_back("a"); |
| 799 config_.search.push_back("b"); | 804 config_.search.push_back("b"); |
| 800 config_.search.push_back("c"); | 805 config_.search.push_back("c"); |
| 801 ConfigureFactory(); | 806 ConfigureFactory(); |
| 802 | 807 |
| 803 AddAsyncQueryAndRcode("x.y.z", dns_protocol::kTypeA, | 808 AddAsyncQueryAndRcode( |
| 804 dns_protocol::kRcodeNXDOMAIN); | 809 "x.y.z", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); |
| 805 AddAsyncQueryAndRcode("x.y.z.a", dns_protocol::kTypeA, | 810 AddAsyncQueryAndRcode( |
| 806 dns_protocol::kRcodeNXDOMAIN); | 811 "x.y.z.a", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); |
| 807 AddAsyncQueryAndResponse(0 /* id */, "x.y.z.b", dns_protocol::kTypeA, | 812 AddAsyncQueryAndResponse(0 /* id */, |
| 808 kResponseNoData, arraysize(kResponseNoData)); | 813 "x.y.z.b", |
| 814 dns_protocol::kTypeA, |
| 815 kResponseNoData, |
| 816 arraysize(kResponseNoData)); |
| 809 | 817 |
| 810 TransactionHelper helper0("x.y.z", dns_protocol::kTypeA, 0 /* answers */); | 818 TransactionHelper helper0("x.y.z", dns_protocol::kTypeA, 0 /* answers */); |
| 811 | 819 |
| 812 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); | 820 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); |
| 813 } | 821 } |
| 814 | 822 |
| 815 TEST_F(DnsTransactionTest, SyncFirstQuery) { | 823 TEST_F(DnsTransactionTest, SyncFirstQuery) { |
| 816 config_.search.push_back("lab.ccs.neu.edu"); | 824 config_.search.push_back("lab.ccs.neu.edu"); |
| 817 config_.search.push_back("ccs.neu.edu"); | 825 config_.search.push_back("ccs.neu.edu"); |
| 818 ConfigureFactory(); | 826 ConfigureFactory(); |
| 819 | 827 |
| 820 AddSyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype, | 828 AddSyncQueryAndResponse(0 /* id */, |
| 821 kT0ResponseDatagram, arraysize(kT0ResponseDatagram)); | 829 kT0HostName, |
| 830 kT0Qtype, |
| 831 kT0ResponseDatagram, |
| 832 arraysize(kT0ResponseDatagram)); |
| 822 | 833 |
| 823 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); | 834 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); |
| 824 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); | 835 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); |
| 825 } | 836 } |
| 826 | 837 |
| 827 TEST_F(DnsTransactionTest, SyncFirstQueryWithSearch) { | 838 TEST_F(DnsTransactionTest, SyncFirstQueryWithSearch) { |
| 828 config_.search.push_back("lab.ccs.neu.edu"); | 839 config_.search.push_back("lab.ccs.neu.edu"); |
| 829 config_.search.push_back("ccs.neu.edu"); | 840 config_.search.push_back("ccs.neu.edu"); |
| 830 ConfigureFactory(); | 841 ConfigureFactory(); |
| 831 | 842 |
| 832 AddSyncQueryAndRcode("www.lab.ccs.neu.edu", kT2Qtype, | 843 AddSyncQueryAndRcode( |
| 833 dns_protocol::kRcodeNXDOMAIN); | 844 "www.lab.ccs.neu.edu", kT2Qtype, dns_protocol::kRcodeNXDOMAIN); |
| 834 // "www.ccs.neu.edu" | 845 // "www.ccs.neu.edu" |
| 835 AddAsyncQueryAndResponse(2 /* id */, kT2HostName, kT2Qtype, | 846 AddAsyncQueryAndResponse(2 /* id */, |
| 836 kT2ResponseDatagram, arraysize(kT2ResponseDatagram)); | 847 kT2HostName, |
| 848 kT2Qtype, |
| 849 kT2ResponseDatagram, |
| 850 arraysize(kT2ResponseDatagram)); |
| 837 | 851 |
| 838 TransactionHelper helper0("www", kT2Qtype, kT2RecordCount); | 852 TransactionHelper helper0("www", kT2Qtype, kT2RecordCount); |
| 839 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); | 853 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); |
| 840 } | 854 } |
| 841 | 855 |
| 842 TEST_F(DnsTransactionTest, SyncSearchQuery) { | 856 TEST_F(DnsTransactionTest, SyncSearchQuery) { |
| 843 config_.search.push_back("lab.ccs.neu.edu"); | 857 config_.search.push_back("lab.ccs.neu.edu"); |
| 844 config_.search.push_back("ccs.neu.edu"); | 858 config_.search.push_back("ccs.neu.edu"); |
| 845 ConfigureFactory(); | 859 ConfigureFactory(); |
| 846 | 860 |
| 847 AddAsyncQueryAndRcode("www.lab.ccs.neu.edu", dns_protocol::kTypeA, | 861 AddAsyncQueryAndRcode("www.lab.ccs.neu.edu", |
| 862 dns_protocol::kTypeA, |
| 848 dns_protocol::kRcodeNXDOMAIN); | 863 dns_protocol::kRcodeNXDOMAIN); |
| 849 AddSyncQueryAndResponse(2 /* id */, kT2HostName, kT2Qtype, | 864 AddSyncQueryAndResponse(2 /* id */, |
| 850 kT2ResponseDatagram, arraysize(kT2ResponseDatagram)); | 865 kT2HostName, |
| 866 kT2Qtype, |
| 867 kT2ResponseDatagram, |
| 868 arraysize(kT2ResponseDatagram)); |
| 851 | 869 |
| 852 TransactionHelper helper0("www", kT2Qtype, kT2RecordCount); | 870 TransactionHelper helper0("www", kT2Qtype, kT2RecordCount); |
| 853 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); | 871 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); |
| 854 } | 872 } |
| 855 | 873 |
| 856 TEST_F(DnsTransactionTest, ConnectFailure) { | 874 TEST_F(DnsTransactionTest, ConnectFailure) { |
| 857 socket_factory_->fail_next_socket_ = true; | 875 socket_factory_->fail_next_socket_ = true; |
| 858 transaction_ids_.push_back(0); // Needed to make a DnsUDPAttempt. | 876 transaction_ids_.push_back(0); // Needed to make a DnsUDPAttempt. |
| 859 TransactionHelper helper0("www.chromium.org", dns_protocol::kTypeA, | 877 TransactionHelper helper0( |
| 860 ERR_CONNECTION_REFUSED); | 878 "www.chromium.org", dns_protocol::kTypeA, ERR_CONNECTION_REFUSED); |
| 861 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); | 879 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); |
| 862 } | 880 } |
| 863 | 881 |
| 864 TEST_F(DnsTransactionTest, ConnectFailureFollowedBySuccess) { | 882 TEST_F(DnsTransactionTest, ConnectFailureFollowedBySuccess) { |
| 865 // Retry after server failure. | 883 // Retry after server failure. |
| 866 config_.attempts = 2; | 884 config_.attempts = 2; |
| 867 ConfigureFactory(); | 885 ConfigureFactory(); |
| 868 // First server connection attempt fails. | 886 // First server connection attempt fails. |
| 869 transaction_ids_.push_back(0); // Needed to make a DnsUDPAttempt. | 887 transaction_ids_.push_back(0); // Needed to make a DnsUDPAttempt. |
| 870 socket_factory_->fail_next_socket_ = true; | 888 socket_factory_->fail_next_socket_ = true; |
| 871 // Second DNS query succeeds. | 889 // Second DNS query succeeds. |
| 872 AddAsyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype, | 890 AddAsyncQueryAndResponse(0 /* id */, |
| 873 kT0ResponseDatagram, arraysize(kT0ResponseDatagram)); | 891 kT0HostName, |
| 892 kT0Qtype, |
| 893 kT0ResponseDatagram, |
| 894 arraysize(kT0ResponseDatagram)); |
| 874 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); | 895 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); |
| 875 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); | 896 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); |
| 876 } | 897 } |
| 877 | 898 |
| 878 TEST_F(DnsTransactionTest, TCPLookup) { | 899 TEST_F(DnsTransactionTest, TCPLookup) { |
| 879 AddAsyncQueryAndRcode(kT0HostName, kT0Qtype, | 900 AddAsyncQueryAndRcode(kT0HostName, |
| 901 kT0Qtype, |
| 880 dns_protocol::kRcodeNOERROR | dns_protocol::kFlagTC); | 902 dns_protocol::kRcodeNOERROR | dns_protocol::kFlagTC); |
| 881 AddQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype, | 903 AddQueryAndResponse(0 /* id */, |
| 882 kT0ResponseDatagram, arraysize(kT0ResponseDatagram), | 904 kT0HostName, |
| 883 ASYNC, true /* use_tcp */); | 905 kT0Qtype, |
| 906 kT0ResponseDatagram, |
| 907 arraysize(kT0ResponseDatagram), |
| 908 ASYNC, |
| 909 true /* use_tcp */); |
| 884 | 910 |
| 885 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); | 911 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); |
| 886 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); | 912 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); |
| 887 } | 913 } |
| 888 | 914 |
| 889 TEST_F(DnsTransactionTest, TCPFailure) { | 915 TEST_F(DnsTransactionTest, TCPFailure) { |
| 890 AddAsyncQueryAndRcode(kT0HostName, kT0Qtype, | 916 AddAsyncQueryAndRcode(kT0HostName, |
| 917 kT0Qtype, |
| 891 dns_protocol::kRcodeNOERROR | dns_protocol::kFlagTC); | 918 dns_protocol::kRcodeNOERROR | dns_protocol::kFlagTC); |
| 892 AddQueryAndRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeSERVFAIL, | 919 AddQueryAndRcode(kT0HostName, |
| 893 ASYNC, true /* use_tcp */); | 920 kT0Qtype, |
| 921 dns_protocol::kRcodeSERVFAIL, |
| 922 ASYNC, |
| 923 true /* use_tcp */); |
| 894 | 924 |
| 895 TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_DNS_SERVER_FAILED); | 925 TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_DNS_SERVER_FAILED); |
| 896 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); | 926 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); |
| 897 } | 927 } |
| 898 | 928 |
| 899 TEST_F(DnsTransactionTest, TCPMalformed) { | 929 TEST_F(DnsTransactionTest, TCPMalformed) { |
| 900 AddAsyncQueryAndRcode(kT0HostName, kT0Qtype, | 930 AddAsyncQueryAndRcode(kT0HostName, |
| 931 kT0Qtype, |
| 901 dns_protocol::kRcodeNOERROR | dns_protocol::kFlagTC); | 932 dns_protocol::kRcodeNOERROR | dns_protocol::kFlagTC); |
| 902 scoped_ptr<DnsSocketData> data( | 933 scoped_ptr<DnsSocketData> data( |
| 903 new DnsSocketData(0 /* id */, kT0HostName, kT0Qtype, ASYNC, true)); | 934 new DnsSocketData(0 /* id */, kT0HostName, kT0Qtype, ASYNC, true)); |
| 904 // Valid response but length too short. | 935 // Valid response but length too short. |
| 905 data->AddResponseWithLength( | 936 data->AddResponseWithLength( |
| 906 make_scoped_ptr( | 937 make_scoped_ptr( |
| 907 new DnsResponse(reinterpret_cast<const char*>(kT0ResponseDatagram), | 938 new DnsResponse(reinterpret_cast<const char*>(kT0ResponseDatagram), |
| 908 arraysize(kT0ResponseDatagram), 0)), | 939 arraysize(kT0ResponseDatagram), |
| 940 0)), |
| 909 ASYNC, | 941 ASYNC, |
| 910 static_cast<uint16>(kT0QuerySize - 1)); | 942 static_cast<uint16>(kT0QuerySize - 1)); |
| 911 AddSocketData(data.Pass()); | 943 AddSocketData(data.Pass()); |
| 912 | 944 |
| 913 TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_DNS_MALFORMED_RESPONSE); | 945 TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_DNS_MALFORMED_RESPONSE); |
| 914 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); | 946 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); |
| 915 } | 947 } |
| 916 | 948 |
| 917 TEST_F(DnsTransactionTest, TCPTimeout) { | 949 TEST_F(DnsTransactionTest, TCPTimeout) { |
| 918 config_.timeout = TestTimeouts::tiny_timeout(); | 950 config_.timeout = TestTimeouts::tiny_timeout(); |
| 919 ConfigureFactory(); | 951 ConfigureFactory(); |
| 920 AddAsyncQueryAndRcode(kT0HostName, kT0Qtype, | 952 AddAsyncQueryAndRcode(kT0HostName, |
| 953 kT0Qtype, |
| 921 dns_protocol::kRcodeNOERROR | dns_protocol::kFlagTC); | 954 dns_protocol::kRcodeNOERROR | dns_protocol::kFlagTC); |
| 922 AddSocketData(make_scoped_ptr( | 955 AddSocketData(make_scoped_ptr( |
| 923 new DnsSocketData(1 /* id */, kT0HostName, kT0Qtype, ASYNC, true))); | 956 new DnsSocketData(1 /* id */, kT0HostName, kT0Qtype, ASYNC, true))); |
| 924 | 957 |
| 925 TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_DNS_TIMED_OUT); | 958 TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_DNS_TIMED_OUT); |
| 926 EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get())); | 959 EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get())); |
| 927 } | 960 } |
| 928 | 961 |
| 929 TEST_F(DnsTransactionTest, InvalidQuery) { | 962 TEST_F(DnsTransactionTest, InvalidQuery) { |
| 930 config_.timeout = TestTimeouts::tiny_timeout(); | 963 config_.timeout = TestTimeouts::tiny_timeout(); |
| 931 ConfigureFactory(); | 964 ConfigureFactory(); |
| 932 | 965 |
| 933 TransactionHelper helper0(".", dns_protocol::kTypeA, ERR_INVALID_ARGUMENT); | 966 TransactionHelper helper0(".", dns_protocol::kTypeA, ERR_INVALID_ARGUMENT); |
| 934 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); | 967 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); |
| 935 } | 968 } |
| 936 | 969 |
| 937 } // namespace | 970 } // namespace |
| 938 | 971 |
| 939 } // namespace net | 972 } // namespace net |
| OLD | NEW |