From 407b37c3f21f03d8148a652cd026ca6939da3517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Mon, 25 Apr 2022 14:09:44 +0200 Subject: [PATCH] Set IP(V6)_RECVERR on connect UDP sockets (via libuv) The connect()ed UDP socket provides feedback on a variety of ICMP errors (eg port unreachable) which bind can then use to decide what to do with errors (report them to the client, try again with a different nameserver etc). However, Linux's implementation does not report what it considers "transient" conditions, which is defined as Destination host Unreachable, Destination network unreachable, Source Route Failed and Message Too Big. Explicitly enable IP_RECVERR / IPV6_RECVERR (via libuv uv_udp_bind() flag) to learn about ICMP destination network/host unreachable. --- configure.ac | 3 +++ lib/isc/netmgr/udp.c | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/configure.ac b/configure.ac index 072f535a84..9b29cb4901 100644 --- a/configure.ac +++ b/configure.ac @@ -562,6 +562,9 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include ], [AC_MSG_RESULT([no]) AC_CHECK_DECLS([UV_UDP_RECVMMSG], [], [], [[#include ]])]) +# libuv recverr support +AC_CHECK_DECLS([UV_UDP_LINUX_RECVERR], [], [], [[#include ]]) + # [pairwise: --enable-doh --with-libnghttp2=auto, --enable-doh --with-libnghttp2=yes, --disable-doh] AC_ARG_ENABLE([doh], [AS_HELP_STRING([--disable-doh], [enable DNS over HTTPS, requires libnghttp2 (default=yes)])], diff --git a/lib/isc/netmgr/udp.c b/lib/isc/netmgr/udp.c index 4c0848fdea..29a603a0dd 100644 --- a/lib/isc/netmgr/udp.c +++ b/lib/isc/netmgr/udp.c @@ -882,6 +882,10 @@ udp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) { uv_bind_flags |= UV_UDP_IPV6ONLY; } +#if HAVE_DECL_UV_UDP_LINUX_RECVERR + uv_bind_flags |= UV_UDP_LINUX_RECVERR; +#endif + r = uv_udp_bind(&sock->uv_handle.udp, &sock->iface.type.sa, uv_bind_flags); if (r != 0) {