From: Remi Gacogne Date: Wed, 2 Oct 2019 13:37:35 +0000 (+0200) Subject: dnsdist: Use SO_BINDTODEVICE when available for newServer's source itf X-Git-Tag: dnsdist-1.4.0-rc4~27^2~7 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=70b0d0e296d2e67cabd2654d394b312de1126cea;p=pdns dnsdist: Use SO_BINDTODEVICE when available for newServer's source itf --- diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index 04c08ca21..07a6ec1df 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -195,6 +195,7 @@ void setupLuaConfig(bool client) } ComboAddress sourceAddr; + std::string sourceItfName; unsigned int sourceItf = 0; size_t numberOfSockets = 1; std::set cpus; @@ -224,8 +225,8 @@ void setupLuaConfig(bool client) if (parsed == false) { /* try to parse as interface name, or v4/v6@itf */ - string itfName = source.substr(pos == std::string::npos ? 0 : pos + 1); - unsigned int itfIdx = if_nametoindex(itfName.c_str()); + string sourceItfName = source.substr(pos == std::string::npos ? 0 : pos + 1); + unsigned int itfIdx = if_nametoindex(sourceItfName.c_str()); if (itfIdx != 0) { if (pos == 0 || pos == std::string::npos) { @@ -240,7 +241,7 @@ void setupLuaConfig(bool client) } else { - warnlog("Dismissing source %s because '%s' is not a valid interface name", source, itfName); + warnlog("Dismissing source %s because '%s' is not a valid interface name", source, sourceItfName); } } } @@ -257,7 +258,7 @@ void setupLuaConfig(bool client) // do not construct DownstreamState now, it would try binding sockets. return ret; } - ret=std::make_shared(serverAddr, sourceAddr, sourceItf, numberOfSockets); + ret=std::make_shared(serverAddr, sourceAddr, sourceItf, sourceItfName, numberOfSockets); if(vars.count("qps")) { int qpsVal=std::stoi(boost::get(vars["qps"])); diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index 1c3f54a62..c55002476 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -702,6 +702,15 @@ bool DownstreamState::reconnect() fd = SSocket(remote.sin4.sin_family, SOCK_DGRAM, 0); if (!IsAnyAddress(sourceAddr)) { SSetsockopt(fd, SOL_SOCKET, SO_REUSEADDR, 1); + if (!sourceItfName.empty()) { +#ifdef SO_BINDTODEVICE + int res = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, sourceItfName.c_str(), sourceItfName.length()); + if (res != 0) { + infolog("Error setting up the interface on backend socket '%s': %s", remote.toStringWithPort(), stringerror()); + } +#endif + } + SBind(fd, sourceAddr); } try { @@ -773,7 +782,7 @@ void DownstreamState::setWeight(int newWeight) } } -DownstreamState::DownstreamState(const ComboAddress& remote_, const ComboAddress& sourceAddr_, unsigned int sourceItf_, size_t numberOfSockets): remote(remote_), sourceAddr(sourceAddr_), sourceItf(sourceItf_) +DownstreamState::DownstreamState(const ComboAddress& remote_, const ComboAddress& sourceAddr_, unsigned int sourceItf_, const std::string& sourceItfName_, size_t numberOfSockets): sourceItfName(sourceItfName_), remote(remote_), sourceAddr(sourceAddr_), sourceItf(sourceItf_) { pthread_rwlock_init(&d_lock, nullptr); id = getUniqueID(); diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index e654b9e15..fa7349a19 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -824,8 +824,8 @@ struct DownstreamState { typedef std::function(const DNSName&, uint16_t, uint16_t, dnsheader*)> checkfunc_t; - DownstreamState(const ComboAddress& remote_, const ComboAddress& sourceAddr_, unsigned int sourceItf, size_t numberOfSockets); - DownstreamState(const ComboAddress& remote_): DownstreamState(remote_, ComboAddress(), 0, 1) {} + DownstreamState(const ComboAddress& remote_, const ComboAddress& sourceAddr_, unsigned int sourceItf, const std::string& sourceItfName, size_t numberOfSockets); + DownstreamState(const ComboAddress& remote_): DownstreamState(remote_, ComboAddress(), 0, std::string(), 1) {} ~DownstreamState() { for (auto& fd : sockets) { @@ -839,6 +839,7 @@ struct DownstreamState std::set hashes; mutable pthread_rwlock_t d_lock; std::vector sockets; + const std::string sourceItfName; std::mutex socketsLock; std::mutex connectLock; std::unique_ptr mplexer{nullptr};