| // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "net/dns/dns_query.h" |
| |
| #include "base/bind.h" |
| #include "base/rand_util.h" |
| #include "net/base/dns_util.h" |
| #include "net/base/io_buffer.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace net { |
| |
| // DNS query consists of a header followed by a question. Header format |
| // and question format are described below. For the meaning of specific |
| // fields, please see RFC 1035. |
| |
| // Header format. |
| // 1 1 1 1 1 1 |
| // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 |
| // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
| // | ID | |
| // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
| // |QR| Opcode |AA|TC|RD|RA| Z | RCODE | |
| // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
| // | QDCOUNT | |
| // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
| // | ANCOUNT | |
| // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
| // | NSCOUNT | |
| // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
| // | ARCOUNT | |
| // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
| |
| // Question format. |
| // 1 1 1 1 1 1 |
| // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 |
| // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
| // | | |
| // / QNAME / |
| // / / |
| // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
| // | QTYPE | |
| // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
| // | QCLASS | |
| // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
| |
| TEST(DnsQueryTest, ConstructorTest) { |
| std::string kQname("\003www\006google\003com", 16); |
| DnsQuery q1(kQname, kDNS_A, base::Bind(&base::RandInt)); |
| EXPECT_EQ(kDNS_A, q1.qtype()); |
| |
| uint8 id_hi = q1.id() >> 8, id_lo = q1.id() & 0xff; |
| |
| // See the top of the file for the description of a DNS query. |
| const uint8 query_data[] = { |
| // Header |
| id_hi, id_lo, |
| 0x01, 0x00, // Flags -- set RD (recursion desired) bit. |
| 0x00, 0x01, // Set QDCOUNT (question count) to 1, all the |
| // rest are 0 for a query. |
| 0x00, 0x00, |
| 0x00, 0x00, |
| 0x00, 0x00, |
| |
| // Question |
| 0x03, 0x77, 0x77, 0x77, // QNAME: www.google.com in DNS format. |
| 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, |
| 0x03, 0x63, 0x6f, 0x6d, 0x00, |
| |
| 0x00, 0x01, // QTYPE: A query. |
| 0x00, 0x01, // QCLASS: IN class. |
| }; |
| |
| int expected_size = arraysize(query_data); |
| EXPECT_EQ(expected_size, q1.io_buffer()->size()); |
| EXPECT_EQ(0, memcmp(q1.io_buffer()->data(), query_data, expected_size)); |
| } |
| |
| TEST(DnsQueryTest, CloneTest) { |
| std::string kQname("\003www\006google\003com", 16); |
| DnsQuery q1(kQname, kDNS_A, base::Bind(&base::RandInt)); |
| |
| scoped_ptr<DnsQuery> q2(q1.CloneWithNewId()); |
| EXPECT_EQ(q1.io_buffer()->size(), q2->io_buffer()->size()); |
| EXPECT_EQ(q1.qtype(), q2->qtype()); |
| EXPECT_EQ(q1.question_size(), q2->question_size()); |
| EXPECT_EQ(0, memcmp(q1.question_data(), q2->question_data(), |
| q1.question_size())); |
| } |
| |
| TEST(DnsQueryTest, RandomIdTest) { |
| std::string kQname("\003www\006google\003com", 16); |
| |
| // Since id fields are 16-bit values, we iterate to reduce the |
| // probability of collision, to avoid a flaky test. |
| bool ids_are_random = false; |
| for (int i = 0; i < 1000; ++i) { |
| DnsQuery q1(kQname, kDNS_A, base::Bind(&base::RandInt)); |
| DnsQuery q2(kQname, kDNS_A, base::Bind(&base::RandInt)); |
| scoped_ptr<DnsQuery> q3(q1.CloneWithNewId()); |
| ids_are_random = q1.id () != q2.id() && q1.id() != q3->id(); |
| if (ids_are_random) |
| break; |
| } |
| EXPECT_TRUE(ids_are_random); |
| } |
| |
| } // namespace net |