mirror of
https://github.com/isc-projects/bind9.git
synced 2026-03-27 04:43:08 -04:00
Merge branch '4419-add-the-ability-to-add-the-ul-edns-option-to-update-messages' into 'main'
Resolve "Add the ability to add the UL EDNS option to UPDATE messages" Closes #4419 See merge request isc-projects/bind9!8469
This commit is contained in:
commit
5ce1ff5214
8 changed files with 200 additions and 4 deletions
3
CHANGES
3
CHANGES
|
|
@ -1,3 +1,6 @@
|
|||
6327. [func] Nsupdate can now set the UL EDNS option when sending
|
||||
UPDATE requests. [GL #4419]
|
||||
|
||||
6326. [func] Add workaround to enforce dynamic linker to pull
|
||||
jemalloc earlier than libc to ensure all memory
|
||||
allocations are done via jemalloc. [GL #4404]
|
||||
|
|
|
|||
|
|
@ -1388,6 +1388,7 @@ typedef struct dig_ednsoptname {
|
|||
|
||||
dig_ednsoptname_t optnames[] = {
|
||||
{ 1, "LLQ" }, /* draft-sekar-dns-llq */
|
||||
{ 2, "UL" }, /* draft-ietf-dnssd-update-lease */
|
||||
{ 3, "NSID" }, /* RFC 5001 */
|
||||
{ 5, "DAU" }, /* RFC 6975 */
|
||||
{ 6, "DHU" }, /* RFC 6975 */
|
||||
|
|
|
|||
|
|
@ -102,6 +102,8 @@
|
|||
|
||||
#define DNSDEFAULTPORT 53
|
||||
|
||||
#define DEFAULT_EDNS_BUFSIZE 1232
|
||||
|
||||
/* Number of addresses to request from isc_getaddresses() */
|
||||
#define MAX_SERVERADDRS 4
|
||||
|
||||
|
|
@ -175,6 +177,8 @@ static isc_mutex_t answer_lock;
|
|||
static dns_message_t *answer = NULL;
|
||||
static uint32_t default_ttl = 0;
|
||||
static bool default_ttl_set = false;
|
||||
static uint32_t lease = 0, keylease = 0;
|
||||
static bool lease_set = false, keylease_set = false;
|
||||
static bool checknames = true;
|
||||
static bool checksvcb = true;
|
||||
static const char *resolvconf = RESOLV_CONF;
|
||||
|
|
@ -1518,6 +1522,90 @@ evaluate_prereq(char *cmdline) {
|
|||
return (make_prereq(cmdline, ispositive, isrrset));
|
||||
}
|
||||
|
||||
static void
|
||||
updateopt(void) {
|
||||
isc_result_t result;
|
||||
dns_ednsopt_t ednsopts[1];
|
||||
unsigned char ul[8];
|
||||
unsigned int count = 0;
|
||||
|
||||
if (lease_set) {
|
||||
isc_buffer_t b;
|
||||
INSIST(count < ARRAY_SIZE(ednsopts));
|
||||
ednsopts[count++] = (dns_ednsopt_t){ .code = DNS_OPT_UL,
|
||||
.length = keylease_set ? 8
|
||||
: 4,
|
||||
.value = ul };
|
||||
|
||||
isc_buffer_init(&b, ul, sizeof(ul));
|
||||
isc_buffer_putuint32(&b, lease);
|
||||
isc_buffer_putuint32(&b, keylease);
|
||||
}
|
||||
|
||||
if (count != 0) {
|
||||
dns_rdataset_t *opt = NULL;
|
||||
result = dns_message_buildopt(updatemsg, &opt, 0,
|
||||
DEFAULT_EDNS_BUFSIZE, 0, ednsopts,
|
||||
count);
|
||||
check_result(result, "dns_message_buildopt");
|
||||
result = dns_message_setopt(updatemsg, opt);
|
||||
check_result(result, "dns_message_setopt");
|
||||
} else {
|
||||
result = dns_message_setopt(updatemsg, NULL);
|
||||
check_result(result, "dns_message_setopt");
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
evaluate_lease(char *cmdline) {
|
||||
char *word;
|
||||
isc_result_t result;
|
||||
uint32_t value1, value2;
|
||||
|
||||
word = nsu_strsep(&cmdline, " \t\r\n");
|
||||
if (word == NULL || *word == 0) {
|
||||
fprintf(stderr, "could not read ttl\n");
|
||||
return (STATUS_SYNTAX);
|
||||
}
|
||||
|
||||
if (!strcasecmp(word, "none")) {
|
||||
lease = 0;
|
||||
lease_set = false;
|
||||
keylease = 0;
|
||||
keylease_set = false;
|
||||
updateopt();
|
||||
return (STATUS_MORE);
|
||||
}
|
||||
|
||||
result = isc_parse_uint32(&value1, word, 10);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (STATUS_SYNTAX);
|
||||
}
|
||||
|
||||
word = nsu_strsep(&cmdline, " \t\r\n");
|
||||
if (word == NULL || *word == 0) {
|
||||
lease = value1;
|
||||
lease_set = true;
|
||||
keylease = 0;
|
||||
keylease_set = false;
|
||||
updateopt();
|
||||
return (STATUS_MORE);
|
||||
}
|
||||
|
||||
result = isc_parse_uint32(&value2, word, 10);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (STATUS_SYNTAX);
|
||||
}
|
||||
|
||||
lease = value1;
|
||||
lease_set = true;
|
||||
keylease = value2;
|
||||
keylease_set = true;
|
||||
updateopt();
|
||||
|
||||
return (STATUS_MORE);
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
evaluate_server(char *cmdline) {
|
||||
char *word, *server;
|
||||
|
|
@ -2222,6 +2310,9 @@ do_next_command(char *cmdline) {
|
|||
if (strcasecmp(word, "add") == 0) {
|
||||
return (update_addordelete(cmdline, false));
|
||||
}
|
||||
if (strcasecmp(word, "lease") == 0) {
|
||||
return (evaluate_lease(cmdline));
|
||||
}
|
||||
if (strcasecmp(word, "server") == 0) {
|
||||
return (evaluate_server(cmdline));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -323,6 +323,11 @@ The command formats and their meanings are as follows:
|
|||
By default check-svcb processing is on. If check-svcb processing
|
||||
fails, the record is not added to the UPDATE message.
|
||||
|
||||
``lease time [keytime]``
|
||||
Set the EDNS Update Lease (UL) option to value to ``time`` and
|
||||
optionally also set the key lease time to ``keytime`` in seconds.
|
||||
If ``time`` is ``none`` the lease times are cleared.
|
||||
|
||||
``prereq nxdomain domain-name``
|
||||
This command requires that no resource record of any type exist with the name
|
||||
``domain-name``.
|
||||
|
|
|
|||
|
|
@ -562,6 +562,25 @@ if [ -x "$DIG" ]; then
|
|||
status=$((status + ret))
|
||||
|
||||
n=$((n + 1))
|
||||
echo_i "checking ednsopt UL prints as expected (single lease) ($n)"
|
||||
ret=0
|
||||
dig_with_opts @10.53.0.3 +ednsopt=UL:00000e10 +qr a.example >dig.out.test$n 2>&1 || ret=1
|
||||
pat='UL: 3600 (1 hour)'
|
||||
grep "$pat" dig.out.test$n >/dev/null || ret=1
|
||||
if [ $ret -ne 0 ]; then echo_i "failed"; fi
|
||||
status=$((status + ret))
|
||||
n=$((n + 1))
|
||||
|
||||
n=$((n + 1))
|
||||
echo_i "checking ednsopt UL prints as expected (split lease) ($n)"
|
||||
ret=0
|
||||
dig_with_opts @10.53.0.3 +ednsopt=UL:00000e1000127500 +qr a.example >dig.out.test$n 2>&1 || ret=1
|
||||
pat='UL: 3600/1209600 (1 hour/2 weeks)'
|
||||
grep "$pat" dig.out.test$n >/dev/null || ret=1
|
||||
if [ $ret -ne 0 ]; then echo_i "failed"; fi
|
||||
status=$((status + ret))
|
||||
n=$((n + 1))
|
||||
|
||||
echo_i "checking ednsopt LLQ prints as expected ($n)"
|
||||
ret=0
|
||||
dig_with_opts @10.53.0.3 +ednsopt=llq:0001000200001234567812345678fefefefe +qr a.example >dig.out.test$n 2>&1 || ret=1
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@
|
|||
|
||||
/*%< EDNS0 extended OPT codes */
|
||||
#define DNS_OPT_LLQ 1 /*%< LLQ opt code */
|
||||
#define DNS_OPT_UL 2 /*%< UL opt code */
|
||||
#define DNS_OPT_NSID 3 /*%< NSID opt code */
|
||||
#define DNS_OPT_CLIENT_SUBNET 8 /*%< client subnet opt code */
|
||||
#define DNS_OPT_EXPIRE 9 /*%< EXPIRE opt code */
|
||||
|
|
@ -1113,14 +1114,14 @@ dns_message_getopt(dns_message_t *msg);
|
|||
isc_result_t
|
||||
dns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt);
|
||||
/*%<
|
||||
* Set the OPT record for 'msg'.
|
||||
* Set/clear the OPT record for 'msg'.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'msg' is a valid message with rendering intent
|
||||
* and no sections have been rendered.
|
||||
*
|
||||
*\li 'opt' is a valid OPT record.
|
||||
*\li 'opt' is a valid OPT record or NULL.
|
||||
*
|
||||
* Ensures:
|
||||
*
|
||||
|
|
|
|||
|
|
@ -2707,12 +2707,17 @@ dns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt) {
|
|||
*/
|
||||
|
||||
REQUIRE(DNS_MESSAGE_VALID(msg));
|
||||
REQUIRE(opt->type == dns_rdatatype_opt);
|
||||
REQUIRE(opt == NULL || DNS_RDATASET_VALID(opt));
|
||||
REQUIRE(opt == NULL || opt->type == dns_rdatatype_opt);
|
||||
REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
|
||||
REQUIRE(msg->state == DNS_SECTION_ANY);
|
||||
|
||||
msgresetopt(msg);
|
||||
|
||||
if (opt == NULL) {
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
result = dns_rdataset_first(opt);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
|
|
@ -3428,7 +3433,7 @@ dns_message_pseudosectiontoyaml(dns_message_t *msg, dns_pseudosection_t section,
|
|||
dns_rdataset_t *ps = NULL;
|
||||
const dns_name_t *name = NULL;
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
char buf[sizeof("1234567890")];
|
||||
char buf[sizeof("/1234567890")];
|
||||
uint32_t mbz;
|
||||
dns_rdata_t rdata;
|
||||
isc_buffer_t optbuf;
|
||||
|
|
@ -3520,6 +3525,39 @@ dns_message_pseudosectiontoyaml(dns_message_t *msg, dns_pseudosection_t section,
|
|||
ADD_STRING(target, "\n");
|
||||
continue;
|
||||
}
|
||||
} else if (optcode == DNS_OPT_UL) {
|
||||
INDENT(style);
|
||||
ADD_STRING(target, "UL:");
|
||||
if (optlen == 4U || optlen == 8U) {
|
||||
uint32_t secs, key = 0;
|
||||
secs = isc_buffer_getuint32(&optbuf);
|
||||
snprintf(buf, sizeof(buf), " %u", secs);
|
||||
ADD_STRING(target, buf);
|
||||
if (optlen == 8U) {
|
||||
key = isc_buffer_getuint32(
|
||||
&optbuf);
|
||||
snprintf(buf, sizeof(buf),
|
||||
"/%u", key);
|
||||
ADD_STRING(target, buf);
|
||||
}
|
||||
ADD_STRING(target, " (");
|
||||
result = dns_ttl_totext(secs, true,
|
||||
true, target);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
if (optlen == 8U) {
|
||||
ADD_STRING(target, "/");
|
||||
result = dns_ttl_totext(
|
||||
key, true, true,
|
||||
target);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
ADD_STRING(target, ")\n");
|
||||
continue;
|
||||
}
|
||||
} else if (optcode == DNS_OPT_NSID) {
|
||||
INDENT(style);
|
||||
ADD_STRING(target, "NSID:");
|
||||
|
|
@ -3880,6 +3918,38 @@ dns_message_pseudosectiontotext(dns_message_t *msg, dns_pseudosection_t section,
|
|||
ADD_STRING(target, "\n");
|
||||
continue;
|
||||
}
|
||||
} else if (optcode == DNS_OPT_UL) {
|
||||
ADD_STRING(target, "; UL:");
|
||||
if (optlen == 4U || optlen == 8U) {
|
||||
uint32_t secs, key = 0;
|
||||
secs = isc_buffer_getuint32(&optbuf);
|
||||
snprintf(buf, sizeof(buf), " %u", secs);
|
||||
ADD_STRING(target, buf);
|
||||
if (optlen == 8U) {
|
||||
key = isc_buffer_getuint32(
|
||||
&optbuf);
|
||||
snprintf(buf, sizeof(buf),
|
||||
"/%u", key);
|
||||
ADD_STRING(target, buf);
|
||||
}
|
||||
ADD_STRING(target, " (");
|
||||
result = dns_ttl_totext(secs, true,
|
||||
true, target);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
if (optlen == 8U) {
|
||||
ADD_STRING(target, "/");
|
||||
result = dns_ttl_totext(
|
||||
key, true, true,
|
||||
target);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
ADD_STRING(target, ")\n");
|
||||
continue;
|
||||
}
|
||||
} else if (optcode == DNS_OPT_NSID) {
|
||||
ADD_STRING(target, "; NSID:");
|
||||
} else if (optcode == DNS_OPT_COOKIE) {
|
||||
|
|
|
|||
|
|
@ -129,6 +129,12 @@ fromwire_opt(ARGS_FROMWIRE) {
|
|||
}
|
||||
isc_region_consume(&sregion, length);
|
||||
break;
|
||||
case DNS_OPT_UL:
|
||||
if (length != 4U && length != 8U) {
|
||||
return (DNS_R_OPTERR);
|
||||
}
|
||||
isc_region_consume(&sregion, length);
|
||||
break;
|
||||
case DNS_OPT_CLIENT_SUBNET: {
|
||||
uint16_t family;
|
||||
uint8_t addrlen;
|
||||
|
|
|
|||
Loading…
Reference in a new issue