Imported Upstream version 1.18.1
[platform/upstream/c-ares.git] / test / ares-test-parse-naptr.cc
1 #include "ares-test.h"
2 #include "dns-proto.h"
3
4 #include <sstream>
5 #include <vector>
6
7 namespace ares {
8 namespace test {
9
10 TEST_F(LibraryTest, ParseNaptrReplyOK) {
11   DNSPacket pkt;
12   pkt.set_qid(0x1234).set_response().set_aa()
13     .add_question(new DNSQuestion("example.com", T_NAPTR))
14     .add_answer(new DNSNaptrRR("example.com", 100,
15                                10, 20, "SP", "service", "regexp", "replace"))
16     .add_answer(new DNSNaptrRR("example.com", 0x0010,
17                                11, 21, "SP", "service2", "regexp2", "replace2"));
18   std::vector<byte> data = pkt.data();
19
20   struct ares_naptr_reply* naptr = nullptr;
21   EXPECT_EQ(ARES_SUCCESS, ares_parse_naptr_reply(data.data(), data.size(), &naptr));
22   ASSERT_NE(nullptr, naptr);
23   EXPECT_EQ("SP", std::string((char*)naptr->flags));
24   EXPECT_EQ("service", std::string((char*)naptr->service));
25   EXPECT_EQ("regexp", std::string((char*)naptr->regexp));
26   EXPECT_EQ("replace", std::string((char*)naptr->replacement));
27   EXPECT_EQ(10, naptr->order);
28   EXPECT_EQ(20, naptr->preference);
29
30   struct ares_naptr_reply* naptr2 = naptr->next;
31   ASSERT_NE(nullptr, naptr2);
32   EXPECT_EQ("SP", std::string((char*)naptr2->flags));
33   EXPECT_EQ("service2", std::string((char*)naptr2->service));
34   EXPECT_EQ("regexp2", std::string((char*)naptr2->regexp));
35   EXPECT_EQ("replace2", std::string((char*)naptr2->replacement));
36   EXPECT_EQ(11, naptr2->order);
37   EXPECT_EQ(21, naptr2->preference);
38   EXPECT_EQ(nullptr, naptr2->next);
39
40   ares_free_data(naptr);
41 }
42
43 TEST_F(LibraryTest, ParseNaptrReplyErrors) {
44   DNSPacket pkt;
45   pkt.set_qid(0x1234).set_response().set_aa()
46     .add_question(new DNSQuestion("example.com", T_NAPTR))
47     .add_answer(new DNSNaptrRR("example.com", 100,
48                                10, 20, "SP", "service", "regexp", "replace"));
49   std::vector<byte> data;
50   struct ares_naptr_reply* naptr = nullptr;
51
52   // No question.
53   pkt.questions_.clear();
54   data = pkt.data();
55   EXPECT_EQ(ARES_EBADRESP, ares_parse_naptr_reply(data.data(), data.size(), &naptr));
56   pkt.add_question(new DNSQuestion("example.com", T_NAPTR));
57
58 #ifdef DISABLED
59   // Question != answer
60   pkt.questions_.clear();
61   pkt.add_question(new DNSQuestion("Axample.com", T_NAPTR));
62   data = pkt.data();
63   EXPECT_EQ(ARES_ENODATA, ares_parse_naptr_reply(data.data(), data.size(), &naptr));
64   pkt.questions_.clear();
65   pkt.add_question(new DNSQuestion("example.com", T_NAPTR));
66 #endif
67
68   // Two questions
69   pkt.add_question(new DNSQuestion("example.com", T_NAPTR));
70   data = pkt.data();
71   EXPECT_EQ(ARES_EBADRESP, ares_parse_naptr_reply(data.data(), data.size(), &naptr));
72   pkt.questions_.clear();
73   pkt.add_question(new DNSQuestion("example.com", T_NAPTR));
74
75   // Wrong sort of answer.
76   pkt.answers_.clear();
77   pkt.add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com"));
78   data = pkt.data();
79   EXPECT_EQ(ARES_SUCCESS, ares_parse_naptr_reply(data.data(), data.size(), &naptr));
80   EXPECT_EQ(nullptr, naptr);
81   pkt.answers_.clear();
82   pkt.add_answer(new DNSNaptrRR("example.com", 100,
83                                10, 20, "SP", "service", "regexp", "replace"));
84
85   // No answer.
86   pkt.answers_.clear();
87   data = pkt.data();
88   EXPECT_EQ(ARES_ENODATA, ares_parse_naptr_reply(data.data(), data.size(), &naptr));
89   pkt.add_answer(new DNSNaptrRR("example.com", 100,
90                                10, 20, "SP", "service", "regexp", "replace"));
91
92   // Truncated packets.
93   data = pkt.data();
94   for (size_t len = 1; len < data.size(); len++) {
95     int rc = ares_parse_naptr_reply(data.data(), len, &naptr);
96     EXPECT_TRUE(rc == ARES_EBADRESP || rc == ARES_EBADNAME);
97   }
98 }
99
100 TEST_F(LibraryTest, ParseNaptrReplyTooShort) {
101   std::vector<byte> data = {
102     0x12, 0x34,  // qid
103     0x84, // response + query + AA + not-TC + not-RD
104     0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
105     0x00, 0x01,  // num questions
106     0x00, 0x01,  // num answer RRs
107     0x00, 0x00,  // num authority RRs
108     0x00, 0x00,  // num additional RRs
109     // Question
110     0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
111     0x03, 'c', 'o', 'm',
112     0x00,
113     0x00, 0x23,  // type NAPTR
114     0x00, 0x01,  // class IN
115     // Answer 1
116     0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
117     0x03, 'c', 'o', 'm',
118     0x00,
119     0x00, 0x23,  // RR type
120     0x00, 0x01,  // class IN
121     0x01, 0x02, 0x03, 0x04, // TTL
122     0x00, 0x01,  // rdata length
123     0x00,  // Too short: expect 2 x int16 and 3 x name (min 1 byte each)
124   };
125   struct ares_naptr_reply* naptr = nullptr;
126   EXPECT_EQ(ARES_EBADRESP, ares_parse_naptr_reply(data.data(), data.size(), &naptr));
127 }
128
129 TEST_F(LibraryTest, ParseNaptrReplyAllocFail) {
130   DNSPacket pkt;
131   pkt.set_qid(0x1234).set_response().set_aa()
132     .add_question(new DNSQuestion("example.com", T_NAPTR))
133     .add_answer(new DNSNaptrRR("example.com", 100,
134                                10, 20, "SP", "service", "regexp", "replace"))
135     .add_answer(new DNSNaptrRR("example.com", 0x0010,
136                                11, 21, "SP", "service2", "regexp2", "replace2"));
137   std::vector<byte> data = pkt.data();
138   struct ares_naptr_reply* naptr = nullptr;
139
140   for (int ii = 1; ii <= 13; ii++) {
141     ClearFails();
142     SetAllocFail(ii);
143     EXPECT_EQ(ARES_ENOMEM, ares_parse_naptr_reply(data.data(), data.size(), &naptr));
144   }
145 }
146
147 }  // namespace test
148 }  // namespace ares