2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-04 00:25:29 +00:00

Refactor how we map isc_result_t <-> dns_rcode_t

The mapping functions between isc_result_t and dns_rcode_t could return
both isc_result_t values not defined in the header and dns_rcode_t
values not defined in the header because it blindly maps anything
withing full 12-bits defined for RCODEs to isc_result_t and back.

Refactor the dns_result_{from,to}rcode() functions to always return
valid isc_result_t and dns_rcode_t values by explicitly mapping the
values to each other and returning DNS_R_SERVFAIL (dns_rcode_servfail)
when encountering value out of the defined range.
This commit is contained in:
Ondřej Surý
2023-06-15 10:24:21 +02:00
parent 189aadbab9
commit b53d1d7069

View File

@@ -19,27 +19,14 @@
#include <dns/result.h> #include <dns/result.h>
#define DNS_RESULT_ISRCODE(result) (DNS_R_NOERROR == ((result)&0xFFFF0000))
dns_rcode_t dns_rcode_t
dns_result_torcode(isc_result_t result) { dns_result_torcode(isc_result_t result) {
dns_rcode_t rcode = dns_rcode_servfail; /* Try to supply an appropriate rcode. */
if (DNS_RESULT_ISRCODE(result)) {
/*
* Rcodes can't be bigger than 12 bits, which is why we
* AND with 0xFFF instead of 0xFFFF.
*/
return ((dns_rcode_t)((result)&0xFFF));
}
/*
* Try to supply an appropriate rcode.
*/
switch (result) { switch (result) {
case DNS_R_NOERROR:
case ISC_R_SUCCESS: case ISC_R_SUCCESS:
rcode = dns_rcode_noerror; return (dns_rcode_noerror);
break; case DNS_R_FORMERR:
case ISC_R_BADBASE64: case ISC_R_BADBASE64:
case ISC_R_RANGE: case ISC_R_RANGE:
case ISC_R_UNEXPECTEDEND: case ISC_R_UNEXPECTEDEND:
@@ -60,29 +47,73 @@ dns_result_torcode(isc_result_t result) {
case DNS_R_UNKNOWN: case DNS_R_UNKNOWN:
case DNS_R_NAMETOOLONG: case DNS_R_NAMETOOLONG:
case DNS_R_OPTERR: case DNS_R_OPTERR:
rcode = dns_rcode_formerr; return (dns_rcode_formerr);
break; case DNS_R_SERVFAIL:
return (dns_rcode_servfail);
case DNS_R_NXDOMAIN:
return (dns_rcode_nxdomain);
case DNS_R_NOTIMP:
return (dns_rcode_notimp);
case DNS_R_REFUSED:
case DNS_R_DISALLOWED: case DNS_R_DISALLOWED:
rcode = dns_rcode_refused; return (dns_rcode_refused);
break; case DNS_R_YXDOMAIN:
return (dns_rcode_yxdomain);
case DNS_R_YXRRSET:
return (dns_rcode_yxrrset);
case DNS_R_NXRRSET:
return (dns_rcode_nxrrset);
case DNS_R_NOTAUTH:
case DNS_R_TSIGVERIFYFAILURE: case DNS_R_TSIGVERIFYFAILURE:
case DNS_R_CLOCKSKEW: case DNS_R_CLOCKSKEW:
rcode = dns_rcode_notauth; return (dns_rcode_notauth);
break; case DNS_R_NOTZONE:
return (dns_rcode_notzone);
case DNS_R_RCODE11:
case DNS_R_RCODE12:
case DNS_R_RCODE13:
case DNS_R_RCODE14:
case DNS_R_RCODE15:
return (result - DNS_R_NOERROR);
case DNS_R_BADVERS:
return (dns_rcode_badvers);
case DNS_R_BADCOOKIE:
return (dns_rcode_badcookie);
default: default:
rcode = dns_rcode_servfail; return (dns_rcode_servfail);
} }
return (rcode);
} }
isc_result_t isc_result_t
dns_result_fromrcode(dns_rcode_t rcode) { dns_result_fromrcode(dns_rcode_t rcode) {
/* switch (rcode) {
* Rcodes can't be bigger than 12 bits, which is why we case dns_rcode_noerror:
* AND with 0xFFF instead of 0xFFFF. return (DNS_R_NOERROR);
*/ case dns_rcode_formerr:
REQUIRE((rcode & 0xFFF) == rcode); return (DNS_R_FORMERR);
case dns_rcode_servfail:
return ((isc_result_t)rcode + DNS_R_NOERROR); return (DNS_R_SERVFAIL);
case dns_rcode_nxdomain:
return (DNS_R_NXDOMAIN);
case dns_rcode_notimp:
return (DNS_R_NOTIMP);
case dns_rcode_refused:
return (DNS_R_REFUSED);
case dns_rcode_yxdomain:
return (DNS_R_YXDOMAIN);
case dns_rcode_yxrrset:
return (DNS_R_YXRRSET);
case dns_rcode_nxrrset:
return (DNS_R_NXRRSET);
case dns_rcode_notauth:
return (DNS_R_NOTAUTH);
case dns_rcode_notzone:
return (DNS_R_NOTZONE);
case dns_rcode_badvers:
return (DNS_R_BADVERS);
case dns_rcode_badcookie:
return (DNS_R_BADCOOKIE);
default:
return (DNS_R_SERVFAIL);
}
} }