12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199 |
- #include "ares-test.h"
- #include "dns-proto.h"
- #ifndef WIN32
- #include <sys/types.h>
- #include <sys/stat.h>
- #endif
- #include <sstream>
- #include <vector>
- using testing::InvokeWithoutArgs;
- using testing::DoAll;
- namespace ares {
- namespace test {
- TEST_P(MockChannelTest, Basic) {
- std::vector<byte> reply = {
- 0x00, 0x00, // qid
- 0x84, // response + query + AA + not-TC + not-RD
- 0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
- 0x00, 0x01, // 1 question
- 0x00, 0x01, // 1 answer RRs
- 0x00, 0x00, // 0 authority RRs
- 0x00, 0x00, // 0 additional RRs
- // Question
- 0x03, 'w', 'w', 'w',
- 0x06, 'g', 'o', 'o', 'g', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x01, // type A
- 0x00, 0x01, // class IN
- // Answer
- 0x03, 'w', 'w', 'w',
- 0x06, 'g', 'o', 'o', 'g', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x01, // type A
- 0x00, 0x01, // class IN
- 0x00, 0x00, 0x01, 0x00, // TTL
- 0x00, 0x04, // rdata length
- 0x01, 0x02, 0x03, 0x04
- };
- ON_CALL(server_, OnRequest("www.google.com", T_A))
- .WillByDefault(SetReplyData(&server_, reply));
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
- }
- // UDP only so mock server doesn't get confused by concatenated requests
- TEST_P(MockUDPChannelTest, GetHostByNameParallelLookups) {
- DNSPacket rsp1;
- rsp1.set_response().set_aa()
- .add_question(new DNSQuestion("www.google.com", T_A))
- .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
- ON_CALL(server_, OnRequest("www.google.com", T_A))
- .WillByDefault(SetReply(&server_, &rsp1));
- DNSPacket rsp2;
- rsp2.set_response().set_aa()
- .add_question(new DNSQuestion("www.example.com", T_A))
- .add_answer(new DNSARR("www.example.com", 100, {1, 2, 3, 4}));
- ON_CALL(server_, OnRequest("www.example.com", T_A))
- .WillByDefault(SetReply(&server_, &rsp2));
- HostResult result1;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result1);
- HostResult result2;
- ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result2);
- HostResult result3;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result3);
- Process();
- EXPECT_TRUE(result1.done_);
- EXPECT_TRUE(result2.done_);
- EXPECT_TRUE(result3.done_);
- std::stringstream ss1;
- ss1 << result1.host_;
- EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss1.str());
- std::stringstream ss2;
- ss2 << result2.host_;
- EXPECT_EQ("{'www.example.com' aliases=[] addrs=[1.2.3.4]}", ss2.str());
- std::stringstream ss3;
- ss3 << result3.host_;
- EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss3.str());
- }
- // UDP to TCP specific test
- TEST_P(MockUDPChannelTest, TruncationRetry) {
- DNSPacket rsptruncated;
- rsptruncated.set_response().set_aa().set_tc()
- .add_question(new DNSQuestion("www.google.com", T_A));
- DNSPacket rspok;
- rspok.set_response()
- .add_question(new DNSQuestion("www.google.com", T_A))
- .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4}));
- EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
- .WillOnce(SetReply(&server_, &rsptruncated))
- .WillOnce(SetReply(&server_, &rspok));
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
- }
- static int sock_cb_count = 0;
- static int SocketConnectCallback(ares_socket_t fd, int type, void *data) {
- int rc = *(int*)data;
- if (verbose) std::cerr << "SocketConnectCallback(" << fd << ") invoked" << std::endl;
- sock_cb_count++;
- return rc;
- }
- TEST_P(MockChannelTest, SockCallback) {
- DNSPacket rsp;
- rsp.set_response().set_aa()
- .add_question(new DNSQuestion("www.google.com", T_A))
- .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
- EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
- .WillOnce(SetReply(&server_, &rsp));
- // Get notified of new sockets
- int rc = ARES_SUCCESS;
- ares_set_socket_callback(channel_, SocketConnectCallback, &rc);
- HostResult result;
- sock_cb_count = 0;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_EQ(1, sock_cb_count);
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
- }
- TEST_P(MockChannelTest, SockFailCallback) {
- // Notification of new sockets gives an error.
- int rc = -1;
- ares_set_socket_callback(channel_, SocketConnectCallback, &rc);
- HostResult result;
- sock_cb_count = 0;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_LT(1, sock_cb_count);
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
- }
- static int sock_config_cb_count = 0;
- static int SocketConfigureCallback(ares_socket_t fd, int type, void *data) {
- int rc = *(int*)data;
- if (verbose) std::cerr << "SocketConfigureCallback(" << fd << ") invoked" << std::endl;
- sock_config_cb_count++;
- return rc;
- }
- TEST_P(MockChannelTest, SockConfigureCallback) {
- DNSPacket rsp;
- rsp.set_response().set_aa()
- .add_question(new DNSQuestion("www.google.com", T_A))
- .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
- EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
- .WillOnce(SetReply(&server_, &rsp));
- // Get notified of new sockets
- int rc = ARES_SUCCESS;
- ares_set_socket_configure_callback(channel_, SocketConfigureCallback, &rc);
- HostResult result;
- sock_config_cb_count = 0;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_EQ(1, sock_config_cb_count);
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
- }
- TEST_P(MockChannelTest, SockConfigureFailCallback) {
- // Notification of new sockets gives an error.
- int rc = -1;
- ares_set_socket_configure_callback(channel_, SocketConfigureCallback, &rc);
- HostResult result;
- sock_config_cb_count = 0;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_LT(1, sock_config_cb_count);
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
- }
- // TCP only to prevent retries
- TEST_P(MockTCPChannelTest, MalformedResponse) {
- std::vector<byte> one = {0x01};
- EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
- .WillOnce(SetReplyData(&server_, one));
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ETIMEOUT, result.status_);
- }
- TEST_P(MockTCPChannelTest, FormErrResponse) {
- DNSPacket rsp;
- rsp.set_response().set_aa()
- .add_question(new DNSQuestion("www.google.com", T_A));
- rsp.set_rcode(FORMERR);
- EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
- .WillOnce(SetReply(&server_, &rsp));
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_EFORMERR, result.status_);
- }
- TEST_P(MockTCPChannelTest, ServFailResponse) {
- DNSPacket rsp;
- rsp.set_response().set_aa()
- .add_question(new DNSQuestion("www.google.com", T_A));
- rsp.set_rcode(SERVFAIL);
- EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
- .WillOnce(SetReply(&server_, &rsp));
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- // ARES_FLAG_NOCHECKRESP not set, so SERVFAIL consumed
- EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
- }
- TEST_P(MockTCPChannelTest, NotImplResponse) {
- DNSPacket rsp;
- rsp.set_response().set_aa()
- .add_question(new DNSQuestion("www.google.com", T_A));
- rsp.set_rcode(NOTIMP);
- EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
- .WillOnce(SetReply(&server_, &rsp));
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- // ARES_FLAG_NOCHECKRESP not set, so NOTIMP consumed
- EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
- }
- TEST_P(MockTCPChannelTest, RefusedResponse) {
- DNSPacket rsp;
- rsp.set_response().set_aa()
- .add_question(new DNSQuestion("www.google.com", T_A));
- rsp.set_rcode(REFUSED);
- EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
- .WillOnce(SetReply(&server_, &rsp));
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- // ARES_FLAG_NOCHECKRESP not set, so REFUSED consumed
- EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
- }
- TEST_P(MockTCPChannelTest, YXDomainResponse) {
- DNSPacket rsp;
- rsp.set_response().set_aa()
- .add_question(new DNSQuestion("www.google.com", T_A));
- rsp.set_rcode(YXDOMAIN);
- EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
- .WillOnce(SetReply(&server_, &rsp));
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ENODATA, result.status_);
- }
- class MockExtraOptsTest
- : public MockChannelOptsTest,
- public ::testing::WithParamInterface< std::pair<int, bool> > {
- public:
- MockExtraOptsTest()
- : MockChannelOptsTest(1, GetParam().first, GetParam().second,
- FillOptions(&opts_),
- ARES_OPT_SOCK_SNDBUF|ARES_OPT_SOCK_RCVBUF) {}
- static struct ares_options* FillOptions(struct ares_options * opts) {
- memset(opts, 0, sizeof(struct ares_options));
- // Set a few options that affect socket communications
- opts->socket_send_buffer_size = 514;
- opts->socket_receive_buffer_size = 514;
- return opts;
- }
- private:
- struct ares_options opts_;
- };
- TEST_P(MockExtraOptsTest, SimpleQuery) {
- ares_set_local_ip4(channel_, 0x7F000001);
- byte addr6[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
- ares_set_local_ip6(channel_, addr6);
- ares_set_local_dev(channel_, "dummy");
- DNSPacket rsp;
- rsp.set_response().set_aa()
- .add_question(new DNSQuestion("www.google.com", T_A))
- .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
- ON_CALL(server_, OnRequest("www.google.com", T_A))
- .WillByDefault(SetReply(&server_, &rsp));
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
- }
- class MockFlagsChannelOptsTest
- : public MockChannelOptsTest,
- public ::testing::WithParamInterface< std::pair<int, bool> > {
- public:
- MockFlagsChannelOptsTest(int flags)
- : MockChannelOptsTest(1, GetParam().first, GetParam().second,
- FillOptions(&opts_, flags), ARES_OPT_FLAGS) {}
- static struct ares_options* FillOptions(struct ares_options * opts, int flags) {
- memset(opts, 0, sizeof(struct ares_options));
- opts->flags = flags;
- return opts;
- }
- private:
- struct ares_options opts_;
- };
- class MockNoCheckRespChannelTest : public MockFlagsChannelOptsTest {
- public:
- MockNoCheckRespChannelTest() : MockFlagsChannelOptsTest(ARES_FLAG_NOCHECKRESP) {}
- };
- TEST_P(MockNoCheckRespChannelTest, ServFailResponse) {
- DNSPacket rsp;
- rsp.set_response().set_aa()
- .add_question(new DNSQuestion("www.google.com", T_A));
- rsp.set_rcode(SERVFAIL);
- ON_CALL(server_, OnRequest("www.google.com", T_A))
- .WillByDefault(SetReply(&server_, &rsp));
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ESERVFAIL, result.status_);
- }
- TEST_P(MockNoCheckRespChannelTest, NotImplResponse) {
- DNSPacket rsp;
- rsp.set_response().set_aa()
- .add_question(new DNSQuestion("www.google.com", T_A));
- rsp.set_rcode(NOTIMP);
- ON_CALL(server_, OnRequest("www.google.com", T_A))
- .WillByDefault(SetReply(&server_, &rsp));
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ENOTIMP, result.status_);
- }
- TEST_P(MockNoCheckRespChannelTest, RefusedResponse) {
- DNSPacket rsp;
- rsp.set_response().set_aa()
- .add_question(new DNSQuestion("www.google.com", T_A));
- rsp.set_rcode(REFUSED);
- ON_CALL(server_, OnRequest("www.google.com", T_A))
- .WillByDefault(SetReply(&server_, &rsp));
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_EREFUSED, result.status_);
- }
- class MockEDNSChannelTest : public MockFlagsChannelOptsTest {
- public:
- MockEDNSChannelTest() : MockFlagsChannelOptsTest(ARES_FLAG_EDNS) {}
- };
- TEST_P(MockEDNSChannelTest, RetryWithoutEDNS) {
- DNSPacket rspfail;
- rspfail.set_response().set_aa().set_rcode(FORMERR)
- .add_question(new DNSQuestion("www.google.com", T_A));
- DNSPacket rspok;
- rspok.set_response()
- .add_question(new DNSQuestion("www.google.com", T_A))
- .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4}));
- EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
- .WillOnce(SetReply(&server_, &rspfail))
- .WillOnce(SetReply(&server_, &rspok));
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
- }
- TEST_P(MockChannelTest, SearchDomains) {
- DNSPacket nofirst;
- nofirst.set_response().set_aa().set_rcode(NXDOMAIN)
- .add_question(new DNSQuestion("www.first.com", T_A));
- ON_CALL(server_, OnRequest("www.first.com", T_A))
- .WillByDefault(SetReply(&server_, &nofirst));
- DNSPacket nosecond;
- nosecond.set_response().set_aa().set_rcode(NXDOMAIN)
- .add_question(new DNSQuestion("www.second.org", T_A));
- ON_CALL(server_, OnRequest("www.second.org", T_A))
- .WillByDefault(SetReply(&server_, &nosecond));
- DNSPacket yesthird;
- yesthird.set_response().set_aa()
- .add_question(new DNSQuestion("www.third.gov", T_A))
- .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
- ON_CALL(server_, OnRequest("www.third.gov", T_A))
- .WillByDefault(SetReply(&server_, &yesthird));
- HostResult result;
- ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str());
- }
- // Relies on retries so is UDP-only
- TEST_P(MockUDPChannelTest, SearchDomainsWithResentReply) {
- DNSPacket nofirst;
- nofirst.set_response().set_aa().set_rcode(NXDOMAIN)
- .add_question(new DNSQuestion("www.first.com", T_A));
- EXPECT_CALL(server_, OnRequest("www.first.com", T_A))
- .WillOnce(SetReply(&server_, &nofirst));
- DNSPacket nosecond;
- nosecond.set_response().set_aa().set_rcode(NXDOMAIN)
- .add_question(new DNSQuestion("www.second.org", T_A));
- EXPECT_CALL(server_, OnRequest("www.second.org", T_A))
- .WillOnce(SetReply(&server_, &nosecond));
- DNSPacket yesthird;
- yesthird.set_response().set_aa()
- .add_question(new DNSQuestion("www.third.gov", T_A))
- .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
- // Before sending the real answer, resend an earlier reply
- EXPECT_CALL(server_, OnRequest("www.third.gov", T_A))
- .WillOnce(DoAll(SetReply(&server_, &nofirst),
- SetReplyQID(&server_, 123)))
- .WillOnce(DoAll(SetReply(&server_, &yesthird),
- SetReplyQID(&server_, -1)));
- HostResult result;
- ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str());
- }
- TEST_P(MockChannelTest, SearchDomainsBare) {
- DNSPacket nofirst;
- nofirst.set_response().set_aa().set_rcode(NXDOMAIN)
- .add_question(new DNSQuestion("www.first.com", T_A));
- ON_CALL(server_, OnRequest("www.first.com", T_A))
- .WillByDefault(SetReply(&server_, &nofirst));
- DNSPacket nosecond;
- nosecond.set_response().set_aa().set_rcode(NXDOMAIN)
- .add_question(new DNSQuestion("www.second.org", T_A));
- ON_CALL(server_, OnRequest("www.second.org", T_A))
- .WillByDefault(SetReply(&server_, &nosecond));
- DNSPacket nothird;
- nothird.set_response().set_aa().set_rcode(NXDOMAIN)
- .add_question(new DNSQuestion("www.third.gov", T_A));
- ON_CALL(server_, OnRequest("www.third.gov", T_A))
- .WillByDefault(SetReply(&server_, ¬hird));
- DNSPacket yesbare;
- yesbare.set_response().set_aa()
- .add_question(new DNSQuestion("www", T_A))
- .add_answer(new DNSARR("www", 0x0200, {2, 3, 4, 5}));
- ON_CALL(server_, OnRequest("www", T_A))
- .WillByDefault(SetReply(&server_, &yesbare));
- HostResult result;
- ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www' aliases=[] addrs=[2.3.4.5]}", ss.str());
- }
- TEST_P(MockChannelTest, SearchNoDataThenSuccess) {
- // First two search domains recognize the name but have no A records.
- DNSPacket nofirst;
- nofirst.set_response().set_aa()
- .add_question(new DNSQuestion("www.first.com", T_A));
- ON_CALL(server_, OnRequest("www.first.com", T_A))
- .WillByDefault(SetReply(&server_, &nofirst));
- DNSPacket nosecond;
- nosecond.set_response().set_aa()
- .add_question(new DNSQuestion("www.second.org", T_A));
- ON_CALL(server_, OnRequest("www.second.org", T_A))
- .WillByDefault(SetReply(&server_, &nosecond));
- DNSPacket yesthird;
- yesthird.set_response().set_aa()
- .add_question(new DNSQuestion("www.third.gov", T_A))
- .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
- ON_CALL(server_, OnRequest("www.third.gov", T_A))
- .WillByDefault(SetReply(&server_, &yesthird));
- HostResult result;
- ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str());
- }
- TEST_P(MockChannelTest, SearchNoDataThenNoDataBare) {
- // First two search domains recognize the name but have no A records.
- DNSPacket nofirst;
- nofirst.set_response().set_aa()
- .add_question(new DNSQuestion("www.first.com", T_A));
- ON_CALL(server_, OnRequest("www.first.com", T_A))
- .WillByDefault(SetReply(&server_, &nofirst));
- DNSPacket nosecond;
- nosecond.set_response().set_aa()
- .add_question(new DNSQuestion("www.second.org", T_A));
- ON_CALL(server_, OnRequest("www.second.org", T_A))
- .WillByDefault(SetReply(&server_, &nosecond));
- DNSPacket nothird;
- nothird.set_response().set_aa()
- .add_question(new DNSQuestion("www.third.gov", T_A));
- ON_CALL(server_, OnRequest("www.third.gov", T_A))
- .WillByDefault(SetReply(&server_, ¬hird));
- DNSPacket nobare;
- nobare.set_response().set_aa()
- .add_question(new DNSQuestion("www", T_A));
- ON_CALL(server_, OnRequest("www", T_A))
- .WillByDefault(SetReply(&server_, &nobare));
- HostResult result;
- ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ENODATA, result.status_);
- }
- TEST_P(MockChannelTest, SearchNoDataThenFail) {
- // First two search domains recognize the name but have no A records.
- DNSPacket nofirst;
- nofirst.set_response().set_aa()
- .add_question(new DNSQuestion("www.first.com", T_A));
- ON_CALL(server_, OnRequest("www.first.com", T_A))
- .WillByDefault(SetReply(&server_, &nofirst));
- DNSPacket nosecond;
- nosecond.set_response().set_aa()
- .add_question(new DNSQuestion("www.second.org", T_A));
- ON_CALL(server_, OnRequest("www.second.org", T_A))
- .WillByDefault(SetReply(&server_, &nosecond));
- DNSPacket nothird;
- nothird.set_response().set_aa()
- .add_question(new DNSQuestion("www.third.gov", T_A));
- ON_CALL(server_, OnRequest("www.third.gov", T_A))
- .WillByDefault(SetReply(&server_, ¬hird));
- DNSPacket nobare;
- nobare.set_response().set_aa().set_rcode(NXDOMAIN)
- .add_question(new DNSQuestion("www", T_A));
- ON_CALL(server_, OnRequest("www", T_A))
- .WillByDefault(SetReply(&server_, &nobare));
- HostResult result;
- ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ENODATA, result.status_);
- }
- TEST_P(MockChannelTest, SearchAllocFailure) {
- SearchResult result;
- SetAllocFail(1);
- ares_search(channel_, "fully.qualified.", C_IN, T_A, SearchCallback, &result);
- /* Already done */
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ENOMEM, result.status_);
- }
- TEST_P(MockChannelTest, SearchHighNdots) {
- DNSPacket nobare;
- nobare.set_response().set_aa().set_rcode(NXDOMAIN)
- .add_question(new DNSQuestion("a.b.c.w.w.w", T_A));
- ON_CALL(server_, OnRequest("a.b.c.w.w.w", T_A))
- .WillByDefault(SetReply(&server_, &nobare));
- DNSPacket yesfirst;
- yesfirst.set_response().set_aa()
- .add_question(new DNSQuestion("a.b.c.w.w.w.first.com", T_A))
- .add_answer(new DNSARR("a.b.c.w.w.w.first.com", 0x0200, {2, 3, 4, 5}));
- ON_CALL(server_, OnRequest("a.b.c.w.w.w.first.com", T_A))
- .WillByDefault(SetReply(&server_, &yesfirst));
- SearchResult result;
- ares_search(channel_, "a.b.c.w.w.w", C_IN, T_A, SearchCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_SUCCESS, result.status_);
- std::stringstream ss;
- ss << PacketToString(result.data_);
- EXPECT_EQ("RSP QRY AA NOERROR Q:{'a.b.c.w.w.w.first.com' IN A} "
- "A:{'a.b.c.w.w.w.first.com' IN A TTL=512 2.3.4.5}",
- ss.str());
- }
- TEST_P(MockChannelTest, UnspecifiedFamilyV6) {
- DNSPacket rsp6;
- rsp6.set_response().set_aa()
- .add_question(new DNSQuestion("example.com", T_AAAA))
- .add_answer(new DNSAaaaRR("example.com", 100,
- {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
- ON_CALL(server_, OnRequest("example.com", T_AAAA))
- .WillByDefault(SetReply(&server_, &rsp6));
- DNSPacket rsp4;
- rsp4.set_response().set_aa()
- .add_question(new DNSQuestion("example.com", T_A));
- ON_CALL(server_, OnRequest("example.com", T_A))
- .WillByDefault(SetReply(&server_, &rsp4));
- HostResult result;
- ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- // Default to IPv6 when both are available.
- EXPECT_EQ("{'example.com' aliases=[] addrs=[2121:0000:0000:0000:0000:0000:0000:0303]}", ss.str());
- }
- TEST_P(MockChannelTest, UnspecifiedFamilyV4) {
- DNSPacket rsp6;
- rsp6.set_response().set_aa()
- .add_question(new DNSQuestion("example.com", T_AAAA));
- ON_CALL(server_, OnRequest("example.com", T_AAAA))
- .WillByDefault(SetReply(&server_, &rsp6));
- DNSPacket rsp4;
- rsp4.set_response().set_aa()
- .add_question(new DNSQuestion("example.com", T_A))
- .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}));
- ON_CALL(server_, OnRequest("example.com", T_A))
- .WillByDefault(SetReply(&server_, &rsp4));
- HostResult result;
- ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
- }
- TEST_P(MockChannelTest, UnspecifiedFamilyNoData) {
- DNSPacket rsp6;
- rsp6.set_response().set_aa()
- .add_question(new DNSQuestion("example.com", T_AAAA))
- .add_answer(new DNSCnameRR("example.com", 100, "elsewhere.com"));
- ON_CALL(server_, OnRequest("example.com", T_AAAA))
- .WillByDefault(SetReply(&server_, &rsp6));
- DNSPacket rsp4;
- rsp4.set_response().set_aa()
- .add_question(new DNSQuestion("example.com", T_A));
- ON_CALL(server_, OnRequest("example.com", T_A))
- .WillByDefault(SetReply(&server_, &rsp4));
- HostResult result;
- ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'' aliases=[] addrs=[]}", ss.str());
- }
- TEST_P(MockChannelTest, UnspecifiedFamilyCname6A4) {
- DNSPacket rsp6;
- rsp6.set_response().set_aa()
- .add_question(new DNSQuestion("example.com", T_AAAA))
- .add_answer(new DNSCnameRR("example.com", 100, "elsewhere.com"));
- ON_CALL(server_, OnRequest("example.com", T_AAAA))
- .WillByDefault(SetReply(&server_, &rsp6));
- DNSPacket rsp4;
- rsp4.set_response().set_aa()
- .add_question(new DNSQuestion("example.com", T_A))
- .add_answer(new DNSARR("example.com", 100, {1, 2, 3, 4}));
- ON_CALL(server_, OnRequest("example.com", T_A))
- .WillByDefault(SetReply(&server_, &rsp4));
- HostResult result;
- ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'example.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
- }
- TEST_P(MockChannelTest, ExplicitIP) {
- HostResult result;
- ares_gethostbyname(channel_, "1.2.3.4", AF_INET, HostCallback, &result);
- EXPECT_TRUE(result.done_); // Immediate return
- EXPECT_EQ(ARES_SUCCESS, result.status_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'1.2.3.4' aliases=[] addrs=[1.2.3.4]}", ss.str());
- }
- TEST_P(MockChannelTest, ExplicitIPAllocFail) {
- HostResult result;
- SetAllocSizeFail(strlen("1.2.3.4") + 1);
- ares_gethostbyname(channel_, "1.2.3.4", AF_INET, HostCallback, &result);
- EXPECT_TRUE(result.done_); // Immediate return
- EXPECT_EQ(ARES_ENOMEM, result.status_);
- }
- TEST_P(MockChannelTest, SortListV4) {
- DNSPacket rsp;
- rsp.set_response().set_aa()
- .add_question(new DNSQuestion("example.com", T_A))
- .add_answer(new DNSARR("example.com", 100, {22, 23, 24, 25}))
- .add_answer(new DNSARR("example.com", 100, {12, 13, 14, 15}))
- .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}));
- ON_CALL(server_, OnRequest("example.com", T_A))
- .WillByDefault(SetReply(&server_, &rsp));
- {
- EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "12.13.0.0/255.255.0.0 1234::5678"));
- HostResult result;
- ares_gethostbyname(channel_, "example.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'example.com' aliases=[] addrs=[12.13.14.15, 22.23.24.25, 2.3.4.5]}", ss.str());
- }
- {
- EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "2.3.0.0/16 130.140.150.160/26"));
- HostResult result;
- ares_gethostbyname(channel_, "example.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'example.com' aliases=[] addrs=[2.3.4.5, 22.23.24.25, 12.13.14.15]}", ss.str());
- }
- struct ares_options options;
- memset(&options, 0, sizeof(options));
- int optmask = 0;
- EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &options, &optmask));
- EXPECT_TRUE((optmask & ARES_OPT_SORTLIST) == ARES_OPT_SORTLIST);
- ares_destroy_options(&options);
- }
- TEST_P(MockChannelTest, SortListV6) {
- DNSPacket rsp;
- rsp.set_response().set_aa()
- .add_question(new DNSQuestion("example.com", T_AAAA))
- .add_answer(new DNSAaaaRR("example.com", 100,
- {0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02}))
- .add_answer(new DNSAaaaRR("example.com", 100,
- {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
- ON_CALL(server_, OnRequest("example.com", T_AAAA))
- .WillByDefault(SetReply(&server_, &rsp));
- {
- ares_set_sortlist(channel_, "1111::/16 2.3.0.0/255.255.0.0");
- HostResult result;
- ares_gethostbyname(channel_, "example.com.", AF_INET6, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'example.com' aliases=[] addrs=[1111:0000:0000:0000:0000:0000:0000:0202, "
- "2121:0000:0000:0000:0000:0000:0000:0303]}", ss.str());
- }
- {
- ares_set_sortlist(channel_, "2121::/8");
- HostResult result;
- ares_gethostbyname(channel_, "example.com.", AF_INET6, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'example.com' aliases=[] addrs=[2121:0000:0000:0000:0000:0000:0000:0303, "
- "1111:0000:0000:0000:0000:0000:0000:0202]}", ss.str());
- }
- }
- // Relies on retries so is UDP-only
- TEST_P(MockUDPChannelTest, SearchDomainsAllocFail) {
- DNSPacket nofirst;
- nofirst.set_response().set_aa().set_rcode(NXDOMAIN)
- .add_question(new DNSQuestion("www.first.com", T_A));
- ON_CALL(server_, OnRequest("www.first.com", T_A))
- .WillByDefault(SetReply(&server_, &nofirst));
- DNSPacket nosecond;
- nosecond.set_response().set_aa().set_rcode(NXDOMAIN)
- .add_question(new DNSQuestion("www.second.org", T_A));
- ON_CALL(server_, OnRequest("www.second.org", T_A))
- .WillByDefault(SetReply(&server_, &nosecond));
- DNSPacket yesthird;
- yesthird.set_response().set_aa()
- .add_question(new DNSQuestion("www.third.gov", T_A))
- .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
- ON_CALL(server_, OnRequest("www.third.gov", T_A))
- .WillByDefault(SetReply(&server_, &yesthird));
- // Fail a variety of different memory allocations, and confirm
- // that the operation either fails with ENOMEM or succeeds
- // with the expected result.
- const int kCount = 34;
- HostResult results[kCount];
- for (int ii = 1; ii <= kCount; ii++) {
- HostResult* result = &(results[ii - 1]);
- ClearFails();
- SetAllocFail(ii);
- ares_gethostbyname(channel_, "www", AF_INET, HostCallback, result);
- Process();
- EXPECT_TRUE(result->done_);
- if (result->status_ == ARES_SUCCESS) {
- std::stringstream ss;
- ss << result->host_;
- EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str()) << " failed alloc #" << ii;
- if (verbose) std::cerr << "Succeeded despite failure of alloc #" << ii << std::endl;
- }
- }
- // Explicitly destroy the channel now, so that the HostResult objects
- // are still valid (in case any pending work refers to them).
- ares_destroy(channel_);
- channel_ = nullptr;
- }
- // Relies on retries so is UDP-only
- TEST_P(MockUDPChannelTest, Resend) {
- std::vector<byte> nothing;
- DNSPacket reply;
- reply.set_response().set_aa()
- .add_question(new DNSQuestion("www.google.com", T_A))
- .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
- EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
- .WillOnce(SetReplyData(&server_, nothing))
- .WillOnce(SetReplyData(&server_, nothing))
- .WillOnce(SetReply(&server_, &reply));
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(2, result.timeouts_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
- }
- TEST_P(MockChannelTest, CancelImmediate) {
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- ares_cancel(channel_);
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ECANCELLED, result.status_);
- EXPECT_EQ(0, result.timeouts_);
- }
- TEST_P(MockChannelTest, CancelImmediateGetHostByAddr) {
- HostResult result;
- struct in_addr addr;
- addr.s_addr = htonl(0x08080808);
-
- ares_gethostbyaddr(channel_, &addr, sizeof(addr), AF_INET, HostCallback, &result);
- ares_cancel(channel_);
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ECANCELLED, result.status_);
- EXPECT_EQ(0, result.timeouts_);
- }
- // Relies on retries so is UDP-only
- TEST_P(MockUDPChannelTest, CancelLater) {
- std::vector<byte> nothing;
- // On second request, cancel the channel.
- EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
- .WillOnce(SetReplyData(&server_, nothing))
- .WillOnce(CancelChannel(&server_, channel_));
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ECANCELLED, result.status_);
- EXPECT_EQ(0, result.timeouts_);
- }
- TEST_P(MockChannelTest, GetHostByNameDestroyAbsolute) {
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- ares_destroy(channel_);
- channel_ = nullptr;
- EXPECT_TRUE(result.done_); // Synchronous
- EXPECT_EQ(ARES_EDESTRUCTION, result.status_);
- EXPECT_EQ(0, result.timeouts_);
- }
- TEST_P(MockChannelTest, GetHostByNameDestroyRelative) {
- HostResult result;
- ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
- ares_destroy(channel_);
- channel_ = nullptr;
- EXPECT_TRUE(result.done_); // Synchronous
- EXPECT_EQ(ARES_EDESTRUCTION, result.status_);
- EXPECT_EQ(0, result.timeouts_);
- }
- TEST_P(MockChannelTest, GetHostByNameCNAMENoData) {
- DNSPacket response;
- response.set_response().set_aa()
- .add_question(new DNSQuestion("cname.first.com", T_A))
- .add_answer(new DNSCnameRR("cname.first.com", 100, "a.first.com"));
- ON_CALL(server_, OnRequest("cname.first.com", T_A))
- .WillByDefault(SetReply(&server_, &response));
- HostResult result;
- ares_gethostbyname(channel_, "cname.first.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ENODATA, result.status_);
- }
- TEST_P(MockChannelTest, GetHostByAddrDestroy) {
- unsigned char gdns_addr4[4] = {0x08, 0x08, 0x08, 0x08};
- HostResult result;
- ares_gethostbyaddr(channel_, gdns_addr4, sizeof(gdns_addr4), AF_INET, HostCallback, &result);
- ares_destroy(channel_);
- channel_ = nullptr;
- EXPECT_TRUE(result.done_); // Synchronous
- EXPECT_EQ(ARES_EDESTRUCTION, result.status_);
- EXPECT_EQ(0, result.timeouts_);
- }
- #ifndef WIN32
- TEST_P(MockChannelTest, HostAlias) {
- DNSPacket reply;
- reply.set_response().set_aa()
- .add_question(new DNSQuestion("www.google.com", T_A))
- .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
- ON_CALL(server_, OnRequest("www.google.com", T_A))
- .WillByDefault(SetReply(&server_, &reply));
- TempFile aliases("\n\n# www commentedout\nwww www.google.com\n");
- EnvValue with_env("HOSTALIASES", aliases.filename());
- HostResult result;
- ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
- }
- TEST_P(MockChannelTest, HostAliasMissing) {
- DNSPacket yesfirst;
- yesfirst.set_response().set_aa()
- .add_question(new DNSQuestion("www.first.com", T_A))
- .add_answer(new DNSARR("www.first.com", 0x0200, {2, 3, 4, 5}));
- ON_CALL(server_, OnRequest("www.first.com", T_A))
- .WillByDefault(SetReply(&server_, &yesfirst));
- TempFile aliases("\n\n# www commentedout\nww www.google.com\n");
- EnvValue with_env("HOSTALIASES", aliases.filename());
- HostResult result;
- ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.first.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
- }
- TEST_P(MockChannelTest, HostAliasMissingFile) {
- DNSPacket yesfirst;
- yesfirst.set_response().set_aa()
- .add_question(new DNSQuestion("www.first.com", T_A))
- .add_answer(new DNSARR("www.first.com", 0x0200, {2, 3, 4, 5}));
- ON_CALL(server_, OnRequest("www.first.com", T_A))
- .WillByDefault(SetReply(&server_, &yesfirst));
- EnvValue with_env("HOSTALIASES", "bogus.mcfile");
- HostResult result;
- ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.first.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
- }
- TEST_P(MockChannelTest, HostAliasUnreadable) {
- TempFile aliases("www www.google.com\n");
- EXPECT_EQ(chmod(aliases.filename(), 0), 0);
- /* Perform OS sanity checks. We are observing on Debian after the chmod(fn, 0)
- * that we are still able to fopen() the file which is unexpected. Skip the
- * test if we observe this behavior */
- struct stat st;
- EXPECT_EQ(stat(aliases.filename(), &st), 0);
- EXPECT_EQ(st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO), 0);
- FILE *fp = fopen(aliases.filename(), "r");
- if (fp != NULL) {
- if (verbose) std::cerr << "Skipping Test due to OS incompatibility (open file caching)" << std::endl;
- fclose(fp);
- return;
- }
- EnvValue with_env("HOSTALIASES", aliases.filename());
- HostResult result;
- ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_EFILE, result.status_);
- chmod(aliases.filename(), 0777);
- }
- #endif
- class MockMultiServerChannelTest
- : public MockChannelOptsTest,
- public ::testing::WithParamInterface< std::pair<int, bool> > {
- public:
- MockMultiServerChannelTest(bool rotate)
- : MockChannelOptsTest(3, GetParam().first, GetParam().second, nullptr, rotate ? ARES_OPT_ROTATE : ARES_OPT_NOROTATE) {}
- void CheckExample() {
- HostResult result;
- ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
- }
- };
- class RotateMultiMockTest : public MockMultiServerChannelTest {
- public:
- RotateMultiMockTest() : MockMultiServerChannelTest(true) {}
- };
- class NoRotateMultiMockTest : public MockMultiServerChannelTest {
- public:
- NoRotateMultiMockTest() : MockMultiServerChannelTest(false) {}
- };
- TEST_P(RotateMultiMockTest, ThirdServer) {
- struct ares_options opts = {0};
- int optmask = 0;
- EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &opts, &optmask));
- EXPECT_EQ(0, (optmask & ARES_OPT_NOROTATE));
- ares_destroy_options(&opts);
- DNSPacket servfailrsp;
- servfailrsp.set_response().set_aa().set_rcode(SERVFAIL)
- .add_question(new DNSQuestion("www.example.com", T_A));
- DNSPacket notimplrsp;
- notimplrsp.set_response().set_aa().set_rcode(NOTIMP)
- .add_question(new DNSQuestion("www.example.com", T_A));
- DNSPacket okrsp;
- okrsp.set_response().set_aa()
- .add_question(new DNSQuestion("www.example.com", T_A))
- .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5}));
- EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
- .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
- EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
- .WillOnce(SetReply(servers_[1].get(), ¬implrsp));
- EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
- .WillOnce(SetReply(servers_[2].get(), &okrsp));
- CheckExample();
- // Second time around, starts from server [1].
- EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
- .WillOnce(SetReply(servers_[1].get(), &servfailrsp));
- EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
- .WillOnce(SetReply(servers_[2].get(), ¬implrsp));
- EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
- .WillOnce(SetReply(servers_[0].get(), &okrsp));
- CheckExample();
- // Third time around, starts from server [2].
- EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
- .WillOnce(SetReply(servers_[2].get(), &servfailrsp));
- EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
- .WillOnce(SetReply(servers_[0].get(), ¬implrsp));
- EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
- .WillOnce(SetReply(servers_[1].get(), &okrsp));
- CheckExample();
- }
- TEST_P(NoRotateMultiMockTest, ThirdServer) {
- struct ares_options opts = {0};
- int optmask = 0;
- EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &opts, &optmask));
- EXPECT_EQ(ARES_OPT_NOROTATE, (optmask & ARES_OPT_NOROTATE));
- ares_destroy_options(&opts);
- DNSPacket servfailrsp;
- servfailrsp.set_response().set_aa().set_rcode(SERVFAIL)
- .add_question(new DNSQuestion("www.example.com", T_A));
- DNSPacket notimplrsp;
- notimplrsp.set_response().set_aa().set_rcode(NOTIMP)
- .add_question(new DNSQuestion("www.example.com", T_A));
- DNSPacket okrsp;
- okrsp.set_response().set_aa()
- .add_question(new DNSQuestion("www.example.com", T_A))
- .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5}));
- EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
- .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
- EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
- .WillOnce(SetReply(servers_[1].get(), ¬implrsp));
- EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
- .WillOnce(SetReply(servers_[2].get(), &okrsp));
- CheckExample();
- // Second time around, still starts from server [0].
- EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
- .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
- EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
- .WillOnce(SetReply(servers_[1].get(), ¬implrsp));
- EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
- .WillOnce(SetReply(servers_[2].get(), &okrsp));
- CheckExample();
- // Third time around, still starts from server [0].
- EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
- .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
- EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
- .WillOnce(SetReply(servers_[1].get(), ¬implrsp));
- EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
- .WillOnce(SetReply(servers_[2].get(), &okrsp));
- CheckExample();
- }
- INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockChannelTest, ::testing::ValuesIn(ares::test::families_modes));
- INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockUDPChannelTest, ::testing::ValuesIn(ares::test::families));
- INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockTCPChannelTest, ::testing::ValuesIn(ares::test::families));
- INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockExtraOptsTest, ::testing::ValuesIn(ares::test::families_modes));
- INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockNoCheckRespChannelTest, ::testing::ValuesIn(ares::test::families_modes));
- INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockEDNSChannelTest, ::testing::ValuesIn(ares::test::families_modes));
- INSTANTIATE_TEST_SUITE_P(TransportModes, RotateMultiMockTest, ::testing::ValuesIn(ares::test::families_modes));
- INSTANTIATE_TEST_SUITE_P(TransportModes, NoRotateMultiMockTest, ::testing::ValuesIn(ares::test::families_modes));
- } // namespace test
- } // namespace ares
|