Skip to content

Commit

Permalink
Merge pull request #11696 from rgacogne/ddist-fix-source-itf
Browse files Browse the repository at this point in the history
dnsdist: Bind to the requested src interface without a src address
  • Loading branch information
rgacogne authored Jun 22, 2022
2 parents f2c5372 + 33363b1 commit f5e76c2
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 32 deletions.
25 changes: 16 additions & 9 deletions pdns/dnsdistdist/dnsdist-backend.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,27 +58,34 @@ bool DownstreamState::reconnect()
}
if (!IsAnyAddress(d_config.remote)) {
fd = SSocket(d_config.remote.sin4.sin_family, SOCK_DGRAM, 0);
if (!IsAnyAddress(d_config.sourceAddr)) {
SSetsockopt(fd, SOL_SOCKET, SO_REUSEADDR, 1);
if (!d_config.sourceItfName.empty()) {

#ifdef SO_BINDTODEVICE
int res = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, d_config.sourceItfName.c_str(), d_config.sourceItfName.length());
if (res != 0) {
infolog("Error setting up the interface on backend socket '%s': %s", d_config.remote.toStringWithPort(), stringerror());
}
#endif
if (!d_config.sourceItfName.empty()) {
int res = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, d_config.sourceItfName.c_str(), d_config.sourceItfName.length());
if (res != 0) {
infolog("Error setting up the interface on backend socket '%s': %s", d_config.remote.toStringWithPort(), stringerror());
}
}
#endif

if (!IsAnyAddress(d_config.sourceAddr)) {
SSetsockopt(fd, SOL_SOCKET, SO_REUSEADDR, 1);
#ifdef IP_BIND_ADDRESS_NO_PORT
if (d_config.ipBindAddrNoPort) {
SSetsockopt(fd, SOL_IP, IP_BIND_ADDRESS_NO_PORT, 1);
}
#endif
SBind(fd, d_config.sourceAddr);
}

try {
SConnect(fd, d_config.remote);
if (sockets.size() > 1) {
(*mplexer.lock())->addReadFD(fd, [](int, boost::any) {});
}
connected = true;
}
catch(const std::runtime_error& error) {
catch (const std::runtime_error& error) {
infolog("Error connecting to new server with address %s: %s", d_config.remote.toStringWithPort(), error.what());
connected = false;
break;
Expand Down
13 changes: 7 additions & 6 deletions pdns/dnsdistdist/dnsdist-discovery.cc
Original file line number Diff line number Diff line change
Expand Up @@ -254,19 +254,20 @@ bool ServiceDiscovery::getDiscoveredConfig(const UpgradeableBackend& upgradeable

Socket sock(addr.sin4.sin_family, SOCK_STREAM);
sock.setNonBlocking();

#ifdef SO_BINDTODEVICE
if (!backend->d_config.sourceItfName.empty()) {
setsockopt(sock.getHandle(), SOL_SOCKET, SO_BINDTODEVICE, backend->d_config.sourceItfName.c_str(), backend->d_config.sourceItfName.length());
}
#endif

if (!IsAnyAddress(backend->d_config.sourceAddr)) {
sock.setReuseAddr();
#ifdef IP_BIND_ADDRESS_NO_PORT
if (backend->d_config.ipBindAddrNoPort) {
SSetsockopt(sock.getHandle(), SOL_IP, IP_BIND_ADDRESS_NO_PORT, 1);
}
#endif

if (!backend->d_config.sourceItfName.empty()) {
#ifdef SO_BINDTODEVICE
setsockopt(sock.getHandle(), SOL_SOCKET, SO_BINDTODEVICE, backend->d_config.sourceItfName.c_str(), backend->d_config.sourceItfName.length());
#endif
}
sock.bind(backend->d_config.sourceAddr);
}
sock.connect(addr, backend->d_config.tcpConnectTimeout);
Expand Down
19 changes: 10 additions & 9 deletions pdns/dnsdistdist/dnsdist-healthchecks.cc
Original file line number Diff line number Diff line change
Expand Up @@ -368,22 +368,23 @@ bool queueHealthCheck(std::unique_ptr<FDMultiplexer>& mplexer, const std::shared
Socket sock(ds->d_config.remote.sin4.sin_family, ds->doHealthcheckOverTCP() ? SOCK_STREAM : SOCK_DGRAM);

sock.setNonBlocking();

#ifdef SO_BINDTODEVICE
if (!ds->d_config.sourceItfName.empty()) {
int res = setsockopt(sock.getHandle(), SOL_SOCKET, SO_BINDTODEVICE, ds->d_config.sourceItfName.c_str(), ds->d_config.sourceItfName.length());
if (res != 0 && g_verboseHealthChecks) {
infolog("Error setting SO_BINDTODEVICE on the health check socket for backend '%s': %s", ds->getNameWithAddr(), stringerror());
}
}
#endif

if (!IsAnyAddress(ds->d_config.sourceAddr)) {
sock.setReuseAddr();
#ifdef IP_BIND_ADDRESS_NO_PORT
if (ds->d_config.ipBindAddrNoPort) {
SSetsockopt(sock.getHandle(), SOL_IP, IP_BIND_ADDRESS_NO_PORT, 1);
}
#endif

if (!ds->d_config.sourceItfName.empty()) {
#ifdef SO_BINDTODEVICE
int res = setsockopt(sock.getHandle(), SOL_SOCKET, SO_BINDTODEVICE, ds->d_config.sourceItfName.c_str(), ds->d_config.sourceItfName.length());
if (res != 0 && g_verboseHealthChecks) {
infolog("Error setting SO_BINDTODEVICE on the health check socket for backend '%s': %s", ds->getNameWithAddr(), stringerror());
}
#endif
}
sock.bind(ds->d_config.sourceAddr);
}

Expand Down
18 changes: 10 additions & 8 deletions pdns/dnsdistdist/dnsdist-tcp-downstream.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,23 +76,25 @@ bool ConnectionToBackend::reconnect()
auto socket = std::make_unique<Socket>(d_ds->d_config.remote.sin4.sin_family, SOCK_STREAM, 0);
DEBUGLOG("result of socket() is "<<socket->getHandle());

#ifdef SO_BINDTODEVICE
if (!d_ds->d_config.sourceItfName.empty()) {
int res = setsockopt(socket->getHandle(), SOL_SOCKET, SO_BINDTODEVICE, d_ds->d_config.sourceItfName.c_str(), d_ds->d_config.sourceItfName.length());
if (res != 0) {
vinfolog("Error setting up the interface on backend TCP socket '%s': %s", d_ds->getNameWithAddr(), stringerror());
}
}
#endif

if (!IsAnyAddress(d_ds->d_config.sourceAddr)) {
SSetsockopt(socket->getHandle(), SOL_SOCKET, SO_REUSEADDR, 1);
#ifdef IP_BIND_ADDRESS_NO_PORT
if (d_ds->d_config.ipBindAddrNoPort) {
SSetsockopt(socket->getHandle(), SOL_IP, IP_BIND_ADDRESS_NO_PORT, 1);
}
#endif
#ifdef SO_BINDTODEVICE
if (!d_ds->d_config.sourceItfName.empty()) {
int res = setsockopt(socket->getHandle(), SOL_SOCKET, SO_BINDTODEVICE, d_ds->d_config.sourceItfName.c_str(), d_ds->d_config.sourceItfName.length());
if (res != 0) {
vinfolog("Error setting up the interface on backend TCP socket '%s': %s", d_ds->getNameWithAddr(), stringerror());
}
}
#endif
socket->bind(d_ds->d_config.sourceAddr, false);
}

socket->setNonBlocking();

gettimeofday(&d_connectionStartTime, nullptr);
Expand Down

0 comments on commit f5e76c2

Please sign in to comment.