diff -up dhcp-4.2.0-P1/common/dispatch.c.64-bit_lease_parse dhcp-4.2.0-P1/common/dispatch.c --- dhcp-4.2.0-P1/common/dispatch.c.64-bit_lease_parse 2010-12-13 11:06:36.000000000 +0100 +++ dhcp-4.2.0-P1/common/dispatch.c 2010-12-13 10:56:59.000000000 +0100 @@ -174,6 +174,7 @@ isclib_timer_callback(isc_task_t *taskp /* maximum value for usec */ #define USEC_MAX 1000000 +#define DHCP_SEC_MAX 0xFFFFFFFF void add_timeout (when, where, what, ref, unref) struct timeval *when; @@ -185,7 +186,8 @@ void add_timeout (when, where, what, ref struct timeout *t, *q; int usereset = 0; isc_result_t status; - int sec, usec; + int64_t sec; + int usec; isc_interval_t interval; isc_time_t expires; @@ -231,9 +233,49 @@ void add_timeout (when, where, what, ref q->what = what; } - /* We don't really need this, but keep it for now */ - q->when.tv_sec = when->tv_sec; - q->when.tv_usec = when->tv_usec; + /* + * The value passed in is a time from an epoch but we need a relative + * time so we need to do some math to try and recover the period. + * This is complicated by the fact that not all of the calls cared + * about the usec value, if it's zero we assume the caller didn't care. + * + * The ISC timer library doesn't seem to like negative values + * and can't accept any values above 4G-1 seconds so we limit + * the values to 0 <= value < 4G-1. We do it before + * checking the trace option so that both the trace code and + * the working code use the same values. + */ + + sec = when->tv_sec - cur_tv.tv_sec; + usec = when->tv_usec - cur_tv.tv_usec; + + if ((when->tv_usec != 0) && (usec < 0)) { + sec--; + usec += USEC_MAX; + } + + if (sec < 0) { + sec = 0; + usec = 0; + } else if (sec > DHCP_SEC_MAX) { + log_error("Timeout requested too large %lld " + "reducing to 2^^32-1", sec); + sec = DHCP_SEC_MAX; + usec = 0; + } + else if (usec < 0) { + usec = 0; + } else if (usec >= USEC_MAX) { + usec = USEC_MAX - 1; + } + + /* + * This is necessary for the tracing code but we put it + * here in case we want to compare timing information + * for some reason, like debugging. + */ + q->when.tv_sec = cur_tv.tv_sec + (sec & DHCP_SEC_MAX); + q->when.tv_usec = usec; #if defined (TRACING) if (trace_playback()) { @@ -283,38 +325,7 @@ void add_timeout (when, where, what, ref q->next = timeouts; timeouts = q; - /* - * Set up the interval values - The previous timers allowed - * negative values to be set, the ISC timer library doesn't like - * that so we make any negative values 0 which sould amount to - * the same thing. - */ - - /* - * The value passed in is a time from an epoch but we need a relative - * time so we need to do some math to try and recover the period. - * This is complicated by the fact that not all of the calls cared - * about the usec value, if it's zero we assume the caller didn't care. - */ - - sec = when->tv_sec - cur_tv.tv_sec; - usec = when->tv_usec - cur_tv.tv_usec; - - if ((when->tv_usec != 0) && (usec < 0)) { - sec--; - usec += USEC_MAX; - } - - if (sec < 0) { - sec = 0; - usec = 0; - } else if (usec < 0) { - usec = 0; - } else if (usec >= USEC_MAX) { - usec = USEC_MAX - 1; - } - - isc_interval_set(&interval, sec, usec * 1000); + isc_interval_set(&interval, sec & 0xFFFFFFFF, usec * 1000); status = isc_time_nowplusinterval(&expires, &interval); if (status != ISC_R_SUCCESS) { /* diff -up dhcp-4.2.0-P1/common/parse.c.64-bit_lease_parse dhcp-4.2.0-P1/common/parse.c --- dhcp-4.2.0-P1/common/parse.c.64-bit_lease_parse 2009-10-28 05:12:29.000000000 +0100 +++ dhcp-4.2.0-P1/common/parse.c 2010-12-13 11:06:36.000000000 +0100 @@ -905,8 +905,8 @@ TIME parse_date_core(cfile) struct parse *cfile; { - int guess; - int tzoff, wday, year, mon, mday, hour, min, sec; + TIME guess; + long int tzoff, wday, year, mon, mday, hour, min, sec; const char *val; enum dhcp_token token; static int months [11] = { 31, 59, 90, 120, 151, 181, @@ -931,7 +931,7 @@ parse_date_core(cfile) return (TIME)0; } - guess = atoi(val); + guess = atol(val); if (!parse_semi(cfile)) return (TIME)0; @@ -945,7 +945,7 @@ parse_date_core(cfile) skip_to_semi (cfile); return (TIME)0; } - wday = atoi (val); + wday = atol (val); /* Year... */ token = next_token (&val, (unsigned *)0, cfile); @@ -960,7 +960,7 @@ parse_date_core(cfile) somebody invents a time machine, I think we can safely disregard it. This actually works around a stupid Y2K bug that was present in a very early beta release of dhcpd. */ - year = atoi (val); + year = atol (val); if (year > 1900) year -= 1900; @@ -982,7 +982,7 @@ parse_date_core(cfile) skip_to_semi (cfile); return (TIME)0; } - mon = atoi (val) - 1; + mon = atol (val) - 1; /* Slash separating month from day... */ token = next_token (&val, (unsigned *)0, cfile); @@ -1002,7 +1002,7 @@ parse_date_core(cfile) skip_to_semi (cfile); return (TIME)0; } - mday = atoi (val); + mday = atol (val); /* Hour... */ token = next_token (&val, (unsigned *)0, cfile); @@ -1012,7 +1012,7 @@ parse_date_core(cfile) skip_to_semi (cfile); return (TIME)0; } - hour = atoi (val); + hour = atol (val); /* Colon separating hour from minute... */ token = next_token (&val, (unsigned *)0, cfile); @@ -1032,7 +1032,7 @@ parse_date_core(cfile) skip_to_semi (cfile); return (TIME)0; } - min = atoi (val); + min = atol (val); /* Colon separating minute from second... */ token = next_token (&val, (unsigned *)0, cfile); @@ -1052,12 +1052,12 @@ parse_date_core(cfile) skip_to_semi (cfile); return (TIME)0; } - sec = atoi (val); + sec = atol (val); token = peek_token (&val, (unsigned *)0, cfile); if (token == NUMBER) { token = next_token (&val, (unsigned *)0, cfile); - tzoff = atoi (val); + tzoff = atol (val); } else tzoff = 0; @@ -1090,7 +1090,7 @@ TIME parse_date(cfile) struct parse *cfile; { - int guess; + TIME guess; guess = parse_date_core(cfile); /* Make sure the date ends in a semicolon... */