diff --git a/src/include/gpxe/dhcp.h b/src/include/gpxe/dhcp.h index 7ce65399..c5ed0ead 100644 --- a/src/include/gpxe/dhcp.h +++ b/src/include/gpxe/dhcp.h @@ -466,6 +466,10 @@ struct dhcphdr { /** Maximum time that we will wait for ProxyDHCP responses */ #define PROXYDHCP_WAIT_TIME ( TICKS_PER_SEC * 1 ) +/** Timeouts for sending DHCP packets */ +#define DHCP_MIN_TIMEOUT ( 1 * TICKS_PER_SEC ) +#define DHCP_MAX_TIMEOUT ( 10 * TICKS_PER_SEC ) + /** Settings block name used for DHCP responses */ #define DHCP_SETTINGS_NAME "dhcp" diff --git a/src/include/gpxe/retry.h b/src/include/gpxe/retry.h index 71982fca..ec57db9e 100644 --- a/src/include/gpxe/retry.h +++ b/src/include/gpxe/retry.h @@ -9,12 +9,28 @@ #include +/** Default timeout value */ +#define DEFAULT_MIN_TIMEOUT ( TICKS_PER_SEC / 4 ) + +/** Limit after which the timeout will be deemed permanent */ +#define DEFAULT_MAX_TIMEOUT ( 10 * TICKS_PER_SEC ) + /** A retry timer */ struct retry_timer { /** List of active timers */ struct list_head list; /** Timeout value (in ticks) */ unsigned long timeout; + /** Minimum timeout value (in ticks) + * + * A value of zero means "use default timeout." + */ + unsigned long min_timeout; + /** Maximum timeout value before failure (in ticks) + * + * A value of zero means "use default timeout." + */ + unsigned long max_timeout; /** Start time (in ticks) * * A start time of zero indicates a stopped timer. diff --git a/src/net/retry.c b/src/net/retry.c index 3c934018..2a645c97 100644 --- a/src/net/retry.c +++ b/src/net/retry.c @@ -36,20 +36,11 @@ * */ -/** Default timeout value */ -#define MIN_TIMEOUT ( TICKS_PER_SEC / 4 ) - -/** Limit after which the timeout will be deemed permanent */ -#define MAX_TIMEOUT ( 10 * TICKS_PER_SEC ) - /* The theoretical minimum that the algorithm in stop_timer() can * adjust the timeout back down to is seven ticks, so set the minimum * timeout to at least that value for the sake of consistency. */ -#if MIN_TIMEOUT < 7 -#undef MIN_TIMEOUT #define MIN_TIMEOUT 7 -#endif /** List of running timers */ static LIST_HEAD ( timers ); @@ -67,8 +58,17 @@ void start_timer ( struct retry_timer *timer ) { if ( ! timer_running ( timer ) ) list_add ( &timer->list, &timers ); timer->start = currticks(); - if ( timer->timeout < MIN_TIMEOUT ) - timer->timeout = MIN_TIMEOUT; + + /* 0 means "use default timeout" */ + if ( timer->min_timeout == 0 ) + timer->min_timeout = DEFAULT_MIN_TIMEOUT; + /* We must never be less than MIN_TIMEOUT under any circumstances */ + if ( timer->min_timeout < MIN_TIMEOUT ) + timer->min_timeout = MIN_TIMEOUT; + /* Honor user-specified minimum timeout */ + if ( timer->timeout < timer->min_timeout ) + timer->timeout = timer->min_timeout; + DBG2 ( "Timer %p started at time %ld (expires at %ld)\n", timer, timer->start, ( timer->start + timer->timeout ) ); } @@ -150,8 +150,10 @@ static void timer_expired ( struct retry_timer *timer ) { /* Back off the timeout value */ timer->timeout <<= 1; - if ( ( fail = ( timer->timeout > MAX_TIMEOUT ) ) ) - timer->timeout = MAX_TIMEOUT; + if ( timer->max_timeout == 0 ) /* 0 means "use default timeout" */ + timer->max_timeout = DEFAULT_MAX_TIMEOUT; + if ( ( fail = ( timer->timeout > timer->max_timeout ) ) ) + timer->timeout = timer->max_timeout; DBG ( "Timer %p timeout backed off to %ld\n", timer, timer->timeout ); diff --git a/src/net/udp/dhcp.c b/src/net/udp/dhcp.c index 93eee6e9..149bdfb5 100644 --- a/src/net/udp/dhcp.c +++ b/src/net/udp/dhcp.c @@ -1059,6 +1059,8 @@ int start_dhcp ( struct job_interface *job, struct net_device *netdev ) { xfer_init ( &dhcp->xfer, &dhcp_xfer_operations, &dhcp->refcnt ); dhcp->netdev = netdev_get ( netdev ); dhcp->timer.expired = dhcp_timer_expired; + dhcp->timer.min_timeout = DHCP_MIN_TIMEOUT; + dhcp->timer.max_timeout = DHCP_MAX_TIMEOUT; dhcp->start = currticks(); /* Instantiate child objects and attach to our interfaces */