cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews/*
3523e19da21545ade45394cb64d7462f20b77347Tinderbox User * Copyright (C) 2000-2005, 2007, 2009, 2013, 2016, 2017 Internet Systems Consortium, Inc. ("ISC")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews */
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/* $Id: byaddr.c,v 1.41 2009/09/02 23:48:02 tbox Exp $ */
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews/*! \file */
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews
94da1ee12ce2c4a3538f4edeaf9ba3524598c539David Lawrence#include <config.h>
8c9c09dacf7e74f20ad5c23854d5c97d2542ee36Michael Graff
8c9c09dacf7e74f20ad5c23854d5c97d2542ee36Michael Graff#include <isc/mem.h>
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews#include <isc/netaddr.h>
94da1ee12ce2c4a3538f4edeaf9ba3524598c539David Lawrence#include <isc/print.h>
125a916d1a0c01f139ced5736145703df28d07cfDavid Lawrence#include <isc/string.h> /* Required for HP/UX (and others?) */
125a916d1a0c01f139ced5736145703df28d07cfDavid Lawrence#include <isc/task.h>
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews#include <isc/util.h>
125a916d1a0c01f139ced5736145703df28d07cfDavid Lawrence
9cd6d409b78a6f833b681c13a68fbdc7c024fe66David Lawrence#include <dns/byaddr.h>
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews#include <dns/db.h>
21f1794606dce19928cf455029e173321f166380Mark Andrews#include <dns/events.h>
5188f8c6a5d149032acb4243bedef4df4e703445Bob Halley#include <dns/lookup.h>
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews#include <dns/rdata.h>
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews#include <dns/rdataset.h>
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews#include <dns/rdatastruct.h>
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews#include <dns/resolver.h>
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews#include <dns/result.h>
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews#include <dns/view.h>
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews/*
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews * XXXRTH We could use a static event...
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt */
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Huntstatic char hex_digits[] = {
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews '0', '1', '2', '3', '4', '5', '6', '7',
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews};
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Huntisc_result_t
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Huntdns_byaddr_createptrname(isc_netaddr_t *address, isc_boolean_t nibble,
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews dns_name_t *name)
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt{
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt /*
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews * We dropped bitstring labels, so all lookups will use nibbles.
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews */
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt UNUSED(nibble);
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt return (dns_byaddr_createptrname2(address,
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews DNS_BYADDROPT_IPV6INT, name));
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt}
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Huntisc_result_t
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Huntdns_byaddr_createptrname2(isc_netaddr_t *address, unsigned int options,
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt dns_name_t *name)
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt{
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews char textname[128];
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews unsigned char *bytes;
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt int i;
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews char *cp;
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt isc_buffer_t buffer;
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt unsigned int len;
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt REQUIRE(address != NULL);
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt /*
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt * We create the text representation and then convert to a
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt * dns_name_t. This is not maximally efficient, but it keeps all
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt * of the knowledge of wire format in the dns_name_ routines.
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews */
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews bytes = (unsigned char *)(&address->type);
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt if (address->family == AF_INET) {
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews (void)snprintf(textname, sizeof(textname),
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt "%u.%u.%u.%u.in-addr.arpa.",
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt (bytes[3] & 0xff),
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt (bytes[2] & 0xff),
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt (bytes[1] & 0xff),
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews (bytes[0] & 0xff));
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews } else if (address->family == AF_INET6) {
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews size_t remaining;
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews cp = textname;
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews for (i = 15; i >= 0; i--) {
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews *cp++ = hex_digits[bytes[i] & 0x0f];
f95231835fdcd8d5f58486c9f9993602f27fe157Mark Andrews *cp++ = '.';
f95231835fdcd8d5f58486c9f9993602f27fe157Mark Andrews *cp++ = hex_digits[(bytes[i] >> 4) & 0x0f];
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews *cp++ = '.';
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews }
f95231835fdcd8d5f58486c9f9993602f27fe157Mark Andrews remaining = sizeof(textname) - (cp - textname);
f95231835fdcd8d5f58486c9f9993602f27fe157Mark Andrews if ((options & DNS_BYADDROPT_IPV6INT) != 0) {
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews strlcpy(cp, "ip6.int.", remaining);
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews } else {
f95231835fdcd8d5f58486c9f9993602f27fe157Mark Andrews strlcpy(cp, "ip6.arpa.", remaining);
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews }
f95231835fdcd8d5f58486c9f9993602f27fe157Mark Andrews } else
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews return (ISC_R_NOTIMPLEMENTED);
f95231835fdcd8d5f58486c9f9993602f27fe157Mark Andrews
f95231835fdcd8d5f58486c9f9993602f27fe157Mark Andrews len = (unsigned int)strlen(textname);
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein isc_buffer_init(&buffer, textname, len);
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews isc_buffer_add(&buffer, len);
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews return (dns_name_fromtext(name, &buffer, dns_rootname, 0, NULL));
4115f9d34bfaa9d4cda383b557f354448ca93c1eAndreas Gustafsson}
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrewsstruct dns_byaddr {
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews /* Unlocked. */
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews unsigned int magic;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews isc_mem_t * mctx;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews isc_mutex_t lock;
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews dns_fixedname_t name;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews /* Locked by lock. */
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews unsigned int options;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews dns_lookup_t * lookup;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews isc_task_t * task;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews dns_byaddrevent_t * event;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein isc_boolean_t canceled;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews};
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews#define BYADDR_MAGIC ISC_MAGIC('B', 'y', 'A', 'd')
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt#define VALID_BYADDR(b) ISC_MAGIC_VALID(b, BYADDR_MAGIC)
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt#define MAX_RESTARTS 16
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt
5af75577578793cb49c0890bfbc47678ba641b2cMark Andrewsstatic inline isc_result_t
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Huntcopy_ptr_targets(dns_byaddr_t *byaddr, dns_rdataset_t *rdataset) {
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews isc_result_t result;
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt dns_name_t *name;
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt dns_rdata_t rdata = DNS_RDATA_INIT;
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews /*
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews * The caller must be holding the byaddr's lock.
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt */
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt result = dns_rdataset_first(rdataset);
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews while (result == ISC_R_SUCCESS) {
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews dns_rdata_ptr_t ptr;
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt dns_rdataset_current(rdataset, &rdata);
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt result = dns_rdata_tostruct(&rdata, &ptr, NULL);
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt if (result != ISC_R_SUCCESS)
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt return (result);
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt name = isc_mem_get(byaddr->mctx, sizeof(*name));
5af75577578793cb49c0890bfbc47678ba641b2cMark Andrews if (name == NULL) {
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt dns_rdata_freestruct(&ptr);
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt return (ISC_R_NOMEMORY);
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt }
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt dns_name_init(name, NULL);
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt result = dns_name_dup(&ptr.ptr, byaddr->mctx, name);
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt dns_rdata_freestruct(&ptr);
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt if (result != ISC_R_SUCCESS) {
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt isc_mem_put(byaddr->mctx, name, sizeof(*name));
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews return (ISC_R_NOMEMORY);
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews }
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt ISC_LIST_APPEND(byaddr->event->names, name, link);
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews dns_rdata_reset(&rdata);
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews result = dns_rdataset_next(rdataset);
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews }
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews if (result == ISC_R_NOMORE)
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews result = ISC_R_SUCCESS;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews return (result);
9165c95fc2d5bd406e3531a5cba2c8fc4faea5d5Andreas Gustafsson}
4115f9d34bfaa9d4cda383b557f354448ca93c1eAndreas Gustafsson
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrewsstatic void
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrewslookup_done(isc_task_t *task, isc_event_t *event) {
6b526894f47f6d6ff08f4f49b952b4ec8247ba9eDavid Lawrence dns_byaddr_t *byaddr = event->ev_arg;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews dns_lookupevent_t *levent;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews isc_result_t result;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews
125a916d1a0c01f139ced5736145703df28d07cfDavid Lawrence REQUIRE(event->ev_type == DNS_EVENT_LOOKUPDONE);
125a916d1a0c01f139ced5736145703df28d07cfDavid Lawrence REQUIRE(VALID_BYADDR(byaddr));
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews REQUIRE(byaddr->task == task);
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews UNUSED(task);
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews levent = (dns_lookupevent_t *)event;
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews
34884bf7892a28c1d6286283fb3e9bc0f94667a2Mark Andrews if (levent->result == ISC_R_SUCCESS) {
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews result = copy_ptr_targets(byaddr, levent->rdataset);
34884bf7892a28c1d6286283fb3e9bc0f94667a2Mark Andrews byaddr->event->result = result;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews } else
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence byaddr->event->result = levent->result;
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews isc_event_free(&event);
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews isc_task_sendanddetach(&byaddr->task, (isc_event_t **)&byaddr->event);
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews}
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrewsstatic void
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrewsbevent_destroy(isc_event_t *event) {
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt dns_byaddrevent_t *bevent;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews dns_name_t *name, *next_name;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews isc_mem_t *mctx;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews REQUIRE(event->ev_type == DNS_EVENT_BYADDRDONE);
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews mctx = event->ev_destroy_arg;
47b26abe77184f9bedc68e36bdad03332cf67570David Lawrence bevent = (dns_byaddrevent_t *)event;
47b26abe77184f9bedc68e36bdad03332cf67570David Lawrence
47b26abe77184f9bedc68e36bdad03332cf67570David Lawrence for (name = ISC_LIST_HEAD(bevent->names);
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt name != NULL;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews name = next_name) {
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews next_name = ISC_LIST_NEXT(name, link);
2e6d7a724ab1d4b3f6d30573d0b4b138cc71e6a4Mark Andrews ISC_LIST_UNLINK(bevent->names, name, link);
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews dns_name_free(name, mctx);
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews isc_mem_put(mctx, name, sizeof(*name));
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews }
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews isc_mem_put(mctx, event, event->ev_size);
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews}
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrewsisc_result_t
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrewsdns_byaddr_create(isc_mem_t *mctx, isc_netaddr_t *address, dns_view_t *view,
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews unsigned int options, isc_task_t *task,
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews isc_taskaction_t action, void *arg, dns_byaddr_t **byaddrp)
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews{
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews isc_result_t result;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews dns_byaddr_t *byaddr;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews isc_event_t *ievent;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews byaddr = isc_mem_get(mctx, sizeof(*byaddr));
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews if (byaddr == NULL)
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews return (ISC_R_NOMEMORY);
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews byaddr->mctx = NULL;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews isc_mem_attach(mctx, &byaddr->mctx);
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews byaddr->options = options;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews byaddr->event = isc_mem_get(mctx, sizeof(*byaddr->event));
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews if (byaddr->event == NULL) {
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews result = ISC_R_NOMEMORY;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews goto cleanup_byaddr;
47b26abe77184f9bedc68e36bdad03332cf67570David Lawrence }
47b26abe77184f9bedc68e36bdad03332cf67570David Lawrence ISC_EVENT_INIT(byaddr->event, sizeof(*byaddr->event), 0, NULL,
47b26abe77184f9bedc68e36bdad03332cf67570David Lawrence DNS_EVENT_BYADDRDONE, action, arg, byaddr,
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews bevent_destroy, mctx);
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews byaddr->event->result = ISC_R_FAILURE;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews ISC_LIST_INIT(byaddr->event->names);
47b26abe77184f9bedc68e36bdad03332cf67570David Lawrence
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews byaddr->task = NULL;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews isc_task_attach(task, &byaddr->task);
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence result = isc_mutex_init(&byaddr->lock);
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews if (result != ISC_R_SUCCESS)
47b26abe77184f9bedc68e36bdad03332cf67570David Lawrence goto cleanup_event;
47b26abe77184f9bedc68e36bdad03332cf67570David Lawrence
47b26abe77184f9bedc68e36bdad03332cf67570David Lawrence dns_fixedname_init(&byaddr->name);
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews result = dns_byaddr_createptrname2(address, options,
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews dns_fixedname_name(&byaddr->name));
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews if (result != ISC_R_SUCCESS)
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews goto cleanup_lock;
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews byaddr->lookup = NULL;
47b26abe77184f9bedc68e36bdad03332cf67570David Lawrence result = dns_lookup_create(mctx, dns_fixedname_name(&byaddr->name),
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews dns_rdatatype_ptr, view, 0, task,
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews lookup_done, byaddr, &byaddr->lookup);
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews if (result != ISC_R_SUCCESS)
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews goto cleanup_lock;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews byaddr->canceled = ISC_FALSE;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews byaddr->magic = BYADDR_MAGIC;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews *byaddrp = byaddr;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews return (ISC_R_SUCCESS);
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews cleanup_lock:
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews DESTROYLOCK(&byaddr->lock);
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews cleanup_event:
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews ievent = (isc_event_t *)byaddr->event;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews isc_event_free(&ievent);
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews byaddr->event = NULL;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews isc_task_detach(&byaddr->task);
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews cleanup_byaddr:
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews isc_mem_putanddetach(&mctx, byaddr, sizeof(*byaddr));
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews
d76b6ae2ad6a61e02daa642ee8a562f7c324f477Andreas Gustafsson return (result);
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews}
d76b6ae2ad6a61e02daa642ee8a562f7c324f477Andreas Gustafsson
d76b6ae2ad6a61e02daa642ee8a562f7c324f477Andreas Gustafssonvoid
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrewsdns_byaddr_cancel(dns_byaddr_t *byaddr) {
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt REQUIRE(VALID_BYADDR(byaddr));
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt LOCK(&byaddr->lock);
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt
a0e34c90eaf2464c6ef7c46c75c2df2dcb152293Mark Andrews if (!byaddr->canceled) {
a0e34c90eaf2464c6ef7c46c75c2df2dcb152293Mark Andrews byaddr->canceled = ISC_TRUE;
a0e34c90eaf2464c6ef7c46c75c2df2dcb152293Mark Andrews if (byaddr->lookup != NULL)
a0e34c90eaf2464c6ef7c46c75c2df2dcb152293Mark Andrews dns_lookup_cancel(byaddr->lookup);
a0e34c90eaf2464c6ef7c46c75c2df2dcb152293Mark Andrews }
a0e34c90eaf2464c6ef7c46c75c2df2dcb152293Mark Andrews
a0e34c90eaf2464c6ef7c46c75c2df2dcb152293Mark Andrews UNLOCK(&byaddr->lock);
a0e34c90eaf2464c6ef7c46c75c2df2dcb152293Mark Andrews}
a0e34c90eaf2464c6ef7c46c75c2df2dcb152293Mark Andrews
a0e34c90eaf2464c6ef7c46c75c2df2dcb152293Mark Andrewsvoid
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrewsdns_byaddr_destroy(dns_byaddr_t **byaddrp) {
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews dns_byaddr_t *byaddr;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews REQUIRE(byaddrp != NULL);
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews byaddr = *byaddrp;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews REQUIRE(VALID_BYADDR(byaddr));
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews REQUIRE(byaddr->event == NULL);
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews REQUIRE(byaddr->task == NULL);
5af75577578793cb49c0890bfbc47678ba641b2cMark Andrews dns_lookup_destroy(&byaddr->lookup);
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews DESTROYLOCK(&byaddr->lock);
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews byaddr->magic = 0;
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews isc_mem_putanddetach(&byaddr->mctx, byaddr, sizeof(*byaddr));
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews
cd71050434eb719ac56ce7cdc350964475c5bc47Mark Andrews *byaddrp = NULL;
38c19e577915221b1783791cbb4f4e3ceea20019Mark Andrews}
cadf8d687b9719b87c121d5cc8b028b1ddccc642Evan Hunt