Imported Upstream version 1.17.1
[platform/upstream/c-ares.git] / test / ares-test-parse.cc
1 #include "ares-test.h"
2 #include "dns-proto.h"
3
4 #include <sstream>
5 #include <vector>
6
7 namespace ares {
8 namespace test {
9
10 TEST_F(LibraryTest, ParseRootName) {
11   DNSPacket pkt;
12   pkt.set_qid(0x1234).set_response().set_aa()
13     .add_question(new DNSQuestion(".", ns_t_a))
14     .add_answer(new DNSARR(".", 100, {0x02, 0x03, 0x04, 0x05}));
15   std::vector<byte> data = pkt.data();
16
17   struct hostent *host = nullptr;
18   struct ares_addrttl info[2];
19   int count = 2;
20   EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
21                                              &host, info, &count));
22   EXPECT_EQ(1, count);
23   std::stringstream ss;
24   ss << HostEnt(host);
25   EXPECT_EQ("{'' aliases=[] addrs=[2.3.4.5]}", ss.str());
26   ares_free_hostent(host);
27 }
28
29 TEST_F(LibraryTest, ParseIndirectRootName) {
30   std::vector<byte> data = {
31     0x12, 0x34,  // qid
32     0x84, // response + query + AA + not-TC + not-RD
33     0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
34     0x00, 0x01,  // num questions
35     0x00, 0x01,  // num answer RRs
36     0x00, 0x00,  // num authority RRs
37     0x00, 0x00,  // num additional RRs
38     // Question
39     0xC0, 0x04,  // weird: pointer to a random zero earlier in the message
40     0x00, 0x01,  // type A
41     0x00, 0x01,  // class IN
42     // Answer 1
43     0xC0, 0x04,
44     0x00, 0x01,  // RR type
45     0x00, 0x01,  // class IN
46     0x01, 0x02, 0x03, 0x04, // TTL
47     0x00, 0x04,  // rdata length
48     0x02, 0x03, 0x04, 0x05,
49   };
50
51   struct hostent *host = nullptr;
52   struct ares_addrttl info[2];
53   int count = 2;
54   EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
55                                              &host, info, &count));
56   EXPECT_EQ(1, count);
57   std::stringstream ss;
58   ss << HostEnt(host);
59   EXPECT_EQ("{'' aliases=[] addrs=[2.3.4.5]}", ss.str());
60   ares_free_hostent(host);
61 }
62
63 TEST_F(LibraryTest, ParseEscapedName) {
64   std::vector<byte> data = {
65     0x12, 0x34,  // qid
66     0x84, // response + query + AA + not-TC + not-RD
67     0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
68     0x00, 0x01,  // num questions
69     0x00, 0x01,  // num answer RRs
70     0x00, 0x00,  // num authority RRs
71     0x00, 0x00,  // num additional RRs
72     // Question
73     0x05, 'a', '\\', 'b', '.', 'c',
74     0x03, 'c', 'o', 'm',
75     0x00,
76     0x00, 0x01,  // type A
77     0x00, 0x01,  // class IN
78     // Answer 1
79     0x05, 'a', '\\', 'b', '.', 'c',
80     0x03, 'c', 'o', 'm',
81     0x00,
82     0x00, 0x01,  // RR type
83     0x00, 0x01,  // class IN
84     0x01, 0x02, 0x03, 0x04, // TTL
85     0x00, 0x04,  // rdata length
86     0x02, 0x03, 0x04, 0x05,
87   };
88   struct hostent *host = nullptr;
89   struct ares_addrttl info[2];
90   int count = 2;
91   EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
92                                              &host, info, &count));
93   EXPECT_EQ(1, count);
94   HostEnt hent(host);
95   std::stringstream ss;
96   ss << hent;
97   // The printable name is expanded with escapes.
98   EXPECT_EQ(11, hent.name_.size());
99   EXPECT_EQ('a', hent.name_[0]);
100   EXPECT_EQ('\\', hent.name_[1]);
101   EXPECT_EQ('\\', hent.name_[2]);
102   EXPECT_EQ('b', hent.name_[3]);
103   EXPECT_EQ('\\', hent.name_[4]);
104   EXPECT_EQ('.', hent.name_[5]);
105   EXPECT_EQ('c', hent.name_[6]);
106   ares_free_hostent(host);
107 }
108
109 TEST_F(LibraryTest, ParsePartialCompressedName) {
110   std::vector<byte> data = {
111     0x12, 0x34,  // qid
112     0x84, // response + query + AA + not-TC + not-RD
113     0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
114     0x00, 0x01,  // num questions
115     0x00, 0x01,  // num answer RRs
116     0x00, 0x00,  // num authority RRs
117     0x00, 0x00,  // num additional RRs
118     // Question
119     0x03, 'w', 'w', 'w',
120     0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
121     0x03, 'c', 'o', 'm',
122     0x00,
123     0x00, 0x01,  // type A
124     0x00, 0x01,  // class IN
125     // Answer 1
126     0x03, 'w', 'w', 'w',
127     0xc0, 0x10,  // offset 16
128     0x00, 0x01,  // RR type
129     0x00, 0x01,  // class IN
130     0x01, 0x02, 0x03, 0x04, // TTL
131     0x00, 0x04,  // rdata length
132     0x02, 0x03, 0x04, 0x05,
133   };
134   struct hostent *host = nullptr;
135   struct ares_addrttl info[2];
136   int count = 2;
137   EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
138                                              &host, info, &count));
139   ASSERT_NE(nullptr, host);
140   std::stringstream ss;
141   ss << HostEnt(host);
142   EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
143   ares_free_hostent(host);
144 }
145
146 TEST_F(LibraryTest, ParseFullyCompressedName) {
147   std::vector<byte> data = {
148     0x12, 0x34,  // qid
149     0x84, // response + query + AA + not-TC + not-RD
150     0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
151     0x00, 0x01,  // num questions
152     0x00, 0x01,  // num answer RRs
153     0x00, 0x00,  // num authority RRs
154     0x00, 0x00,  // num additional RRs
155     // Question
156     0x03, 'w', 'w', 'w',
157     0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
158     0x03, 'c', 'o', 'm',
159     0x00,
160     0x00, 0x01,  // type A
161     0x00, 0x01,  // class IN
162     // Answer 1
163     0xc0, 0x0c,  // offset 12
164     0x00, 0x01,  // RR type
165     0x00, 0x01,  // class IN
166     0x01, 0x02, 0x03, 0x04, // TTL
167     0x00, 0x04,  // rdata length
168     0x02, 0x03, 0x04, 0x05,
169   };
170   struct hostent *host = nullptr;
171   struct ares_addrttl info[2];
172   int count = 2;
173   EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
174                                              &host, info, &count));
175   ASSERT_NE(nullptr, host);
176   std::stringstream ss;
177   ss << HostEnt(host);
178   EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
179   ares_free_hostent(host);
180 }
181
182 TEST_F(LibraryTest, ParseFullyCompressedName2) {
183   std::vector<byte> data = {
184     0x12, 0x34,  // qid
185     0x84, // response + query + AA + not-TC + not-RD
186     0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
187     0x00, 0x01,  // num questions
188     0x00, 0x01,  // num answer RRs
189     0x00, 0x00,  // num authority RRs
190     0x00, 0x00,  // num additional RRs
191     // Question
192     0xC0, 0x12,  // pointer to later in message
193     0x00, 0x01,  // type A
194     0x00, 0x01,  // class IN
195     // Answer 1
196     0x03, 'w', 'w', 'w',
197     0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
198     0x03, 'c', 'o', 'm',
199     0x00,
200     0x00, 0x01,  // RR type
201     0x00, 0x01,  // class IN
202     0x01, 0x02, 0x03, 0x04, // TTL
203     0x00, 0x04,  // rdata length
204     0x02, 0x03, 0x04, 0x05,
205   };
206   struct hostent *host = nullptr;
207   struct ares_addrttl info[2];
208   int count = 2;
209   EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
210                                              &host, info, &count));
211   ASSERT_NE(nullptr, host);
212   std::stringstream ss;
213   ss << HostEnt(host);
214   EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
215   ares_free_hostent(host);
216 }
217
218 }  // namespace test
219 }  // namespace ares