From: Charles-Henri Bruyand Date: Mon, 20 Mar 2023 13:43:49 +0000 (+0100) Subject: auth: allow multiple blocks of ips in ifportup() X-Git-Tag: auth-4.8.0-beta1~9^2~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6c8714d2a73180eb0ea08a39edf3b7c95dde29dc;p=thirdparty%2Fpdns.git auth: allow multiple blocks of ips in ifportup() --- diff --git a/pdns/lua-record.cc b/pdns/lua-record.cc index 5665bdbbd0..b4810b4cf5 100644 --- a/pdns/lua-record.cc +++ b/pdns/lua-record.cc @@ -548,13 +548,13 @@ static vector convComboAddressListToString(const vector& i return result; } -static vector convComboAddressList(const iplist_t& items) +static vector convComboAddressList(const iplist_t& items, uint16_t port=0) { vector result; result.reserve(items.size()); for(const auto& item : items) { - result.emplace_back(ComboAddress(item.second)); + result.emplace_back(ComboAddress(item.second, port)); } return result; @@ -832,33 +832,51 @@ static void setupLuaRecords(LuaContext& lua) * * @example ifportup(443, { '1.2.3.4', '5.4.3.2' })" */ - lua.writeFunction("ifportup", [](int port, const vector >& ips, const boost::optional> options) { - vector candidates, unavailables; + lua.writeFunction("ifportup", [](int port, const boost::variant& ips, const boost::optional> options) { + vector> candidates; opts_t opts; - vector conv; std::string selector; + if (port < 0) { + port = 0; + } + if (port > std::numeric_limits::max()) { + port = std::numeric_limits::max(); + } if(options) opts = *options; - for(const auto& i : ips) { - ComboAddress rem(i.second, port); - if(g_up.isUp(rem, opts)) { - candidates.push_back(rem); + + if(auto simple = boost::get(&ips)) { + vector unit = convComboAddressList(*simple, port); + candidates.push_back(unit); + } else { + auto units = boost::get(ips); + for(const auto& u : units) { + vector unit = convComboAddressList(u.second, port); + candidates.push_back(unit); + } + } + + for(const auto& unit : candidates) { + vector available; + for(const auto& c : unit) { + if(g_up.isUp(c, opts)) { + available.push_back(c); + } } - else { - unavailables.push_back(rem); + if(!available.empty()) { + vector res = useSelector(getOptionValue(options, "selector", "random"), s_lua_record_ctx->bestwho, available); + return convComboAddressListToString(res); } } - if(!candidates.empty()) { - // use regular selector - selector = getOptionValue(options, "selector", "random"); - } else { - // All units are down, apply backupSelector on all candidates - candidates = std::move(unavailables); - selector = getOptionValue(options, "backupSelector", "random"); + + // All units down, apply backupSelector on all candidates + vector unavailable{}; + for(const auto& unit : candidates) { + unavailable.insert(unavailable.end(), unit.begin(), unit.end()); } - vector res = useSelector(selector, s_lua_record_ctx->bestwho, candidates); + vector res = useSelector(getOptionValue(options, "backupSelector", "random"), s_lua_record_ctx->bestwho, unavailable); return convComboAddressListToString(res); });