Fix problem with local time changes.
This commit is contained in:
parent
1389f3699f
commit
fd91ae3325
6 changed files with 81 additions and 20 deletions
|
@ -49,6 +49,8 @@ else
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
LIBS=" -lrt"
|
||||||
|
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
|
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
|
|
|
@ -22,7 +22,7 @@ password_find(list *l)
|
||||||
{
|
{
|
||||||
WALK_LIST(pi, *l)
|
WALK_LIST(pi, *l)
|
||||||
{
|
{
|
||||||
if ((pi->genfrom < now) && (pi->gento > now))
|
if ((pi->genfrom < now_real) && (pi->gento > now_real))
|
||||||
return pi;
|
return pi;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,7 +165,7 @@ ospf_pkt_checkauth(struct ospf_neighbor *n, struct ospf_iface *ifa, struct ospf_
|
||||||
WALK_LIST(ptmp, *(ifa->passwords))
|
WALK_LIST(ptmp, *(ifa->passwords))
|
||||||
{
|
{
|
||||||
if (pkt->u.md5.keyid != ptmp->id) continue;
|
if (pkt->u.md5.keyid != ptmp->id) continue;
|
||||||
if ((ptmp->accfrom > now) || (ptmp->accto < now)) continue;
|
if ((ptmp->accfrom > now_real) || (ptmp->accto < now_real)) continue;
|
||||||
pass = ptmp;
|
pass = ptmp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ rip_incoming_authentication( struct proto *p, struct rip_block_auth *block, stru
|
||||||
WALK_LIST(ptmp, *l)
|
WALK_LIST(ptmp, *l)
|
||||||
{
|
{
|
||||||
if (block->keyid != ptmp->id) continue;
|
if (block->keyid != ptmp->id) continue;
|
||||||
if ((ptmp->genfrom > now) || (ptmp->gento < now)) continue;
|
if ((ptmp->genfrom > now_real) || (ptmp->gento < now_real)) continue;
|
||||||
pass = ptmp;
|
pass = ptmp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,10 +83,11 @@ tracked_fopen(pool *p, char *name, char *mode)
|
||||||
* doesn't guarantee exact timing, only that a timer function
|
* doesn't guarantee exact timing, only that a timer function
|
||||||
* won't be called before the requested time.
|
* won't be called before the requested time.
|
||||||
*
|
*
|
||||||
* In BIRD, real time is represented by values of the &bird_clock_t type
|
* In BIRD, time is represented by values of the &bird_clock_t type
|
||||||
* which are integral numbers interpreted as a number of seconds since
|
* which are integral numbers interpreted as a relative number of seconds since
|
||||||
* a fixed (but platform dependent) epoch. The current time can be read
|
* some fixed time point in past. The current time can be read
|
||||||
* from a variable @now with reasonable accuracy.
|
* from variable @now with reasonable accuracy and is monotonic. There is also
|
||||||
|
* a current 'absolute' time in variable @now_real reported by OS.
|
||||||
*
|
*
|
||||||
* Each timer is described by a &timer structure containing a pointer
|
* Each timer is described by a &timer structure containing a pointer
|
||||||
* to the handler function (@hook), data private to this function (@data),
|
* to the handler function (@hook), data private to this function (@data),
|
||||||
|
@ -99,7 +100,61 @@ tracked_fopen(pool *p, char *name, char *mode)
|
||||||
static list near_timers, far_timers;
|
static list near_timers, far_timers;
|
||||||
static bird_clock_t first_far_timer = TIME_INFINITY;
|
static bird_clock_t first_far_timer = TIME_INFINITY;
|
||||||
|
|
||||||
bird_clock_t now;
|
bird_clock_t now, now_real;
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_times_plain(void)
|
||||||
|
{
|
||||||
|
bird_clock_t new_time = time(NULL);
|
||||||
|
int delta = new_time - now_real;
|
||||||
|
|
||||||
|
if ((delta >= 0) && (delta < 60))
|
||||||
|
now += delta;
|
||||||
|
else if (now_real != 0)
|
||||||
|
log(L_WARN "Time jump, delta %d s", delta);
|
||||||
|
|
||||||
|
now_real = new_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_times_gettime(void)
|
||||||
|
{
|
||||||
|
struct timespec ts;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||||
|
if (rv != 0)
|
||||||
|
die("clock_gettime: %m");
|
||||||
|
|
||||||
|
if (ts.tv_sec != now) {
|
||||||
|
if (ts.tv_sec < now)
|
||||||
|
log(L_ERR "Monotonic timer is broken");
|
||||||
|
|
||||||
|
now = ts.tv_sec;
|
||||||
|
now_real = time(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int clock_monotonic_available;
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
update_times(void)
|
||||||
|
{
|
||||||
|
if (clock_monotonic_available)
|
||||||
|
update_times_gettime();
|
||||||
|
else
|
||||||
|
update_times_plain();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
init_times(void)
|
||||||
|
{
|
||||||
|
struct timespec ts;
|
||||||
|
clock_monotonic_available = (clock_gettime(CLOCK_MONOTONIC, &ts) == 0);
|
||||||
|
if (!clock_monotonic_available)
|
||||||
|
log(L_WARN "Monotonic timer is missing");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tm_free(resource *r)
|
tm_free(resource *r)
|
||||||
|
@ -353,8 +408,8 @@ tm_parse_date(char *x)
|
||||||
* @x: destination buffer of size %TM_DATE_BUFFER_SIZE
|
* @x: destination buffer of size %TM_DATE_BUFFER_SIZE
|
||||||
* @t: time
|
* @t: time
|
||||||
*
|
*
|
||||||
* This function formats the given time value @t to a textual
|
* This function formats the given relative time value @t to a textual
|
||||||
* date representation (dd-mm-yyyy).
|
* date representation (dd-mm-yyyy) in real time..
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
tm_format_date(char *x, bird_clock_t t)
|
tm_format_date(char *x, bird_clock_t t)
|
||||||
|
@ -370,14 +425,15 @@ tm_format_date(char *x, bird_clock_t t)
|
||||||
* @x: destination buffer of size %TM_DATETIME_BUFFER_SIZE
|
* @x: destination buffer of size %TM_DATETIME_BUFFER_SIZE
|
||||||
* @t: time
|
* @t: time
|
||||||
*
|
*
|
||||||
* This function formats the given time value @t to a textual
|
* This function formats the given relative time value @t to a textual
|
||||||
* date/time representation (dd-mm-yyyy hh:mm:ss).
|
* date/time representation (dd-mm-yyyy hh:mm:ss) in real time.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
tm_format_datetime(char *x, bird_clock_t t)
|
tm_format_datetime(char *x, bird_clock_t t)
|
||||||
{
|
{
|
||||||
struct tm *tm;
|
struct tm *tm;
|
||||||
|
bird_clock_t delta = now - t;
|
||||||
|
t = now_real - delta;
|
||||||
tm = localtime(&t);
|
tm = localtime(&t);
|
||||||
if (strftime(x, TM_DATETIME_BUFFER_SIZE, "%d-%m-%Y %H:%M:%S", tm) == TM_DATETIME_BUFFER_SIZE)
|
if (strftime(x, TM_DATETIME_BUFFER_SIZE, "%d-%m-%Y %H:%M:%S", tm) == TM_DATETIME_BUFFER_SIZE)
|
||||||
strcpy(x, "<too-long>");
|
strcpy(x, "<too-long>");
|
||||||
|
@ -388,16 +444,17 @@ tm_format_datetime(char *x, bird_clock_t t)
|
||||||
* @x: destination buffer of size %TM_RELTIME_BUFFER_SIZE
|
* @x: destination buffer of size %TM_RELTIME_BUFFER_SIZE
|
||||||
* @t: time
|
* @t: time
|
||||||
*
|
*
|
||||||
* This function formats the given time value @t to a short
|
* This function formats the given relative time value @t to a short
|
||||||
* textual representation relative to the current time.
|
* textual representation in real time, relative to the current time.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
tm_format_reltime(char *x, bird_clock_t t)
|
tm_format_reltime(char *x, bird_clock_t t)
|
||||||
{
|
{
|
||||||
struct tm *tm;
|
struct tm *tm;
|
||||||
bird_clock_t delta = (t < now) ? (now - t) : (t - now);
|
|
||||||
static char *month_names[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
static char *month_names[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
||||||
|
|
||||||
|
bird_clock_t delta = now - t;
|
||||||
|
t = now_real - delta;
|
||||||
tm = localtime(&t);
|
tm = localtime(&t);
|
||||||
if (delta < 20*3600)
|
if (delta < 20*3600)
|
||||||
bsprintf(x, "%02d:%02d", tm->tm_hour, tm->tm_min);
|
bsprintf(x, "%02d:%02d", tm->tm_hour, tm->tm_min);
|
||||||
|
@ -1217,8 +1274,9 @@ io_init(void)
|
||||||
init_list(&sock_list);
|
init_list(&sock_list);
|
||||||
init_list(&global_event_list);
|
init_list(&global_event_list);
|
||||||
krt_io_init();
|
krt_io_init();
|
||||||
now = time(NULL);
|
init_times();
|
||||||
srandom((int) now);
|
update_times();
|
||||||
|
srandom((int) now_real);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1235,7 +1293,7 @@ io_loop(void)
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
events = ev_run_list(&global_event_list);
|
events = ev_run_list(&global_event_list);
|
||||||
now = time(NULL);
|
update_times();
|
||||||
tout = tm_first_shot();
|
tout = tm_first_shot();
|
||||||
if (tout <= now)
|
if (tout <= now)
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,7 +30,8 @@ void tm_start(timer *, unsigned after);
|
||||||
void tm_stop(timer *);
|
void tm_stop(timer *);
|
||||||
void tm_dump_all(void);
|
void tm_dump_all(void);
|
||||||
|
|
||||||
extern bird_clock_t now; /* Time in seconds since unknown epoch */
|
extern bird_clock_t now; /* Relative, monotonic time in seconds */
|
||||||
|
extern bird_clock_t now_real; /* Time in seconds since fixed known epoch */
|
||||||
|
|
||||||
bird_clock_t tm_parse_date(char *); /* Convert date to bird_clock_t */
|
bird_clock_t tm_parse_date(char *); /* Convert date to bird_clock_t */
|
||||||
bird_clock_t tm_parse_datetime(char *); /* Convert date to bird_clock_t */
|
bird_clock_t tm_parse_datetime(char *); /* Convert date to bird_clock_t */
|
||||||
|
|
Loading…
Reference in a new issue