Blame SOURCES/0001-ldap-add-socket-timeout.patch

baad69
From 370bf84857d5674a092f46fa5932a0c92ad5bbf5 Mon Sep 17 00:00:00 2001
baad69
From: Sumit Bose <sbose@redhat.com>
baad69
Date: Wed, 24 Nov 2021 17:25:18 +0100
baad69
Subject: [PATCH] ldap: add socket timeout
baad69
baad69
During the discovery phase realmd tries to open LDAP connections to
baad69
multiple DC addresses returned by DNS. When cleaning up we have to call
baad69
ldap_destroy() to release the resources allocated for the LDAP context.
baad69
ldap_destroy() tries to send a LDAP unbind request independent of the
baad69
connection state. If the related address is block by a firewall or a not
baad69
properly routed IPv6 address there might be no reply on the TCP level
baad69
and the request might be stuck for quite some tome in the kernel.
baad69
baad69
To avoid the unexpected long delays will block realmd this patch lowers
baad69
the timeout considerably to 5s. As multiple other timeouts this value is
baad69
currently hardcoded.
baad69
baad69
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1817869
baad69
---
baad69
 service/realm-ldap.c | 21 +++++++++++++++++++++
baad69
 1 file changed, 21 insertions(+)
baad69
baad69
diff --git a/service/realm-ldap.c b/service/realm-ldap.c
baad69
index bdfb96c..f7b6d13 100644
baad69
--- a/service/realm-ldap.c
baad69
+++ b/service/realm-ldap.c
baad69
@@ -22,6 +22,7 @@
baad69
 #include <sys/types.h>
baad69
 #include <sys/socket.h>
baad69
 #include <netinet/in.h>
baad69
+#include <netinet/tcp.h>
baad69
 
baad69
 #include <errno.h>
baad69
 
baad69
@@ -179,6 +180,7 @@ static GSourceFuncs socket_source_funcs = {
baad69
 
baad69
 /* Not included in ldap.h but documented */
baad69
 int ldap_init_fd (ber_socket_t fd, int proto, LDAP_CONST char *url, struct ldap **ldp);
baad69
+#define LDAP_SOCKET_TIMEOUT 5
baad69
 
baad69
 GSource *
baad69
 realm_ldap_connect_anonymous (GSocketAddress *address,
baad69
@@ -202,6 +204,8 @@ realm_ldap_connect_anonymous (GSocketAddress *address,
baad69
 	int opt_rc;
baad69
 	int ldap_opt_val;
baad69
 	const char *errmsg = NULL;
baad69
+	struct timeval tv = {LDAP_SOCKET_TIMEOUT, 0};
baad69
+	unsigned int milli = LDAP_SOCKET_TIMEOUT * 1000;
baad69
 
baad69
 	g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (address), NULL);
baad69
 
baad69
@@ -244,6 +248,23 @@ realm_ldap_connect_anonymous (GSocketAddress *address,
baad69
 		if (!g_unix_set_fd_nonblocking (ls->sock, FALSE, NULL))
baad69
 			g_warning ("couldn't set to blocking");
baad69
 
baad69
+		/* Lower the kernel defaults which might be minutes to hours */
baad69
+		rc = setsockopt (ls->sock, SOL_SOCKET, SO_RCVTIMEO,
baad69
+		                 &tv, sizeof (tv));
baad69
+		if (rc != 0) {
baad69
+			g_warning ("couldn't set SO_RCVTIMEO");
baad69
+		}
baad69
+		rc = setsockopt (ls->sock, SOL_SOCKET, SO_SNDTIMEO,
baad69
+		                 &tv, sizeof (tv));
baad69
+		if (rc != 0) {
baad69
+			g_warning ("couldn't set SO_SNDTIMEO");
baad69
+		}
baad69
+		rc = setsockopt (ls->sock, IPPROTO_TCP, TCP_USER_TIMEOUT,
baad69
+		                 &milli, sizeof (milli));
baad69
+		if (rc != 0) {
baad69
+			g_warning ("couldn't set TCP_USER_TIMEOUT");
baad69
+		}
baad69
+
baad69
 		if (family == G_SOCKET_FAMILY_IPV4) {
baad69
 			url = g_strdup_printf ("%s://%s:%d",
baad69
 			                       use_ldaps ? "ldaps" : "ldap",
baad69
-- 
baad69
2.34.1
baad69