1135446Strhodes/* 2262706Serwin * Copyright (C) 2004-2007, 2009, 2013, 2014 Internet Systems Consortium, Inc. ("ISC") 3135446Strhodes * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. 4135446Strhodes * 5193149Sdougb * Permission to use, copy, modify, and/or distribute this software for any 6135446Strhodes * purpose with or without fee is hereby granted, provided that the above 7135446Strhodes * copyright notice and this permission notice appear in all copies. 8135446Strhodes * 9135446Strhodes * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10135446Strhodes * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11135446Strhodes * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12135446Strhodes * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13135446Strhodes * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14135446Strhodes * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15135446Strhodes * PERFORMANCE OF THIS SOFTWARE. 16135446Strhodes */ 17135446Strhodes 18234010Sdougb/* $Id: lwdgrbn.c,v 1.22 2009/09/02 23:48:01 tbox Exp $ */ 19135446Strhodes 20170222Sdougb/*! \file */ 21170222Sdougb 22135446Strhodes#include <config.h> 23135446Strhodes 24135446Strhodes#include <isc/mem.h> 25135446Strhodes#include <isc/socket.h> 26135446Strhodes#include <isc/string.h> /* Required for HP/UX (and others?) */ 27135446Strhodes#include <isc/util.h> 28135446Strhodes 29135446Strhodes#include <dns/db.h> 30135446Strhodes#include <dns/lookup.h> 31135446Strhodes#include <dns/rdata.h> 32135446Strhodes#include <dns/rdataset.h> 33135446Strhodes#include <dns/rdatasetiter.h> 34135446Strhodes#include <dns/result.h> 35135446Strhodes#include <dns/view.h> 36135446Strhodes 37135446Strhodes#include <named/types.h> 38135446Strhodes#include <named/lwdclient.h> 39135446Strhodes#include <named/lwresd.h> 40135446Strhodes#include <named/lwsearch.h> 41135446Strhodes 42135446Strhodesstatic void start_lookup(ns_lwdclient_t *); 43135446Strhodes 44135446Strhodesstatic isc_result_t 45135446Strhodesfill_array(int *pos, dns_rdataset_t *rdataset, 46135446Strhodes int size, unsigned char **rdatas, lwres_uint16_t *rdatalen) 47135446Strhodes{ 48135446Strhodes dns_rdata_t rdata; 49135446Strhodes isc_result_t result; 50135446Strhodes isc_region_t r; 51135446Strhodes 52135446Strhodes UNUSED(size); 53135446Strhodes 54135446Strhodes dns_rdata_init(&rdata); 55135446Strhodes for (result = dns_rdataset_first(rdataset); 56135446Strhodes result == ISC_R_SUCCESS; 57135446Strhodes result = dns_rdataset_next(rdataset)) 58135446Strhodes { 59135446Strhodes INSIST(*pos < size); 60135446Strhodes dns_rdataset_current(rdataset, &rdata); 61135446Strhodes dns_rdata_toregion(&rdata, &r); 62135446Strhodes rdatas[*pos] = r.base; 63135446Strhodes rdatalen[*pos] = r.length; 64135446Strhodes dns_rdata_reset(&rdata); 65135446Strhodes (*pos)++; 66135446Strhodes } 67135446Strhodes if (result == ISC_R_NOMORE) 68135446Strhodes result = ISC_R_SUCCESS; 69135446Strhodes return (result); 70135446Strhodes} 71135446Strhodes 72135446Strhodesstatic isc_result_t 73135446Strhodesiterate_node(lwres_grbnresponse_t *grbn, dns_db_t *db, dns_dbnode_t *node, 74135446Strhodes isc_mem_t *mctx) 75135446Strhodes{ 76135446Strhodes int used = 0, count; 77135446Strhodes int size = 8, oldsize = 0; 78135446Strhodes unsigned char **rdatas = NULL, **oldrdatas = NULL, **newrdatas = NULL; 79135446Strhodes lwres_uint16_t *lens = NULL, *oldlens = NULL, *newlens = NULL; 80135446Strhodes dns_rdatasetiter_t *iter = NULL; 81135446Strhodes dns_rdataset_t set; 82135446Strhodes dns_ttl_t ttl = ISC_INT32_MAX; 83135446Strhodes lwres_uint32_t flags = LWRDATA_VALIDATED; 84135446Strhodes isc_result_t result = ISC_R_NOMEMORY; 85135446Strhodes 86135446Strhodes result = dns_db_allrdatasets(db, node, NULL, 0, &iter); 87135446Strhodes if (result != ISC_R_SUCCESS) 88135446Strhodes goto out; 89135446Strhodes 90135446Strhodes rdatas = isc_mem_get(mctx, size * sizeof(*rdatas)); 91135446Strhodes if (rdatas == NULL) 92135446Strhodes goto out; 93135446Strhodes lens = isc_mem_get(mctx, size * sizeof(*lens)); 94135446Strhodes if (lens == NULL) 95135446Strhodes goto out; 96135446Strhodes 97135446Strhodes for (result = dns_rdatasetiter_first(iter); 98135446Strhodes result == ISC_R_SUCCESS; 99135446Strhodes result = dns_rdatasetiter_next(iter)) 100135446Strhodes { 101135446Strhodes result = ISC_R_NOMEMORY; 102135446Strhodes dns_rdataset_init(&set); 103135446Strhodes dns_rdatasetiter_current(iter, &set); 104135446Strhodes 105135446Strhodes if (set.type != dns_rdatatype_rrsig) { 106135446Strhodes dns_rdataset_disassociate(&set); 107135446Strhodes continue; 108135446Strhodes } 109135446Strhodes 110135446Strhodes count = dns_rdataset_count(&set); 111135446Strhodes if (used + count > size) { 112135446Strhodes /* copy & reallocate */ 113135446Strhodes oldsize = size; 114135446Strhodes oldrdatas = rdatas; 115135446Strhodes oldlens = lens; 116135446Strhodes rdatas = NULL; 117135446Strhodes lens = NULL; 118135446Strhodes 119135446Strhodes size *= 2; 120135446Strhodes 121135446Strhodes rdatas = isc_mem_get(mctx, size * sizeof(*rdatas)); 122135446Strhodes if (rdatas == NULL) 123135446Strhodes goto out; 124135446Strhodes lens = isc_mem_get(mctx, size * sizeof(*lens)); 125135446Strhodes if (lens == NULL) 126135446Strhodes goto out; 127262706Serwin memmove(rdatas, oldrdatas, used * sizeof(*rdatas)); 128262706Serwin memmove(lens, oldlens, used * sizeof(*lens)); 129135446Strhodes isc_mem_put(mctx, oldrdatas, 130135446Strhodes oldsize * sizeof(*oldrdatas)); 131135446Strhodes isc_mem_put(mctx, oldlens, oldsize * sizeof(*oldlens)); 132135446Strhodes oldrdatas = NULL; 133135446Strhodes oldlens = NULL; 134135446Strhodes } 135135446Strhodes if (set.ttl < ttl) 136135446Strhodes ttl = set.ttl; 137135446Strhodes if (set.trust != dns_trust_secure) 138135446Strhodes flags &= (~LWRDATA_VALIDATED); 139135446Strhodes result = fill_array(&used, &set, size, rdatas, lens); 140135446Strhodes dns_rdataset_disassociate(&set); 141135446Strhodes if (result != ISC_R_SUCCESS) 142135446Strhodes goto out; 143135446Strhodes } 144135446Strhodes if (result == ISC_R_NOMORE) 145135446Strhodes result = ISC_R_SUCCESS; 146135446Strhodes if (result != ISC_R_SUCCESS) 147135446Strhodes goto out; 148135446Strhodes dns_rdatasetiter_destroy(&iter); 149135446Strhodes 150135446Strhodes /* 151135446Strhodes * If necessary, shrink and copy the arrays. 152135446Strhodes */ 153135446Strhodes if (size != used) { 154135446Strhodes result = ISC_R_NOMEMORY; 155135446Strhodes newrdatas = isc_mem_get(mctx, used * sizeof(*rdatas)); 156135446Strhodes if (newrdatas == NULL) 157135446Strhodes goto out; 158135446Strhodes newlens = isc_mem_get(mctx, used * sizeof(*lens)); 159135446Strhodes if (newlens == NULL) 160135446Strhodes goto out; 161262706Serwin memmove(newrdatas, rdatas, used * sizeof(*rdatas)); 162262706Serwin memmove(newlens, lens, used * sizeof(*lens)); 163135446Strhodes isc_mem_put(mctx, rdatas, size * sizeof(*rdatas)); 164135446Strhodes isc_mem_put(mctx, lens, size * sizeof(*lens)); 165135446Strhodes grbn->rdatas = newrdatas; 166135446Strhodes grbn->rdatalen = newlens; 167135446Strhodes } else { 168135446Strhodes grbn->rdatas = rdatas; 169135446Strhodes grbn->rdatalen = lens; 170135446Strhodes } 171135446Strhodes grbn->nrdatas = used; 172135446Strhodes grbn->ttl = ttl; 173135446Strhodes grbn->flags = flags; 174135446Strhodes return (ISC_R_SUCCESS); 175135446Strhodes 176135446Strhodes out: 177135446Strhodes dns_rdatasetiter_destroy(&iter); 178135446Strhodes if (rdatas != NULL) 179135446Strhodes isc_mem_put(mctx, rdatas, size * sizeof(*rdatas)); 180135446Strhodes if (lens != NULL) 181135446Strhodes isc_mem_put(mctx, lens, size * sizeof(*lens)); 182135446Strhodes if (oldrdatas != NULL) 183135446Strhodes isc_mem_put(mctx, oldrdatas, oldsize * sizeof(*oldrdatas)); 184135446Strhodes if (oldlens != NULL) 185135446Strhodes isc_mem_put(mctx, oldlens, oldsize * sizeof(*oldlens)); 186135446Strhodes if (newrdatas != NULL) 187135446Strhodes isc_mem_put(mctx, newrdatas, used * sizeof(*oldrdatas)); 188135446Strhodes return (result); 189135446Strhodes} 190135446Strhodes 191135446Strhodesstatic void 192135446Strhodeslookup_done(isc_task_t *task, isc_event_t *event) { 193135446Strhodes ns_lwdclient_t *client; 194135446Strhodes ns_lwdclientmgr_t *cm; 195135446Strhodes dns_lookupevent_t *levent; 196135446Strhodes lwres_buffer_t lwb; 197135446Strhodes dns_name_t *name; 198135446Strhodes dns_rdataset_t *rdataset; 199135446Strhodes dns_rdataset_t *sigrdataset; 200135446Strhodes isc_result_t result; 201135446Strhodes lwres_result_t lwresult; 202135446Strhodes isc_region_t r; 203135446Strhodes isc_buffer_t b; 204135446Strhodes lwres_grbnresponse_t *grbn; 205135446Strhodes int i; 206135446Strhodes 207262706Serwin REQUIRE(event != NULL); 208262706Serwin 209135446Strhodes UNUSED(task); 210135446Strhodes 211135446Strhodes lwb.base = NULL; 212135446Strhodes client = event->ev_arg; 213135446Strhodes cm = client->clientmgr; 214135446Strhodes INSIST(client->lookup == (dns_lookup_t *)event->ev_sender); 215135446Strhodes 216135446Strhodes levent = (dns_lookupevent_t *)event; 217135446Strhodes grbn = &client->grbn; 218135446Strhodes 219135446Strhodes ns_lwdclient_log(50, "lookup event result = %s", 220135446Strhodes isc_result_totext(levent->result)); 221135446Strhodes 222135446Strhodes result = levent->result; 223135446Strhodes if (result != ISC_R_SUCCESS) { 224135446Strhodes dns_lookup_destroy(&client->lookup); 225135446Strhodes isc_event_free(&event); 226135446Strhodes levent = NULL; 227135446Strhodes 228135446Strhodes switch (result) { 229135446Strhodes case DNS_R_NXDOMAIN: 230135446Strhodes case DNS_R_NCACHENXDOMAIN: 231135446Strhodes result = ns_lwsearchctx_next(&client->searchctx); 232135446Strhodes if (result != ISC_R_SUCCESS) 233135446Strhodes lwresult = LWRES_R_NOTFOUND; 234135446Strhodes else { 235135446Strhodes start_lookup(client); 236135446Strhodes return; 237135446Strhodes } 238135446Strhodes break; 239135446Strhodes case DNS_R_NXRRSET: 240135446Strhodes case DNS_R_NCACHENXRRSET: 241135446Strhodes lwresult = LWRES_R_TYPENOTFOUND; 242135446Strhodes break; 243135446Strhodes default: 244135446Strhodes lwresult = LWRES_R_FAILURE; 245135446Strhodes } 246135446Strhodes ns_lwdclient_errorpktsend(client, lwresult); 247135446Strhodes return; 248135446Strhodes } 249135446Strhodes 250135446Strhodes name = levent->name; 251135446Strhodes b = client->recv_buffer; 252135446Strhodes 253135446Strhodes grbn->flags = 0; 254135446Strhodes 255135446Strhodes grbn->nrdatas = 0; 256135446Strhodes grbn->rdatas = NULL; 257135446Strhodes grbn->rdatalen = NULL; 258135446Strhodes 259135446Strhodes grbn->nsigs = 0; 260135446Strhodes grbn->sigs = NULL; 261135446Strhodes grbn->siglen = NULL; 262135446Strhodes 263135446Strhodes result = dns_name_totext(name, ISC_TRUE, &client->recv_buffer); 264135446Strhodes if (result != ISC_R_SUCCESS) 265135446Strhodes goto out; 266135446Strhodes grbn->realname = (char *)isc_buffer_used(&b); 267135446Strhodes grbn->realnamelen = isc_buffer_usedlength(&client->recv_buffer) - 268135446Strhodes isc_buffer_usedlength(&b); 269135446Strhodes ns_lwdclient_log(50, "found name '%.*s'", grbn->realnamelen, 270135446Strhodes grbn->realname); 271135446Strhodes 272135446Strhodes grbn->rdclass = cm->view->rdclass; 273135446Strhodes grbn->rdtype = client->rdtype; 274135446Strhodes 275135446Strhodes rdataset = levent->rdataset; 276135446Strhodes if (rdataset != NULL) { 277135446Strhodes /* The normal case */ 278135446Strhodes grbn->nrdatas = dns_rdataset_count(rdataset); 279135446Strhodes grbn->rdatas = isc_mem_get(cm->mctx, grbn->nrdatas * 280135446Strhodes sizeof(unsigned char *)); 281135446Strhodes if (grbn->rdatas == NULL) 282135446Strhodes goto out; 283135446Strhodes grbn->rdatalen = isc_mem_get(cm->mctx, grbn->nrdatas * 284135446Strhodes sizeof(lwres_uint16_t)); 285135446Strhodes if (grbn->rdatalen == NULL) 286135446Strhodes goto out; 287135446Strhodes 288135446Strhodes i = 0; 289135446Strhodes result = fill_array(&i, rdataset, grbn->nrdatas, grbn->rdatas, 290135446Strhodes grbn->rdatalen); 291135446Strhodes if (result != ISC_R_SUCCESS) 292135446Strhodes goto out; 293135446Strhodes INSIST(i == grbn->nrdatas); 294135446Strhodes grbn->ttl = rdataset->ttl; 295135446Strhodes if (rdataset->trust == dns_trust_secure) 296135446Strhodes grbn->flags |= LWRDATA_VALIDATED; 297135446Strhodes } else { 298135446Strhodes /* The SIG query case */ 299135446Strhodes result = iterate_node(grbn, levent->db, levent->node, 300135446Strhodes cm->mctx); 301135446Strhodes if (result != ISC_R_SUCCESS) 302135446Strhodes goto out; 303135446Strhodes } 304135446Strhodes ns_lwdclient_log(50, "filled in %d rdata%s", grbn->nrdatas, 305135446Strhodes (grbn->nrdatas == 1) ? "" : "s"); 306135446Strhodes 307135446Strhodes sigrdataset = levent->sigrdataset; 308135446Strhodes if (sigrdataset != NULL) { 309135446Strhodes grbn->nsigs = dns_rdataset_count(sigrdataset); 310135446Strhodes grbn->sigs = isc_mem_get(cm->mctx, grbn->nsigs * 311135446Strhodes sizeof(unsigned char *)); 312135446Strhodes if (grbn->sigs == NULL) 313135446Strhodes goto out; 314135446Strhodes grbn->siglen = isc_mem_get(cm->mctx, grbn->nsigs * 315135446Strhodes sizeof(lwres_uint16_t)); 316135446Strhodes if (grbn->siglen == NULL) 317135446Strhodes goto out; 318135446Strhodes 319135446Strhodes i = 0; 320135446Strhodes result = fill_array(&i, sigrdataset, grbn->nsigs, grbn->sigs, 321135446Strhodes grbn->siglen); 322135446Strhodes if (result != ISC_R_SUCCESS) 323135446Strhodes goto out; 324135446Strhodes INSIST(i == grbn->nsigs); 325135446Strhodes ns_lwdclient_log(50, "filled in %d signature%s", grbn->nsigs, 326135446Strhodes (grbn->nsigs == 1) ? "" : "s"); 327135446Strhodes } 328135446Strhodes 329135446Strhodes /* 330135446Strhodes * Render the packet. 331135446Strhodes */ 332135446Strhodes client->pkt.recvlength = LWRES_RECVLENGTH; 333135446Strhodes client->pkt.authtype = 0; /* XXXMLG */ 334135446Strhodes client->pkt.authlength = 0; 335135446Strhodes client->pkt.result = LWRES_R_SUCCESS; 336135446Strhodes 337135446Strhodes lwresult = lwres_grbnresponse_render(cm->lwctx, 338135446Strhodes grbn, &client->pkt, &lwb); 339135446Strhodes if (lwresult != LWRES_R_SUCCESS) 340135446Strhodes goto out; 341135446Strhodes 342135446Strhodes isc_mem_put(cm->mctx, grbn->rdatas, 343135446Strhodes grbn->nrdatas * sizeof(unsigned char *)); 344135446Strhodes isc_mem_put(cm->mctx, grbn->rdatalen, 345135446Strhodes grbn->nrdatas * sizeof(lwres_uint16_t)); 346135446Strhodes 347135446Strhodes if (grbn->sigs != NULL) 348135446Strhodes isc_mem_put(cm->mctx, grbn->sigs, 349135446Strhodes grbn->nsigs * sizeof(unsigned char *)); 350135446Strhodes if (grbn->siglen != NULL) 351135446Strhodes isc_mem_put(cm->mctx, grbn->siglen, 352135446Strhodes grbn->nsigs * sizeof(lwres_uint16_t)); 353135446Strhodes 354135446Strhodes r.base = lwb.base; 355135446Strhodes r.length = lwb.used; 356135446Strhodes client->sendbuf = r.base; 357135446Strhodes client->sendlength = r.length; 358135446Strhodes result = ns_lwdclient_sendreply(client, &r); 359135446Strhodes if (result != ISC_R_SUCCESS) 360165071Sdougb goto out2; 361135446Strhodes 362135446Strhodes NS_LWDCLIENT_SETSEND(client); 363135446Strhodes 364262706Serwin dns_lookup_destroy(&client->lookup); 365262706Serwin isc_event_free(&event); 366262706Serwin 367135446Strhodes return; 368135446Strhodes 369135446Strhodes out: 370135446Strhodes if (grbn->rdatas != NULL) 371135446Strhodes isc_mem_put(cm->mctx, grbn->rdatas, 372135446Strhodes grbn->nrdatas * sizeof(unsigned char *)); 373135446Strhodes if (grbn->rdatalen != NULL) 374135446Strhodes isc_mem_put(cm->mctx, grbn->rdatalen, 375135446Strhodes grbn->nrdatas * sizeof(lwres_uint16_t)); 376135446Strhodes 377135446Strhodes if (grbn->sigs != NULL) 378135446Strhodes isc_mem_put(cm->mctx, grbn->sigs, 379135446Strhodes grbn->nsigs * sizeof(unsigned char *)); 380135446Strhodes if (grbn->siglen != NULL) 381135446Strhodes isc_mem_put(cm->mctx, grbn->siglen, 382135446Strhodes grbn->nsigs * sizeof(lwres_uint16_t)); 383165071Sdougb out2: 384135446Strhodes if (client->lookup != NULL) 385135446Strhodes dns_lookup_destroy(&client->lookup); 386135446Strhodes if (lwb.base != NULL) 387135446Strhodes lwres_context_freemem(cm->lwctx, lwb.base, lwb.length); 388135446Strhodes 389262706Serwin isc_event_free(&event); 390135446Strhodes 391135446Strhodes ns_lwdclient_log(50, "error constructing getrrsetbyname response"); 392135446Strhodes ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); 393135446Strhodes} 394135446Strhodes 395135446Strhodesstatic void 396135446Strhodesstart_lookup(ns_lwdclient_t *client) { 397135446Strhodes isc_result_t result; 398135446Strhodes ns_lwdclientmgr_t *cm; 399135446Strhodes dns_fixedname_t absname; 400135446Strhodes 401135446Strhodes cm = client->clientmgr; 402135446Strhodes 403135446Strhodes INSIST(client->lookup == NULL); 404135446Strhodes 405135446Strhodes dns_fixedname_init(&absname); 406135446Strhodes result = ns_lwsearchctx_current(&client->searchctx, 407135446Strhodes dns_fixedname_name(&absname)); 408135446Strhodes /* 409135446Strhodes * This will return failure if relative name + suffix is too long. 410135446Strhodes * In this case, just go on to the next entry in the search path. 411135446Strhodes */ 412135446Strhodes if (result != ISC_R_SUCCESS) 413135446Strhodes start_lookup(client); 414135446Strhodes 415135446Strhodes result = dns_lookup_create(cm->mctx, 416135446Strhodes dns_fixedname_name(&absname), 417135446Strhodes client->rdtype, cm->view, 418135446Strhodes client->options, cm->task, lookup_done, 419135446Strhodes client, &client->lookup); 420135446Strhodes if (result != ISC_R_SUCCESS) { 421135446Strhodes ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); 422135446Strhodes return; 423135446Strhodes } 424135446Strhodes} 425135446Strhodes 426135446Strhodesstatic void 427135446Strhodesinit_grbn(ns_lwdclient_t *client) { 428135446Strhodes client->grbn.rdclass = 0; 429135446Strhodes client->grbn.rdtype = 0; 430135446Strhodes client->grbn.ttl = 0; 431135446Strhodes client->grbn.nrdatas = 0; 432135446Strhodes client->grbn.realname = NULL; 433135446Strhodes client->grbn.realnamelen = 0; 434135446Strhodes client->grbn.rdatas = 0; 435135446Strhodes client->grbn.rdatalen = 0; 436135446Strhodes client->grbn.base = NULL; 437135446Strhodes client->grbn.baselen = 0; 438135446Strhodes isc_buffer_init(&client->recv_buffer, client->buffer, LWRES_RECVLENGTH); 439135446Strhodes} 440135446Strhodes 441135446Strhodesvoid 442135446Strhodesns_lwdclient_processgrbn(ns_lwdclient_t *client, lwres_buffer_t *b) { 443135446Strhodes lwres_grbnrequest_t *req; 444135446Strhodes isc_result_t result; 445135446Strhodes ns_lwdclientmgr_t *cm; 446135446Strhodes isc_buffer_t namebuf; 447135446Strhodes 448135446Strhodes REQUIRE(NS_LWDCLIENT_ISRECVDONE(client)); 449135446Strhodes INSIST(client->byaddr == NULL); 450135446Strhodes 451135446Strhodes cm = client->clientmgr; 452135446Strhodes req = NULL; 453135446Strhodes 454135446Strhodes result = lwres_grbnrequest_parse(cm->lwctx, 455135446Strhodes b, &client->pkt, &req); 456135446Strhodes if (result != LWRES_R_SUCCESS) 457135446Strhodes goto out; 458135446Strhodes if (req->name == NULL) 459135446Strhodes goto out; 460135446Strhodes 461135446Strhodes client->options = 0; 462135446Strhodes if (req->rdclass != cm->view->rdclass) 463135446Strhodes goto out; 464135446Strhodes 465135446Strhodes if (req->rdclass == dns_rdataclass_any || 466135446Strhodes req->rdtype == dns_rdatatype_any) 467135446Strhodes goto out; 468135446Strhodes 469135446Strhodes client->rdtype = req->rdtype; 470135446Strhodes 471135446Strhodes isc_buffer_init(&namebuf, req->name, req->namelen); 472135446Strhodes isc_buffer_add(&namebuf, req->namelen); 473135446Strhodes 474135446Strhodes dns_fixedname_init(&client->query_name); 475135446Strhodes result = dns_name_fromtext(dns_fixedname_name(&client->query_name), 476224092Sdougb &namebuf, NULL, 0, NULL); 477135446Strhodes if (result != ISC_R_SUCCESS) 478135446Strhodes goto out; 479135446Strhodes ns_lwsearchctx_init(&client->searchctx, 480135446Strhodes cm->listener->manager->search, 481135446Strhodes dns_fixedname_name(&client->query_name), 482135446Strhodes cm->listener->manager->ndots); 483135446Strhodes ns_lwsearchctx_first(&client->searchctx); 484135446Strhodes 485135446Strhodes ns_lwdclient_log(50, "client %p looking for type %d", 486135446Strhodes client, client->rdtype); 487135446Strhodes 488135446Strhodes /* 489135446Strhodes * We no longer need to keep this around. 490135446Strhodes */ 491135446Strhodes lwres_grbnrequest_free(cm->lwctx, &req); 492135446Strhodes 493135446Strhodes /* 494135446Strhodes * Initialize the real name and alias arrays in the reply we're 495135446Strhodes * going to build up. 496135446Strhodes */ 497135446Strhodes init_grbn(client); 498135446Strhodes 499135446Strhodes /* 500135446Strhodes * Start the find. 501135446Strhodes */ 502135446Strhodes start_lookup(client); 503135446Strhodes 504135446Strhodes return; 505135446Strhodes 506135446Strhodes /* 507135446Strhodes * We're screwed. Return an error packet to our caller. 508135446Strhodes */ 509135446Strhodes out: 510135446Strhodes if (req != NULL) 511135446Strhodes lwres_grbnrequest_free(cm->lwctx, &req); 512135446Strhodes 513135446Strhodes ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); 514135446Strhodes} 515