diff options
-rw-r--r-- | RELNOTES | 7 | ||||
-rw-r--r-- | server/dhcp.c | 14 | ||||
-rw-r--r-- | server/mdb.c | 13 | ||||
-rw-r--r-- | server/omapi.c | 101 |
4 files changed, 112 insertions, 23 deletions
@@ -600,6 +600,13 @@ by Eric Young (eay@cryptsoft.com). (typically 1) in the outbound upstream packets. [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 diff --git a/server/dhcp.c b/server/dhcp.c index 5969895c..dcbadc39 100644 --- a/server/dhcp.c +++ b/server/dhcp.c @@ -3,7 +3,7 @@ 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 * * 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 (< -> hardware_addr.hbuf [1], 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 committed, execute them. */ diff --git a/server/mdb.c b/server/mdb.c index 99f1910f..ed89b5b3 100644 --- a/server/mdb.c +++ b/server/mdb.c @@ -3,7 +3,7 @@ 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) 1996-2003 by Internet Software Consortium * @@ -1136,7 +1136,6 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate, from_pool) if (pimmediate && !commit) return 0; #endif - /* If there is no sample lease, just do the move. */ if (!lease) goto just_move_it; @@ -1223,8 +1222,6 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate, from_pool) host_dereference (&comp -> host, MDL); host_reference (&comp -> host, lease -> host, MDL); comp -> hardware_addr = lease -> hardware_addr; - comp -> flags = ((lease -> flags & ~PERSISTENT_FLAGS) | - (comp -> flags & ~EPHEMERAL_FLAGS)); if (comp -> scope) binding_scope_dereference (&comp -> scope, MDL); if (lease -> scope) { @@ -1375,6 +1372,14 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate, from_pool) timer sequence. */ 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. */ if (commit || !pimmediate) make_binding_state_transition (comp); diff --git a/server/omapi.c b/server/omapi.c index 5756d294..60e35f3f 100644 --- a/server/omapi.c +++ b/server/omapi.c @@ -3,7 +3,7 @@ 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) 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_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_pool; 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); return ISC_R_IOERROR; } else if (!omapi_ds_strcmp(name, "flags")) { - u_int8_t oldflags; - - 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; + return (update_lease_flags(lease, value)); } else if (!omapi_ds_strcmp (name, "billing-class")) { return DHCP_R_UNCHANGED; /* XXX carefully allow change. */ } 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; } +/* + * \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, omapi_data_string_t *name, |