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