ares-test-parse-txt.cc
Go to the documentation of this file.
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, ParseTxtReplyOK) {
11  DNSPacket pkt;
12  std::string expected1 = "txt1.example.com";
13  std::string expected2a = "txt2a";
14  std::string expected2b("ABC\0ABC", 7);
15  pkt.set_qid(0x1234).set_response().set_aa()
16  .add_question(new DNSQuestion("example.com", T_MX))
17  .add_answer(new DNSTxtRR("example.com", 100, {expected1}))
18  .add_answer(new DNSTxtRR("example.com", 100, {expected2a, expected2b}));
19  std::vector<byte> data = pkt.data();
20 
21  struct ares_txt_reply* txt = nullptr;
23  ASSERT_NE(nullptr, txt);
24  EXPECT_EQ(std::vector<byte>(expected1.data(), expected1.data() + expected1.size()),
25  std::vector<byte>(txt->txt, txt->txt + txt->length));
26 
27  struct ares_txt_reply* txt2 = txt->next;
28  ASSERT_NE(nullptr, txt2);
29  EXPECT_EQ(std::vector<byte>(expected2a.data(), expected2a.data() + expected2a.size()),
30  std::vector<byte>(txt2->txt, txt2->txt + txt2->length));
31 
32  struct ares_txt_reply* txt3 = txt2->next;
33  ASSERT_NE(nullptr, txt3);
34  EXPECT_EQ(std::vector<byte>(expected2b.data(), expected2b.data() + expected2b.size()),
35  std::vector<byte>(txt3->txt, txt3->txt + txt3->length));
36  EXPECT_EQ(nullptr, txt3->next);
37 
39 }
40 
41 TEST_F(LibraryTest, ParseTxtExtReplyOK) {
42  DNSPacket pkt;
43  std::string expected1 = "txt1.example.com";
44  std::string expected2a = "txt2a";
45  std::string expected2b("ABC\0ABC", 7);
46  pkt.set_qid(0x1234).set_response().set_aa()
47  .add_question(new DNSQuestion("example.com", T_MX))
48  .add_answer(new DNSTxtRR("example.com", 100, {expected1}))
49  .add_answer(new DNSTxtRR("example.com", 100, {expected2a, expected2b}));
50  std::vector<byte> data = pkt.data();
51 
52  struct ares_txt_ext* txt = nullptr;
54  ASSERT_NE(nullptr, txt);
55  EXPECT_EQ(std::vector<byte>(expected1.data(), expected1.data() + expected1.size()),
56  std::vector<byte>(txt->txt, txt->txt + txt->length));
57  EXPECT_EQ(1, txt->record_start);
58 
59  struct ares_txt_ext* txt2 = txt->next;
60  ASSERT_NE(nullptr, txt2);
61  EXPECT_EQ(std::vector<byte>(expected2a.data(), expected2a.data() + expected2a.size()),
62  std::vector<byte>(txt2->txt, txt2->txt + txt2->length));
63  EXPECT_EQ(1, txt2->record_start);
64 
65  struct ares_txt_ext* txt3 = txt2->next;
66  ASSERT_NE(nullptr, txt3);
67  EXPECT_EQ(std::vector<byte>(expected2b.data(), expected2b.data() + expected2b.size()),
68  std::vector<byte>(txt3->txt, txt3->txt + txt3->length));
69  EXPECT_EQ(nullptr, txt3->next);
70  EXPECT_EQ(0, txt3->record_start);
71 
73 }
74 
75 TEST_F(LibraryTest, ParseTxtMalformedReply1) {
76  std::vector<byte> data = {
77  0x12, 0x34, // qid
78  0x84, // response + query + AA + not-TC + not-RD
79  0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
80  0x00, 0x01, // num questions
81  0x00, 0x01, // num answer RRs
82  0x00, 0x00, // num authority RRs
83  0x00, 0x00, // num additional RRs
84  // Question
85  0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
86  0x03, 'c', 'o', 'm',
87  0x00,
88  0x00, 0x10, // type TXT
89  0x00, 0x01, // class IN
90  // Answer 1
91  0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
92  0x03, 'c', 'o', 'm',
93  0x00,
94  0x00, 0x10, // RR type
95  0x00, 0x01, // class IN
96  0x01, 0x02, 0x03, 0x04, // TTL
97  0x00, 0x03, // rdata length
98  0x12, 'a', 'b', // invalid length
99  };
100 
101  struct ares_txt_reply* txt = nullptr;
103  ASSERT_EQ(nullptr, txt);
104 }
105 
106 TEST_F(LibraryTest, ParseTxtMalformedReply2) {
107  std::vector<byte> data = {
108  0x12, 0x34, // qid
109  0x84, // response + query + AA + not-TC + not-RD
110  0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
111  0x00, 0x01, // num questions
112  0x00, 0x01, // num answer RRs
113  0x00, 0x00, // num authority RRs
114  0x00, 0x00, // num additional RRs
115  // Question
116  0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
117  0x03, 'c', 'o', 'm',
118  0x00,
119  0x00, 0x10, // type TXT
120  0x00, 0x01, // class IN
121  // Answer 1
122  0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
123  0x03, 'c', 'o', 'm',
124  0x00,
125  0x00, 0x10, // RR type
126  // truncated
127  };
128 
129  struct ares_txt_reply* txt = nullptr;
131  ASSERT_EQ(nullptr, txt);
132 }
133 
134 TEST_F(LibraryTest, ParseTxtMalformedReply3) {
135  std::vector<byte> data = {
136  0x12, 0x34, // qid
137  0x84, // response + query + AA + not-TC + not-RD
138  0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
139  0x00, 0x01, // num questions
140  0x00, 0x01, // num answer RRs
141  0x00, 0x00, // num authority RRs
142  0x00, 0x00, // num additional RRs
143  // Question
144  0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
145  0x03, 'c', 'o', 'm',
146  0x00,
147  0x00, 0x10, // type TXT
148  0x00, 0x01, // class IN
149  // Answer 1
150  0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
151  0x03, 'c', 'o', 'm',
152  0x00,
153  0x00, 0x10, // RR type
154  0x00, 0x01, // class IN
155  0x01, 0x02, 0x03, 0x04, // TTL
156  0x00, 0x13, // rdata length INVALID
157  0x02, 'a', 'b',
158  };
159 
160  struct ares_txt_reply* txt = nullptr;
162  ASSERT_EQ(nullptr, txt);
163 }
164 
165 TEST_F(LibraryTest, ParseTxtMalformedReply4) {
166  std::vector<byte> data = {
167  0x12, 0x34, // qid
168  0x84, // response + query + AA + not-TC + not-RD
169  0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
170  0x00, 0x01, // num questions
171  0x00, 0x01, // num answer RRs
172  0x00, 0x00, // num authority RRs
173  0x00, 0x00, // num additional RRs
174  // Question
175  0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
176  0x03, 'c', 'o', 'm',
177  0x00,
178  0x00, 0x10, // type TXT
179  0x00, // TRUNCATED
180  };
181 
182  struct ares_txt_reply* txt = nullptr;
184  ASSERT_EQ(nullptr, txt);
185 }
186 
187 TEST_F(LibraryTest, ParseTxtReplyErrors) {
188  DNSPacket pkt;
189  std::string expected1 = "txt1.example.com";
190  std::string expected2a = "txt2a";
191  std::string expected2b = "txt2b";
192  pkt.set_qid(0x1234).set_response().set_aa()
193  .add_question(new DNSQuestion("example.com", T_MX))
194  .add_answer(new DNSTxtRR("example.com", 100, {expected1}))
195  .add_answer(new DNSTxtRR("example.com", 100, {expected1}))
196  .add_answer(new DNSTxtRR("example.com", 100, {expected2a, expected2b}));
197  std::vector<byte> data = pkt.data();
198  struct ares_txt_reply* txt = nullptr;
199 
200  // No question.
201  pkt.questions_.clear();
202  data = pkt.data();
203  txt = nullptr;
205  EXPECT_EQ(nullptr, txt);
206  pkt.add_question(new DNSQuestion("example.com", T_MX));
207 
208 #ifdef DISABLED
209  // Question != answer
210  pkt.questions_.clear();
211  pkt.add_question(new DNSQuestion("Axample.com", T_TXT));
212  data = pkt.data();
214  pkt.questions_.clear();
215  pkt.add_question(new DNSQuestion("example.com", T_TXT));
216 #endif
217 
218  // Two questions.
219  pkt.add_question(new DNSQuestion("example.com", T_MX));
220  data = pkt.data();
221  txt = nullptr;
223  EXPECT_EQ(nullptr, txt);
224  pkt.questions_.clear();
225  pkt.add_question(new DNSQuestion("example.com", T_MX));
226 
227  // No answer.
228  pkt.answers_.clear();
229  data = pkt.data();
230  txt = nullptr;
232  EXPECT_EQ(nullptr, txt);
233  pkt.add_answer(new DNSTxtRR("example.com", 100, {expected1}));
234 
235  // Truncated packets.
236  for (size_t len = 1; len < data.size(); len++) {
237  txt = nullptr;
239  EXPECT_EQ(nullptr, txt);
240  }
241 }
242 
243 TEST_F(LibraryTest, ParseTxtReplyAllocFail) {
244  DNSPacket pkt;
245  std::string expected1 = "txt1.example.com";
246  std::string expected2a = "txt2a";
247  std::string expected2b = "txt2b";
248  pkt.set_qid(0x1234).set_response().set_aa()
249  .add_question(new DNSQuestion("example.com", T_MX))
250  .add_answer(new DNSCnameRR("example.com", 300, "c.example.com"))
251  .add_answer(new DNSTxtRR("c.example.com", 100, {expected1}))
252  .add_answer(new DNSTxtRR("c.example.com", 100, {expected1}))
253  .add_answer(new DNSTxtRR("c.example.com", 100, {expected2a, expected2b}));
254  std::vector<byte> data = pkt.data();
255  struct ares_txt_reply* txt = nullptr;
256 
257  for (int ii = 1; ii <= 13; ii++) {
258  ClearFails();
259  SetAllocFail(ii);
260  EXPECT_EQ(ARES_ENOMEM, ares_parse_txt_reply(data.data(), data.size(), &txt)) << ii;
261  }
262 }
263 
264 
265 } // namespace test
266 } // namespace ares
ASSERT_NE
#define ASSERT_NE(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2060
ARES_ENOMEM
#define ARES_ENOMEM
Definition: ares.h:117
ares::DNSPacket
Definition: dns-proto.h:188
ares::DNSPacket::set_aa
DNSPacket & set_aa(bool v=true)
Definition: dns-proto.h:213
test
Definition: spinlock_test.cc:36
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
ares::DNSPacket::set_qid
DNSPacket & set_qid(int qid)
Definition: dns-proto.h:211
ares::DNSPacket::answers_
std::vector< std::unique_ptr< DNSRR > > answers_
Definition: dns-proto.h:237
T_TXT
#define T_TXT
Definition: ares_nameser.h:355
ares_txt_ext
Definition: ares.h:561
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
ares::DNSPacket::add_question
DNSPacket & add_question(DNSQuestion *q)
Definition: dns-proto.h:194
ARES_EBADRESP
#define ARES_EBADRESP
Definition: ares.h:112
ares_txt_reply
Definition: ares.h:553
ares::DNSCnameRR
Definition: dns-proto.h:100
EXPECT_NE
#define EXPECT_NE(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2028
ARES_ENODATA
#define ARES_ENODATA
Definition: ares.h:101
ares_txt_ext::record_start
unsigned char record_start
Definition: ares.h:567
ares::DNSPacket::data
std::vector< byte > data() const
Definition: dns-proto.cc:592
ares_txt_reply::txt
unsigned char * txt
Definition: ares.h:555
ares_parse_txt_reply
CARES_EXTERN int ares_parse_txt_reply(const unsigned char *abuf, int alen, struct ares_txt_reply **txt_out)
Definition: ares_parse_txt_reply.c:202
data
char data[kBufferLength]
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1006
ares_txt_reply::next
struct ares_txt_reply * next
Definition: ares.h:554
ares-test.h
ARES_SUCCESS
#define ARES_SUCCESS
Definition: ares.h:98
ares::DNSPacket::add_answer
DNSPacket & add_answer(DNSRR *q)
Definition: dns-proto.h:198
ares_txt_ext::next
struct ares_txt_ext * next
Definition: ares.h:562
ares::DNSPacket::questions_
std::vector< std::unique_ptr< DNSQuestion > > questions_
Definition: dns-proto.h:236
ares_free_data
CARES_EXTERN void ares_free_data(void *dataptr)
Definition: ares_data.c:41
ares::DNSPacket::set_response
DNSPacket & set_response(bool v=true)
Definition: dns-proto.h:212
ares_parse_txt_reply_ext
CARES_EXTERN int ares_parse_txt_reply_ext(const unsigned char *abuf, int alen, struct ares_txt_ext **txt_out)
Definition: ares_parse_txt_reply.c:210
ares_txt_reply::length
size_t length
Definition: ares.h:556
ares_txt_ext::length
size_t length
Definition: ares.h:564
ares_txt_ext::txt
unsigned char * txt
Definition: ares.h:563
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
ares::test::TEST_F
TEST_F(LibraryTest, OptionsChannelInit)
Definition: ares-test-init.cc:55
ares::DNSTxtRR
Definition: dns-proto.h:115
ares::DNSQuestion
Definition: dns-proto.h:45
ares
Definition: ares-test-ai.h:9
ares::test::LibraryTest
Definition: ares-test.h:60
ASSERT_EQ
#define ASSERT_EQ(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2056
T_MX
#define T_MX
Definition: ares_nameser.h:352
dns-proto.h


grpc
Author(s):
autogenerated on Fri May 16 2025 02:57:43