adb.c revision 1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff/*
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * Copyright (C) 1999-2001 Internet Software Consortium.
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff *
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * Permission to use, copy, modify, and distribute this software for any
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * purpose with or without fee is hereby granted, provided that the above
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * copyright notice and this permission notice appear in all copies.
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff *
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff */
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff/* $Id: adb.c,v 1.195 2001/11/30 01:59:03 gson Exp $ */
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff/*
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * Implementation notes
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff * --------------------
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff *
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley * In finds, if task == NULL, no events will be generated, and no events
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * have been sent. If task != NULL but taskaction == NULL, an event has been
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * posted but not yet freed. If neither are NULL, no event was posted.
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff *
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff */
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff/*
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff * After we have cleaned all buckets, dump the database contents.
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff */
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff#if 0
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff#define DUMP_ADB_AFTER_CLEANING
058eeac2105c39e7cb31fb75ee0b473717ec3bbcMark Andrews#endif
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff#include <config.h>
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff#include <limits.h>
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff#include <isc/mutexblock.h>
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff#include <isc/netaddr.h>
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff#include <isc/random.h>
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graff#include <isc/string.h> /* Required for HP/UX (and others?) */
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff#include <isc/task.h>
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff#include <isc/timer.h>
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff#include <isc/util.h>
440be4c866f6935ac069db79a414304507a664c2Michael Graff
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff#include <dns/a6.h>
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley#include <dns/adb.h>
e45d323a2a0f4ca08d4b139546e60a5fa7bd3f0cMichael Graff#include <dns/db.h>
29f28fe573d4b3b318b3b026d567c1eb86738015Michael Graff#include <dns/events.h>
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff#include <dns/log.h>
11efdeb076d65fa9f0c5fc067dc040e7c99dfba6Michael Graff#include <dns/rdata.h>
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff#include <dns/rdataset.h>
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff#include <dns/rdatastruct.h>
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff#include <dns/resolver.h>
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff#include <dns/result.h>
11efdeb076d65fa9f0c5fc067dc040e7c99dfba6Michael Graff
11efdeb076d65fa9f0c5fc067dc040e7c99dfba6Michael Graff#define DNS_ADB_MAGIC ISC_MAGIC('D', 'a', 'd', 'b')
439c0011e642fb1d26011116144af698125262dbMichael Graff#define DNS_ADB_VALID(x) ISC_MAGIC_VALID(x, DNS_ADB_MAGIC)
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff#define DNS_ADBNAME_MAGIC ISC_MAGIC('a', 'd', 'b', 'N')
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff#define DNS_ADBNAME_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAME_MAGIC)
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff#define DNS_ADBNAMEHOOK_MAGIC ISC_MAGIC('a', 'd', 'N', 'H')
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff#define DNS_ADBNAMEHOOK_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAMEHOOK_MAGIC)
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff#define DNS_ADBZONEINFO_MAGIC ISC_MAGIC('a', 'd', 'b', 'Z')
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff#define DNS_ADBZONEINFO_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBZONEINFO_MAGIC)
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff#define DNS_ADBENTRY_MAGIC ISC_MAGIC('a', 'd', 'b', 'E')
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff#define DNS_ADBENTRY_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBENTRY_MAGIC)
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff#define DNS_ADBFETCH_MAGIC ISC_MAGIC('a', 'd', 'F', '4')
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff#define DNS_ADBFETCH_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFETCH_MAGIC)
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff#define DNS_ADBFETCH6_MAGIC ISC_MAGIC('a', 'd', 'F', '6')
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff#define DNS_ADBFETCH6_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFETCH6_MAGIC)
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley/*
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * The number of buckets needs to be a prime (for good hashing).
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff *
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * XXXRTH How many buckets do we need?
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley */
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley#define NBUCKETS 1009 /* how many buckets for names/addrs */
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley/*
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley * For type 3 negative cache entries, we will remember that the address is
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * broken for this long. XXXMLG This is also used for actual addresses, too.
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff * The intent is to keep us from constantly asking about A/A6/AAAA records
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff * if the zone has extremely low TTLs.
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff */
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff#define ADB_CACHE_MINIMUM 10 /* seconds */
d947011dc393d9f9988d1349d585b246d19cc3c7Michael Graff#define ADB_CACHE_MAXIMUM 86400 /* seconds (86400 = 24 hours) */
d947011dc393d9f9988d1349d585b246d19cc3c7Michael Graff
d947011dc393d9f9988d1349d585b246d19cc3c7Michael Graff/*
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff * Wake up every CLEAN_SECONDS and clean CLEAN_BUCKETS buckets, so that all
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley * buckets are cleaned in CLEAN_PERIOD seconds.
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff */
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley#define CLEAN_PERIOD 3600
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley#define CLEAN_SECONDS 30
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley#define CLEAN_BUCKETS ((NBUCKETS * CLEAN_SECONDS) / CLEAN_PERIOD)
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff#define FREE_ITEMS 64 /* free count for memory pools */
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff#define FILL_COUNT 16 /* fill count for memory pools */
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff#define DNS_ADB_INVALIDBUCKET (-1) /* invalid bucket address */
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff#define DNS_ADB_MINADBSIZE (1024*1024) /* 1 Megabyte */
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Grafftypedef ISC_LIST(dns_adbname_t) dns_adbnamelist_t;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Grafftypedef struct dns_adbnamehook dns_adbnamehook_t;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Grafftypedef ISC_LIST(dns_adbnamehook_t) dns_adbnamehooklist_t;
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Grafftypedef struct dns_adbzoneinfo dns_adbzoneinfo_t;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Grafftypedef ISC_LIST(dns_adbentry_t) dns_adbentrylist_t;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Grafftypedef struct dns_adbfetch dns_adbfetch_t;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Grafftypedef struct dns_adbfetch6 dns_adbfetch6_t;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graffstruct dns_adb {
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley unsigned int magic;
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff isc_mutex_t lock;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff isc_mutex_t reflock; /* Covers irefcnt, erefcnt */
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff isc_mem_t *mctx;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff dns_view_t *view;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley isc_timermgr_t *timermgr;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff isc_timer_t *timer;
439c0011e642fb1d26011116144af698125262dbMichael Graff isc_taskmgr_t *taskmgr;
11efdeb076d65fa9f0c5fc067dc040e7c99dfba6Michael Graff isc_task_t *task;
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff isc_boolean_t overmem;
11efdeb076d65fa9f0c5fc067dc040e7c99dfba6Michael Graff
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff isc_interval_t tick_interval;
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff int next_cleanbucket;
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley unsigned int irefcnt;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff unsigned int erefcnt;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff isc_mutex_t mplock;
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff isc_mempool_t *nmp; /* dns_adbname_t */
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_mempool_t *nhmp; /* dns_adbnamehook_t */
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff isc_mempool_t *zimp; /* dns_adbzoneinfo_t */
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff isc_mempool_t *emp; /* dns_adbentry_t */
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff isc_mempool_t *ahmp; /* dns_adbfind_t */
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff isc_mempool_t *aimp; /* dns_adbaddrinfo_t */
2992344aacdb08e4af936c176d49ef789f5673ddMichael Graff isc_mempool_t *afmp; /* dns_adbfetch_t */
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff isc_mempool_t *af6mp; /* dns_adbfetch6_t */
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley /*
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * Bucketized locks and lists for names.
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff *
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff * XXXRTH Have a per-bucket structure that contains all of these?
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graff */
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graff dns_adbnamelist_t names[NBUCKETS];
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley isc_mutex_t namelocks[NBUCKETS];
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley isc_boolean_t name_sd[NBUCKETS];
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graff unsigned int name_refcnt[NBUCKETS];
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff /*
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff * Bucketized locks for entries.
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff *
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graff * XXXRTH Have a per-bucket structure that contains all of these?
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graff */
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graff dns_adbentrylist_t entries[NBUCKETS];
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley isc_mutex_t entrylocks[NBUCKETS];
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley isc_boolean_t entry_sd[NBUCKETS]; /* shutting down */
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graff unsigned int entry_refcnt[NBUCKETS];
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff isc_event_t cevent;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley isc_boolean_t cevent_sent;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley isc_boolean_t shutting_down;
59c049874bbef182857c57bd9cca292898921c69Bob Halley isc_eventlist_t whenshutdown;
59c049874bbef182857c57bd9cca292898921c69Bob Halley};
59c049874bbef182857c57bd9cca292898921c69Bob Halley
59c049874bbef182857c57bd9cca292898921c69Bob Halley/*
59c049874bbef182857c57bd9cca292898921c69Bob Halley * XXXMLG Document these structures.
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff */
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halleystruct dns_adbname {
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley unsigned int magic;
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley dns_name_t name;
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley dns_adb_t *adb;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff unsigned int partial_result;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff unsigned int flags;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff int lock_bucket;
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff dns_name_t target;
1f90c108282533a23b8362c34bcde4267c1eb4b1Michael Graff isc_stdtime_t expire_target;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff isc_stdtime_t expire_v4;
ebdd11e84734e28ddd64562e82a7c646a58a04f4Michael Graff isc_stdtime_t expire_v6;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley unsigned int chains;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley dns_adbnamehooklist_t v4;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff dns_adbnamehooklist_t v6;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff dns_adbfetch_t *fetch_a;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley dns_adbfetch_t *fetch_aaaa;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff ISC_LIST(dns_adbfetch6_t) fetches_a6;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff unsigned int fetch_err;
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff unsigned int fetch6_err;
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff dns_adbfindlist_t finds;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley ISC_LINK(dns_adbname_t) plink;
28ab8277a068f273f0a805a83b4811446cb78a5bBob Halley};
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graffstruct dns_adbfetch {
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff unsigned int magic;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff dns_adbnamehook_t *namehook;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff dns_adbentry_t *entry;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff dns_fetch_t *fetch;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff dns_rdataset_t rdataset;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff};
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graffstruct dns_adbfetch6 {
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff unsigned int magic;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley unsigned int flags;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley dns_adbnamehook_t *namehook;
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff dns_adbentry_t *entry;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley dns_fetch_t *fetch;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley dns_rdataset_t rdataset;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley dns_a6context_t a6ctx;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley ISC_LINK(dns_adbfetch6_t) plink;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley};
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley/*
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * dns_adbnamehook_t
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff *
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * This is a small widget that dangles off a dns_adbname_t. It contains a
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * pointer to the address information about this host, and a link to the next
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * namehook that will contain the next address this host has.
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff */
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graffstruct dns_adbnamehook {
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff unsigned int magic;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff dns_adbentry_t *entry;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff ISC_LINK(dns_adbnamehook_t) plink;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff};
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff/*
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * dns_adbzoneinfo_t
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff *
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * This is a small widget that holds zone-specific information about an
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * address. Currently limited to lameness, but could just as easily be
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * extended to other types of information about zones.
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff */
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graffstruct dns_adbzoneinfo {
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff unsigned int magic;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff dns_name_t zone;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff isc_stdtime_t lame_timer;
439c0011e642fb1d26011116144af698125262dbMichael Graff
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff ISC_LINK(dns_adbzoneinfo_t) plink;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff};
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff/*
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * An address entry. It holds quite a bit of information about addresses,
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * including edns state (in "flags"), rtt, and of course the address of
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * the host.
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff */
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graffstruct dns_adbentry {
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff unsigned int magic;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff int lock_bucket;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff unsigned int refcnt;
439c0011e642fb1d26011116144af698125262dbMichael Graff
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff unsigned int flags;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff unsigned int srtt;
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff isc_sockaddr_t sockaddr;
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff isc_stdtime_t expires;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff /*
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * A nonzero 'expires' field indicates that the entry should
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * persist until that time. This allows entries found
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * using dns_adb_findaddrinfo() to persist for a limited time
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff * even though they are not necessarily associated with a
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * name.
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff */
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff ISC_LIST(dns_adbzoneinfo_t) zoneinfo;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff ISC_LINK(dns_adbentry_t) plink;
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff};
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graff/*
439c0011e642fb1d26011116144af698125262dbMichael Graff * Internal functions (and prototypes).
439c0011e642fb1d26011116144af698125262dbMichael Graff */
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graffstatic inline dns_adbname_t *new_adbname(dns_adb_t *, dns_name_t *);
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline void free_adbname(dns_adb_t *, dns_adbname_t **);
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline dns_adbnamehook_t *new_adbnamehook(dns_adb_t *,
439c0011e642fb1d26011116144af698125262dbMichael Graff dns_adbentry_t *);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graffstatic inline void free_adbnamehook(dns_adb_t *, dns_adbnamehook_t **);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graffstatic inline dns_adbzoneinfo_t *new_adbzoneinfo(dns_adb_t *, dns_name_t *);
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline void free_adbzoneinfo(dns_adb_t *, dns_adbzoneinfo_t **);
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline dns_adbentry_t *new_adbentry(dns_adb_t *);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffstatic inline void free_adbentry(dns_adb_t *, dns_adbentry_t **);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffstatic inline dns_adbfind_t *new_adbfind(dns_adb_t *);
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graffstatic inline void free_adbfind(dns_adb_t *, dns_adbfind_t **);
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graffstatic inline dns_adbaddrinfo_t *new_adbaddrinfo(dns_adb_t *, dns_adbentry_t *,
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley in_port_t);
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline dns_adbfetch_t *new_adbfetch(dns_adb_t *);
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline void free_adbfetch(dns_adb_t *, dns_adbfetch_t **);
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline dns_adbfetch6_t *new_adbfetch6(dns_adb_t *, dns_adbname_t *,
439c0011e642fb1d26011116144af698125262dbMichael Graff dns_a6context_t *);
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graffstatic inline void free_adbfetch6(dns_adb_t *, dns_adbfetch6_t **);
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline dns_adbname_t *find_name_and_lock(dns_adb_t *, dns_name_t *,
439c0011e642fb1d26011116144af698125262dbMichael Graff unsigned int, int *);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graffstatic inline dns_adbentry_t *find_entry_and_lock(dns_adb_t *,
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff isc_sockaddr_t *, int *);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halleystatic void dump_adb(dns_adb_t *, FILE *, isc_boolean_t debug);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graffstatic void print_dns_name(FILE *, dns_name_t *);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffstatic void print_namehook_list(FILE *, const char *legend,
439c0011e642fb1d26011116144af698125262dbMichael Graff dns_adbnamehooklist_t *list,
439c0011e642fb1d26011116144af698125262dbMichael Graff isc_boolean_t debug);
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic void print_find_list(FILE *, dns_adbname_t *);
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic void print_fetch_list(FILE *, dns_adbname_t *);
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graffstatic inline void dec_adb_irefcnt(dns_adb_t *);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffstatic inline void inc_adb_erefcnt(dns_adb_t *);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halleystatic inline void inc_entry_refcnt(dns_adb_t *, dns_adbentry_t *,
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff isc_boolean_t);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graffstatic inline void dec_entry_refcnt(dns_adb_t *, dns_adbentry_t *,
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff isc_boolean_t);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halleystatic inline void violate_locking_hierarchy(isc_mutex_t *, isc_mutex_t *);
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graffstatic void clean_namehooks(dns_adb_t *, dns_adbnamehooklist_t *);
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graffstatic void clean_target(dns_adb_t *, dns_name_t *);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halleystatic void clean_finds_at_name(dns_adbname_t *, isc_eventtype_t,
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley unsigned int);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halleystatic void check_expire_namehooks(dns_adbname_t *, isc_stdtime_t,
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley isc_boolean_t);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffstatic void cancel_fetches_at_name(dns_adbname_t *);
3ac63b472022ff92691d1fe69ac715a729671965Michael Graffstatic isc_result_t dbfind_name(dns_adbname_t *, isc_stdtime_t,
651228967966ba4fb2e52f92d1207c790af4b130Michael Graff dns_rdatatype_t);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffstatic isc_result_t fetch_name_v4(dns_adbname_t *, isc_boolean_t);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleystatic isc_result_t fetch_name_aaaa(dns_adbname_t *);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffstatic isc_result_t fetch_name_a6(dns_adbname_t *, isc_boolean_t);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffstatic inline void check_exit(dns_adb_t *);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleystatic void timer_cleanup(isc_task_t *, isc_event_t *);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleystatic void destroy(dns_adb_t *);
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graffstatic void shutdown_names(dns_adb_t *);
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graffstatic void shutdown_entries(dns_adb_t *);
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graffstatic inline void link_name(dns_adb_t *, int, dns_adbname_t *);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffstatic inline void unlink_name(dns_adb_t *, dns_adbname_t *);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graffstatic inline void link_entry(dns_adb_t *, int, dns_adbentry_t *);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graffstatic inline void unlink_entry(dns_adb_t *, dns_adbentry_t *);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graffstatic void kill_name(dns_adbname_t **, isc_eventtype_t);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graffstatic void fetch_callback_a6(isc_task_t *, isc_event_t *);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graffstatic isc_result_t dbfind_a6(dns_adbname_t *, isc_stdtime_t);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graffstatic void water(void *arg, int mark);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff/*
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff * MUST NOT overlap DNS_ADBFIND_* flags!
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff */
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff#define FIND_EVENT_SENT 0x40000000
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff#define FIND_EVENT_FREED 0x80000000
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff#define FIND_EVENTSENT(h) (((h)->flags & FIND_EVENT_SENT) != 0)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define FIND_EVENTFREED(h) (((h)->flags & FIND_EVENT_FREED) != 0)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define NAME_NEEDS_POKE 0x80000000
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define NAME_IS_DEAD 0x40000000
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define NAME_HINT_OK DNS_ADBFIND_HINTOK
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define NAME_GLUE_OK DNS_ADBFIND_GLUEOK
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define NAME_STARTATROOT DNS_ADBFIND_STARTATROOT
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff#define NAME_DEAD(n) (((n)->flags & NAME_IS_DEAD) != 0)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define NAME_NEEDSPOKE(n) (((n)->flags & NAME_NEEDS_POKE) != 0)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define NAME_GLUEOK(n) (((n)->flags & NAME_GLUE_OK) != 0)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define NAME_HINTOK(n) (((n)->flags & NAME_HINT_OK) != 0)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff/*
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff * To the name, address classes are all that really exist. If it has a
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff * V6 address it doesn't care if it came from an A6 chain or an AAAA query.
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff */
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff#define NAME_HAS_V4(n) (!ISC_LIST_EMPTY((n)->v4))
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff#define NAME_HAS_V6(n) (!ISC_LIST_EMPTY((n)->v6))
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff#define NAME_HAS_ADDRS(n) (NAME_HAS_V4(n) || NAME_HAS_V6(n))
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff/*
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff * Fetches are broken out into A, AAAA, and A6 types. In some cases,
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff * however, it makes more sense to test for a particular class of fetches,
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff * like V4 or V6 above.
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff */
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define NAME_FETCH_A(n) ((n)->fetch_a != NULL)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define NAME_FETCH_AAAA(n) ((n)->fetch_aaaa != NULL)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define NAME_FETCH_A6(n) (!ISC_LIST_EMPTY((n)->fetches_a6))
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define NAME_FETCH_V4(n) (NAME_FETCH_A(n))
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define NAME_FETCH_V6(n) (NAME_FETCH_AAAA(n) || NAME_FETCH_A6(n))
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define NAME_FETCH(n) (NAME_FETCH_V4(n) || NAME_FETCH_V6(n))
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff/*
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff * Was this fetch started using the hints database?
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff * Was this the initial fetch for the A6 record? If so, we might want to
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley * start AAAA queries if it fails.
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley */
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley#define FETCH_FIRST_A6 0x80000000
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley#define FETCH_FIRSTA6(f) (((f)->flags & FETCH_FIRST_A6) != 0)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff/*
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley * Find options and tests to see if there are addresses on the list.
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff */
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define FIND_WANTEVENT(fn) (((fn)->options & DNS_ADBFIND_WANTEVENT) != 0)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define FIND_WANTEMPTYEVENT(fn) (((fn)->options & DNS_ADBFIND_EMPTYEVENT) != 0)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define FIND_AVOIDFETCHES(fn) (((fn)->options & DNS_ADBFIND_AVOIDFETCHES) \
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff != 0)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff#define FIND_STARTATROOT(fn) (((fn)->options & DNS_ADBFIND_STARTATROOT) \
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff != 0)
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff#define FIND_HINTOK(fn) (((fn)->options & DNS_ADBFIND_HINTOK) != 0)
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff#define FIND_GLUEOK(fn) (((fn)->options & DNS_ADBFIND_GLUEOK) != 0)
78854e02c127f31ab90f56da0531542004b45377Michael Graff#define FIND_HAS_ADDRS(fn) (!ISC_LIST_EMPTY((fn)->list))
78854e02c127f31ab90f56da0531542004b45377Michael Graff#define FIND_RETURNLAME(fn) (((fn)->options & DNS_ADBFIND_RETURNLAME) != 0)
78854e02c127f31ab90f56da0531542004b45377Michael Graff
78854e02c127f31ab90f56da0531542004b45377Michael Graff/*
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff * These are currently used on simple unsigned ints, so they are
78854e02c127f31ab90f56da0531542004b45377Michael Graff * not really associated with any particular type.
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff */
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff#define WANT_INET(x) (((x) & DNS_ADBFIND_INET) != 0)
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley#define WANT_INET6(x) (((x) & DNS_ADBFIND_INET6) != 0)
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff#define EXPIRE_OK(exp, now) ((exp == INT_MAX) || (exp < now))
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff/*
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff * Find out if the flags on a name (nf) indicate if it is a hint or
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff * glue, and compare this to the appropriate bits set in o, to see if
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff * this is ok.
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff */
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff#define GLUE_OK(nf, o) (!NAME_GLUEOK(nf) || (((o) & DNS_ADBFIND_GLUEOK) != 0))
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff#define HINT_OK(nf, o) (!NAME_HINTOK(nf) || (((o) & DNS_ADBFIND_HINTOK) != 0))
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff#define GLUEHINT_OK(nf, o) (GLUE_OK(nf, o) || HINT_OK(nf, o))
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff#define STARTATROOT_MATCHES(nf, o) (((nf)->flags & NAME_STARTATROOT) == \
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff ((o) & DNS_ADBFIND_STARTATROOT))
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff#define ENTER_LEVEL 50
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff#define EXIT_LEVEL ENTER_LEVEL
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff#define CLEAN_LEVEL 100
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff#define DEF_LEVEL 5
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff#define NCACHE_LEVEL 20
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff#define NCACHE_RESULT(r) ((r) == DNS_R_NCACHENXDOMAIN || \
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff (r) == DNS_R_NCACHENXRRSET)
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff#define AUTH_NX(r) ((r) == DNS_R_NXDOMAIN || \
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff (r) == DNS_R_NXRRSET)
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff#define NXDOMAIN_RESULT(r) ((r) == DNS_R_NXDOMAIN || \
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff (r) == DNS_R_NCACHENXDOMAIN)
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff#define NXRRSET_RESULT(r) ((r) == DNS_R_NCACHENXRRSET || \
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff (r) == DNS_R_NXRRSET || \
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff (r) == DNS_R_HINTNXRRSET)
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff/*
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff * Error state rankings.
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff */
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff#define FIND_ERR_SUCCESS 0 /* highest rank */
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff#define FIND_ERR_CANCELED 1
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff#define FIND_ERR_FAILURE 2
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff#define FIND_ERR_NXDOMAIN 3
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff#define FIND_ERR_NXRRSET 4
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff#define FIND_ERR_UNEXPECTED 5
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff#define FIND_ERR_NOTFOUND 6
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff#define FIND_ERR_MAX 7
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graffstatic const char *errnames[] = {
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff "success",
f6f4ceece41f040cc43722afa9a5cd1f54a576b6Michael Graff "canceled",
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff "failure",
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff "nxdomain",
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff "nxrrset",
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff "unexpected",
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff "not_found"
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff};
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff#define NEWERR(old, new) (ISC_MIN((old), (new)))
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graffstatic isc_result_t find_err_map[FIND_ERR_MAX] = {
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff ISC_R_SUCCESS,
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff ISC_R_CANCELED,
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff ISC_R_FAILURE,
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff DNS_R_NXDOMAIN,
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff DNS_R_NXRRSET,
01883602b1e9c0a91f1c3526d80d8ef9db747e92Mark Andrews ISC_R_UNEXPECTED,
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff ISC_R_NOTFOUND /* not YET found */
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff};
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graffstatic void
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael GraffDP(int level, const char *format, ...) ISC_FORMAT_PRINTF(2, 3);
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graffstatic void
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael GraffDP(int level, const char *format, ...) {
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff va_list args;
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff va_start(args, format);
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff isc_log_vwrite(dns_lctx,
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ADB,
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff ISC_LOG_DEBUG(level), format, args);
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff va_end(args);
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff}
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff
528829aa8ad69238e674cd81078bc14d4199691bMichael Graffstatic inline dns_ttl_t
528829aa8ad69238e674cd81078bc14d4199691bMichael Graffttlclamp(dns_ttl_t ttl) {
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff if (ttl < ADB_CACHE_MINIMUM)
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff ttl = ADB_CACHE_MINIMUM;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff if (ttl > ADB_CACHE_MAXIMUM)
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff ttl = ADB_CACHE_MAXIMUM;
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff return (ttl);
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff}
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff/*
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff * Requires the adbname bucket be locked and that no entry buckets be locked.
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff *
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff * This code handles A and AAAA rdatasets only.
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff */
528829aa8ad69238e674cd81078bc14d4199691bMichael Graffstatic isc_result_t
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleyimport_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset,
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff isc_stdtime_t now)
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff{
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff isc_result_t result;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff dns_adb_t *adb;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff dns_adbnamehook_t *nh;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff dns_rdata_t rdata = DNS_RDATA_INIT;
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff struct in_addr ina;
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff struct in6_addr in6a;
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff isc_sockaddr_t sockaddr;
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff dns_adbentry_t *foundentry; /* NO CLEAN UP! */
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff int addr_bucket;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff isc_boolean_t new_addresses_added;
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff dns_rdatatype_t rdtype;
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff unsigned int findoptions;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff INSIST(DNS_ADBNAME_VALID(adbname));
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff adb = adbname->adb;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff INSIST(DNS_ADB_VALID(adb));
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff rdtype = rdataset->type;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff INSIST((rdtype == dns_rdatatype_a) || (rdtype == dns_rdatatype_aaaa));
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff if (rdtype == dns_rdatatype_a)
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff findoptions = DNS_ADBFIND_INET;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff else
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley findoptions = DNS_ADBFIND_INET6;
d947011dc393d9f9988d1349d585b246d19cc3c7Michael Graff
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff addr_bucket = DNS_ADB_INVALIDBUCKET;
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff new_addresses_added = ISC_FALSE;
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff nh = NULL;
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff result = dns_rdataset_first(rdataset);
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff while (result == ISC_R_SUCCESS) {
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff dns_rdata_reset(&rdata);
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff dns_rdataset_current(rdataset, &rdata);
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff if (rdtype == dns_rdatatype_a) {
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff INSIST(rdata.length == 4);
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff memcpy(&ina.s_addr, rdata.data, 4);
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff isc_sockaddr_fromin(&sockaddr, &ina, 0);
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff } else {
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff INSIST(rdata.length == 16);
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff memcpy(in6a.s6_addr, rdata.data, 16);
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff isc_sockaddr_fromin6(&sockaddr, &in6a, 0);
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff }
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff INSIST(nh == NULL);
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff nh = new_adbnamehook(adb, NULL);
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff if (nh == NULL) {
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff adbname->partial_result |= findoptions;
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff result = ISC_R_NOMEMORY;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff goto fail;
59c049874bbef182857c57bd9cca292898921c69Bob Halley }
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff foundentry = find_entry_and_lock(adb, &sockaddr, &addr_bucket);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff if (foundentry == NULL) {
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff dns_adbentry_t *entry;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff entry = new_adbentry(adb);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff if (entry == NULL) {
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff adbname->partial_result |= findoptions;
59c049874bbef182857c57bd9cca292898921c69Bob Halley result = ISC_R_NOMEMORY;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff goto fail;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff }
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff entry->sockaddr = sockaddr;
1ac7292ced16b8469bebf04356d50279eae78d97Bob Halley entry->refcnt = 1;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff
78854e02c127f31ab90f56da0531542004b45377Michael Graff nh->entry = entry;
288f9443ac447c9c14f3722dd6d32c1faef0f009Michael Graff
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff link_entry(adb, addr_bucket, entry);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff } else {
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff foundentry->refcnt++;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff nh->entry = foundentry;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff }
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff
59c049874bbef182857c57bd9cca292898921c69Bob Halley new_addresses_added = ISC_TRUE;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff if (rdtype == dns_rdatatype_a)
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff ISC_LIST_APPEND(adbname->v4, nh, plink);
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff else
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff ISC_LIST_APPEND(adbname->v6, nh, plink);
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff nh = NULL;
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff result = dns_rdataset_next(rdataset);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff }
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff fail:
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff if (nh != NULL)
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff free_adbnamehook(adb, &nh);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff if (addr_bucket != DNS_ADB_INVALIDBUCKET)
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff UNLOCK(&adb->entrylocks[addr_bucket]);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff rdataset->ttl = ttlclamp(rdataset->ttl);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff if (rdtype == dns_rdatatype_a) {
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley DP(NCACHE_LEVEL, "expire_v4 set to MIN(%u,%u) import_rdataset",
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff adbname->expire_v4, now + rdataset->ttl);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff adbname->expire_v4 = ISC_MIN(adbname->expire_v4,
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff now + rdataset->ttl);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff } else {
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff DP(NCACHE_LEVEL, "expire_v6 set to MIN(%u,%u) import_rdataset",
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff adbname->expire_v6, now + rdataset->ttl);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff adbname->expire_v6 = ISC_MIN(adbname->expire_v6,
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff now + rdataset->ttl);
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff }
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley if (new_addresses_added) {
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley /*
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley * Lie a little here. This is more or less so code that cares
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley * can find out if any new information was added or not.
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley */
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff return (ISC_R_SUCCESS);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff }
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff return (result);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff}
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graffstatic void
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffimport_a6(dns_a6context_t *a6ctx) {
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff dns_adbname_t *name;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff dns_adb_t *adb;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff dns_adbnamehook_t *nh;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff dns_adbentry_t *foundentry; /* NO CLEAN UP! */
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff int addr_bucket;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff isc_sockaddr_t sockaddr;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff name = a6ctx->arg;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff INSIST(DNS_ADBNAME_VALID(name));
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff adb = name->adb;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff INSIST(DNS_ADB_VALID(adb));
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff addr_bucket = DNS_ADB_INVALIDBUCKET;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff DP(ENTER_LEVEL, "ENTER: import_a6() name %p", name);
78854e02c127f31ab90f56da0531542004b45377Michael Graff
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff nh = new_adbnamehook(adb, NULL);
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff if (nh == NULL) {
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff name->partial_result |= DNS_ADBFIND_INET6; /* clear for AAAA */
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff goto fail;
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff }
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff isc_sockaddr_fromin6(&sockaddr, &a6ctx->in6addr, 0);
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff foundentry = find_entry_and_lock(adb, &sockaddr, &addr_bucket);
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff if (foundentry == NULL) {
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff dns_adbentry_t *entry;
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff entry = new_adbentry(adb);
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff if (entry == NULL) {
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff name->partial_result |= DNS_ADBFIND_INET6;
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff goto fail;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff }
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff entry->sockaddr = sockaddr;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley entry->refcnt = 1;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff nh->entry = entry;
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff link_entry(adb, addr_bucket, entry);
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff } else {
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff foundentry->refcnt++;
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff nh->entry = foundentry;
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff }
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff ISC_LIST_APPEND(name->v6, nh, plink);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff nh = NULL;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley fail:
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff DP(NCACHE_LEVEL, "expire_v6 set to MIN(%u,%u) in import_v6",
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff name->expire_v6, a6ctx->expiration);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff name->expire_v6 = ISC_MIN(name->expire_v6, a6ctx->expiration);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff name->flags |= NAME_NEEDS_POKE;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff if (nh != NULL)
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff free_adbnamehook(adb, &nh);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff if (addr_bucket != DNS_ADB_INVALIDBUCKET)
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff UNLOCK(&adb->entrylocks[addr_bucket]);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff}
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff/*
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff * Requires the name's bucket be locked.
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff */
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffstatic void
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffkill_name(dns_adbname_t **n, isc_eventtype_t ev) {
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff dns_adbname_t *name;
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff dns_adb_t *adb;
93d3a6fd20aceb9998eca4723bba8810243e7689Michael Graff
93d3a6fd20aceb9998eca4723bba8810243e7689Michael Graff INSIST(n != NULL);
f788a5704623c1d686b770a0f014fd52834d4a67Michael Graff name = *n;
93d3a6fd20aceb9998eca4723bba8810243e7689Michael Graff *n = NULL;
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff INSIST(DNS_ADBNAME_VALID(name));
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff adb = name->adb;
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff INSIST(DNS_ADB_VALID(adb));
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff DP(DEF_LEVEL, "killing name %p", name);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff /*
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff * If we're dead already, just check to see if we should go
93d3a6fd20aceb9998eca4723bba8810243e7689Michael Graff * away now or not.
93d3a6fd20aceb9998eca4723bba8810243e7689Michael Graff */
f788a5704623c1d686b770a0f014fd52834d4a67Michael Graff if (NAME_DEAD(name) && !NAME_FETCH(name)) {
93d3a6fd20aceb9998eca4723bba8810243e7689Michael Graff unlink_name(adb, name);
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff free_adbname(adb, &name);
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff return;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley }
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley /*
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley * Clean up the name's various lists. These two are destructive
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley * in that they will always empty the list.
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley */
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley clean_finds_at_name(name, ev, DNS_ADBFIND_ADDRESSMASK);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley clean_namehooks(adb, &name->v4);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff clean_namehooks(adb, &name->v6);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff clean_target(adb, &name->target);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff /*
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff * If fetches are running, cancel them. If none are running, we can
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff * just kill the name here.
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff */
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff if (!NAME_FETCH(name)) {
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff unlink_name(adb, name);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff free_adbname(adb, &name);
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff } else {
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff name->flags |= NAME_IS_DEAD;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff cancel_fetches_at_name(name);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff }
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff}
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff/*
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff * Requires the name's bucket be locked and no entry buckets be locked.
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff */
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffstatic void
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffcheck_expire_namehooks(dns_adbname_t *name, isc_stdtime_t now,
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff isc_boolean_t overmem)
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff{
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff dns_adb_t *adb;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff isc_boolean_t expire;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff INSIST(DNS_ADBNAME_VALID(name));
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff adb = name->adb;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff INSIST(DNS_ADB_VALID(adb));
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley if (overmem) {
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley isc_uint32_t val;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff isc_random_get(&val);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley expire = ISC_TF((val % 4) == 0);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley } else
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley expire = ISC_FALSE;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley /*
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * Check to see if we need to remove the v4 addresses
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley */
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if (!NAME_FETCH_V4(name) &&
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley (expire || EXPIRE_OK(name->expire_v4, now))) {
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if (NAME_HAS_V4(name)) {
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley DP(DEF_LEVEL, "expiring v4 for name %p", name);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley clean_namehooks(adb, &name->v4);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley name->partial_result &= ~DNS_ADBFIND_INET;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley }
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley name->expire_v4 = INT_MAX;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley }
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley /*
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * Check to see if we need to remove the v6 addresses
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley */
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if (!NAME_FETCH_V6(name) &&
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley (expire || EXPIRE_OK(name->expire_v6, now))) {
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if (NAME_HAS_V6(name)) {
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley DP(DEF_LEVEL, "expiring v6 for name %p", name);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley clean_namehooks(adb, &name->v6);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley name->partial_result &= ~DNS_ADBFIND_INET6;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley }
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley name->expire_v6 = INT_MAX;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley }
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff /*
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff * Check to see if we need to remove the alias target.
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff */
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff if (expire || EXPIRE_OK(name->expire_target, now)) {
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff clean_target(adb, &name->target);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff name->expire_target = INT_MAX;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff }
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff}
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff/*
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff * Requires the name's bucket be locked.
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff */
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graffstatic inline void
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Grafflink_name(dns_adb_t *adb, int bucket, dns_adbname_t *name) {
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff INSIST(name->lock_bucket == DNS_ADB_INVALIDBUCKET);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff ISC_LIST_PREPEND(adb->names[bucket], name, plink);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff name->lock_bucket = bucket;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff adb->name_refcnt[bucket]++;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff}
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff/*
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff * Requires the name's bucket be locked.
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff */
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graffstatic inline void
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halleyunlink_name(dns_adb_t *adb, dns_adbname_t *name) {
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley int bucket;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley bucket = name->lock_bucket;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley INSIST(bucket != DNS_ADB_INVALIDBUCKET);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley ISC_LIST_UNLINK(adb->names[bucket], name, plink);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley name->lock_bucket = DNS_ADB_INVALIDBUCKET;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley INSIST(adb->name_refcnt[bucket] > 0);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley adb->name_refcnt[bucket]--;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley if (adb->name_sd[bucket] && adb->name_refcnt[bucket] == 0)
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley dec_adb_irefcnt(adb);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley}
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley/*
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley * Requires the entry's bucket be locked.
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley */
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halleystatic inline void
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halleylink_entry(dns_adb_t *adb, int bucket, dns_adbentry_t *entry) {
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff ISC_LIST_PREPEND(adb->entries[bucket], entry, plink);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff entry->lock_bucket = bucket;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff adb->entry_refcnt[bucket]++;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff}
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff/*
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * Requires the entry's bucket be locked.
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley */
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleystatic inline void
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleyunlink_entry(dns_adb_t *adb, dns_adbentry_t *entry) {
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley int bucket;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley bucket = entry->lock_bucket;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley INSIST(bucket != DNS_ADB_INVALIDBUCKET);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley ISC_LIST_UNLINK(adb->entries[bucket], entry, plink);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley entry->lock_bucket = DNS_ADB_INVALIDBUCKET;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley INSIST(adb->entry_refcnt[bucket] > 0);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley adb->entry_refcnt[bucket]--;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if (adb->entry_sd[bucket] && adb->entry_refcnt[bucket] == 0)
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley dec_adb_irefcnt(adb);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley}
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halleystatic inline void
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halleyviolate_locking_hierarchy(isc_mutex_t *have, isc_mutex_t *want) {
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley if (isc_mutex_trylock(want) != ISC_R_SUCCESS) {
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley UNLOCK(have);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley LOCK(want);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley LOCK(have);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley }
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley}
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley/*
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley * The ADB _MUST_ be locked before calling. Also, exit conditions must be
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley * checked after calling this function.
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley */
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halleystatic void
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halleyshutdown_names(dns_adb_t *adb) {
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley int bucket;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley dns_adbname_t *name;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley dns_adbname_t *next_name;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley for (bucket = 0; bucket < NBUCKETS; bucket++) {
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley LOCK(&adb->namelocks[bucket]);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley adb->name_sd[bucket] = ISC_TRUE;
fbc09123cd0cac8d513165c441ef2b2ed9b3445cBob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley name = ISC_LIST_HEAD(adb->names[bucket]);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if (name == NULL) {
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley /*
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff * This bucket has no names. We must decrement the
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff * irefcnt ourselves, since it will not be
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff * automatically triggered by a name being unlinked.
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff */
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley dec_adb_irefcnt(adb);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff } else {
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff /*
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff * Run through the list. For each name, clean up finds
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff * found there, and cancel any fetches running. When
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * all the fetches are canceled, the name will destroy
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * itself.
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff */
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff while (name != NULL) {
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley next_name = ISC_LIST_NEXT(name, plink);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley kill_name(&name, DNS_EVENT_ADBSHUTDOWN);
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff name = next_name;
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff }
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff }
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff UNLOCK(&adb->namelocks[bucket]);
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff }
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff}
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff/*
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff * The ADB _MUST_ be locked before calling. Also, exit conditions must be
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff * checked after calling this function.
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff */
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffstatic void
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graffshutdown_entries(dns_adb_t *adb) {
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff int bucket;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff dns_adbentry_t *entry;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff dns_adbentry_t *next_entry;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff for (bucket = 0; bucket < NBUCKETS; bucket++) {
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff LOCK(&adb->entrylocks[bucket]);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff adb->entry_sd[bucket] = ISC_TRUE;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff entry = ISC_LIST_HEAD(adb->entries[bucket]);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff if (entry == NULL) {
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff /*
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff * This bucket has no entries. We must decrement the
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff * irefcnt ourselves, since it will not be
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff * automatically triggered by an entry being unlinked.
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff */
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff dec_adb_irefcnt(adb);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff } else {
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff /*
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff * Run through the list. Cleanup any entries not
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff * associated with names, and which are not in use.
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff */
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff while (entry != NULL) {
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff next_entry = ISC_LIST_NEXT(entry, plink);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff if (entry->refcnt == 0 &&
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff entry->expires != 0) {
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff unlink_entry(adb, entry);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff free_adbentry(adb, &entry);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff }
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff entry = next_entry;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff }
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff }
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff UNLOCK(&adb->entrylocks[bucket]);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff }
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff}
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff/*
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff * Name bucket must be locked
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff */
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graffstatic void
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halleycancel_fetches_at_name(dns_adbname_t *name) {
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley dns_adbfetch6_t *fetch6;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley if (NAME_FETCH_A(name))
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley dns_resolver_cancelfetch(name->fetch_a->fetch);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley if (NAME_FETCH_AAAA(name))
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley dns_resolver_cancelfetch(name->fetch_aaaa->fetch);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley fetch6 = ISC_LIST_HEAD(name->fetches_a6);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley while (fetch6 != NULL) {
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley dns_resolver_cancelfetch(fetch6->fetch);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley fetch6 = ISC_LIST_NEXT(fetch6, plink);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley }
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley}
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley/*
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley * Assumes the name bucket is locked.
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley */
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halleystatic void
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halleyclean_namehooks(dns_adb_t *adb, dns_adbnamehooklist_t *namehooks) {
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley dns_adbentry_t *entry;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley dns_adbnamehook_t *namehook;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley int addr_bucket;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley addr_bucket = DNS_ADB_INVALIDBUCKET;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley namehook = ISC_LIST_HEAD(*namehooks);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley while (namehook != NULL) {
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley INSIST(DNS_ADBNAMEHOOK_VALID(namehook));
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley /*
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley * Clean up the entry if needed.
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley */
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley entry = namehook->entry;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley if (entry != NULL) {
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley INSIST(DNS_ADBENTRY_VALID(entry));
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley if (addr_bucket != entry->lock_bucket) {
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley if (addr_bucket != DNS_ADB_INVALIDBUCKET)
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley UNLOCK(&adb->entrylocks[addr_bucket]);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley addr_bucket = entry->lock_bucket;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley LOCK(&adb->entrylocks[addr_bucket]);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley }
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley dec_entry_refcnt(adb, entry, ISC_FALSE);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley }
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley /*
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley * Free the namehook
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley */
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley namehook->entry = NULL;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley ISC_LIST_UNLINK(*namehooks, namehook, plink);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley free_adbnamehook(adb, &namehook);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley namehook = ISC_LIST_HEAD(*namehooks);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley }
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley if (addr_bucket != DNS_ADB_INVALIDBUCKET)
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley UNLOCK(&adb->entrylocks[addr_bucket]);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley}
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halleystatic void
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halleyclean_target(dns_adb_t *adb, dns_name_t *target) {
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley if (dns_name_countlabels(target) > 0) {
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley dns_name_free(target, adb->mctx);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley dns_name_init(target, NULL);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley }
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley}
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halleystatic isc_result_t
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halleyset_target(dns_adb_t *adb, dns_name_t *name, dns_name_t *fname,
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley dns_rdataset_t *rdataset, dns_name_t *target)
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley{
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley isc_result_t result;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley dns_namereln_t namereln;
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff unsigned int nlabels, nbits;
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff int order;
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff dns_rdata_t rdata = DNS_RDATA_INIT;
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff dns_fixedname_t fixed1, fixed2;
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff dns_name_t *prefix, *new_target;
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff REQUIRE(dns_name_countlabels(target) == 0);
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff if (rdataset->type == dns_rdatatype_cname) {
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff dns_rdata_cname_t cname;
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff /*
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff * Copy the CNAME's target into the target name.
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff */
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff result = dns_rdataset_first(rdataset);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff if (result != ISC_R_SUCCESS)
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff return (result);
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff dns_rdataset_current(rdataset, &rdata);
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff result = dns_rdata_tostruct(&rdata, &cname, NULL);
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff if (result != ISC_R_SUCCESS)
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff return (result);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff result = dns_name_dup(&cname.cname, adb->mctx, target);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff dns_rdata_freestruct(&cname);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff if (result != ISC_R_SUCCESS)
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff return (result);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff } else {
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff dns_rdata_dname_t dname;
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff INSIST(rdataset->type == dns_rdatatype_dname);
78854e02c127f31ab90f56da0531542004b45377Michael Graff namereln = dns_name_fullcompare(name, fname, &order,
78854e02c127f31ab90f56da0531542004b45377Michael Graff &nlabels, &nbits);
78854e02c127f31ab90f56da0531542004b45377Michael Graff INSIST(namereln == dns_namereln_subdomain);
78854e02c127f31ab90f56da0531542004b45377Michael Graff /*
78854e02c127f31ab90f56da0531542004b45377Michael Graff * Get the target name of the DNAME.
78854e02c127f31ab90f56da0531542004b45377Michael Graff */
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff result = dns_rdataset_first(rdataset);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff if (result != ISC_R_SUCCESS)
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff return (result);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff dns_rdataset_current(rdataset, &rdata);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff result = dns_rdata_tostruct(&rdata, &dname, NULL);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff if (result != ISC_R_SUCCESS)
78854e02c127f31ab90f56da0531542004b45377Michael Graff return (result);
78854e02c127f31ab90f56da0531542004b45377Michael Graff /*
78854e02c127f31ab90f56da0531542004b45377Michael Graff * Construct the new target name.
78854e02c127f31ab90f56da0531542004b45377Michael Graff */
78854e02c127f31ab90f56da0531542004b45377Michael Graff dns_fixedname_init(&fixed1);
875e88e734b310976b178dc26a74d86fbebc935cBob Halley prefix = dns_fixedname_name(&fixed1);
78854e02c127f31ab90f56da0531542004b45377Michael Graff dns_fixedname_init(&fixed2);
875e88e734b310976b178dc26a74d86fbebc935cBob Halley new_target = dns_fixedname_name(&fixed2);
78854e02c127f31ab90f56da0531542004b45377Michael Graff result = dns_name_split(name, nlabels, nbits, prefix, NULL);
78854e02c127f31ab90f56da0531542004b45377Michael Graff if (result != ISC_R_SUCCESS) {
78854e02c127f31ab90f56da0531542004b45377Michael Graff dns_rdata_freestruct(&dname);
78854e02c127f31ab90f56da0531542004b45377Michael Graff return (result);
78854e02c127f31ab90f56da0531542004b45377Michael Graff }
875e88e734b310976b178dc26a74d86fbebc935cBob Halley result = dns_name_concatenate(prefix, &dname.dname, new_target,
78854e02c127f31ab90f56da0531542004b45377Michael Graff NULL);
78854e02c127f31ab90f56da0531542004b45377Michael Graff dns_rdata_freestruct(&dname);
78854e02c127f31ab90f56da0531542004b45377Michael Graff if (result != ISC_R_SUCCESS)
78854e02c127f31ab90f56da0531542004b45377Michael Graff return (result);
875e88e734b310976b178dc26a74d86fbebc935cBob Halley result = dns_name_dup(new_target, adb->mctx, target);
78854e02c127f31ab90f56da0531542004b45377Michael Graff if (result != ISC_R_SUCCESS)
78854e02c127f31ab90f56da0531542004b45377Michael Graff return (result);
78854e02c127f31ab90f56da0531542004b45377Michael Graff }
78854e02c127f31ab90f56da0531542004b45377Michael Graff
78854e02c127f31ab90f56da0531542004b45377Michael Graff return (ISC_R_SUCCESS);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff}
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
78854e02c127f31ab90f56da0531542004b45377Michael Graff/*
78854e02c127f31ab90f56da0531542004b45377Michael Graff * Assumes nothing is locked, since this is called by the client.
78854e02c127f31ab90f56da0531542004b45377Michael Graff */
78854e02c127f31ab90f56da0531542004b45377Michael Graffstatic void
78854e02c127f31ab90f56da0531542004b45377Michael Graffevent_free(isc_event_t *event) {
78854e02c127f31ab90f56da0531542004b45377Michael Graff dns_adbfind_t *find;
78854e02c127f31ab90f56da0531542004b45377Michael Graff
78854e02c127f31ab90f56da0531542004b45377Michael Graff INSIST(event != NULL);
78854e02c127f31ab90f56da0531542004b45377Michael Graff find = event->ev_destroy_arg;
78854e02c127f31ab90f56da0531542004b45377Michael Graff INSIST(DNS_ADBFIND_VALID(find));
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff LOCK(&find->lock);
2a0b8796d46265c078ba7f4dea2979c62ebf5badBob Halley find->flags |= FIND_EVENT_FREED;
78854e02c127f31ab90f56da0531542004b45377Michael Graff event->ev_destroy_arg = NULL;
78854e02c127f31ab90f56da0531542004b45377Michael Graff UNLOCK(&find->lock);
78854e02c127f31ab90f56da0531542004b45377Michael Graff}
78854e02c127f31ab90f56da0531542004b45377Michael Graff
78854e02c127f31ab90f56da0531542004b45377Michael Graff/*
78854e02c127f31ab90f56da0531542004b45377Michael Graff * Assumes the name bucket is locked.
2a0b8796d46265c078ba7f4dea2979c62ebf5badBob Halley */
78854e02c127f31ab90f56da0531542004b45377Michael Graffstatic void
78854e02c127f31ab90f56da0531542004b45377Michael Graffclean_finds_at_name(dns_adbname_t *name, isc_eventtype_t evtype,
78854e02c127f31ab90f56da0531542004b45377Michael Graff unsigned int addrs)
78854e02c127f31ab90f56da0531542004b45377Michael Graff{
78854e02c127f31ab90f56da0531542004b45377Michael Graff isc_event_t *ev;
78854e02c127f31ab90f56da0531542004b45377Michael Graff isc_task_t *task;
78854e02c127f31ab90f56da0531542004b45377Michael Graff dns_adbfind_t *find;
78854e02c127f31ab90f56da0531542004b45377Michael Graff dns_adbfind_t *next_find;
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff isc_boolean_t process;
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff unsigned int wanted, notify;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff DP(ENTER_LEVEL,
78854e02c127f31ab90f56da0531542004b45377Michael Graff "ENTER clean_finds_at_name, name %p, evtype %08x, addrs %08x",
78854e02c127f31ab90f56da0531542004b45377Michael Graff name, evtype, addrs);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff find = ISC_LIST_HEAD(name->finds);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff while (find != NULL) {
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff LOCK(&find->lock);
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff next_find = ISC_LIST_NEXT(find, plink);
59c049874bbef182857c57bd9cca292898921c69Bob Halley
59c049874bbef182857c57bd9cca292898921c69Bob Halley process = ISC_FALSE;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley wanted = find->flags & DNS_ADBFIND_ADDRESSMASK;
59c049874bbef182857c57bd9cca292898921c69Bob Halley notify = wanted & addrs;
59c049874bbef182857c57bd9cca292898921c69Bob Halley
59c049874bbef182857c57bd9cca292898921c69Bob Halley switch (evtype) {
59c049874bbef182857c57bd9cca292898921c69Bob Halley case DNS_EVENT_ADBMOREADDRESSES:
59c049874bbef182857c57bd9cca292898921c69Bob Halley DP(3, "DNS_EVENT_ADBMOREADDRESSES");
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley if ((notify) != 0) {
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley find->flags &= ~addrs;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley process = ISC_TRUE;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley }
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley break;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley case DNS_EVENT_ADBNOMOREADDRESSES:
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley DP(3, "DNS_EVENT_ADBNOMOREADDRESSES");
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley find->flags &= ~addrs;
59c049874bbef182857c57bd9cca292898921c69Bob Halley wanted = find->flags & DNS_ADBFIND_ADDRESSMASK;
59c049874bbef182857c57bd9cca292898921c69Bob Halley if (wanted == 0)
59c049874bbef182857c57bd9cca292898921c69Bob Halley process = ISC_TRUE;
59c049874bbef182857c57bd9cca292898921c69Bob Halley break;
59c049874bbef182857c57bd9cca292898921c69Bob Halley default:
59c049874bbef182857c57bd9cca292898921c69Bob Halley find->flags &= ~addrs;
59c049874bbef182857c57bd9cca292898921c69Bob Halley process = ISC_TRUE;
59c049874bbef182857c57bd9cca292898921c69Bob Halley }
59c049874bbef182857c57bd9cca292898921c69Bob Halley
59c049874bbef182857c57bd9cca292898921c69Bob Halley if (process) {
59c049874bbef182857c57bd9cca292898921c69Bob Halley DP(DEF_LEVEL, "cfan: processing find %p", find);
59c049874bbef182857c57bd9cca292898921c69Bob Halley /*
59c049874bbef182857c57bd9cca292898921c69Bob Halley * Unlink the find from the name, letting the caller
59c049874bbef182857c57bd9cca292898921c69Bob Halley * call dns_adb_destroyfind() on it to clean it up
59c049874bbef182857c57bd9cca292898921c69Bob Halley * later.
59c049874bbef182857c57bd9cca292898921c69Bob Halley */
59c049874bbef182857c57bd9cca292898921c69Bob Halley ISC_LIST_UNLINK(name->finds, find, plink);
59c049874bbef182857c57bd9cca292898921c69Bob Halley find->adbname = NULL;
59c049874bbef182857c57bd9cca292898921c69Bob Halley find->name_bucket = DNS_ADB_INVALIDBUCKET;
59c049874bbef182857c57bd9cca292898921c69Bob Halley
59c049874bbef182857c57bd9cca292898921c69Bob Halley INSIST(!FIND_EVENTSENT(find));
59c049874bbef182857c57bd9cca292898921c69Bob Halley
59c049874bbef182857c57bd9cca292898921c69Bob Halley ev = &find->event;
59c049874bbef182857c57bd9cca292898921c69Bob Halley task = ev->ev_sender;
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff ev->ev_sender = find;
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff find->result_v4 = find_err_map[name->fetch_err];
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff find->result_v6 = find_err_map[name->fetch6_err];
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley ev->ev_type = evtype;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff ev->ev_destroy = event_free;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley ev->ev_destroy_arg = find;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff DP(DEF_LEVEL,
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff "sending event %p to task %p for find %p",
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff ev, task, find);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff isc_task_sendanddetach(&task, (isc_event_t **)&ev);
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff } else {
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff DP(DEF_LEVEL, "cfan: skipping find %p", find);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff }
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff UNLOCK(&find->lock);
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff find = next_find;
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff }
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff DP(ENTER_LEVEL, "EXIT clean_finds_at_name, name %p", name);
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff}
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graffstatic inline void
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graffcheck_exit(dns_adb_t *adb) {
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff isc_event_t *event;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff isc_task_t *etask;
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff isc_boolean_t zeroirefcnt, zeroerefcnt;
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff /*
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff * The caller must be holding the adb lock.
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff */
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff LOCK(&adb->reflock);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley zeroirefcnt = ISC_TF(adb->irefcnt == 0);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley zeroerefcnt = ISC_TF(adb->erefcnt == 0);
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff UNLOCK(&adb->reflock);
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff if (adb->shutting_down && zeroirefcnt &&
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff isc_mempool_getallocated(adb->ahmp) == 0) {
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff /*
439c0011e642fb1d26011116144af698125262dbMichael Graff * We're now shutdown. Send any whenshutdown events.
439c0011e642fb1d26011116144af698125262dbMichael Graff */
439c0011e642fb1d26011116144af698125262dbMichael Graff event = ISC_LIST_HEAD(adb->whenshutdown);
439c0011e642fb1d26011116144af698125262dbMichael Graff while (event != NULL) {
439c0011e642fb1d26011116144af698125262dbMichael Graff ISC_LIST_UNLINK(adb->whenshutdown, event, ev_link);
439c0011e642fb1d26011116144af698125262dbMichael Graff etask = event->ev_sender;
439c0011e642fb1d26011116144af698125262dbMichael Graff event->ev_sender = adb;
439c0011e642fb1d26011116144af698125262dbMichael Graff isc_task_sendanddetach(&etask, &event);
439c0011e642fb1d26011116144af698125262dbMichael Graff event = ISC_LIST_HEAD(adb->whenshutdown);
439c0011e642fb1d26011116144af698125262dbMichael Graff }
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graff /*
439c0011e642fb1d26011116144af698125262dbMichael Graff * If there aren't any external references either, we're
439c0011e642fb1d26011116144af698125262dbMichael Graff * done. Send the control event to initiate shutdown.
439c0011e642fb1d26011116144af698125262dbMichael Graff */
439c0011e642fb1d26011116144af698125262dbMichael Graff if (zeroerefcnt) {
439c0011e642fb1d26011116144af698125262dbMichael Graff INSIST(!adb->cevent_sent); /* Sanity check. */
439c0011e642fb1d26011116144af698125262dbMichael Graff event = &adb->cevent;
439c0011e642fb1d26011116144af698125262dbMichael Graff isc_task_send(adb->task, &event);
439c0011e642fb1d26011116144af698125262dbMichael Graff adb->cevent_sent = ISC_TRUE;
439c0011e642fb1d26011116144af698125262dbMichael Graff }
439c0011e642fb1d26011116144af698125262dbMichael Graff }
439c0011e642fb1d26011116144af698125262dbMichael Graff}
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline void
439c0011e642fb1d26011116144af698125262dbMichael Graffdec_adb_irefcnt(dns_adb_t *adb) {
439c0011e642fb1d26011116144af698125262dbMichael Graff LOCK(&adb->reflock);
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graff INSIST(adb->irefcnt > 0);
439c0011e642fb1d26011116144af698125262dbMichael Graff adb->irefcnt--;
439c0011e642fb1d26011116144af698125262dbMichael Graff
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley UNLOCK(&adb->reflock);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley}
439c0011e642fb1d26011116144af698125262dbMichael Graff
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleystatic inline void
439c0011e642fb1d26011116144af698125262dbMichael Graffinc_adb_erefcnt(dns_adb_t *adb) {
439c0011e642fb1d26011116144af698125262dbMichael Graff LOCK(&adb->reflock);
439c0011e642fb1d26011116144af698125262dbMichael Graff adb->erefcnt++;
439c0011e642fb1d26011116144af698125262dbMichael Graff UNLOCK(&adb->reflock);
439c0011e642fb1d26011116144af698125262dbMichael Graff}
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline void
439c0011e642fb1d26011116144af698125262dbMichael Graffinc_entry_refcnt(dns_adb_t *adb, dns_adbentry_t *entry, isc_boolean_t lock) {
439c0011e642fb1d26011116144af698125262dbMichael Graff int bucket;
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graff bucket = entry->lock_bucket;
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graff if (lock)
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff LOCK(&adb->entrylocks[bucket]);
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff entry->refcnt++;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (lock)
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff UNLOCK(&adb->entrylocks[bucket]);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff}
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffstatic inline void
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffdec_entry_refcnt(dns_adb_t *adb, dns_adbentry_t *entry, isc_boolean_t lock) {
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff int bucket;
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff isc_boolean_t destroy_entry;
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff bucket = entry->lock_bucket;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff if (lock)
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff LOCK(&adb->entrylocks[bucket]);
1f90c108282533a23b8362c34bcde4267c1eb4b1Michael Graff
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff INSIST(entry->refcnt > 0);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff entry->refcnt--;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley destroy_entry = ISC_FALSE;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (entry->refcnt == 0 &&
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff (adb->entry_sd[bucket] || entry->expires == 0)) {
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff destroy_entry = ISC_TRUE;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff unlink_entry(adb, entry);
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff }
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff if (lock)
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff UNLOCK(&adb->entrylocks[bucket]);
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (!destroy_entry)
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff return;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff entry->lock_bucket = DNS_ADB_INVALIDBUCKET;
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff free_adbentry(adb, &entry);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff}
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graffstatic inline dns_adbname_t *
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graffnew_adbname(dns_adb_t *adb, dns_name_t *dnsname) {
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff dns_adbname_t *name;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff name = isc_mempool_get(adb->nmp);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff if (name == NULL)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff return (NULL);
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff dns_name_init(&name->name, NULL);
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff if (dns_name_dup(dnsname, adb->mctx, &name->name) != ISC_R_SUCCESS) {
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff isc_mempool_put(adb->nmp, name);
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff return (NULL);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff }
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff dns_name_init(&name->target, NULL);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff name->magic = DNS_ADBNAME_MAGIC;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff name->adb = adb;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff name->partial_result = 0;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff name->flags = 0;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff name->expire_v4 = INT_MAX;
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff name->expire_v6 = INT_MAX;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff name->expire_target = INT_MAX;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff name->chains = 0;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff name->lock_bucket = DNS_ADB_INVALIDBUCKET;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff ISC_LIST_INIT(name->v4);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff ISC_LIST_INIT(name->v6);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff name->fetch_a = NULL;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff name->fetch_aaaa = NULL;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff ISC_LIST_INIT(name->fetches_a6);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff name->fetch_err = FIND_ERR_UNEXPECTED;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff name->fetch6_err = FIND_ERR_UNEXPECTED;
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff ISC_LIST_INIT(name->finds);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff ISC_LINK_INIT(name, plink);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff return (name);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff}
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graffstatic inline void
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Grafffree_adbname(dns_adb_t *adb, dns_adbname_t **name) {
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff dns_adbname_t *n;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff INSIST(name != NULL && DNS_ADBNAME_VALID(*name));
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff n = *name;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff *name = NULL;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff INSIST(!NAME_HAS_V4(n));
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff INSIST(!NAME_HAS_V6(n));
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff INSIST(!NAME_FETCH(n));
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff INSIST(ISC_LIST_EMPTY(n->finds));
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff INSIST(!ISC_LINK_LINKED(n, plink));
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff INSIST(n->lock_bucket == DNS_ADB_INVALIDBUCKET);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff INSIST(n->adb == adb);
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff n->magic = 0;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff dns_name_free(&n->name, adb->mctx);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_mempool_put(adb->nmp, n);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff}
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffstatic inline dns_adbnamehook_t *
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffnew_adbnamehook(dns_adb_t *adb, dns_adbentry_t *entry) {
439c0011e642fb1d26011116144af698125262dbMichael Graff dns_adbnamehook_t *nh;
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff nh = isc_mempool_get(adb->nhmp);
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff if (nh == NULL)
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff return (NULL);
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff nh->magic = DNS_ADBNAMEHOOK_MAGIC;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff nh->entry = entry;
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff ISC_LINK_INIT(nh, plink);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff return (nh);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff}
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline void
439c0011e642fb1d26011116144af698125262dbMichael Grafffree_adbnamehook(dns_adb_t *adb, dns_adbnamehook_t **namehook) {
439c0011e642fb1d26011116144af698125262dbMichael Graff dns_adbnamehook_t *nh;
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graff INSIST(namehook != NULL && DNS_ADBNAMEHOOK_VALID(*namehook));
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff nh = *namehook;
439c0011e642fb1d26011116144af698125262dbMichael Graff *namehook = NULL;
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graff INSIST(nh->entry == NULL);
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff INSIST(!ISC_LINK_LINKED(nh, plink));
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graff nh->magic = 0;
439c0011e642fb1d26011116144af698125262dbMichael Graff isc_mempool_put(adb->nhmp, nh);
439c0011e642fb1d26011116144af698125262dbMichael Graff}
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic inline dns_adbzoneinfo_t *
439c0011e642fb1d26011116144af698125262dbMichael Graffnew_adbzoneinfo(dns_adb_t *adb, dns_name_t *zone) {
439c0011e642fb1d26011116144af698125262dbMichael Graff dns_adbzoneinfo_t *zi;
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff zi = isc_mempool_get(adb->zimp);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (zi == NULL)
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff return (NULL);
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff dns_name_init(&zi->zone, NULL);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (dns_name_dup(zone, adb->mctx, &zi->zone) != ISC_R_SUCCESS) {
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_mempool_put(adb->zimp, zi);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff return (NULL);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff }
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff zi->magic = DNS_ADBZONEINFO_MAGIC;
439c0011e642fb1d26011116144af698125262dbMichael Graff zi->lame_timer = 0;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff ISC_LINK_INIT(zi, plink);
97a274369d7d132ae620845a290f14706fd2dff9Bob Halley
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff return (zi);
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff}
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleystatic inline void
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Grafffree_adbzoneinfo(dns_adb_t *adb, dns_adbzoneinfo_t **zoneinfo) {
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff dns_adbzoneinfo_t *zi;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff INSIST(zoneinfo != NULL && DNS_ADBZONEINFO_VALID(*zoneinfo));
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff zi = *zoneinfo;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff *zoneinfo = NULL;
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff INSIST(!ISC_LINK_LINKED(zi, plink));
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff dns_name_free(&zi->zone, adb->mctx);
3f6a66689410910ef601a4d26f10a24f331ef83cMichael Graff
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff zi->magic = 0;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff isc_mempool_put(adb->zimp, zi);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff}
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graffstatic inline dns_adbentry_t *
439c0011e642fb1d26011116144af698125262dbMichael Graffnew_adbentry(dns_adb_t *adb) {
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff dns_adbentry_t *e;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff isc_uint32_t r;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
3f6a66689410910ef601a4d26f10a24f331ef83cMichael Graff e = isc_mempool_get(adb->emp);
3f6a66689410910ef601a4d26f10a24f331ef83cMichael Graff if (e == NULL)
3f6a66689410910ef601a4d26f10a24f331ef83cMichael Graff return (NULL);
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff
3f6a66689410910ef601a4d26f10a24f331ef83cMichael Graff e->magic = DNS_ADBENTRY_MAGIC;
3f6a66689410910ef601a4d26f10a24f331ef83cMichael Graff e->lock_bucket = DNS_ADB_INVALIDBUCKET;
3f6a66689410910ef601a4d26f10a24f331ef83cMichael Graff e->refcnt = 0;
3f6a66689410910ef601a4d26f10a24f331ef83cMichael Graff e->flags = 0;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff isc_random_get(&r);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff e->srtt = (r & 0x1f) + 1;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff e->expires = 0;
2992344aacdb08e4af936c176d49ef789f5673ddMichael Graff ISC_LIST_INIT(e->zoneinfo);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff ISC_LINK_INIT(e, plink);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
2992344aacdb08e4af936c176d49ef789f5673ddMichael Graff return (e);
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff}
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffstatic inline void
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Grafffree_adbentry(dns_adb_t *adb, dns_adbentry_t **entry) {
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff dns_adbentry_t *e;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff dns_adbzoneinfo_t *zi;
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff INSIST(entry != NULL && DNS_ADBENTRY_VALID(*entry));
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff e = *entry;
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff *entry = NULL;
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff
1f90c108282533a23b8362c34bcde4267c1eb4b1Michael Graff INSIST(e->lock_bucket == DNS_ADB_INVALIDBUCKET);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff INSIST(e->refcnt == 0);
78854e02c127f31ab90f56da0531542004b45377Michael Graff INSIST(!ISC_LINK_LINKED(e, plink));
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff
d4d2a13916a114879763562db6a19b70b1444ec1Michael Graff e->magic = 0;
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff zi = ISC_LIST_HEAD(e->zoneinfo);
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff while (zi != NULL) {
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff ISC_LIST_UNLINK(e->zoneinfo, zi, plink);
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff free_adbzoneinfo(adb, &zi);
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff zi = ISC_LIST_HEAD(e->zoneinfo);
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff }
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff isc_mempool_put(adb->emp, e);
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff}
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graffstatic inline dns_adbfind_t *
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graffnew_adbfind(dns_adb_t *adb) {
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff dns_adbfind_t *h;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_result_t result;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff h = isc_mempool_get(adb->ahmp);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (h == NULL)
2992344aacdb08e4af936c176d49ef789f5673ddMichael Graff return (NULL);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff /*
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * Public members.
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff */
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff h->magic = 0;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff h->adb = adb;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff h->partial_result = 0;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff h->options = 0;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff h->flags = 0;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff h->result_v4 = ISC_R_UNEXPECTED;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff h->result_v6 = ISC_R_UNEXPECTED;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff ISC_LINK_INIT(h, publink);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff ISC_LINK_INIT(h, plink);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff ISC_LIST_INIT(h->list);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff h->adbname = NULL;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff h->name_bucket = DNS_ADB_INVALIDBUCKET;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff /*
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff * private members
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff */
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff result = isc_mutex_init(&h->lock);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff if (result != ISC_R_SUCCESS) {
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff UNEXPECTED_ERROR(__FILE__, __LINE__,
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff "isc_mutex_init failed in new_adbfind()");
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff isc_mempool_put(adb->ahmp, h);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff return (NULL);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff }
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff ISC_EVENT_INIT(&h->event, sizeof(isc_event_t), 0, 0, 0, NULL, NULL,
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff NULL, NULL, h);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff h->magic = DNS_ADBFIND_MAGIC;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff return (h);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff}
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graffstatic inline dns_adbfetch_t *
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graffnew_adbfetch(dns_adb_t *adb) {
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff dns_adbfetch_t *f;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff f = isc_mempool_get(adb->afmp);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff if (f == NULL)
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff return (NULL);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff f->magic = 0;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff f->namehook = NULL;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff f->entry = NULL;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff f->fetch = NULL;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff f->namehook = new_adbnamehook(adb, NULL);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff if (f->namehook == NULL)
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff goto err;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff f->entry = new_adbentry(adb);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff if (f->entry == NULL)
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff goto err;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff
5a5b79c5ab0ccdc821dd5498935e5cc7b96d2499Michael Graff dns_rdataset_init(&f->rdataset);
5a5b79c5ab0ccdc821dd5498935e5cc7b96d2499Michael Graff
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff f->magic = DNS_ADBFETCH_MAGIC;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff return (f);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley err:
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (f->namehook != NULL)
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley free_adbnamehook(adb, &f->namehook);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (f->entry != NULL)
59c049874bbef182857c57bd9cca292898921c69Bob Halley free_adbentry(adb, &f->entry);
59c049874bbef182857c57bd9cca292898921c69Bob Halley isc_mempool_put(adb->afmp, f);
59c049874bbef182857c57bd9cca292898921c69Bob Halley return (NULL);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley}
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halleystatic inline void
fe14eafefa91fada7cea0a55b09196c01477406cBob Halleyfree_adbfetch(dns_adb_t *adb, dns_adbfetch_t **fetch) {
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley dns_adbfetch_t *f;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley INSIST(fetch != NULL && DNS_ADBFETCH_VALID(*fetch));
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley f = *fetch;
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley *fetch = NULL;
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley f->magic = 0;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (f->namehook != NULL)
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley free_adbnamehook(adb, &f->namehook);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (f->entry != NULL)
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley free_adbentry(adb, &f->entry);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (dns_rdataset_isassociated(&f->rdataset))
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley dns_rdataset_disassociate(&f->rdataset);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley isc_mempool_put(adb->afmp, f);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley}
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley/*
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * Caller must be holding the name lock.
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley */
fe14eafefa91fada7cea0a55b09196c01477406cBob Halleystatic isc_result_t
fe14eafefa91fada7cea0a55b09196c01477406cBob Halleya6find(void *arg, dns_name_t *a6name, dns_rdatatype_t type, isc_stdtime_t now,
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley{
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley dns_adbname_t *name;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley dns_adb_t *adb;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley isc_result_t result;
59c049874bbef182857c57bd9cca292898921c69Bob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley name = arg;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley INSIST(DNS_ADBNAME_VALID(name));
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley adb = name->adb;
9af545a6bdb70a31893beaa420cee7557ffa4742Bob Halley INSIST(DNS_ADB_VALID(adb));
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley result = dns_view_simplefind(adb->view, a6name, type, now,
9af545a6bdb70a31893beaa420cee7557ffa4742Bob Halley DNS_DBFIND_GLUEOK, ISC_FALSE,
9af545a6bdb70a31893beaa420cee7557ffa4742Bob Halley rdataset, sigrdataset);
9af545a6bdb70a31893beaa420cee7557ffa4742Bob Halley if (result == DNS_R_GLUE)
9af545a6bdb70a31893beaa420cee7557ffa4742Bob Halley result = ISC_R_SUCCESS;
9af545a6bdb70a31893beaa420cee7557ffa4742Bob Halley return (result);
9af545a6bdb70a31893beaa420cee7557ffa4742Bob Halley}
9af545a6bdb70a31893beaa420cee7557ffa4742Bob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley/*
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * Caller must be holding the name lock.
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley */
fe14eafefa91fada7cea0a55b09196c01477406cBob Halleystatic void
fe14eafefa91fada7cea0a55b09196c01477406cBob Halleya6missing(dns_a6context_t *a6ctx, dns_name_t *a6name) {
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley dns_adbname_t *name;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley dns_adb_t *adb;
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff dns_adbfetch6_t *fetch;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley isc_result_t result;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley name = a6ctx->arg;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley INSIST(DNS_ADBNAME_VALID(name));
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley adb = name->adb;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley INSIST(DNS_ADB_VALID(adb));
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley fetch = new_adbfetch6(adb, name, a6ctx);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (fetch == NULL) {
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley name->partial_result |= DNS_ADBFIND_INET6;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley return;
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff }
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley result = dns_resolver_createfetch(adb->view->resolver, a6name,
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley dns_rdatatype_a6,
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley NULL, NULL, NULL, 0,
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley adb->task, fetch_callback_a6,
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley name, &fetch->rdataset, NULL,
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley &fetch->fetch);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (result != ISC_R_SUCCESS)
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley goto cleanup;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley name->chains = a6ctx->chains;
c8b60c24abf816a48691ed8a06281c5a4e35e482Bob Halley ISC_LIST_APPEND(name->fetches_a6, fetch, plink);
c8b60c24abf816a48691ed8a06281c5a4e35e482Bob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley cleanup:
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (result != ISC_R_SUCCESS) {
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley free_adbfetch6(adb, &fetch);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley name->partial_result |= DNS_ADBFIND_INET6;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley }
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley}
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halleystatic inline dns_adbfetch6_t *
fe14eafefa91fada7cea0a55b09196c01477406cBob Halleynew_adbfetch6(dns_adb_t *adb, dns_adbname_t *name, dns_a6context_t *a6ctx) {
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley dns_adbfetch6_t *f;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley f = isc_mempool_get(adb->af6mp);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (f == NULL)
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley return (NULL);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley f->magic = 0;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley f->namehook = NULL;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley f->entry = NULL;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley f->fetch = NULL;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley f->flags = 0;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley f->namehook = new_adbnamehook(adb, NULL);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (f->namehook == NULL)
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley goto err;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley f->entry = new_adbentry(adb);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (f->entry == NULL)
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley goto err;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley dns_rdataset_init(&f->rdataset);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley dns_a6_init(&f->a6ctx, a6find, NULL, import_a6,
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley a6missing, name);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (a6ctx != NULL)
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley dns_a6_copy(a6ctx, &f->a6ctx);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley ISC_LINK_INIT(f, plink);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley f->magic = DNS_ADBFETCH6_MAGIC;
439c0011e642fb1d26011116144af698125262dbMichael Graff
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff return (f);
439c0011e642fb1d26011116144af698125262dbMichael Graff
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff err:
439c0011e642fb1d26011116144af698125262dbMichael Graff if (f->namehook != NULL)
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff free_adbnamehook(adb, &f->namehook);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff if (f->entry != NULL)
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff free_adbentry(adb, &f->entry);
439c0011e642fb1d26011116144af698125262dbMichael Graff isc_mempool_put(adb->af6mp, f);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff return (NULL);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff}
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graffstatic inline void
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Grafffree_adbfetch6(dns_adb_t *adb, dns_adbfetch6_t **fetch) {
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff dns_adbfetch6_t *f;
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graff INSIST(fetch != NULL && DNS_ADBFETCH6_VALID(*fetch));
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff f = *fetch;
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff *fetch = NULL;
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graff f->magic = 0;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (f->namehook != NULL)
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff free_adbnamehook(adb, &f->namehook);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (f->entry != NULL)
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff free_adbentry(adb, &f->entry);
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (dns_rdataset_isassociated(&f->rdataset))
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff dns_rdataset_disassociate(&f->rdataset);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_mempool_put(adb->af6mp, f);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff}
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffstatic inline void
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Grafffree_adbfind(dns_adb_t *adb, dns_adbfind_t **findp) {
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff dns_adbfind_t *find;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff INSIST(findp != NULL && DNS_ADBFIND_VALID(*findp));
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff find = *findp;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff *findp = NULL;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff INSIST(!FIND_HAS_ADDRS(find));
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff INSIST(!ISC_LINK_LINKED(find, publink));
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff INSIST(!ISC_LINK_LINKED(find, plink));
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff INSIST(find->name_bucket == DNS_ADB_INVALIDBUCKET);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff INSIST(find->adbname == NULL);
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff find->magic = 0;
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff DESTROYLOCK(&find->lock);
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff isc_mempool_put(adb->ahmp, find);
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff}
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff/*
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff * Copy bits from the entry into the newly allocated addrinfo. The entry
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff * must be locked, and the reference count must be bumped up by one
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff * if this function returns a valid pointer.
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff */
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graffstatic inline dns_adbaddrinfo_t *
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graffnew_adbaddrinfo(dns_adb_t *adb, dns_adbentry_t *entry, in_port_t port) {
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff dns_adbaddrinfo_t *ai;
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff ai = isc_mempool_get(adb->aimp);
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff if (ai == NULL)
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff return (NULL);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff ai->magic = DNS_ADBADDRINFO_MAGIC;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff ai->sockaddr = entry->sockaddr;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff isc_sockaddr_setport(&ai->sockaddr, port);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff ai->srtt = entry->srtt;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff ai->flags = entry->flags;
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff ai->entry = entry;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff ISC_LINK_INIT(ai, publink);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff return (ai);
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff}
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graffstatic inline void
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Grafffree_adbaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **ainfo) {
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff dns_adbaddrinfo_t *ai;
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff INSIST(ainfo != NULL && DNS_ADBADDRINFO_VALID(*ainfo));
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff ai = *ainfo;
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff *ainfo = NULL;
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff INSIST(ai->entry == NULL);
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff INSIST(!ISC_LINK_LINKED(ai, publink));
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff ai->magic = 0;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff isc_mempool_put(adb->aimp, ai);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff}
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff/*
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff * Search for the name. NOTE: The bucket is kept locked on both
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * success and failure, so it must always be unlocked by the caller!
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff *
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * On the first call to this function, *bucketp must be set to
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * DNS_ADB_INVALIDBUCKET.
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff */
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffstatic inline dns_adbname_t *
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Grafffind_name_and_lock(dns_adb_t *adb, dns_name_t *name,
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff unsigned int options, int *bucketp)
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff{
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff dns_adbname_t *adbname;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff int bucket;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff bucket = dns_name_hash(name, ISC_FALSE) % NBUCKETS;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (*bucketp == DNS_ADB_INVALIDBUCKET) {
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff LOCK(&adb->namelocks[bucket]);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff *bucketp = bucket;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff } else if (*bucketp != bucket) {
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff UNLOCK(&adb->namelocks[*bucketp]);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff LOCK(&adb->namelocks[bucket]);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff *bucketp = bucket;
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff }
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff adbname = ISC_LIST_HEAD(adb->names[bucket]);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff while (adbname != NULL) {
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff if (!NAME_DEAD(adbname)) {
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff if (dns_name_equal(name, &adbname->name)
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff && GLUEHINT_OK(adbname, options)
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff && STARTATROOT_MATCHES(adbname, options))
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff return (adbname);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff }
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff adbname = ISC_LIST_NEXT(adbname, plink);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff }
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff return (NULL);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff}
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff/*
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * Search for the address. NOTE: The bucket is kept locked on both
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * success and failure, so it must always be unlocked by the caller.
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff *
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * On the first call to this function, *bucketp must be set to
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff * DNS_ADB_INVALIDBUCKET. This will cause a lock to occur. On
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff * later calls (within the same "lock path") it can be left alone, so
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff * if this function is called multiple times locking is only done if
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff * the bucket changes.
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff */
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graffstatic inline dns_adbentry_t *
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Grafffind_entry_and_lock(dns_adb_t *adb, isc_sockaddr_t *addr, int *bucketp) {
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff dns_adbentry_t *entry;
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff int bucket;
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff bucket = isc_sockaddr_hash(addr, ISC_TRUE) % NBUCKETS;
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff if (*bucketp == DNS_ADB_INVALIDBUCKET) {
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff LOCK(&adb->entrylocks[bucket]);
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff *bucketp = bucket;
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff } else if (*bucketp != bucket) {
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff UNLOCK(&adb->entrylocks[*bucketp]);
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff LOCK(&adb->entrylocks[bucket]);
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff *bucketp = bucket;
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff }
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff entry = ISC_LIST_HEAD(adb->entries[bucket]);
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff while (entry != NULL) {
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff if (isc_sockaddr_equal(addr, &entry->sockaddr))
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff return (entry);
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff entry = ISC_LIST_NEXT(entry, plink);
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff }
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff return (NULL);
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff}
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff/*
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff * Entry bucket MUST be locked!
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff */
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graffstatic isc_boolean_t
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graffentry_is_bad_for_zone(dns_adb_t *adb, dns_adbentry_t *entry, dns_name_t *zone,
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff isc_stdtime_t now)
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff{
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff dns_adbzoneinfo_t *zi, *next_zi;
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff isc_boolean_t is_bad;
439c0011e642fb1d26011116144af698125262dbMichael Graff
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff is_bad = ISC_FALSE;
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graff zi = ISC_LIST_HEAD(entry->zoneinfo);
439c0011e642fb1d26011116144af698125262dbMichael Graff if (zi == NULL)
439c0011e642fb1d26011116144af698125262dbMichael Graff return (ISC_FALSE);
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff while (zi != NULL) {
439c0011e642fb1d26011116144af698125262dbMichael Graff next_zi = ISC_LIST_NEXT(zi, plink);
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graff /*
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff * Has the entry expired?
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff */
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff if (zi->lame_timer < now) {
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff ISC_LIST_UNLINK(entry->zoneinfo, zi, plink);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff free_adbzoneinfo(adb, &zi);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff }
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff /*
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff * Order tests from least to most expensive.
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff */
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff if (zi != NULL && !is_bad) {
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff if (dns_name_equal(zone, &zi->zone))
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff is_bad = ISC_TRUE;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff }
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff zi = next_zi;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff }
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff return (is_bad);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff}
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffstatic void
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graffcopy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_name_t *zone,
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff dns_adbname_t *name, isc_stdtime_t now)
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff{
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff dns_adbnamehook_t *namehook;
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff dns_adbaddrinfo_t *addrinfo;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff dns_adbentry_t *entry;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff int bucket;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff bucket = DNS_ADB_INVALIDBUCKET;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff if (find->options & DNS_ADBFIND_INET) {
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff namehook = ISC_LIST_HEAD(name->v4);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff while (namehook != NULL) {
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff entry = namehook->entry;
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff bucket = entry->lock_bucket;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff LOCK(&adb->entrylocks[bucket]);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff if (!FIND_RETURNLAME(find)
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff && entry_is_bad_for_zone(adb, entry, zone, now)) {
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff find->options |= DNS_ADBFIND_LAMEPRUNED;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff goto nextv4;
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff }
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff addrinfo = new_adbaddrinfo(adb, entry, find->port);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff if (addrinfo == NULL) {
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff find->partial_result |= DNS_ADBFIND_INET;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff goto out;
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff }
439c0011e642fb1d26011116144af698125262dbMichael Graff /*
439c0011e642fb1d26011116144af698125262dbMichael Graff * Found a valid entry. Add it to the find's list.
439c0011e642fb1d26011116144af698125262dbMichael Graff */
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff inc_entry_refcnt(adb, entry, ISC_FALSE);
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff ISC_LIST_APPEND(find->list, addrinfo, publink);
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff addrinfo = NULL;
439c0011e642fb1d26011116144af698125262dbMichael Graff nextv4:
439c0011e642fb1d26011116144af698125262dbMichael Graff UNLOCK(&adb->entrylocks[bucket]);
08d131595373326ec4a3af793b536df8c33115ecMichael Graff bucket = DNS_ADB_INVALIDBUCKET;
08d131595373326ec4a3af793b536df8c33115ecMichael Graff namehook = ISC_LIST_NEXT(namehook, plink);
08d131595373326ec4a3af793b536df8c33115ecMichael Graff }
08d131595373326ec4a3af793b536df8c33115ecMichael Graff }
651228967966ba4fb2e52f92d1207c790af4b130Michael Graff
651228967966ba4fb2e52f92d1207c790af4b130Michael Graff if (find->options & DNS_ADBFIND_INET6) {
08d131595373326ec4a3af793b536df8c33115ecMichael Graff namehook = ISC_LIST_HEAD(name->v6);
08d131595373326ec4a3af793b536df8c33115ecMichael Graff while (namehook != NULL) {
08d131595373326ec4a3af793b536df8c33115ecMichael Graff entry = namehook->entry;
08d131595373326ec4a3af793b536df8c33115ecMichael Graff bucket = entry->lock_bucket;
08d131595373326ec4a3af793b536df8c33115ecMichael Graff LOCK(&adb->entrylocks[bucket]);
08d131595373326ec4a3af793b536df8c33115ecMichael Graff
08d131595373326ec4a3af793b536df8c33115ecMichael Graff if (entry_is_bad_for_zone(adb, entry, zone, now))
08d131595373326ec4a3af793b536df8c33115ecMichael Graff goto nextv6;
59c049874bbef182857c57bd9cca292898921c69Bob Halley addrinfo = new_adbaddrinfo(adb, entry, find->port);
08d131595373326ec4a3af793b536df8c33115ecMichael Graff if (addrinfo == NULL) {
08d131595373326ec4a3af793b536df8c33115ecMichael Graff find->partial_result |= DNS_ADBFIND_INET6;
08d131595373326ec4a3af793b536df8c33115ecMichael Graff goto out;
08d131595373326ec4a3af793b536df8c33115ecMichael Graff }
08d131595373326ec4a3af793b536df8c33115ecMichael Graff /*
59c049874bbef182857c57bd9cca292898921c69Bob Halley * Found a valid entry. Add it to the find's list.
08d131595373326ec4a3af793b536df8c33115ecMichael Graff */
08d131595373326ec4a3af793b536df8c33115ecMichael Graff inc_entry_refcnt(adb, entry, ISC_FALSE);
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff ISC_LIST_APPEND(find->list, addrinfo, publink);
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff addrinfo = NULL;
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff nextv6:
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff UNLOCK(&adb->entrylocks[bucket]);
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff bucket = DNS_ADB_INVALIDBUCKET;
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff namehook = ISC_LIST_NEXT(namehook, plink);
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff }
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff }
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff out:
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff if (bucket != DNS_ADB_INVALIDBUCKET)
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff UNLOCK(&adb->entrylocks[bucket]);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff}
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graffstatic void
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graffshutdown_task(isc_task_t *task, isc_event_t *ev) {
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff dns_adb_t *adb;
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff UNUSED(task);
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley adb = ev->ev_arg;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley INSIST(DNS_ADB_VALID(adb));
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff /*
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff * Kill the timer, and then the ADB itself. Note that this implies
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff * that this task was the one scheduled to get timer events. If
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff * this is not true (and it is unfortunate there is no way to INSIST()
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley * this) badness will occur.
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley */
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley LOCK(&adb->lock);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley isc_timer_detach(&adb->timer);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley UNLOCK(&adb->lock);
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff isc_event_free(&ev);
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff destroy(adb);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley}
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley/*
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * Name bucket must be locked; adb may be locked; no other locks held.
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley */
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleystatic void
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleycheck_expire_name(dns_adbname_t **namep, isc_stdtime_t now) {
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley dns_adbname_t *name;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley INSIST(namep != NULL && DNS_ADBNAME_VALID(*namep));
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley name = *namep;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if (NAME_HAS_V4(name) || NAME_HAS_V6(name))
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley return;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if (NAME_FETCH(name))
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley return;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if (!EXPIRE_OK(name->expire_v4, now))
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley return;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if (!EXPIRE_OK(name->expire_v6, now))
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley return;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if (!EXPIRE_OK(name->expire_target, now))
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley return;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley /*
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * The name is empty. Delete it.
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley */
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff kill_name(&name, DNS_EVENT_ADBEXPIRED);
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff *namep = NULL;
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff /*
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff * Our caller, or one of its callers, will be calling check_exit() at
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff * some point, so we don't need to do it here.
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff */
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff}
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley/*
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff * Entry bucket must be locked; adb may be locked; no other locks held.
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff */
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graffstatic void
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graffcheck_expire_entry(dns_adb_t *adb, dns_adbentry_t **entryp, isc_stdtime_t now)
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff{
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff dns_adbentry_t *entry;
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff isc_boolean_t expire;
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff INSIST(entryp != NULL && DNS_ADBENTRY_VALID(*entryp));
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff entry = *entryp;
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff if (entry->refcnt != 0)
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff return;
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff if (adb->overmem) {
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff isc_uint32_t val;
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley isc_random_get(&val);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley expire = ISC_TF((val % 4) == 0);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley } else
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley expire = ISC_FALSE;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if (entry->expires == 0 || (! expire && entry->expires > now))
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley return;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley /*
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * The entry is not in use. Delete it.
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley */
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley DP(DEF_LEVEL, "killing entry %p", entry);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley INSIST(ISC_LINK_LINKED(entry, plink));
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley unlink_entry(adb, entry);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley free_adbentry(adb, &entry);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley *entryp = NULL;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley}
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley/*
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * ADB must be locked, and no other locks held.
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff */
3ac63b472022ff92691d1fe69ac715a729671965Michael Graffstatic void
3ac63b472022ff92691d1fe69ac715a729671965Michael Graffcleanup_names(dns_adb_t *adb, int bucket, isc_stdtime_t now) {
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff dns_adbname_t *name;
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff dns_adbname_t *next_name;
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff DP(CLEAN_LEVEL, "cleaning name bucket %d", bucket);
651228967966ba4fb2e52f92d1207c790af4b130Michael Graff
651228967966ba4fb2e52f92d1207c790af4b130Michael Graff LOCK(&adb->namelocks[bucket]);
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff if (adb->name_sd[bucket]) {
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff UNLOCK(&adb->namelocks[bucket]);
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff return;
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff }
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff
58aaab3687aac838542ee4ef65a9c094a5d34ab0Michael Graff name = ISC_LIST_HEAD(adb->names[bucket]);
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff while (name != NULL) {
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff next_name = ISC_LIST_NEXT(name, plink);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley check_expire_namehooks(name, now, adb->overmem);
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff check_expire_name(&name, now);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley name = next_name;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley }
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff UNLOCK(&adb->namelocks[bucket]);
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff}
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff/*
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * ADB must be locked, and no other locks held.
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley */
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleystatic void
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graffcleanup_entries(dns_adb_t *adb, int bucket, isc_stdtime_t now) {
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff dns_adbentry_t *entry, *next_entry;
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff DP(CLEAN_LEVEL, "cleaning entry bucket %d", bucket);
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff LOCK(&adb->entrylocks[bucket]);
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff entry = ISC_LIST_HEAD(adb->entries[bucket]);
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff while (entry != NULL) {
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff next_entry = ISC_LIST_NEXT(entry, plink);
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff check_expire_entry(adb, &entry, now);
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff entry = next_entry;
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff }
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff UNLOCK(&adb->entrylocks[bucket]);
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff}
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff
3ac63b472022ff92691d1fe69ac715a729671965Michael Graffstatic void
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Grafftimer_cleanup(isc_task_t *task, isc_event_t *ev) {
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff dns_adb_t *adb;
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff isc_stdtime_t now;
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff unsigned int i;
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff isc_interval_t interval;
08d131595373326ec4a3af793b536df8c33115ecMichael Graff
08d131595373326ec4a3af793b536df8c33115ecMichael Graff UNUSED(task);
08d131595373326ec4a3af793b536df8c33115ecMichael Graff
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff adb = ev->ev_arg;
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff INSIST(DNS_ADB_VALID(adb));
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff LOCK(&adb->lock);
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff isc_stdtime_get(&now);
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff for (i = 0; i < CLEAN_BUCKETS; i++) {
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff /*
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff * Call our cleanup routines.
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff */
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff cleanup_names(adb, adb->next_cleanbucket, now);
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff cleanup_entries(adb, adb->next_cleanbucket, now);
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley /*
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff * Set the next bucket to be cleaned.
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff */
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff adb->next_cleanbucket++;
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff if (adb->next_cleanbucket >= NBUCKETS) {
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff adb->next_cleanbucket = 0;
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff#ifdef DUMP_ADB_AFTER_CLEANING
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff dump_adb(adb, stdout, ISC_TRUE);
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff#endif
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff }
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff }
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff /*
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * Reset the timer.
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * XXXDCL isc_timer_reset might return ISC_R_UNEXPECTED or
fbcf7bc351f2d42d338cb1fa29e59babd9bee94eMichael Graff * ISC_R_NOMEMORY, but it isn't clear what could be done here
11efdeb076d65fa9f0c5fc067dc040e7c99dfba6Michael Graff * if either one of those things happened.
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff */
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff interval = adb->tick_interval;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (adb->overmem)
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_interval_set(&interval, 0, 1);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff (void)isc_timer_reset(adb->timer, isc_timertype_once, NULL,
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff &interval, ISC_FALSE);
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff UNLOCK(&adb->lock);
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff isc_event_free(&ev);
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff}
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffstatic void
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffdestroy(dns_adb_t *adb) {
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff adb->magic = 0;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff /*
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * The timer is already dead, from the task's shutdown callback.
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff */
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_task_detach(&adb->task);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff isc_mempool_destroy(&adb->nmp);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_mempool_destroy(&adb->nhmp);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_mempool_destroy(&adb->zimp);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_mempool_destroy(&adb->emp);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_mempool_destroy(&adb->ahmp);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_mempool_destroy(&adb->aimp);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_mempool_destroy(&adb->afmp);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff isc_mempool_destroy(&adb->af6mp);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff DESTROYMUTEXBLOCK(adb->entrylocks, NBUCKETS);
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff DESTROYMUTEXBLOCK(adb->namelocks, NBUCKETS);
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff DESTROYLOCK(&adb->reflock);
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff DESTROYLOCK(&adb->lock);
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff DESTROYLOCK(&adb->mplock);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
59c049874bbef182857c57bd9cca292898921c69Bob Halley isc_mem_putanddetach(&adb->mctx, adb, sizeof(dns_adb_t));
59c049874bbef182857c57bd9cca292898921c69Bob Halley}
59c049874bbef182857c57bd9cca292898921c69Bob Halley
59c049874bbef182857c57bd9cca292898921c69Bob Halley
59c049874bbef182857c57bd9cca292898921c69Bob Halley/*
59c049874bbef182857c57bd9cca292898921c69Bob Halley * Public functions.
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff */
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffisc_result_t
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graffdns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff isc_taskmgr_t *taskmgr, dns_adb_t **newadb)
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff{
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff dns_adb_t *adb;
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff isc_result_t result;
651228967966ba4fb2e52f92d1207c790af4b130Michael Graff int i;
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff REQUIRE(mem != NULL);
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff REQUIRE(view != NULL);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff REQUIRE(timermgr != NULL);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley REQUIRE(taskmgr != NULL);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley REQUIRE(newadb != NULL && *newadb == NULL);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley adb = isc_mem_get(mem, sizeof(dns_adb_t));
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (adb == NULL)
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff return (ISC_R_NOMEMORY);
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff /*
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff * Initialize things here that cannot fail, and especially things
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff * that must be NULL for the error return to work properly.
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff */
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff adb->magic = 0;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff adb->erefcnt = 1;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff adb->irefcnt = 0;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff adb->nmp = NULL;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff adb->nhmp = NULL;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff adb->zimp = NULL;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley adb->emp = NULL;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff adb->ahmp = NULL;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley adb->aimp = NULL;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley adb->afmp = NULL;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley adb->af6mp = NULL;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley adb->task = NULL;
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff adb->timer = NULL;
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff adb->mctx = NULL;
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff adb->view = view;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff adb->timermgr = timermgr;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff adb->taskmgr = taskmgr;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff adb->next_cleanbucket = 0;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff ISC_EVENT_INIT(&adb->cevent, sizeof(adb->cevent), 0, NULL,
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff DNS_EVENT_ADBCONTROL, shutdown_task, adb,
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff adb, NULL, NULL);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff adb->cevent_sent = ISC_FALSE;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff adb->shutting_down = ISC_FALSE;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff adb->overmem = ISC_FALSE;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff ISC_LIST_INIT(adb->whenshutdown);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff isc_mem_attach(mem, &adb->mctx);
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff result = isc_mutex_init(&adb->lock);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (result != ISC_R_SUCCESS)
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff goto fail0b;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff result = isc_mutex_init(&adb->mplock);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff if (result != ISC_R_SUCCESS)
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff goto fail0c;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff result = isc_mutex_init(&adb->reflock);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (result != ISC_R_SUCCESS)
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff goto fail0d;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff /*
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff * Initialize the bucket locks for names and elements.
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff * May as well initialize the list heads, too.
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff */
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff result = isc_mutexblock_init(adb->namelocks, NBUCKETS);
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff if (result != ISC_R_SUCCESS)
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff goto fail1;
e485d16462b0a66b835107fae04fe9d562e77af0Bob Halley for (i = 0; i < NBUCKETS; i++) {
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff ISC_LIST_INIT(adb->names[i]);
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff adb->name_sd[i] = ISC_FALSE;
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff adb->name_refcnt[i] = 0;
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff adb->irefcnt++;
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff }
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff for (i = 0; i < NBUCKETS; i++) {
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff ISC_LIST_INIT(adb->entries[i]);
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff adb->entry_sd[i] = ISC_FALSE;
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff adb->entry_refcnt[i] = 0;
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff adb->irefcnt++;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff }
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff result = isc_mutexblock_init(adb->entrylocks, NBUCKETS);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (result != ISC_R_SUCCESS)
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff goto fail2;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff /*
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * Memory pools
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff */
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff#define MPINIT(t, p, n) do { \
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff result = isc_mempool_create(mem, sizeof(t), &(p)); \
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff if (result != ISC_R_SUCCESS) \
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff goto fail3; \
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff isc_mempool_setfreemax((p), FREE_ITEMS); \
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff isc_mempool_setfillcount((p), FILL_COUNT); \
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff isc_mempool_setname((p), n); \
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_mempool_associatelock((p), &adb->mplock); \
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff} while (0)
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff MPINIT(dns_adbname_t, adb->nmp, "adbname");
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff MPINIT(dns_adbnamehook_t, adb->nhmp, "adbnamehook");
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff MPINIT(dns_adbzoneinfo_t, adb->zimp, "adbzoneinfo");
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff MPINIT(dns_adbentry_t, adb->emp, "adbentry");
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff MPINIT(dns_adbfind_t, adb->ahmp, "adbfind");
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff MPINIT(dns_adbaddrinfo_t, adb->aimp, "adbaddrinfo");
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff MPINIT(dns_adbfetch_t, adb->afmp, "adbfetch");
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff MPINIT(dns_adbfetch6_t, adb->af6mp, "adbfetch6");
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff#undef MPINIT
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff /*
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * Allocate a timer and a task for our periodic cleanup.
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff */
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff result = isc_task_create(adb->taskmgr, 0, &adb->task);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff if (result != ISC_R_SUCCESS)
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff goto fail3;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff isc_task_setname(adb->task, "ADB", adb);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff /*
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley * XXXMLG When this is changed to be a config file option,
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley */
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_interval_set(&adb->tick_interval, CLEAN_SECONDS, 0);
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff result = isc_timer_create(adb->timermgr, isc_timertype_once,
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff NULL, &adb->tick_interval, adb->task,
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff timer_cleanup, adb, &adb->timer);
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff if (result != ISC_R_SUCCESS)
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff goto fail3;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff DP(5, "cleaning interval for adb: "
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff "%u buckets every %u seconds, %u buckets in system, %u cl.interval",
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff CLEAN_BUCKETS, CLEAN_SECONDS, NBUCKETS, CLEAN_PERIOD);
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff /*
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff * Normal return.
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff */
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff adb->magic = DNS_ADB_MAGIC;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff *newadb = adb;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff return (ISC_R_SUCCESS);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff fail3:
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (adb->task != NULL)
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_task_detach(&adb->task);
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff if (adb->timer != NULL)
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff isc_timer_detach(&adb->timer);
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff
59c049874bbef182857c57bd9cca292898921c69Bob Halley /* clean up entrylocks */
59c049874bbef182857c57bd9cca292898921c69Bob Halley DESTROYMUTEXBLOCK(adb->entrylocks, NBUCKETS);
59c049874bbef182857c57bd9cca292898921c69Bob Halley
59c049874bbef182857c57bd9cca292898921c69Bob Halley fail2: /* clean up namelocks */
59c049874bbef182857c57bd9cca292898921c69Bob Halley DESTROYMUTEXBLOCK(adb->namelocks, NBUCKETS);
59c049874bbef182857c57bd9cca292898921c69Bob Halley
59c049874bbef182857c57bd9cca292898921c69Bob Halley fail1: /* clean up only allocated memory */
59c049874bbef182857c57bd9cca292898921c69Bob Halley if (adb->nmp != NULL)
59c049874bbef182857c57bd9cca292898921c69Bob Halley isc_mempool_destroy(&adb->nmp);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley if (adb->nhmp != NULL)
59c049874bbef182857c57bd9cca292898921c69Bob Halley isc_mempool_destroy(&adb->nhmp);
59c049874bbef182857c57bd9cca292898921c69Bob Halley if (adb->zimp != NULL)
59c049874bbef182857c57bd9cca292898921c69Bob Halley isc_mempool_destroy(&adb->zimp);
59c049874bbef182857c57bd9cca292898921c69Bob Halley if (adb->emp != NULL)
59c049874bbef182857c57bd9cca292898921c69Bob Halley isc_mempool_destroy(&adb->emp);
59c049874bbef182857c57bd9cca292898921c69Bob Halley if (adb->ahmp != NULL)
59c049874bbef182857c57bd9cca292898921c69Bob Halley isc_mempool_destroy(&adb->ahmp);
59c049874bbef182857c57bd9cca292898921c69Bob Halley if (adb->aimp != NULL)
59c049874bbef182857c57bd9cca292898921c69Bob Halley isc_mempool_destroy(&adb->aimp);
59c049874bbef182857c57bd9cca292898921c69Bob Halley if (adb->afmp != NULL)
59c049874bbef182857c57bd9cca292898921c69Bob Halley isc_mempool_destroy(&adb->afmp);
59c049874bbef182857c57bd9cca292898921c69Bob Halley if (adb->af6mp != NULL)
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley isc_mempool_destroy(&adb->af6mp);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley DESTROYLOCK(&adb->reflock);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley fail0d:
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley DESTROYLOCK(&adb->mplock);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley fail0c:
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley DESTROYLOCK(&adb->lock);
59c049874bbef182857c57bd9cca292898921c69Bob Halley fail0b:
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley isc_mem_putanddetach(&adb->mctx, adb, sizeof(dns_adb_t));
59c049874bbef182857c57bd9cca292898921c69Bob Halley
59c049874bbef182857c57bd9cca292898921c69Bob Halley return (result);
59c049874bbef182857c57bd9cca292898921c69Bob Halley}
59c049874bbef182857c57bd9cca292898921c69Bob Halley
59c049874bbef182857c57bd9cca292898921c69Bob Halleyvoid
59c049874bbef182857c57bd9cca292898921c69Bob Halleydns_adb_attach(dns_adb_t *adb, dns_adb_t **adbx) {
59c049874bbef182857c57bd9cca292898921c69Bob Halley
59c049874bbef182857c57bd9cca292898921c69Bob Halley REQUIRE(DNS_ADB_VALID(adb));
59c049874bbef182857c57bd9cca292898921c69Bob Halley REQUIRE(adbx != NULL && *adbx == NULL);
59c049874bbef182857c57bd9cca292898921c69Bob Halley
59c049874bbef182857c57bd9cca292898921c69Bob Halley inc_adb_erefcnt(adb);
59c049874bbef182857c57bd9cca292898921c69Bob Halley *adbx = adb;
59c049874bbef182857c57bd9cca292898921c69Bob Halley}
59c049874bbef182857c57bd9cca292898921c69Bob Halley
59c049874bbef182857c57bd9cca292898921c69Bob Halleyvoid
59c049874bbef182857c57bd9cca292898921c69Bob Halleydns_adb_detach(dns_adb_t **adbx) {
59c049874bbef182857c57bd9cca292898921c69Bob Halley dns_adb_t *adb;
59c049874bbef182857c57bd9cca292898921c69Bob Halley isc_boolean_t zeroerefcnt;
59c049874bbef182857c57bd9cca292898921c69Bob Halley
59c049874bbef182857c57bd9cca292898921c69Bob Halley REQUIRE(adbx != NULL && DNS_ADB_VALID(*adbx));
59c049874bbef182857c57bd9cca292898921c69Bob Halley
59c049874bbef182857c57bd9cca292898921c69Bob Halley adb = *adbx;
59c049874bbef182857c57bd9cca292898921c69Bob Halley *adbx = NULL;
59c049874bbef182857c57bd9cca292898921c69Bob Halley
59c049874bbef182857c57bd9cca292898921c69Bob Halley INSIST(adb->erefcnt > 0);
59c049874bbef182857c57bd9cca292898921c69Bob Halley
59c049874bbef182857c57bd9cca292898921c69Bob Halley LOCK(&adb->reflock);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff adb->erefcnt--;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley zeroerefcnt = ISC_TF(adb->erefcnt == 0);
59c049874bbef182857c57bd9cca292898921c69Bob Halley UNLOCK(&adb->reflock);
59c049874bbef182857c57bd9cca292898921c69Bob Halley
59c049874bbef182857c57bd9cca292898921c69Bob Halley if (zeroerefcnt) {
08d131595373326ec4a3af793b536df8c33115ecMichael Graff LOCK(&adb->lock);
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff check_exit(adb);
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff INSIST(adb->shutting_down);
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff UNLOCK(&adb->lock);
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff }
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff}
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graffvoid
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graffdns_adb_whenshutdown(dns_adb_t *adb, isc_task_t *task, isc_event_t **eventp) {
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff isc_task_t *clone;
439c0011e642fb1d26011116144af698125262dbMichael Graff isc_event_t *event;
439c0011e642fb1d26011116144af698125262dbMichael Graff isc_boolean_t zeroirefcnt = ISC_FALSE;
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff /*
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff * Send '*eventp' to 'task' when 'adb' has shutdown.
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley */
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff REQUIRE(DNS_ADB_VALID(adb));
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff REQUIRE(eventp != NULL);
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff event = *eventp;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff *eventp = NULL;
439c0011e642fb1d26011116144af698125262dbMichael Graff
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff LOCK(&adb->lock);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley LOCK(&adb->reflock);
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff zeroirefcnt = ISC_TF(adb->irefcnt == 0);
3edb3c8e7da482d00acb35341f44bff6844c3193Michael Graff UNLOCK(&adb->reflock);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff if (adb->shutting_down && zeroirefcnt &&
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff isc_mempool_getallocated(adb->ahmp) == 0) {
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley /*
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff * We're already shutdown. Send the event.
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff */
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley event->ev_sender = adb;
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley isc_task_send(task, &event);
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff } else {
58aaab3687aac838542ee4ef65a9c094a5d34ab0Michael Graff clone = NULL;
58aaab3687aac838542ee4ef65a9c094a5d34ab0Michael Graff isc_task_attach(task, &clone);
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff event->ev_sender = clone;
50b5857f1ad137624a18ce67b26b9941e316b007Michael Graff ISC_LIST_APPEND(adb->whenshutdown, event, ev_link);
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley }
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley
439c0011e642fb1d26011116144af698125262dbMichael Graff UNLOCK(&adb->lock);
50b5857f1ad137624a18ce67b26b9941e316b007Michael Graff}
50b5857f1ad137624a18ce67b26b9941e316b007Michael Graff
50b5857f1ad137624a18ce67b26b9941e316b007Michael Graffvoid
439c0011e642fb1d26011116144af698125262dbMichael Graffdns_adb_shutdown(dns_adb_t *adb) {
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graff /*
50b5857f1ad137624a18ce67b26b9941e316b007Michael Graff * Shutdown 'adb'.
50b5857f1ad137624a18ce67b26b9941e316b007Michael Graff */
50b5857f1ad137624a18ce67b26b9941e316b007Michael Graff
50b5857f1ad137624a18ce67b26b9941e316b007Michael Graff LOCK(&adb->lock);
50b5857f1ad137624a18ce67b26b9941e316b007Michael Graff
50b5857f1ad137624a18ce67b26b9941e316b007Michael Graff if (!adb->shutting_down) {
50b5857f1ad137624a18ce67b26b9941e316b007Michael Graff adb->shutting_down = ISC_TRUE;
50b5857f1ad137624a18ce67b26b9941e316b007Michael Graff isc_mem_setwater(adb->mctx, water, adb, 0, 0);
50b5857f1ad137624a18ce67b26b9941e316b007Michael Graff shutdown_names(adb);
50b5857f1ad137624a18ce67b26b9941e316b007Michael Graff shutdown_entries(adb);
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley check_exit(adb);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff }
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff UNLOCK(&adb->lock);
439c0011e642fb1d26011116144af698125262dbMichael Graff}
439c0011e642fb1d26011116144af698125262dbMichael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffisc_result_t
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffdns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff void *arg, dns_name_t *name, dns_name_t *zone,
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff unsigned int options, isc_stdtime_t now, dns_name_t *target,
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff in_port_t port, dns_adbfind_t **findp)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff{
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff dns_adbfind_t *find;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff dns_adbname_t *adbname;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff int bucket;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff isc_boolean_t want_event, start_at_root, alias, have_address;
439c0011e642fb1d26011116144af698125262dbMichael Graff isc_result_t result;
439c0011e642fb1d26011116144af698125262dbMichael Graff unsigned int wanted_addresses;
439c0011e642fb1d26011116144af698125262dbMichael Graff unsigned int wanted_fetches;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff unsigned int query_pending;
78854e02c127f31ab90f56da0531542004b45377Michael Graff
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff REQUIRE(DNS_ADB_VALID(adb));
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff if (task != NULL) {
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff REQUIRE(action != NULL);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff }
fc4fe6e5e61dbc916707ab2e071ffd22aef9de7fMichael Graff REQUIRE(name != NULL);
fc4fe6e5e61dbc916707ab2e071ffd22aef9de7fMichael Graff REQUIRE(zone != NULL);
fc4fe6e5e61dbc916707ab2e071ffd22aef9de7fMichael Graff REQUIRE(findp != NULL && *findp == NULL);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff REQUIRE(target == NULL || dns_name_hasbuffer(target));
fc4fe6e5e61dbc916707ab2e071ffd22aef9de7fMichael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff REQUIRE((options & DNS_ADBFIND_ADDRESSMASK) != 0);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff result = ISC_R_UNEXPECTED;
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff wanted_addresses = (options & DNS_ADBFIND_ADDRESSMASK);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff wanted_fetches = 0;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff query_pending = 0;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff want_event = ISC_FALSE;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff start_at_root = ISC_FALSE;
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff alias = ISC_FALSE;
f3d059d1155aa016f75a4047a2a15b4b2c5b7e01Michael Graff
f3d059d1155aa016f75a4047a2a15b4b2c5b7e01Michael Graff if (now == 0)
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff isc_stdtime_get(&now);
f3d059d1155aa016f75a4047a2a15b4b2c5b7e01Michael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff /*
f3d059d1155aa016f75a4047a2a15b4b2c5b7e01Michael Graff * XXXMLG Move this comment somewhere else!
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff *
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff * Look up the name in our internal database.
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley *
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * Possibilities: Note that these are not always exclusive.
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley *
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * No name found. In this case, allocate a new name header and
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * an initial namehook or two. If any of these allocations
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * fail, clean up and return ISC_R_NOMEMORY.
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley *
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * Name found, valid addresses present. Allocate one addrinfo
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * structure for each found and append it to the linked list
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * of addresses for this header.
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley *
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * Name found, queries pending. In this case, if a task was
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * passed in, allocate a job id, attach it to the name's job
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * list and remember to tell the caller that there will be
f3d059d1155aa016f75a4047a2a15b4b2c5b7e01Michael Graff * more info coming later.
f3d059d1155aa016f75a4047a2a15b4b2c5b7e01Michael Graff */
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
f3d059d1155aa016f75a4047a2a15b4b2c5b7e01Michael Graff find = new_adbfind(adb);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff if (find == NULL)
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff return (ISC_R_NOMEMORY);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff find->port = port;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
78854e02c127f31ab90f56da0531542004b45377Michael Graff /*
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff * Remember what types of addresses we are interested in.
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff */
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff find->options = options;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff find->flags |= wanted_addresses;
f3d059d1155aa016f75a4047a2a15b4b2c5b7e01Michael Graff if (FIND_WANTEVENT(find)) {
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley REQUIRE(task != NULL);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley }
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley /*
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * Try to see if we know anything about this name at all.
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley */
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley bucket = DNS_ADB_INVALIDBUCKET;
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley adbname = find_name_and_lock(adb, name, find->options, &bucket);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley if (adb->name_sd[bucket]) {
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley DP(DEF_LEVEL,
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley "dns_adb_createfind: returning ISC_R_SHUTTINGDOWN");
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff free_adbfind(adb, &find);
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff result = ISC_R_SHUTTINGDOWN;
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff goto out;
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff }
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff /*
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff * Nothing found. Allocate a new adbname structure for this name.
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley */
ea6228c9ce45dafa26e4cd79d71629c8ba5cd7c7Michael Graff if (adbname == NULL) {
ea6228c9ce45dafa26e4cd79d71629c8ba5cd7c7Michael Graff adbname = new_adbname(adb, name);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff if (adbname == NULL) {
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff free_adbfind(adb, &find);
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff result = ISC_R_NOMEMORY;
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff goto out;
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff }
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff link_name(adb, bucket, adbname);
78854e02c127f31ab90f56da0531542004b45377Michael Graff if (FIND_HINTOK(find))
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff adbname->flags |= NAME_HINT_OK;
3edb3c8e7da482d00acb35341f44bff6844c3193Michael Graff if (FIND_GLUEOK(find))
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley adbname->flags |= NAME_GLUE_OK;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff if (FIND_STARTATROOT(find))
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff adbname->flags |= NAME_STARTATROOT;
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley }
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley /*
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * Expire old entries, etc.
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley */
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley check_expire_namehooks(adbname, now, adb->overmem);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley /*
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * Do we know that the name is an alias?
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley */
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley if (!EXPIRE_OK(adbname->expire_target, now)) {
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff /*
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff * Yes, it is.
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff */
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff DP(DEF_LEVEL,
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley "dns_adb_createfind: name %p is an alias (cached)",
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley adbname);
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley alias = ISC_TRUE;
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley goto post_copy;
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley }
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley /*
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley * Try to populate the name from the database and/or
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley * start fetches. First try looking for an A record
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff * in the database.
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley */
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley if (!NAME_HAS_V4(adbname) && !NAME_FETCH_V4(adbname)
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley && EXPIRE_OK(adbname->expire_v4, now)
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley && WANT_INET(wanted_addresses)) {
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff result = dbfind_name(adbname, now, dns_rdatatype_a);
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley if (result == ISC_R_SUCCESS) {
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley DP(DEF_LEVEL,
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley "dns_adb_createfind: found A for name %p in db",
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley adbname);
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley goto v6;
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley }
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley /*
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley * Did we get a CNAME or DNAME?
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley */
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley if (result == DNS_R_ALIAS) {
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley DP(DEF_LEVEL,
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley "dns_adb_createfind: name %p is an alias",
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley adbname);
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley alias = ISC_TRUE;
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley goto post_copy;
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley }
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley /*
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley * If the name doesn't exist at all, don't bother with
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley * v6 queries; they won't work.
78854e02c127f31ab90f56da0531542004b45377Michael Graff *
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff * If the name does exist but we didn't get our data, go
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff * ahead and try a6.
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff *
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff * If the result is neither of these, try a fetch for A.
439c0011e642fb1d26011116144af698125262dbMichael Graff */
439c0011e642fb1d26011116144af698125262dbMichael Graff if (NXDOMAIN_RESULT(result))
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff goto fetch;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff else if (NXRRSET_RESULT(result))
439c0011e642fb1d26011116144af698125262dbMichael Graff goto v6;
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff
dec90b6caef758fe2890ee50db148cff6acffb90Michael Graff wanted_fetches |= DNS_ADBFIND_INET;
5a675fa40aa755b21ab2906e90b1b80e2105291fMichael Graff }
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff v6:
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff if (!NAME_HAS_V6(adbname) && !NAME_FETCH_V6(adbname)
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff && EXPIRE_OK(adbname->expire_v6, now)
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff && WANT_INET6(wanted_addresses)) {
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff result = dbfind_a6(adbname, now);
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff if (result == ISC_R_SUCCESS) {
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff DP(DEF_LEVEL,
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff "dns_adb_createfind: found A6 for name %p",
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff adbname);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff goto fetch;
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff }
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff /*
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff * Did we get a CNAME or DNAME?
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff */
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley if (result == DNS_R_ALIAS) {
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley DP(DEF_LEVEL,
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff "dns_adb_createfind: name %p is an alias",
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff adbname);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff alias = ISC_TRUE;
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff goto post_copy;
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff }
78854e02c127f31ab90f56da0531542004b45377Michael Graff
78854e02c127f31ab90f56da0531542004b45377Michael Graff /*
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff * If the name doesn't exist at all, jump to the fetch
b5492be2c7c3792a1b6c03995fe378703fc814cbMichael Graff * code. Otherwise, we'll try AAAA.
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff */
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff if (NXDOMAIN_RESULT(result))
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff goto fetch;
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff result = dbfind_name(adbname, now, dns_rdatatype_aaaa);
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff if (result == ISC_R_SUCCESS) {
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff DP(DEF_LEVEL,
5a675fa40aa755b21ab2906e90b1b80e2105291fMichael Graff "dns_adb_createfind: found AAAA for name %p",
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff adbname);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff goto fetch;
78854e02c127f31ab90f56da0531542004b45377Michael Graff }
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graff /*
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff * Did we get a CNAME or DNAME? This should have hit
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * during the A6 query, but we'll reproduce it here Just
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * In Case.
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley */
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley if (result == DNS_R_ALIAS) {
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley DP(DEF_LEVEL,
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley "dns_adb_createfind: name %p is an alias",
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley adbname);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley alias = ISC_TRUE;
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley goto post_copy;
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley }
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff /*
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff * Listen to negative cache hints, and don't start
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff * another query.
439c0011e642fb1d26011116144af698125262dbMichael Graff */
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff if (NCACHE_RESULT(result) || AUTH_NX(result))
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff goto fetch;
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff
78854e02c127f31ab90f56da0531542004b45377Michael Graff wanted_fetches |= DNS_ADBFIND_INET6;
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff }
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff fetch:
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff if ((WANT_INET(wanted_addresses) && NAME_HAS_V4(adbname)) ||
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff (WANT_INET6(wanted_addresses) && NAME_HAS_V6(adbname)))
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff have_address = ISC_TRUE;
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff else
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff have_address = ISC_FALSE;
67052fc64487f080489bb5a6d52c3028dc21046eBob Halley if (wanted_fetches != 0 &&
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff ! (FIND_AVOIDFETCHES(find) && have_address)) {
439c0011e642fb1d26011116144af698125262dbMichael Graff /*
439c0011e642fb1d26011116144af698125262dbMichael Graff * We're missing at least one address family. Either the
439c0011e642fb1d26011116144af698125262dbMichael Graff * caller hasn't instructed us to avoid fetches, or we don't
439c0011e642fb1d26011116144af698125262dbMichael Graff * know anything about any of the address families that would
3c5148c4d98af51d6dcb449c6dbd45fe8c645f61Michael Graff * be acceptable so we have to launch fetches.
3c5148c4d98af51d6dcb449c6dbd45fe8c645f61Michael Graff */
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff if (FIND_STARTATROOT(find))
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff start_at_root = ISC_TRUE;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff /*
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley * Start V4.
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff */
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff if (WANT_INET(wanted_fetches) &&
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff fetch_name_v4(adbname, start_at_root) == ISC_R_SUCCESS) {
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff DP(DEF_LEVEL,
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff "dns_adb_createfind: started A fetch for name %p",
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff adbname);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff }
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff /*
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff * Start V6.
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff */
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff if (WANT_INET6(wanted_fetches) &&
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff fetch_name_a6(adbname, start_at_root) == ISC_R_SUCCESS) {
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff DP(DEF_LEVEL,
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff "dns_adb_createfind: started A6 fetch for name %p",
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff adbname);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff }
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff }
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley /*
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley * Run through the name and copy out the bits we are
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley * interested in.
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley */
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley copy_namehook_lists(adb, find, zone, adbname, now);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff post_copy:
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff if (NAME_FETCH_V4(adbname))
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff query_pending |= DNS_ADBFIND_INET;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff if (NAME_FETCH_V6(adbname))
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley query_pending |= DNS_ADBFIND_INET6;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley /*
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley * Attach to the name's query list if there are queries
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley * already running, and we have been asked to.
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff */
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff want_event = ISC_TRUE;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff if (!FIND_WANTEVENT(find))
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff want_event = ISC_FALSE;
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff if (FIND_WANTEMPTYEVENT(find) && FIND_HAS_ADDRS(find))
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff want_event = ISC_FALSE;
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley if ((wanted_addresses & query_pending) == 0)
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley want_event = ISC_FALSE;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (alias)
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff want_event = ISC_FALSE;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff if (want_event) {
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff find->adbname = adbname;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff find->name_bucket = bucket;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff ISC_LIST_APPEND(adbname->finds, find, plink);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff find->query_pending = (query_pending & wanted_addresses);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff find->flags &= ~DNS_ADBFIND_ADDRESSMASK;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff find->flags |= (find->query_pending & DNS_ADBFIND_ADDRESSMASK);
fc4fe6e5e61dbc916707ab2e071ffd22aef9de7fMichael Graff DP(DEF_LEVEL, "createfind: attaching find %p to adbname %p",
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff find, adbname);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff } else {
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff /*
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * Remove the flag so the caller knows there will never
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * be an event, and set internal flags to fake that
58aaab3687aac838542ee4ef65a9c094a5d34ab0Michael Graff * the event was sent and freed, so dns_adb_destroyfind() will
58aaab3687aac838542ee4ef65a9c094a5d34ab0Michael Graff * do the right thing.
fc4fe6e5e61dbc916707ab2e071ffd22aef9de7fMichael Graff */
fc4fe6e5e61dbc916707ab2e071ffd22aef9de7fMichael Graff find->query_pending = (query_pending & wanted_addresses);
fc4fe6e5e61dbc916707ab2e071ffd22aef9de7fMichael Graff find->options &= ~DNS_ADBFIND_WANTEVENT;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff find->flags |= (FIND_EVENT_SENT | FIND_EVENT_FREED);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff find->flags &= ~DNS_ADBFIND_ADDRESSMASK;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff }
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff find->partial_result |= (adbname->partial_result & wanted_addresses);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (alias) {
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (target != NULL) {
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff result = dns_name_copy(&adbname->target, target, NULL);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (result != ISC_R_SUCCESS)
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff goto out;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff }
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff result = DNS_R_ALIAS;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff } else
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff result = ISC_R_SUCCESS;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff /*
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * Copy out error flags from the name structure into the find.
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff */
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff find->result_v4 = find_err_map[adbname->fetch_err];
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff find->result_v6 = find_err_map[adbname->fetch6_err];
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff out:
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (find != NULL) {
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff *findp = find;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (want_event) {
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_task_t *taskp;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff INSIST((find->flags & DNS_ADBFIND_ADDRESSMASK) != 0);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff taskp = NULL;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_task_attach(task, &taskp);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff find->event.ev_sender = taskp;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff find->event.ev_action = action;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff find->event.ev_arg = arg;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff }
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff }
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (bucket != DNS_ADB_INVALIDBUCKET)
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff UNLOCK(&adb->namelocks[bucket]);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff return (result);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff}
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffvoid
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffdns_adb_destroyfind(dns_adbfind_t **findp) {
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff dns_adbfind_t *find;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff dns_adbentry_t *entry;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff dns_adbaddrinfo_t *ai;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff int bucket;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff dns_adb_t *adb;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff REQUIRE(findp != NULL && DNS_ADBFIND_VALID(*findp));
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff find = *findp;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff *findp = NULL;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff LOCK(&find->lock);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff DP(DEF_LEVEL, "dns_adb_destroyfind on find %p", find);
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff adb = find->adb;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff REQUIRE(DNS_ADB_VALID(adb));
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff REQUIRE(FIND_EVENTFREED(find));
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff bucket = find->name_bucket;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff INSIST(bucket == DNS_ADB_INVALIDBUCKET);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff UNLOCK(&find->lock);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff /*
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff * The find doesn't exist on any list, and nothing is locked.
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * Return the find to the memory pool, and decrement the adb's
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff * reference count.
439c0011e642fb1d26011116144af698125262dbMichael Graff */
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff ai = ISC_LIST_HEAD(find->list);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff while (ai != NULL) {
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff ISC_LIST_UNLINK(find->list, ai, publink);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff entry = ai->entry;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff ai->entry = NULL;
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff INSIST(DNS_ADBENTRY_VALID(entry));
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff dec_entry_refcnt(adb, entry, ISC_TRUE);
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff free_adbaddrinfo(adb, &ai);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley ai = ISC_LIST_HEAD(find->list);
fc4fe6e5e61dbc916707ab2e071ffd22aef9de7fMichael Graff }
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff
fc4fe6e5e61dbc916707ab2e071ffd22aef9de7fMichael Graff /*
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * WARNING: The find is freed with the adb locked. This is done
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff * to avoid a race condition where we free the find, some other
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * thread tests to see if it should be destroyed, detects it should
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff * be, destroys it, and then we try to lock it for our check, but the
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * lock is destroyed.
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff */
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff LOCK(&adb->lock);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff free_adbfind(adb, &find);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff check_exit(adb);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff UNLOCK(&adb->lock);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff}
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffvoid
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffdns_adb_cancelfind(dns_adbfind_t *find) {
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff isc_event_t *ev;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_task_t *task;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff dns_adb_t *adb;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff int bucket;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff int unlock_bucket;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff LOCK(&find->lock);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff DP(DEF_LEVEL, "dns_adb_cancelfind on find %p", find);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff adb = find->adb;
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff REQUIRE(DNS_ADB_VALID(adb));
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff REQUIRE(!FIND_EVENTFREED(find));
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff REQUIRE(FIND_WANTEVENT(find));
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff bucket = find->name_bucket;
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff if (bucket == DNS_ADB_INVALIDBUCKET)
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff goto cleanup;
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff /*
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff * We need to get the adbname's lock to unlink the find.
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff */
2d083fead27c474feff3a6f79fc3da09d3637a09Andreas Gustafsson unlock_bucket = bucket;
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff violate_locking_hierarchy(&find->lock, &adb->namelocks[unlock_bucket]);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff bucket = find->name_bucket;
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff if (bucket != DNS_ADB_INVALIDBUCKET) {
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff ISC_LIST_UNLINK(find->adbname->finds, find, plink);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff find->adbname = NULL;
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff find->name_bucket = DNS_ADB_INVALIDBUCKET;
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff }
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff UNLOCK(&adb->namelocks[unlock_bucket]);
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff bucket = DNS_ADB_INVALIDBUCKET;
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff cleanup:
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff if (!FIND_EVENTSENT(find)) {
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff ev = &find->event;
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff task = ev->ev_sender;
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff ev->ev_sender = find;
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff ev->ev_type = DNS_EVENT_ADBCANCELED;
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff ev->ev_destroy = event_free;
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff ev->ev_destroy_arg = find;
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff find->result_v4 = ISC_R_CANCELED;
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff find->result_v6 = ISC_R_CANCELED;
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff DP(DEF_LEVEL, "sending event %p to task %p for find %p",
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff ev, task, find);
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff isc_task_sendanddetach(&task, (isc_event_t **)&ev);
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff }
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff UNLOCK(&find->lock);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff}
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graffvoid
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graffdns_adb_dump(dns_adb_t *adb, FILE *f) {
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff REQUIRE(DNS_ADB_VALID(adb));
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff REQUIRE(f != NULL);
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff /*
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff * Lock the adb itself, lock all the name buckets, then lock all
08d131595373326ec4a3af793b536df8c33115ecMichael Graff * the entry buckets. This should put the adb into a state where
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * nothing can change, so we can iterate through everything and
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff * print at our leisure.
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff */
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff LOCK(&adb->lock);
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff dump_adb(adb, f, ISC_FALSE);
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff UNLOCK(&adb->lock);
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff}
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff
a44bd6a6edccd4c8e3884a13fcff037e7e2dd868Michael Graffstatic void
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graffdump_ttl(FILE *f, const char *legend, isc_stdtime_t value, isc_stdtime_t now) {
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff if (value == INT_MAX)
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff return;
78854e02c127f31ab90f56da0531542004b45377Michael Graff fprintf(f, " [%s TTL %d]", legend, value - now);
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff}
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graffstatic void
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graffdump_adb(dns_adb_t *adb, FILE *f, isc_boolean_t debug) {
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff int i;
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff dns_adbname_t *name;
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff isc_stdtime_t now;
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff isc_stdtime_get(&now);
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff fprintf(f, ";\n; Address database dump\n;\n");
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff if (debug)
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff fprintf(f, "; addr %p, erefcnt %u, irefcnt %u, finds out %u\n",
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff adb, adb->erefcnt, adb->irefcnt,
a44bd6a6edccd4c8e3884a13fcff037e7e2dd868Michael Graff isc_mempool_getallocated(adb->nhmp));
a44bd6a6edccd4c8e3884a13fcff037e7e2dd868Michael Graff
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff for (i = 0; i < NBUCKETS; i++)
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff LOCK(&adb->namelocks[i]);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff for (i = 0; i < NBUCKETS; i++)
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff LOCK(&adb->entrylocks[i]);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff /*
a44bd6a6edccd4c8e3884a13fcff037e7e2dd868Michael Graff * Dump the names
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff */
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff for (i = 0; i < NBUCKETS; i++) {
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff name = ISC_LIST_HEAD(adb->names[i]);
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff if (name == NULL)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff continue;
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff if (debug)
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff fprintf(f, "; bucket %d\n", i);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff for (;
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff name != NULL;
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff name = ISC_LIST_NEXT(name, plink))
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff {
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff if (debug)
78854e02c127f31ab90f56da0531542004b45377Michael Graff fprintf(f, "; name %p (flags %08x)\n",
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff name, name->flags);
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff fprintf(f, "; ");
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff print_dns_name(f, &name->name);
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff if (dns_name_countlabels(&name->target) > 0) {
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff fprintf(f, " alias ");
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff print_dns_name(f, &name->target);
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff }
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff dump_ttl(f, "v4", name->expire_v4, now);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff dump_ttl(f, "v6", name->expire_v6, now);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff dump_ttl(f, "target", name->expire_target, now);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff fprintf(f, " [v4 %s] [v6 %s]",
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff errnames[name->fetch_err],
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff errnames[name->fetch6_err]);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff fprintf(f, "\n");
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff print_namehook_list(f, "v4", &name->v4, debug);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff print_namehook_list(f, "v6", &name->v6, debug);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff if (debug)
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff print_fetch_list(f, name);
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff if (debug)
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff print_find_list(f, name);
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff }
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff }
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff /*
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff * Unlock everything
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff */
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff for (i = 0; i < NBUCKETS; i++)
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff UNLOCK(&adb->entrylocks[i]);
11e89b9b44862128b46994a87484027b3c7d533aMichael Graff for (i = 0; i < NBUCKETS; i++)
11e89b9b44862128b46994a87484027b3c7d533aMichael Graff UNLOCK(&adb->namelocks[i]);
58aaab3687aac838542ee4ef65a9c094a5d34ab0Michael Graff}
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graffstatic void
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graffdump_entry(FILE *f, dns_adbentry_t *entry, isc_boolean_t debug)
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff{
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff char addrbuf[ISC_NETADDR_FORMATSIZE];
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff isc_netaddr_t netaddr;
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff isc_netaddr_fromsockaddr(&netaddr, &entry->sockaddr);
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf));
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff if (debug)
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff fprintf(f, ";\t%p: refcnt %u flags %08x \n",
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff entry, entry->refcnt, entry->flags);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff fprintf(f, ";\t%s [srtt %u]", addrbuf, entry->srtt);
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff fprintf(f, "\n");
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff}
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graffvoid
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graffdns_adb_dumpfind(dns_adbfind_t *find, FILE *f) {
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff char tmp[512];
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff const char *tmpp;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff dns_adbaddrinfo_t *ai;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff isc_sockaddr_t *sa;
11e89b9b44862128b46994a87484027b3c7d533aMichael Graff
11e89b9b44862128b46994a87484027b3c7d533aMichael Graff /*
11e89b9b44862128b46994a87484027b3c7d533aMichael Graff * Not used currently, in the API Just In Case we
11e89b9b44862128b46994a87484027b3c7d533aMichael Graff * want to dump out the name and/or entries too.
11e89b9b44862128b46994a87484027b3c7d533aMichael Graff */
11e89b9b44862128b46994a87484027b3c7d533aMichael Graff
fd1c538c9d5a747ffc7d3a983a598ad6c5583263Bob Halley LOCK(&find->lock);
11e89b9b44862128b46994a87484027b3c7d533aMichael Graff
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley fprintf(f, ";Find %p\n", find);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley fprintf(f, ";\tqpending %08x partial %08x options %08x flags %08x\n",
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley find->query_pending, find->partial_result,
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley find->options, find->flags);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley fprintf(f, ";\tname_bucket %d, name %p, event sender %p\n",
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff find->name_bucket, find->adbname, find->event.ev_sender);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley ai = ISC_LIST_HEAD(find->list);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley if (ai != NULL)
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley fprintf(f, "\tAddresses:\n");
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff while (ai != NULL) {
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff sa = &ai->sockaddr;
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff switch (sa->type.sa.sa_family) {
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff case AF_INET:
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff tmpp = inet_ntop(AF_INET, &sa->type.sin.sin_addr,
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff tmp, sizeof(tmp));
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff break;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff case AF_INET6:
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff tmpp = inet_ntop(AF_INET6, &sa->type.sin6.sin6_addr,
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff tmp, sizeof(tmp));
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff break;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff default:
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff tmpp = "UnkFamily";
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff }
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff if (tmpp == NULL)
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff tmpp = "BadAddress";
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff fprintf(f, "\t\tentry %p, flags %08x"
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff " srtt %u addr %s\n",
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff ai->entry, ai->flags, ai->srtt, tmpp);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff ai = ISC_LIST_NEXT(ai, publink);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff }
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff UNLOCK(&find->lock);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff}
a9ece9973c35d4d780338e89e288fb6a59575324Michael Graff
a9ece9973c35d4d780338e89e288fb6a59575324Michael Graffstatic void
a9ece9973c35d4d780338e89e288fb6a59575324Michael Graffprint_dns_name(FILE *f, dns_name_t *name) {
a9ece9973c35d4d780338e89e288fb6a59575324Michael Graff char buf[DNS_NAME_FORMATSIZE];
a9ece9973c35d4d780338e89e288fb6a59575324Michael Graff
a9ece9973c35d4d780338e89e288fb6a59575324Michael Graff INSIST(f != NULL);
a9ece9973c35d4d780338e89e288fb6a59575324Michael Graff
a9ece9973c35d4d780338e89e288fb6a59575324Michael Graff dns_name_format(name, buf, sizeof(buf));
a9ece9973c35d4d780338e89e288fb6a59575324Michael Graff fprintf(f, "%s", buf);
a9ece9973c35d4d780338e89e288fb6a59575324Michael Graff}
a9ece9973c35d4d780338e89e288fb6a59575324Michael Graff
a9ece9973c35d4d780338e89e288fb6a59575324Michael Graffstatic void
a9ece9973c35d4d780338e89e288fb6a59575324Michael Graffprint_namehook_list(FILE *f, const char *legend, dns_adbnamehooklist_t *list,
a9ece9973c35d4d780338e89e288fb6a59575324Michael Graff isc_boolean_t debug)
a9ece9973c35d4d780338e89e288fb6a59575324Michael Graff{
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff dns_adbnamehook_t *nh;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff for (nh = ISC_LIST_HEAD(*list);
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff nh != NULL;
a9ece9973c35d4d780338e89e288fb6a59575324Michael Graff nh = ISC_LIST_NEXT(nh, plink))
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff {
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff if (debug)
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff fprintf(f, ";\tHook(%s) %p\n", legend, nh);
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff dump_entry(f, nh->entry, debug);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff }
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff}
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graffstatic inline void
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graffprint_fetch(FILE *f, dns_adbfetch_t *ft, const char *type) {
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff fprintf(f, "\t\tFetch(%s): %p -> { nh %p, entry %p, fetch %p }\n",
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff type, ft, ft->namehook, ft->entry, ft->fetch);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff}
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graffstatic inline void
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graffprint_fetch6(FILE *f, dns_adbfetch6_t *ft) {
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff fprintf(f, "\t\tFetch(A6): %p -> { nh %p, entry %p, fetch %p }\n",
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff ft, ft->namehook, ft->entry, ft->fetch);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff}
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graffstatic void
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graffprint_fetch_list(FILE *f, dns_adbname_t *n) {
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff dns_adbfetch6_t *fetch6;
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff if (NAME_FETCH_A(n))
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff print_fetch(f, n->fetch_a, "A");
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff if (NAME_FETCH_AAAA(n))
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff print_fetch(f, n->fetch_aaaa, "AAAA");
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff fetch6 = ISC_LIST_HEAD(n->fetches_a6);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff while (fetch6 != NULL) {
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff print_fetch6(f, fetch6);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff fetch6 = ISC_LIST_NEXT(fetch6, plink);
78854e02c127f31ab90f56da0531542004b45377Michael Graff }
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff}
78854e02c127f31ab90f56da0531542004b45377Michael Graff
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graffstatic void
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graffprint_find_list(FILE *f, dns_adbname_t *name) {
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff dns_adbfind_t *find;
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff find = ISC_LIST_HEAD(name->finds);
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff while (find != NULL) {
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff dns_adb_dumpfind(find, f);
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff find = ISC_LIST_NEXT(find, plink);
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff }
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff}
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graffstatic isc_result_t
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graffdbfind_name(dns_adbname_t *adbname, isc_stdtime_t now, dns_rdatatype_t rdtype)
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff{
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff isc_result_t result;
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff dns_rdataset_t rdataset;
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff dns_adb_t *adb;
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff dns_fixedname_t foundname;
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff dns_name_t *fname;
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff INSIST(DNS_ADBNAME_VALID(adbname));
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff adb = adbname->adb;
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff INSIST(DNS_ADB_VALID(adb));
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff INSIST(rdtype == dns_rdatatype_a || rdtype == dns_rdatatype_aaaa);
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff dns_fixedname_init(&foundname);
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff fname = dns_fixedname_name(&foundname);
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff dns_rdataset_init(&rdataset);
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff if (rdtype == dns_rdatatype_a)
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff adbname->fetch_err = FIND_ERR_UNEXPECTED;
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff else
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff adbname->fetch6_err = FIND_ERR_UNEXPECTED;
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff result = dns_view_find(adb->view, &adbname->name, rdtype, now,
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff NAME_GLUEOK(adbname),
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff ISC_TF(NAME_HINTOK(adbname)),
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley NULL, NULL, fname, &rdataset, NULL);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley switch (result) {
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff case DNS_R_GLUE:
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff case DNS_R_HINT:
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff case ISC_R_SUCCESS:
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley /*
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff * Found in the database. Even if we can't copy out
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * any information, return success, or else a fetch
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * will be made, which will only make things worse.
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley */
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley if (rdtype == dns_rdatatype_a)
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff adbname->fetch_err = FIND_ERR_SUCCESS;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff else
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff adbname->fetch6_err = FIND_ERR_SUCCESS;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff result = import_rdataset(adbname, &rdataset, now);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff break;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff case DNS_R_NXDOMAIN:
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff case DNS_R_NXRRSET:
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff /*
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff * We're authoritative and the data doesn't exist.
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff * Make up a negative cache entry so we don't ask again
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff * for a while.
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff *
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff * XXXRTH What time should we use? I'm putting in 30 seconds
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff * for now.
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff */
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff if (rdtype == dns_rdatatype_a) {
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff adbname->expire_v4 = now + 30;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff DP(NCACHE_LEVEL,
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff "adb name %p: Caching auth negative entry for A",
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff adbname);
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff if (result == DNS_R_NXDOMAIN)
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff adbname->fetch_err = FIND_ERR_NXDOMAIN;
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff else
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff adbname->fetch_err = FIND_ERR_NXRRSET;
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff } else {
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff DP(NCACHE_LEVEL,
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff "adb name %p: Caching auth negative entry for AAAA",
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff adbname);
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff adbname->expire_v6 = now + 30;
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff if (result == DNS_R_NXDOMAIN)
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff adbname->fetch6_err = FIND_ERR_NXDOMAIN;
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff else
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff adbname->fetch6_err = FIND_ERR_NXRRSET;
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff }
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff break;
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff case DNS_R_NCACHENXDOMAIN:
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff case DNS_R_NCACHENXRRSET:
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff /*
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff * We found a negative cache entry. Pull the TTL from it
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff * so we won't ask again for a while.
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff */
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff rdataset.ttl = ttlclamp(rdataset.ttl);
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff if (rdtype == dns_rdatatype_a) {
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff adbname->expire_v4 = rdataset.ttl + now;
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff if (result == DNS_R_NCACHENXDOMAIN)
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff adbname->fetch_err = FIND_ERR_NXDOMAIN;
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff else
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff adbname->fetch_err = FIND_ERR_NXRRSET;
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff DP(NCACHE_LEVEL,
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff "adb name %p: Caching negative entry for A (ttl %u)",
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff adbname, rdataset.ttl);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff } else {
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff DP(NCACHE_LEVEL,
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff "adb name %p: Caching negative entry for AAAA (ttl %u)",
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff adbname, rdataset.ttl);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff adbname->expire_v6 = rdataset.ttl + now;
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff if (result == DNS_R_NCACHENXDOMAIN)
b5492be2c7c3792a1b6c03995fe378703fc814cbMichael Graff adbname->fetch6_err = FIND_ERR_NXDOMAIN;
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff else
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff adbname->fetch6_err = FIND_ERR_NXRRSET;
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff }
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff break;
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff case DNS_R_CNAME:
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff case DNS_R_DNAME:
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff /*
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff * Clear the hint and glue flags, so this will match
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff * more often.
29f28fe573d4b3b318b3b026d567c1eb86738015Michael Graff */
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff adbname->flags &= ~(DNS_ADBFIND_GLUEOK | DNS_ADBFIND_HINTOK);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley rdataset.ttl = ttlclamp(rdataset.ttl);
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff clean_target(adb, &adbname->target);
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff adbname->expire_target = INT_MAX;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff result = set_target(adb, &adbname->name, fname, &rdataset,
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff &adbname->target);
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff if (result == ISC_R_SUCCESS) {
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff result = DNS_R_ALIAS;
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley DP(NCACHE_LEVEL,
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley "adb name %p: caching alias target",
29f28fe573d4b3b318b3b026d567c1eb86738015Michael Graff adbname);
29f28fe573d4b3b318b3b026d567c1eb86738015Michael Graff adbname->expire_target = rdataset.ttl + now;
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley }
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley if (rdtype == dns_rdatatype_a)
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley adbname->fetch_err = FIND_ERR_SUCCESS;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff else
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff adbname->fetch6_err = FIND_ERR_SUCCESS;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff break;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff }
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff if (dns_rdataset_isassociated(&rdataset))
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff dns_rdataset_disassociate(&rdataset);
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff return (result);
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff}
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halleystatic isc_result_t
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halleydbfind_a6(dns_adbname_t *adbname, isc_stdtime_t now) {
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley isc_result_t result;
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley dns_rdataset_t rdataset;
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley dns_adb_t *adb;
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley dns_a6context_t a6ctx;
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley dns_fixedname_t foundname;
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley dns_name_t *fname;
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley INSIST(DNS_ADBNAME_VALID(adbname));
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley adb = adbname->adb;
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley INSIST(DNS_ADB_VALID(adb));
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley INSIST(!NAME_FETCH_V6(adbname));
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley result = ISC_R_UNEXPECTED;
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley dns_fixedname_init(&foundname);
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley fname = dns_fixedname_name(&foundname);
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley dns_rdataset_init(&rdataset);
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley adbname->fetch6_err = FIND_ERR_UNEXPECTED;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff result = dns_view_find(adb->view, &adbname->name, dns_rdatatype_a6,
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff now, NAME_GLUEOK(adbname),
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff ISC_TF(NAME_HINTOK(adbname)),
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff NULL, NULL, fname, &rdataset, NULL);
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff switch (result) {
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley case DNS_R_GLUE:
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff case DNS_R_HINT:
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff case ISC_R_SUCCESS:
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley /*
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley * Start A6 chain follower. There is no need to poke people
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff * who might be waiting, since this is call requires there
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff * are none.
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley */
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley adbname->fetch6_err = FIND_ERR_SUCCESS;
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff dns_a6_init(&a6ctx, a6find, NULL, import_a6,
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff a6missing, adbname);
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff (void)dns_a6_foreach(&a6ctx, &rdataset, now);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley adbname->flags &= ~NAME_NEEDS_POKE;
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley result = ISC_R_SUCCESS;
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley break;
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley case DNS_R_NXDOMAIN:
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley case DNS_R_NXRRSET:
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley /*
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * We're authoritative and the data doesn't exist.
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * Make up a negative cache entry so we don't ask again
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * for a while.
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley *
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * XXXRTH What time should we use? I'm putting in 30 seconds
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * for now.
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley */
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley DP(NCACHE_LEVEL,
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley "adb name %p: Caching auth negative entry for A6",
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff adbname);
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff adbname->expire_v6 = now + 30;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff if (result == DNS_R_NXDOMAIN)
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff adbname->fetch6_err = FIND_ERR_NXDOMAIN;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff else
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff adbname->fetch6_err = FIND_ERR_NXRRSET;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff break;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff case DNS_R_NCACHENXDOMAIN:
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff case DNS_R_NCACHENXRRSET:
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff /*
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff * We found a negative cache entry. Pull the TTL from it
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff * so we won't ask again for a while.
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff */
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff DP(NCACHE_LEVEL,
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff "adb name %p: Caching negative entry for A6 (ttl %u)",
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley adbname, rdataset.ttl);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley adbname->expire_v6 = ISC_MIN(rdataset.ttl + now,
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff adbname->expire_v6);
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff if (result == DNS_R_NCACHENXDOMAIN)
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff adbname->fetch6_err = FIND_ERR_NXDOMAIN;
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff else
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff adbname->fetch6_err = FIND_ERR_NXRRSET;
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff break;
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff case DNS_R_CNAME:
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff case DNS_R_DNAME:
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley rdataset.ttl = ttlclamp(rdataset.ttl);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley clean_target(adb, &adbname->target);
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff adbname->expire_target = INT_MAX;
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff result = set_target(adb, &adbname->name, fname, &rdataset,
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley &adbname->target);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley if (result == ISC_R_SUCCESS) {
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley result = DNS_R_ALIAS;
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff DP(NCACHE_LEVEL,
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff "adb name %p: caching alias target",
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff adbname);
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff adbname->expire_target = rdataset.ttl + now;
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff }
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff break;
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff }
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff if (dns_rdataset_isassociated(&rdataset))
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff dns_rdataset_disassociate(&rdataset);
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff
59c049874bbef182857c57bd9cca292898921c69Bob Halley return (result);
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff}
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halleystatic void
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halleyfetch_callback(isc_task_t *task, isc_event_t *ev) {
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley dns_fetchevent_t *dev;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley dns_adbname_t *name;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley dns_adb_t *adb;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley dns_adbfetch_t *fetch;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley int bucket;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley isc_eventtype_t ev_status;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley isc_stdtime_t now;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley isc_result_t result;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley unsigned int address_type;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley isc_boolean_t want_check_exit = ISC_FALSE;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley UNUSED(task);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff INSIST(ev->ev_type == DNS_EVENT_FETCHDONE);
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff dev = (dns_fetchevent_t *)ev;
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff name = ev->ev_arg;
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff INSIST(DNS_ADBNAME_VALID(name));
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff adb = name->adb;
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff INSIST(DNS_ADB_VALID(adb));
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley bucket = name->lock_bucket;
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff LOCK(&adb->namelocks[bucket]);
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff INSIST(NAME_FETCH_A(name) || NAME_FETCH_AAAA(name));
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley address_type = 0;
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley if (NAME_FETCH_A(name) && (name->fetch_a->fetch == dev->fetch)) {
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley address_type = DNS_ADBFIND_INET;
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley fetch = name->fetch_a;
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley name->fetch_a = NULL;
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley } else if (NAME_FETCH_AAAA(name)
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley && (name->fetch_aaaa->fetch == dev->fetch)) {
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley address_type = DNS_ADBFIND_INET6;
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley fetch = name->fetch_aaaa;
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley name->fetch_aaaa = NULL;
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley }
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley INSIST(address_type != 0);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley dns_resolver_destroyfetch(&fetch->fetch);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley dev->fetch = NULL;
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff ev_status = DNS_EVENT_ADBNOMOREADDRESSES;
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff /*
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff * Cleanup things we don't care about.
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff */
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff if (dev->node != NULL)
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff dns_db_detachnode(dev->db, &dev->node);
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff if (dev->db != NULL)
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff dns_db_detach(&dev->db);
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff /*
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff * If this name is marked as dead, clean up, throwing away
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff * potentially good data.
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff */
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff if (NAME_DEAD(name)) {
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff free_adbfetch(adb, &fetch);
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff isc_event_free(&ev);
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff kill_name(&name, DNS_EVENT_ADBCANCELED);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff /*
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff * If we're shutting down and this bucket is empty, we need
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff * to call check_exit() to see if we're done.
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff */
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff if (adb->name_sd[bucket] && adb->name_refcnt[bucket] == 0)
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff want_check_exit = ISC_TRUE;
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff UNLOCK(&adb->namelocks[bucket]);
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff if (want_check_exit) {
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff LOCK(&adb->lock);
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff check_exit(adb);
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff UNLOCK(&adb->lock);
c68421fffe3dd7fcc4ae5a228d9eb888df4b5e72Michael Graff }
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff
c68421fffe3dd7fcc4ae5a228d9eb888df4b5e72Michael Graff return;
c68421fffe3dd7fcc4ae5a228d9eb888df4b5e72Michael Graff }
c68421fffe3dd7fcc4ae5a228d9eb888df4b5e72Michael Graff
c68421fffe3dd7fcc4ae5a228d9eb888df4b5e72Michael Graff isc_stdtime_get(&now);
c68421fffe3dd7fcc4ae5a228d9eb888df4b5e72Michael Graff
c68421fffe3dd7fcc4ae5a228d9eb888df4b5e72Michael Graff /*
c68421fffe3dd7fcc4ae5a228d9eb888df4b5e72Michael Graff * If we got a negative cache response, remember it.
c68421fffe3dd7fcc4ae5a228d9eb888df4b5e72Michael Graff */
c68421fffe3dd7fcc4ae5a228d9eb888df4b5e72Michael Graff if (NCACHE_RESULT(dev->result)) {
c68421fffe3dd7fcc4ae5a228d9eb888df4b5e72Michael Graff dev->rdataset->ttl = ttlclamp(dev->rdataset->ttl);
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff if (address_type == DNS_ADBFIND_INET) {
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff DP(NCACHE_LEVEL, "adb fetch name %p: "
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley "caching negative entry for A (ttl %u)",
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff name, dev->rdataset->ttl);
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff name->expire_v4 = ISC_MIN(name->expire_v4,
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff dev->rdataset->ttl + now);
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff if (dev->result == DNS_R_NCACHENXDOMAIN)
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff name->fetch_err = FIND_ERR_NXDOMAIN;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff else
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff name->fetch_err = FIND_ERR_NXRRSET;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff } else {
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff DP(NCACHE_LEVEL, "adb fetch name %p: "
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff "caching negative entry for AAAA (ttl %u)",
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff name, dev->rdataset->ttl);
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff name->expire_v6 = ISC_MIN(name->expire_v6,
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff dev->rdataset->ttl + now);
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff if (dev->result == DNS_R_NCACHENXDOMAIN)
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff name->fetch6_err = FIND_ERR_NXDOMAIN;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff else
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff name->fetch6_err = FIND_ERR_NXRRSET;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff }
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff goto out;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff }
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff /*
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley * Handle CNAME/DNAME.
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley */
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley if (dev->result == DNS_R_CNAME || dev->result == DNS_R_DNAME) {
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley dev->rdataset->ttl = ttlclamp(dev->rdataset->ttl);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley clean_target(adb, &name->target);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley name->expire_target = INT_MAX;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff result = set_target(adb, &name->name,
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff dns_fixedname_name(&dev->foundname),
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff dev->rdataset,
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley &name->target);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley if (result == ISC_R_SUCCESS) {
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley DP(NCACHE_LEVEL,
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley "adb fetch name %p: caching alias target",
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley name);
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff name->expire_target = dev->rdataset->ttl + now;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff }
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff goto check_result;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff }
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley /*
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff * Did we get back junk? If so, and there are no more fetches
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff * sitting out there, tell all the finds about it.
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff */
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff if (dev->result != ISC_R_SUCCESS) {
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley /* XXXMLG Don't pound on bad servers. */
d947011dc393d9f9988d1349d585b246d19cc3c7Michael Graff if (address_type == DNS_ADBFIND_INET) {
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff name->expire_v4 = ISC_MIN(name->expire_v4, now + 300);
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff name->fetch_err = FIND_ERR_FAILURE;
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff } else {
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff name->expire_v6 = ISC_MIN(name->expire_v6, now + 300);
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff name->fetch6_err = FIND_ERR_FAILURE;
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff }
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff goto out;
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff }
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff /*
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff * We got something potentially useful.
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff */
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff result = import_rdataset(name, &fetch->rdataset, now);
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff check_result:
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff if (result == ISC_R_SUCCESS) {
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley ev_status = DNS_EVENT_ADBMOREADDRESSES;
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley if (address_type == DNS_ADBFIND_INET)
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley name->fetch_err = FIND_ERR_SUCCESS;
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley else
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley name->fetch6_err = FIND_ERR_SUCCESS;
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley }
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley out:
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley free_adbfetch(adb, &fetch);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley isc_event_free(&ev);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley clean_finds_at_name(name, ev_status, address_type);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley UNLOCK(&adb->namelocks[bucket]);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley}
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halleystatic void
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halleyfetch_callback_a6(isc_task_t *task, isc_event_t *ev) {
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley dns_fetchevent_t *dev;
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley dns_adbname_t *name;
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley dns_adb_t *adb;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff dns_adbfetch6_t *fetch;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff int bucket;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff isc_stdtime_t now;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff isc_result_t result;
ef5e39139c46f8b953845dbfd37339fcf4472e44Michael Graff isc_boolean_t want_check_exit = ISC_FALSE;
ef5e39139c46f8b953845dbfd37339fcf4472e44Michael Graff
ef5e39139c46f8b953845dbfd37339fcf4472e44Michael Graff UNUSED(task);
ef5e39139c46f8b953845dbfd37339fcf4472e44Michael Graff
ef5e39139c46f8b953845dbfd37339fcf4472e44Michael Graff INSIST(ev->ev_type == DNS_EVENT_FETCHDONE);
ef5e39139c46f8b953845dbfd37339fcf4472e44Michael Graff dev = (dns_fetchevent_t *)ev;
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff name = ev->ev_arg;
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff INSIST(DNS_ADBNAME_VALID(name));
ef5e39139c46f8b953845dbfd37339fcf4472e44Michael Graff adb = name->adb;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff INSIST(DNS_ADB_VALID(adb));
ef5e39139c46f8b953845dbfd37339fcf4472e44Michael Graff
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff bucket = name->lock_bucket;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff LOCK(&adb->namelocks[bucket]);
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff INSIST(!NAME_NEEDSPOKE(name));
58aaab3687aac838542ee4ef65a9c094a5d34ab0Michael Graff
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley for (fetch = ISC_LIST_HEAD(name->fetches_a6);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley fetch != NULL;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff fetch = ISC_LIST_NEXT(fetch, plink))
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff if (fetch->fetch == dev->fetch)
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff break;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff INSIST(fetch != NULL);
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff ISC_LIST_UNLINK(name->fetches_a6, fetch, plink);
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff DP(ENTER_LEVEL, "ENTER: fetch_callback_a6() name %p", name);
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff dns_resolver_destroyfetch(&fetch->fetch);
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff dev->fetch = NULL;
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff /*
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * Cleanup things we don't care about.
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley */
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (dev->node != NULL)
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley dns_db_detachnode(dev->db, &dev->node);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (dev->db != NULL)
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley dns_db_detach(&dev->db);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley /*
59c049874bbef182857c57bd9cca292898921c69Bob Halley * If this name is marked as dead, clean up, throwing away
59c049874bbef182857c57bd9cca292898921c69Bob Halley * potentially good data.
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley */
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (NAME_DEAD(name)) {
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley free_adbfetch6(adb, &fetch);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley isc_event_free(&ev);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley kill_name(&name, DNS_EVENT_ADBCANCELED);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley /*
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * If we're shutting down and this bucket is empty, we need
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * to call check_exit() to see if we're done.
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley */
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (adb->name_sd[bucket] && adb->name_refcnt[bucket] == 0)
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley want_check_exit = ISC_TRUE;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff UNLOCK(&adb->namelocks[bucket]);
288f9443ac447c9c14f3722dd6d32c1faef0f009Michael Graff
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (want_check_exit) {
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley LOCK(&adb->lock);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley check_exit(adb);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley UNLOCK(&adb->lock);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley }
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley return;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley }
78854e02c127f31ab90f56da0531542004b45377Michael Graff
78854e02c127f31ab90f56da0531542004b45377Michael Graff isc_stdtime_get(&now);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley /*
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * If the A6 query didn't succeed, and this is the first query
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * in the A6 chain, try AAAA records instead. For later failures,
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * don't do this.
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley */
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (dev->result != ISC_R_SUCCESS) {
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley DP(DEF_LEVEL, "name %p: A6 failed: %s",
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley name, isc_result_totext(dev->result));
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley /*
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * If we got a negative cache response, remember it.
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley */
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (NCACHE_RESULT(dev->result)) {
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley dev->rdataset->ttl = ttlclamp(dev->rdataset->ttl);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff DP(NCACHE_LEVEL, "adb fetch name %p: "
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley "caching negative entry for A6 (ttl %u)",
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley name, dev->rdataset->ttl);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley name->expire_v6 = ISC_MIN(name->expire_v6,
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley dev->rdataset->ttl + now);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (dev->result == DNS_R_NCACHENXDOMAIN)
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley name->fetch6_err = FIND_ERR_NXDOMAIN;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley else
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley name->fetch6_err = FIND_ERR_NXRRSET;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley }
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley /*
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * Handle CNAME/DNAME.
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley */
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (dev->result == DNS_R_CNAME || dev->result == DNS_R_DNAME) {
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley dev->rdataset->ttl = ttlclamp(dev->rdataset->ttl);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley clean_target(adb, &name->target);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley name->expire_target = INT_MAX;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley result = set_target(adb, &name->name,
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley dns_fixedname_name(&dev->foundname),
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley dev->rdataset,
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley &name->target);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (result == ISC_R_SUCCESS) {
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley DP(NCACHE_LEVEL,
58aaab3687aac838542ee4ef65a9c094a5d34ab0Michael Graff "adb A6 fetch name %p: caching alias target",
59c049874bbef182857c57bd9cca292898921c69Bob Halley name);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley name->expire_target = dev->rdataset->ttl + now;
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff if (FETCH_FIRSTA6(fetch)) {
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff /*
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff * Make this name 'pokeable', since
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * we've learned that this name is an
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff * alias.
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff */
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff name->flags |= NAME_NEEDS_POKE;
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff }
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff }
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff goto out;
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff }
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff if (FETCH_FIRSTA6(fetch) && !NAME_HAS_V6(name)) {
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff DP(DEF_LEVEL,
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley "name %p: A6 query failed, starting AAAA", name);
d947011dc393d9f9988d1349d585b246d19cc3c7Michael Graff
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff /*
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff * Since this is the very first fetch, and it
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff * failed, we know there are no more running.
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff */
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff result = dbfind_name(name, now, dns_rdatatype_aaaa);
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff if (result == ISC_R_SUCCESS) {
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff DP(DEF_LEVEL,
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley "name %p: callback_a6: Found AAAA for",
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley name);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley name->flags |= NAME_NEEDS_POKE;
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley goto out;
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley }
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley /*
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley * Listen to negative cache hints, and don't start
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley * another query.
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley */
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley if (NCACHE_RESULT(result) || AUTH_NX(result)) {
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley if (NXDOMAIN_RESULT(result))
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley name->fetch6_err = NEWERR(name->fetch6_err, FIND_ERR_NXDOMAIN);
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley else
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley name->fetch6_err = NEWERR(name->fetch6_err, FIND_ERR_NXRRSET);
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley goto out;
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley }
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley /*
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley * Try to start fetches for AAAA.
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley */
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley result = fetch_name_aaaa(name);
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley if (result == ISC_R_SUCCESS) {
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley DP(DEF_LEVEL,
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley "name %p: callback_a6: Started AAAA fetch",
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley name);
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley goto out;
fe197676cc48d9b81940a0031a340bb5d23e1dcbBob Halley }
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley }
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff goto out;
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff }
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff /*
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff * We got something potentially useful. Run the A6 chain
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff * follower on this A6 rdataset.
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff */
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff fetch->a6ctx.chains = name->chains;
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff (void)dns_a6_foreach(&fetch->a6ctx, dev->rdataset, now);
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff out:
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff free_adbfetch6(adb, &fetch);
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff isc_event_free(&ev);
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff if (NAME_NEEDSPOKE(name)) {
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff clean_finds_at_name(name, DNS_EVENT_ADBMOREADDRESSES,
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff DNS_ADBFIND_INET6);
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff name->fetch6_err = FIND_ERR_SUCCESS;
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff } else if (!NAME_FETCH_V6(name))
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff clean_finds_at_name(name, DNS_EVENT_ADBNOMOREADDRESSES,
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff DNS_ADBFIND_INET6);
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff name->flags &= ~NAME_NEEDS_POKE;
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff UNLOCK(&adb->namelocks[bucket]);
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley return;
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff}
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graffstatic isc_result_t
14b98cb34eda66c87ce41a207704a2c232280eafMichael Grafffetch_name_v4(dns_adbname_t *adbname, isc_boolean_t start_at_root) {
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff isc_result_t result;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley dns_adbfetch_t *fetch = NULL;
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff dns_adb_t *adb;
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff dns_name_t *name;
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff dns_rdataset_t rdataset;
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff dns_rdataset_t *nameservers;
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff unsigned int options;
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff INSIST(DNS_ADBNAME_VALID(adbname));
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff adb = adbname->adb;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley INSIST(DNS_ADB_VALID(adb));
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley INSIST(!NAME_FETCH_V4(adbname));
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley adbname->fetch_err = FIND_ERR_NOTFOUND;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley name = NULL;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley nameservers = NULL;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley dns_rdataset_init(&rdataset);
59c049874bbef182857c57bd9cca292898921c69Bob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley options = 0;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (start_at_root) {
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley DP(50, "fetch_name_v4: starting at DNS root for name %p",
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley adbname);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley name = dns_rootname;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff result = dns_view_simplefind(adb->view, name, dns_rdatatype_ns,
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley 0, 0, ISC_TRUE, &rdataset, NULL);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (result != ISC_R_SUCCESS && result != DNS_R_HINT)
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff goto cleanup;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley nameservers = &rdataset;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley options |= DNS_FETCHOPT_UNSHARED;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley }
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley fetch = new_adbfetch(adb);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (fetch == NULL) {
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley result = ISC_R_NOMEMORY;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley goto cleanup;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley }
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
ea6228c9ce45dafa26e4cd79d71629c8ba5cd7c7Michael Graff result = dns_resolver_createfetch(adb->view->resolver, &adbname->name,
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley dns_rdatatype_a,
ea6228c9ce45dafa26e4cd79d71629c8ba5cd7c7Michael Graff name, nameservers, NULL, options,
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff adb->task, fetch_callback,
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff adbname, &fetch->rdataset, NULL,
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff &fetch->fetch);
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley if (result != ISC_R_SUCCESS)
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff goto cleanup;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff adbname->fetch_a = fetch;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff fetch = NULL; /* Keep us from cleaning this up below. */
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff cleanup:
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff if (fetch != NULL)
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley free_adbfetch(adb, &fetch);
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley if (dns_rdataset_isassociated(&rdataset))
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley dns_rdataset_disassociate(&rdataset);
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley return (result);
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley}
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff/* XXXMLG Why doesn't this look a lot like fetch_name_a and fetch_name_a6? */
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graffstatic isc_result_t
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Grafffetch_name_aaaa(dns_adbname_t *adbname) {
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff isc_result_t result;
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff dns_adbfetch_t *fetch;
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff dns_adb_t *adb;
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley INSIST(DNS_ADBNAME_VALID(adbname));
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley adb = adbname->adb;
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff INSIST(DNS_ADB_VALID(adb));
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff INSIST(!NAME_FETCH_AAAA(adbname));
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff adbname->fetch6_err = FIND_ERR_NOTFOUND;
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff fetch = new_adbfetch(adb);
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff if (fetch == NULL) {
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff result = ISC_R_NOMEMORY;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff goto cleanup;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff }
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff result = dns_resolver_createfetch(adb->view->resolver, &adbname->name,
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff dns_rdatatype_aaaa,
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff NULL, NULL, NULL, 0,
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff adb->task, fetch_callback,
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff adbname, &fetch->rdataset, NULL,
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley &fetch->fetch);
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff if (result != ISC_R_SUCCESS)
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff goto cleanup;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff adbname->fetch_aaaa = fetch;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff fetch = NULL; /* Keep us from cleaning this up below. */
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff cleanup:
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff if (fetch != NULL)
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff free_adbfetch(adb, &fetch);
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff return (result);
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff}
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff
528829aa8ad69238e674cd81078bc14d4199691bMichael Graffstatic isc_result_t
528829aa8ad69238e674cd81078bc14d4199691bMichael Grafffetch_name_a6(dns_adbname_t *adbname, isc_boolean_t start_at_root) {
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff isc_result_t result;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff dns_adbfetch6_t *fetch = NULL;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff dns_adb_t *adb;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley dns_name_t *name;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley dns_rdataset_t rdataset;
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff dns_rdataset_t *nameservers;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff unsigned int options;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff INSIST(DNS_ADBNAME_VALID(adbname));
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff adb = adbname->adb;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff INSIST(DNS_ADB_VALID(adb));
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff INSIST(!NAME_FETCH_V6(adbname));
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff adbname->fetch6_err = FIND_ERR_NOTFOUND;
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff name = NULL;
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff nameservers = NULL;
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff dns_rdataset_init(&rdataset);
ea6228c9ce45dafa26e4cd79d71629c8ba5cd7c7Michael Graff
ea6228c9ce45dafa26e4cd79d71629c8ba5cd7c7Michael Graff options = 0;
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff if (start_at_root) {
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley DP(50, "fetch_name_a6: starting at DNS root for name %p",
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley adbname);
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff name = dns_rootname;
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff result = dns_view_simplefind(adb->view, name, dns_rdatatype_ns,
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff 0, 0, ISC_TRUE, &rdataset, NULL);
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff if (result != ISC_R_SUCCESS && result != DNS_R_HINT)
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley goto cleanup;
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff nameservers = &rdataset;
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff options |= DNS_FETCHOPT_UNSHARED;
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff }
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff fetch = new_adbfetch6(adb, adbname, NULL);
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff if (fetch == NULL) {
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff result = ISC_R_NOMEMORY;
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley goto cleanup;
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley }
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley fetch->flags |= FETCH_FIRST_A6;
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley result = dns_resolver_createfetch(adb->view->resolver, &adbname->name,
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley dns_rdatatype_a6,
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff name, nameservers, NULL, options,
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff adb->task, fetch_callback_a6,
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff adbname, &fetch->rdataset, NULL,
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff &fetch->fetch);
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff if (result != ISC_R_SUCCESS)
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff goto cleanup;
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff ISC_LIST_APPEND(adbname->fetches_a6, fetch, plink);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff fetch = NULL; /* Keep us from cleaning this up below. */
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff cleanup:
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley if (fetch != NULL)
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley free_adbfetch6(adb, &fetch);
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff if (dns_rdataset_isassociated(&rdataset))
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff dns_rdataset_disassociate(&rdataset);
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff return (result);
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff}
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff/*
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff * XXXMLG Needs to take a find argument and an address info, no zone or adb,
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff * since these can be extracted from the find itself.
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff */
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graffisc_result_t
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graffdns_adb_marklame(dns_adb_t *adb, dns_adbaddrinfo_t *addr, dns_name_t *zone,
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff isc_stdtime_t expire_time)
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff{
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff dns_adbzoneinfo_t *zi;
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff int bucket;
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff REQUIRE(DNS_ADB_VALID(adb));
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff REQUIRE(DNS_ADBADDRINFO_VALID(addr));
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff REQUIRE(zone != NULL);
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff
f00d96a15cdd11e764437f9359e67328631caaeaMichael Graff zi = new_adbzoneinfo(adb, zone);
f00d96a15cdd11e764437f9359e67328631caaeaMichael Graff if (zi == NULL)
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff return (ISC_R_NOMEMORY);
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff
f00d96a15cdd11e764437f9359e67328631caaeaMichael Graff zi->lame_timer = expire_time;
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff bucket = addr->entry->lock_bucket;
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff LOCK(&adb->entrylocks[bucket]);
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff ISC_LIST_PREPEND(addr->entry->zoneinfo, zi, plink);
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff UNLOCK(&adb->entrylocks[bucket]);
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff return (ISC_R_SUCCESS);
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff}
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff
f00d96a15cdd11e764437f9359e67328631caaeaMichael Graffvoid
f00d96a15cdd11e764437f9359e67328631caaeaMichael Graffdns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
f00d96a15cdd11e764437f9359e67328631caaeaMichael Graff unsigned int rtt, unsigned int factor)
f00d96a15cdd11e764437f9359e67328631caaeaMichael Graff{
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff int bucket;
f00d96a15cdd11e764437f9359e67328631caaeaMichael Graff unsigned int new_srtt;
f00d96a15cdd11e764437f9359e67328631caaeaMichael Graff
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff REQUIRE(DNS_ADB_VALID(adb));
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff REQUIRE(DNS_ADBADDRINFO_VALID(addr));
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff REQUIRE(factor <= 10);
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff bucket = addr->entry->lock_bucket;
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff LOCK(&adb->entrylocks[bucket]);
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff new_srtt = (addr->entry->srtt / 10 * factor)
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff + (rtt / 10 * (10 - factor));
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff
beb2b4f19624af46230a8e3df97e54d6c596573eMichael Graff addr->entry->srtt = new_srtt;
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff addr->srtt = new_srtt;
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff UNLOCK(&adb->entrylocks[bucket]);
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff}
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff
ca924f706b53b895a662de8345d88437b23b8f01Michael Graffvoid
ca924f706b53b895a662de8345d88437b23b8f01Michael Graffdns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff unsigned int bits, unsigned int mask)
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff{
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff int bucket;
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff REQUIRE(DNS_ADB_VALID(adb));
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff REQUIRE(DNS_ADBADDRINFO_VALID(addr));
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff bucket = addr->entry->lock_bucket;
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff LOCK(&adb->entrylocks[bucket]);
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff addr->entry->flags = (addr->entry->flags & ~mask) | (bits & mask);
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff /*
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff * Note that we do not update the other bits in addr->flags with
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff * the most recent values from addr->entry->flags.
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff */
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff addr->flags = (addr->flags & ~mask) | (bits & mask);
beb2b4f19624af46230a8e3df97e54d6c596573eMichael Graff
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff UNLOCK(&adb->entrylocks[bucket]);
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff}
ca924f706b53b895a662de8345d88437b23b8f01Michael Graff
ca924f706b53b895a662de8345d88437b23b8f01Michael Graffisc_result_t
beb2b4f19624af46230a8e3df97e54d6c596573eMichael Graffdns_adb_findaddrinfo(dns_adb_t *adb, isc_sockaddr_t *sa,
beb2b4f19624af46230a8e3df97e54d6c596573eMichael Graff dns_adbaddrinfo_t **addrp, isc_stdtime_t now)
beb2b4f19624af46230a8e3df97e54d6c596573eMichael Graff{
beb2b4f19624af46230a8e3df97e54d6c596573eMichael Graff int bucket;
beb2b4f19624af46230a8e3df97e54d6c596573eMichael Graff dns_adbentry_t *entry;
beb2b4f19624af46230a8e3df97e54d6c596573eMichael Graff dns_adbaddrinfo_t *addr;
beb2b4f19624af46230a8e3df97e54d6c596573eMichael Graff isc_result_t result;
beb2b4f19624af46230a8e3df97e54d6c596573eMichael Graff in_port_t port;
beb2b4f19624af46230a8e3df97e54d6c596573eMichael Graff
42fe494186d386ddda15eb9403038c3558bbd5bfMichael Graff REQUIRE(DNS_ADB_VALID(adb));
beb2b4f19624af46230a8e3df97e54d6c596573eMichael Graff REQUIRE(addrp != NULL && *addrp == NULL);
beb2b4f19624af46230a8e3df97e54d6c596573eMichael Graff
beb2b4f19624af46230a8e3df97e54d6c596573eMichael Graff UNUSED(now);
beb2b4f19624af46230a8e3df97e54d6c596573eMichael Graff
42fe494186d386ddda15eb9403038c3558bbd5bfMichael Graff result = ISC_R_SUCCESS;
42fe494186d386ddda15eb9403038c3558bbd5bfMichael Graff bucket = DNS_ADB_INVALIDBUCKET;
42fe494186d386ddda15eb9403038c3558bbd5bfMichael Graff entry = find_entry_and_lock(adb, sa, &bucket);
beb2b4f19624af46230a8e3df97e54d6c596573eMichael Graff if (adb->entry_sd[bucket]) {
beb2b4f19624af46230a8e3df97e54d6c596573eMichael Graff result = ISC_R_SHUTTINGDOWN;
beb2b4f19624af46230a8e3df97e54d6c596573eMichael Graff goto unlock;
beb2b4f19624af46230a8e3df97e54d6c596573eMichael Graff }
beb2b4f19624af46230a8e3df97e54d6c596573eMichael Graff if (entry == NULL) {
4f6dd51441290a9feacbe62991a2cdfdc7554e8bMichael Graff /*
4f6dd51441290a9feacbe62991a2cdfdc7554e8bMichael Graff * We don't know anything about this address.
4f6dd51441290a9feacbe62991a2cdfdc7554e8bMichael Graff */
4f6dd51441290a9feacbe62991a2cdfdc7554e8bMichael Graff entry = new_adbentry(adb);
4f6dd51441290a9feacbe62991a2cdfdc7554e8bMichael Graff if (entry == NULL) {
4f6dd51441290a9feacbe62991a2cdfdc7554e8bMichael Graff result = ISC_R_NOMEMORY;
4f6dd51441290a9feacbe62991a2cdfdc7554e8bMichael Graff goto unlock;
4f6dd51441290a9feacbe62991a2cdfdc7554e8bMichael Graff }
4f6dd51441290a9feacbe62991a2cdfdc7554e8bMichael Graff entry->sockaddr = *sa;
4f6dd51441290a9feacbe62991a2cdfdc7554e8bMichael Graff link_entry(adb, bucket, entry);
4f6dd51441290a9feacbe62991a2cdfdc7554e8bMichael Graff DP(50, "findaddrinfo: new entry %p", entry);
4f6dd51441290a9feacbe62991a2cdfdc7554e8bMichael Graff } else
4f6dd51441290a9feacbe62991a2cdfdc7554e8bMichael Graff DP(50, "findaddrinfo: found entry %p", entry);
70b065bd9297ae7baf203a2335211fc7b4544818Bob Halley
70b065bd9297ae7baf203a2335211fc7b4544818Bob Halley port = isc_sockaddr_getport(sa);
70b065bd9297ae7baf203a2335211fc7b4544818Bob Halley addr = new_adbaddrinfo(adb, entry, port);
70b065bd9297ae7baf203a2335211fc7b4544818Bob Halley if (addr != NULL) {
70b065bd9297ae7baf203a2335211fc7b4544818Bob Halley inc_entry_refcnt(adb, entry, ISC_FALSE);
70b065bd9297ae7baf203a2335211fc7b4544818Bob Halley *addrp = addr;
70b065bd9297ae7baf203a2335211fc7b4544818Bob Halley }
70b065bd9297ae7baf203a2335211fc7b4544818Bob Halley
70b065bd9297ae7baf203a2335211fc7b4544818Bob Halley unlock:
4f6dd51441290a9feacbe62991a2cdfdc7554e8bMichael Graff UNLOCK(&adb->entrylocks[bucket]);
4f6dd51441290a9feacbe62991a2cdfdc7554e8bMichael Graff
4f6dd51441290a9feacbe62991a2cdfdc7554e8bMichael Graff return (result);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley}
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleyvoid
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleydns_adb_freeaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **addrp) {
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley dns_adbaddrinfo_t *addr;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley dns_adbentry_t *entry;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley int bucket;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley isc_stdtime_t now;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley isc_boolean_t want_check_exit = ISC_FALSE;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley REQUIRE(DNS_ADB_VALID(adb));
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley REQUIRE(addrp != NULL);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley addr = *addrp;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley REQUIRE(DNS_ADBADDRINFO_VALID(addr));
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley entry = addr->entry;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley REQUIRE(DNS_ADBENTRY_VALID(entry));
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley isc_stdtime_get(&now);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley *addrp = NULL;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley bucket = addr->entry->lock_bucket;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley LOCK(&adb->entrylocks[bucket]);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley entry->expires = now + 1800; /* XXXRTH */
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley dec_entry_refcnt(adb, entry, ISC_FALSE);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if (adb->entry_sd[bucket] && adb->entry_refcnt[bucket] == 0)
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley want_check_exit = ISC_TRUE;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley UNLOCK(&adb->entrylocks[bucket]);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley addr->entry = NULL;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley free_adbaddrinfo(adb, &addr);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if (want_check_exit) {
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley LOCK(&adb->lock);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley check_exit(adb);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley UNLOCK(&adb->lock);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley }
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley}
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleyvoid
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleydns_adb_flush(dns_adb_t *adb) {
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley unsigned int i;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley INSIST(DNS_ADB_VALID(adb));
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley LOCK(&adb->lock);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley for (i = 0; i < NBUCKETS; i++) {
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley /*
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * Call our cleanup routines.
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley */
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley cleanup_names(adb, i, INT_MAX);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley cleanup_entries(adb, i, INT_MAX);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley }
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley#ifdef DUMP_ADB_AFTER_CLEANING
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley dump_adb(adb, stdout, ISC_TRUE);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley#endif
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley UNLOCK(&adb->lock);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley}
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleyvoid
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleydns_adb_flushname(dns_adb_t *adb, dns_name_t *name) {
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley dns_adbname_t *adbname;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley dns_adbname_t *nextname;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley int bucket;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley INSIST(DNS_ADB_VALID(adb));
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley LOCK(&adb->lock);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley bucket = dns_name_hash(name, ISC_FALSE) % NBUCKETS;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley LOCK(&adb->namelocks[bucket]);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley adbname = ISC_LIST_HEAD(adb->names[bucket]);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley while (adbname != NULL) {
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley nextname = ISC_LIST_NEXT(adbname, plink);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if (!NAME_DEAD(adbname) &&
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley dns_name_equal(name, &adbname->name)) {
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley kill_name(&adbname, DNS_EVENT_ADBCANCELED);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley }
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley adbname = nextname;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley }
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley UNLOCK(&adb->namelocks[bucket]);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley UNLOCK(&adb->lock);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley}
static void
water(void *arg, int mark) {
dns_adb_t *adb = arg;
isc_boolean_t overmem = ISC_TF(mark == ISC_MEM_HIWATER);
isc_interval_t interval;
REQUIRE(DNS_ADB_VALID(adb));
DP(1, "adb reached %s water mark", overmem ? "high" : "low");
adb->overmem = overmem;
if (overmem) {
isc_interval_set(&interval, 0, 1);
(void)isc_timer_reset(adb->timer, isc_timertype_once, NULL,
&interval, ISC_TRUE);
}
}
void
dns_adb_setadbsize(dns_adb_t *adb, isc_uint32_t size) {
isc_uint32_t hiwater;
isc_uint32_t lowater;
INSIST(DNS_ADB_VALID(adb));
if (size != 0 && size < DNS_ADB_MINADBSIZE)
size = DNS_ADB_MINADBSIZE;
hiwater = size - (size >> 3); /* Approximately 7/8ths. */
lowater = size - (size >> 2); /* Approximately 3/4ths. */
if (size == 0 || hiwater == 0 || lowater == 0)
isc_mem_setwater(adb->mctx, water, adb, 0, 0);
else
isc_mem_setwater(adb->mctx, water, adb, hiwater, lowater);
}