From: Otto Date: Mon, 15 Feb 2021 08:55:27 +0000 (+0100) Subject: Process review comments; most importantly a separate type for X-Git-Tag: dnsdist-1.6.0-alpha2~39^2~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=adf0f3686d08905df7e66afb99a79e2100403ebc;p=thirdparty%2Fpdns.git Process review comments; most importantly a separate type for RecursorControlChannel::Answer --- diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index 45e44b62eb..07c8f2dc6b 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -3842,13 +3842,6 @@ static vector >& operator+=(vector& operator+=(std::pair& a, const std::pair& b) -{ - a.first |= b.first; - a.second += b.second; - return a; -} - /* This function should only be called by the handler to gather metrics, wipe the cache, reload the Lua script (not the Lua config) or change the current trace regex, @@ -3891,7 +3884,7 @@ template T broadcastAccFunction(const boost::function& func) } template string broadcastAccFunction(const boost::function& fun); // explicit instantiation -template std::pair broadcastAccFunction(const boost::function*()>& fun); // explicit instantiation +template RecursorControlChannel::Answer broadcastAccFunction(const boost::function& fun); // explicit instantiation template uint64_t broadcastAccFunction(const boost::function& fun); // explicit instantiation template vector broadcastAccFunction(const boost::function *()>& fun); // explicit instantiation template vector > broadcastAccFunction(const boost::function > *()>& fun); // explicit instantiation @@ -3901,7 +3894,7 @@ static void handleRCC(int fd, FDMultiplexer::funcparam_t& var) { try { string remote; - string msg = s_rcc.recv(&remote).second; + string msg = s_rcc.recv(&remote).d_str; RecursorControlParser rcp; RecursorControlParser::func_t* command; @@ -4117,14 +4110,14 @@ static FDMultiplexer* getMultiplexer() } -static std::pair* doReloadLuaScript() +static RecursorControlChannel::Answer* doReloadLuaScript() { string fname= ::arg()["lua-dns-script"]; try { if(fname.empty()) { t_pdl.reset(); g_log<(0, string("unloaded\n")); + return new RecursorControlChannel::Answer{0, string("unloaded\n")}; } else { t_pdl = std::make_shared(); @@ -4132,25 +4125,25 @@ static std::pair* doReloadLuaScript() if (err != 0) { string msg = std::to_string(t_id) + " Retaining current script, could not read '" + fname + "': " + stringerror(err); g_log<(1, msg + "\n"); + return new RecursorControlChannel::Answer{1, msg + "\n"}; } } } catch(std::exception& e) { g_log<(1, string("retaining current script, error from '"+fname+"': "+e.what()+"\n")); + return new RecursorControlChannel::Answer{1, string("retaining current script, error from '"+fname+"': "+e.what()+"\n")}; } g_log<(0, string("(re)loaded '"+fname+"'\n")); + return new RecursorControlChannel::Answer{0, string("(re)loaded '"+fname+"'\n")}; } -std::pair doQueueReloadLuaScript(vector::const_iterator begin, vector::const_iterator end) +RecursorControlChannel::Answer doQueueReloadLuaScript(vector::const_iterator begin, vector::const_iterator end) { if(begin != end) ::arg().set("lua-dns-script") = *begin; - return broadcastAccFunction>(doReloadLuaScript); + return broadcastAccFunction(doReloadLuaScript); } static string* pleaseUseNewTraceRegex(const std::string& newRegex) diff --git a/pdns/rec_channel.cc b/pdns/rec_channel.cc index 3d95e5b772..d610d14a18 100644 --- a/pdns/rec_channel.cc +++ b/pdns/rec_channel.cc @@ -179,7 +179,7 @@ static void sendfd(int s, int fd, const string* remote) } } -void RecursorControlChannel::send(const std::pair& msg, const std::string* remote, unsigned int timeout, int fd) +void RecursorControlChannel::send(const Answer& msg, const std::string* remote, unsigned int timeout, int fd) { int ret = waitForRWData(d_fd, false, timeout, 0); if(ret == 0) { @@ -197,15 +197,15 @@ void RecursorControlChannel::send(const std::pair& msg, cons strncpy(remoteaddr.sun_path, remote->c_str(), sizeof(remoteaddr.sun_path)-1); remoteaddr.sun_path[sizeof(remoteaddr.sun_path)-1] = '\0'; - if(::sendto(d_fd, &msg.first, sizeof(msg.first), 0, (struct sockaddr*) &remoteaddr, sizeof(remoteaddr) ) < 0) + if(::sendto(d_fd, &msg.d_ret, sizeof(msg.d_ret), 0, (struct sockaddr*) &remoteaddr, sizeof(remoteaddr) ) < 0) throw PDNSException("Unable to send message over control channel '"+string(remoteaddr.sun_path)+"': "+stringerror()); - if(::sendto(d_fd, msg.second.c_str(), msg.second.length(), 0, (struct sockaddr*) &remoteaddr, sizeof(remoteaddr) ) < 0) + if(::sendto(d_fd, msg.d_str.c_str(), msg.d_str.length(), 0, (struct sockaddr*) &remoteaddr, sizeof(remoteaddr) ) < 0) throw PDNSException("Unable to send message over control channel '"+string(remoteaddr.sun_path)+"': "+stringerror()); } else { - if(::send(d_fd, &msg.first, sizeof(msg.first), 0) < 0) + if(::send(d_fd, &msg.d_ret, sizeof(msg.d_ret), 0) < 0) throw PDNSException("Unable to send message over control channel: "+stringerror()); - if(::send(d_fd, msg.second.c_str(), msg.second.length(), 0) < 0) + if(::send(d_fd, msg.d_str.c_str(), msg.d_str.length(), 0) < 0) throw PDNSException("Unable to send message over control channel: "+stringerror()); } if (fd != -1) { @@ -213,7 +213,7 @@ void RecursorControlChannel::send(const std::pair& msg, cons } } -std::pair RecursorControlChannel::recv(std::string* remote, unsigned int timeout) +RecursorControlChannel::Answer RecursorControlChannel::recv(std::string* remote, unsigned int timeout) { char buffer[16384]; ssize_t len; @@ -225,10 +225,10 @@ std::pair RecursorControlChannel::recv(std::string* remote, unsigne throw PDNSException("Timeout waiting for answer from control channel"); } int err; - if (ret < 0 || ::recvfrom(d_fd, &err, sizeof(err), 0, (struct sockaddr*)&remoteaddr, &addrlen) < 0) { + if (::recvfrom(d_fd, &err, sizeof(err), 0, (struct sockaddr*)&remoteaddr, &addrlen) != sizeof(err)) { throw PDNSException("Unable to receive return status over control channel: " + stringerror()); } - if (ret < 0 || (len = ::recvfrom(d_fd, buffer, sizeof(buffer), 0, (struct sockaddr*)&remoteaddr, &addrlen)) < 0) { + if ((len = ::recvfrom(d_fd, buffer, sizeof(buffer), 0, (struct sockaddr*)&remoteaddr, &addrlen)) < 0) { throw PDNSException("Unable to receive message over control channel: "+stringerror()); } @@ -236,6 +236,6 @@ std::pair RecursorControlChannel::recv(std::string* remote, unsigne *remote=remoteaddr.sun_path; } - return make_pair(err, string(buffer, buffer+len)); + return {err, string(buffer, buffer + len)}; } diff --git a/pdns/rec_channel.hh b/pdns/rec_channel.hh index 2a03b44666..0b1610827e 100644 --- a/pdns/rec_channel.hh +++ b/pdns/rec_channel.hh @@ -51,11 +51,26 @@ public: uint64_t getStat(const std::string& name); - void send(const std::pair&, const std::string* remote=nullptr, unsigned int timeout=5, int fd = -1); - std::pair recv(std::string* remote=0, unsigned int timeout=5); + struct Answer + { + Answer& operator+=(const Answer& rhs) + { + if (d_ret == 0 && rhs.d_ret != 0) { + d_ret = rhs.d_ret; + } + d_str += rhs.d_str; + return *this; + } + int d_ret{0}; + std::string d_str; + }; + + void send(const Answer&, const std::string* remote = nullptr, unsigned int timeout = 5, int fd = -1); + RecursorControlChannel::Answer recv(std::string* remote = nullptr, unsigned int timeout = 5); int d_fd; static volatile sig_atomic_t stop; + private: struct sockaddr_un d_local; }; @@ -68,9 +83,11 @@ public: } static void nop(void){} typedef void func_t(void); - pair getAnswer(int s, const std::string& question, func_t** func); + + RecursorControlChannel::Answer getAnswer(int s, const std::string& question, func_t** func); }; + enum class StatComponent { API, Carbon, RecControl, SNMP }; struct StatsMapEntry { @@ -101,3 +118,4 @@ void registerAllStats(); void doExitGeneric(bool nicely); void doExit(); void doExitNicely(); +RecursorControlChannel::Answer doQueueReloadLuaScript(vector::const_iterator begin, vector::const_iterator end); diff --git a/pdns/rec_channel_rec.cc b/pdns/rec_channel_rec.cc index b67796292e..dc688835e2 100644 --- a/pdns/rec_channel_rec.cc +++ b/pdns/rec_channel_rec.cc @@ -315,16 +315,19 @@ getfd(int s) msg.msg_iov = io_vector; msg.msg_iovlen = 1; - if (recvmsg(s, &msg, 0) == -1) + if (recvmsg(s, &msg, 0) == -1) { throw PDNSException("recvmsg"); - if ((msg.msg_flags & MSG_TRUNC) || (msg.msg_flags & MSG_CTRUNC)) + } + if ((msg.msg_flags & MSG_TRUNC) || (msg.msg_flags & MSG_CTRUNC)) { throw PDNSException("control message truncated"); + } for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_len == CMSG_LEN(sizeof(int)) && cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) { fd = *(int *)CMSG_DATA(cmsg); + break; } } return fd; @@ -1712,21 +1715,21 @@ static string clearDontThrottleNetmasks(T begin, T end) { } -std::pair RecursorControlParser::getAnswer(int s, const string& question, RecursorControlParser::func_t** command) +RecursorControlChannel::Answer RecursorControlParser::getAnswer(int s, const string& question, RecursorControlParser::func_t** command) { *command=nop; vector words; stringtok(words, question); if(words.empty()) - return make_pair(1, "invalid command\n"); + return {1, "invalid command\n"}; string cmd=toLower(words[0]); vector::const_iterator begin=words.begin()+1, end=words.end(); // should probably have a smart dispatcher here, like auth has if(cmd=="help") - return make_pair(0, + return {0, "add-dont-throttle-names [N...] add names that are not allowed to be throttled\n" "add-dont-throttle-netmasks [N...]\n" " add netmasks that are not allowed to be throttled\n" @@ -1782,53 +1785,53 @@ std::pair RecursorControlParser::getAnswer(int s, const string& que "unload-lua-script unload Lua script\n" "version return Recursor version number\n" "wipe-cache domain0 [domain1] .. wipe domain data from cache\n" -"wipe-cache-typed type domain0 [domain1] .. wipe domain data with qtype from cache\n"); +"wipe-cache-typed type domain0 [domain1] .. wipe domain data with qtype from cache\n"}; if (cmd == "get-all") { - return make_pair(0, getAllStats()); + return {0, getAllStats()}; } if (cmd == "get") { - return make_pair(0, doGet(begin, end)); + return {0, doGet(begin, end)}; } if (cmd == "get-parameter") { - return make_pair(0, doGetParameter(begin, end)); + return {0, doGetParameter(begin, end)}; } if (cmd == "quit") { *command=&doExit; - return make_pair(0, "bye\n"); + return {0, "bye\n"}; } if (cmd == "version") { - return make_pair(0, getPDNSVersion()+"\n"); + return {0, getPDNSVersion()+"\n"}; } if (cmd == "quit-nicely") { *command=&doExitNicely; - return make_pair(0, "bye nicely\n"); + return {0, "bye nicely\n"}; } if (cmd == "dump-cache") { - return make_pair(0, doDumpCache(s)); + return {0, doDumpCache(s)}; } if (cmd == "dump-ednsstatus" || cmd == "dump-edns") { - return make_pair(0, doDumpEDNSStatus(begin, end)); + return {0, doDumpEDNSStatus(begin, end)}; } if (cmd == "dump-nsspeeds") { - return make_pair(0, doDumpNSSpeeds(begin, end)); + return {0, doDumpNSSpeeds(begin, end)}; } if (cmd == "dump-failedservers") { - return make_pair(0, doDumpFailedServers(begin, end)); + return {0, doDumpFailedServers(begin, end)}; } if (cmd == "dump-rpz") { - return make_pair(0, doDumpRPZ(begin, end)); + return {0, doDumpRPZ(begin, end)}; } if (cmd == "dump-throttlemap") { - return make_pair(0, doDumpThrottleMap(begin, end)); + return {0, doDumpThrottleMap(begin, end)}; } if (cmd == "wipe-cache" || cmd == "flushname") { - return make_pair(0, doWipeCache(begin, end, 0xffff)); + return {0, doWipeCache(begin, end, 0xffff)}; } if (cmd == "wipe-cache-typed") { uint16_t qtype = QType::chartocode(begin->c_str()); ++begin; - return make_pair(0, doWipeCache(begin, end, qtype)); + return {0, doWipeCache(begin, end, qtype)}; } if (cmd == "reload-lua-script") { return doQueueReloadLuaScript(begin, end); @@ -1842,20 +1845,20 @@ std::pair RecursorControlParser::getAnswer(int s, const string& que loadRecursorLuaConfig(::arg()["lua-config-file"], delayedLuaThreads); startLuaConfigDelayedThreads(delayedLuaThreads, g_luaconfs.getCopy().generation); g_log< empty; @@ -1865,7 +1868,7 @@ std::pair RecursorControlParser::getAnswer(int s, const string& que if (cmd == "reload-acls") { if (!::arg()["chroot"].empty()) { g_log< RecursorControlParser::getAnswer(int s, const string& que } catch(std::exception& e) { g_log<(nopFunction)); + return {0, broadcastAccFunction(nopFunction)}; } if (cmd == "reload-zones") { if (!::arg()["chroot"].empty()) { g_log< t_servfailremotes, t_largeans extern thread_local std::unique_ptr > > t_queryring, t_servfailqueryring, t_bogusqueryring; extern thread_local std::shared_ptr t_allowFrom; -std::pair doQueueReloadLuaScript(vector::const_iterator begin, vector::const_iterator end); string doTraceRegex(vector::const_iterator begin, vector::const_iterator end); void parseACLs(); extern RecursorStats g_stats;