ares-test-parse-mx.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, ParseMxReplyOK) {
11  DNSPacket pkt;
12  pkt.set_qid(0x1234).set_response().set_aa()
13  .add_question(new DNSQuestion("example.com", T_MX))
14  .add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com"))
15  .add_answer(new DNSMxRR("example.com", 100, 200, "mx2.example.com"));
16  std::vector<byte> data = pkt.data();
17 
18  struct ares_mx_reply* mx = nullptr;
19  EXPECT_EQ(ARES_SUCCESS, ares_parse_mx_reply(data.data(), data.size(), &mx));
20  ASSERT_NE(nullptr, mx);
21  EXPECT_EQ("mx1.example.com", std::string(mx->host));
22  EXPECT_EQ(100, mx->priority);
23 
24  struct ares_mx_reply* mx2 = mx->next;
25  ASSERT_NE(nullptr, mx2);
26  EXPECT_EQ("mx2.example.com", std::string(mx2->host));
27  EXPECT_EQ(200, mx2->priority);
28  EXPECT_EQ(nullptr, mx2->next);
29 
30  ares_free_data(mx);
31 }
32 
33 TEST_F(LibraryTest, ParseMxReplyMalformed) {
34  std::vector<byte> data = {
35  0x12, 0x34, // qid
36  0x84, // response + query + AA + not-TC + not-RD
37  0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
38  0x00, 0x01, // num questions
39  0x00, 0x01, // num answer RRs
40  0x00, 0x00, // num authority RRs
41  0x00, 0x00, // num additional RRs
42  // Question
43  0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
44  0x03, 'c', 'o', 'm',
45  0x00,
46  0x00, 0x0F, // type MX
47  0x00, 0x01, // class IN
48  // Answer 1
49  0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
50  0x03, 'c', 'o', 'm',
51  0x00,
52  0x00, 0x0F, // RR type
53  0x00, 0x01, // class IN
54  0x01, 0x02, 0x03, 0x04, // TTL
55  0x00, 0x01, // rdata length -- too short
56  0x02,
57  };
58 
59  struct ares_mx_reply* mx = nullptr;
60  EXPECT_EQ(ARES_EBADRESP, ares_parse_mx_reply(data.data(), data.size(), &mx));
61  ASSERT_EQ(nullptr, mx);
62 }
63 
64 
65 TEST_F(LibraryTest, ParseMxReplyErrors) {
66  DNSPacket pkt;
67  pkt.set_qid(0x1234).set_response().set_aa()
68  .add_question(new DNSQuestion("example.com", T_MX))
69  .add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com"));
70  std::vector<byte> data;
71  struct ares_mx_reply* mx = nullptr;
72 
73  // No question.
74  pkt.questions_.clear();
75  data = pkt.data();
76  EXPECT_EQ(ARES_EBADRESP, ares_parse_mx_reply(data.data(), data.size(), &mx));
77  EXPECT_EQ(nullptr, mx);
78  pkt.add_question(new DNSQuestion("example.com", T_MX));
79 
80 #ifdef DISABLED
81  // Question != answer
82  pkt.questions_.clear();
83  pkt.add_question(new DNSQuestion("Axample.com", T_MX));
84  data = pkt.data();
85  EXPECT_EQ(ARES_EBADRESP, ares_parse_mx_reply(data.data(), data.size(), &mx));
86  pkt.questions_.clear();
87  pkt.add_question(new DNSQuestion("example.com", T_MX));
88 #endif
89 
90  // Two questions.
91  pkt.add_question(new DNSQuestion("example.com", T_MX));
92  data = pkt.data();
93  EXPECT_EQ(ARES_EBADRESP, ares_parse_mx_reply(data.data(), data.size(), &mx));
94  EXPECT_EQ(nullptr, mx);
95  pkt.questions_.clear();
96  pkt.add_question(new DNSQuestion("example.com", T_MX));
97 
98  // Wrong sort of answer.
99  // TODO(drysdale): check if this should be ARES_ENODATA?
100  pkt.answers_.clear();
101  pkt.add_answer(new DNSSrvRR("example.abc.def.com", 180, 0, 10, 8160, "example.abc.def.com"));
102  data = pkt.data();
103  EXPECT_EQ(ARES_SUCCESS, ares_parse_mx_reply(data.data(), data.size(), &mx));
104  EXPECT_EQ(nullptr, mx);
105  pkt.answers_.clear();
106  pkt.add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com"));
107 
108  // No answer.
109  pkt.answers_.clear();
110  data = pkt.data();
111  EXPECT_EQ(ARES_ENODATA, ares_parse_mx_reply(data.data(), data.size(), &mx));
112  EXPECT_EQ(nullptr, mx);
113  pkt.add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com"));
114 
115  // Truncated packets.
116  data = pkt.data();
117  for (size_t len = 1; len < data.size(); len++) {
118  int rc = ares_parse_mx_reply(data.data(), len, &mx);
119  EXPECT_EQ(nullptr, mx);
120  EXPECT_TRUE(rc == ARES_EBADRESP || rc == ARES_EBADNAME);
121  }
122 }
123 
124 TEST_F(LibraryTest, ParseMxReplyAllocFail) {
125  DNSPacket pkt;
126  pkt.set_qid(0x1234).set_response().set_aa()
127  .add_question(new DNSQuestion("example.com", T_MX))
128  .add_answer(new DNSCnameRR("example.com", 300, "c.example.com"))
129  .add_answer(new DNSMxRR("c.example.com", 100, 100, "mx1.example.com"));
130  std::vector<byte> data = pkt.data();
131  struct ares_mx_reply* mx = nullptr;
132 
133  for (int ii = 1; ii <= 5; ii++) {
134  ClearFails();
135  SetAllocFail(ii);
136  EXPECT_EQ(ARES_ENOMEM, ares_parse_mx_reply(data.data(), data.size(), &mx)) << ii;
137  }
138 }
139 
140 } // namespace test
141 } // 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
ares_mx_reply::next
struct ares_mx_reply * next
Definition: ares.h:548
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_parse_mx_reply
CARES_EXTERN int ares_parse_mx_reply(const unsigned char *abuf, int alen, struct ares_mx_reply **mx_out)
Definition: ares_parse_mx_reply.c:38
ares::DNSPacket::answers_
std::vector< std::unique_ptr< DNSRR > > answers_
Definition: dns-proto.h:237
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::DNSCnameRR
Definition: dns-proto.h:100
ARES_ENODATA
#define ARES_ENODATA
Definition: ares.h:101
ares::DNSSrvRR
Definition: dns-proto.h:130
ares::DNSPacket::data
std::vector< byte > data() const
Definition: dns-proto.cc:592
data
char data[kBufferLength]
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1006
ARES_EBADNAME
#define ARES_EBADNAME
Definition: ares.h:110
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_mx_reply::priority
unsigned short priority
Definition: ares.h:550
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_mx_reply
Definition: ares.h:547
ares::DNSPacket::set_response
DNSPacket & set_response(bool v=true)
Definition: dns-proto.h:212
EXPECT_TRUE
#define EXPECT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1967
ares_mx_reply::host
char * host
Definition: ares.h:549
ares::DNSMxRR
Definition: dns-proto.h:122
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::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:42