From fcb6534d7525ee01ce293cedca9ddc35a5852fa8 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 15 May 2023 14:10:55 +0200 Subject: [PATCH] dnsdist: Stop setting SO_REUSEADDR on outgoing UDP client sockets `SO_REUSEADDR` is useful on TCP server sockets to allow binding quickly after restarting the process without waiting `TIME_WAIT` seconds, or to allow some port reuse on BSD. It also allows reusing a port more quickly for TCP client sockets. For UDP sockets, however, Linux allows two sockets to be bound to the same address and port, and will distribute all packets to the most recent socket, which is very unexpected, to say the least. (cherry picked from commit b33f09f1989e938c503142a38c556df94254443a) --- pdns/dnsdistdist/dnsdist-backend.cc | 1 - pdns/dnsdistdist/dnsdist-healthchecks.cc | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-backend.cc b/pdns/dnsdistdist/dnsdist-backend.cc index 9113183c83..cfa6e5c7b6 100644 --- a/pdns/dnsdistdist/dnsdist-backend.cc +++ b/pdns/dnsdistdist/dnsdist-backend.cc @@ -72,7 +72,6 @@ bool DownstreamState::reconnect() #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); diff --git a/pdns/dnsdistdist/dnsdist-healthchecks.cc b/pdns/dnsdistdist/dnsdist-healthchecks.cc index 4a52052276..fc831e6481 100644 --- a/pdns/dnsdistdist/dnsdist-healthchecks.cc +++ b/pdns/dnsdistdist/dnsdist-healthchecks.cc @@ -319,7 +319,9 @@ bool queueHealthCheck(std::unique_ptr& mplexer, const std::shared #endif if (!IsAnyAddress(ds->d_config.sourceAddr)) { - sock.setReuseAddr(); + if (ds->doHealthcheckOverTCP()) { + sock.setReuseAddr(); + } #ifdef IP_BIND_ADDRESS_NO_PORT if (ds->d_config.ipBindAddrNoPort) { SSetsockopt(sock.getHandle(), SOL_IP, IP_BIND_ADDRESS_NO_PORT, 1); -- 2.47.2