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:
parent
21d3034757
commit
d9b2a590e8
13
RELNOTES
13
RELNOTES
@ -146,6 +146,19 @@ by Eric Young (eay@cryptsoft.com).
|
|||||||
[ISC-Bugs #36810]
|
[ISC-Bugs #36810]
|
||||||
[ISC-Bugs #20352]
|
[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
|
Changes since 4.3.1b1
|
||||||
|
|
||||||
- Modify the linux and openwrt dhclient scripts to process information
|
- Modify the linux and openwrt dhclient scripts to process information
|
||||||
|
@ -1253,6 +1253,70 @@ int binding_scope_reference (ptr, bp, file, line)
|
|||||||
return 1;
|
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
|
/* Make a copy of the data in data_string, upping the buffer reference
|
||||||
count if there's a buffer. */
|
count if there's a buffer. */
|
||||||
|
|
||||||
|
@ -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
|
* We test the functions provided in alloc.c here. These are very
|
||||||
* basic functions, and it is very important that they work correctly.
|
* basic functions, and it is very important that they work correctly.
|
||||||
@ -27,6 +27,8 @@
|
|||||||
#include <atf-c.h>
|
#include <atf-c.h>
|
||||||
#include "dhcpd.h"
|
#include "dhcpd.h"
|
||||||
|
|
||||||
|
static const char* checkString (struct data_string* ds, const char *src);
|
||||||
|
|
||||||
ATF_TC(buffer_allocate);
|
ATF_TC(buffer_allocate);
|
||||||
|
|
||||||
ATF_TC_HEAD(buffer_allocate, tc) {
|
ATF_TC_HEAD(buffer_allocate, tc) {
|
||||||
@ -187,7 +189,7 @@ ATF_TC_BODY(buffer_dereference, tc) {
|
|||||||
if (!buffer_reference(&b, a, MDL)) {
|
if (!buffer_reference(&b, a, MDL)) {
|
||||||
atf_tc_fail("buffer_reference() failed");
|
atf_tc_fail("buffer_reference() failed");
|
||||||
}
|
}
|
||||||
a->refcnt = 0; /* purposely set to invalid value */
|
a->refcnt = 0; /* purposely set to invalid value */
|
||||||
if (buffer_dereference(&a, MDL)) {
|
if (buffer_dereference(&a, MDL)) {
|
||||||
atf_tc_fail("buffer_dereference() succeeded on error input");
|
atf_tc_fail("buffer_dereference() succeeded on error input");
|
||||||
}
|
}
|
||||||
@ -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_TCS(tp)
|
||||||
{
|
{
|
||||||
ATF_TP_ADD_TC(tp, buffer_allocate);
|
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_forget_nobuf);
|
||||||
ATF_TP_ADD_TC(tp, data_string_copy);
|
ATF_TP_ADD_TC(tp, data_string_copy);
|
||||||
ATF_TP_ADD_TC(tp, data_string_copy_nobuf);
|
ATF_TP_ADD_TC(tp, data_string_copy_nobuf);
|
||||||
|
ATF_TP_ADD_TC(tp, data_string_new);
|
||||||
|
|
||||||
return (atf_no_error());
|
return (atf_no_error());
|
||||||
}
|
}
|
||||||
|
@ -2384,6 +2384,8 @@ int option_state_reference (struct option_state **,
|
|||||||
struct option_state *, const char *, int);
|
struct option_state *, const char *, int);
|
||||||
int option_state_dereference (struct option_state **,
|
int option_state_dereference (struct option_state **,
|
||||||
const char *, int);
|
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 *,
|
void data_string_copy(struct data_string *, const struct data_string *,
|
||||||
const char *, int);
|
const char *, int);
|
||||||
void data_string_forget (struct data_string *, const char *, int);
|
void data_string_forget (struct data_string *, const char *, int);
|
||||||
|
@ -221,6 +221,22 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old,
|
|||||||
else
|
else
|
||||||
s1 = 0;
|
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);
|
oc = lookup_option(&server_universe, options, SV_DDNS_DOMAIN_NAME);
|
||||||
if (oc)
|
if (oc)
|
||||||
s2 = evaluate_option_cache(&ddns_domainname, packet, lease,
|
s2 = evaluate_option_cache(&ddns_domainname, packet, lease,
|
||||||
|
@ -63,10 +63,9 @@ int server_identifier_matched;
|
|||||||
|
|
||||||
/* This stuff is always executed to figure the default values for certain
|
/* This stuff is always executed to figure the default values for certain
|
||||||
ddns variables. */
|
ddns variables. */
|
||||||
|
|
||||||
char std_nsupdate [] = " \n\
|
char std_nsupdate [] = " \n\
|
||||||
option server.ddns-hostname = \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-domainname = config-option domain-name; \n\
|
||||||
option server.ddns-rev-domainname = \"in-addr.arpa.\";";
|
option server.ddns-rev-domainname = \"in-addr.arpa.\";";
|
||||||
|
|
||||||
|
@ -1153,17 +1153,23 @@ IP address, it can update its own A record, assuming that the
|
|||||||
.PP
|
.PP
|
||||||
If the server is configured not to allow client updates, or if the
|
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
|
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)
|
choose a name for the client. By default, the server will choose
|
||||||
or the hostname option (if present). It will use its own
|
from the following three values:
|
||||||
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
|
.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
|
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
|
.PP
|
||||||
Further, if the \fIignore client-updates;\fR directive is used, then
|
Further, if the \fIignore client-updates;\fR directive is used, then
|
||||||
the server will in addition send a response in the DHCP packet, using
|
the server will in addition send a response in the DHCP packet, using
|
||||||
@ -2931,6 +2937,11 @@ is equivalent to
|
|||||||
}
|
}
|
||||||
.fi
|
.fi
|
||||||
.PP
|
.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
|
An \fIoption host-name\fR statement within a host declaration will
|
||||||
override the use of the name in the host declaration.
|
override the use of the name in the host declaration.
|
||||||
.PP
|
.PP
|
||||||
|
Loading…
x
Reference in New Issue
Block a user