ares-test-parse-naptr.cc (6654B)
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 35 TEST_F(LibraryTest, ParseNaptrReplyOK) { 36 DNSPacket pkt; 37 pkt.set_qid(0x1234).set_response().set_aa() 38 .add_question(new DNSQuestion("example.com", T_NAPTR)) 39 .add_answer(new DNSNaptrRR("example.com", 100, 40 10, 20, "SP", "service", "regexp", "replace")) 41 .add_answer(new DNSNaptrRR("example.com", 0x0010, 42 11, 21, "SP", "service2", "regexp2", "replace2")); 43 std::vector<byte> data = pkt.data(); 44 45 struct ares_naptr_reply* naptr = nullptr; 46 EXPECT_EQ(ARES_SUCCESS, ares_parse_naptr_reply(data.data(), (int)data.size(), &naptr)); 47 ASSERT_NE(nullptr, naptr); 48 EXPECT_EQ("SP", std::string((char*)naptr->flags)); 49 EXPECT_EQ("service", std::string((char*)naptr->service)); 50 EXPECT_EQ("regexp", std::string((char*)naptr->regexp)); 51 EXPECT_EQ("replace", std::string((char*)naptr->replacement)); 52 EXPECT_EQ(10, naptr->order); 53 EXPECT_EQ(20, naptr->preference); 54 55 struct ares_naptr_reply* naptr2 = naptr->next; 56 ASSERT_NE(nullptr, naptr2); 57 EXPECT_EQ("SP", std::string((char*)naptr2->flags)); 58 EXPECT_EQ("service2", std::string((char*)naptr2->service)); 59 EXPECT_EQ("regexp2", std::string((char*)naptr2->regexp)); 60 EXPECT_EQ("replace2", std::string((char*)naptr2->replacement)); 61 EXPECT_EQ(11, naptr2->order); 62 EXPECT_EQ(21, naptr2->preference); 63 EXPECT_EQ(nullptr, naptr2->next); 64 65 ares_free_data(naptr); 66 } 67 68 TEST_F(LibraryTest, ParseNaptrReplyErrors) { 69 DNSPacket pkt; 70 pkt.set_qid(0x1234).set_response().set_aa() 71 .add_question(new DNSQuestion("example.com", T_NAPTR)) 72 .add_answer(new DNSNaptrRR("example.com", 100, 73 10, 20, "SP", "service", "regexp", "replace")); 74 std::vector<byte> data; 75 struct ares_naptr_reply* naptr = nullptr; 76 77 // No question. 78 pkt.questions_.clear(); 79 data = pkt.data(); 80 EXPECT_EQ(ARES_EBADRESP, ares_parse_naptr_reply(data.data(), (int)data.size(), &naptr)); 81 pkt.add_question(new DNSQuestion("example.com", T_NAPTR)); 82 83 #ifdef DISABLED 84 // Question != answer 85 pkt.questions_.clear(); 86 pkt.add_question(new DNSQuestion("Axample.com", T_NAPTR)); 87 data = pkt.data(); 88 EXPECT_EQ(ARES_ENODATA, ares_parse_naptr_reply(data.data(), (int)data.size(), &naptr)); 89 pkt.questions_.clear(); 90 pkt.add_question(new DNSQuestion("example.com", T_NAPTR)); 91 #endif 92 93 // Two questions 94 pkt.add_question(new DNSQuestion("example.com", T_NAPTR)); 95 data = pkt.data(); 96 EXPECT_EQ(ARES_EBADRESP, ares_parse_naptr_reply(data.data(), (int)data.size(), &naptr)); 97 pkt.questions_.clear(); 98 pkt.add_question(new DNSQuestion("example.com", T_NAPTR)); 99 100 // Wrong sort of answer. 101 pkt.answers_.clear(); 102 pkt.add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com")); 103 data = pkt.data(); 104 EXPECT_EQ(ARES_SUCCESS, ares_parse_naptr_reply(data.data(), (int)data.size(), &naptr)); 105 EXPECT_EQ(nullptr, naptr); 106 pkt.answers_.clear(); 107 pkt.add_answer(new DNSNaptrRR("example.com", 100, 108 10, 20, "SP", "service", "regexp", "replace")); 109 110 // No answer. 111 pkt.answers_.clear(); 112 data = pkt.data(); 113 EXPECT_EQ(ARES_ENODATA, ares_parse_naptr_reply(data.data(), (int)data.size(), &naptr)); 114 pkt.add_answer(new DNSNaptrRR("example.com", 100, 115 10, 20, "SP", "service", "regexp", "replace")); 116 117 // Truncated packets. 118 data = pkt.data(); 119 for (size_t len = 1; len < data.size(); len++) { 120 int rc = ares_parse_naptr_reply(data.data(), (int)len, &naptr); 121 EXPECT_TRUE(rc == ARES_EBADRESP || rc == ARES_EBADNAME); 122 } 123 124 // Negative Length 125 EXPECT_EQ(ARES_EBADRESP, ares_parse_naptr_reply(data.data(), -1, &naptr)); 126 } 127 128 TEST_F(LibraryTest, ParseNaptrReplyTooShort) { 129 std::vector<byte> data = { 130 0x12, 0x34, // qid 131 0x84, // response + query + AA + not-TC + not-RD 132 0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError 133 0x00, 0x01, // num questions 134 0x00, 0x01, // num answer RRs 135 0x00, 0x00, // num authority RRs 136 0x00, 0x00, // num additional RRs 137 // Question 138 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 139 0x03, 'c', 'o', 'm', 140 0x00, 141 0x00, 0x23, // type NAPTR 142 0x00, 0x01, // class IN 143 // Answer 1 144 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 145 0x03, 'c', 'o', 'm', 146 0x00, 147 0x00, 0x23, // RR type 148 0x00, 0x01, // class IN 149 0x01, 0x02, 0x03, 0x04, // TTL 150 0x00, 0x01, // rdata length 151 0x00, // Too short: expect 2 x int16 and 3 x name (min 1 byte each) 152 }; 153 struct ares_naptr_reply* naptr = nullptr; 154 EXPECT_EQ(ARES_EBADRESP, ares_parse_naptr_reply(data.data(), (int)data.size(), &naptr)); 155 } 156 157 TEST_F(LibraryTest, ParseNaptrReplyAllocFail) { 158 DNSPacket pkt; 159 pkt.set_qid(0x1234).set_response().set_aa() 160 .add_question(new DNSQuestion("example.com", T_NAPTR)) 161 .add_answer(new DNSNaptrRR("example.com", 100, 162 10, 20, "SP", "service", "regexp", "replace")) 163 .add_answer(new DNSNaptrRR("example.com", 0x0010, 164 11, 21, "SP", "service2", "regexp2", "replace2")); 165 std::vector<byte> data = pkt.data(); 166 struct ares_naptr_reply* naptr = nullptr; 167 168 for (int ii = 1; ii <= 13; ii++) { 169 ClearFails(); 170 SetAllocFail(ii); 171 EXPECT_EQ(ARES_ENOMEM, ares_parse_naptr_reply(data.data(), (int)data.size(), &naptr)); 172 } 173 } 174 175 } // namespace test 176 } // namespace ares