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