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 13 matching lines...) Expand all Loading... |
24 namespace net { | 24 namespace net { |
25 | 25 |
26 namespace { | 26 namespace { |
27 | 27 |
28 std::string DomainFromDot(const base::StringPiece& dotted) { | 28 std::string DomainFromDot(const base::StringPiece& dotted) { |
29 std::string out; | 29 std::string out; |
30 EXPECT_TRUE(DNSDomainFromDot(dotted, &out)); | 30 EXPECT_TRUE(DNSDomainFromDot(dotted, &out)); |
31 return out; | 31 return out; |
32 } | 32 } |
33 | 33 |
34 // A SocketDataProvider builder for MockUDPClientSocket. Each socket used by a | 34 // A SocketDataProvider builder. |
35 // DnsTransaction expects only one write and zero or more reads. | |
36 class DnsSocketData { | 35 class DnsSocketData { |
37 public: | 36 public: |
38 // The ctor takes parameters for the DnsQuery. | 37 // The ctor takes parameters for the DnsQuery. |
39 DnsSocketData(uint16 id, const char* dotted_name, uint16 qtype, IoMode mode) | 38 DnsSocketData(uint16 id, |
| 39 const char* dotted_name, |
| 40 uint16 qtype, |
| 41 IoMode mode, |
| 42 bool use_tcp) |
40 : query_(new DnsQuery(id, DomainFromDot(dotted_name), qtype)), | 43 : query_(new DnsQuery(id, DomainFromDot(dotted_name), qtype)), |
41 write_(mode, query_->io_buffer()->data(), query_->io_buffer()->size()) { | 44 use_tcp_(use_tcp) { |
| 45 if (use_tcp_) { |
| 46 scoped_ptr<uint16> length(new uint16); |
| 47 *length = base::HostToNet16(query_->io_buffer()->size()); |
| 48 writes_.push_back(MockWrite(mode, |
| 49 reinterpret_cast<const char*>(length.get()), |
| 50 sizeof(uint16))); |
| 51 lengths_.push_back(length.release()); |
| 52 } |
| 53 writes_.push_back(MockWrite(mode, |
| 54 query_->io_buffer()->data(), |
| 55 query_->io_buffer()->size())); |
42 } | 56 } |
43 ~DnsSocketData() {} | 57 ~DnsSocketData() {} |
44 | 58 |
45 // All responses must be added before GetProvider. | 59 // All responses must be added before GetProvider. |
46 | 60 |
47 // Add pre-built DnsResponse. | 61 // Adds pre-built DnsResponse. |tcp_length| will be used in TCP mode only. |
48 void AddResponse(scoped_ptr<DnsResponse> response, IoMode mode) { | 62 void AddResponseWithLength(scoped_ptr<DnsResponse> response, IoMode mode, |
| 63 uint16 tcp_length) { |
49 CHECK(!provider_.get()); | 64 CHECK(!provider_.get()); |
| 65 if (use_tcp_) { |
| 66 scoped_ptr<uint16> length(new uint16); |
| 67 *length = base::HostToNet16(tcp_length); |
| 68 reads_.push_back(MockRead(mode, |
| 69 reinterpret_cast<const char*>(length.get()), |
| 70 sizeof(uint16))); |
| 71 lengths_.push_back(length.release()); |
| 72 } |
50 reads_.push_back(MockRead(mode, | 73 reads_.push_back(MockRead(mode, |
51 response->io_buffer()->data(), | 74 response->io_buffer()->data(), |
52 response->io_buffer()->size())); | 75 response->io_buffer()->size())); |
53 responses_.push_back(response.release()); | 76 responses_.push_back(response.release()); |
54 } | 77 } |
55 | 78 |
| 79 // Adds pre-built DnsResponse. |
| 80 void AddResponse(scoped_ptr<DnsResponse> response, IoMode mode) { |
| 81 uint16 tcp_length = response->io_buffer()->size(); |
| 82 AddResponseWithLength(response.Pass(), mode, tcp_length); |
| 83 } |
| 84 |
56 // Adds pre-built response from |data| buffer. | 85 // Adds pre-built response from |data| buffer. |
57 void AddResponseData(const uint8* data, size_t length, IoMode mode) { | 86 void AddResponseData(const uint8* data, size_t length, IoMode mode) { |
58 CHECK(!provider_.get()); | 87 CHECK(!provider_.get()); |
59 AddResponse(make_scoped_ptr( | 88 AddResponse(make_scoped_ptr( |
60 new DnsResponse(reinterpret_cast<const char*>(data), length, 0)), mode); | 89 new DnsResponse(reinterpret_cast<const char*>(data), length, 0)), mode); |
61 } | 90 } |
62 | 91 |
63 // Add no-answer (RCODE only) response matching the query. | 92 // Add no-answer (RCODE only) response matching the query. |
64 void AddRcode(int rcode, IoMode mode) { | 93 void AddRcode(int rcode, IoMode mode) { |
65 scoped_ptr<DnsResponse> response( | 94 scoped_ptr<DnsResponse> response( |
66 new DnsResponse(query_->io_buffer()->data(), | 95 new DnsResponse(query_->io_buffer()->data(), |
67 query_->io_buffer()->size(), | 96 query_->io_buffer()->size(), |
68 0)); | 97 0)); |
69 dns_protocol::Header* header = | 98 dns_protocol::Header* header = |
70 reinterpret_cast<dns_protocol::Header*>(response->io_buffer()->data()); | 99 reinterpret_cast<dns_protocol::Header*>(response->io_buffer()->data()); |
71 header->flags |= base::HostToNet16(dns_protocol::kFlagResponse | rcode); | 100 header->flags |= base::HostToNet16(dns_protocol::kFlagResponse | rcode); |
72 AddResponse(response.Pass(), mode); | 101 AddResponse(response.Pass(), mode); |
73 } | 102 } |
74 | 103 |
75 // Build, if needed, and return the SocketDataProvider. No new responses | 104 // Build, if needed, and return the SocketDataProvider. No new responses |
76 // should be added afterwards. | 105 // should be added afterwards. |
77 SocketDataProvider* GetProvider() { | 106 SocketDataProvider* GetProvider() { |
78 if (provider_.get()) | 107 if (provider_.get()) |
79 return provider_.get(); | 108 return provider_.get(); |
80 if (reads_.empty()) { | 109 // Terminate the reads with ERR_IO_PENDING to prevent overrun and default to |
81 // Timeout. | 110 // timeout. |
82 provider_.reset(new DelayedSocketData(2, NULL, 0, &write_, 1)); | 111 reads_.push_back(MockRead(ASYNC, ERR_IO_PENDING)); |
83 } else { | 112 provider_.reset(new DelayedSocketData(1, &reads_[0], reads_.size(), |
84 // Terminate the reads with ERR_IO_PENDING to prevent overrun. | 113 &writes_[0], writes_.size())); |
85 reads_.push_back(MockRead(ASYNC, ERR_IO_PENDING)); | 114 if (use_tcp_) { |
86 provider_.reset(new DelayedSocketData(1, &reads_[0], reads_.size(), | 115 provider_->set_connect_data(MockConnect(reads_[0].mode, OK)); |
87 &write_, 1)); | |
88 } | 116 } |
89 return provider_.get(); | 117 return provider_.get(); |
90 } | 118 } |
91 | 119 |
92 uint16 query_id() const { | 120 uint16 query_id() const { |
93 return query_->id(); | 121 return query_->id(); |
94 } | 122 } |
95 | 123 |
96 // Returns true if the expected query was written to the socket. | 124 // Returns true if the expected query was written to the socket. |
97 bool was_written() const { | 125 bool was_written() const { |
98 CHECK(provider_.get()); | 126 CHECK(provider_.get()); |
99 return provider_->write_index() > 0; | 127 return provider_->write_index() > 0; |
100 } | 128 } |
101 | 129 |
102 private: | 130 private: |
103 scoped_ptr<DnsQuery> query_; | 131 scoped_ptr<DnsQuery> query_; |
| 132 bool use_tcp_; |
| 133 ScopedVector<uint16> lengths_; |
104 ScopedVector<DnsResponse> responses_; | 134 ScopedVector<DnsResponse> responses_; |
105 MockWrite write_; | 135 std::vector<MockWrite> writes_; |
106 std::vector<MockRead> reads_; | 136 std::vector<MockRead> reads_; |
107 scoped_ptr<DelayedSocketData> provider_; | 137 scoped_ptr<DelayedSocketData> provider_; |
108 | 138 |
109 DISALLOW_COPY_AND_ASSIGN(DnsSocketData); | 139 DISALLOW_COPY_AND_ASSIGN(DnsSocketData); |
110 }; | 140 }; |
111 | 141 |
112 class TestSocketFactory; | 142 class TestSocketFactory; |
113 | 143 |
114 // A variant of MockUDPClientSocket which always fails to Connect. | 144 // A variant of MockUDPClientSocket which always fails to Connect. |
115 class FailingUDPClientSocket : public MockUDPClientSocket { | 145 class FailingUDPClientSocket : public MockUDPClientSocket { |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 socket_factory_.reset(new TestSocketFactory()); | 351 socket_factory_.reset(new TestSocketFactory()); |
322 session_ = new DnsSession( | 352 session_ = new DnsSession( |
323 config_, | 353 config_, |
324 DnsSocketPool::CreateNull(socket_factory_.get()), | 354 DnsSocketPool::CreateNull(socket_factory_.get()), |
325 base::Bind(&DnsTransactionTest::GetNextId, base::Unretained(this)), | 355 base::Bind(&DnsTransactionTest::GetNextId, base::Unretained(this)), |
326 NULL /* NetLog */); | 356 NULL /* NetLog */); |
327 transaction_factory_ = DnsTransactionFactory::CreateFactory(session_.get()); | 357 transaction_factory_ = DnsTransactionFactory::CreateFactory(session_.get()); |
328 } | 358 } |
329 | 359 |
330 void AddSocketData(scoped_ptr<DnsSocketData> data) { | 360 void AddSocketData(scoped_ptr<DnsSocketData> data) { |
| 361 CHECK(socket_factory_.get()); |
331 transaction_ids_.push_back(data->query_id()); | 362 transaction_ids_.push_back(data->query_id()); |
332 socket_factory_->AddSocketDataProvider(data->GetProvider()); | 363 socket_factory_->AddSocketDataProvider(data->GetProvider()); |
333 socket_data_.push_back(data.release()); | 364 socket_data_.push_back(data.release()); |
334 } | 365 } |
335 | 366 |
336 // Add expected query for |dotted_name| and |qtype| with |id| and response | 367 // Add expected query for |dotted_name| and |qtype| with |id| and response |
337 // taken verbatim from |data| of |data_length| bytes. The transaction id in | 368 // taken verbatim from |data| of |data_length| bytes. The transaction id in |
338 // |data| should equal |id|, unless testing mismatched response. | 369 // |data| should equal |id|, unless testing mismatched response. |
339 void AddQueryAndResponse(uint16 id, | 370 void AddQueryAndResponse(uint16 id, |
340 const char* dotted_name, | 371 const char* dotted_name, |
341 uint16 qtype, | 372 uint16 qtype, |
342 const uint8* response_data, | 373 const uint8* response_data, |
343 size_t response_length, | 374 size_t response_length, |
344 IoMode mode) { | 375 IoMode mode, |
| 376 bool use_tcp) { |
345 CHECK(socket_factory_.get()); | 377 CHECK(socket_factory_.get()); |
346 scoped_ptr<DnsSocketData> data( | 378 scoped_ptr<DnsSocketData> data( |
347 new DnsSocketData(id, dotted_name, qtype, mode)); | 379 new DnsSocketData(id, dotted_name, qtype, mode, use_tcp)); |
348 data->AddResponseData(response_data, response_length, mode); | 380 data->AddResponseData(response_data, response_length, mode); |
349 AddSocketData(data.Pass()); | 381 AddSocketData(data.Pass()); |
350 } | 382 } |
351 | 383 |
352 void AddAsyncQueryAndResponse(uint16 id, | 384 void AddAsyncQueryAndResponse(uint16 id, |
353 const char* dotted_name, | 385 const char* dotted_name, |
354 uint16 qtype, | 386 uint16 qtype, |
355 const uint8* data, | 387 const uint8* data, |
356 size_t data_length) { | 388 size_t data_length) { |
357 AddQueryAndResponse(id, dotted_name, qtype, data, data_length, ASYNC); | 389 AddQueryAndResponse(id, dotted_name, qtype, data, data_length, ASYNC, |
| 390 false); |
358 } | 391 } |
359 | 392 |
360 void AddSyncQueryAndResponse(uint16 id, | 393 void AddSyncQueryAndResponse(uint16 id, |
361 const char* dotted_name, | 394 const char* dotted_name, |
362 uint16 qtype, | 395 uint16 qtype, |
363 const uint8* data, | 396 const uint8* data, |
364 size_t data_length) { | 397 size_t data_length) { |
365 AddQueryAndResponse(id, dotted_name, qtype, data, data_length, SYNCHRONOUS); | 398 AddQueryAndResponse(id, dotted_name, qtype, data, data_length, SYNCHRONOUS, |
| 399 false); |
366 } | 400 } |
367 | 401 |
368 // Add expected query of |dotted_name| and |qtype| and no response. | 402 // Add expected query of |dotted_name| and |qtype| and no response. |
369 void AddQueryAndTimeout(const char* dotted_name, uint16 qtype) { | 403 void AddQueryAndTimeout(const char* dotted_name, uint16 qtype) { |
370 CHECK(socket_factory_.get()); | |
371 uint16 id = base::RandInt(0, kuint16max); | 404 uint16 id = base::RandInt(0, kuint16max); |
372 scoped_ptr<DnsSocketData> data( | 405 scoped_ptr<DnsSocketData> data( |
373 new DnsSocketData(id, dotted_name, qtype, ASYNC)); | 406 new DnsSocketData(id, dotted_name, qtype, ASYNC, false)); |
374 AddSocketData(data.Pass()); | 407 AddSocketData(data.Pass()); |
375 } | 408 } |
376 | 409 |
377 // Add expected query of |dotted_name| and |qtype| and matching response with | 410 // Add expected query of |dotted_name| and |qtype| and matching response with |
378 // no answer and RCODE set to |rcode|. The id will be generated randomly. | 411 // no answer and RCODE set to |rcode|. The id will be generated randomly. |
379 void AddQueryAndRcode(const char* dotted_name, | 412 void AddQueryAndRcode(const char* dotted_name, |
380 uint16 qtype, | 413 uint16 qtype, |
381 int rcode, | 414 int rcode, |
382 IoMode mode) { | 415 IoMode mode, |
383 CHECK(socket_factory_.get()); | 416 bool use_tcp) { |
384 CHECK_NE(dns_protocol::kRcodeNOERROR, rcode); | 417 CHECK_NE(dns_protocol::kRcodeNOERROR, rcode); |
385 uint16 id = base::RandInt(0, kuint16max); | 418 uint16 id = base::RandInt(0, kuint16max); |
386 scoped_ptr<DnsSocketData> data( | 419 scoped_ptr<DnsSocketData> data( |
387 new DnsSocketData(id, dotted_name, qtype, mode)); | 420 new DnsSocketData(id, dotted_name, qtype, mode, use_tcp)); |
388 data->AddRcode(rcode, mode); | 421 data->AddRcode(rcode, mode); |
389 AddSocketData(data.Pass()); | 422 AddSocketData(data.Pass()); |
390 } | 423 } |
391 | 424 |
392 void AddAsyncQueryAndRcode(const char* dotted_name, uint16 qtype, int rcode) { | 425 void AddAsyncQueryAndRcode(const char* dotted_name, uint16 qtype, int rcode) { |
393 AddQueryAndRcode(dotted_name, qtype, rcode, ASYNC); | 426 AddQueryAndRcode(dotted_name, qtype, rcode, ASYNC, false); |
394 } | 427 } |
395 | 428 |
396 void AddSyncQueryAndRcode(const char* dotted_name, uint16 qtype, int rcode) { | 429 void AddSyncQueryAndRcode(const char* dotted_name, uint16 qtype, int rcode) { |
397 AddQueryAndRcode(dotted_name, qtype, rcode, SYNCHRONOUS); | 430 AddQueryAndRcode(dotted_name, qtype, rcode, SYNCHRONOUS, false); |
398 } | 431 } |
399 | 432 |
400 // Checks if the sockets were connected in the order matching the indices in | 433 // Checks if the sockets were connected in the order matching the indices in |
401 // |servers|. | 434 // |servers|. |
402 void CheckServerOrder(const unsigned* servers, size_t num_attempts) { | 435 void CheckServerOrder(const unsigned* servers, size_t num_attempts) { |
403 ASSERT_EQ(num_attempts, socket_factory_->remote_endpoints_.size()); | 436 ASSERT_EQ(num_attempts, socket_factory_->remote_endpoints_.size()); |
404 for (size_t i = 0; i < num_attempts; ++i) { | 437 for (size_t i = 0; i < num_attempts; ++i) { |
405 EXPECT_EQ(socket_factory_->remote_endpoints_[i], | 438 EXPECT_EQ(socket_factory_->remote_endpoints_[i], |
406 session_->config().nameservers[servers[i]]); | 439 session_->config().nameservers[servers[i]]); |
407 } | 440 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 ScopedVector<DnsSocketData> socket_data_; | 472 ScopedVector<DnsSocketData> socket_data_; |
440 | 473 |
441 std::deque<int> transaction_ids_; | 474 std::deque<int> transaction_ids_; |
442 scoped_ptr<TestSocketFactory> socket_factory_; | 475 scoped_ptr<TestSocketFactory> socket_factory_; |
443 scoped_refptr<DnsSession> session_; | 476 scoped_refptr<DnsSession> session_; |
444 scoped_ptr<DnsTransactionFactory> transaction_factory_; | 477 scoped_ptr<DnsTransactionFactory> transaction_factory_; |
445 }; | 478 }; |
446 | 479 |
447 TEST_F(DnsTransactionTest, Lookup) { | 480 TEST_F(DnsTransactionTest, Lookup) { |
448 AddAsyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype, | 481 AddAsyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype, |
449 kT0ResponseDatagram, arraysize(kT0ResponseDatagram)); | 482 kT0ResponseDatagram, arraysize(kT0ResponseDatagram)); |
450 | 483 |
451 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); | 484 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); |
452 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); | 485 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); |
453 } | 486 } |
454 | 487 |
455 // Concurrent lookup tests assume that DnsTransaction::Start immediately | 488 // Concurrent lookup tests assume that DnsTransaction::Start immediately |
456 // consumes a socket from ClientSocketFactory. | 489 // consumes a socket from ClientSocketFactory. |
457 TEST_F(DnsTransactionTest, ConcurrentLookup) { | 490 TEST_F(DnsTransactionTest, ConcurrentLookup) { |
458 AddAsyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype, | 491 AddAsyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype, |
459 kT0ResponseDatagram, arraysize(kT0ResponseDatagram)); | 492 kT0ResponseDatagram, arraysize(kT0ResponseDatagram)); |
(...skipping 25 matching lines...) Expand all Loading... |
485 helper0.Cancel(); | 518 helper0.Cancel(); |
486 | 519 |
487 MessageLoop::current()->RunUntilIdle(); | 520 MessageLoop::current()->RunUntilIdle(); |
488 | 521 |
489 EXPECT_FALSE(helper0.has_completed()); | 522 EXPECT_FALSE(helper0.has_completed()); |
490 EXPECT_TRUE(helper1.has_completed()); | 523 EXPECT_TRUE(helper1.has_completed()); |
491 } | 524 } |
492 | 525 |
493 TEST_F(DnsTransactionTest, DestroyFactory) { | 526 TEST_F(DnsTransactionTest, DestroyFactory) { |
494 AddAsyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype, | 527 AddAsyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype, |
495 kT0ResponseDatagram, arraysize(kT0ResponseDatagram)); | 528 kT0ResponseDatagram, arraysize(kT0ResponseDatagram)); |
496 | 529 |
497 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); | 530 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); |
498 helper0.StartTransaction(transaction_factory_.get()); | 531 helper0.StartTransaction(transaction_factory_.get()); |
499 | 532 |
500 // Destroying the client does not affect running requests. | 533 // Destroying the client does not affect running requests. |
501 transaction_factory_.reset(NULL); | 534 transaction_factory_.reset(NULL); |
502 | 535 |
503 MessageLoop::current()->RunUntilIdle(); | 536 MessageLoop::current()->RunUntilIdle(); |
504 | 537 |
505 EXPECT_TRUE(helper0.has_completed()); | 538 EXPECT_TRUE(helper0.has_completed()); |
506 } | 539 } |
507 | 540 |
508 TEST_F(DnsTransactionTest, CancelFromCallback) { | 541 TEST_F(DnsTransactionTest, CancelFromCallback) { |
509 AddAsyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype, | 542 AddAsyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype, |
510 kT0ResponseDatagram, arraysize(kT0ResponseDatagram)); | 543 kT0ResponseDatagram, arraysize(kT0ResponseDatagram)); |
511 | 544 |
512 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); | 545 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); |
513 helper0.set_cancel_in_callback(); | 546 helper0.set_cancel_in_callback(); |
514 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); | 547 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); |
515 } | 548 } |
516 | 549 |
517 TEST_F(DnsTransactionTest, MismatchedResponseSync) { | 550 TEST_F(DnsTransactionTest, MismatchedResponseSync) { |
518 config_.attempts = 2; | 551 config_.attempts = 2; |
519 config_.timeout = TestTimeouts::tiny_timeout(); | 552 config_.timeout = TestTimeouts::tiny_timeout(); |
520 ConfigureFactory(); | 553 ConfigureFactory(); |
521 | 554 |
522 // Attempt receives mismatched response followed by valid response. | 555 // Attempt receives mismatched response followed by valid response. |
523 scoped_ptr<DnsSocketData> data( | 556 scoped_ptr<DnsSocketData> data( |
524 new DnsSocketData(0 /* id */, kT0HostName, kT0Qtype, SYNCHRONOUS)); | 557 new DnsSocketData(0 /* id */, kT0HostName, kT0Qtype, SYNCHRONOUS, false)); |
525 data->AddResponseData(kT1ResponseDatagram, | 558 data->AddResponseData(kT1ResponseDatagram, |
526 arraysize(kT1ResponseDatagram), SYNCHRONOUS); | 559 arraysize(kT1ResponseDatagram), SYNCHRONOUS); |
527 data->AddResponseData(kT0ResponseDatagram, | 560 data->AddResponseData(kT0ResponseDatagram, |
528 arraysize(kT0ResponseDatagram), SYNCHRONOUS); | 561 arraysize(kT0ResponseDatagram), SYNCHRONOUS); |
529 AddSocketData(data.Pass()); | 562 AddSocketData(data.Pass()); |
530 | 563 |
531 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); | 564 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); |
532 EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get())); | 565 EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get())); |
533 } | 566 } |
534 | 567 |
535 TEST_F(DnsTransactionTest, MismatchedResponseAsync) { | 568 TEST_F(DnsTransactionTest, MismatchedResponseAsync) { |
536 config_.attempts = 2; | 569 config_.attempts = 2; |
537 config_.timeout = TestTimeouts::tiny_timeout(); | 570 config_.timeout = TestTimeouts::tiny_timeout(); |
538 ConfigureFactory(); | 571 ConfigureFactory(); |
539 | 572 |
540 // First attempt receives mismatched response followed by valid response. | 573 // First attempt receives mismatched response followed by valid response. |
541 // Second attempt times out. | 574 // Second attempt times out. |
542 scoped_ptr<DnsSocketData> data( | 575 scoped_ptr<DnsSocketData> data( |
543 new DnsSocketData(0 /* id */, kT0HostName, kT0Qtype, ASYNC)); | 576 new DnsSocketData(0 /* id */, kT0HostName, kT0Qtype, ASYNC, false)); |
544 data->AddResponseData(kT1ResponseDatagram, | 577 data->AddResponseData(kT1ResponseDatagram, |
545 arraysize(kT1ResponseDatagram), ASYNC); | 578 arraysize(kT1ResponseDatagram), ASYNC); |
546 data->AddResponseData(kT0ResponseDatagram, | 579 data->AddResponseData(kT0ResponseDatagram, |
547 arraysize(kT0ResponseDatagram), ASYNC); | 580 arraysize(kT0ResponseDatagram), ASYNC); |
548 AddSocketData(data.Pass()); | 581 AddSocketData(data.Pass()); |
549 AddQueryAndTimeout(kT0HostName, kT0Qtype); | 582 AddQueryAndTimeout(kT0HostName, kT0Qtype); |
550 | 583 |
551 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); | 584 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); |
552 EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get())); | 585 EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get())); |
553 } | 586 } |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
824 } | 857 } |
825 | 858 |
826 TEST_F(DnsTransactionTest, ConnectFailure) { | 859 TEST_F(DnsTransactionTest, ConnectFailure) { |
827 socket_factory_->create_failing_sockets_ = true; | 860 socket_factory_->create_failing_sockets_ = true; |
828 transaction_ids_.push_back(0); // Needed to make a DnsUDPAttempt. | 861 transaction_ids_.push_back(0); // Needed to make a DnsUDPAttempt. |
829 TransactionHelper helper0("www.chromium.org", dns_protocol::kTypeA, | 862 TransactionHelper helper0("www.chromium.org", dns_protocol::kTypeA, |
830 ERR_CONNECTION_REFUSED); | 863 ERR_CONNECTION_REFUSED); |
831 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); | 864 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); |
832 } | 865 } |
833 | 866 |
| 867 TEST_F(DnsTransactionTest, TCPLookup) { |
| 868 AddAsyncQueryAndRcode(kT0HostName, kT0Qtype, |
| 869 dns_protocol::kRcodeNOERROR | dns_protocol::kFlagTC); |
| 870 AddQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype, |
| 871 kT0ResponseDatagram, arraysize(kT0ResponseDatagram), |
| 872 ASYNC, true /* use_tcp */); |
| 873 |
| 874 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount); |
| 875 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); |
| 876 } |
| 877 |
| 878 TEST_F(DnsTransactionTest, TCPFailure) { |
| 879 AddAsyncQueryAndRcode(kT0HostName, kT0Qtype, |
| 880 dns_protocol::kRcodeNOERROR | dns_protocol::kFlagTC); |
| 881 AddQueryAndRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeSERVFAIL, |
| 882 ASYNC, true /* use_tcp */); |
| 883 |
| 884 TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_DNS_SERVER_FAILED); |
| 885 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); |
| 886 } |
| 887 |
| 888 TEST_F(DnsTransactionTest, TCPMalformed) { |
| 889 AddAsyncQueryAndRcode(kT0HostName, kT0Qtype, |
| 890 dns_protocol::kRcodeNOERROR | dns_protocol::kFlagTC); |
| 891 scoped_ptr<DnsSocketData> data( |
| 892 new DnsSocketData(0 /* id */, kT0HostName, kT0Qtype, ASYNC, true)); |
| 893 // Valid response but length too short. |
| 894 data->AddResponseWithLength( |
| 895 make_scoped_ptr( |
| 896 new DnsResponse(reinterpret_cast<const char*>(kT0ResponseDatagram), |
| 897 arraysize(kT0ResponseDatagram), 0)), |
| 898 ASYNC, |
| 899 static_cast<uint16>(kT0QuerySize - 1)); |
| 900 AddSocketData(data.Pass()); |
| 901 |
| 902 TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_DNS_MALFORMED_RESPONSE); |
| 903 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); |
| 904 } |
| 905 |
| 906 TEST_F(DnsTransactionTest, TCPTimeout) { |
| 907 config_.timeout = TestTimeouts::tiny_timeout(); |
| 908 ConfigureFactory(); |
| 909 AddAsyncQueryAndRcode(kT0HostName, kT0Qtype, |
| 910 dns_protocol::kRcodeNOERROR | dns_protocol::kFlagTC); |
| 911 AddSocketData(make_scoped_ptr( |
| 912 new DnsSocketData(1 /* id */, kT0HostName, kT0Qtype, ASYNC, true))); |
| 913 |
| 914 TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_DNS_TIMED_OUT); |
| 915 EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get())); |
| 916 } |
| 917 |
834 } // namespace | 918 } // namespace |
835 | 919 |
836 } // namespace net | 920 } // namespace net |
OLD | NEW |