mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-02 07:35:26 +00:00
[master] DLZ fixes
- handle malformed answers from DLZ better: - handle dlz_lookup errors better: when the first lookup of a name returns an unexpected failure code, we return it to the caller rather than continuing on to look up the wildcard. we now only continue processing if the return from the first lookup was either ISC_R_SUCCESS or ISC_R_NOTFOUND. - improved backward-compatibility for dlz_version: added a DLZ_DLOPEN_AGE value indicating how many versions back from the current DLZ_DLOPEN_VERSION named will support
This commit is contained in:
@@ -326,11 +326,13 @@ dlopen_dlz_create(const char *dlzname, unsigned int argc, char *argv[],
|
||||
|
||||
/* Check the version of the API is the same */
|
||||
cd->version = cd->dlz_version(&cd->flags);
|
||||
if (cd->version != DLZ_DLOPEN_VERSION) {
|
||||
if (cd->version < (DLZ_DLOPEN_VERSION - DLZ_DLOPEN_AGE) ||
|
||||
cd->version > DLZ_DLOPEN_VERSION)
|
||||
{
|
||||
dlopen_log(ISC_LOG_ERROR,
|
||||
"dlz_dlopen: incorrect version %d "
|
||||
"should be %d in '%s'",
|
||||
cd->version, DLZ_DLOPEN_VERSION, cd->dl_path);
|
||||
"dlz_dlopen: %s: incorrect driver API version %d, "
|
||||
"requires %d",
|
||||
cd->dl_path, cd->version, DLZ_DLOPEN_VERSION);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
@@ -310,11 +310,13 @@ dlopen_dlz_create(const char *dlzname, unsigned int argc, char *argv[],
|
||||
|
||||
/* Check the version of the API is the same */
|
||||
cd->version = cd->dlz_version(&cd->flags);
|
||||
if (cd->version != DLZ_DLOPEN_VERSION) {
|
||||
if (cd->version < (DLZ_DLOPEN_VERSION - DLZ_DLOPEN_AGE) ||
|
||||
cd->version > DLZ_DLOPEN_VERSION)
|
||||
{
|
||||
dlopen_log(ISC_LOG_ERROR,
|
||||
"dlz_dlopen: incorrect version %d "
|
||||
"should be %d in '%s'",
|
||||
cd->version, DLZ_DLOPEN_VERSION, cd->dl_path);
|
||||
"dlz_dlopen: %s: incorrect driver API version %d, "
|
||||
"requires %d",
|
||||
cd->dl_path, cd->version, DLZ_DLOPEN_VERSION);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
@@ -368,8 +368,11 @@ dlz_findzonedb(void *dbdata, const char *name,
|
||||
/*
|
||||
* Look up one record in the sample database.
|
||||
*
|
||||
* If the queryname is "source-addr", we add a TXT record containing
|
||||
* If the queryname is "source-addr", send back a TXT record containing
|
||||
* the address of the client, to test the use of 'methods' and 'clientinfo'
|
||||
*
|
||||
* If the queryname is "too-long", send back a TXT record that's too long
|
||||
* to process; this should result in a SERVFAIL when queried.
|
||||
*/
|
||||
isc_result_t
|
||||
dlz_lookup(const char *zone, const char *name, void *dbdata,
|
||||
@@ -381,6 +384,7 @@ dlz_lookup(const char *zone, const char *name, void *dbdata,
|
||||
isc_boolean_t found = ISC_FALSE;
|
||||
isc_sockaddr_t *src;
|
||||
char full_name[256];
|
||||
char buf[512];
|
||||
int i;
|
||||
|
||||
UNUSED(zone);
|
||||
@@ -395,7 +399,6 @@ dlz_lookup(const char *zone, const char *name, void *dbdata,
|
||||
snprintf(full_name, 255, "%s.%s", name, state->zone_name);
|
||||
|
||||
if (strcmp(name, "source-addr") == 0) {
|
||||
char buf[100];
|
||||
strcpy(buf, "unknown");
|
||||
if (methods != NULL &&
|
||||
methods->sourceip != NULL &&
|
||||
@@ -415,6 +418,16 @@ dlz_lookup(const char *zone, const char *name, void *dbdata,
|
||||
return (result);
|
||||
}
|
||||
|
||||
if (strcmp(name, "too-long") == 0) {
|
||||
for (i = 0; i < 511; i++)
|
||||
buf[i] = 'x';
|
||||
buf[i] = '\0';
|
||||
found = ISC_TRUE;
|
||||
result = state->putrr(lookup, "TXT", 0, buf);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_RECORDS; i++) {
|
||||
if (strcasecmp(state->current[i].name, full_name) == 0) {
|
||||
found = ISC_TRUE;
|
||||
|
@@ -136,4 +136,11 @@ lines=`grep "dlz_findzonedb.*example\.net.*alternate.nil" ns1/named.run | wc -l`
|
||||
[ "$ret" -eq 0 ] || echo "I:failed"
|
||||
status=`expr $status + $ret`
|
||||
|
||||
ret=0
|
||||
echo "I:testing zone returning oversized data"
|
||||
$DIG $DIGOPTS txt too-long.example.nil > dig.out.ns1.6 2>&1 || ret=1
|
||||
grep "status: SERVFAIL" dig.out.ns1.6 > /dev/null || ret=1
|
||||
[ "$ret" -eq 0 ] || echo "I:failed"
|
||||
status=`expr $status + $ret`
|
||||
|
||||
exit $status
|
||||
|
@@ -357,9 +357,12 @@ dlz_findzonedb(void *dbdata, const char *name,
|
||||
/*
|
||||
* Look up one record in the sample database.
|
||||
*
|
||||
* If the queryname is "source-addr", we add a TXT record containing
|
||||
* If the queryname is "source-addr", send back a TXT record containing
|
||||
* the address of the client; this demonstrates the use of 'methods'
|
||||
* and 'clientinfo'.
|
||||
*
|
||||
* If the queryname is "too-long", send back a TXT record that's too long
|
||||
* to process; this should result in a SERVFAIL when queried.
|
||||
*/
|
||||
isc_result_t
|
||||
dlz_lookup(const char *zone, const char *name, void *dbdata,
|
||||
@@ -371,6 +374,7 @@ dlz_lookup(const char *zone, const char *name, void *dbdata,
|
||||
isc_boolean_t found = ISC_FALSE;
|
||||
isc_sockaddr_t *src;
|
||||
char full_name[256];
|
||||
char buf[512];
|
||||
int i;
|
||||
|
||||
UNUSED(zone);
|
||||
@@ -385,7 +389,6 @@ dlz_lookup(const char *zone, const char *name, void *dbdata,
|
||||
snprintf(full_name, 255, "%s.%s", name, state->zone_name);
|
||||
|
||||
if (strcmp(name, "source-addr") == 0) {
|
||||
char buf[100];
|
||||
strcpy(buf, "unknown");
|
||||
if (methods != NULL &&
|
||||
methods->sourceip != NULL &&
|
||||
@@ -406,6 +409,16 @@ dlz_lookup(const char *zone, const char *name, void *dbdata,
|
||||
return (result);
|
||||
}
|
||||
|
||||
if (strcmp(name, "too-long") == 0) {
|
||||
for (i = 0; i < 511; i++)
|
||||
buf[i] = 'x';
|
||||
buf[i] = '\0';
|
||||
found = ISC_TRUE;
|
||||
result = state->putrr(lookup, "TXT", 0, buf);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_RECORDS; i++) {
|
||||
if (strcasecmp(state->current[i].name, full_name) == 0) {
|
||||
found = ISC_TRUE;
|
||||
|
@@ -37,6 +37,7 @@ typedef int isc_boolean_t;
|
||||
typedef uint32_t dns_ttl_t;
|
||||
|
||||
#define DLZ_DLOPEN_VERSION 3
|
||||
#define DLZ_DLOPEN_AGE 0
|
||||
|
||||
/* return this in flags to dlz_version() if thread safe */
|
||||
#define DNS_SDLZFLAG_THREADSAFE 0x00000001U
|
||||
|
@@ -31,6 +31,7 @@ ISC_LANG_BEGINDECLS
|
||||
*/
|
||||
|
||||
#define DLZ_DLOPEN_VERSION 3
|
||||
#define DLZ_DLOPEN_AGE 0
|
||||
|
||||
/*
|
||||
* dlz_dlopen_version() is required for all DLZ external drivers. It
|
||||
|
@@ -605,7 +605,7 @@ findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
|
||||
* if the host (namestr) was not found, try to lookup a
|
||||
* "wildcard" host.
|
||||
*/
|
||||
if (result != ISC_R_SUCCESS && !create)
|
||||
if (result == ISC_R_NOTFOUND && !create)
|
||||
result = sdlz->dlzimp->methods->lookup(zonestr, "*",
|
||||
sdlz->dlzimp->driverarg,
|
||||
sdlz->dbdata, node,
|
||||
@@ -878,10 +878,11 @@ findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
||||
dns_name_getlabelsequence(name, nlabels - i, i, xname);
|
||||
result = findnodeext(db, xname, ISC_FALSE,
|
||||
methods, clientinfo, &node);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
if (result == ISC_R_NOTFOUND) {
|
||||
result = DNS_R_NXDOMAIN;
|
||||
continue;
|
||||
}
|
||||
} else if (result != ISC_R_SUCCESS)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Look for a DNAME at the current label, unless this is
|
||||
|
Reference in New Issue
Block a user