1 /* MIT License
2 *
3 * Copyright (c) The c-ares project and its contributors
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 *
24 * SPDX-License-Identifier: MIT
25 */
26 #include "ares-test.h"
27 #include "dns-proto.h"
28
29 #include <sstream>
30 #include <vector>
31
32 namespace ares {
33 namespace test {
34
TEST_F(LibraryTest,ParseAaaaReplyOK)35 TEST_F(LibraryTest, ParseAaaaReplyOK) {
36 DNSPacket pkt;
37 pkt.set_qid(0x1234).set_response().set_aa()
38 .add_question(new DNSQuestion("example.com", T_AAAA))
39 .add_answer(new DNSAaaaRR("example.com", 100,
40 {0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
41 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04}))
42 .add_answer(new DNSARR("example.com", 0x01020304, {2,3,4,5}));
43 std::vector<byte> data = pkt.data();
44 struct hostent *host = nullptr;
45 struct ares_addr6ttl info[5];
46 int count = 5;
47 EXPECT_EQ(ARES_SUCCESS, ares_parse_aaaa_reply(data.data(), (int)data.size(),
48 &host, info, &count));
49 EXPECT_EQ(1, count);
50 EXPECT_EQ(100, info[0].ttl);
51 EXPECT_EQ(0x01, info[0].ip6addr._S6_un._S6_u8[0]);
52 EXPECT_EQ(0x02, info[0].ip6addr._S6_un._S6_u8[4]);
53 ASSERT_NE(nullptr, host);
54 std::stringstream ss;
55 ss << HostEnt(host);
56 EXPECT_EQ("{'example.com' aliases=[] addrs=[0101:0101:0202:0202:0303:0303:0404:0404]}", ss.str());
57 ares_free_hostent(host);
58
59 // Repeat without providing places to put the results
60 count = 0;
61 EXPECT_EQ(ARES_SUCCESS, ares_parse_aaaa_reply(data.data(), (int)data.size(),
62 nullptr, info, &count));
63 }
64
TEST_F(LibraryTest,ParseAaaaReplyCname)65 TEST_F(LibraryTest, ParseAaaaReplyCname) {
66 DNSPacket pkt;
67 pkt.set_qid(0x1234).set_response().set_aa()
68 .add_question(new DNSQuestion("example.com", T_AAAA))
69 .add_answer(new DNSCnameRR("example.com", 50, "c.example.com"))
70 .add_answer(new DNSAaaaRR("c.example.com", 100,
71 {0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
72 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04}));
73 std::vector<byte> data = pkt.data();
74 struct hostent *host = nullptr;
75 struct ares_addr6ttl info[5];
76 int count = 5;
77 EXPECT_EQ(ARES_SUCCESS, ares_parse_aaaa_reply(data.data(), (int)data.size(),
78 &host, info, &count));
79 EXPECT_EQ(1, count);
80 // CNAME TTL overrides AAAA TTL.
81 EXPECT_EQ(50, info[0].ttl);
82 EXPECT_EQ(0x01, info[0].ip6addr._S6_un._S6_u8[0]);
83 EXPECT_EQ(0x02, info[0].ip6addr._S6_un._S6_u8[4]);
84 ASSERT_NE(nullptr, host);
85 std::stringstream ss;
86 ss << HostEnt(host);
87 EXPECT_EQ("{'c.example.com' aliases=[example.com] addrs=[0101:0101:0202:0202:0303:0303:0404:0404]}", ss.str());
88 ares_free_hostent(host);
89
90 // Repeat without providing a hostent
91 count = 5;
92 EXPECT_EQ(ARES_SUCCESS, ares_parse_aaaa_reply(data.data(), (int)data.size(),
93 nullptr, info, &count));
94 EXPECT_EQ(1, count);
95 EXPECT_EQ(50, info[0].ttl);
96 EXPECT_EQ(0x01, info[0].ip6addr._S6_un._S6_u8[0]);
97 EXPECT_EQ(0x02, info[0].ip6addr._S6_un._S6_u8[4]);
98 }
99
TEST_F(LibraryTest,ParseAaaaReplyNoData)100 TEST_F(LibraryTest, ParseAaaaReplyNoData) {
101 DNSPacket pkt;
102 pkt.set_qid(0x1234).set_response().set_aa()
103 .add_question(new DNSQuestion("example.com", T_AAAA));
104 std::vector<byte> data = pkt.data();
105 struct hostent *host = nullptr;
106 struct ares_addr6ttl info[2];
107 int count = 2;
108 EXPECT_EQ(ARES_ENODATA, ares_parse_aaaa_reply(data.data(), (int)data.size(),
109 &host, info, &count));
110 EXPECT_EQ(0, count);
111 EXPECT_EQ(nullptr, host);
112
113 // Again but with a CNAME.
114 pkt.add_answer(new DNSCnameRR("example.com", 200, "c.example.com"));
115 EXPECT_EQ(ARES_ENODATA, ares_parse_aaaa_reply(data.data(), (int)data.size(),
116 &host, info, &count));
117 EXPECT_EQ(0, count);
118 EXPECT_EQ(nullptr, host);
119 }
120
TEST_F(LibraryTest,ParseAaaaReplyErrors)121 TEST_F(LibraryTest, ParseAaaaReplyErrors) {
122 DNSPacket pkt;
123 pkt.set_qid(0x1234).set_response().set_aa()
124 .add_question(new DNSQuestion("example.com", T_AAAA))
125 .add_answer(new DNSAaaaRR("example.com", 100,
126 {0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
127 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04}));
128 std::vector<byte> data;
129
130 struct hostent *host = nullptr;
131 struct ares_addr6ttl info[2];
132 int count = 2;
133
134 // No question.
135 pkt.questions_.clear();
136 data = pkt.data();
137 EXPECT_EQ(ARES_EBADRESP, ares_parse_aaaa_reply(data.data(), (int)data.size(),
138 &host, info, &count));
139 EXPECT_EQ(nullptr, host);
140 pkt.add_question(new DNSQuestion("example.com", T_AAAA));
141
142 // Question != answer, this is ok as of Issue #683
143 pkt.questions_.clear();
144 pkt.add_question(new DNSQuestion("Axample.com", T_AAAA));
145 data = pkt.data();
146 EXPECT_EQ(ARES_SUCCESS, ares_parse_aaaa_reply(data.data(), (int)data.size(),
147 &host, info, &count));
148 ASSERT_NE(nullptr, host);
149 std::stringstream ss;
150 ss << HostEnt(host);
151 EXPECT_EQ("{'axample.com' aliases=[] addrs=[0101:0101:0202:0202:0303:0303:0404:0404]}", ss.str());
152 ares_free_hostent(host);
153
154 host = nullptr;
155 pkt.questions_.clear();
156 pkt.add_question(new DNSQuestion("example.com", T_AAAA));
157
158 // Two questions.
159 pkt.add_question(new DNSQuestion("example.com", T_AAAA));
160 data = pkt.data();
161 EXPECT_EQ(ARES_EBADRESP, ares_parse_aaaa_reply(data.data(), (int)data.size(),
162 &host, info, &count));
163 EXPECT_EQ(nullptr, host);
164 pkt.questions_.clear();
165 pkt.add_question(new DNSQuestion("example.com", T_AAAA));
166
167 // Wrong sort of answer.
168 pkt.answers_.clear();
169 pkt.add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com"));
170 data = pkt.data();
171 EXPECT_EQ(ARES_ENODATA, ares_parse_aaaa_reply(data.data(), (int)data.size(),
172 &host, info, &count));
173 EXPECT_EQ(nullptr, host);
174 pkt.answers_.clear();
175 pkt.add_answer(new DNSAaaaRR("example.com", 100,
176 {0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
177 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04}));
178
179 // No answer.
180 pkt.answers_.clear();
181 data = pkt.data();
182 EXPECT_EQ(ARES_ENODATA, ares_parse_aaaa_reply(data.data(), (int)data.size(),
183 &host, info, &count));
184 EXPECT_EQ(nullptr, host);
185 pkt.add_answer(new DNSAaaaRR("example.com", 100,
186 {0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
187 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04}));
188
189 // Truncated packets.
190 data = pkt.data();
191 for (size_t len = 1; len < data.size(); len++) {
192 EXPECT_EQ(ARES_EBADRESP, ares_parse_aaaa_reply(data.data(), (int)len,
193 &host, info, &count));
194 EXPECT_EQ(nullptr, host);
195 EXPECT_EQ(ARES_EBADRESP, ares_parse_aaaa_reply(data.data(), (int)len,
196 nullptr, info, &count));
197 }
198
199 // Negative length
200 EXPECT_EQ(ARES_EBADRESP, ares_parse_aaaa_reply(data.data(), -1,
201 &host, info, &count));
202 }
203
TEST_F(LibraryTest,ParseAaaaReplyAllocFail)204 TEST_F(LibraryTest, ParseAaaaReplyAllocFail) {
205 DNSPacket pkt;
206 pkt.set_qid(0x1234).set_response().set_aa()
207 .add_question(new DNSQuestion("example.com", T_AAAA))
208 .add_answer(new DNSCnameRR("example.com", 300, "c.example.com"))
209 .add_answer(new DNSAaaaRR("c.example.com", 100,
210 {0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
211 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04}));
212 std::vector<byte> data = pkt.data();
213 struct hostent *host = nullptr;
214 struct ares_addr6ttl info[2];
215 int count = 2;
216
217 for (int ii = 1; ii <= 8; ii++) {
218 ClearFails();
219 SetAllocFail(ii);
220 EXPECT_EQ(ARES_ENOMEM, ares_parse_aaaa_reply(data.data(), (int)data.size(),
221 &host, info, &count)) << ii;
222 EXPECT_EQ(nullptr, host);
223 }
224 }
225
226 } // namespace test
227 } // namespace ares
228