/contrib/bind9/lib/dns/adb.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 4113 lines · 2943 code · 573 blank · 597 comment · 770 complexity · 4b87144099769830b153bfe500bfa4ea MD5 · raw file

Large files are truncated click here to view the full file

  1. /*
  2. * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
  3. * Copyright (C) 1999-2003 Internet Software Consortium.
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  10. * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  11. * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  12. * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  13. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  14. * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  15. * PERFORMANCE OF THIS SOFTWARE.
  16. */
  17. /* $Id$ */
  18. /*! \file
  19. *
  20. * \note
  21. * In finds, if task == NULL, no events will be generated, and no events
  22. * have been sent. If task != NULL but taskaction == NULL, an event has been
  23. * posted but not yet freed. If neither are NULL, no event was posted.
  24. *
  25. */
  26. #include <config.h>
  27. #include <limits.h>
  28. #include <isc/mutexblock.h>
  29. #include <isc/netaddr.h>
  30. #include <isc/random.h>
  31. #include <isc/stats.h>
  32. #include <isc/string.h> /* Required for HP/UX (and others?) */
  33. #include <isc/task.h>
  34. #include <isc/util.h>
  35. #include <dns/adb.h>
  36. #include <dns/db.h>
  37. #include <dns/events.h>
  38. #include <dns/log.h>
  39. #include <dns/rdata.h>
  40. #include <dns/rdataset.h>
  41. #include <dns/rdatastruct.h>
  42. #include <dns/rdatatype.h>
  43. #include <dns/resolver.h>
  44. #include <dns/result.h>
  45. #include <dns/stats.h>
  46. #define DNS_ADB_MAGIC ISC_MAGIC('D', 'a', 'd', 'b')
  47. #define DNS_ADB_VALID(x) ISC_MAGIC_VALID(x, DNS_ADB_MAGIC)
  48. #define DNS_ADBNAME_MAGIC ISC_MAGIC('a', 'd', 'b', 'N')
  49. #define DNS_ADBNAME_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAME_MAGIC)
  50. #define DNS_ADBNAMEHOOK_MAGIC ISC_MAGIC('a', 'd', 'N', 'H')
  51. #define DNS_ADBNAMEHOOK_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAMEHOOK_MAGIC)
  52. #define DNS_ADBLAMEINFO_MAGIC ISC_MAGIC('a', 'd', 'b', 'Z')
  53. #define DNS_ADBLAMEINFO_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBLAMEINFO_MAGIC)
  54. #define DNS_ADBENTRY_MAGIC ISC_MAGIC('a', 'd', 'b', 'E')
  55. #define DNS_ADBENTRY_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBENTRY_MAGIC)
  56. #define DNS_ADBFETCH_MAGIC ISC_MAGIC('a', 'd', 'F', '4')
  57. #define DNS_ADBFETCH_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFETCH_MAGIC)
  58. #define DNS_ADBFETCH6_MAGIC ISC_MAGIC('a', 'd', 'F', '6')
  59. #define DNS_ADBFETCH6_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFETCH6_MAGIC)
  60. /*!
  61. * For type 3 negative cache entries, we will remember that the address is
  62. * broken for this long. XXXMLG This is also used for actual addresses, too.
  63. * The intent is to keep us from constantly asking about A/AAAA records
  64. * if the zone has extremely low TTLs.
  65. */
  66. #define ADB_CACHE_MINIMUM 10 /*%< seconds */
  67. #define ADB_CACHE_MAXIMUM 86400 /*%< seconds (86400 = 24 hours) */
  68. #define ADB_ENTRY_WINDOW 1800 /*%< seconds */
  69. /*%
  70. * The period in seconds after which an ADB name entry is regarded as stale
  71. * and forced to be cleaned up.
  72. * TODO: This should probably be configurable at run-time.
  73. */
  74. #ifndef ADB_STALE_MARGIN
  75. #define ADB_STALE_MARGIN 1800
  76. #endif
  77. #define FREE_ITEMS 64 /*%< free count for memory pools */
  78. #define FILL_COUNT 16 /*%< fill count for memory pools */
  79. #define DNS_ADB_INVALIDBUCKET (-1) /*%< invalid bucket address */
  80. #define DNS_ADB_MINADBSIZE (1024*1024) /*%< 1 Megabyte */
  81. typedef ISC_LIST(dns_adbname_t) dns_adbnamelist_t;
  82. typedef struct dns_adbnamehook dns_adbnamehook_t;
  83. typedef ISC_LIST(dns_adbnamehook_t) dns_adbnamehooklist_t;
  84. typedef struct dns_adblameinfo dns_adblameinfo_t;
  85. typedef ISC_LIST(dns_adbentry_t) dns_adbentrylist_t;
  86. typedef struct dns_adbfetch dns_adbfetch_t;
  87. typedef struct dns_adbfetch6 dns_adbfetch6_t;
  88. /*% dns adb structure */
  89. struct dns_adb {
  90. unsigned int magic;
  91. isc_mutex_t lock;
  92. isc_mutex_t reflock; /*%< Covers irefcnt, erefcnt */
  93. isc_mutex_t overmemlock; /*%< Covers overmem */
  94. isc_mem_t *mctx;
  95. dns_view_t *view;
  96. isc_taskmgr_t *taskmgr;
  97. isc_task_t *task;
  98. isc_interval_t tick_interval;
  99. int next_cleanbucket;
  100. unsigned int irefcnt;
  101. unsigned int erefcnt;
  102. isc_mutex_t mplock;
  103. isc_mempool_t *nmp; /*%< dns_adbname_t */
  104. isc_mempool_t *nhmp; /*%< dns_adbnamehook_t */
  105. isc_mempool_t *limp; /*%< dns_adblameinfo_t */
  106. isc_mempool_t *emp; /*%< dns_adbentry_t */
  107. isc_mempool_t *ahmp; /*%< dns_adbfind_t */
  108. isc_mempool_t *aimp; /*%< dns_adbaddrinfo_t */
  109. isc_mempool_t *afmp; /*%< dns_adbfetch_t */
  110. /*!
  111. * Bucketized locks and lists for names.
  112. *
  113. * XXXRTH Have a per-bucket structure that contains all of these?
  114. */
  115. unsigned int nnames;
  116. isc_mutex_t namescntlock;
  117. unsigned int namescnt;
  118. dns_adbnamelist_t *names;
  119. dns_adbnamelist_t *deadnames;
  120. isc_mutex_t *namelocks;
  121. isc_boolean_t *name_sd;
  122. unsigned int *name_refcnt;
  123. /*!
  124. * Bucketized locks and lists for entries.
  125. *
  126. * XXXRTH Have a per-bucket structure that contains all of these?
  127. */
  128. unsigned int nentries;
  129. isc_mutex_t entriescntlock;
  130. unsigned int entriescnt;
  131. dns_adbentrylist_t *entries;
  132. dns_adbentrylist_t *deadentries;
  133. isc_mutex_t *entrylocks;
  134. isc_boolean_t *entry_sd; /*%< shutting down */
  135. unsigned int *entry_refcnt;
  136. isc_event_t cevent;
  137. isc_boolean_t cevent_sent;
  138. isc_boolean_t shutting_down;
  139. isc_eventlist_t whenshutdown;
  140. isc_event_t growentries;
  141. isc_boolean_t growentries_sent;
  142. isc_event_t grownames;
  143. isc_boolean_t grownames_sent;
  144. };
  145. /*
  146. * XXXMLG Document these structures.
  147. */
  148. /*% dns_adbname structure */
  149. struct dns_adbname {
  150. unsigned int magic;
  151. dns_name_t name;
  152. dns_adb_t *adb;
  153. unsigned int partial_result;
  154. unsigned int flags;
  155. int lock_bucket;
  156. dns_name_t target;
  157. isc_stdtime_t expire_target;
  158. isc_stdtime_t expire_v4;
  159. isc_stdtime_t expire_v6;
  160. unsigned int chains;
  161. dns_adbnamehooklist_t v4;
  162. dns_adbnamehooklist_t v6;
  163. dns_adbfetch_t *fetch_a;
  164. dns_adbfetch_t *fetch_aaaa;
  165. unsigned int fetch_err;
  166. unsigned int fetch6_err;
  167. dns_adbfindlist_t finds;
  168. /* for LRU-based management */
  169. isc_stdtime_t last_used;
  170. ISC_LINK(dns_adbname_t) plink;
  171. };
  172. /*% The adbfetch structure */
  173. struct dns_adbfetch {
  174. unsigned int magic;
  175. dns_fetch_t *fetch;
  176. dns_rdataset_t rdataset;
  177. };
  178. /*%
  179. * This is a small widget that dangles off a dns_adbname_t. It contains a
  180. * pointer to the address information about this host, and a link to the next
  181. * namehook that will contain the next address this host has.
  182. */
  183. struct dns_adbnamehook {
  184. unsigned int magic;
  185. dns_adbentry_t *entry;
  186. ISC_LINK(dns_adbnamehook_t) plink;
  187. };
  188. /*%
  189. * This is a small widget that holds qname-specific information about an
  190. * address. Currently limited to lameness, but could just as easily be
  191. * extended to other types of information about zones.
  192. */
  193. struct dns_adblameinfo {
  194. unsigned int magic;
  195. dns_name_t qname;
  196. dns_rdatatype_t qtype;
  197. isc_stdtime_t lame_timer;
  198. ISC_LINK(dns_adblameinfo_t) plink;
  199. };
  200. /*%
  201. * An address entry. It holds quite a bit of information about addresses,
  202. * including edns state (in "flags"), rtt, and of course the address of
  203. * the host.
  204. */
  205. struct dns_adbentry {
  206. unsigned int magic;
  207. int lock_bucket;
  208. unsigned int refcnt;
  209. unsigned int flags;
  210. unsigned int srtt;
  211. isc_sockaddr_t sockaddr;
  212. isc_stdtime_t expires;
  213. /*%<
  214. * A nonzero 'expires' field indicates that the entry should
  215. * persist until that time. This allows entries found
  216. * using dns_adb_findaddrinfo() to persist for a limited time
  217. * even though they are not necessarily associated with a
  218. * name.
  219. */
  220. ISC_LIST(dns_adblameinfo_t) lameinfo;
  221. ISC_LINK(dns_adbentry_t) plink;
  222. };
  223. /*
  224. * Internal functions (and prototypes).
  225. */
  226. static inline dns_adbname_t *new_adbname(dns_adb_t *, dns_name_t *);
  227. static inline void free_adbname(dns_adb_t *, dns_adbname_t **);
  228. static inline dns_adbnamehook_t *new_adbnamehook(dns_adb_t *,
  229. dns_adbentry_t *);
  230. static inline void free_adbnamehook(dns_adb_t *, dns_adbnamehook_t **);
  231. static inline dns_adblameinfo_t *new_adblameinfo(dns_adb_t *, dns_name_t *,
  232. dns_rdatatype_t);
  233. static inline void free_adblameinfo(dns_adb_t *, dns_adblameinfo_t **);
  234. static inline dns_adbentry_t *new_adbentry(dns_adb_t *);
  235. static inline void free_adbentry(dns_adb_t *, dns_adbentry_t **);
  236. static inline dns_adbfind_t *new_adbfind(dns_adb_t *);
  237. static inline isc_boolean_t free_adbfind(dns_adb_t *, dns_adbfind_t **);
  238. static inline dns_adbaddrinfo_t *new_adbaddrinfo(dns_adb_t *, dns_adbentry_t *,
  239. in_port_t);
  240. static inline dns_adbfetch_t *new_adbfetch(dns_adb_t *);
  241. static inline void free_adbfetch(dns_adb_t *, dns_adbfetch_t **);
  242. static inline dns_adbname_t *find_name_and_lock(dns_adb_t *, dns_name_t *,
  243. unsigned int, int *);
  244. static inline dns_adbentry_t *find_entry_and_lock(dns_adb_t *,
  245. isc_sockaddr_t *, int *,
  246. isc_stdtime_t);
  247. static void dump_adb(dns_adb_t *, FILE *, isc_boolean_t debug, isc_stdtime_t);
  248. static void print_dns_name(FILE *, dns_name_t *);
  249. static void print_namehook_list(FILE *, const char *legend,
  250. dns_adbnamehooklist_t *list,
  251. isc_boolean_t debug,
  252. isc_stdtime_t now);
  253. static void print_find_list(FILE *, dns_adbname_t *);
  254. static void print_fetch_list(FILE *, dns_adbname_t *);
  255. static inline isc_boolean_t dec_adb_irefcnt(dns_adb_t *);
  256. static inline void inc_adb_irefcnt(dns_adb_t *);
  257. static inline void inc_adb_erefcnt(dns_adb_t *);
  258. static inline void inc_entry_refcnt(dns_adb_t *, dns_adbentry_t *,
  259. isc_boolean_t);
  260. static inline isc_boolean_t dec_entry_refcnt(dns_adb_t *, isc_boolean_t,
  261. dns_adbentry_t *, isc_boolean_t);
  262. static inline void violate_locking_hierarchy(isc_mutex_t *, isc_mutex_t *);
  263. static isc_boolean_t clean_namehooks(dns_adb_t *, dns_adbnamehooklist_t *);
  264. static void clean_target(dns_adb_t *, dns_name_t *);
  265. static void clean_finds_at_name(dns_adbname_t *, isc_eventtype_t,
  266. unsigned int);
  267. static isc_boolean_t check_expire_namehooks(dns_adbname_t *, isc_stdtime_t);
  268. static isc_boolean_t check_expire_entry(dns_adb_t *, dns_adbentry_t **,
  269. isc_stdtime_t);
  270. static void cancel_fetches_at_name(dns_adbname_t *);
  271. static isc_result_t dbfind_name(dns_adbname_t *, isc_stdtime_t,
  272. dns_rdatatype_t);
  273. static isc_result_t fetch_name(dns_adbname_t *, isc_boolean_t,
  274. dns_rdatatype_t);
  275. static inline void check_exit(dns_adb_t *);
  276. static void destroy(dns_adb_t *);
  277. static isc_boolean_t shutdown_names(dns_adb_t *);
  278. static isc_boolean_t shutdown_entries(dns_adb_t *);
  279. static inline void link_name(dns_adb_t *, int, dns_adbname_t *);
  280. static inline isc_boolean_t unlink_name(dns_adb_t *, dns_adbname_t *);
  281. static inline void link_entry(dns_adb_t *, int, dns_adbentry_t *);
  282. static inline isc_boolean_t unlink_entry(dns_adb_t *, dns_adbentry_t *);
  283. static isc_boolean_t kill_name(dns_adbname_t **, isc_eventtype_t);
  284. static void water(void *, int);
  285. static void dump_entry(FILE *, dns_adbentry_t *, isc_boolean_t, isc_stdtime_t);
  286. /*
  287. * MUST NOT overlap DNS_ADBFIND_* flags!
  288. */
  289. #define FIND_EVENT_SENT 0x40000000
  290. #define FIND_EVENT_FREED 0x80000000
  291. #define FIND_EVENTSENT(h) (((h)->flags & FIND_EVENT_SENT) != 0)
  292. #define FIND_EVENTFREED(h) (((h)->flags & FIND_EVENT_FREED) != 0)
  293. #define NAME_NEEDS_POKE 0x80000000
  294. #define NAME_IS_DEAD 0x40000000
  295. #define NAME_HINT_OK DNS_ADBFIND_HINTOK
  296. #define NAME_GLUE_OK DNS_ADBFIND_GLUEOK
  297. #define NAME_STARTATZONE DNS_ADBFIND_STARTATZONE
  298. #define NAME_DEAD(n) (((n)->flags & NAME_IS_DEAD) != 0)
  299. #define NAME_NEEDSPOKE(n) (((n)->flags & NAME_NEEDS_POKE) != 0)
  300. #define NAME_GLUEOK(n) (((n)->flags & NAME_GLUE_OK) != 0)
  301. #define NAME_HINTOK(n) (((n)->flags & NAME_HINT_OK) != 0)
  302. /*
  303. * Private flag(s) for entries.
  304. * MUST NOT overlap FCTX_ADDRINFO_xxx and DNS_FETCHOPT_NOEDNS0.
  305. */
  306. #define ENTRY_IS_DEAD 0x80000000
  307. /*
  308. * To the name, address classes are all that really exist. If it has a
  309. * V6 address it doesn't care if it came from a AAAA query.
  310. */
  311. #define NAME_HAS_V4(n) (!ISC_LIST_EMPTY((n)->v4))
  312. #define NAME_HAS_V6(n) (!ISC_LIST_EMPTY((n)->v6))
  313. #define NAME_HAS_ADDRS(n) (NAME_HAS_V4(n) || NAME_HAS_V6(n))
  314. /*
  315. * Fetches are broken out into A and AAAA types. In some cases,
  316. * however, it makes more sense to test for a particular class of fetches,
  317. * like V4 or V6 above.
  318. * Note: since we have removed the support of A6 in adb, FETCH_A and FETCH_AAAA
  319. * are now equal to FETCH_V4 and FETCH_V6, respectively.
  320. */
  321. #define NAME_FETCH_A(n) ((n)->fetch_a != NULL)
  322. #define NAME_FETCH_AAAA(n) ((n)->fetch_aaaa != NULL)
  323. #define NAME_FETCH_V4(n) (NAME_FETCH_A(n))
  324. #define NAME_FETCH_V6(n) (NAME_FETCH_AAAA(n))
  325. #define NAME_FETCH(n) (NAME_FETCH_V4(n) || NAME_FETCH_V6(n))
  326. /*
  327. * Find options and tests to see if there are addresses on the list.
  328. */
  329. #define FIND_WANTEVENT(fn) (((fn)->options & DNS_ADBFIND_WANTEVENT) != 0)
  330. #define FIND_WANTEMPTYEVENT(fn) (((fn)->options & DNS_ADBFIND_EMPTYEVENT) != 0)
  331. #define FIND_AVOIDFETCHES(fn) (((fn)->options & DNS_ADBFIND_AVOIDFETCHES) \
  332. != 0)
  333. #define FIND_STARTATZONE(fn) (((fn)->options & DNS_ADBFIND_STARTATZONE) \
  334. != 0)
  335. #define FIND_HINTOK(fn) (((fn)->options & DNS_ADBFIND_HINTOK) != 0)
  336. #define FIND_GLUEOK(fn) (((fn)->options & DNS_ADBFIND_GLUEOK) != 0)
  337. #define FIND_HAS_ADDRS(fn) (!ISC_LIST_EMPTY((fn)->list))
  338. #define FIND_RETURNLAME(fn) (((fn)->options & DNS_ADBFIND_RETURNLAME) != 0)
  339. /*
  340. * These are currently used on simple unsigned ints, so they are
  341. * not really associated with any particular type.
  342. */
  343. #define WANT_INET(x) (((x) & DNS_ADBFIND_INET) != 0)
  344. #define WANT_INET6(x) (((x) & DNS_ADBFIND_INET6) != 0)
  345. #define EXPIRE_OK(exp, now) ((exp == INT_MAX) || (exp < now))
  346. /*
  347. * Find out if the flags on a name (nf) indicate if it is a hint or
  348. * glue, and compare this to the appropriate bits set in o, to see if
  349. * this is ok.
  350. */
  351. #define GLUE_OK(nf, o) (!NAME_GLUEOK(nf) || (((o) & DNS_ADBFIND_GLUEOK) != 0))
  352. #define HINT_OK(nf, o) (!NAME_HINTOK(nf) || (((o) & DNS_ADBFIND_HINTOK) != 0))
  353. #define GLUEHINT_OK(nf, o) (GLUE_OK(nf, o) || HINT_OK(nf, o))
  354. #define STARTATZONE_MATCHES(nf, o) (((nf)->flags & NAME_STARTATZONE) == \
  355. ((o) & DNS_ADBFIND_STARTATZONE))
  356. #define ENTER_LEVEL ISC_LOG_DEBUG(50)
  357. #define EXIT_LEVEL ENTER_LEVEL
  358. #define CLEAN_LEVEL ISC_LOG_DEBUG(100)
  359. #define DEF_LEVEL ISC_LOG_DEBUG(5)
  360. #define NCACHE_LEVEL ISC_LOG_DEBUG(20)
  361. #define NCACHE_RESULT(r) ((r) == DNS_R_NCACHENXDOMAIN || \
  362. (r) == DNS_R_NCACHENXRRSET)
  363. #define AUTH_NX(r) ((r) == DNS_R_NXDOMAIN || \
  364. (r) == DNS_R_NXRRSET)
  365. #define NXDOMAIN_RESULT(r) ((r) == DNS_R_NXDOMAIN || \
  366. (r) == DNS_R_NCACHENXDOMAIN)
  367. #define NXRRSET_RESULT(r) ((r) == DNS_R_NCACHENXRRSET || \
  368. (r) == DNS_R_NXRRSET || \
  369. (r) == DNS_R_HINTNXRRSET)
  370. /*
  371. * Error state rankings.
  372. */
  373. #define FIND_ERR_SUCCESS 0 /* highest rank */
  374. #define FIND_ERR_CANCELED 1
  375. #define FIND_ERR_FAILURE 2
  376. #define FIND_ERR_NXDOMAIN 3
  377. #define FIND_ERR_NXRRSET 4
  378. #define FIND_ERR_UNEXPECTED 5
  379. #define FIND_ERR_NOTFOUND 6
  380. #define FIND_ERR_MAX 7
  381. static const char *errnames[] = {
  382. "success",
  383. "canceled",
  384. "failure",
  385. "nxdomain",
  386. "nxrrset",
  387. "unexpected",
  388. "not_found"
  389. };
  390. #define NEWERR(old, new) (ISC_MIN((old), (new)))
  391. static isc_result_t find_err_map[FIND_ERR_MAX] = {
  392. ISC_R_SUCCESS,
  393. ISC_R_CANCELED,
  394. ISC_R_FAILURE,
  395. DNS_R_NXDOMAIN,
  396. DNS_R_NXRRSET,
  397. ISC_R_UNEXPECTED,
  398. ISC_R_NOTFOUND /* not YET found */
  399. };
  400. static void
  401. DP(int level, const char *format, ...) ISC_FORMAT_PRINTF(2, 3);
  402. static void
  403. DP(int level, const char *format, ...) {
  404. va_list args;
  405. va_start(args, format);
  406. isc_log_vwrite(dns_lctx,
  407. DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ADB,
  408. level, format, args);
  409. va_end(args);
  410. }
  411. /*%
  412. * Increment resolver-related statistics counters.
  413. */
  414. static inline void
  415. inc_stats(dns_adb_t *adb, isc_statscounter_t counter) {
  416. if (adb->view->resstats != NULL)
  417. isc_stats_increment(adb->view->resstats, counter);
  418. }
  419. static inline dns_ttl_t
  420. ttlclamp(dns_ttl_t ttl) {
  421. if (ttl < ADB_CACHE_MINIMUM)
  422. ttl = ADB_CACHE_MINIMUM;
  423. if (ttl > ADB_CACHE_MAXIMUM)
  424. ttl = ADB_CACHE_MAXIMUM;
  425. return (ttl);
  426. }
  427. /*
  428. * Hashing is most efficient if the number of buckets is prime.
  429. * The sequence below is the closest previous primes to 2^n and
  430. * 1.5 * 2^n, for values of n from 10 to 28. (The tables will
  431. * no longer grow beyond 2^28 entries.)
  432. */
  433. static const unsigned nbuckets[] = { 1021, 1531, 2039, 3067, 4093, 6143,
  434. 8191, 12281, 16381, 24571, 32749,
  435. 49193, 65521, 98299, 131071, 199603,
  436. 262139, 393209, 524287, 768431, 1048573,
  437. 1572853, 2097143, 3145721, 4194301,
  438. 6291449, 8388593, 12582893, 16777213,
  439. 25165813, 33554393, 50331599, 67108859,
  440. 100663291, 134217689, 201326557,
  441. 268535431, 0 };
  442. static void
  443. grow_entries(isc_task_t *task, isc_event_t *ev) {
  444. dns_adb_t *adb;
  445. dns_adbentry_t *e;
  446. dns_adbentrylist_t *newdeadentries = NULL;
  447. dns_adbentrylist_t *newentries = NULL;
  448. isc_boolean_t *newentry_sd = NULL;
  449. isc_mutex_t *newentrylocks = NULL;
  450. isc_result_t result;
  451. unsigned int *newentry_refcnt = NULL;
  452. unsigned int i, n, bucket;
  453. adb = ev->ev_arg;
  454. INSIST(DNS_ADB_VALID(adb));
  455. isc_event_free(&ev);
  456. isc_task_beginexclusive(task);
  457. i = 0;
  458. while (nbuckets[i] != 0 && adb->nentries >= nbuckets[i])
  459. i++;
  460. if (nbuckets[i] != 0)
  461. n = nbuckets[i];
  462. else
  463. goto done;
  464. DP(ISC_LOG_INFO, "adb: grow_entries to %u starting", n);
  465. /*
  466. * Are we shutting down?
  467. */
  468. for (i = 0; i < adb->nentries; i++)
  469. if (adb->entry_sd[i])
  470. goto cleanup;
  471. /*
  472. * Grab all the resources we need.
  473. */
  474. newentries = isc_mem_get(adb->mctx, sizeof(*newentries) * n);
  475. newdeadentries = isc_mem_get(adb->mctx, sizeof(*newdeadentries) * n);
  476. newentrylocks = isc_mem_get(adb->mctx, sizeof(*newentrylocks) * n);
  477. newentry_sd = isc_mem_get(adb->mctx, sizeof(*newentry_sd) * n);
  478. newentry_refcnt = isc_mem_get(adb->mctx, sizeof(*newentry_refcnt) * n);
  479. if (newentries == NULL || newdeadentries == NULL ||
  480. newentrylocks == NULL || newentry_sd == NULL ||
  481. newentry_refcnt == NULL)
  482. goto cleanup;
  483. /*
  484. * Initialise the new resources.
  485. */
  486. result = isc_mutexblock_init(newentrylocks, n);
  487. if (result != ISC_R_SUCCESS)
  488. goto cleanup;
  489. for (i = 0; i < n; i++) {
  490. ISC_LIST_INIT(newentries[i]);
  491. ISC_LIST_INIT(newdeadentries[i]);
  492. newentry_sd[i] = ISC_FALSE;
  493. newentry_refcnt[i] = 0;
  494. adb->irefcnt++;
  495. }
  496. /*
  497. * Move entries to new arrays.
  498. */
  499. for (i = 0; i < adb->nentries; i++) {
  500. e = ISC_LIST_HEAD(adb->entries[i]);
  501. while (e != NULL) {
  502. ISC_LIST_UNLINK(adb->entries[i], e, plink);
  503. bucket = isc_sockaddr_hash(&e->sockaddr, ISC_TRUE) % n;
  504. e->lock_bucket = bucket;
  505. ISC_LIST_APPEND(newentries[bucket], e, plink);
  506. INSIST(adb->entry_refcnt[i] > 0);
  507. adb->entry_refcnt[i]--;
  508. newentry_refcnt[bucket]++;
  509. e = ISC_LIST_HEAD(adb->entries[i]);
  510. }
  511. e = ISC_LIST_HEAD(adb->deadentries[i]);
  512. while (e != NULL) {
  513. ISC_LIST_UNLINK(adb->deadentries[i], e, plink);
  514. bucket = isc_sockaddr_hash(&e->sockaddr, ISC_TRUE) % n;
  515. e->lock_bucket = bucket;
  516. ISC_LIST_APPEND(newdeadentries[bucket], e, plink);
  517. INSIST(adb->entry_refcnt[i] > 0);
  518. adb->entry_refcnt[i]--;
  519. newentry_refcnt[bucket]++;
  520. e = ISC_LIST_HEAD(adb->deadentries[i]);
  521. }
  522. INSIST(adb->entry_refcnt[i] == 0);
  523. adb->irefcnt--;
  524. }
  525. /*
  526. * Cleanup old resources.
  527. */
  528. DESTROYMUTEXBLOCK(adb->entrylocks, adb->nentries);
  529. isc_mem_put(adb->mctx, adb->entries,
  530. sizeof(*adb->entries) * adb->nentries);
  531. isc_mem_put(adb->mctx, adb->deadentries,
  532. sizeof(*adb->deadentries) * adb->nentries);
  533. isc_mem_put(adb->mctx, adb->entrylocks,
  534. sizeof(*adb->entrylocks) * adb->nentries);
  535. isc_mem_put(adb->mctx, adb->entry_sd,
  536. sizeof(*adb->entry_sd) * adb->nentries);
  537. isc_mem_put(adb->mctx, adb->entry_refcnt,
  538. sizeof(*adb->entry_refcnt) * adb->nentries);
  539. /*
  540. * Install new resources.
  541. */
  542. adb->entries = newentries;
  543. adb->deadentries = newdeadentries;
  544. adb->entrylocks = newentrylocks;
  545. adb->entry_sd = newentry_sd;
  546. adb->entry_refcnt = newentry_refcnt;
  547. adb->nentries = n;
  548. /*
  549. * Only on success do we set adb->growentries_sent to ISC_FALSE.
  550. * This will prevent us being continuously being called on error.
  551. */
  552. adb->growentries_sent = ISC_FALSE;
  553. goto done;
  554. cleanup:
  555. if (newentries != NULL)
  556. isc_mem_put(adb->mctx, newentries,
  557. sizeof(*newentries) * n);
  558. if (newdeadentries != NULL)
  559. isc_mem_put(adb->mctx, newdeadentries,
  560. sizeof(*newdeadentries) * n);
  561. if (newentrylocks != NULL)
  562. isc_mem_put(adb->mctx, newentrylocks,
  563. sizeof(*newentrylocks) * n);
  564. if (newentry_sd != NULL)
  565. isc_mem_put(adb->mctx, newentry_sd,
  566. sizeof(*newentry_sd) * n);
  567. if (newentry_refcnt != NULL)
  568. isc_mem_put(adb->mctx, newentry_refcnt,
  569. sizeof(*newentry_refcnt) * n);
  570. done:
  571. isc_task_endexclusive(task);
  572. LOCK(&adb->lock);
  573. if (dec_adb_irefcnt(adb))
  574. check_exit(adb);
  575. UNLOCK(&adb->lock);
  576. DP(ISC_LOG_INFO, "adb: grow_entries finished");
  577. }
  578. static void
  579. grow_names(isc_task_t *task, isc_event_t *ev) {
  580. dns_adb_t *adb;
  581. dns_adbname_t *name;
  582. dns_adbnamelist_t *newdeadnames = NULL;
  583. dns_adbnamelist_t *newnames = NULL;
  584. isc_boolean_t *newname_sd = NULL;
  585. isc_mutex_t *newnamelocks = NULL;
  586. isc_result_t result;
  587. unsigned int *newname_refcnt = NULL;
  588. unsigned int i, n, bucket;
  589. adb = ev->ev_arg;
  590. INSIST(DNS_ADB_VALID(adb));
  591. isc_event_free(&ev);
  592. isc_task_beginexclusive(task);
  593. i = 0;
  594. while (nbuckets[i] != 0 && adb->nnames >= nbuckets[i])
  595. i++;
  596. if (nbuckets[i] != 0)
  597. n = nbuckets[i];
  598. else
  599. goto done;
  600. DP(ISC_LOG_INFO, "adb: grow_names to %u starting", n);
  601. /*
  602. * Are we shutting down?
  603. */
  604. for (i = 0; i < adb->nnames; i++)
  605. if (adb->name_sd[i])
  606. goto cleanup;
  607. /*
  608. * Grab all the resources we need.
  609. */
  610. newnames = isc_mem_get(adb->mctx, sizeof(*newnames) * n);
  611. newdeadnames = isc_mem_get(adb->mctx, sizeof(*newdeadnames) * n);
  612. newnamelocks = isc_mem_get(adb->mctx, sizeof(*newnamelocks) * n);
  613. newname_sd = isc_mem_get(adb->mctx, sizeof(*newname_sd) * n);
  614. newname_refcnt = isc_mem_get(adb->mctx, sizeof(*newname_refcnt) * n);
  615. if (newnames == NULL || newdeadnames == NULL ||
  616. newnamelocks == NULL || newname_sd == NULL ||
  617. newname_refcnt == NULL)
  618. goto cleanup;
  619. /*
  620. * Initialise the new resources.
  621. */
  622. result = isc_mutexblock_init(newnamelocks, n);
  623. if (result != ISC_R_SUCCESS)
  624. goto cleanup;
  625. for (i = 0; i < n; i++) {
  626. ISC_LIST_INIT(newnames[i]);
  627. ISC_LIST_INIT(newdeadnames[i]);
  628. newname_sd[i] = ISC_FALSE;
  629. newname_refcnt[i] = 0;
  630. adb->irefcnt++;
  631. }
  632. /*
  633. * Move names to new arrays.
  634. */
  635. for (i = 0; i < adb->nnames; i++) {
  636. name = ISC_LIST_HEAD(adb->names[i]);
  637. while (name != NULL) {
  638. ISC_LIST_UNLINK(adb->names[i], name, plink);
  639. bucket = dns_name_fullhash(&name->name, ISC_TRUE) % n;
  640. name->lock_bucket = bucket;
  641. ISC_LIST_APPEND(newnames[bucket], name, plink);
  642. INSIST(adb->name_refcnt[i] > 0);
  643. adb->name_refcnt[i]--;
  644. newname_refcnt[bucket]++;
  645. name = ISC_LIST_HEAD(adb->names[i]);
  646. }
  647. name = ISC_LIST_HEAD(adb->deadnames[i]);
  648. while (name != NULL) {
  649. ISC_LIST_UNLINK(adb->deadnames[i], name, plink);
  650. bucket = dns_name_fullhash(&name->name, ISC_TRUE) % n;
  651. name->lock_bucket = bucket;
  652. ISC_LIST_APPEND(newdeadnames[bucket], name, plink);
  653. INSIST(adb->name_refcnt[i] > 0);
  654. adb->name_refcnt[i]--;
  655. newname_refcnt[bucket]++;
  656. name = ISC_LIST_HEAD(adb->deadnames[i]);
  657. }
  658. INSIST(adb->name_refcnt[i] == 0);
  659. adb->irefcnt--;
  660. }
  661. /*
  662. * Cleanup old resources.
  663. */
  664. DESTROYMUTEXBLOCK(adb->namelocks, adb->nnames);
  665. isc_mem_put(adb->mctx, adb->names,
  666. sizeof(*adb->names) * adb->nnames);
  667. isc_mem_put(adb->mctx, adb->deadnames,
  668. sizeof(*adb->deadnames) * adb->nnames);
  669. isc_mem_put(adb->mctx, adb->namelocks,
  670. sizeof(*adb->namelocks) * adb->nnames);
  671. isc_mem_put(adb->mctx, adb->name_sd,
  672. sizeof(*adb->name_sd) * adb->nnames);
  673. isc_mem_put(adb->mctx, adb->name_refcnt,
  674. sizeof(*adb->name_refcnt) * adb->nnames);
  675. /*
  676. * Install new resources.
  677. */
  678. adb->names = newnames;
  679. adb->deadnames = newdeadnames;
  680. adb->namelocks = newnamelocks;
  681. adb->name_sd = newname_sd;
  682. adb->name_refcnt = newname_refcnt;
  683. adb->nnames = n;
  684. /*
  685. * Only on success do we set adb->grownames_sent to ISC_FALSE.
  686. * This will prevent us being continuously being called on error.
  687. */
  688. adb->grownames_sent = ISC_FALSE;
  689. goto done;
  690. cleanup:
  691. if (newnames != NULL)
  692. isc_mem_put(adb->mctx, newnames, sizeof(*newnames) * n);
  693. if (newdeadnames != NULL)
  694. isc_mem_put(adb->mctx, newdeadnames, sizeof(*newdeadnames) * n);
  695. if (newnamelocks != NULL)
  696. isc_mem_put(adb->mctx, newnamelocks, sizeof(*newnamelocks) * n);
  697. if (newname_sd != NULL)
  698. isc_mem_put(adb->mctx, newname_sd, sizeof(*newname_sd) * n);
  699. if (newname_refcnt != NULL)
  700. isc_mem_put(adb->mctx, newname_refcnt,
  701. sizeof(*newname_refcnt) * n);
  702. done:
  703. isc_task_endexclusive(task);
  704. LOCK(&adb->lock);
  705. if (dec_adb_irefcnt(adb))
  706. check_exit(adb);
  707. UNLOCK(&adb->lock);
  708. DP(ISC_LOG_INFO, "adb: grow_names finished");
  709. }
  710. /*
  711. * Requires the adbname bucket be locked and that no entry buckets be locked.
  712. *
  713. * This code handles A and AAAA rdatasets only.
  714. */
  715. static isc_result_t
  716. import_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset,
  717. isc_stdtime_t now)
  718. {
  719. isc_result_t result;
  720. dns_adb_t *adb;
  721. dns_adbnamehook_t *nh;
  722. dns_adbnamehook_t *anh;
  723. dns_rdata_t rdata = DNS_RDATA_INIT;
  724. struct in_addr ina;
  725. struct in6_addr in6a;
  726. isc_sockaddr_t sockaddr;
  727. dns_adbentry_t *foundentry; /* NO CLEAN UP! */
  728. int addr_bucket;
  729. isc_boolean_t new_addresses_added;
  730. dns_rdatatype_t rdtype;
  731. unsigned int findoptions;
  732. dns_adbnamehooklist_t *hookhead;
  733. INSIST(DNS_ADBNAME_VALID(adbname));
  734. adb = adbname->adb;
  735. INSIST(DNS_ADB_VALID(adb));
  736. rdtype = rdataset->type;
  737. INSIST((rdtype == dns_rdatatype_a) || (rdtype == dns_rdatatype_aaaa));
  738. if (rdtype == dns_rdatatype_a)
  739. findoptions = DNS_ADBFIND_INET;
  740. else
  741. findoptions = DNS_ADBFIND_INET6;
  742. addr_bucket = DNS_ADB_INVALIDBUCKET;
  743. new_addresses_added = ISC_FALSE;
  744. nh = NULL;
  745. result = dns_rdataset_first(rdataset);
  746. while (result == ISC_R_SUCCESS) {
  747. dns_rdata_reset(&rdata);
  748. dns_rdataset_current(rdataset, &rdata);
  749. if (rdtype == dns_rdatatype_a) {
  750. INSIST(rdata.length == 4);
  751. memcpy(&ina.s_addr, rdata.data, 4);
  752. isc_sockaddr_fromin(&sockaddr, &ina, 0);
  753. hookhead = &adbname->v4;
  754. } else {
  755. INSIST(rdata.length == 16);
  756. memcpy(in6a.s6_addr, rdata.data, 16);
  757. isc_sockaddr_fromin6(&sockaddr, &in6a, 0);
  758. hookhead = &adbname->v6;
  759. }
  760. INSIST(nh == NULL);
  761. nh = new_adbnamehook(adb, NULL);
  762. if (nh == NULL) {
  763. adbname->partial_result |= findoptions;
  764. result = ISC_R_NOMEMORY;
  765. goto fail;
  766. }
  767. foundentry = find_entry_and_lock(adb, &sockaddr, &addr_bucket,
  768. now);
  769. if (foundentry == NULL) {
  770. dns_adbentry_t *entry;
  771. entry = new_adbentry(adb);
  772. if (entry == NULL) {
  773. adbname->partial_result |= findoptions;
  774. result = ISC_R_NOMEMORY;
  775. goto fail;
  776. }
  777. entry->sockaddr = sockaddr;
  778. entry->refcnt = 1;
  779. nh->entry = entry;
  780. link_entry(adb, addr_bucket, entry);
  781. } else {
  782. for (anh = ISC_LIST_HEAD(*hookhead);
  783. anh != NULL;
  784. anh = ISC_LIST_NEXT(anh, plink))
  785. if (anh->entry == foundentry)
  786. break;
  787. if (anh == NULL) {
  788. foundentry->refcnt++;
  789. nh->entry = foundentry;
  790. } else
  791. free_adbnamehook(adb, &nh);
  792. }
  793. new_addresses_added = ISC_TRUE;
  794. if (nh != NULL)
  795. ISC_LIST_APPEND(*hookhead, nh, plink);
  796. nh = NULL;
  797. result = dns_rdataset_next(rdataset);
  798. }
  799. fail:
  800. if (nh != NULL)
  801. free_adbnamehook(adb, &nh);
  802. if (addr_bucket != DNS_ADB_INVALIDBUCKET)
  803. UNLOCK(&adb->entrylocks[addr_bucket]);
  804. if (rdataset->trust == dns_trust_glue ||
  805. rdataset->trust == dns_trust_additional)
  806. rdataset->ttl = ADB_CACHE_MINIMUM;
  807. else if (rdataset->trust == dns_trust_ultimate)
  808. rdataset->ttl = 0;
  809. else
  810. rdataset->ttl = ttlclamp(rdataset->ttl);
  811. if (rdtype == dns_rdatatype_a) {
  812. DP(NCACHE_LEVEL, "expire_v4 set to MIN(%u,%u) import_rdataset",
  813. adbname->expire_v4, now + rdataset->ttl);
  814. adbname->expire_v4 = ISC_MIN(adbname->expire_v4,
  815. now + rdataset->ttl);
  816. } else {
  817. DP(NCACHE_LEVEL, "expire_v6 set to MIN(%u,%u) import_rdataset",
  818. adbname->expire_v6, now + rdataset->ttl);
  819. adbname->expire_v6 = ISC_MIN(adbname->expire_v6,
  820. now + rdataset->ttl);
  821. }
  822. if (new_addresses_added) {
  823. /*
  824. * Lie a little here. This is more or less so code that cares
  825. * can find out if any new information was added or not.
  826. */
  827. return (ISC_R_SUCCESS);
  828. }
  829. return (result);
  830. }
  831. /*
  832. * Requires the name's bucket be locked.
  833. */
  834. static isc_boolean_t
  835. kill_name(dns_adbname_t **n, isc_eventtype_t ev) {
  836. dns_adbname_t *name;
  837. isc_boolean_t result = ISC_FALSE;
  838. isc_boolean_t result4, result6;
  839. int bucket;
  840. dns_adb_t *adb;
  841. INSIST(n != NULL);
  842. name = *n;
  843. *n = NULL;
  844. INSIST(DNS_ADBNAME_VALID(name));
  845. adb = name->adb;
  846. INSIST(DNS_ADB_VALID(adb));
  847. DP(DEF_LEVEL, "killing name %p", name);
  848. /*
  849. * If we're dead already, just check to see if we should go
  850. * away now or not.
  851. */
  852. if (NAME_DEAD(name) && !NAME_FETCH(name)) {
  853. result = unlink_name(adb, name);
  854. free_adbname(adb, &name);
  855. if (result)
  856. result = dec_adb_irefcnt(adb);
  857. return (result);
  858. }
  859. /*
  860. * Clean up the name's various lists. These two are destructive
  861. * in that they will always empty the list.
  862. */
  863. clean_finds_at_name(name, ev, DNS_ADBFIND_ADDRESSMASK);
  864. result4 = clean_namehooks(adb, &name->v4);
  865. result6 = clean_namehooks(adb, &name->v6);
  866. clean_target(adb, &name->target);
  867. result = ISC_TF(result4 || result6);
  868. /*
  869. * If fetches are running, cancel them. If none are running, we can
  870. * just kill the name here.
  871. */
  872. if (!NAME_FETCH(name)) {
  873. INSIST(result == ISC_FALSE);
  874. result = unlink_name(adb, name);
  875. free_adbname(adb, &name);
  876. if (result)
  877. result = dec_adb_irefcnt(adb);
  878. } else {
  879. cancel_fetches_at_name(name);
  880. if (!NAME_DEAD(name)) {
  881. bucket = name->lock_bucket;
  882. ISC_LIST_UNLINK(adb->names[bucket], name, plink);
  883. ISC_LIST_APPEND(adb->deadnames[bucket], name, plink);
  884. name->flags |= NAME_IS_DEAD;
  885. }
  886. }
  887. return (result);
  888. }
  889. /*
  890. * Requires the name's bucket be locked and no entry buckets be locked.
  891. */
  892. static isc_boolean_t
  893. check_expire_namehooks(dns_adbname_t *name, isc_stdtime_t now) {
  894. dns_adb_t *adb;
  895. isc_boolean_t result4 = ISC_FALSE;
  896. isc_boolean_t result6 = ISC_FALSE;
  897. INSIST(DNS_ADBNAME_VALID(name));
  898. adb = name->adb;
  899. INSIST(DNS_ADB_VALID(adb));
  900. /*
  901. * Check to see if we need to remove the v4 addresses
  902. */
  903. if (!NAME_FETCH_V4(name) && EXPIRE_OK(name->expire_v4, now)) {
  904. if (NAME_HAS_V4(name)) {
  905. DP(DEF_LEVEL, "expiring v4 for name %p", name);
  906. result4 = clean_namehooks(adb, &name->v4);
  907. name->partial_result &= ~DNS_ADBFIND_INET;
  908. }
  909. name->expire_v4 = INT_MAX;
  910. name->fetch_err = FIND_ERR_UNEXPECTED;
  911. }
  912. /*
  913. * Check to see if we need to remove the v6 addresses
  914. */
  915. if (!NAME_FETCH_V6(name) && EXPIRE_OK(name->expire_v6, now)) {
  916. if (NAME_HAS_V6(name)) {
  917. DP(DEF_LEVEL, "expiring v6 for name %p", name);
  918. result6 = clean_namehooks(adb, &name->v6);
  919. name->partial_result &= ~DNS_ADBFIND_INET6;
  920. }
  921. name->expire_v6 = INT_MAX;
  922. name->fetch6_err = FIND_ERR_UNEXPECTED;
  923. }
  924. /*
  925. * Check to see if we need to remove the alias target.
  926. */
  927. if (EXPIRE_OK(name->expire_target, now)) {
  928. clean_target(adb, &name->target);
  929. name->expire_target = INT_MAX;
  930. }
  931. return (ISC_TF(result4 || result6));
  932. }
  933. /*
  934. * Requires the name's bucket be locked.
  935. */
  936. static inline void
  937. link_name(dns_adb_t *adb, int bucket, dns_adbname_t *name) {
  938. INSIST(name->lock_bucket == DNS_ADB_INVALIDBUCKET);
  939. ISC_LIST_PREPEND(adb->names[bucket], name, plink);
  940. name->lock_bucket = bucket;
  941. adb->name_refcnt[bucket]++;
  942. }
  943. /*
  944. * Requires the name's bucket be locked.
  945. */
  946. static inline isc_boolean_t
  947. unlink_name(dns_adb_t *adb, dns_adbname_t *name) {
  948. int bucket;
  949. isc_boolean_t result = ISC_FALSE;
  950. bucket = name->lock_bucket;
  951. INSIST(bucket != DNS_ADB_INVALIDBUCKET);
  952. if (NAME_DEAD(name))
  953. ISC_LIST_UNLINK(adb->deadnames[bucket], name, plink);
  954. else
  955. ISC_LIST_UNLINK(adb->names[bucket], name, plink);
  956. name->lock_bucket = DNS_ADB_INVALIDBUCKET;
  957. INSIST(adb->name_refcnt[bucket] > 0);
  958. adb->name_refcnt[bucket]--;
  959. if (adb->name_sd[bucket] && adb->name_refcnt[bucket] == 0)
  960. result = ISC_TRUE;
  961. return (result);
  962. }
  963. /*
  964. * Requires the entry's bucket be locked.
  965. */
  966. static inline void
  967. link_entry(dns_adb_t *adb, int bucket, dns_adbentry_t *entry) {
  968. int i;
  969. dns_adbentry_t *e;
  970. if (isc_mem_isovermem(adb->mctx)) {
  971. for (i = 0; i < 2; i++) {
  972. e = ISC_LIST_TAIL(adb->entries[bucket]);
  973. if (e == NULL)
  974. break;
  975. if (e->refcnt == 0) {
  976. unlink_entry(adb, e);
  977. free_adbentry(adb, &e);
  978. continue;
  979. }
  980. INSIST((e->flags & ENTRY_IS_DEAD) == 0);
  981. e->flags |= ENTRY_IS_DEAD;
  982. ISC_LIST_UNLINK(adb->entries[bucket], e, plink);
  983. ISC_LIST_PREPEND(adb->deadentries[bucket], e, plink);
  984. }
  985. }
  986. ISC_LIST_PREPEND(adb->entries[bucket], entry, plink);
  987. entry->lock_bucket = bucket;
  988. adb->entry_refcnt[bucket]++;
  989. }
  990. /*
  991. * Requires the entry's bucket be locked.
  992. */
  993. static inline isc_boolean_t
  994. unlink_entry(dns_adb_t *adb, dns_adbentry_t *entry) {
  995. int bucket;
  996. isc_boolean_t result = ISC_FALSE;
  997. bucket = entry->lock_bucket;
  998. INSIST(bucket != DNS_ADB_INVALIDBUCKET);
  999. if ((entry->flags & ENTRY_IS_DEAD) != 0)
  1000. ISC_LIST_UNLINK(adb->deadentries[bucket], entry, plink);
  1001. else
  1002. ISC_LIST_UNLINK(adb->entries[bucket], entry, plink);
  1003. entry->lock_bucket = DNS_ADB_INVALIDBUCKET;
  1004. INSIST(adb->entry_refcnt[bucket] > 0);
  1005. adb->entry_refcnt[bucket]--;
  1006. if (adb->entry_sd[bucket] && adb->entry_refcnt[bucket] == 0)
  1007. result = ISC_TRUE;
  1008. return (result);
  1009. }
  1010. static inline void
  1011. violate_locking_hierarchy(isc_mutex_t *have, isc_mutex_t *want) {
  1012. if (isc_mutex_trylock(want) != ISC_R_SUCCESS) {
  1013. UNLOCK(have);
  1014. LOCK(want);
  1015. LOCK(have);
  1016. }
  1017. }
  1018. /*
  1019. * The ADB _MUST_ be locked before calling. Also, exit conditions must be
  1020. * checked after calling this function.
  1021. */
  1022. static isc_boolean_t
  1023. shutdown_names(dns_adb_t *adb) {
  1024. unsigned int bucket;
  1025. isc_boolean_t result = ISC_FALSE;
  1026. dns_adbname_t *name;
  1027. dns_adbname_t *next_name;
  1028. for (bucket = 0; bucket < adb->nnames; bucket++) {
  1029. LOCK(&adb->namelocks[bucket]);
  1030. adb->name_sd[bucket] = ISC_TRUE;
  1031. name = ISC_LIST_HEAD(adb->names[bucket]);
  1032. if (name == NULL) {
  1033. /*
  1034. * This bucket has no names. We must decrement the
  1035. * irefcnt ourselves, since it will not be
  1036. * automatically triggered by a name being unlinked.
  1037. */
  1038. INSIST(result == ISC_FALSE);
  1039. result = dec_adb_irefcnt(adb);
  1040. } else {
  1041. /*
  1042. * Run through the list. For each name, clean up finds
  1043. * found there, and cancel any fetches running. When
  1044. * all the fetches are canceled, the name will destroy
  1045. * itself.
  1046. */
  1047. while (name != NULL) {
  1048. next_name = ISC_LIST_NEXT(name, plink);
  1049. INSIST(result == ISC_FALSE);
  1050. result = kill_name(&name,
  1051. DNS_EVENT_ADBSHUTDOWN);
  1052. name = next_name;
  1053. }
  1054. }
  1055. UNLOCK(&adb->namelocks[bucket]);
  1056. }
  1057. return (result);
  1058. }
  1059. /*
  1060. * The ADB _MUST_ be locked before calling. Also, exit conditions must be
  1061. * checked after calling this function.
  1062. */
  1063. static isc_boolean_t
  1064. shutdown_entries(dns_adb_t *adb) {
  1065. unsigned int bucket;
  1066. isc_boolean_t result = ISC_FALSE;
  1067. dns_adbentry_t *entry;
  1068. dns_adbentry_t *next_entry;
  1069. for (bucket = 0; bucket < adb->nentries; bucket++) {
  1070. LOCK(&adb->entrylocks[bucket]);
  1071. adb->entry_sd[bucket] = ISC_TRUE;
  1072. entry = ISC_LIST_HEAD(adb->entries[bucket]);
  1073. if (adb->entry_refcnt[bucket] == 0) {
  1074. /*
  1075. * This bucket has no entries. We must decrement the
  1076. * irefcnt ourselves, since it will not be
  1077. * automatically triggered by an entry being unlinked.
  1078. */
  1079. result = dec_adb_irefcnt(adb);
  1080. } else {
  1081. /*
  1082. * Run through the list. Cleanup any entries not
  1083. * associated with names, and which are not in use.
  1084. */
  1085. while (entry != NULL) {
  1086. next_entry = ISC_LIST_NEXT(entry, plink);
  1087. if (entry->refcnt == 0 &&
  1088. entry->expires != 0) {
  1089. result = unlink_entry(adb, entry);
  1090. free_adbentry(adb, &entry);
  1091. if (result)
  1092. result = dec_adb_irefcnt(adb);
  1093. }
  1094. entry = next_entry;
  1095. }
  1096. }
  1097. UNLOCK(&adb->entrylocks[bucket]);
  1098. }
  1099. return (result);
  1100. }
  1101. /*
  1102. * Name bucket must be locked
  1103. */
  1104. static void
  1105. cancel_fetches_at_name(dns_adbname_t *name) {
  1106. if (NAME_FETCH_A(name))
  1107. dns_resolver_cancelfetch(name->fetch_a->fetch);
  1108. if (NAME_FETCH_AAAA(name))
  1109. dns_resolver_cancelfetch(name->fetch_aaaa->fetch);
  1110. }
  1111. /*
  1112. * Assumes the name bucket is locked.
  1113. */
  1114. static isc_boolean_t
  1115. clean_namehooks(dns_adb_t *adb, dns_adbnamehooklist_t *namehooks) {
  1116. dns_adbentry_t *entry;
  1117. dns_adbnamehook_t *namehook;
  1118. int addr_bucket;
  1119. isc_boolean_t result = ISC_FALSE;
  1120. isc_boolean_t overmem = isc_mem_isovermem(adb->mctx);
  1121. addr_bucket = DNS_ADB_INVALIDBUCKET;
  1122. namehook = ISC_LIST_HEAD(*namehooks);
  1123. while (namehook != NULL) {
  1124. INSIST(DNS_ADBNAMEHOOK_VALID(namehook));
  1125. /*
  1126. * Clean up the entry if needed.
  1127. */
  1128. entry = namehook->entry;
  1129. if (entry != NULL) {
  1130. INSIST(DNS_ADBENTRY_VALID(entry));
  1131. if (addr_bucket != entry->lock_bucket) {
  1132. if (addr_bucket != DNS_ADB_INVALIDBUCKET)
  1133. UNLOCK(&adb->entrylocks[addr_bucket]);
  1134. addr_bucket = entry->lock_bucket;
  1135. LOCK(&adb->entrylocks[addr_bucket]);
  1136. }
  1137. result = dec_entry_refcnt(adb, overmem, entry,
  1138. ISC_FALSE);
  1139. }
  1140. /*
  1141. * Free the namehook
  1142. */
  1143. namehook->entry = NULL;
  1144. ISC_LIST_UNLINK(*namehooks, namehook, plink);
  1145. free_adbnamehook(adb, &namehook);
  1146. namehook = ISC_LIST_HEAD(*namehooks);
  1147. }
  1148. if (addr_bucket != DNS_ADB_INVALIDBUCKET)
  1149. UNLOCK(&adb->entrylocks[addr_bucket]);
  1150. return (result);
  1151. }
  1152. static void
  1153. clean_target(dns_adb_t *adb, dns_name_t *target) {
  1154. if (dns_name_countlabels(target) > 0) {
  1155. dns_name_free(target, adb->mctx);
  1156. dns_name_init(target, NULL);
  1157. }
  1158. }
  1159. static isc_result_t
  1160. set_target(dns_adb_t *adb, dns_name_t *name, dns_name_t *fname,
  1161. dns_rdataset_t *rdataset, dns_name_t *target)
  1162. {
  1163. isc_result_t result;
  1164. dns_namereln_t namereln;
  1165. unsigned int nlabels;
  1166. int order;
  1167. dns_rdata_t rdata = DNS_RDATA_INIT;
  1168. dns_fixedname_t fixed1, fixed2;
  1169. dns_name_t *prefix, *new_target;
  1170. REQUIRE(dns_name_countlabels(target) == 0);
  1171. if (rdataset->type == dns_rdatatype_cname) {
  1172. dns_rdata_cname_t cname;
  1173. /*
  1174. * Copy the CNAME's target into the target name.
  1175. */
  1176. result = dns_rdataset_first(rdataset);
  1177. if (result != ISC_R_SUCCESS)
  1178. return (result);
  1179. dns_rdataset_current(rdataset, &rdata);
  1180. result = dns_rdata_tostruct(&rdata, &cname, NULL);
  1181. if (result != ISC_R_SUCCESS)
  1182. return (result);
  1183. result = dns_name_dup(&cname.cname, adb->mctx, target);
  1184. dns_rdata_freestruct(&cname);
  1185. if (result != ISC_R_SUCCESS)
  1186. return (result);
  1187. } else {
  1188. dns_rdata_dname_t dname;
  1189. INSIST(rdataset->type == dns_rdatatype_dname);
  1190. namereln = dns_name_fullcompare(name, fname, &order, &nlabels);
  1191. INSIST(namereln == dns_namereln_subdomain);
  1192. /*
  1193. * Get the target name of the DNAME.
  1194. */
  1195. result = dns_rdataset_first(rdataset);
  1196. if (result != ISC_R_SUCCESS)
  1197. return (result);
  1198. dns_rdataset_current(rdataset, &rdata);
  1199. result = dns_rdata_tostruct(&rdata, &dname, NULL);
  1200. if (result != ISC_R_SUCCESS)
  1201. return (result);
  1202. /*
  1203. * Construct the new target name.
  1204. */
  1205. dns_fixedname_init(&fixed1);
  1206. prefix = dns_fixedname_name(&fixed1);
  1207. dns_fixedname_init(&fixed2);
  1208. new_target = dns_fixedname_name(&fixed2);
  1209. dns_name_split(name, nlabels, prefix, NULL);
  1210. result = dns_name_concatenate(prefix, &dname.dname, new_target,
  1211. NULL);
  1212. dns_rdata_freestruct(&dname);
  1213. if (result != ISC_R_SUCCESS)
  1214. return (result);
  1215. result = dns_name_dup(new_target, adb->mctx, target);
  1216. if (result != ISC_R_SUCCESS)
  1217. return (result);
  1218. }
  1219. return (ISC_R_SUCCESS);
  1220. }
  1221. /*
  1222. * Assumes nothing is locked, since this is called by the client.
  1223. */
  1224. static void
  1225. event_free(isc_event_t *event) {
  1226. dns_adbfind_t *find;
  1227. INSIST(event != NULL);
  1228. find = event->ev_destroy_arg;
  1229. INSIST(DNS_ADBFIND_VALID(find));
  1230. LOCK(&find->lock);
  1231. find->flags |= FIND_EVENT_FREED;
  1232. event->ev_destroy_arg = NULL;
  1233. UNLOCK(&find->lock);
  1234. }
  1235. /*
  1236. * Assumes the name bucket is locked.
  1237. */
  1238. static void
  1239. clean_finds_at_name(dns_adbname_t *name, isc_eventtype_t evtype,
  1240. unsigned int addrs)
  1241. {
  1242. isc_event_t *ev;
  1243. isc_task_t *task;
  1244. dns_adbfind_t *find;
  1245. dns_adbfind_t *next_find;
  1246. isc_boolean_t process;
  1247. unsigned int wanted, notify;
  1248. DP(ENTER_LEVEL,
  1249. "ENTER clean_finds_at_name, name %p, evtype %08x, addrs %08x",
  1250. name, evtype, addrs);
  1251. find = ISC_LIST_HEAD(name->finds);
  1252. while (find != NULL) {
  1253. LOCK(&find->lock);
  1254. next_find = ISC_LIST_NEXT(find, plink);
  1255. process = ISC_FALSE;
  1256. wanted = find->flags & DNS_ADBFIND_ADDRESSMASK;
  1257. notify = wanted & addrs;
  1258. switch (evtype) {
  1259. case DNS_EVENT_ADBMOREADDRESSES:
  1260. DP(ISC_LOG_DEBUG(3), "DNS_EVENT_ADBMOREADDRESSES");
  1261. if ((notify) != 0) {
  1262. find->flags &= ~addrs;
  1263. process = ISC_TRUE;
  1264. }
  1265. break;
  1266. case DNS_EVENT_ADBNOMOREADDRESSES:
  1267. DP(ISC_LOG_DEBUG(3), "DNS_EVENT_ADBNOMOREADDRESSES");
  1268. find->flags &= ~addrs;
  1269. wanted = find->flags & DNS_ADBFIND_ADDRESSMASK;
  1270. if (wanted == 0)
  1271. process = ISC_TRUE;
  1272. break;
  1273. default:
  1274. find->flags &= ~addrs;
  1275. process = ISC_TRUE;
  1276. }
  1277. if (process) {
  1278. DP(DEF_LEVEL, "cfan: processing find %p", find);
  1279. /*
  1280. * Unlink the find from the name, letting the caller
  1281. * call dns_adb_destroyfind() on it to clean it up
  1282. * later.
  1283. */
  1284. ISC_LIST_UNLINK(name->finds, find, plink);
  1285. find->adbname = NULL;
  1286. find->name_bucket = DNS_ADB_INVALIDBUCKET;
  1287. INSIST(!FIND_EVENTSENT(find));
  1288. ev = &find->event;
  1289. task = ev->ev_sender;
  1290. ev->ev_sender = find;
  1291. find->result_v4 = find_err_map[name->fetch_err];
  1292. find->result_v6 = find_err_map[name->fetch6_err];
  1293. ev->ev_type = evtype;
  1294. ev->ev_destroy = event_free;
  1295. ev->ev_destroy_arg = find;
  1296. DP(DEF_LEVEL,
  1297. "sending event %p to task %p for find %p",
  1298. ev, task, find);
  1299. isc_task_sendanddetach(&task, (isc_event_t **)&ev);
  1300. } else {
  1301. DP(DEF_LEVEL, "cfan: skipping find %p", find);
  1302. }
  1303. UNLOCK(&find->lock);
  1304. find = next_find;
  1305. }
  1306. DP(ENTER_LEVEL, "EXIT clean_finds_at_name, name %p", name);
  1307. }
  1308. static inline void
  1309. check_exit(dns_adb_t *adb) {
  1310. isc_event_t *event;
  1311. /*
  1312. * The caller must be holding the adb lock.
  1313. */
  1314. if (adb->shutting_down) {
  1315. /*
  1316. * If there aren't any external references either, we're
  1317. * done. Send the control event to initiate shutdown.
  1318. */
  1319. INSIST(!adb->cevent_sent); /* Sanity check. */
  1320. event = &adb->cevent;
  1321. isc_task_send(adb->task, &event);
  1322. adb->cevent_sent = ISC_TRUE;
  1323. }
  1324. }
  1325. static inline isc_boolean_t
  1326. dec_adb_irefcnt(dns_adb_t *adb) {
  1327. isc_event_t *event;
  1328. isc_task_t *etask;
  1329. isc_boolean_t result = ISC_FALSE;
  1330. LOCK(&adb->reflock);
  1331. INSIST(adb->irefcnt > 0);
  1332. adb->irefcnt--;
  1333. if (adb->irefcnt == 0) {
  1334. event = ISC_LIST_HEAD(adb->whenshutdown);
  1335. while (event != NULL) {
  1336. ISC_LIST_UNLINK(adb->whenshutdown, event, ev_link);
  1337. etask = event->ev_sender;
  1338. event->ev_sender = adb;
  1339. isc_task_sendanddetach(&etask, &event);
  1340. event = ISC_LIST_HEAD(adb->whenshutdown);
  1341. }
  1342. }
  1343. if (adb->irefcnt == 0 && adb->erefcnt == 0)
  1344. result = ISC_TRUE;
  1345. UNLOCK(&adb->reflock);
  1346. return (result);
  1347. }
  1348. static inline void
  1349. inc_adb_irefcnt(dns_adb_t *adb) {
  1350. LOCK(&adb->reflock);
  1351. adb->irefcnt++;
  1352. UNLOCK(&adb->reflock);
  1353. }
  1354. static inline void
  1355. inc_adb_erefcnt(dns_adb_t *adb) {
  1356. LOCK(&adb->reflock);
  1357. adb->erefcnt++;
  1358. UNLOCK(&adb->reflock);
  1359. }
  1360. static inline void
  1361. inc_entry_refcnt(dns_adb_t *adb, dns_adbentry_t *entry, isc_boolean_t lock) {
  1362. int bucket;
  1363. bucket = entry->lock_bucket;
  1364. if (lock)
  1365. LOCK(&adb->entrylocks[bucket]);
  1366. entry->refcnt++;
  1367. if (lock)
  1368. UNLOCK(&adb->entrylocks[bucket]);
  1369. }
  1370. static inline isc_boolean_t
  1371. dec_entry_refcnt(dns_adb_t *adb, isc_boolean_t overmem, dns_adbentry_t *entry,
  1372. isc_boolean_t lock)
  1373. {
  1374. int bucket;
  1375. isc_boolean_t destroy_entry;
  1376. isc_boolean_t result = ISC_FALSE;
  1377. bucket = entry->lock_bucket;
  1378. if (lock)
  1379. LOCK(&adb->entrylocks[bucket]);
  1380. INSIST(entry->refcnt > 0);
  1381. entry->refcnt--;
  1382. destroy_entry = ISC_FALSE;
  1383. if (entry->refcnt == 0 &&
  1384. (adb->entry_sd[bucket] || entry->expires == 0 || overmem ||
  1385. (entry->flags & ENTRY_IS_DEAD) != 0)) {
  1386. destroy_entry = ISC_TRUE;
  1387. result = unlink_entry(adb, entry);
  1388. }
  1389. if (lock)
  1390. UNLOCK(&adb->entrylocks[bucket]);
  1391. if (!destroy_entry)
  1392. return (result);
  1393. entry->lock_bucket = DNS_ADB_INVALIDBUCKET;
  1394. free_adbentry(adb, &entry);
  1395. if (result)
  1396. result = dec_adb_irefcnt(adb);
  1397. return (result);
  1398. }
  1399. static inline dns_adbname_t *
  1400. new_adbname(dns_adb_t *adb, dns_name_t *dnsname) {
  1401. dns_adbname_t *name;
  1402. name = isc_mempool_get(adb->nmp);
  1403. if (name == NULL)
  1404. return (NULL);
  1405. dns_name_init(&name->name, NULL);
  1406. if (dns_name_dup(dnsname, adb->mctx, &name->name) != ISC_R_SUCCESS) {
  1407. isc_mempool_put(adb->nmp, name);
  1408. return (NULL);
  1409. }
  1410. dns_name_init(&name->target, NULL);
  1411. name->magic = DNS_ADBNAME_MAGIC;
  1412. name->adb = adb;
  1413. name->partial_result = 0;
  1414. name->flags = 0;
  1415. name->expire_v4 = INT_MAX;
  1416. name->expire_v6 = INT_MAX;
  1417. name->expire_target = INT_MAX;
  1418. name->chains = 0;
  1419. name->lock_bucket = DNS_ADB_INVALIDBUCKET;
  1420. ISC_LIST_INIT(name->v4);
  1421. ISC_LIST_INIT(name->v6);
  1422. name->fetch_a = NULL;
  1423. name->fetch_aaaa = NULL;
  1424. name->fetch_err = FIND_ERR_UNEXPECTED;
  1425. name->fetch6_err = FIND_ERR_UNEXPECTED;
  1426. ISC_LIST_INIT(name->finds);
  1427. ISC_LINK_INIT(name, plink);
  1428. LOCK(&adb->namescntlock);
  1429. adb->namescnt++;
  1430. if (!adb->grownames_sent && adb->namescnt > (adb->nnames * 8)) {
  1431. isc_event_t *event = &adb->grownames;
  1432. inc_adb_irefcnt(adb);
  1433. isc_task_send(adb->task, &event);
  1434. adb->grownames_sent = ISC_TRUE;
  1435. }
  1436. UNLOCK(&adb->namescntlock);
  1437. return (name);
  1438. }
  1439. static inline void
  1440. free_adbname(dns_adb_t *adb, dns_adbname_t **name) {
  1441. dns_adbname_t *n;
  1442. INSIST(name != NULL && DNS_ADBNAME_VALID(*name));
  1443. n = *name;
  1444. *name = NULL;
  1445. INSIST(!NAME_HAS_V4(n));
  1446. INSIST(!NAME_HAS_V6(n));
  1447. INSIST(!NAME_FETCH(n));
  1448. INSIST(ISC_LIST_EMPTY(n->finds));
  1449. INSIST(!ISC_LINK_LINKED(n, plink));
  1450. INSIST(n->lock_bucket == DNS_ADB_INVALIDBUCKET);
  1451. INSIST(n->adb == adb);
  1452. n->magic = 0;
  1453. dns_name_free(&n->name, adb->mctx);
  1454. isc_mempool_put(adb->nmp, n);
  1455. LOCK(&adb->namescntlock);
  1456. adb->namescnt--;
  1457. UNLOCK(&adb->namescntlock);
  1458. }
  1459. static inline dns_adbnamehook_t *
  1460. new_adbnamehook(dns_adb_t *adb, dns_adbentry_t *entry) {
  1461. dns_adbnamehook_t *nh;
  1462. nh = isc_mempool_get(adb->nhmp);
  1463. if (nh == NULL)
  1464. return (NULL);
  1465. nh->magic = DNS_ADBNAMEHOOK_MAGIC;
  1466. nh->entry = entry;
  1467. ISC_LINK_INIT(nh, plink);
  1468. return (nh);
  1469. }
  1470. static inline void
  1471. free_adbnamehook(dns_adb_t *adb, dns_adbnamehook_t **namehook) {
  1472. dns_adbnamehook_t *nh;
  1473. INSIST(namehook != NULL && DNS_ADBNAMEHOOK_VALID(*namehook));
  1474. nh = *namehook;
  1475. *namehook = NULL;
  1476. INSIST(nh->entry == NULL);
  1477. INSIST(!ISC_LINK_LINKED(nh, plink));
  1478. nh->magic = 0;
  1479. isc_mempool_put(adb->nhmp, nh);
  1480. }
  1481. static inline dns_adblameinfo_t *
  1482. new_adblameinfo(dns_adb_t *adb, dns_name_t *qname, dns_rdatatype_t qtype) {
  1483. dns_adblameinfo_t *li;
  1484. li = isc_mempool_get(adb->limp);
  1485. if (li == NULL)
  1486. return (NULL);
  1487. dns_name_init(&li->qname, NULL);
  1488. if (dns_name_dup(qname, adb->mctx, &li->qname) != ISC_R_SUCCESS) {
  1489. isc_mempool_put(adb->limp, li);
  1490. return (NULL);
  1491. }
  1492. li->magic = DNS_ADBLAMEINFO_MAGIC;
  1493. li->lame_timer = 0;
  1494. li->qtype = qtype;
  1495. ISC_LINK_INIT(li, plink);
  1496. return (li);
  1497. }
  1498. static inline void
  1499. free_adblameinfo(dns_adb_t *adb, dns_adblameinfo_t **lameinfo) {
  1500. dns_adblameinfo_t *li;
  1501. INSIST(lameinfo != NULL && DNS_ADBLAMEINFO_VALID(*lameinfo));
  1502. li = *lameinfo;
  1503. *lameinfo = NULL;
  1504. INSIST(!ISC_LINK_LINKED(li, plink));
  1505. dns_name_free(&li->qname, adb->mctx);
  1506. li->magic = 0;
  1507. isc_mempool_put(adb->limp, li);
  1508. }
  1509. static inline dns_adbentry_t *
  1510. new_adbentry(dns_adb_t *adb) {
  1511. dns_adbentry_t *e;
  1512. isc_uint32_t r;
  1513. e = isc_mempool_get(adb->emp);
  1514. if (e == NULL)
  1515. return (NULL);
  1516. e->magic = DNS_ADBENTRY_MAGIC;
  1517. e->lock_bucket = DNS_ADB_INVALIDBUCKET;
  1518. e->refcnt = 0;
  1519. e->flags = 0;
  1520. isc_random_get(&r);
  1521. e->srtt = (r & 0x1f) + 1;
  1522. e->expires = 0;
  1523. ISC_LIST_INIT(e->lameinfo);
  1524. ISC_LINK_INIT(e, plink);
  1525. LOCK(&adb->entriescntlock);
  1526. adb->entriescnt++;
  1527. if (!adb->growentries_sent &&
  1528. adb->entriescnt > (adb->nentries * 8)) {
  1529. isc_event_t *event = &adb->growentries;
  1530. inc_adb_irefcnt(adb);
  1531. isc_task_send(adb->task,