From 44829997fb50ca457df290c5e8fdc78e5b9f18fc Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 15 Apr 2020 17:42:11 +0200 Subject: [PATCH 1/2] Fix compilation of the ports event multiplexer (cherry picked from commit e9d446399be2db08cc18606537e6f9ba5bee933b) --- pdns/portsmplexer.cc | 65 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/pdns/portsmplexer.cc b/pdns/portsmplexer.cc index 39939b2f4fbc..39a0aa07ec93 100644 --- a/pdns/portsmplexer.cc +++ b/pdns/portsmplexer.cc @@ -23,11 +23,12 @@ class PortsFDMultiplexer : public FDMultiplexer close(d_portfd); } - virtual int run(struct timeval* tv, int timeout=500); + virtual int run(struct timeval* tv, int timeout=500) override; + virtual void getAvailableFDs(std::vector& fds, int timeout) override; - virtual void addFD(callbackmap_t& cbmap, int fd, callbackfunc_t toDo, const boost::any& parameter, const struct timeval* ttd=nullptr); - virtual void removeFD(callbackmap_t& cbmap, int fd); - string getName() + virtual void addFD(callbackmap_t& cbmap, int fd, callbackfunc_t toDo, const boost::any& parameter, const struct timeval* ttd=nullptr) override; + virtual void removeFD(callbackmap_t& cbmap, int fd) override; + string getName() const override { return "solaris completion ports"; } @@ -78,6 +79,58 @@ void PortsFDMultiplexer::removeFD(callbackmap_t& cbmap, int fd) throw FDMultiplexerException("Removing fd from port set: "+stringerror()); } +void PortsFDMultiplexer::getAvailableFDs(std::vector& fds, int timeout) +{ + struct timespec timeoutspec; + timeoutspec.tv_sec = timeout / 1000; + timeoutspec.tv_nsec = (timeout % 1000) * 1000000; + unsigned int numevents = 1; + int ret = port_getn(d_portfd, d_pevents.get(), min(PORT_MAX_LIST, s_maxevents), &numevents, &timeoutspec); + + /* port_getn has an unusual API - (ret == -1, errno == ETIME) can + mean partial success; you must check (*numevents) in this case + and process anything in there, otherwise you'll never see any + events from that object again. We don't care about pure timeouts + (ret == -1, errno == ETIME, *numevents == 0) so we don't bother + with that case. */ + if (ret == -1 && errno != ETIME) { + if (errno != EINTR) { + throw FDMultiplexerException("completion port_getn returned error: " + stringerror()); + } + + // EINTR is not really an error + return; + } + + if (numevents == 0) { + // nothing + return; + } + + fds.reserve(numevents); + + for (unsigned int n = 0; n < numevents; ++n) { + const auto fd = d_pevents[n].portev_object; + + /* we need to re-associate the FD */ + if (d_readCallbacks.count(fd)) { + if (port_associate(d_portfd, PORT_SOURCE_FD, fd, POLLIN, 0) < 0) { + throw FDMultiplexerException("Unable to add fd back to ports (read): " + stringerror()); + } + } + else if (d_writeCallbacks.count(fd)) { + if (port_associate(d_portfd, PORT_SOURCE_FD, fd, POLLOUT, 0) < 0) { + throw FDMultiplexerException("Unable to add fd back to ports (write): " + stringerror()); + } + } else { + /* not registered, this is unexpected */ + continue; + } + + fds.push_back(fd); + } +} + int PortsFDMultiplexer::run(struct timeval* now, int timeout) { if(d_inrun) { @@ -85,8 +138,8 @@ int PortsFDMultiplexer::run(struct timeval* now, int timeout) } struct timespec timeoutspec; - timeoutspec.tv_sec = time / 1000; - timeoutspec.tv_nsec = (time % 1000) * 1000000; + timeoutspec.tv_sec = timeout / 1000; + timeoutspec.tv_nsec = (timeout % 1000) * 1000000; unsigned int numevents=1; int ret= port_getn(d_portfd, d_pevents.get(), min(PORT_MAX_LIST, s_maxevents), &numevents, &timeoutspec); From 3272fbb44b9aeb777f028d8357c92e06fc0f4c1a Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 15 Apr 2020 17:47:12 +0200 Subject: [PATCH 2/2] Fix compilation of test-dns_random_hh.cc w/ getrandom AND arc4random (cherry picked from commit b212114bb037c9d202da750af76c6a6ac5c2c652) --- pdns/test-dns_random_hh.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/test-dns_random_hh.cc b/pdns/test-dns_random_hh.cc index 8482991e4b55..13a31597a535 100644 --- a/pdns/test-dns_random_hh.cc +++ b/pdns/test-dns_random_hh.cc @@ -123,7 +123,7 @@ BOOST_AUTO_TEST_CASE(test_dns_random_getrandom_average) { #endif #if defined(HAVE_ARC4RANDOM) -BOOST_AUTO_TEST_CASE(test_dns_random_getrandom_average) { +BOOST_AUTO_TEST_CASE(test_dns_random_arc4random_average) { ::arg().set("rng")="arc4random"; ::arg().set("entropy-source")="/dev/urandom";