Disconnect an idle LDAP connection after 150 seconds.
authorVolker Lendecke <vlendec@samba.org>
Thu, 17 Jul 2003 11:24:54 +0000 (11:24 +0000)
committerVolker Lendecke <vlendec@samba.org>
Thu, 17 Jul 2003 11:24:54 +0000 (11:24 +0000)
Not strictly a bugfix, but it should considerably reduce the load we
put on LDAP servers given that at least nss_ldap on Linux keeps a
connection open.

And it should also stress our reconnect-code a bit more ;-)

Thanks to metze for this!

Volker
(This used to be commit e68d8eabeb9c64dc45d057619f9b3dd0cd507444)

source3/include/smbldap.h
source3/lib/smbldap.c

index 589d01aa6dd592f76149cea731912c7a216fe3f6..826fc3c55a17af3a6d27ea5dcf0bd777b38290d6 100644 (file)
@@ -132,6 +132,9 @@ struct smbldap_state {
        char *bind_secret;
 
        unsigned int num_failures;
+
+       time_t last_use;
+       smb_event_id_t event_id;
 };
 
 #endif         /* HAVE_LDAP */
index 39c1990decb58c6cbf3f41b00b62e7566c62d5bf..7c2409312bc93aa7937b39562595c9642711a246 100644 (file)
@@ -5,7 +5,7 @@
    Copyright (C) Gerald Carter                 2001-2003
    Copyright (C) Shahms King                   2001
    Copyright (C) Andrew Bartlett               2002-2003
-   Copyright (C) Stefan (metze) Metzmacher     2002
+   Copyright (C) Stefan (metze) Metzmacher     2002-2003
     
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -35,6 +35,8 @@
 #define SMBLDAP_DONT_PING_TIME 10      /* ping only all 10 seconds */
 #define SMBLDAP_NUM_RETRIES 8          /* retry only 8 times */
 
+#define SMBLDAP_IDLE_TIME 150          /* After 2.5 minutes disconnect */
+
 
 /* attributes used by Samba 2.2 */
 
@@ -925,6 +927,8 @@ int smbldap_search(struct smbldap_state *ldap_state,
                smbldap_close(ldap_state);      
        }
 
+       ldap_state->last_use = time(NULL);
+
        SAFE_FREE(utf8_filter);
        return rc;
 }
@@ -954,6 +958,8 @@ int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *at
                smbldap_close(ldap_state);      
        }
        
+       ldap_state->last_use = time(NULL);
+
        SAFE_FREE(utf8_dn);
        return rc;
 }
@@ -983,6 +989,8 @@ int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs
                smbldap_close(ldap_state);      
        }
                
+       ldap_state->last_use = time(NULL);
+
        SAFE_FREE(utf8_dn);
        return rc;
 }
@@ -1012,6 +1020,8 @@ int smbldap_delete(struct smbldap_state *ldap_state, const char *dn)
                smbldap_close(ldap_state);      
        }
                
+       ldap_state->last_use = time(NULL);
+
        SAFE_FREE(utf8_dn);
        return rc;
 }
@@ -1041,6 +1051,8 @@ int smbldap_extended_operation(struct smbldap_state *ldap_state,
                smbldap_close(ldap_state);      
        }
                
+       ldap_state->last_use = time(NULL);
+
        return rc;
 }
 
@@ -1071,6 +1083,24 @@ int smbldap_search_suffix (struct smbldap_state *ldap_state, const char *filter,
        return rc;
 }
 
+static void smbldap_idle_fn(void **data, time_t *interval, time_t now)
+{
+       struct smbldap_state *state = (struct smbldap_state *)(*data);
+
+       if (state->ldap_struct == NULL) {
+               DEBUG(10,("ldap connection not connected...\n"));
+               return;
+       }
+               
+       if ((state->last_use+SMBLDAP_IDLE_TIME) > now) {
+               DEBUG(10,("ldap connection not idle...\n"));
+               return;
+       }
+               
+       DEBUG(7,("ldap connection idle...closing connection\n"));
+       smbldap_close(state);
+}
+
 /**********************************************************************
  Housekeeping
  *********************************************************************/
@@ -1086,6 +1116,8 @@ void smbldap_free_struct(struct smbldap_state **ldap_state)
        SAFE_FREE((*ldap_state)->bind_dn);
        SAFE_FREE((*ldap_state)->bind_secret);
 
+       smb_unregister_idle_event((*ldap_state)->event_id);
+
        *ldap_state = NULL;
 
        /* No need to free any further, as it is talloc()ed */
@@ -1109,6 +1141,16 @@ NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, const char *location, struct smbldap_
        } else {
                (*smbldap_state)->uri = "ldap://localhost";
        }
+
+       (*smbldap_state)->event_id =
+               smb_register_idle_event(smbldap_idle_fn, (void *)(*smbldap_state),
+                                       SMBLDAP_IDLE_TIME);
+
+       if ((*smbldap_state)->event_id == SMB_EVENT_ID_INVALID) {
+               DEBUG(0,("Failed to register LDAP idle event!\n"));
+               return NT_STATUS_INVALID_HANDLE;
+       }
+
        return NT_STATUS_OK;
 }