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