]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/overlays/retcode.c
better handling of randomness
[openldap] / servers / slapd / overlays / retcode.c
index add5a75235424f3a1ae2099f76f7a9846f7b8446..b966a4b1ddec7809691953a9e5cd9ff913546a23 100644 (file)
@@ -90,6 +90,25 @@ typedef struct retcode_t {
 static int
 retcode_entry_response( Operation *op, SlapReply *rs, BackendInfo *bi, Entry *e );
 
+static unsigned int
+retcode_sleep( int s )
+{
+       /* sleep as required */
+       if ( s < 0 ) {
+#if 0  /* use high-order bits for better randomness (Numerical Recipes in "C") */
+               unsigned        r = rand() % (-s);
+#endif
+               unsigned        r = ((double)(-s))*rand()/(RAND_MAX + 1.0);
+               return sleep( r );
+       }
+
+       if ( s > 0 ) {
+               return sleep( (unsigned int)s );
+       }
+
+       return 0;
+}
+
 static int
 retcode_cleanup_cb( Operation *op, SlapReply *rs )
 {
@@ -262,12 +281,7 @@ retcode_op_func( Operation *op, SlapReply *rs )
        slap_callback           *cb = NULL;
 
        /* sleep as required */
-       if ( rd->rd_sleep < 0 ) {
-               sleep( rand() % ( - rd->rd_sleep ) );
-
-       } else if ( rd->rd_sleep > 0 ) {
-               sleep( rd->rd_sleep );
-       }
+       retcode_sleep( rd->rd_sleep );
 
        if ( !dnIsSuffix( &op->o_req_ndn, &rd->rd_npdn ) ) {
                if ( RETCODE_INDIR( rd ) ) {
@@ -416,9 +430,7 @@ retcode_op_func( Operation *op, SlapReply *rs )
                        }
                }
 
-               if ( rdi->rdi_sleeptime > 0 ) {
-                       sleep( rdi->rdi_sleeptime );
-               }
+               retcode_sleep( rdi->rdi_sleeptime );
        }
 
        switch ( op->o_tag ) {
@@ -534,9 +546,8 @@ retcode_entry_response( Operation *op, SlapReply *rs, BackendInfo *bi, Entry *e
        if ( a != NULL && a->a_nvals[ 0 ].bv_val[ 0 ] != '-' ) {
                int     sleepTime;
 
-               sleepTime = strtoul( a->a_nvals[ 0 ].bv_val, &next, 0 );
-               if ( next != a->a_nvals[ 0 ].bv_val && next[ 0 ] == '\0' ) {
-                       sleep( sleepTime );
+               if ( lutil_atoi( &sleepTime, a->a_nvals[ 0 ].bv_val ) == 0 ) {
+                       retcode_sleep( sleepTime );
                }
        }
 
@@ -619,6 +630,8 @@ retcode_db_init( BackendDB *be )
        slap_overinst   *on = (slap_overinst *)be->bd_info;
        retcode_t       *rd;
 
+       srand( getpid() );
+
        rd = (retcode_t *)ch_malloc( sizeof( retcode_t ) );
        memset( rd, 0, sizeof( retcode_t ) );
 
@@ -858,7 +871,6 @@ retcode_db_config(
 
                                } else if ( strncasecmp( argv[ i ], "sleeptime=", STRLENOF( "sleeptime=" ) ) == 0 )
                                {
-                                       char            *next;
                                        if ( rdi.rdi_sleeptime != 0 ) {
                                                fprintf( stderr, "%s: line %d: retcode: "
                                                        "\"sleeptime\" already provided.\n",
@@ -866,8 +878,7 @@ retcode_db_config(
                                                return 1;
                                        }
 
-                                       rdi.rdi_sleeptime = strtol( &argv[ i ][ STRLENOF( "sleeptime=" ) ], &next, 10 );
-                                       if ( next == argv[ i ] || next[ 0 ] != '\0' ) {
+                                       if ( lutil_atoi( &rdi.rdi_sleeptime, &argv[ i ][ STRLENOF( "sleeptime=" ) ] ) ) {
                                                fprintf( stderr, "%s: line %d: retcode: "
                                                        "unable to parse \"sleeptime=%s\".\n",
                                                        fname, lineno, &argv[ i ][ STRLENOF( "sleeptime=" ) ] );
@@ -997,7 +1008,7 @@ retcode_db_open( BackendDB *be )
                }
 
                /* sleep time */
-               if ( rdi->rdi_sleeptime > 0 ) {
+               if ( rdi->rdi_sleeptime ) {
                        snprintf( buf, sizeof( buf ), "%d", rdi->rdi_sleeptime );
                        ber_str2bv( buf, 0, 0, &val[ 0 ] );