lists.arthurdejong.org
RSS feed

[PATCH 1/2] Check a socket's connectivity before trying to use it

[Date Prev][Date Next] [Thread Prev][Thread Next]

[PATCH 1/2] Check a socket's connectivity before trying to use it



This alleviates some cases where multi-second lag occurs before a query
returns due to some or all connections having been closed by the peer,
e.g. a load balancer timing out old connections, but they are all tried
before opening new connections.

Tested and working on Linux.
---
 nslcd/myldap.c | 40 ++++++++++++++++++++++++++++++----------
 1 file changed, 30 insertions(+), 10 deletions(-)

diff --git a/nslcd/myldap.c b/nslcd/myldap.c
index 7babe0e..6868a2a 100644
--- a/nslcd/myldap.c
+++ b/nslcd/myldap.c
@@ -959,19 +959,39 @@ void myldap_session_check(MYLDAP_SESSION *session)
     errno = EINVAL;
     return;
   }
-  /* check if we should time out the connection */
-  if ((session->ld != NULL) && (nslcd_cfg->idle_timelimit > 0))
+  if (session->ld != NULL)
   {
-    /* if we have any running searches, don't time out */
-    for (i = 0; i < MAX_SEARCHES_IN_SESSION; i++)
-      if ((session->searches[i] != NULL) && (session->searches[i]->valid))
+    int sd;
+    int rc;
+    struct sockaddr sa;
+    socklen_t salen = sizeof(sa);
+    rc = ldap_get_option(session->ld, LDAP_OPT_DESC, &sd);
+    if (rc == LDAP_SUCCESS)
+    {
+      /* check if the connection was closed by the peer */
+      if ((getpeername(sd, &sa, &salen) == -1) && (errno == ENOTCONN))
+      {
+        log_log(LOG_DEBUG, "myldap_session_check(): connection reset by peer");
+        do_close(session);
         return;
-    /* consider timeout (there are no running searches) */
-    time(&current_time);
-    if ((session->lastactivity + nslcd_cfg->idle_timelimit) < current_time)
+      }
+    }
+    else
+      myldap_err(LOG_ERR, session->ld, rc, "ldap_get_option(LDAP_OPT_DESC) 
failed");
+    /* check if we should time out the connection */
+    if (nslcd_cfg->idle_timelimit > 0)
     {
-      log_log(LOG_DEBUG, "myldap_session_check(): idle_timelimit reached");
-      do_close(session);
+      /* if we have any running searches, don't time out */
+      for (i = 0; i < MAX_SEARCHES_IN_SESSION; i++)
+        if ((session->searches[i] != NULL) && (session->searches[i]->valid))
+          return;
+      /* consider timeout (there are no running searches) */
+      time(&current_time);
+      if ((session->lastactivity + nslcd_cfg->idle_timelimit) < current_time)
+      {
+        log_log(LOG_DEBUG, "myldap_session_check(): idle_timelimit reached");
+        do_close(session);
+      }
     }
   }
 }
-- 
2.0.0

-- 
To unsubscribe send an email to
nss-pam-ldapd-users-unsubscribe@lists.arthurdejong.org or see
http://lists.arthurdejong.org/nss-pam-ldapd-users/