mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-04 16:45:24 +00:00
database lookups
This commit is contained in:
@@ -78,6 +78,10 @@ lookup_callback(isc_task_t *task, isc_event_t *ev)
|
|||||||
isc_app_shutdown();
|
isc_app_shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned char namestorage1[512];
|
||||||
|
unsigned char namestorage2[512];
|
||||||
|
unsigned char namestorage3[512];
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@@ -85,10 +89,8 @@ main(int argc, char **argv)
|
|||||||
isc_sockaddr_t sockaddr;
|
isc_sockaddr_t sockaddr;
|
||||||
struct in_addr ina;
|
struct in_addr ina;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
dns_name_t name1, name2;
|
dns_name_t name1, name2, name3;
|
||||||
isc_buffer_t t, namebuf;
|
isc_buffer_t t, namebuf;
|
||||||
unsigned char namestorage1[512];
|
|
||||||
unsigned char namestorage2[512];
|
|
||||||
dns_view_t *view;
|
dns_view_t *view;
|
||||||
dns_adb_t *adb;
|
dns_adb_t *adb;
|
||||||
dns_adbhandle_t *handle;
|
dns_adbhandle_t *handle;
|
||||||
@@ -132,6 +134,8 @@ main(int argc, char **argv)
|
|||||||
result = dns_view_create(mctx, dns_rdataclass_in, "foo", &view);
|
result = dns_view_create(mctx, dns_rdataclass_in, "foo", &view);
|
||||||
check_result(result, "dns_view_create");
|
check_result(result, "dns_view_create");
|
||||||
|
|
||||||
|
dns_view_freeze(view);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create the address database.
|
* Create the address database.
|
||||||
*/
|
*/
|
||||||
@@ -139,8 +143,9 @@ main(int argc, char **argv)
|
|||||||
result = dns_adb_create(mctx, view, &adb);
|
result = dns_adb_create(mctx, view, &adb);
|
||||||
check_result(result, "dns_adb_create");
|
check_result(result, "dns_adb_create");
|
||||||
|
|
||||||
#define NAME1 "nonexistant.flame.org."
|
#define NAME1 "kechara.flame.org."
|
||||||
#define NAME2 "badname.isc.org."
|
#define NAME2 "moghedien.isc.org."
|
||||||
|
#define NAME3 "nonexistant.flame.org."
|
||||||
|
|
||||||
isc_buffer_init(&t, NAME1, sizeof NAME1 - 1, ISC_BUFFERTYPE_TEXT);
|
isc_buffer_init(&t, NAME1, sizeof NAME1 - 1, ISC_BUFFERTYPE_TEXT);
|
||||||
isc_buffer_add(&t, strlen(NAME1));
|
isc_buffer_add(&t, strlen(NAME1));
|
||||||
@@ -160,6 +165,15 @@ main(int argc, char **argv)
|
|||||||
&namebuf);
|
&namebuf);
|
||||||
check_result(result, "dns_name_fromtext NAME2");
|
check_result(result, "dns_name_fromtext NAME2");
|
||||||
|
|
||||||
|
isc_buffer_init(&t, NAME3, sizeof NAME3 - 1, ISC_BUFFERTYPE_TEXT);
|
||||||
|
isc_buffer_add(&t, strlen(NAME3));
|
||||||
|
isc_buffer_init(&namebuf, namestorage3, sizeof namestorage3,
|
||||||
|
ISC_BUFFERTYPE_BINARY);
|
||||||
|
dns_name_init(&name3, NULL);
|
||||||
|
result = dns_name_fromtext(&name3, &t, dns_rootname, ISC_FALSE,
|
||||||
|
&namebuf);
|
||||||
|
check_result(result, "dns_name_fromtext NAME3");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Store this address for this name.
|
* Store this address for this name.
|
||||||
*/
|
*/
|
||||||
@@ -239,6 +253,28 @@ main(int argc, char **argv)
|
|||||||
dns_adb_dump(adb, stderr);
|
dns_adb_dump(adb, stderr);
|
||||||
|
|
||||||
dns_adb_done(adb, &handle);
|
dns_adb_done(adb, &handle);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* look up a name that doesn't exit.
|
||||||
|
*/
|
||||||
|
result = dns_adb_lookup(adb, t2, lookup_callback, &name3,
|
||||||
|
&name3, &name3, now, &handle);
|
||||||
|
if (result == ISC_R_SUCCESS) {
|
||||||
|
check_result(handle->result, "handle->result");
|
||||||
|
|
||||||
|
check_result(result, "dns_adb_lookup name3");
|
||||||
|
dns_adb_dump(adb, stderr);
|
||||||
|
dns_adb_dumphandle(adb, handle, stderr);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "lookup of name3: %s\n",
|
||||||
|
isc_result_totext(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
dns_adb_dump(adb, stderr);
|
||||||
|
|
||||||
|
if (handle != NULL)
|
||||||
|
dns_adb_done(adb, &handle);
|
||||||
|
|
||||||
isc_task_detach(&t1);
|
isc_task_detach(&t1);
|
||||||
isc_task_detach(&t2);
|
isc_task_detach(&t2);
|
||||||
|
|
||||||
|
@@ -39,6 +39,7 @@
|
|||||||
#include <isc/random.h>
|
#include <isc/random.h>
|
||||||
|
|
||||||
#include <dns/address.h>
|
#include <dns/address.h>
|
||||||
|
#include <dns/db.h>
|
||||||
#include <dns/events.h>
|
#include <dns/events.h>
|
||||||
#include <dns/name.h>
|
#include <dns/name.h>
|
||||||
#include <dns/rdata.h>
|
#include <dns/rdata.h>
|
||||||
@@ -113,7 +114,7 @@ struct dns_adb {
|
|||||||
struct dns_adbname {
|
struct dns_adbname {
|
||||||
unsigned int magic;
|
unsigned int magic;
|
||||||
dns_name_t name;
|
dns_name_t name;
|
||||||
isc_boolean_t partial_results;
|
isc_boolean_t partial_result;
|
||||||
isc_stdtime_t expire_time;
|
isc_stdtime_t expire_time;
|
||||||
ISC_LIST(dns_adbnamehook_t) namehooks;
|
ISC_LIST(dns_adbnamehook_t) namehooks;
|
||||||
ISC_LIST(dns_adbnamehook_t) in_progress;
|
ISC_LIST(dns_adbnamehook_t) in_progress;
|
||||||
@@ -206,7 +207,8 @@ static inline void violate_locking_hierarchy(isc_mutex_t *, isc_mutex_t *);
|
|||||||
static void clean_namehooks_at_name(dns_adb_t *, dns_adbname_t *);
|
static void clean_namehooks_at_name(dns_adb_t *, dns_adbname_t *);
|
||||||
static void clean_handles_at_name(dns_adbname_t *, isc_eventtype_t);
|
static void clean_handles_at_name(dns_adbname_t *, isc_eventtype_t);
|
||||||
static isc_result_t construct_name(dns_adb_t *, dns_adbhandle_t *,
|
static isc_result_t construct_name(dns_adb_t *, dns_adbhandle_t *,
|
||||||
dns_name_t *, dns_adbname_t *, int);
|
dns_name_t *, dns_name_t *,
|
||||||
|
dns_adbname_t *, int, isc_stdtime_t);
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
violate_locking_hierarchy(isc_mutex_t *have, isc_mutex_t *want)
|
violate_locking_hierarchy(isc_mutex_t *have, isc_mutex_t *want)
|
||||||
@@ -462,7 +464,7 @@ new_adbname(dns_adb_t *adb, dns_name_t *dnsname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
name->magic = DNS_ADBNAME_MAGIC;
|
name->magic = DNS_ADBNAME_MAGIC;
|
||||||
name->partial_results = ISC_FALSE;
|
name->partial_result = ISC_FALSE;
|
||||||
name->expire_time = 0;
|
name->expire_time = 0;
|
||||||
ISC_LIST_INIT(name->namehooks);
|
ISC_LIST_INIT(name->namehooks);
|
||||||
ISC_LIST_INIT(name->in_progress);
|
ISC_LIST_INIT(name->in_progress);
|
||||||
@@ -628,6 +630,7 @@ new_adbhandle(dns_adb_t *adb)
|
|||||||
*/
|
*/
|
||||||
h->magic = 0;
|
h->magic = 0;
|
||||||
h->query_pending = ISC_FALSE;
|
h->query_pending = ISC_FALSE;
|
||||||
|
h->partial_result = ISC_FALSE;
|
||||||
h->result = ISC_R_UNEXPECTED;
|
h->result = ISC_R_UNEXPECTED;
|
||||||
ISC_LIST_INIT(h->list);
|
ISC_LIST_INIT(h->list);
|
||||||
ISC_LINK_INIT(h, next);
|
ISC_LINK_INIT(h, next);
|
||||||
@@ -839,7 +842,6 @@ copy_namehook_list(dns_adb_t *adb, dns_adbhandle_t *handle,
|
|||||||
int bucket;
|
int bucket;
|
||||||
|
|
||||||
handle->query_pending = ISC_FALSE;
|
handle->query_pending = ISC_FALSE;
|
||||||
handle->result = ISC_R_UNEXPECTED;
|
|
||||||
bucket = DNS_ADB_INVALIDBUCKET;
|
bucket = DNS_ADB_INVALIDBUCKET;
|
||||||
|
|
||||||
namehook = ISC_LIST_HEAD(name->namehooks);
|
namehook = ISC_LIST_HEAD(name->namehooks);
|
||||||
@@ -850,6 +852,7 @@ copy_namehook_list(dns_adb_t *adb, dns_adbhandle_t *handle,
|
|||||||
goto next;
|
goto next;
|
||||||
addrinfo = new_adbaddrinfo(adb, namehook->entry);
|
addrinfo = new_adbaddrinfo(adb, namehook->entry);
|
||||||
if (addrinfo == NULL) {
|
if (addrinfo == NULL) {
|
||||||
|
handle->partial_result = ISC_TRUE;
|
||||||
handle->result = ISC_R_NOMEMORY;
|
handle->result = ISC_R_NOMEMORY;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -1176,10 +1179,12 @@ dns_adb_lookup(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
|
|||||||
* of data was added, and/or fetches were started. If nothing new
|
* of data was added, and/or fetches were started. If nothing new
|
||||||
* can ever be found it will return DNS_R_NOMEMORY more than likely.
|
* can ever be found it will return DNS_R_NOMEMORY more than likely.
|
||||||
*/
|
*/
|
||||||
result = construct_name(adb, handle, name, adbname, bucket);
|
result = construct_name(adb, handle, name, zone, adbname, bucket, now);
|
||||||
if (result == ISC_R_SUCCESS) {
|
if (result == ISC_R_SUCCESS) {
|
||||||
ISC_LIST_PREPEND(adb->names[bucket], adbname, link);
|
ISC_LIST_PREPEND(adb->names[bucket], adbname, link);
|
||||||
adb->name_refcnt[bucket]++;
|
adb->name_refcnt[bucket]++;
|
||||||
|
if (adbname->partial_result)
|
||||||
|
handle->partial_result = ISC_TRUE;
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1188,8 +1193,6 @@ dns_adb_lookup(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
|
|||||||
* (since it will have nothing useful in it) and return via the
|
* (since it will have nothing useful in it) and return via the
|
||||||
* failure return.
|
* failure return.
|
||||||
*/
|
*/
|
||||||
free_adbname(adb, &adbname);
|
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
free_adbhandle(adb, &handle);
|
free_adbhandle(adb, &handle);
|
||||||
|
|
||||||
@@ -1197,7 +1200,7 @@ dns_adb_lookup(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
|
|||||||
* If the name isn't on a list it means we allocated it here, and it
|
* If the name isn't on a list it means we allocated it here, and it
|
||||||
* should be killed.
|
* should be killed.
|
||||||
*/
|
*/
|
||||||
if (!ISC_LINK_LINKED(adbname, link))
|
if (adbname != NULL && !ISC_LINK_LINKED(adbname, link))
|
||||||
free_adbname(adb, &adbname);
|
free_adbname(adb, &adbname);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1673,13 +1676,18 @@ print_handle_list(FILE *f, dns_adbname_t *name)
|
|||||||
*/
|
*/
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
construct_name(dns_adb_t *adb, dns_adbhandle_t *handle, dns_name_t *name,
|
construct_name(dns_adb_t *adb, dns_adbhandle_t *handle, dns_name_t *name,
|
||||||
dns_adbname_t *adbname, int bucket)
|
dns_name_t *zone, dns_adbname_t *adbname, int bucket,
|
||||||
|
isc_stdtime_t now)
|
||||||
{
|
{
|
||||||
dns_adbentry_t *entry;
|
dns_adbentry_t *entry;
|
||||||
dns_adbnamehook_t *nh;
|
dns_adbnamehook_t *nh;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
int addr_bucket;
|
int addr_bucket;
|
||||||
isc_boolean_t return_success;
|
isc_boolean_t return_success;
|
||||||
|
isc_boolean_t use_hints;
|
||||||
|
dns_rdataset_t rdataset;
|
||||||
|
dns_rdata_t rdata;
|
||||||
|
struct in_addr ina;
|
||||||
|
|
||||||
INSIST(DNS_ADB_VALID(adb));
|
INSIST(DNS_ADB_VALID(adb));
|
||||||
INSIST(DNS_ADBHANDLE_VALID(handle));
|
INSIST(DNS_ADBHANDLE_VALID(handle));
|
||||||
@@ -1687,34 +1695,53 @@ construct_name(dns_adb_t *adb, dns_adbhandle_t *handle, dns_name_t *name,
|
|||||||
INSIST(DNS_ADBNAME_VALID(adbname));
|
INSIST(DNS_ADBNAME_VALID(adbname));
|
||||||
INSIST(bucket != DNS_ADB_INVALIDBUCKET);
|
INSIST(bucket != DNS_ADB_INVALIDBUCKET);
|
||||||
|
|
||||||
|
if (adb->view == NULL)
|
||||||
|
return (ISC_R_NOTIMPLEMENTED);
|
||||||
|
|
||||||
result = ISC_R_UNEXPECTED;
|
result = ISC_R_UNEXPECTED;
|
||||||
addr_bucket = DNS_ADB_INVALIDBUCKET;
|
addr_bucket = DNS_ADB_INVALIDBUCKET;
|
||||||
return_success = ISC_FALSE;
|
return_success = ISC_FALSE;
|
||||||
|
entry = NULL;
|
||||||
|
nh = NULL;
|
||||||
|
|
||||||
/*
|
use_hints = dns_name_equal(zone, dns_rootname);
|
||||||
* Allocate an entry and a namehook, but don't string them up
|
dns_rdataset_init(&rdataset);
|
||||||
* anywhere yet. If we need more, we will have to get more later.
|
adbname->partial_result = ISC_FALSE;
|
||||||
* These are the first two that cannot fail or else we are broken.
|
|
||||||
* Later ones can fail, but it is still bad to have that happen.
|
|
||||||
*/
|
|
||||||
entry = new_adbentry(adb);
|
|
||||||
if (entry == NULL) {
|
|
||||||
result = ISC_R_NOMEMORY;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
nh = new_adbnamehook(adb, NULL);
|
|
||||||
if (nh == NULL) {
|
|
||||||
result = ISC_R_NOMEMORY;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
result = dns_view_find(adb->view, name, dns_rdatatype_a,
|
||||||
* Look up the A record in the database, the cache, or in glue.
|
now, DNS_DBFIND_GLUEOK, use_hints,
|
||||||
* If it isn't found in any of these, we will have to start a
|
&rdataset, NULL);
|
||||||
* fetch for it.
|
if (result == DNS_R_SUCCESS ||
|
||||||
*/
|
result == DNS_R_GLUE ||
|
||||||
|
result == DNS_R_HINT) {
|
||||||
|
result = dns_rdataset_first(&rdataset);
|
||||||
|
while (result == ISC_R_SUCCESS) {
|
||||||
|
entry = new_adbentry(adb);
|
||||||
|
if (entry == NULL) {
|
||||||
|
adbname->partial_result = ISC_TRUE;
|
||||||
|
result = ISC_R_NOMEMORY;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
nh = new_adbnamehook(adb, NULL);
|
||||||
|
if (nh == NULL) {
|
||||||
|
adbname->partial_result = ISC_TRUE;
|
||||||
|
result = ISC_R_NOMEMORY;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
dns_rdataset_current(&rdataset, &rdata);
|
||||||
|
INSIST(rdata.length == 4);
|
||||||
|
memcpy(&ina.s_addr, rdata.data, 4);
|
||||||
|
isc_sockaddr_fromin(&entry->sockaddr, &ina, 53);
|
||||||
|
|
||||||
|
return_success = ISC_TRUE;
|
||||||
|
|
||||||
|
result = dns_rdataset_next(&rdataset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
if (dns_rdataset_isassociated(&rdataset))
|
||||||
|
dns_rdataset_disassociate(&rdataset);
|
||||||
if (entry != NULL)
|
if (entry != NULL)
|
||||||
free_adbentry(adb, &entry);
|
free_adbentry(adb, &entry);
|
||||||
if (nh != NULL)
|
if (nh != NULL)
|
||||||
@@ -1722,7 +1749,6 @@ construct_name(dns_adb_t *adb, dns_adbhandle_t *handle, dns_name_t *name,
|
|||||||
|
|
||||||
if (return_success)
|
if (return_success)
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
adbname->partial_results = ISC_TRUE;
|
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -129,6 +129,7 @@ struct dns_adbhandle {
|
|||||||
ISC_LIST(dns_adbaddrinfo_t) list; /* RO: list of addrs */
|
ISC_LIST(dns_adbaddrinfo_t) list; /* RO: list of addrs */
|
||||||
ISC_LINK(dns_adbhandle_t) next; /* RW: next handle */
|
ISC_LINK(dns_adbhandle_t) next; /* RW: next handle */
|
||||||
isc_boolean_t query_pending; /* RO: partial list */
|
isc_boolean_t query_pending; /* RO: partial list */
|
||||||
|
isc_boolean_t partial_result; /* RO: addrs missing */
|
||||||
isc_result_t result; /* RO: extra result */
|
isc_result_t result; /* RO: extra result */
|
||||||
|
|
||||||
/* Private */
|
/* Private */
|
||||||
@@ -254,7 +255,8 @@ dns_adb_lookup(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
|
|||||||
*
|
*
|
||||||
* *adb be a valid isc_adb_t object.
|
* *adb be a valid isc_adb_t object.
|
||||||
*
|
*
|
||||||
* *task be a valid task, and isc_taskaction_t != NULL.
|
* If events are to be sent, *task be a valid task,
|
||||||
|
* and isc_taskaction_t != NULL.
|
||||||
*
|
*
|
||||||
* *name is a valid dns_name_t.
|
* *name is a valid dns_name_t.
|
||||||
*
|
*
|
||||||
@@ -267,7 +269,8 @@ dns_adb_lookup(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
|
|||||||
* ISC_R_SUCCESS Addresses might have been returned, and events will be
|
* ISC_R_SUCCESS Addresses might have been returned, and events will be
|
||||||
* delivered for unresolved addresses.
|
* delivered for unresolved addresses.
|
||||||
* ISC_R_NOMORE Addresses might have been returned, but no events
|
* ISC_R_NOMORE Addresses might have been returned, but no events
|
||||||
* will ever be posted for this context.
|
* will ever be posted for this context. This is only
|
||||||
|
* returned if task != NULL.
|
||||||
* ISC_R_NOMEMORY insufficient resources
|
* ISC_R_NOMEMORY insufficient resources
|
||||||
*
|
*
|
||||||
* Calls, and returns error codes from:
|
* Calls, and returns error codes from:
|
||||||
|
Reference in New Issue
Block a user