[6782] in Kerberos
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