s3/ldap: use monotonic clock for timeouts in smbldap
authorBjörn Jacke <bj@sernet.de>
Mon, 6 Sep 2010 23:04:10 +0000 (01:04 +0200)
committerBjörn Jacke <bj@sernet.de>
Wed, 8 Sep 2010 20:33:31 +0000 (22:33 +0200)
tevent would need monotonic clock features to make also smbldap's idle handling
aware of backward clock jumps. Other areas in smbldap are clock jump save now.

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

index 69b4153f28000250251bf8a5cef88782ae227184..060fcc21eb0ff77e798ff6591ede5b60cf868ed7 100644 (file)
@@ -153,7 +153,7 @@ int smbldap_modify(struct smbldap_state *ldap_state,
 struct smbldap_state {
        LDAP *ldap_struct;
        pid_t pid;
-       time_t last_ping;
+       time_t last_ping; /* monotonic */
        /* retrive-once info */
        const char *uri;
 
@@ -166,11 +166,11 @@ struct smbldap_state {
 
        unsigned int num_failures;
 
-       time_t last_use;
+       time_t last_use; /* monotonic */
        struct event_context *event_context;
        struct timed_event *idle_event;
 
-       struct timeval last_rebind;
+       struct timeval last_rebind; /* monotonic */
 };
 
 /* struct used by both pdb_ldap.c and pdb_nds.c */
index 996c1c4c85337be87be7c4fc43409226c9c59d9e..67e3d4dc1b17e5d8be84fdabd5f578ffa2af0fdf 100644 (file)
@@ -958,6 +958,7 @@ static int rebindproc_with_state  (LDAP * ld, char **whop, char **credp,
                                   int *methodp, int freeit, void *arg)
 {
        struct smbldap_state *ldap_state = arg;
+       struct timespec ts;
 
        /** @TODO Should we be doing something to check what servers we rebind to?
            Could we get a referral to a machine that we don't want to give our
@@ -990,7 +991,8 @@ static int rebindproc_with_state  (LDAP * ld, char **whop, char **credp,
                *methodp = LDAP_AUTH_SIMPLE;
        }
 
-       GetTimeOfDay(&ldap_state->last_rebind);
+       clock_gettime_mono(&ts);
+       ldap_state->last_rebind = convert_timespec_to_timeval(ts);
 
        return 0;
 }
@@ -1010,6 +1012,7 @@ static int rebindproc_connect_with_state (LDAP *ldap_struct,
        struct smbldap_state *ldap_state =
                (struct smbldap_state *)arg;
        int rc;
+       struct timespec ts;
        int version;
 
        DEBUG(5,("rebindproc_connect_with_state: Rebinding to %s as \"%s\"\n", 
@@ -1042,7 +1045,8 @@ static int rebindproc_connect_with_state (LDAP *ldap_struct,
                        DEBUG(10,("rebindproc_connect_with_state: "
                                "setting last_rebind timestamp "
                                "(req: 0x%02x)\n", (unsigned int)request));
-                       GetTimeOfDay(&ldap_state->last_rebind);
+                       clock_gettime_mono(&ts);
+                       ldap_state->last_rebind = convert_timespec_to_timeval(ts);
                        break;
                default:
                        ZERO_STRUCT(ldap_state->last_rebind);
@@ -1168,7 +1172,7 @@ static int smbldap_connect_system(struct smbldap_state *ldap_state, LDAP * ldap_
 
 static void smbldap_idle_fn(struct event_context *event_ctx,
                            struct timed_event *te,
-                           struct timeval now,
+                           struct timeval now_abs,
                            void *private_data);
 
 /**********************************************************************
@@ -1180,7 +1184,7 @@ static int smbldap_open(struct smbldap_state *ldap_state)
        bool reopen = False;
        SMB_ASSERT(ldap_state);
 
-       if ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping + SMBLDAP_DONT_PING_TIME) < time(NULL))) {
+       if ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping + SMBLDAP_DONT_PING_TIME) < time_mono(NULL))) {
 
 #ifdef HAVE_UNIXSOCKET
                struct sockaddr_un addr;
@@ -1204,7 +1208,7 @@ static int smbldap_open(struct smbldap_state *ldap_state)
                        ldap_state->ldap_struct = NULL;
                        ldap_state->last_ping = (time_t)0;
                } else {
-                       ldap_state->last_ping = time(NULL);
+                       ldap_state->last_ping = time_mono(NULL);
                } 
        }
 
@@ -1224,7 +1228,7 @@ static int smbldap_open(struct smbldap_state *ldap_state)
        }
 
 
-       ldap_state->last_ping = time(NULL);
+       ldap_state->last_ping = time_mono(NULL);
        ldap_state->pid = sys_getpid();
 
        TALLOC_FREE(ldap_state->idle_event);
@@ -1274,7 +1278,7 @@ static void gotalarm_sig(int dummy)
 static int another_ldap_try(struct smbldap_state *ldap_state, int *rc,
                            int *attempts, time_t endtime)
 {
-       time_t now = time(NULL);
+       time_t now = time_mono(NULL);
        int open_rc = LDAP_SERVER_DOWN;
 
        if (*rc != LDAP_SERVER_DOWN)
@@ -1347,7 +1351,7 @@ static int smbldap_search_ext(struct smbldap_state *ldap_state,
        int             rc = LDAP_SERVER_DOWN;
        int             attempts = 0;
        char           *utf8_filter;
-       time_t          endtime = time(NULL)+lp_ldap_timeout();
+       time_t          endtime = time_mono(NULL)+lp_ldap_timeout();
        struct          timeval timeout;
        size_t          converted_size;
 
@@ -1358,11 +1362,12 @@ static int smbldap_search_ext(struct smbldap_state *ldap_state,
 
        if (ldap_state->last_rebind.tv_sec > 0) {
                struct timeval  tval;
+               struct timespec ts;
                int64_t tdiff = 0;
                int             sleep_time = 0;
 
-               ZERO_STRUCT(tval);
-               GetTimeOfDay(&tval);
+               clock_gettime_mono(&ts);
+               tval = convert_timespec_to_timeval(ts);
 
                tdiff = usec_time_diff(&tval, &ldap_state->last_rebind);
                tdiff /= 1000; /* Convert to milliseconds. */
@@ -1545,7 +1550,7 @@ int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *at
        int             rc = LDAP_SERVER_DOWN;
        int             attempts = 0;
        char           *utf8_dn;
-       time_t          endtime = time(NULL)+lp_ldap_timeout();
+       time_t          endtime = time_mono(NULL)+lp_ldap_timeout();;
        size_t          converted_size;
 
        SMB_ASSERT(ldap_state);
@@ -1589,7 +1594,7 @@ int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs
        int             rc = LDAP_SERVER_DOWN;
        int             attempts = 0;
        char           *utf8_dn;
-       time_t          endtime = time(NULL)+lp_ldap_timeout();
+       time_t          endtime = time_mono(NULL)+lp_ldap_timeout();;
        size_t          converted_size;
 
        SMB_ASSERT(ldap_state);
@@ -1633,7 +1638,7 @@ int smbldap_delete(struct smbldap_state *ldap_state, const char *dn)
        int             rc = LDAP_SERVER_DOWN;
        int             attempts = 0;
        char           *utf8_dn;
-       time_t          endtime = time(NULL)+lp_ldap_timeout();
+       time_t          endtime = time_mono(NULL)+lp_ldap_timeout();;
        size_t          converted_size;
 
        SMB_ASSERT(ldap_state);
@@ -1679,7 +1684,7 @@ int smbldap_extended_operation(struct smbldap_state *ldap_state,
 {
        int             rc = LDAP_SERVER_DOWN;
        int             attempts = 0;
-       time_t          endtime = time(NULL)+lp_ldap_timeout();
+       time_t          endtime = time_mono(NULL)+lp_ldap_timeout();
 
        if (!ldap_state)
                return (-1);
@@ -1726,7 +1731,7 @@ int smbldap_search_suffix (struct smbldap_state *ldap_state,
 
 static void smbldap_idle_fn(struct event_context *event_ctx,
                            struct timed_event *te,
-                           struct timeval now,
+                           struct timeval now_abs,
                            void *private_data)
 {
        struct smbldap_state *state = (struct smbldap_state *)private_data;
@@ -1738,12 +1743,13 @@ static void smbldap_idle_fn(struct event_context *event_ctx,
                return;
        }
 
-       if ((state->last_use+SMBLDAP_IDLE_TIME) > now.tv_sec) {
+       if ((state->last_use+SMBLDAP_IDLE_TIME) > time_mono(NULL)) {
                DEBUG(10,("ldap connection not idle...\n"));
 
+               /* this needs to be made monotonic clock aware inside tevent: */
                state->idle_event = event_add_timed(
                        event_ctx, NULL,
-                       timeval_add(&now, SMBLDAP_IDLE_TIME, 0),
+                       timeval_add(&now_abs, SMBLDAP_IDLE_TIME, 0),
                        smbldap_idle_fn,
                        private_data);
                return;