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:
parent
703873ab37
commit
b024480eba
4
RELNOTES
4
RELNOTES
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 }
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user