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

[master] Host declaration name can now be used in DNS forward name

Merges in rt21323.
This commit is contained in:
Thomas Markwalder 2014-11-19 10:56:17 -05:00
parent 21d3034757
commit d9b2a590e8
7 changed files with 218 additions and 13 deletions

View File

@ -146,6 +146,19 @@ by Eric Young (eay@cryptsoft.com).
[ISC-Bugs #36810]
[ISC-Bugs #20352]
- By default, the server will now choose the value to use in the forward DNS
name from the following in order of preference:
1. FQDN option if provided by the client
2. Host name option if provided by the client
3. Configured option host-name if defined
As before, this may be overridden by defining ddns-hostname to the desired
value (or expression). In addition, the server logic has been extended to
use the value of the host name declaration if use-host-decl-names is enabled
and no other value is available.
[ISC-Bugs #21323]
Changes since 4.3.1b1
- Modify the linux and openwrt dhclient scripts to process information

View File

@ -1253,6 +1253,70 @@ int binding_scope_reference (ptr, bp, file, line)
return 1;
}
/*!
* \brief Constructs a null-terminated data_string from a char* and length.
*
* Allocates a data_string and copies into it the given length of bytes
* from the given source, adding a terminating null if not present in the source
* at length-1.
*
* \param new_string pointer to the data_string to construct. Cannot be
* NULL. Note that its contents will be overwritten. Passing in the address
* of an allocated data_string will result in memory leaks.
* \param src data to be copied. Cannot be NULL.
* \param len length of the data to copied
*
* \return 1 - if the data_string is constructed successfully, 0 if
* target data_struct is NULL or the buffer allocation fails.
*/
int
data_string_new(struct data_string *new_string,
const char *src, unsigned int len,
const char *file, int line)
{
unsigned int copy_len = 0;
if (new_string == NULL) {
log_error("data_string_new: new_string cannot be NULL %s(%d)",
file, line);
return (0);
}
if (src == NULL) {
log_error("data_string_new: src cannot be NULL %s(%d)",
file, line);
return (0);
}
memset(new_string, 0, sizeof (struct data_string));
/* If we already have a NULL back off length by one. This lets
* us always just add a NULL at the end. */
copy_len = (len > 0 && src[len - 1 ] == 0) ? len - 1 : len;
/* Allocate the buffer, accounting for terminating null */
if (!buffer_allocate(&(new_string->buffer), copy_len + 1, MDL)) {
log_error("data_string_new: No memory %s(%d)", file, line);
return (0);
}
/* Only copy if there's something to copy */
if (copy_len > 0) {
memcpy(new_string->buffer->data, src, copy_len);
}
/* Always tack on the null */
new_string->buffer->data[copy_len + 1] = 0;
/* Update data_string accessor values. Note len does NOT include
* the NULL. */
new_string->data = new_string->buffer->data;
new_string->len = copy_len;
new_string->terminated = 1;
return (1);
}
/* Make a copy of the data in data_string, upping the buffer reference
count if there's a buffer. */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007,2009,2012 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2007,2009-2014 by Internet Systems Consortium, Inc. ("ISC")
*
* We test the functions provided in alloc.c here. These are very
* basic functions, and it is very important that they work correctly.
@ -27,6 +27,8 @@
#include <atf-c.h>
#include "dhcpd.h"
static const char* checkString (struct data_string* ds, const char *src);
ATF_TC(buffer_allocate);
ATF_TC_HEAD(buffer_allocate, tc) {
@ -387,6 +389,103 @@ ATF_TC_BODY(data_string_copy_nobuf, tc) {
}
ATF_TC(data_string_new);
ATF_TC_HEAD(data_string_new, tc) {
atf_tc_set_md_var(tc, "descr", "data_string_new test, "
"exercises data_string_new function");
}
ATF_TC_BODY(data_string_new, tc) {
struct data_string new_string;
const char *src = "Really? Latin? ... geeks";
int len_arg = 0;
const char *error;
/* Case 1: Call with an invalid data_string pointer, should fail */
if (data_string_new(NULL, src, len_arg, MDL)) {
atf_tc_fail("case 1: call should have failed");
}
/* Case 2: Passing in NULL src should fail */
if (data_string_new(&new_string, NULL, 10, MDL)) {
atf_tc_fail("case 2: did not return success");
}
/* Case 3: Call with valid params, length includes NULL */
len_arg = strlen(src) + 1;
if (data_string_new(&new_string, src, len_arg, MDL) == 0) {
atf_tc_fail("case 3: did not return success");
}
error = checkString(&new_string, src);
ATF_REQUIRE_MSG((error == NULL), "case 3: %s", error);
data_string_forget(&new_string, MDL);
/* Case 4: Call with valid params, length does not include NULL */
len_arg = 7;
if (data_string_new(&new_string, src, len_arg, MDL) == 0) {
atf_tc_fail("case 4: did not return success");
}
error = checkString(&new_string, "Really?");
ATF_REQUIRE_MSG((error == NULL), "case 4: %s", error);
data_string_forget(&new_string, MDL);
/* Case 5: Call with valid params, source string is "" */
len_arg = 0;
if (data_string_new(&new_string, "", len_arg, MDL) == 0) {
atf_tc_fail("case 5: did not return success");
}
error = checkString(&new_string, "");
ATF_REQUIRE_MSG((error == NULL), "case 4: %s", error);
data_string_forget(&new_string, MDL);
}
/* Helper function which tests validity of a data_string
*
* Verifies that the given data_string contains a null-terminated string
* equal to a given string.
*
* \param string data_string to test
* \param src text content string should contain
* \return returns NULL if data_string is validate or an error message
* describing why it is invalid
*/
const char* checkString (struct data_string* string,
const char* src) {
int src_len = strlen(src);
if (string->buffer == NULL) {
return ("buffer is NULL");
}
if (string->data != string->buffer->data) {
return ("data not set to buffer->data");
}
if (string->len != src_len) {
return ("len is wrong ");
}
if (string->terminated != 1) {
return ("terminated flag not set");
}
if (memcmp(string->data, src, src_len + 1)) {
return ("data content wrong");
}
return (NULL);
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, buffer_allocate);
@ -396,6 +495,7 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, data_string_forget_nobuf);
ATF_TP_ADD_TC(tp, data_string_copy);
ATF_TP_ADD_TC(tp, data_string_copy_nobuf);
ATF_TP_ADD_TC(tp, data_string_new);
return (atf_no_error());
}

View File

@ -2384,6 +2384,8 @@ int option_state_reference (struct option_state **,
struct option_state *, const char *, int);
int option_state_dereference (struct option_state **,
const char *, int);
int data_string_new(struct data_string *, const char *, unsigned int,
const char *, int);
void data_string_copy(struct data_string *, const struct data_string *,
const char *, int);
void data_string_forget (struct data_string *, const char *, int);

View File

@ -221,6 +221,22 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old,
else
s1 = 0;
/* If we don't have a host name based on ddns-hostname then use
* the host declaration name if there is one and use-host-decl-names
* is turned on. */
if ((s1 == 0) && (lease && lease->host && lease->host->name)) {
oc = lookup_option(&server_universe, options,
SV_USE_HOST_DECL_NAMES);
if (evaluate_boolean_option_cache(NULL, packet, lease,
NULL, packet->options,
options, scope, oc, MDL)) {
s1 = ((data_string_new(&ddns_hostname,
lease->host->name,
strlen(lease->host->name),
MDL) && ddns_hostname.len > 0));
}
}
oc = lookup_option(&server_universe, options, SV_DDNS_DOMAIN_NAME);
if (oc)
s2 = evaluate_option_cache(&ddns_domainname, packet, lease,

View File

@ -63,10 +63,9 @@ int server_identifier_matched;
/* This stuff is always executed to figure the default values for certain
ddns variables. */
char std_nsupdate [] = " \n\
option server.ddns-hostname = \n\
pick (option fqdn.hostname, option host-name); \n\
pick (option fqdn.hostname, option host-name, config-option host-name); \n\
option server.ddns-domainname = config-option domain-name; \n\
option server.ddns-rev-domainname = \"in-addr.arpa.\";";

View File

@ -1153,17 +1153,23 @@ IP address, it can update its own A record, assuming that the
.PP
If the server is configured not to allow client updates, or if the
client doesn\'t want to do its own update, the server will simply
choose a name for the client from either the \fBfqdn\fR option (if present)
or the hostname option (if present). It will use its own
domain name for the client. It will then update both the A and PTR
record, using the name that it chose for the client. If the client
sends a fully-qualified domain name in the \fBfqdn\fR option, the
server uses only the leftmost part of the domain name - in the
example above, "jschmoe" instead of "jschmoe.radish.org".
choose a name for the client. By default, the server will choose
from the following three values:
.PP
If the defaults for choosing the host name are not appropriate
1. \fBfqdn\fR option (if present)
2. hostname option (if present)
3. Configured hostname option (if defined).
.PP
If these defaults for choosing the host name are not appropriate
you can write your own statement to set the ddns-hostname variable
as you wish.
as you wish. If none of the above are found the server will use
the host declaration name (if one) and use-host-decl-names is on.
.PP
It will use its own domain name for the client. It will then update
both the A and PTR record, using the name that it chose for the client.
If the client sends a fully-qualified domain name in the \fBfqdn\fR option,
the server uses only the leftmost part of the domain name - in the example
above, "jschmoe" instead of "jschmoe.radish.org".
.PP
Further, if the \fIignore client-updates;\fR directive is used, then
the server will in addition send a response in the DHCP packet, using
@ -2931,6 +2937,11 @@ is equivalent to
}
.fi
.PP
Additionally, enabling use-host-decl-names instructs the server to use
the host declaration name in the the forward DNS name, if no other values
are available. This value selection process is discussed in more detail
under DNS updates.
.PP
An \fIoption host-name\fR statement within a host declaration will
override the use of the name in the host declaration.
.PP