• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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