diff -C4 -r dhcp-3.0.1rc6/includes/dhcpd.h dhcp-3.0.1rc6_fff/includes/dhcpd.h
*** dhcp-3.0.1rc6/includes/dhcpd.h	Thu Jan 17 19:45:57 2002
--- dhcp-3.0.1rc6_fff/includes/dhcpd.h	Wed Jan 23 20:43:41 2002
***************
*** 414,421 ****
--- 414,422 ----
  #define SV_UPDATE_OPTIMIZATION		41
  #define SV_PING_CHECKS			42
  #define SV_UPDATE_STATIC_LEASES		43
  #define SV_LOG_FACILITY			44
+ #define SV_FAILOVER_FUDGE_FACTOR	99
  
  #if !defined (DEFAULT_DEFAULT_LEASE_TIME)
  # define DEFAULT_DEFAULT_LEASE_TIME 43200
  #endif
***************
*** 431,438 ****
--- 432,443 ----
  #if !defined (DEFAULT_DDNS_TTL)
  # define DEFAULT_DDNS_TTL 3600
  #endif
  
+ #if !defined (DEFAULT_FAILOVER_FUDGE_FACTOR)
+ # define DEFAULT_FAILOVER_FUDGE_FACTOR 0
+ #endif
+ 
  /* Client option names */
  
  #define	CL_TIMEOUT		1
  #define	CL_SELECT_INTERVAL	2
***************
*** 1117,1124 ****
--- 1122,1131 ----
  extern const char *path_dhcpd_db;
  extern const char *path_dhcpd_pid;
  
  extern int dhcp_max_agent_option_packet_length;
+ 
+ extern unsigned int fff ;
  
  int main PROTO ((int, char **, char **));
  void postconf_initialization (int);
  void postdb_startup (void);
diff -C4 -r dhcp-3.0.1rc6/server/dhcpd.c dhcp-3.0.1rc6_fff/server/dhcpd.c
*** dhcp-3.0.1rc6/server/dhcpd.c	Fri Jun 22 04:12:58 2001
--- dhcp-3.0.1rc6_fff/server/dhcpd.c	Wed Jan 23 20:56:32 2002
***************
*** 819,826 ****
--- 819,848 ----
  			data_string_forget (&db, MDL);
  		}
  	}
  
+ 	oc = lookup_option (&server_universe,
+ 			options, SV_FAILOVER_FUDGE_FACTOR);
+ 	if (oc) {
+ 		if (evaluate_option_cache (&db, (struct packet *)0,
+ 					(struct lease *)0,
+ 					(struct client_state *)0,
+ 					options,
+ 					(struct option_state *)0,
+ 					&global_scope, oc, MDL)) {
+ 			if (db.len == sizeof(u_int16_t)) {
+ 				fff = getUShort(db.data) ;
+ 				if (fff > 0)
+ 					log_debug ("failover fudge factor is %u!", fff) ;
+ 			}
+ 			else
+ 				log_fatal ("invalid failover fudge factor "
+ 					   "data length");
+ 
+ 			data_string_forget (&db, MDL);
+ 		}
+ 	}
+ 
  	/* Don't need the options anymore. */
  	option_state_dereference (&options, MDL);
  	
  #if defined (NSUPDATE)
diff -C4 -r dhcp-3.0.1rc6/server/dhcpd.conf.5 dhcp-3.0.1rc6_fff/server/dhcpd.conf.5
*** dhcp-3.0.1rc6/server/dhcpd.conf.5	Thu Jan 17 19:10:29 2002
--- dhcp-3.0.1rc6_fff/server/dhcpd.conf.5	Wed Jan 23 20:41:22 2002
***************
*** 1833,1840 ****
--- 1833,1864 ----
  caution.
  .RE
  .PP
  The
+ .I failover-fudge-factor
+ statement
+ .RS 0.25i
+ .PP
+ .B failover-fudge-factor\fR \fIseconds\fR\fB;\fR
+ .PP
+ The \fIfailover-fudge-factor\fR statement can be used to specify how many
+ seconds early state transitions to expired are allowed to be. If failover
+ is not enabled, this statement is ignored.
+ .P
+ When one failover peer tells the other that a lease has expired, the
+ current time on the receiving peer may be a second or so out. As a result,
+ the receiving peer may regard the lease as still active, and reject the
+ state transition. This fudge factor tells the peer to permit such
+ transitions, even if they are up to \fIseconds\fR "early".
+ .P
+ If you are seeing messages in your server logs about invalid state
+ transitions from active to expired, this fudge factor may help. Although
+ fudge factors of up to 65535 are possible, the value used should be kept
+ as small as possible consistent with overcoming the problem. Start with
+ one second and work up.
+ .RE
+ .PP
+ The
  .I filename
  statement
  .RS 0.25i
  .PP
diff -C4 -r dhcp-3.0.1rc6/server/failover.c dhcp-3.0.1rc6_fff/server/failover.c
*** dhcp-3.0.1rc6/server/failover.c	Mon Nov  5 02:54:40 2001
--- dhcp-3.0.1rc6_fff/server/failover.c	Wed Jan 23 21:28:13 2002
***************
*** 49,56 ****
--- 49,58 ----
  #include "dhcpd.h"
  #include "version.h"
  #include <omapip/omapip_p.h>
  
+ unsigned int fff = DEFAULT_FAILOVER_FUDGE_FACTOR ;
+ 
  #if defined (FAILOVER_PROTOCOL)
  dhcp_failover_state_t *failover_states;
  static isc_result_t do_a_failover_option (omapi_object_t *,
  					  dhcp_failover_link_t *);
***************
*** 4972,4980 ****
  			}
  			return binding_state;
  
  		      case FTS_EXPIRED:
! 			if (lease -> ends > cur_time) {
  				new_state = lease -> binding_state;
  				goto out;
  			}
  
--- 4974,4982 ----
  			}
  			return binding_state;
  
  		      case FTS_EXPIRED:
! 			if (lease -> ends > cur_time + fff) {
  				new_state = lease -> binding_state;
  				goto out;
  			}
  
***************
*** 5113,5121 ****
  
  			      case FTS_EXPIRED:
  			      case FTS_RELEASED:
  			      case FTS_RESET:
! 				if (lease -> ends > cur_time)
  					new_state =
  						lease -> binding_state;
  				else
  					new_state = binding_state;
--- 5115,5123 ----
  
  			      case FTS_EXPIRED:
  			      case FTS_RELEASED:
  			      case FTS_RESET:
! 				if (lease -> ends > cur_time + fff)
  					new_state =
  						lease -> binding_state;
  				else
  					new_state = binding_state;
diff -C4 -r dhcp-3.0.1rc6/server/stables.c dhcp-3.0.1rc6_fff/server/stables.c
*** dhcp-3.0.1rc6/server/stables.c	Wed Oct 17 05:32:03 2001
--- dhcp-3.0.1rc6_fff/server/stables.c	Wed Jan 23 20:25:12 2002
***************
*** 543,551 ****
  	{ "#95", "X",			&server_universe, 95 },
  	{ "#96", "X",			&server_universe, 96 },
  	{ "#97", "X",			&server_universe, 97 },
  	{ "#98", "X",			&server_universe, 98 },
! 	{ "#99", "X",			&server_universe, 99 },
  	{ "#100", "X",			&server_universe, 100 },
  	{ "#101", "X",			&server_universe, 101 },
  	{ "#102", "X",			&server_universe, 102 },
  	{ "#103", "X",			&server_universe, 103 },
--- 543,551 ----
  	{ "#95", "X",			&server_universe, 95 },
  	{ "#96", "X",			&server_universe, 96 },
  	{ "#97", "X",			&server_universe, 97 },
  	{ "#98", "X",			&server_universe, 98 },
! 	{ "failover-fudge-factor", "S",	&server_universe, 99 },
  	{ "#100", "X",			&server_universe, 100 },
  	{ "#101", "X",			&server_universe, 101 },
  	{ "#102", "X",			&server_universe, 102 },
  	{ "#103", "X",			&server_universe, 103 },
