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,ParseSoaAnyReplyOK)35 TEST_F(LibraryTest, ParseSoaAnyReplyOK) {
36 DNSPacket pkt;
37 pkt.set_qid(0x1234).set_response().set_aa()
38 .add_question(new DNSQuestion("example.com", T_ANY))\
39 .add_answer(new DNSARR("example.com", 0x01020304, {2,3,4,5}))
40 .add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com"))
41 .add_answer(new DNSMxRR("example.com", 100, 200, "mx2.example.com"))
42 .add_answer(new DNSSoaRR("example.com", 100,
43 "soa1.example.com", "fred.example.com",
44 1, 2, 3, 4, 5));
45 std::vector<byte> data = pkt.data();
46
47 struct ares_soa_reply* soa = nullptr;
48 EXPECT_EQ(ARES_SUCCESS, ares_parse_soa_reply(data.data(), (int)data.size(), &soa));
49 ASSERT_NE(nullptr, soa);
50 EXPECT_EQ("soa1.example.com", std::string(soa->nsname));
51 EXPECT_EQ("fred.example.com", std::string(soa->hostmaster));
52 EXPECT_EQ((unsigned int)1, soa->serial);
53 EXPECT_EQ((unsigned int)2, soa->refresh);
54 EXPECT_EQ((unsigned int)3, soa->retry);
55 EXPECT_EQ((unsigned int)4, soa->expire);
56 EXPECT_EQ((unsigned int)5, soa->minttl);
57 ares_free_data(soa);
58 }
59
TEST_F(LibraryTest,ParseSoaAnyReplyErrors)60 TEST_F(LibraryTest, ParseSoaAnyReplyErrors) {
61 DNSPacket pkt;
62 pkt.set_qid(0x1234).set_response().set_aa()
63 .add_question(new DNSQuestion("example.com", T_ANY))
64 .add_answer(new DNSSoaRR("example.com", 100,
65 "soa1.example.com", "fred.example.com",
66 1, 2, 3, 4, 5));
67 std::vector<byte> data;
68 struct ares_soa_reply* soa = nullptr;
69
70 // No question.
71 pkt.questions_.clear();
72 data = pkt.data();
73 EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), (int)data.size(), &soa));
74 pkt.add_question(new DNSQuestion("example.com", T_ANY));
75
76 #ifdef DISABLED
77 // Question != answer
78 pkt.questions_.clear();
79 pkt.add_question(new DNSQuestion("Axample.com", T_ANY));
80 data = pkt.data();
81 EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), (int)data.size(), &soa));
82 pkt.questions_.clear();
83 pkt.add_question(new DNSQuestion("example.com", T_ANY));
84 #endif
85
86 // Two questions
87 pkt.add_question(new DNSQuestion("example.com", T_ANY));
88 data = pkt.data();
89 EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), (int)data.size(), &soa));
90 pkt.questions_.clear();
91 pkt.add_question(new DNSQuestion("example.com", T_ANY));
92
93 // Wrong sort of answer.
94 pkt.answers_.clear();
95 pkt.add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com"));
96 data = pkt.data();
97 EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), (int)data.size(), &soa));
98 pkt.answers_.clear();
99 pkt.add_answer(new DNSSoaRR("example.com", 100,
100 "soa1.example.com", "fred.example.com",
101 1, 2, 3, 4, 5));
102
103 // No answer.
104 pkt.answers_.clear();
105 data = pkt.data();
106 EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), (int)data.size(), &soa));
107 pkt.add_answer(new DNSSoaRR("example.com", 100,
108 "soa1.example.com", "fred.example.com",
109 1, 2, 3, 4, 5));
110
111 // Truncated packets.
112 data = pkt.data();
113 for (size_t len = 1; len < data.size(); len++) {
114 EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), (int)len, &soa));
115 }
116
117 // Negative Length
118 EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), -1, &soa));
119 }
120
TEST_F(LibraryTest,ParseSoaAnyReplyAllocFail)121 TEST_F(LibraryTest, ParseSoaAnyReplyAllocFail) {
122 DNSPacket pkt;
123 pkt.set_qid(0x1234).set_response().set_aa()
124 .add_question(new DNSQuestion("example.com", T_ANY))
125 .add_answer(new DNSSoaRR("example.com", 100,
126 "soa1.example.com", "fred.example.com",
127 1, 2, 3, 4, 5));
128 std::vector<byte> data = pkt.data();
129 struct ares_soa_reply* soa = nullptr;
130
131 for (int ii = 1; ii <= 5; ii++) {
132 ClearFails();
133 SetAllocFail(ii);
134 EXPECT_EQ(ARES_ENOMEM, ares_parse_soa_reply(data.data(), (int)data.size(), &soa)) << ii;
135 }
136 }
137
138 } // namespace test
139 } // namespace ares
140