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