Commit 99e8f4ee authored by Shawn Routhier's avatar Shawn Routhier
Browse files

[v4_1_esv]

Modify the nak_lease function to make some attempts to find a
server-identifier option to use for the NAK.
parent daf80830
......@@ -80,6 +80,12 @@ work on other platforms. Please report any problems and suggested fixes to
- Parsing unquoted base64 strings improved. Parser now properly handles
strings that contain reserved names. [ISC-Bugs #23048]
- Modify the nak_lease function to make some attempts to find a
server-identifier option to use for the NAK. This feature is
enabled by defining SERVER_ID_FOR_NAK in includes/site.h and
currently defaults to disabled.
[ISC-Bugs #25689]
Changes since 4.1-ESV-R6
- Existing legacy unit-tests have been migrated to Automated Test
......
......@@ -217,3 +217,14 @@
require the original functionality. */
/* #define RFC3315_PRE_ERRATA_2010_08 */
/* In previous versions of the code when the server generates a NAK
it doesn't attempt to determine if the configuration included a
server ID for that client. Defining this option causes the server
to make a modest effort to determine the server id when building
a NAK as a response. This effort will only check the first subnet
and pool associated with a shared subnet and will not check for
host declarations. With some configurations the server id
computed for a NAK may not match that computed for an ACK. */
/* #define SERVER_ID_FOR_NAK */
......@@ -1318,6 +1318,7 @@ void nak_lease (packet, cip)
struct sockaddr_in to;
struct in_addr from;
int result;
int got_source = 0;
struct dhcp_packet raw;
unsigned char nak = DHCPNAK;
struct packet outgoing;
......@@ -1369,8 +1370,96 @@ void nak_lease (packet, cip)
&i, 0, MDL);
save_option (&dhcp_universe, options, oc);
option_cache_dereference (&oc, MDL);
get_server_source_address(&from, options, packet);
#if defined(SERVER_ID_FOR_NAK)
/*
* Check to see if there is a server id we should use for the NAK.
* In order to minimize the effort involved we only check the
* global, shared_network and first subnet and pool on the
* shared_network (if they exist). We skip the other subnets
* and pools and don't check on the host declarations.
*
* We get the shared subnet from the packet and execute the statements
* then check for a server id. As we only want the server ID we
* execute the statements into a separate options area and then
* free that area when we finish
*/
if (packet->shared_network != NULL) {
struct option_state *sid_options = NULL;
struct data_string d;
struct option_cache *soc = NULL;
option_state_allocate (&sid_options, MDL);
/*
* If we have a subnet and group start with that else start
* with the shared network group. The first will recurse and
* include the second.
*/
if ((packet->shared_network->subnets != NULL) &&
(packet->shared_network->subnets->group != NULL)) {
execute_statements_in_scope(NULL, packet, NULL, NULL,
packet->options, sid_options,
&global_scope,
packet->shared_network->subnets->group,
NULL);
} else {
execute_statements_in_scope(NULL, packet, NULL, NULL,
packet->options, sid_options,
&global_scope,
packet->shared_network->group,
NULL);
}
/* do the pool if there is one */
if (packet->shared_network->pools != NULL) {
execute_statements_in_scope(NULL, packet, NULL, NULL,
packet->options, sid_options,
&global_scope,
packet->shared_network->pools->group,
packet->shared_network->group);
}
memset(&d, 0, sizeof(d));
i = DHO_DHCP_SERVER_IDENTIFIER;
oc = lookup_option(&dhcp_universe, sid_options, i);
if ((oc != NULL) &&
(evaluate_option_cache(&d, packet, NULL, NULL,
packet->options, sid_options,
&global_scope, oc, MDL))) {
if (d.len == sizeof(from)) {
/* We have a server id and it's the proper length
* for an address save the address and try to add
* it to the options list we are building for the
* response packet.
*/
memcpy(&from, d.data, sizeof(from));
got_source = 1;
if (option_cache_allocate(&soc, MDL) &&
(make_const_data(&soc->expression,
(unsigned char *)&from,
sizeof(from),
0, 1, MDL))) {
option_code_hash_lookup(&soc->option,
dhcp_universe.code_hash,
&i, 0, MDL);
save_option(&dhcp_universe, options,
soc);
}
if (soc != NULL)
option_cache_dereference(&soc, MDL);
}
data_string_forget(&d, MDL);
}
oc = NULL;
option_state_dereference (&sid_options, MDL);
}
#endif /* if defined(SERVER_ID_FOR_NAK) */
if (got_source == 0) {
get_server_source_address(&from, options, packet);
}
/* If there were agent options in the incoming packet, return
* them. We do not check giaddr to detect the presence of a
......@@ -2572,10 +2661,10 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
if (oc -> option)
option_reference(&(noc->option), oc->option,
MDL);
}
save_option (&dhcp_universe, state -> options, noc);
option_cache_dereference (&noc, MDL);
save_option (&dhcp_universe, state -> options, noc);
option_cache_dereference (&noc, MDL);
}
}
/* Now, if appropriate, put in DHCP-specific options that
......
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