lookup.c revision 573d78f3d53859bc01ce5d5cebbaac9b8b90bfba
69fe9aaafdd6a141610e86a777d325db75422070Mark Andrews * Copyright (C) 2004, 2005, 2007, 2013 Internet Systems Consortium, Inc. ("ISC")
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
cd82aa8fa32698240ecd6634f11e3052ca7a2448Michael Graff * Permission to use, copy, modify, and/or distribute this software for any
cd82aa8fa32698240ecd6634f11e3052ca7a2448Michael Graff * purpose with or without fee is hereby granted, provided that the above
cd82aa8fa32698240ecd6634f11e3052ca7a2448Michael Graff * copyright notice and this permission notice appear in all copies.
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * PERFORMANCE OF THIS SOFTWARE.
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews/* $Id: lookup.c,v 1.21 2007/06/18 23:47:40 tbox Exp $ */
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <isc/string.h> /* Required for HP/UX (and others?) */
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews /* Unlocked. */
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews unsigned int magic;
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews /* Locked by lock. */
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews unsigned int options;
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews unsigned int restarts;
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews#define LOOKUP_MAGIC ISC_MAGIC('l', 'o', 'o', 'k')
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews#define VALID_LOOKUP(l) ISC_MAGIC_VALID((l), LOOKUP_MAGIC)
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrewsstatic void lookup_find(dns_lookup_t *lookup, dns_fetchevent_t *event);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrewsfetch_done(isc_task_t *task, isc_event_t *event) {
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE);
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews * The caller must be holding the lookup's lock.
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews result = dns_resolver_createfetch(lookup->view->resolver,
88b9c12a3cbafc3bebedf50a731bec9ce2f99a13Brian Wellington name = isc_mem_get(lookup->mctx, sizeof(dns_name_t));
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews result = dns_name_dup(dns_fixedname_name(&lookup->name),
cd82aa8fa32698240ecd6634f11e3052ca7a2448Michael Graff if (dns_rdataset_isassociated(&lookup->rdataset)) {
88b9c12a3cbafc3bebedf50a731bec9ce2f99a13Brian Wellington rdataset = isc_mem_get(lookup->mctx, sizeof(dns_rdataset_t));
88b9c12a3cbafc3bebedf50a731bec9ce2f99a13Brian Wellington dns_rdataset_clone(&lookup->rdataset, rdataset);
383665e42ad838046472e847b16c4e0d3f1aaf76Bob Halley if (dns_rdataset_isassociated(&lookup->sigrdataset)) {
88b9c12a3cbafc3bebedf50a731bec9ce2f99a13Brian Wellington dns_rdataset_clone(&lookup->sigrdataset, sigrdataset);
88b9c12a3cbafc3bebedf50a731bec9ce2f99a13Brian Wellington isc_mem_put(lookup->mctx, name, sizeof(dns_name_t));
383665e42ad838046472e847b16c4e0d3f1aaf76Bob Halley isc_mem_put(lookup->mctx, rdataset, sizeof(dns_rdataset_t));
88b9c12a3cbafc3bebedf50a731bec9ce2f99a13Brian Wellingtonview_find(dns_lookup_t *lookup, dns_name_t *foundname) {
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews dns_name_t *name = dns_fixedname_name(&lookup->name);
383665e42ad838046472e847b16c4e0d3f1aaf76Bob Halley result = dns_view_find(lookup->view, name, type, 0, 0, ISC_FALSE,
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrewslookup_find(dns_lookup_t *lookup, dns_fetchevent_t *event) {
cd82aa8fa32698240ecd6634f11e3052ca7a2448Michael Graff INSIST(!dns_rdataset_isassociated(&lookup->rdataset));
cd82aa8fa32698240ecd6634f11e3052ca7a2448Michael Graff * If we have restarted then clear the old node. */
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews * We don't know anything about the name.
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews * Launch a fetch.
d76ed813a51465e5c47d521ab09ea20c06f1428dMark Andrews INSIST(event->sigrdataset == &lookup->sigrdataset);
cd82aa8fa32698240ecd6634f11e3052ca7a2448Michael Graff * If we've been canceled, forget about the result.
8cf24d101a291aa3274e8fd07d1a13cb5fe9976bBrian Wellington * Copy the CNAME's target into the lookup's
8cf24d101a291aa3274e8fd07d1a13cb5fe9976bBrian Wellington * query name and start over.
8cf24d101a291aa3274e8fd07d1a13cb5fe9976bBrian Wellington result = dns_rdataset_first(&lookup->rdataset);
8cf24d101a291aa3274e8fd07d1a13cb5fe9976bBrian Wellington dns_rdataset_current(&lookup->rdataset, &rdata);
8cf24d101a291aa3274e8fd07d1a13cb5fe9976bBrian Wellington result = dns_rdata_tostruct(&rdata, &cname, NULL);
80b782f356f0692c11b4e52e8dd46ec41704e5a2Mark Andrews result = dns_name_copy(&cname.cname, name, NULL);
8cf24d101a291aa3274e8fd07d1a13cb5fe9976bBrian Wellington namereln = dns_name_fullcompare(name, fname, &order,
8cf24d101a291aa3274e8fd07d1a13cb5fe9976bBrian Wellington INSIST(namereln == dns_namereln_subdomain);
8cf24d101a291aa3274e8fd07d1a13cb5fe9976bBrian Wellington * Get the target name of the DNAME.
8cf24d101a291aa3274e8fd07d1a13cb5fe9976bBrian Wellington result = dns_rdataset_first(&lookup->rdataset);
80b782f356f0692c11b4e52e8dd46ec41704e5a2Mark Andrews dns_rdataset_current(&lookup->rdataset, &rdata);
8cf24d101a291aa3274e8fd07d1a13cb5fe9976bBrian Wellington result = dns_rdata_tostruct(&rdata, &dname, NULL);
8cf24d101a291aa3274e8fd07d1a13cb5fe9976bBrian Wellington * Construct the new query name and start over.
8cf24d101a291aa3274e8fd07d1a13cb5fe9976bBrian Wellington dns_name_split(name, nlabels, prefix, NULL);
8cf24d101a291aa3274e8fd07d1a13cb5fe9976bBrian Wellington result = dns_name_concatenate(prefix, &dname.dname,
8cf24d101a291aa3274e8fd07d1a13cb5fe9976bBrian Wellington if (dns_rdataset_isassociated(&lookup->rdataset))
8cf24d101a291aa3274e8fd07d1a13cb5fe9976bBrian Wellington dns_rdataset_disassociate(&lookup->rdataset);
8cf24d101a291aa3274e8fd07d1a13cb5fe9976bBrian Wellington if (dns_rdataset_isassociated(&lookup->sigrdataset))
8cf24d101a291aa3274e8fd07d1a13cb5fe9976bBrian Wellington dns_rdataset_disassociate(&lookup->sigrdataset);
8cf24d101a291aa3274e8fd07d1a13cb5fe9976bBrian Wellington dns_db_detachnode(event->db, &event->node);
8cf24d101a291aa3274e8fd07d1a13cb5fe9976bBrian Wellington * Limit the number of restarts.
8cf24d101a291aa3274e8fd07d1a13cb5fe9976bBrian Wellington if (want_restart && lookup->restarts == MAX_RESTARTS) {
8cf24d101a291aa3274e8fd07d1a13cb5fe9976bBrian Wellington REQUIRE(event->ev_type == DNS_EVENT_LOOKUPDONE);
8cf24d101a291aa3274e8fd07d1a13cb5fe9976bBrian Wellington isc_mem_put(mctx, levent->name, sizeof(dns_name_t));
8cf24d101a291aa3274e8fd07d1a13cb5fe9976bBrian Wellington dns_rdataset_disassociate(levent->rdataset);
8cf24d101a291aa3274e8fd07d1a13cb5fe9976bBrian Wellington isc_mem_put(mctx, levent->rdataset, sizeof(dns_rdataset_t));
8cf24d101a291aa3274e8fd07d1a13cb5fe9976bBrian Wellington dns_rdataset_disassociate(levent->sigrdataset);
8cf24d101a291aa3274e8fd07d1a13cb5fe9976bBrian Wellington isc_mem_put(mctx, levent->sigrdataset, sizeof(dns_rdataset_t));
8cf24d101a291aa3274e8fd07d1a13cb5fe9976bBrian Wellington dns_db_detachnode(levent->db, &levent->node);
e800570a5a7572a94604815cd7d7e788c0479ed2Bob Halleydns_lookup_create(isc_mem_t *mctx, dns_name_t *name, dns_rdatatype_t type,
e800570a5a7572a94604815cd7d7e788c0479ed2Bob Halley dns_view_t *view, unsigned int options, isc_task_t *task,
e800570a5a7572a94604815cd7d7e788c0479ed2Bob Halley isc_taskaction_t action, void *arg, dns_lookup_t **lookupp)
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence ievent = isc_event_allocate(mctx, lookup, DNS_EVENT_LOOKUPDONE,
da41917c3f882b6e12c7101b653926830a396b81Andreas Gustafsson lookup->event = (dns_lookupevent_t *)ievent;
da41917c3f882b6e12c7101b653926830a396b81Andreas Gustafsson lookup->event->ev_destroy = levent_destroy;
da41917c3f882b6e12c7101b653926830a396b81Andreas Gustafsson result = dns_name_copy(name, dns_fixedname_name(&lookup->name), NULL);
368b37b616234fce3d23099eb180f1dd38e1fb62Mark Andrews isc_mem_putanddetach(&mctx, lookup, sizeof(*lookup));
5bfea18ff8bfa907b86ba7d17fb38b9cf493ae97Bob Halley if (dns_rdataset_isassociated(&lookup->rdataset))
5bfea18ff8bfa907b86ba7d17fb38b9cf493ae97Bob Halley if (dns_rdataset_isassociated(&lookup->sigrdataset))