From c3c6055e70c7aaed88e440700ffd200acb6d2e30 Mon Sep 17 00:00:00 2001 From: Patrick J Volkerding Date: Fri, 6 Mar 2020 22:10:25 +0000 Subject: Fri Mar 6 22:10:25 UTC 2020 a/cryptsetup-2.3.0-x86_64-2.txz: Rebuilt. Include some additional documentation. Thanks to regdub. a/sdparm-1.11-x86_64-1.txz: Upgraded. ap/moc-2.5.2-x86_64-6.txz: Rebuilt. Fixed docs permissions. Thanks to regdub. l/glib-networking-2.64.0-x86_64-1.txz: Upgraded. l/glib2-2.64.0-x86_64-1.txz: Upgraded. l/gvfs-1.44.0-x86_64-1.txz: Upgraded. l/libnl-1.1.4-x86_64-3.txz: Rebuilt. Fixed docs permissions. Thanks to regdub. l/tdb-1.4.3-x86_64-3.txz: Rebuilt. Fixed docs permissions. Thanks to regdub. l/tevent-0.10.2-x86_64-3.txz: Rebuilt. Fixed docs permissions. Thanks to regdub. n/bind-9.16.0-x86_64-3.txz: Rebuilt. Applied upstream patch to fix a discrepancy in the quota code that can result in a situation where the count is not properly decremented in some cases. n/dovecot-2.3.10-x86_64-1.txz: Upgraded. n/rp-pppoe-3.13-x86_64-2.txz: Rebuilt. This needed a rebuild for ppp-2.4.8. Thanks to regdub. x/libinput-1.15.3-x86_64-1.txz: Upgraded. testing/packages/PAM/dovecot-2.3.10-x86_64-1_pam.txz: Upgraded. --- source/n/bind/bind-v9.16.0-tcp_quota_fix.patch | 341 +++++++++++++++++++++++++ source/n/bind/bind.SlackBuild | 4 +- 2 files changed, 344 insertions(+), 1 deletion(-) create mode 100644 source/n/bind/bind-v9.16.0-tcp_quota_fix.patch (limited to 'source/n/bind') diff --git a/source/n/bind/bind-v9.16.0-tcp_quota_fix.patch b/source/n/bind/bind-v9.16.0-tcp_quota_fix.patch new file mode 100644 index 00000000..bad95ddd --- /dev/null +++ b/source/n/bind/bind-v9.16.0-tcp_quota_fix.patch @@ -0,0 +1,341 @@ +diff --git a/lib/isc/netmgr/netmgr-int.h b/lib/isc/netmgr/netmgr-int.h +index ae83f943d3..c85065f39d 100644 +--- a/lib/isc/netmgr/netmgr-int.h ++++ b/lib/isc/netmgr/netmgr-int.h +@@ -356,7 +356,16 @@ struct isc_nmsocket { + */ + isc_quota_t *quota; + isc_quota_t *pquota; +- bool overquota; ++ ++ /*% ++ * How many connections we have not accepted due to quota? ++ * When we close a connection we need to accept a new one. ++ */ ++ int overquota; ++ /*% ++ * How many active connections we have? ++ */ ++ int conns; + + /*% + * Socket statistics +diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c +index f4361575cc..26728c1ba6 100644 +--- a/lib/isc/netmgr/netmgr.c ++++ b/lib/isc/netmgr/netmgr.c +@@ -727,6 +727,11 @@ nmsocket_cleanup(isc_nmsocket_t *sock, bool dofree) + for (int i = 0; i < sock->nchildren; i++) { + if (!atomic_load(&sock->children[i].destroying)) { + nmsocket_cleanup(&sock->children[i], false); ++ if (sock->statsindex != NULL) { ++ isc__nm_decstats( ++ sock->mgr, ++ sock->statsindex[STATID_ACTIVE]); ++ } + } + } + +@@ -738,6 +743,9 @@ nmsocket_cleanup(isc_nmsocket_t *sock, bool dofree) + sock->children = NULL; + sock->nchildren = 0; + } ++ if (sock->statsindex != NULL) { ++ isc__nm_decstats(sock->mgr, sock->statsindex[STATID_ACTIVE]); ++ } + + if (sock->tcphandle != NULL) { + isc_nmhandle_unref(sock->tcphandle); +@@ -854,8 +862,6 @@ isc__nmsocket_prep_destroy(isc_nmsocket_t *sock) + if (sock->children != NULL) { + for (int i = 0; i < sock->nchildren; i++) { + atomic_store(&sock->children[i].active, false); +- isc__nm_decstats(sock->mgr, +- sock->statsindex[STATID_ACTIVE]); + } + } + +diff --git a/lib/isc/netmgr/tcp.c b/lib/isc/netmgr/tcp.c +index a83fede0d2..58ffd3c404 100644 +--- a/lib/isc/netmgr/tcp.c ++++ b/lib/isc/netmgr/tcp.c +@@ -26,12 +26,28 @@ + #include + #include + #include ++#include + #include + #include + + #include "netmgr-int.h" + #include "uv-compat.h" + ++static atomic_uint_fast32_t last_tcpquota_log = ATOMIC_VAR_INIT(0); ++ ++static bool ++can_log_tcp_quota() { ++ isc_stdtime_t now, last; ++ ++ isc_stdtime_get(&now); ++ last = atomic_exchange_relaxed(&last_tcpquota_log, now); ++ if (now != last) { ++ return (true); ++ } ++ ++ return (false); ++} ++ + static int + tcp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req); + +@@ -668,9 +684,6 @@ read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) + } + + isc__nm_free_uvbuf(sock, buf); +- if (sock->quota) { +- isc_quota_detach(&sock->quota); +- } + + /* + * This might happen if the inner socket is closing. It means that +@@ -699,6 +712,7 @@ accept_connection(isc_nmsocket_t *ssock) + struct sockaddr_storage ss; + isc_sockaddr_t local; + int r; ++ bool overquota = false; + + REQUIRE(VALID_NMSOCK(ssock)); + REQUIRE(ssock->tid == isc_nm_tid()); +@@ -711,10 +725,25 @@ accept_connection(isc_nmsocket_t *ssock) + + if (ssock->pquota != NULL) { + result = isc_quota_attach(ssock->pquota, "a); ++ ++ /* ++ * We share the quota between all TCP sockets. Others ++ * may have used up all the quota slots, in which case ++ * this socket could starve. So we only fail here if we ++ * already had at least one active connection on this ++ * socket. This guarantees that we'll maintain some level ++ * of service while over quota, and will resume normal ++ * service when the quota comes back down. ++ */ + if (result != ISC_R_SUCCESS) { +- isc__nm_incstats(ssock->mgr, +- ssock->statsindex[STATID_ACCEPTFAIL]); +- return (result); ++ ssock->overquota++; ++ overquota = true; ++ if (ssock->conns > 0) { ++ isc__nm_incstats( ++ ssock->mgr, ++ ssock->statsindex[STATID_ACCEPTFAIL]); ++ return (result); ++ } + } + } + +@@ -761,6 +790,7 @@ accept_connection(isc_nmsocket_t *ssock) + } + + isc_nmsocket_attach(ssock, &csock->server); ++ ssock->conns++; + + handle = isc__nmhandle_get(csock, NULL, &local); + +@@ -779,6 +809,9 @@ error: + if (csock->quota != NULL) { + isc_quota_detach(&csock->quota); + } ++ if (overquota) { ++ ssock->overquota--; ++ } + /* We need to detach it properly to make sure uv_close is called. */ + isc_nmsocket_detach(&csock); + return (result); +@@ -793,14 +826,14 @@ tcp_connection_cb(uv_stream_t *server, int status) + UNUSED(status); + + result = accept_connection(ssock); +- if (result != ISC_R_SUCCESS) { +- if (result == ISC_R_QUOTA || result == ISC_R_SOFTQUOTA) { +- ssock->overquota = true; ++ if (result != ISC_R_SUCCESS && result != ISC_R_NOCONN) { ++ if ((result != ISC_R_QUOTA && result != ISC_R_SOFTQUOTA) || ++ can_log_tcp_quota()) { ++ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ++ ISC_LOGMODULE_NETMGR, ISC_LOG_ERROR, ++ "TCP connection failed: %s", ++ isc_result_totext(result)); + } +- isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, +- ISC_LOGMODULE_NETMGR, ISC_LOG_ERROR, +- "TCP connection failed: %s", +- isc_result_totext(result)); + } + } + +@@ -936,17 +969,27 @@ tcp_close_direct(isc_nmsocket_t *sock) + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(sock->tid == isc_nm_tid()); + REQUIRE(sock->type == isc_nm_tcpsocket); ++ isc_nmsocket_t *ssock = sock->server; + + if (sock->quota != NULL) { +- isc_nmsocket_t *ssock = sock->server; +- + isc_quota_detach(&sock->quota); +- +- if (ssock->overquota) { ++ } ++ if (ssock != NULL) { ++ ssock->conns--; ++ while (ssock->conns == 0 && ssock->overquota > 0) { ++ ssock->overquota--; + isc_result_t result = accept_connection(ssock); +- if (result != ISC_R_QUOTA && +- result != ISC_R_SOFTQUOTA) { +- ssock->overquota = false; ++ if (result == ISC_R_SUCCESS || result == ISC_R_NOCONN) { ++ continue; ++ } ++ if ((result != ISC_R_QUOTA && ++ result != ISC_R_SOFTQUOTA) || ++ can_log_tcp_quota()) { ++ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ++ ISC_LOGMODULE_NETMGR, ++ ISC_LOG_ERROR, ++ "TCP connection failed: %s", ++ isc_result_totext(result)); + } + } + } +diff --git a/lib/isc/netmgr/tcpdns.c b/lib/isc/netmgr/tcpdns.c +index e384b73be9..f89eb359af 100644 +--- a/lib/isc/netmgr/tcpdns.c ++++ b/lib/isc/netmgr/tcpdns.c +@@ -43,6 +43,9 @@ dnslisten_readcb(isc_nmhandle_t *handle, isc_region_t *region, void *arg); + static void + resume_processing(void *arg); + ++static void ++tcpdns_close_direct(isc_nmsocket_t *sock); ++ + static inline size_t + dnslen(unsigned char *base) + { +@@ -82,7 +85,6 @@ timer_close_cb(uv_handle_t *handle) + { + isc_nmsocket_t *sock = (isc_nmsocket_t *)uv_handle_get_data(handle); + INSIST(VALID_NMSOCK(sock)); +- atomic_store(&sock->closed, true); + isc_nmsocket_detach(&sock); + } + +@@ -94,9 +96,7 @@ dnstcp_readtimeout(uv_timer_t *timer) + + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(sock->tid == isc_nm_tid()); +- +- isc_nmsocket_detach(&sock->outer); +- uv_close((uv_handle_t *)&sock->timer, timer_close_cb); ++ tcpdns_close_direct(sock); + } + + /* +@@ -252,7 +252,9 @@ dnslisten_readcb(isc_nmhandle_t *handle, isc_region_t *region, void *arg) + * We have a packet: stop timeout timers + */ + atomic_store(&dnssock->outer->processing, true); +- uv_timer_stop(&dnssock->timer); ++ if (dnssock->timer_initialized) { ++ uv_timer_stop(&dnssock->timer); ++ } + + if (atomic_load(&dnssock->sequential)) { + /* +@@ -399,8 +401,10 @@ resume_processing(void *arg) + if (atomic_load(&sock->ah) == 0) { + /* Nothing is active; sockets can timeout now */ + atomic_store(&sock->outer->processing, false); +- uv_timer_start(&sock->timer, dnstcp_readtimeout, +- sock->read_timeout, 0); ++ if (sock->timer_initialized) { ++ uv_timer_start(&sock->timer, dnstcp_readtimeout, ++ sock->read_timeout, 0); ++ } + } + + /* +@@ -413,7 +417,9 @@ resume_processing(void *arg) + result = processbuffer(sock, &handle); + if (result == ISC_R_SUCCESS) { + atomic_store(&sock->outer->processing, true); +- uv_timer_stop(&sock->timer); ++ if (sock->timer_initialized) { ++ uv_timer_stop(&sock->timer); ++ } + isc_nmhandle_unref(handle); + } else if (sock->outer != NULL) { + isc_nm_resumeread(sock->outer); +@@ -441,7 +447,9 @@ resume_processing(void *arg) + break; + } + +- uv_timer_stop(&sock->timer); ++ if (sock->timer_initialized) { ++ uv_timer_stop(&sock->timer); ++ } + atomic_store(&sock->outer->processing, true); + isc_nmhandle_unref(dnshandle); + } while (atomic_load(&sock->ah) < TCPDNS_CLIENTS_PER_CONN); +@@ -507,18 +515,29 @@ static void + tcpdns_close_direct(isc_nmsocket_t *sock) + { + REQUIRE(sock->tid == isc_nm_tid()); +- if (sock->outer != NULL) { +- sock->outer->rcb.recv = NULL; +- isc_nmsocket_detach(&sock->outer); +- } +- if (sock->listener != NULL) { +- isc_nmsocket_detach(&sock->listener); +- } + /* We don't need atomics here, it's all in single network thread */ + if (sock->timer_initialized) { ++ /* ++ * We need to fire the timer callback to clean it up, ++ * it will then call us again (via detach) so that we ++ * can finally close the socket. ++ */ + sock->timer_initialized = false; + uv_timer_stop(&sock->timer); + uv_close((uv_handle_t *)&sock->timer, timer_close_cb); ++ } else { ++ /* ++ * At this point we're certain that there are no external ++ * references, we can close everything. ++ */ ++ if (sock->outer != NULL) { ++ sock->outer->rcb.recv = NULL; ++ isc_nmsocket_detach(&sock->outer); ++ } ++ if (sock->listener != NULL) { ++ isc_nmsocket_detach(&sock->listener); ++ } ++ atomic_store(&sock->closed, true); + } + } + +diff --git a/lib/isc/netmgr/uverr2result.c b/lib/isc/netmgr/uverr2result.c +index b6a8065e3e..9781454ca6 100644 +--- a/lib/isc/netmgr/uverr2result.c ++++ b/lib/isc/netmgr/uverr2result.c +@@ -38,6 +38,8 @@ isc___nm_uverr2result(int uverr, bool dolog, const char *file, + return (ISC_R_INVALIDFILE); + case UV_ENOENT: + return (ISC_R_FILENOTFOUND); ++ case UV_EAGAIN: ++ return (ISC_R_NOCONN); + case UV_EACCES: + case UV_EPERM: + return (ISC_R_NOPERM); diff --git a/source/n/bind/bind.SlackBuild b/source/n/bind/bind.SlackBuild index 593664e1..fdf021ac 100755 --- a/source/n/bind/bind.SlackBuild +++ b/source/n/bind/bind.SlackBuild @@ -24,7 +24,7 @@ cd $(dirname $0) ; CWD=$(pwd) PKGNAM=bind VERSION=${VERSION:-$(echo ${PKGNAM}-[0-9]*.tar.?z | rev | cut -f 3- -d . | cut -f 1 -d - | rev)} -BUILD=${BUILD:-2} +BUILD=${BUILD:-3} # Automatically determine the architecture we're building on: if [ -z "$ARCH" ]; then @@ -82,6 +82,8 @@ else GSSAPI=" " fi +zcat $CWD/bind-v9.16.0-tcp_quota_fix.patch.gz | patch -p1 --verbose || exit 1 + # Configure: CFLAGS="$SLKCFLAGS" \ ./configure \ -- cgit v1.2.3