diff --git a/CHANGES b/CHANGES index c612496020..300653d2c1 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +6155. [bug] Treat ISC_R_INVALIDPROTO as a networking error + in the dispatch code to avoid retrying with the + same server. [GL #4005]< + 6154. [func] Add spinlock implementation. The spinlock is much smaller (8 bytes) than pthread_mutex (40 bytes), so it can be easily embedded into objects for more diff --git a/doc/notes/notes-current.rst b/doc/notes/notes-current.rst index 51c5e2d9e6..0d0ada857e 100644 --- a/doc/notes/notes-current.rst +++ b/doc/notes/notes-current.rst @@ -35,14 +35,16 @@ Feature Changes Bug Fixes ~~~~~~~~~ -- None. - - When the same ``notify-source`` address and port number was configured for multiple destinations and zones, an unresponsive server could tie up the socket until it timed out; in the meantime, NOTIFY messages for other servers silently failed.``named`` will now retry these failing messages over TCP. NOTIFY failures are now logged at level INFO. :gl:`#4001` :gl:`#4002` +- When ISC_R_INVALIDPROTO (ENOPROTOOPT, EPROTONOSUPPORT) is returned from + libuv, treat it as a network failure, mark the server as broken and don't + try again. :gl:`#4005` + Known Issues ~~~~~~~~~~~~ diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index e472c6e78e..2564f09de0 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -7791,6 +7791,7 @@ rctx_dispfail(respctx_t *rctx) { case ISC_R_NETUNREACH: case ISC_R_CONNREFUSED: case ISC_R_CONNECTIONRESET: + case ISC_R_INVALIDPROTO: case ISC_R_CANCELED: case ISC_R_SHUTTINGDOWN: rctx->broken_server = rctx->result; diff --git a/lib/isc/include/isc/result.h b/lib/isc/include/isc/result.h index ac7273ce52..215c83aba3 100644 --- a/lib/isc/include/isc/result.h +++ b/lib/isc/include/isc/result.h @@ -95,6 +95,7 @@ typedef enum isc_result { ISC_R_TLSBADPEERCERT, /*%< TLS peer certificate verification failed */ ISC_R_HTTP2ALPNERROR, /*%< ALPN for HTTP/2 failed */ ISC_R_DOTALPNERROR, /*%< ALPN for DoT failed */ + ISC_R_INVALIDPROTO, /*%< invalid protocol */ DNS_R_LABELTOOLONG = 1 << 16, DNS_R_BADESCAPE, diff --git a/lib/isc/result.c b/lib/isc/result.c index b41f760fa4..ac55e0bd46 100644 --- a/lib/isc/result.c +++ b/lib/isc/result.c @@ -94,6 +94,7 @@ static const char *description[ISC_R_NRESULTS] = { [ISC_R_TLSBADPEERCERT] = "TLS peer certificate verification failed", [ISC_R_HTTP2ALPNERROR] = "ALPN for HTTP/2 failed", [ISC_R_DOTALPNERROR] = "ALPN for DoT failed", + [ISC_R_INVALIDPROTO] = "invalid protocol", [DNS_R_LABELTOOLONG] = "label too long", [DNS_R_BADESCAPE] = "bad escape", diff --git a/lib/isc/uv.c b/lib/isc/uv.c index 79c4362479..8b1ef7398e 100644 --- a/lib/isc/uv.c +++ b/lib/isc/uv.c @@ -87,13 +87,15 @@ isc__uverr2result(int uverr, bool dolog, const char *file, unsigned int line, return (ISC_R_MAXSIZE); case UV_ENOTSUP: return (ISC_R_FAMILYNOSUPPORT); + case UV_ENOPROTOOPT: + case UV_EPROTONOSUPPORT: + return (ISC_R_INVALIDPROTO); default: if (dolog) { - UNEXPECTED_ERROR( - file, line, - "unable to convert libuv " - "error code in %s to isc_result: %d: %s", - func, uverr, uv_strerror(uverr)); + UNEXPECTED_ERROR("unable to convert libuv error code " + "in %s (%s:%d) to isc_result: %d: %s", + func, file, line, uverr, + uv_strerror(uverr)); } return (ISC_R_UNEXPECTED); }