Add method to set extended DNS error
Add a new parameter to 'ns_client_t' to store potential extended DNS error. Reset when the client request ends, or is put back. Add defines for all well-known info-codes. Update the number of DNS_EDNSOPTIONS that we are willing to set. Create a new function to set the extended error for a client reply.
This commit is contained in:
@@ -112,8 +112,49 @@
|
||||
|
||||
/*%< Experimental options [65001...65534] as per RFC6891 */
|
||||
|
||||
/*%< The number of EDNS options we know about. */
|
||||
#define DNS_EDNSOPTIONS 7
|
||||
/*%<
|
||||
* The maximum number of EDNS options we allow to set. Reserve space for the
|
||||
* options we know about. Extended DNS Errors may occur multiple times, but we
|
||||
* will set only one per message (for now).
|
||||
*/
|
||||
#define DNS_EDNSOPTIONS 8
|
||||
|
||||
/*%< EDNS0 extended DNS errors */
|
||||
#define DNS_EDE_OTHER 0 /*%< Other Error */
|
||||
#define DNS_EDE_DNSKEYALG 1 /*%< Unsupported DNSKEY Algorithm */
|
||||
#define DNS_EDE_DSDIGESTTYPE 2 /*%< Unsupported DS Digest Type */
|
||||
#define DNS_EDE_STALEANSWER 3 /*%< Stale Answer */
|
||||
#define DNS_EDE_FORGEDANSWER 4 /*%< Forged Answer */
|
||||
#define DNS_EDE_DNSSECINDETERMINATE 5 /*%< DNSSEC Indeterminate */
|
||||
#define DNS_EDE_DNSSECBOGUS 6 /*%< DNSSEC Bogus */
|
||||
#define DNS_EDE_SIGNATUREEXPIRED 7 /*%< Signature Expired */
|
||||
#define DNS_EDE_SIGNATURENOTYETVALID 8 /*%< Signature Not Yet Valid */
|
||||
#define DNS_EDE_DNSKEYMISSING 9 /*%< DNSKEY Missing */
|
||||
#define DNS_EDE_RRSIGSMISSING 10 /*%< RRSIGs Missing */
|
||||
#define DNS_EDE_NOZONEKEYBITSET 11 /*%< No Zone Key Bit Set */
|
||||
#define DNS_EDE_NSECMISSING 12 /*%< NSEC Missing */
|
||||
#define DNS_EDE_CACHEDERROR 13 /*%< Cached Error */
|
||||
#define DNS_EDE_NOTREADY 14 /*%< Not Ready */
|
||||
#define DNS_EDE_BLOCKED 15 /*%< Blocked */
|
||||
#define DNS_EDE_CENSORED 16 /*%< Censored */
|
||||
#define DNS_EDE_FILTERED 17 /*%< Filtered */
|
||||
#define DNS_EDE_PROHIBITED 18 /*%< Prohibited */
|
||||
#define DNS_EDE_STALENXANSWER 19 /*%< Stale NXDomain Answer */
|
||||
#define DNS_EDE_NOTAUTH 20 /*%< Not Authoritative */
|
||||
#define DNS_EDE_NOTSUPPORTED 21 /*%< Not Supported */
|
||||
#define DNS_EDE_NOREACHABLEAUTH 22 /*%< No Reachable Authority */
|
||||
#define DNS_EDE_NETWORKERROR 23 /*%< Network Error */
|
||||
#define DNS_EDE_INVALIDDATA 24 /*%< Invalid Data */
|
||||
|
||||
/*
|
||||
* From RFC 8914:
|
||||
* Because long EXTRA-TEXT fields may trigger truncation (which is undesirable
|
||||
* given the supplemental nature of EDE), implementers and operators creating
|
||||
* EDE options SHOULD avoid lengthy EXTRA-TEXT contents.
|
||||
*
|
||||
* Following this advice we limit the EXTRA-TEXT length to 64 characters.
|
||||
*/
|
||||
#define DNS_EDE_EXTRATEXT_LEN 64
|
||||
|
||||
#define DNS_MESSAGE_REPLYPRESERVE (DNS_MESSAGEFLAG_RD | DNS_MESSAGEFLAG_CD)
|
||||
#define DNS_MESSAGEEXTFLAG_REPLYPRESERVE (DNS_MESSAGEEXTFLAG_DO)
|
||||
|
||||
@@ -163,6 +163,56 @@ ns_client_settimeout(ns_client_t *client, unsigned int seconds) {
|
||||
/* XXXWPK TODO use netmgr to set timeout */
|
||||
}
|
||||
|
||||
static void
|
||||
client_extendederror_reset(ns_client_t *client) {
|
||||
if (client->ede == NULL) {
|
||||
return;
|
||||
}
|
||||
isc_mem_put(client->mctx, client->ede->value, client->ede->length);
|
||||
isc_mem_put(client->mctx, client->ede, sizeof(dns_ednsopt_t));
|
||||
client->ede = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
ns_client_extendederror(ns_client_t *client, uint16_t code, const char *text) {
|
||||
unsigned char ede[DNS_EDE_EXTRATEXT_LEN + 2];
|
||||
isc_buffer_t buf;
|
||||
uint16_t len = sizeof(uint16_t);
|
||||
|
||||
REQUIRE(NS_CLIENT_VALID(client));
|
||||
|
||||
if (client->ede != NULL) {
|
||||
ns_client_log(client, NS_LOGCATEGORY_CLIENT,
|
||||
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1),
|
||||
"already have ede, ignoring %u %s", code,
|
||||
text == NULL ? "(null)" : text);
|
||||
return;
|
||||
}
|
||||
|
||||
ns_client_log(client, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_CLIENT,
|
||||
ISC_LOG_DEBUG(1), "set ede: info-code %u extra-text %s",
|
||||
code, text == NULL ? "(null)" : text);
|
||||
|
||||
isc_buffer_init(&buf, ede, sizeof(ede));
|
||||
isc_buffer_putuint16(&buf, code);
|
||||
if (text != NULL && strlen(text) > 0) {
|
||||
if (strlen(text) < DNS_EDE_EXTRATEXT_LEN) {
|
||||
isc_buffer_putstr(&buf, text);
|
||||
len += (uint16_t)(strlen(text));
|
||||
} else {
|
||||
ns_client_log(client, NS_LOGCATEGORY_CLIENT,
|
||||
NS_LOGMODULE_CLIENT, ISC_LOG_WARNING,
|
||||
"ede extra-text too long, ignoring");
|
||||
}
|
||||
}
|
||||
|
||||
client->ede = isc_mem_get(client->mctx, sizeof(dns_ednsopt_t));
|
||||
client->ede->code = DNS_OPT_EDE;
|
||||
client->ede->length = len;
|
||||
client->ede->value = isc_mem_get(client->mctx, len);
|
||||
memmove(client->ede->value, ede, len);
|
||||
};
|
||||
|
||||
static void
|
||||
ns_client_endrequest(ns_client_t *client) {
|
||||
INSIST(client->nupdates == 0);
|
||||
@@ -200,6 +250,7 @@ ns_client_endrequest(ns_client_t *client) {
|
||||
dns_message_puttemprdataset(client->message, &client->opt);
|
||||
}
|
||||
|
||||
client_extendederror_reset(client);
|
||||
client->signer = NULL;
|
||||
client->udpsize = 512;
|
||||
client->extflags = 0;
|
||||
@@ -1062,6 +1113,14 @@ no_nsid:
|
||||
count++;
|
||||
}
|
||||
|
||||
if (client->ede != NULL) {
|
||||
INSIST(count < DNS_EDNSOPTIONS);
|
||||
ednsopts[count].code = DNS_OPT_EDE;
|
||||
ednsopts[count].length = client->ede->length;
|
||||
ednsopts[count].value = client->ede->value;
|
||||
count++;
|
||||
}
|
||||
|
||||
/* Padding must be added last */
|
||||
if ((view != NULL) && (view->padding > 0) && WANTPAD(client) &&
|
||||
(TCP_CLIENT(client) ||
|
||||
@@ -1607,6 +1666,7 @@ ns__client_put_cb(void *client0) {
|
||||
dns_rdataset_disassociate(client->opt);
|
||||
dns_message_puttemprdataset(client->message, &client->opt);
|
||||
}
|
||||
client_extendederror_reset(client);
|
||||
|
||||
dns_message_detach(&client->message);
|
||||
|
||||
@@ -1877,6 +1937,7 @@ ns__client_request(isc_nmhandle_t *handle, isc_result_t eresult,
|
||||
}
|
||||
|
||||
client->message->rcode = dns_rcode_noerror;
|
||||
client->ede = NULL;
|
||||
|
||||
/*
|
||||
* Deal with EDNS.
|
||||
|
||||
@@ -190,6 +190,7 @@ struct ns_client {
|
||||
dns_message_t *message;
|
||||
unsigned char *sendbuf;
|
||||
dns_rdataset_t *opt;
|
||||
dns_ednsopt_t *ede;
|
||||
uint16_t udpsize;
|
||||
uint16_t extflags;
|
||||
int16_t ednsversion; /* -1 noedns */
|
||||
@@ -311,6 +312,12 @@ ns_client_error(ns_client_t *client, isc_result_t result);
|
||||
* will have an RCODE determined by 'result'.
|
||||
*/
|
||||
|
||||
void
|
||||
ns_client_extendederror(ns_client_t *client, uint16_t code, const char *text);
|
||||
/*%<
|
||||
* Set extended error with INFO-CODE <code> and EXTRA-TEXT <text>.
|
||||
*/
|
||||
|
||||
void
|
||||
ns_client_drop(ns_client_t *client, isc_result_t result);
|
||||
/*%<
|
||||
|
||||
Reference in New Issue
Block a user