}
}
-
static std::string getGeo(const std::string& ip, GeoIPInterface::GeoIPQueryAttribute qa)
{
static bool initialized;
return result;
}
+/**
+ * Reads and unify single or multiple sets of ips :
+ * - {'192.0.2.1', '192.0.2.2'}
+ * - {{'192.0.2.1', '192.0.2.2'}, {'198.51.100.1'}}
+ */
+
+static vector<vector<ComboAddress>> convMultiComboAddressList(const boost::variant<iplist_t, ipunitlist_t>& items, uint16_t port = 0)
+{
+ vector<vector<ComboAddress>> candidates;
+
+ if(auto simple = boost::get<iplist_t>(&items)) {
+ vector<ComboAddress> unit = convComboAddressList(*simple, port);
+ candidates.push_back(unit);
+ } else {
+ auto units = boost::get<ipunitlist_t>(items);
+ for(const auto& u : units) {
+ vector<ComboAddress> unit = convComboAddressList(u.second, port);
+ candidates.push_back(unit);
+ }
+ }
+ return candidates;
+}
+
static vector<string> convStringList(const iplist_t& items)
{
vector<string> result;
static thread_local unique_ptr<lua_record_ctx_t> s_lua_record_ctx;
+static vector<string> genericIfUp(const boost::variant<iplist_t, ipunitlist_t>& ips, boost::optional<opts_t> options, std::function<bool(const ComboAddress&, const opts_t&)> upcheckf, uint16_t port = 0) {
+ vector<vector<ComboAddress> > candidates;
+ opts_t opts;
+ if(options)
+ opts = *options;
+
+ candidates = convMultiComboAddressList(ips, port);
+
+ for(const auto& unit : candidates) {
+ vector<ComboAddress> available;
+ for(const auto& c : unit) {
+ if (upcheckf(c, opts)) {
+ available.push_back(c);
+ }
+ }
+ if(!available.empty()) {
+ vector<ComboAddress> res = useSelector(getOptionValue(options, "selector", "random"), s_lua_record_ctx->bestwho, available);
+ return convComboAddressListToString(res);
+ }
+ }
+
+ // All units down, apply backupSelector on all candidates
+ vector<ComboAddress> ret{};
+ for(const auto& unit : candidates) {
+ ret.insert(ret.end(), unit.begin(), unit.end());
+ }
+
+ vector<ComboAddress> res = useSelector(getOptionValue(options, "backupSelector", "random"), s_lua_record_ctx->bestwho, ret);
+ return convComboAddressListToString(res);
+}
+
static void setupLuaRecords(LuaContext& lua)
{
lua.writeFunction("latlon", []() {
* @example ifportup(443, { '1.2.3.4', '5.4.3.2' })"
*/
lua.writeFunction("ifportup", [](int port, const boost::variant<iplist_t, ipunitlist_t>& ips, const boost::optional<std::unordered_map<string,string>> options) {
- vector<vector<ComboAddress>> candidates;
- opts_t opts;
- std::string selector;
-
if (port < 0) {
port = 0;
}
if (port > std::numeric_limits<uint16_t>::max()) {
port = std::numeric_limits<uint16_t>::max();
}
- if(options)
- opts = *options;
-
- if(auto simple = boost::get<iplist_t>(&ips)) {
- vector<ComboAddress> unit = convComboAddressList(*simple, port);
- candidates.push_back(unit);
- } else {
- auto units = boost::get<ipunitlist_t>(ips);
- for(const auto& u : units) {
- vector<ComboAddress> unit = convComboAddressList(u.second, port);
- candidates.push_back(unit);
- }
- }
-
- for(const auto& unit : candidates) {
- vector<ComboAddress> available;
- for(const auto& c : unit) {
- if(g_up.isUp(c, opts)) {
- available.push_back(c);
- }
- }
- if(!available.empty()) {
- vector<ComboAddress> res = useSelector(getOptionValue(options, "selector", "random"), s_lua_record_ctx->bestwho, available);
- return convComboAddressListToString(res);
- }
- }
- // All units down, apply backupSelector on all candidates
- vector<ComboAddress> unavailable{};
- for(const auto& unit : candidates) {
- unavailable.insert(unavailable.end(), unit.begin(), unit.end());
- }
-
- vector<ComboAddress> res = useSelector(getOptionValue(options, "backupSelector", "random"), s_lua_record_ctx->bestwho, unavailable);
- return convComboAddressListToString(res);
+ auto checker = [](const ComboAddress& addr, const opts_t& opts) {
+ return g_up.isUp(addr, opts);
+ };
+ return genericIfUp(ips, options, checker, port);
});
lua.writeFunction("ifurlextup", [](const vector<pair<int, opts_t> >& ipurls, boost::optional<opts_t> options) {
lua.writeFunction("ifurlup", [](const std::string& url,
const boost::variant<iplist_t, ipunitlist_t>& ips,
boost::optional<opts_t> options) {
- vector<vector<ComboAddress> > candidates;
- opts_t opts;
- if(options)
- opts = *options;
- if(auto simple = boost::get<iplist_t>(&ips)) {
- vector<ComboAddress> unit = convComboAddressList(*simple);
- candidates.push_back(unit);
- } else {
- auto units = boost::get<ipunitlist_t>(ips);
- for(const auto& u : units) {
- vector<ComboAddress> unit = convComboAddressList(u.second);
- candidates.push_back(unit);
- }
- }
- for(const auto& unit : candidates) {
- vector<ComboAddress> available;
- for(const auto& c : unit) {
- if(g_up.isUp(c, url, opts)) {
- available.push_back(c);
- }
- }
- if(!available.empty()) {
- vector<ComboAddress> res = useSelector(getOptionValue(options, "selector", "random"), s_lua_record_ctx->bestwho, available);
- return convComboAddressListToString(res);
- }
- }
-
- // All units down, apply backupSelector on all candidates
- vector<ComboAddress> ret{};
- for(const auto& unit : candidates) {
- ret.insert(ret.end(), unit.begin(), unit.end());
- }
-
- vector<ComboAddress> res = useSelector(getOptionValue(options, "backupSelector", "random"), s_lua_record_ctx->bestwho, ret);
- return convComboAddressListToString(res);
+ auto checker = [&url](const ComboAddress& addr, const opts_t& opts) {
+ return g_up.isUp(addr, url, opts);
+ };
+ return genericIfUp(ips, options, checker);
});
/*
* Returns a random IP address from the supplied list