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