[6782] in Kerberos

home help back first fref pref prev next nref lref last post

about krb5_us_timeofday

daemon@ATHENA.MIT.EDU (Jim Miller)
Wed Feb 28 00:28:43 1996

From: jim@bilbo.suite.com (Jim Miller)
Date: Tue, 27 Feb 96 23:23:04 -0600
To: krb5-bugs@MIT.EDU
Cc: kerberos@MIT.EDU
Reply-To: Jim_Miller@bilbo.suite.com


[This "bug" report is about Kerb 5.4 beta 3, although it may be relevant to later releases.]

I think the implementation of krb5_us_timeofday should be changed.  Here is the KRB 5.4.3  
code:

static struct timeval last_tv = {0, 0};

krb5_error_code
krb5_us_timeofday(seconds, microseconds)
register krb5_int32 *seconds, *microseconds;
{
    struct timeval tv;

    if (gettimeofday(&tv, (struct timezone *)0) == -1) {
	/* failed, return errno */
	return (krb5_error_code) errno;
    }
    if ((tv.tv_sec == last_tv.tv_sec) && (tv.tv_usec == last_tv.tv_usec)) {
	    if (++last_tv.tv_usec >= 1000000) {
		    last_tv.tv_usec = 0;
		    last_tv.tv_sec++;
	    }
	    tv = last_tv;
    } else 

	    last_tv = tv;
	    

    *seconds = tv.tv_sec;
    *microseconds = tv.tv_usec;
    return 0;
}


The "last_tv" logic was added in sometime after Kerb 4.  I don';t really remember when.  I  
think the purpose of the "last_tv" logic was to make sure that krb5_us_timeofday doesn't  
return the same time two calls in a row, and it does do that.  However, I think the logic is  
flawed for the case when gettimeofday returns the same value three or more times in a row.

In that case, krb5_us_timeofday would return time values like the following:

X
X+1
X

The first time gettimeofday returns X assume last_tv is < X, therefore, last_tv is set to X, and  
krb5_us_timeofday returns X.  The second time gettimeofday returns X,  tv == last_tv, so  
last_tv becomes X+1 and krb5_us_timeofday returns X+1.  The third time gettimeofday  
returns X, tv != last_tv, so last_tv is set back to X and krb5_us_timeofday returns X again.

I feel the following is a better implementation:

static struct timeval last_tv = {0, 0};
static krb5_int32 last_tv_count = 0;

krb5_error_code
krb5_us_timeofday(seconds, microseconds)
register krb5_int32 *seconds, *microseconds;
{
    struct timeval tv;

    if (gettimeofday(&tv, (struct timezone *)0) == -1) {
	/* failed, return errno */
	return (krb5_error_code) errno;
    }
    if ((tv.tv_sec == last_tv.tv_sec) && (tv.tv_usec == last_tv.tv_usec)) {
	    tv.tv_usec += (++last_tv_count);

	    if (tv.tv_usec >= 1000000) {
		tv.tv_usec = 0;
		tv.tv_sec++;
	    }

    } else {
	    last_tv = tv;
	    last_tv_count = 0;
    }
    

    *seconds = tv.tv_sec;
    *microseconds = tv.tv_usec;
    return 0;
}


With the above changes,  krb5_us_timeofday would return X, X+1, X+2 if gettimeofday  
returned X three times in a row.

Ignore this message if the most recent version of  krb5_us_timeofday already does something  
like this.

Jim_Miller@suite.com

home help back first fref pref prev next nref lref last post