* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+
+// for OpenBSD, sys/socket.h needs to come before net/if.h
+#include <sys/socket.h>
+#include <net/if.h>
+
#include <boost/format.hpp>
#include "config.h"
}
#endif /* HAVE_XSK */
+bool DownstreamState::parseSourceParameter(const std::string& source, DownstreamState::Config& config)
+{
+ /* handle source in the following forms:
+ - v4 address ("192.0.2.1")
+ - v6 address ("2001:DB8::1")
+ - interface name ("eth0")
+ - v4 address and interface name ("192.0.2.1@eth0")
+ - v6 address and interface name ("2001:DB8::1@eth0")
+ */
+ std::string::size_type pos = source.find('@');
+ if (pos == std::string::npos) {
+ /* no '@', try to parse that as a valid v4/v6 address */
+ try {
+ config.sourceAddr = ComboAddress(source);
+ return true;
+ }
+ catch (...) {
+ }
+ }
+
+ /* try to parse as interface name, or v4/v6@itf */
+ config.sourceItfName = source.substr(pos == std::string::npos ? 0 : pos + 1);
+ unsigned int itfIdx = if_nametoindex(config.sourceItfName.c_str());
+ if (itfIdx != 0) {
+ if (pos == 0 || pos == std::string::npos) {
+ /* "eth0" or "@eth0" */
+ config.sourceItf = itfIdx;
+ }
+ else {
+ /* "192.0.2.1@eth0" */
+ config.sourceAddr = ComboAddress(source.substr(0, pos));
+ config.sourceItf = itfIdx;
+ }
+#ifdef SO_BINDTODEVICE
+ if (!dnsdist::configuration::isImmutableConfigurationDone()) {
+ /* we need to retain CAP_NET_RAW to be able to set SO_BINDTODEVICE in the health checks */
+ dnsdist::configuration::updateImmutableConfiguration([](dnsdist::configuration::ImmutableConfiguration& currentConfig) {
+ currentConfig.d_capabilitiesToRetain.insert("CAP_NET_RAW");
+ });
+ }
+#endif
+ return true;
+ }
+
+ warnlog("Dismissing source %s because '%s' is not a valid interface name", source, config.sourceItfName);
+ return false;
+}
+
+std::optional<DownstreamState::Availability> DownstreamState::getAvailabilityFromStr(const std::string& mode)
+{
+ if (pdns_iequals(mode, "auto")) {
+ return DownstreamState::Availability::Auto;
+ }
+ if (pdns_iequals(mode, "lazy")) {
+ return DownstreamState::Availability::Lazy;
+ }
+ if (pdns_iequals(mode, "up")) {
+ return DownstreamState::Availability::Up;
+ }
+ if (pdns_iequals(mode, "down")) {
+ return DownstreamState::Availability::Down;
+ }
+ return std::nullopt;
+}
+
size_t ServerPool::countServers(bool upOnly)
{
std::shared_ptr<const ServerPolicy::NumberedServerVector> servers = nullptr;
#include <fstream>
#include <cinttypes>
-// for OpenBSD, sys/socket.h needs to come before net/if.h
-#include <sys/socket.h>
-#include <net/if.h>
-
#include <regex>
#include <sys/types.h>
#include <sys/stat.h>
if (getOptionalValue<std::string>(vars, "healthCheckMode", valueStr) > 0) {
const auto& mode = valueStr;
- if (pdns_iequals(mode, "auto")) {
- config.availability = DownstreamState::Availability::Auto;
- }
- else if (pdns_iequals(mode, "lazy")) {
- config.availability = DownstreamState::Availability::Lazy;
- }
- else if (pdns_iequals(mode, "up")) {
- config.availability = DownstreamState::Availability::Up;
- }
- else if (pdns_iequals(mode, "down")) {
- config.availability = DownstreamState::Availability::Down;
+ auto availability = DownstreamState::getAvailabilityFromStr(mode);
+ if (availability) {
+ config.availability = *availability;
}
else {
warnlog("Ignoring unknown value '%s' for 'healthCheckMode' on 'newServer'", mode);
static void handleNewServerSourceParameter(boost::optional<newserver_t>& vars, DownstreamState::Config& config)
{
std::string source;
- if (getOptionalValue<std::string>(vars, "source", source) > 0) {
- /* handle source in the following forms:
- - v4 address ("192.0.2.1")
- - v6 address ("2001:DB8::1")
- - interface name ("eth0")
- - v4 address and interface name ("192.0.2.1@eth0")
- - v6 address and interface name ("2001:DB8::1@eth0")
- */
- bool parsed = false;
- std::string::size_type pos = source.find('@');
- if (pos == std::string::npos) {
- /* no '@', try to parse that as a valid v4/v6 address */
- try {
- config.sourceAddr = ComboAddress(source);
- parsed = true;
- }
- catch (...) {
- }
- }
-
- if (!parsed) {
- /* try to parse as interface name, or v4/v6@itf */
- config.sourceItfName = source.substr(pos == std::string::npos ? 0 : pos + 1);
- unsigned int itfIdx = if_nametoindex(config.sourceItfName.c_str());
- if (itfIdx != 0) {
- if (pos == 0 || pos == std::string::npos) {
- /* "eth0" or "@eth0" */
- config.sourceItf = itfIdx;
- }
- else {
- /* "192.0.2.1@eth0" */
- config.sourceAddr = ComboAddress(source.substr(0, pos));
- config.sourceItf = itfIdx;
- }
-#ifdef SO_BINDTODEVICE
- /* we need to retain CAP_NET_RAW to be able to set SO_BINDTODEVICE in the health checks */
- dnsdist::configuration::updateImmutableConfiguration([](dnsdist::configuration::ImmutableConfiguration& currentConfig) {
- currentConfig.d_capabilitiesToRetain.insert("CAP_NET_RAW");
- });
-#endif
- }
- else {
- warnlog("Dismissing source %s because '%s' is not a valid interface name", source, config.sourceItfName);
- }
- }
+ if (getOptionalValue<std::string>(vars, "source", source) <= 0) {
+ return;
}
+
+ DownstreamState::parseSourceParameter(source, config);
}
// NOLINTNEXTLINE(readability-function-cognitive-complexity,readability-function-size): this function declares Lua bindings, even with a good refactoring it will likely blow up the threshold