Commit b1d3778c authored by David Hankins's avatar David Hankins

- 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.  [ISC-Bugs #17110]
parent e4a6be15
......@@ -59,6 +59,12 @@ suggested fixes to <dhcp-users@isc.org>.
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
......
......@@ -732,6 +732,8 @@ intern(char *atom, enum dhcp_token dfv) {
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"))
......
......@@ -843,13 +843,15 @@ void convert_num (cfile, buf, str, base, size)
* 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;
......@@ -1008,10 +1010,6 @@ TIME parse_date (cfile)
} 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 */
......@@ -1036,6 +1034,22 @@ TIME parse_date (cfile)
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
......
......@@ -752,9 +752,11 @@ struct permit {
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 {
......@@ -775,6 +777,9 @@ 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
......@@ -1691,6 +1696,7 @@ unsigned char *parse_numeric_aggregate PROTO ((struct parse *,
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 *));
......
......@@ -344,7 +344,8 @@ enum dhcp_token {
LL = 647,
RANGE6 = 648,
WHITESPACE = 649,
TOKEN_ALSO = 650
TOKEN_ALSO = 650,
AFTER = 651
};
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
......
......@@ -1344,6 +1344,8 @@ void parse_pool_statement (cfile, group, type)
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);
......@@ -1440,6 +1442,8 @@ void parse_pool_statement (cfile, group, type)
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)
......@@ -1522,6 +1526,24 @@ void parse_pool_statement (cfile, group, type)
"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);
......@@ -1535,6 +1557,8 @@ void parse_pool_statement (cfile, group, type)
case DENY:
permit_head = &pool -> prohibit_list;
/* remember the clause which leads to get_permit */
is_allow = 0;
goto get_permit;
case RBRACE:
......
......@@ -1451,6 +1451,8 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
TIME ping_timeout;
TIME lease_cltt;
struct in_addr from;
TIME remaining_time;
struct iaddr cip;
unsigned i, j;
int s1;
......@@ -2072,6 +2074,54 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
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, &lt->ip_addr.iabuf, 4);
nak_lease(packet, &cip);
free_lease_state (state, MDL);
lease_dereference (&lt, 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, &lt->ip_addr.iabuf, 4);
nak_lease(packet, &cip);
free_lease_state (state, MDL);
lease_dereference (&lt, 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;
......@@ -2079,6 +2129,7 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
lease_time = default_lease_time;
}
#if defined (FAILOVER_PROTOCOL)
/* Okay, we know the lease duration. Now check the
failover state, if any. */
......@@ -3839,6 +3890,11 @@ int permitted (packet, permit_list)
return 1;
}
break;
case permit_after:
if (cur_time > p->after)
return 1;
break;
}
}
return 0;
......
......@@ -28,7 +28,7 @@
.\" 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
......@@ -1831,6 +1831,18 @@ pool declaration for some reason, but hold it in reserve, or when you
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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment