From b33f09f1989e938c503142a38c556df94254443a 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. --- 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 1addf7583d..9ec50e3a5a 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