them, if advertised by the client. It still only seeks to allocate one
new address.
+- Relative time may now be used as a qualifier for 'allow' and 'deny' access
+ control lists. These directives may be used to assist in re-addressing
+ address pools without having to constantly reconfigure the server. Please
+ see 'man dhcpd.conf' for more information on allow/deny 'after time' syntax.
+ Thanks to a patch from Christof Chen.
+
Changes since 4.0.0b1
- Use different paths for PID and lease files when running in DHCPv4
return TOKEN_ACTIVE;
if (!strcasecmp (atom + 1, "tsfp"))
return ATSFP;
+ if (!strcasecmp (atom + 1, "fter"))
+ return AFTER;
break;
case 'b':
if (!strcasecmp (atom + 1, "ackup"))
* NUMBER COLON NUMBER COLON NUMBER NUMBER SEMI |
* NEVER
*
- * Dates are stored in GMT or with a timezone offset; first number is day
+ * Dates are stored in UTC or with a timezone offset; first number is day
* of week; next is year/month/day; next is hours:minutes:seconds on a
* 24-hour clock, followed by the timezone offset in seconds, which is
* optional.
*/
-TIME parse_date (cfile)
+/* just parse the date */
+TIME
+parse_date_core(cfile)
struct parse *cfile;
{
int guess;
} else
tzoff = 0;
- /* Make sure the date ends in a semicolon... */
- if (!parse_semi (cfile))
- return 0;
-
/* Guess the time value... */
guess = ((((((365 * (year - 70) + /* Days in years since '70 */
(year - 69) / 4 + /* Leap days since '70 */
return guess;
}
+/* Wrapper to consume the semicolon after the date */
+TIME
+parse_date(cfile)
+ struct parse *cfile;
+{
+ int guess;
+ guess = parse_date_core(cfile);
+
+ /* Make sure the date ends in a semicolon... */
+ if (!parse_semi(cfile))
+ return 0;
+ return guess;
+}
+
+
+
/*
* option-name :== IDENTIFIER |
IDENTIFIER . IDENTIFIER
permit_unauthenticated_clients,
permit_all_clients,
permit_dynamic_bootp_clients,
- permit_class
+ permit_class,
+ permit_after
} type;
struct class *class;
+ TIME after; /* date after which this clause applies */
};
struct pool {
int free_leases;
int backup_leases;
int index;
+ TIME valid_from; /* deny pool use before this date */
+ TIME valid_until; /* deny pool use after this date */
+
#if defined (FAILOVER_PROTOCOL)
dhcp_failover_state_t *failover_peer;
#endif
void convert_num PROTO ((struct parse *, unsigned char *, const char *,
int, unsigned));
TIME parse_date PROTO ((struct parse *));
+TIME parse_date_core(struct parse *);
isc_result_t parse_option_name PROTO ((struct parse *, int, int *,
struct option **));
void parse_option_space_decl PROTO ((struct parse *));
LL = 647,
RANGE6 = 648,
WHITESPACE = 649,
- TOKEN_ALSO = 650
+ TOKEN_ALSO = 650,
+ AFTER = 651
};
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
int declaration = 0;
isc_result_t status;
struct lease *lpchain = (struct lease *)0, *lp;
+ TIME t;
+ int is_allow = 0;
pool = (struct pool *)0;
status = pool_allocate (&pool, MDL);
break;
case ALLOW:
permit_head = &pool -> permit_list;
+ /* remember the clause which leads to get_permit */
+ is_allow = 1;
get_permit:
permit = new_permit (MDL);
if (!permit)
"no such class: %s", val);
break;
+ case AFTER:
+ if (pool->valid_from || pool->valid_until) {
+ parse_warn(cfile,
+ "duplicate \"after\" clause.");
+ skip_to_semi(cfile);
+ free_permit(permit, MDL);
+ continue;
+ }
+ t = parse_date_core(cfile);
+ permit->type = permit_after;
+ permit->after = t;
+ if (is_allow) {
+ pool->valid_from = t;
+ } else {
+ pool->valid_until = t;
+ }
+ break;
+
default:
parse_warn (cfile, "expecting permit type.");
skip_to_semi (cfile);
case DENY:
permit_head = &pool -> prohibit_list;
+ /* remember the clause which leads to get_permit */
+ is_allow = 0;
goto get_permit;
case RBRACE:
TIME ping_timeout;
TIME lease_cltt;
struct in_addr from;
+ TIME remaining_time;
+ struct iaddr cip;
unsigned i, j;
int s1;
data_string_forget(&d1, MDL);
}
+ /* a client requests an address which is not yet active*/
+ if (lease->pool && lease->pool->valid_from &&
+ cur_time < lease->pool->valid_from) {
+ /* NAK leases before pool activation date */
+ cip.len = 4;
+ memcpy (cip.iabuf, <->ip_addr.iabuf, 4);
+ nak_lease(packet, &cip);
+ free_lease_state (state, MDL);
+ lease_dereference (<, MDL);
+ if (host)
+ host_dereference (&host, MDL);
+ return;
+
+ }
+
+ /* CC:
+ a) NAK current lease if past the expiration date
+ b) extend lease only up to the expiration date, but not
+ below min-lease-time
+ Setting min-lease-time is essential for this to work!
+ The value of min-lease-time determines the lenght
+ of the transition window:
+ A client renewing a second before the deadline will
+ get a min-lease-time lease. Since the current ip might not
+ be routable after the deadline, the client will
+ be offline until it DISCOVERS again. Otherwise it will
+ receive a NAK at T/2.
+ A min-lease-time of 6 seconds effectively switches over
+ all clients in this pool very quickly.
+ */
+
+ if (lease->pool && lease->pool->valid_until) {
+ if (cur_time >= lease->pool->valid_until) {
+ /* NAK leases after pool expiration date */
+ cip.len = 4;
+ memcpy (cip.iabuf, <->ip_addr.iabuf, 4);
+ nak_lease(packet, &cip);
+ free_lease_state (state, MDL);
+ lease_dereference (<, MDL);
+ if (host)
+ host_dereference (&host, MDL);
+ return;
+ }
+ remaining_time = lease->pool->valid_until - cur_time;
+ if (lease_time > remaining_time)
+ lease_time = remaining_time;
+ }
+
if (lease_time < min_lease_time) {
if (min_lease_time)
lease_time = min_lease_time;
lease_time = default_lease_time;
}
+
#if defined (FAILOVER_PROTOCOL)
/* Okay, we know the lease duration. Now check the
failover state, if any. */
return 1;
}
break;
+
+ case permit_after:
+ if (cur_time > p->after)
+ return 1;
+ break;
}
}
return 0;
.\" see ``http://www.vix.com''. To learn more about Nominum, Inc., see
.\" ``http://www.nominum.com''.
.\"
-.\" $Id: dhcpd.conf.5,v 1.89 2007/10/27 19:15:36 each Exp $
+.\" $Id: dhcpd.conf.5,v 1.90 2007/10/31 19:13:33 dhankins Exp $
.\"
.TH dhcpd.conf 5
.SH NAME
want to renumber your network quickly, and thus want the server to
force all clients that have been allocated addresses from this pool to
obtain new addresses immediately when they next renew.
+.PP
+ \fBafter \fItime\fR\fB;\fR
+.PP
+If specified, this statement either allows or prevents allocation from
+this pool after a given date. This can be used when you want to move
+clients from one pool to another. The server adjusts the regular lease
+time so that the latest expiry time is at the given time+min-lease-time.
+A short min-lease-time enforces a step change, whereas a longer
+min-lease-time allows for a gradual change.
+\fItime\fR is either second since epoch, or a UTC time string e.g.
+4 2007/08/24 09:14:32 or a string with time zone offset in seconds
+e.g. 4 2007/08/24 11:14:32 -7200
.SH REFERENCE: PARAMETERS
The
.I adaptive-lease-time-threshold