* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: adb.c,v 1.221 2005/04/27 04:56:44 sra Exp $ */
+/* $Id: adb.c,v 1.222 2005/06/23 04:22:01 marka Exp $ */
/*! \file
*
#include <dns/rdata.h>
#include <dns/rdataset.h>
#include <dns/rdatastruct.h>
+#include <dns/rdatatype.h>
#include <dns/resolver.h>
#include <dns/result.h>
#define DNS_ADBNAME_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAME_MAGIC)
#define DNS_ADBNAMEHOOK_MAGIC ISC_MAGIC('a', 'd', 'N', 'H')
#define DNS_ADBNAMEHOOK_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAMEHOOK_MAGIC)
-#define DNS_ADBZONEINFO_MAGIC ISC_MAGIC('a', 'd', 'b', 'Z')
-#define DNS_ADBZONEINFO_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBZONEINFO_MAGIC)
+#define DNS_ADBLAMEINFO_MAGIC ISC_MAGIC('a', 'd', 'b', 'Z')
+#define DNS_ADBLAMEINFO_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBLAMEINFO_MAGIC)
#define DNS_ADBENTRY_MAGIC ISC_MAGIC('a', 'd', 'b', 'E')
#define DNS_ADBENTRY_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBENTRY_MAGIC)
#define DNS_ADBFETCH_MAGIC ISC_MAGIC('a', 'd', 'F', '4')
typedef ISC_LIST(dns_adbname_t) dns_adbnamelist_t;
typedef struct dns_adbnamehook dns_adbnamehook_t;
typedef ISC_LIST(dns_adbnamehook_t) dns_adbnamehooklist_t;
-typedef struct dns_adbzoneinfo dns_adbzoneinfo_t;
+typedef struct dns_adblameinfo dns_adblameinfo_t;
typedef ISC_LIST(dns_adbentry_t) dns_adbentrylist_t;
typedef struct dns_adbfetch dns_adbfetch_t;
typedef struct dns_adbfetch6 dns_adbfetch6_t;
isc_mutex_t mplock;
isc_mempool_t *nmp; /*%< dns_adbname_t */
isc_mempool_t *nhmp; /*%< dns_adbnamehook_t */
- isc_mempool_t *zimp; /*%< dns_adbzoneinfo_t */
+ isc_mempool_t *limp; /*%< dns_adblameinfo_t */
isc_mempool_t *emp; /*%< dns_adbentry_t */
isc_mempool_t *ahmp; /*%< dns_adbfind_t */
isc_mempool_t *aimp; /*%< dns_adbaddrinfo_t */
};
/*%
- * This is a small widget that holds zone-specific information about an
+ * This is a small widget that holds qname-specific information about an
* address. Currently limited to lameness, but could just as easily be
* extended to other types of information about zones.
*/
-struct dns_adbzoneinfo {
+struct dns_adblameinfo {
unsigned int magic;
- dns_name_t zone;
+ dns_name_t qname;
+ dns_rdatatype_t qtype;
isc_stdtime_t lame_timer;
- ISC_LINK(dns_adbzoneinfo_t) plink;
+ ISC_LINK(dns_adblameinfo_t) plink;
};
/*%
* name.
*/
- ISC_LIST(dns_adbzoneinfo_t) zoneinfo;
+ ISC_LIST(dns_adblameinfo_t) lameinfo;
ISC_LINK(dns_adbentry_t) plink;
};
static inline dns_adbnamehook_t *new_adbnamehook(dns_adb_t *,
dns_adbentry_t *);
static inline void free_adbnamehook(dns_adb_t *, dns_adbnamehook_t **);
-static inline dns_adbzoneinfo_t *new_adbzoneinfo(dns_adb_t *, dns_name_t *);
-static inline void free_adbzoneinfo(dns_adb_t *, dns_adbzoneinfo_t **);
+static inline dns_adblameinfo_t *new_adblameinfo(dns_adb_t *, dns_name_t *,
+ dns_rdatatype_t);
+static inline void free_adblameinfo(dns_adb_t *, dns_adblameinfo_t **);
static inline dns_adbentry_t *new_adbentry(dns_adb_t *);
static inline void free_adbentry(dns_adb_t *, dns_adbentry_t **);
static inline dns_adbfind_t *new_adbfind(dns_adb_t *);
isc_mempool_put(adb->nhmp, nh);
}
-static inline dns_adbzoneinfo_t *
-new_adbzoneinfo(dns_adb_t *adb, dns_name_t *zone) {
- dns_adbzoneinfo_t *zi;
+static inline dns_adblameinfo_t *
+new_adblameinfo(dns_adb_t *adb, dns_name_t *qname, dns_rdatatype_t qtype) {
+ dns_adblameinfo_t *li;
- zi = isc_mempool_get(adb->zimp);
- if (zi == NULL)
+ li = isc_mempool_get(adb->limp);
+ if (li == NULL)
return (NULL);
- dns_name_init(&zi->zone, NULL);
- if (dns_name_dup(zone, adb->mctx, &zi->zone) != ISC_R_SUCCESS) {
- isc_mempool_put(adb->zimp, zi);
+ dns_name_init(&li->qname, NULL);
+ if (dns_name_dup(qname, adb->mctx, &li->qname) != ISC_R_SUCCESS) {
+ isc_mempool_put(adb->limp, li);
return (NULL);
}
+ li->magic = DNS_ADBLAMEINFO_MAGIC;
+ li->lame_timer = 0;
+ li->qtype = qtype;
+ ISC_LINK_INIT(li, plink);
- zi->magic = DNS_ADBZONEINFO_MAGIC;
- zi->lame_timer = 0;
- ISC_LINK_INIT(zi, plink);
-
- return (zi);
+ return (li);
}
static inline void
-free_adbzoneinfo(dns_adb_t *adb, dns_adbzoneinfo_t **zoneinfo) {
- dns_adbzoneinfo_t *zi;
+free_adblameinfo(dns_adb_t *adb, dns_adblameinfo_t **lameinfo) {
+ dns_adblameinfo_t *li;
- INSIST(zoneinfo != NULL && DNS_ADBZONEINFO_VALID(*zoneinfo));
- zi = *zoneinfo;
- *zoneinfo = NULL;
+ INSIST(lameinfo != NULL && DNS_ADBLAMEINFO_VALID(*lameinfo));
+ li = *lameinfo;
+ *lameinfo = NULL;
- INSIST(!ISC_LINK_LINKED(zi, plink));
+ INSIST(!ISC_LINK_LINKED(li, plink));
- dns_name_free(&zi->zone, adb->mctx);
+ dns_name_free(&li->qname, adb->mctx);
- zi->magic = 0;
+ li->magic = 0;
- isc_mempool_put(adb->zimp, zi);
+ isc_mempool_put(adb->limp, li);
}
static inline dns_adbentry_t *
isc_random_get(&r);
e->srtt = (r & 0x1f) + 1;
e->expires = 0;
- ISC_LIST_INIT(e->zoneinfo);
+ ISC_LIST_INIT(e->lameinfo);
ISC_LINK_INIT(e, plink);
return (e);
static inline void
free_adbentry(dns_adb_t *adb, dns_adbentry_t **entry) {
dns_adbentry_t *e;
- dns_adbzoneinfo_t *zi;
+ dns_adblameinfo_t *li;
INSIST(entry != NULL && DNS_ADBENTRY_VALID(*entry));
e = *entry;
e->magic = 0;
- zi = ISC_LIST_HEAD(e->zoneinfo);
- while (zi != NULL) {
- ISC_LIST_UNLINK(e->zoneinfo, zi, plink);
- free_adbzoneinfo(adb, &zi);
- zi = ISC_LIST_HEAD(e->zoneinfo);
+ li = ISC_LIST_HEAD(e->lameinfo);
+ while (li != NULL) {
+ ISC_LIST_UNLINK(e->lameinfo, li, plink);
+ free_adblameinfo(adb, &li);
+ li = ISC_LIST_HEAD(e->lameinfo);
}
isc_mempool_put(adb->emp, e);
* Entry bucket MUST be locked!
*/
static isc_boolean_t
-entry_is_bad_for_zone(dns_adb_t *adb, dns_adbentry_t *entry, dns_name_t *zone,
- isc_stdtime_t now)
+entry_is_lame(dns_adb_t *adb, dns_adbentry_t *entry, dns_name_t *qname,
+ dns_rdatatype_t qtype, isc_stdtime_t now)
{
- dns_adbzoneinfo_t *zi, *next_zi;
+ dns_adblameinfo_t *li, *next_li;
isc_boolean_t is_bad;
is_bad = ISC_FALSE;
- zi = ISC_LIST_HEAD(entry->zoneinfo);
- if (zi == NULL)
+ li = ISC_LIST_HEAD(entry->lameinfo);
+ if (li == NULL)
return (ISC_FALSE);
- while (zi != NULL) {
- next_zi = ISC_LIST_NEXT(zi, plink);
+ while (li != NULL) {
+ next_li = ISC_LIST_NEXT(li, plink);
/*
* Has the entry expired?
*/
- if (zi->lame_timer < now) {
- ISC_LIST_UNLINK(entry->zoneinfo, zi, plink);
- free_adbzoneinfo(adb, &zi);
+ if (li->lame_timer < now) {
+ ISC_LIST_UNLINK(entry->lameinfo, li, plink);
+ free_adblameinfo(adb, &li);
}
/*
* Order tests from least to most expensive.
*/
- if (zi != NULL && !is_bad) {
- if (dns_name_equal(zone, &zi->zone))
+ if (li != NULL && !is_bad) {
+ if (li->qtype == qtype &&
+ dns_name_equal(qname, &li->qname))
is_bad = ISC_TRUE;
}
- zi = next_zi;
+ li = next_li;
}
return (is_bad);
}
static void
-copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_name_t *zone,
- dns_adbname_t *name, isc_stdtime_t now)
+copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_name_t *qname,
+ dns_rdatatype_t qtype, dns_adbname_t *name,
+ isc_stdtime_t now)
{
dns_adbnamehook_t *namehook;
dns_adbaddrinfo_t *addrinfo;
LOCK(&adb->entrylocks[bucket]);
if (!FIND_RETURNLAME(find)
- && entry_is_bad_for_zone(adb, entry, zone, now)) {
+ && entry_is_lame(adb, entry, qname, qtype, now)) {
find->options |= DNS_ADBFIND_LAMEPRUNED;
goto nextv4;
}
bucket = entry->lock_bucket;
LOCK(&adb->entrylocks[bucket]);
- if (entry_is_bad_for_zone(adb, entry, zone, now))
+ if (entry_is_lame(adb, entry, qname, qtype, now))
goto nextv6;
addrinfo = new_adbaddrinfo(adb, entry, find->port);
if (addrinfo == NULL) {
isc_mempool_destroy(&adb->nmp);
isc_mempool_destroy(&adb->nhmp);
- isc_mempool_destroy(&adb->zimp);
+ isc_mempool_destroy(&adb->limp);
isc_mempool_destroy(&adb->emp);
isc_mempool_destroy(&adb->ahmp);
isc_mempool_destroy(&adb->aimp);
adb->irefcnt = 0;
adb->nmp = NULL;
adb->nhmp = NULL;
- adb->zimp = NULL;
+ adb->limp = NULL;
adb->emp = NULL;
adb->ahmp = NULL;
adb->aimp = NULL;
MPINIT(dns_adbname_t, adb->nmp, "adbname");
MPINIT(dns_adbnamehook_t, adb->nhmp, "adbnamehook");
- MPINIT(dns_adbzoneinfo_t, adb->zimp, "adbzoneinfo");
+ MPINIT(dns_adblameinfo_t, adb->limp, "adblameinfo");
MPINIT(dns_adbentry_t, adb->emp, "adbentry");
MPINIT(dns_adbfind_t, adb->ahmp, "adbfind");
MPINIT(dns_adbaddrinfo_t, adb->aimp, "adbaddrinfo");
isc_mempool_destroy(&adb->nmp);
if (adb->nhmp != NULL)
isc_mempool_destroy(&adb->nhmp);
- if (adb->zimp != NULL)
- isc_mempool_destroy(&adb->zimp);
+ if (adb->limp != NULL)
+ isc_mempool_destroy(&adb->limp);
if (adb->emp != NULL)
isc_mempool_destroy(&adb->emp);
if (adb->ahmp != NULL)
isc_result_t
dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
- void *arg, dns_name_t *name, dns_name_t *zone,
- unsigned int options, isc_stdtime_t now, dns_name_t *target,
+ void *arg, dns_name_t *name, dns_name_t *qname,
+ dns_rdatatype_t qtype, unsigned int options,
+ isc_stdtime_t now, dns_name_t *target,
in_port_t port, dns_adbfind_t **findp)
{
dns_adbfind_t *find;
REQUIRE(action != NULL);
}
REQUIRE(name != NULL);
- REQUIRE(zone != NULL);
+ REQUIRE(qname != NULL);
REQUIRE(findp != NULL && *findp == NULL);
REQUIRE(target == NULL || dns_name_hasbuffer(target));
* Run through the name and copy out the bits we are
* interested in.
*/
- copy_namehook_lists(adb, find, zone, adbname, now);
+ copy_namehook_lists(adb, find, qname, qtype, adbname, now);
post_copy:
if (NAME_FETCH_V4(adbname))
isc_stdtime_t now)
{
char addrbuf[ISC_NETADDR_FORMATSIZE];
+ char typebuf[DNS_RDATATYPE_FORMATSIZE];
isc_netaddr_t netaddr;
- dns_adbzoneinfo_t *zi;
+ dns_adblameinfo_t *li;
isc_netaddr_fromsockaddr(&netaddr, &entry->sockaddr);
isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf));
if (entry->expires != 0)
fprintf(f, " [ttl %d]", entry->expires - now);
fprintf(f, "\n");
- for (zi = ISC_LIST_HEAD(entry->zoneinfo);
- zi != NULL;
- zi = ISC_LIST_NEXT(zi, plink)) {
+ for (li = ISC_LIST_HEAD(entry->lameinfo);
+ li != NULL;
+ li = ISC_LIST_NEXT(li, plink)) {
fprintf(f, ";\t\t");
- print_dns_name(f, &zi->zone);
- fprintf(f, " [lame TTL %d]\n", zi->lame_timer - now);
+ print_dns_name(f, &li->qname);
+ dns_rdatatype_format(li->qtype, typebuf, sizeof(typebuf));
+ fprintf(f, " %s [lame TTL %d]\n", typebuf,
+ li->lame_timer - now);
}
}
* since these can be extracted from the find itself.
*/
isc_result_t
-dns_adb_marklame(dns_adb_t *adb, dns_adbaddrinfo_t *addr, dns_name_t *zone,
- isc_stdtime_t expire_time)
+dns_adb_marklame(dns_adb_t *adb, dns_adbaddrinfo_t *addr, dns_name_t *qname,
+ dns_rdatatype_t qtype, isc_stdtime_t expire_time)
{
- dns_adbzoneinfo_t *zi;
+ dns_adblameinfo_t *li;
int bucket;
isc_result_t result = ISC_R_SUCCESS;
REQUIRE(DNS_ADB_VALID(adb));
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
- REQUIRE(zone != NULL);
+ REQUIRE(qname != NULL);
bucket = addr->entry->lock_bucket;
LOCK(&adb->entrylocks[bucket]);
- zi = ISC_LIST_HEAD(addr->entry->zoneinfo);
- while (zi != NULL && !dns_name_equal(zone, &zi->zone))
- zi = ISC_LIST_NEXT(zi, plink);
- if (zi != NULL) {
- if (expire_time > zi->lame_timer)
- zi->lame_timer = expire_time;
+ li = ISC_LIST_HEAD(addr->entry->lameinfo);
+ while (li != NULL && li->qtype != qtype &&
+ !dns_name_equal(qname, &li->qname))
+ li = ISC_LIST_NEXT(li, plink);
+ if (li != NULL) {
+ if (expire_time > li->lame_timer)
+ li->lame_timer = expire_time;
goto unlock;
}
- zi = new_adbzoneinfo(adb, zone);
- if (zi == NULL) {
+ li = new_adblameinfo(adb, qname, qtype);
+ if (li == NULL) {
result = ISC_R_NOMEMORY;
goto unlock;
}
- zi->lame_timer = expire_time;
+ li->lame_timer = expire_time;
- ISC_LIST_PREPEND(addr->entry->zoneinfo, zi, plink);
+ ISC_LIST_PREPEND(addr->entry->lameinfo, li, plink);
unlock:
UNLOCK(&adb->entrylocks[bucket]);
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: resolver.c,v 1.311 2005/06/17 01:58:22 marka Exp $ */
+/* $Id: resolver.c,v 1.312 2005/06/23 04:22:01 marka Exp $ */
/*! \file */
static void
findname(fetchctx_t *fctx, dns_name_t *name, in_port_t port,
unsigned int options, unsigned int flags, isc_stdtime_t now,
- isc_boolean_t *pruned, isc_boolean_t *need_alternate)
+ isc_boolean_t *need_alternate)
{
dns_adbaddrinfo_t *ai;
dns_adbfind_t *find;
result = dns_adb_createfind(fctx->adb,
res->buckets[fctx->bucketnum].task,
fctx_finddone, fctx, name,
- &fctx->domain, options, now, NULL,
+ &fctx->name, fctx->type,
+ options, now, NULL,
res->view->dstport, &find);
if (result != ISC_R_SUCCESS) {
if (result == DNS_R_ALIAS) {
(res->dispatchv6 == NULL &&
find->result_v4 == DNS_R_NXRRSET)))
*need_alternate = ISC_TRUE;
- /*
- * And ADB isn't going to send us any events
- * either. This find loses.
- */
- if ((find->options & DNS_ADBFIND_LAMEPRUNED) != 0) {
- /*
- * The ADB pruned lame servers for
- * this name. Remember that in case
- * we get desperate later on.
- */
- *pruned = ISC_TRUE;
- }
dns_adb_destroyfind(&find);
}
}
unsigned int stdoptions;
isc_sockaddr_t *sa;
dns_adbaddrinfo_t *ai;
- isc_boolean_t pruned, all_bad;
+ isc_boolean_t all_bad;
dns_rdata_ns_t ns;
isc_boolean_t need_alternate = ISC_FALSE;
isc_boolean_t unshared;
}
res = fctx->res;
- pruned = ISC_FALSE;
stdoptions = 0; /* Keep compiler happy. */
unshared = ISC_TF((fctx->options | DNS_FETCHOPT_UNSHARED) != 0);
stdoptions |= DNS_ADBFIND_INET6;
isc_stdtime_get(&now);
- restart:
INSIST(ISC_LIST_EMPTY(fctx->finds));
INSIST(ISC_LIST_EMPTY(fctx->altfinds));
continue;
findname(fctx, &ns.name, 0, stdoptions, 0, now,
- &pruned, &need_alternate);
+ &need_alternate);
dns_rdata_reset(&rdata);
dns_rdata_freestruct(&ns);
}
if (!a->isaddress) {
findname(fctx, &a->_u._n.name, a->_u._n.port,
stdoptions, FCTX_ADDRINFO_FORWARDER,
- now, &pruned, NULL);
+ now, NULL);
continue;
}
if (isc_sockaddr_pf(&a->_u.addr) != family)
* yet. Tell the caller to wait for an answer.
*/
result = DNS_R_WAIT;
- } else if (pruned) {
- /*
- * Some addresses were removed by lame pruning.
- * Turn pruning off and try again.
- */
- FCTXTRACE("restarting with returnlame");
- INSIST((stdoptions & DNS_ADBFIND_RETURNLAME) == 0);
- stdoptions |= DNS_ADBFIND_RETURNLAME;
- pruned = ISC_FALSE;
- fctx_cleanupaltfinds(fctx);
- fctx_cleanupfinds(fctx);
- goto restart;
} else {
/*
* We've lost completely. We don't know any
is_lame(fctx)) {
log_lame(fctx, query->addrinfo);
result = dns_adb_marklame(fctx->adb, query->addrinfo,
- &fctx->domain,
+ &fctx->domain, fctx->type,
now + fctx->res->lame_ttl);
if (result != ISC_R_SUCCESS)
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,