2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-30 05:47:45 +00:00

[master] Fixed infinite-is-reserved and lease:flags setting via omapi

Merges in rt31179.
This commit is contained in:
Thomas Markwalder 2016-02-05 09:03:51 -05:00
parent 1d3fc4d0d8
commit 606f272018
4 changed files with 112 additions and 23 deletions

View File

@ -600,6 +600,13 @@ by Eric Young (eay@cryptsoft.com).
(typically 1) in the outbound upstream packets. (typically 1) in the outbound upstream packets.
[ISC-Bugs #37426] [ISC-Bugs #37426]
- The server will now correctly treat a lease as reserved when the client
requests an infinite lease time (i.e. OxFFFFFFFF) and "infinite-is-reserved"
is enabled. Prior to this the server would halt. In addition, corrections
were made to the server to allow a lease's flags field to be set via omapi.
Prior to this, the server, depending on the host architecture, would
incorrectly parse the new flags value from the omapi message.
[ISC-Bugs #31179]
Changes since 4.3.1b1 Changes since 4.3.1b1

View File

@ -3,7 +3,7 @@
DHCP Protocol engine. */ DHCP Protocol engine. */
/* /*
* Copyright (c) 2004-2015 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2004-2016 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-2003 by Internet Software Consortium * Copyright (c) 1995-2003 by Internet Software Consortium
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
@ -2909,7 +2909,17 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
memcpy (&lt -> hardware_addr.hbuf [1], packet -> raw -> chaddr, memcpy (&lt -> hardware_addr.hbuf [1], packet -> raw -> chaddr,
sizeof packet -> raw -> chaddr); sizeof packet -> raw -> chaddr);
lt -> flags = lease -> flags & ~PERSISTENT_FLAGS; /*
* If client has requested the lease become infinite, then it
* doens't qualify for reuse even if it's younger than the
* dhcp-cache-threshold.
*/
if ((lt->flags & RESERVED_LEASE) && !(lease->flags & RESERVED_LEASE)) {
log_debug ("Cannot reuse: lease is changing to RESERVED");
lease->cannot_reuse = 1;
}
lt->flags |= lease->flags & ~PERSISTENT_FLAGS;
/* If there are statements to execute when the lease is /* If there are statements to execute when the lease is
committed, execute them. */ committed, execute them. */

View File

@ -3,7 +3,7 @@
Server-specific in-memory database support. */ Server-specific in-memory database support. */
/* /*
* Copyright (c) 2011-2015 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2011-2016 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2004-2009 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2004-2009 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1996-2003 by Internet Software Consortium * Copyright (c) 1996-2003 by Internet Software Consortium
* *
@ -1136,7 +1136,6 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate, from_pool)
if (pimmediate && !commit) if (pimmediate && !commit)
return 0; return 0;
#endif #endif
/* If there is no sample lease, just do the move. */ /* If there is no sample lease, just do the move. */
if (!lease) if (!lease)
goto just_move_it; goto just_move_it;
@ -1223,8 +1222,6 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate, from_pool)
host_dereference (&comp -> host, MDL); host_dereference (&comp -> host, MDL);
host_reference (&comp -> host, lease -> host, MDL); host_reference (&comp -> host, lease -> host, MDL);
comp -> hardware_addr = lease -> hardware_addr; comp -> hardware_addr = lease -> hardware_addr;
comp -> flags = ((lease -> flags & ~PERSISTENT_FLAGS) |
(comp -> flags & ~EPHEMERAL_FLAGS));
if (comp -> scope) if (comp -> scope)
binding_scope_dereference (&comp -> scope, MDL); binding_scope_dereference (&comp -> scope, MDL);
if (lease -> scope) { if (lease -> scope) {
@ -1375,6 +1372,14 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate, from_pool)
timer sequence. */ timer sequence. */
LEASE_REMOVEP(lq, comp); LEASE_REMOVEP(lq, comp);
/* Now that we've done the flag-affected queue removal
* we can update the new lease's flags, if there's an
* existing lease */
if (lease) {
comp->flags = ((lease->flags & ~PERSISTENT_FLAGS) |
(comp->flags & ~EPHEMERAL_FLAGS));
}
/* Make the state transition. */ /* Make the state transition. */
if (commit || !pimmediate) if (commit || !pimmediate)
make_binding_state_transition (comp); make_binding_state_transition (comp);

View File

@ -3,7 +3,7 @@
OMAPI object interfaces for the DHCP server. */ OMAPI object interfaces for the DHCP server. */
/* /*
* Copyright (c) 2012-2015 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2012-2016 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2004-2009 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2004-2009 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1999-2003 by Internet Software Consortium * Copyright (c) 1999-2003 by Internet Software Consortium
* *
@ -41,6 +41,9 @@ static isc_result_t class_lookup (omapi_object_t **,
omapi_object_t *, omapi_object_t *, omapi_object_t *, omapi_object_t *,
omapi_object_type_t *); omapi_object_type_t *);
static isc_result_t update_lease_flags(struct lease* lease,
omapi_typed_data_t *value);
omapi_object_type_t *dhcp_type_lease; omapi_object_type_t *dhcp_type_lease;
omapi_object_type_t *dhcp_type_pool; omapi_object_type_t *dhcp_type_pool;
omapi_object_type_t *dhcp_type_class; omapi_object_type_t *dhcp_type_class;
@ -269,22 +272,7 @@ isc_result_t dhcp_lease_set_value (omapi_object_t *h,
piaddr(lease->ip_addr), old_lease_end, lease_end); piaddr(lease->ip_addr), old_lease_end, lease_end);
return ISC_R_IOERROR; return ISC_R_IOERROR;
} else if (!omapi_ds_strcmp(name, "flags")) { } else if (!omapi_ds_strcmp(name, "flags")) {
u_int8_t oldflags; return (update_lease_flags(lease, value));
if (value->type != omapi_datatype_data)
return DHCP_R_INVALIDARG;
oldflags = lease->flags;
lease->flags = (value->u.buffer.value[0] & EPHEMERAL_FLAGS) |
(lease->flags & ~EPHEMERAL_FLAGS);
if(oldflags == lease->flags)
return ISC_R_SUCCESS;
if (!supersede_lease(lease, NULL, 1, 1, 1, 0)) {
log_error("Failed to update flags for lease %s.",
piaddr(lease->ip_addr));
return ISC_R_IOERROR;
}
return ISC_R_SUCCESS;
} else if (!omapi_ds_strcmp (name, "billing-class")) { } else if (!omapi_ds_strcmp (name, "billing-class")) {
return DHCP_R_UNCHANGED; /* XXX carefully allow change. */ return DHCP_R_UNCHANGED; /* XXX carefully allow change. */
} else if (!omapi_ds_strcmp (name, "hardware-address")) { } else if (!omapi_ds_strcmp (name, "hardware-address")) {
@ -321,6 +309,85 @@ isc_result_t dhcp_lease_set_value (omapi_object_t *h,
return ISC_R_IOERROR; return ISC_R_IOERROR;
} }
/*
* \brief Updates the lease's flags to a given value
*
* In order to update the lease's flags, we make a copy of the
* lease, and update the copy's flags with the new value.
* We then use the updated copy as the second parameter to a
* call to supersede_lease(). This ensures that the lease
* moves between queues correctly. This is critical when
* the RESERVED_LEASE flag is being changed.
*
* Note that only the EPHEMERAL flags are permitted to be changed.
*
* \param lease - pointer to the lease to update
* \param value - omapi data value containing the new flags value
*
* \return ISC_R_SUCCESS if the lease was successfully updated,
* DHCP_R_UNCHANGED if new value would result in no change to the
* lease's flags, or an appropriate status on other errors
*/
static isc_result_t update_lease_flags(struct lease* lease,
omapi_typed_data_t *value)
{
u_int8_t oldflags;
u_int8_t newflags;
struct lease* lupdate = NULL;
isc_result_t status;
/* Grab the requested flags value. We (the server) send flags
* out as 1-byte, so we expect clients to do the same. However
* omshell, will send a network-ordered 4 byte integer if the
* input is "set flags = <n>", so we'll accomdate that too. */
if (value->u.buffer.len == 1) {
newflags = value->u.buffer.value[0];
} else {
unsigned long tmp;
status = omapi_get_int_value (&tmp, value);
if (status != ISC_R_SUCCESS) {
return (status);
}
newflags = (u_int8_t)tmp;
}
/* Save off the current flags value. */
oldflags = lease->flags;
/* The new value must preserve all PERSISTANT_FLAGS */
newflags = ((lease->flags & ~EPHEMERAL_FLAGS) |
(newflags & EPHEMERAL_FLAGS));
/* If there's no net change, we're done */
if (oldflags == newflags) {
return (DHCP_R_UNCHANGED);
}
/* Make a copy of the lease. */
if (!lease_copy(&lupdate, lease, MDL)) {
return (ISC_R_FAILURE);
}
/* Set the copy's flags to the new value */
lupdate->flags = newflags;
/* Attempt to update the lease */
if (!supersede_lease(lease, lupdate, 1, 1, 1, 0)) {
log_error("Failed to update flags for lease %s.",
piaddr(lease->ip_addr));
status = ISC_R_FAILURE;
} else {
log_debug ("lease flags changed from %x to %x for lease %s.",
oldflags, newflags, piaddr(lease->ip_addr));
status = ISC_R_SUCCESS;
}
lease_dereference(&lupdate, MDL);
return (status);
}
isc_result_t dhcp_lease_get_value (omapi_object_t *h, omapi_object_t *id, isc_result_t dhcp_lease_get_value (omapi_object_t *h, omapi_object_t *id,
omapi_data_string_t *name, omapi_data_string_t *name,