2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-22 09:57:20 +00:00

- The server now limits clients that request multiple addresses to one

address per IA by default, which can be adjusted through the
  "limit-addrs-per-ia" configuration option.  [ISC-Bugs #17271]
This commit is contained in:
David Hankins 2007-11-20 18:34:37 +00:00
parent 703873ab37
commit b024480eba
5 changed files with 74 additions and 13 deletions

View File

@ -65,6 +65,10 @@ suggested fixes to <dhcp-users@isc.org>.
order to avoid cascading renewals in the event a server elects not to
extend one of multiple IAADDR leases.
- The server now limits clients that request multiple addresses to one
address per IA by default, which can be adjusted through the
"limit-addrs-per-ia" configuration option.
Changes since 4.0.0b2
- Clarified error message when lease limit exceeded

View File

@ -620,6 +620,7 @@ struct lease_state {
#define SV_PREFER_LIFETIME 53
#define SV_DHCPV6_LEASE_FILE_NAME 54
#define SV_DHCPV6_PID_FILE_NAME 55
#define SV_LIMIT_ADDRS_PER_IA 56
#if !defined (DEFAULT_PING_TIMEOUT)
# define DEFAULT_PING_TIMEOUT 1

View File

@ -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.90 2007/10/31 19:13:33 dhankins Exp $
.\" $Id: dhcpd.conf.5,v 1.91 2007/11/20 18:34:37 dhankins Exp $
.\"
.TH dhcpd.conf 5
.SH NAME
@ -2251,6 +2251,22 @@ environment variable.
.RE
.PP
The
.I limit-addrs-per-ia
statement
.RS 0.25i
.PP
.B limit-addrs-per-ia \fInumber\fB;\fR
.PP
By default, the DHCPv6 server will limit clients to one IAADDR per IA
option, meaning one address. If you wish to permit clients to hang onto
multiple addresses at a time, configure a larger \fInumber\fR here.
.PP
Note that there is no present method to configure the server to forcibly
configure the client with one IP address per each subnet on a shared network.
This is left to future work.
.RE
.PP
The
.I dhcpv6-lease-file-name
statement
.RS 0.25i

View File

@ -49,7 +49,8 @@ struct reply_state {
/* IA level persistent state */
unsigned ia_count;
isc_boolean_t client_addressed, static_lease;
unsigned client_addresses;
isc_boolean_t static_lease;
struct ia_na *ia_na;
struct ia_na *old_ia;
struct option_state *reply_ia;
@ -1244,7 +1245,7 @@ reply_process_ia(struct reply_state *reply, struct option_cache *ia) {
oc = lookup_option(&dhcpv6_universe, packet_ia, D6O_IAADDR);
reply->valid = reply->prefer = 0xffffffff;
reply->client_valid = reply->client_prefer = 0;
reply->client_addressed = ISC_FALSE;
reply->client_addresses = 0;
for (; oc != NULL ; oc = oc->next) {
status = reply_process_addr(reply, oc);
@ -1267,7 +1268,7 @@ reply_process_ia(struct reply_state *reply, struct option_cache *ia) {
* If we fell through the above and never gave the client
* an address, give it one now.
*/
if ((status != ISC_R_CANCELED) && !reply->client_addressed) {
if ((status != ISC_R_CANCELED) && (reply->client_addresses == 0)) {
status = find_client_address(reply);
/*
@ -1482,6 +1483,7 @@ reply_process_addr(struct reply_state *reply, struct option_cache *addr) {
struct group *group;
struct subnet *subnet;
struct iaddr tmp_addr;
struct option_cache *oc;
struct data_string iaaddr, data;
isc_result_t status = ISC_R_SUCCESS;
@ -1689,6 +1691,47 @@ reply_process_addr(struct reply_state *reply, struct option_cache *addr) {
group = reply->shared->group;
}
/*
* If client_addresses is nonzero, then the reply_process_is_addressed
* function has executed configuration state into the reply option
* cache. We will use that valid cache to derive configuration for
* whether or not to engage in additional addresses, and similar.
*/
if (reply->client_addresses != 0) {
unsigned limit = 1;
/*
* Does this client have "enough" addresses already? Default
* to one. Everybody gets one, and one should be enough for
* anybody.
*/
oc = lookup_option(&server_universe, reply->opt_state,
SV_LIMIT_ADDRS_PER_IA);
if (oc != NULL) {
if (!evaluate_option_cache(&data, reply->packet,
NULL, NULL,
reply->packet->options,
reply->opt_state,
scope, oc, MDL) ||
(data.len != 4)) {
log_error("reply_process_ia: unable to "
"evaluate addrs-per-ia value.");
status = ISC_R_FAILURE;
goto cleanup;
}
limit = getULong(data.data);
data_string_forget(&data, MDL);
}
/*
* If we wish to limit the client to a certain number of
* addresses, then omit the address from the reply.
*/
if (reply->client_addresses >= limit)
goto cleanup;
}
status = reply_process_is_addressed(reply, scope, group);
if (status != ISC_R_SUCCESS)
goto cleanup;
@ -1889,12 +1932,10 @@ reply_process_is_addressed(struct reply_state *reply,
oc = lookup_option(&server_universe, reply->opt_state,
SV_DEFAULT_LEASE_TIME);
if (oc != NULL) {
if (!evaluate_option_cache(&data, reply->packet, NULL,
NULL,
if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
reply->packet->options,
reply->opt_state,
&reply->lease->scope,
oc, MDL) ||
scope, oc, MDL) ||
(data.len != 4)) {
log_error("reply_process_ia: uanble to "
"evaluate default lease time");
@ -1918,12 +1959,10 @@ reply_process_is_addressed(struct reply_state *reply,
oc = lookup_option(&server_universe, reply->opt_state,
SV_PREFER_LIFETIME);
if (oc != NULL) {
if (!evaluate_option_cache(&data, reply->packet, NULL,
NULL,
if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
reply->packet->options,
reply->opt_state,
&reply->lease->scope,
oc, MDL) ||
scope, oc, MDL) ||
(data.len != 4)) {
log_error("reply_process_ia: unable to "
"evaluate preferred lease time");
@ -1989,7 +2028,7 @@ reply_process_is_addressed(struct reply_state *reply,
data_string_forget(&data, MDL);
if (status == ISC_R_SUCCESS)
reply->client_addressed = ISC_TRUE;
reply->client_addresses++;
return status;
}

View File

@ -237,6 +237,7 @@ static struct option server_options[] = {
{ "preferred-lifetime", "T", &server_universe, 53, 1 },
{ "dhcpv6-lease-file-name", "t", &server_universe, 54, 1 },
{ "dhcpv6-pid-file-name", "t", &server_universe, 55, 1 },
{ "limit-addrs-per-ia", "L", &server_universe, 56, 1 },
{ NULL, NULL, NULL, 0, 0 }
};