dispatch.c revision 171577
1/*
2 * Copyright (C) 2004-2007  Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2003  Internet Software Consortium.
4 *
5 * Permission to use, copy, modify, and 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
18/* $Id: dispatch.c,v 1.116.18.13.10.4 2007/06/27 04:17:45 marka Exp $ */
19
20/*! \file */
21
22#include <config.h>
23
24#include <stdlib.h>
25#include <sys/types.h>
26#include <unistd.h>
27
28#include <isc/entropy.h>
29#include <isc/mem.h>
30#include <isc/mutex.h>
31#include <isc/print.h>
32#include <isc/string.h>
33#include <isc/task.h>
34#include <isc/time.h>
35#include <isc/util.h>
36
37#include <dns/acl.h>
38#include <dns/dispatch.h>
39#include <dns/events.h>
40#include <dns/log.h>
41#include <dns/message.h>
42#include <dns/portlist.h>
43#include <dns/tcpmsg.h>
44#include <dns/types.h>
45
46typedef ISC_LIST(dns_dispentry_t)	dns_displist_t;
47
48typedef struct dns_nsid {
49	isc_uint16_t	nsid_state;
50	isc_uint16_t	*nsid_vtable;
51	isc_uint16_t	*nsid_pool;
52	isc_uint16_t	nsid_a1, nsid_a2, nsid_a3;
53	isc_uint16_t	nsid_c1, nsid_c2, nsid_c3;
54	isc_uint16_t	nsid_state2;
55	isc_boolean_t	nsid_usepool;
56} dns_nsid_t;
57
58typedef struct dns_qid {
59	unsigned int	magic;
60	unsigned int	qid_nbuckets;	/*%< hash table size */
61	unsigned int	qid_increment;	/*%< id increment on collision */
62	isc_mutex_t	lock;
63	dns_nsid_t      nsid;
64	dns_displist_t	*qid_table;	/*%< the table itself */
65} dns_qid_t;
66
67struct dns_dispatchmgr {
68	/* Unlocked. */
69	unsigned int			magic;
70	isc_mem_t		       *mctx;
71	dns_acl_t		       *blackhole;
72	dns_portlist_t		       *portlist;
73
74	/* Locked by "lock". */
75	isc_mutex_t			lock;
76	unsigned int			state;
77	ISC_LIST(dns_dispatch_t)	list;
78
79	/* locked by buffer lock */
80	dns_qid_t			*qid;
81	isc_mutex_t			buffer_lock;
82	unsigned int			buffers;    /*%< allocated buffers */
83	unsigned int			buffersize; /*%< size of each buffer */
84	unsigned int			maxbuffers; /*%< max buffers */
85
86	/* Locked internally. */
87	isc_mutex_t			pool_lock;
88	isc_mempool_t		       *epool;	/*%< memory pool for events */
89	isc_mempool_t		       *rpool;	/*%< memory pool for replies */
90	isc_mempool_t		       *dpool;  /*%< dispatch allocations */
91	isc_mempool_t		       *bpool;	/*%< memory pool for buffers */
92
93	isc_entropy_t		       *entropy; /*%< entropy source */
94};
95
96#define MGR_SHUTTINGDOWN		0x00000001U
97#define MGR_IS_SHUTTINGDOWN(l)	(((l)->state & MGR_SHUTTINGDOWN) != 0)
98
99#define IS_PRIVATE(d)	(((d)->attributes & DNS_DISPATCHATTR_PRIVATE) != 0)
100
101struct dns_dispentry {
102	unsigned int			magic;
103	dns_dispatch_t		       *disp;
104	dns_messageid_t			id;
105	unsigned int			bucket;
106	isc_sockaddr_t			host;
107	isc_task_t		       *task;
108	isc_taskaction_t		action;
109	void			       *arg;
110	isc_boolean_t			item_out;
111	ISC_LIST(dns_dispatchevent_t)	items;
112	ISC_LINK(dns_dispentry_t)	link;
113};
114
115#define INVALID_BUCKET		(0xffffdead)
116
117struct dns_dispatch {
118	/* Unlocked. */
119	unsigned int		magic;		/*%< magic */
120	dns_dispatchmgr_t      *mgr;		/*%< dispatch manager */
121	isc_task_t	       *task;		/*%< internal task */
122	isc_socket_t	       *socket;		/*%< isc socket attached to */
123	isc_sockaddr_t		local;		/*%< local address */
124	unsigned int		maxrequests;	/*%< max requests */
125	isc_event_t	       *ctlevent;
126
127	/*% Locked by mgr->lock. */
128	ISC_LINK(dns_dispatch_t) link;
129
130	/* Locked by "lock". */
131	isc_mutex_t		lock;		/*%< locks all below */
132	isc_sockettype_t	socktype;
133	unsigned int		attributes;
134	unsigned int		refcount;	/*%< number of users */
135	dns_dispatchevent_t    *failsafe_ev;	/*%< failsafe cancel event */
136	unsigned int		shutting_down : 1,
137				shutdown_out : 1,
138				connected : 1,
139				tcpmsg_valid : 1,
140				recv_pending : 1; /*%< is a recv() pending? */
141	isc_result_t		shutdown_why;
142	unsigned int		requests;	/*%< how many requests we have */
143	unsigned int		tcpbuffers;	/*%< allocated buffers */
144	dns_tcpmsg_t		tcpmsg;		/*%< for tcp streams */
145	dns_qid_t		*qid;
146};
147
148#define QID_MAGIC		ISC_MAGIC('Q', 'i', 'd', ' ')
149#define VALID_QID(e)		ISC_MAGIC_VALID((e), QID_MAGIC)
150
151#define RESPONSE_MAGIC		ISC_MAGIC('D', 'r', 's', 'p')
152#define VALID_RESPONSE(e)	ISC_MAGIC_VALID((e), RESPONSE_MAGIC)
153
154#define DISPATCH_MAGIC		ISC_MAGIC('D', 'i', 's', 'p')
155#define VALID_DISPATCH(e)	ISC_MAGIC_VALID((e), DISPATCH_MAGIC)
156
157#define DNS_DISPATCHMGR_MAGIC	ISC_MAGIC('D', 'M', 'g', 'r')
158#define VALID_DISPATCHMGR(e)	ISC_MAGIC_VALID((e), DNS_DISPATCHMGR_MAGIC)
159
160#define DNS_QID(disp) ((disp)->socktype == isc_sockettype_tcp) ? \
161		       (disp)->qid : (disp)->mgr->qid
162/*
163 * Statics.
164 */
165static dns_dispentry_t *bucket_search(dns_qid_t *, isc_sockaddr_t *,
166				      dns_messageid_t, unsigned int);
167static isc_boolean_t destroy_disp_ok(dns_dispatch_t *);
168static void destroy_disp(isc_task_t *task, isc_event_t *event);
169static void udp_recv(isc_task_t *, isc_event_t *);
170static void tcp_recv(isc_task_t *, isc_event_t *);
171static void startrecv(dns_dispatch_t *);
172static dns_messageid_t dns_randomid(dns_nsid_t *);
173static isc_uint32_t dns_hash(dns_qid_t *, isc_sockaddr_t *, dns_messageid_t);
174static void free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len);
175static void *allocate_udp_buffer(dns_dispatch_t *disp);
176static inline void free_event(dns_dispatch_t *disp, dns_dispatchevent_t *ev);
177static inline dns_dispatchevent_t *allocate_event(dns_dispatch_t *disp);
178static void do_cancel(dns_dispatch_t *disp);
179static dns_dispentry_t *linear_first(dns_qid_t *disp);
180static dns_dispentry_t *linear_next(dns_qid_t *disp,
181				    dns_dispentry_t *resp);
182static void dispatch_free(dns_dispatch_t **dispp);
183static isc_result_t dispatch_createudp(dns_dispatchmgr_t *mgr,
184				       isc_socketmgr_t *sockmgr,
185				       isc_taskmgr_t *taskmgr,
186				       isc_sockaddr_t *localaddr,
187				       unsigned int maxrequests,
188				       unsigned int attributes,
189				       dns_dispatch_t **dispp);
190static isc_boolean_t destroy_mgr_ok(dns_dispatchmgr_t *mgr);
191static void destroy_mgr(dns_dispatchmgr_t **mgrp);
192static isc_result_t qid_allocate(dns_dispatchmgr_t *mgr, unsigned int buckets,
193				 unsigned int increment, isc_boolean_t usepool,
194				 dns_qid_t **qidp);
195static void qid_destroy(isc_mem_t *mctx, dns_qid_t **qidp);
196static isc_uint16_t nsid_next(dns_nsid_t *nsid);
197static isc_result_t nsid_init(isc_mem_t *mctx, dns_nsid_t *nsid, isc_boolean_t usepool);
198static void nsid_destroy(isc_mem_t *mctx, dns_nsid_t *nsid);
199
200#define LVL(x) ISC_LOG_DEBUG(x)
201
202static void
203mgr_log(dns_dispatchmgr_t *mgr, int level, const char *fmt, ...)
204     ISC_FORMAT_PRINTF(3, 4);
205
206static void
207mgr_log(dns_dispatchmgr_t *mgr, int level, const char *fmt, ...) {
208	char msgbuf[2048];
209	va_list ap;
210
211	if (! isc_log_wouldlog(dns_lctx, level))
212		return;
213
214	va_start(ap, fmt);
215	vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
216	va_end(ap);
217
218	isc_log_write(dns_lctx,
219		      DNS_LOGCATEGORY_DISPATCH, DNS_LOGMODULE_DISPATCH,
220		      level, "dispatchmgr %p: %s", mgr, msgbuf);
221}
222
223static void
224dispatch_log(dns_dispatch_t *disp, int level, const char *fmt, ...)
225     ISC_FORMAT_PRINTF(3, 4);
226
227static void
228dispatch_log(dns_dispatch_t *disp, int level, const char *fmt, ...) {
229	char msgbuf[2048];
230	va_list ap;
231
232	if (! isc_log_wouldlog(dns_lctx, level))
233		return;
234
235	va_start(ap, fmt);
236	vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
237	va_end(ap);
238
239	isc_log_write(dns_lctx,
240		      DNS_LOGCATEGORY_DISPATCH, DNS_LOGMODULE_DISPATCH,
241		      level, "dispatch %p: %s", disp, msgbuf);
242}
243
244static void
245request_log(dns_dispatch_t *disp, dns_dispentry_t *resp,
246	    int level, const char *fmt, ...)
247     ISC_FORMAT_PRINTF(4, 5);
248
249static void
250request_log(dns_dispatch_t *disp, dns_dispentry_t *resp,
251	    int level, const char *fmt, ...)
252{
253	char msgbuf[2048];
254	char peerbuf[256];
255	va_list ap;
256
257	if (! isc_log_wouldlog(dns_lctx, level))
258		return;
259
260	va_start(ap, fmt);
261	vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
262	va_end(ap);
263
264	if (VALID_RESPONSE(resp)) {
265		isc_sockaddr_format(&resp->host, peerbuf, sizeof(peerbuf));
266		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DISPATCH,
267			      DNS_LOGMODULE_DISPATCH, level,
268			      "dispatch %p response %p %s: %s", disp, resp,
269			      peerbuf, msgbuf);
270	} else {
271		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DISPATCH,
272			      DNS_LOGMODULE_DISPATCH, level,
273			      "dispatch %p req/resp %p: %s", disp, resp,
274			      msgbuf);
275	}
276}
277
278/*
279 * Return an unpredictable message ID.
280 */
281static dns_messageid_t
282dns_randomid(dns_nsid_t *nsid) {
283	isc_uint32_t id;
284
285	id = nsid_next(nsid);
286
287	return ((dns_messageid_t)id);
288}
289
290/*
291 * Return a hash of the destination and message id.
292 */
293static isc_uint32_t
294dns_hash(dns_qid_t *qid, isc_sockaddr_t *dest, dns_messageid_t id) {
295	unsigned int ret;
296
297	ret = isc_sockaddr_hash(dest, ISC_TRUE);
298	ret ^= id;
299	ret %= qid->qid_nbuckets;
300
301	INSIST(ret < qid->qid_nbuckets);
302
303	return (ret);
304}
305
306/*
307 * Find the first entry in 'qid'.  Returns NULL if there are no entries.
308 */
309static dns_dispentry_t *
310linear_first(dns_qid_t *qid) {
311	dns_dispentry_t *ret;
312	unsigned int bucket;
313
314	bucket = 0;
315
316	while (bucket < qid->qid_nbuckets) {
317		ret = ISC_LIST_HEAD(qid->qid_table[bucket]);
318		if (ret != NULL)
319			return (ret);
320		bucket++;
321	}
322
323	return (NULL);
324}
325
326/*
327 * Find the next entry after 'resp' in 'qid'.  Return NULL if there are
328 * no more entries.
329 */
330static dns_dispentry_t *
331linear_next(dns_qid_t *qid, dns_dispentry_t *resp) {
332	dns_dispentry_t *ret;
333	unsigned int bucket;
334
335	ret = ISC_LIST_NEXT(resp, link);
336	if (ret != NULL)
337		return (ret);
338
339	bucket = resp->bucket;
340	bucket++;
341	while (bucket < qid->qid_nbuckets) {
342		ret = ISC_LIST_HEAD(qid->qid_table[bucket]);
343		if (ret != NULL)
344			return (ret);
345		bucket++;
346	}
347
348	return (NULL);
349}
350
351/*
352 * The dispatch must be locked.
353 */
354static isc_boolean_t
355destroy_disp_ok(dns_dispatch_t *disp)
356{
357	if (disp->refcount != 0)
358		return (ISC_FALSE);
359
360	if (disp->recv_pending != 0)
361		return (ISC_FALSE);
362
363	if (disp->shutting_down == 0)
364		return (ISC_FALSE);
365
366	return (ISC_TRUE);
367}
368
369
370/*
371 * Called when refcount reaches 0 (and safe to destroy).
372 *
373 * The dispatcher must not be locked.
374 * The manager must be locked.
375 */
376static void
377destroy_disp(isc_task_t *task, isc_event_t *event) {
378	dns_dispatch_t *disp;
379	dns_dispatchmgr_t *mgr;
380	isc_boolean_t killmgr;
381
382	INSIST(event->ev_type == DNS_EVENT_DISPATCHCONTROL);
383
384	UNUSED(task);
385
386	disp = event->ev_arg;
387	mgr = disp->mgr;
388
389	LOCK(&mgr->lock);
390	ISC_LIST_UNLINK(mgr->list, disp, link);
391
392	dispatch_log(disp, LVL(90),
393		     "shutting down; detaching from sock %p, task %p",
394		     disp->socket, disp->task);
395
396	isc_socket_detach(&disp->socket);
397	isc_task_detach(&disp->task);
398	isc_event_free(&event);
399
400	dispatch_free(&disp);
401
402	killmgr = destroy_mgr_ok(mgr);
403	UNLOCK(&mgr->lock);
404	if (killmgr)
405		destroy_mgr(&mgr);
406}
407
408
409/*
410 * Find an entry for query ID 'id' and socket address 'dest' in 'qid'.
411 * Return NULL if no such entry exists.
412 */
413static dns_dispentry_t *
414bucket_search(dns_qid_t *qid, isc_sockaddr_t *dest, dns_messageid_t id,
415	      unsigned int bucket)
416{
417	dns_dispentry_t *res;
418
419	REQUIRE(bucket < qid->qid_nbuckets);
420
421	res = ISC_LIST_HEAD(qid->qid_table[bucket]);
422
423	while (res != NULL) {
424		if ((res->id == id) && isc_sockaddr_equal(dest, &res->host))
425			return (res);
426		res = ISC_LIST_NEXT(res, link);
427	}
428
429	return (NULL);
430}
431
432static void
433free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len) {
434	INSIST(buf != NULL && len != 0);
435
436
437	switch (disp->socktype) {
438	case isc_sockettype_tcp:
439		INSIST(disp->tcpbuffers > 0);
440		disp->tcpbuffers--;
441		isc_mem_put(disp->mgr->mctx, buf, len);
442		break;
443	case isc_sockettype_udp:
444		LOCK(&disp->mgr->buffer_lock);
445		INSIST(disp->mgr->buffers > 0);
446		INSIST(len == disp->mgr->buffersize);
447		disp->mgr->buffers--;
448		isc_mempool_put(disp->mgr->bpool, buf);
449		UNLOCK(&disp->mgr->buffer_lock);
450		break;
451	default:
452		INSIST(0);
453		break;
454	}
455}
456
457static void *
458allocate_udp_buffer(dns_dispatch_t *disp) {
459	void *temp;
460
461	LOCK(&disp->mgr->buffer_lock);
462	temp = isc_mempool_get(disp->mgr->bpool);
463
464	if (temp != NULL)
465		disp->mgr->buffers++;
466	UNLOCK(&disp->mgr->buffer_lock);
467
468	return (temp);
469}
470
471static inline void
472free_event(dns_dispatch_t *disp, dns_dispatchevent_t *ev) {
473	if (disp->failsafe_ev == ev) {
474		INSIST(disp->shutdown_out == 1);
475		disp->shutdown_out = 0;
476
477		return;
478	}
479
480	isc_mempool_put(disp->mgr->epool, ev);
481}
482
483static inline dns_dispatchevent_t *
484allocate_event(dns_dispatch_t *disp) {
485	dns_dispatchevent_t *ev;
486
487	ev = isc_mempool_get(disp->mgr->epool);
488	if (ev == NULL)
489		return (NULL);
490	ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, 0,
491		       NULL, NULL, NULL, NULL, NULL);
492
493	return (ev);
494}
495
496/*
497 * General flow:
498 *
499 * If I/O result == CANCELED or error, free the buffer.
500 *
501 * If query, free the buffer, restart.
502 *
503 * If response:
504 *	Allocate event, fill in details.
505 *		If cannot allocate, free buffer, restart.
506 *	find target.  If not found, free buffer, restart.
507 *	if event queue is not empty, queue.  else, send.
508 *	restart.
509 */
510static void
511udp_recv(isc_task_t *task, isc_event_t *ev_in) {
512	isc_socketevent_t *ev = (isc_socketevent_t *)ev_in;
513	dns_dispatch_t *disp = ev_in->ev_arg;
514	dns_messageid_t id;
515	isc_result_t dres;
516	isc_buffer_t source;
517	unsigned int flags;
518	dns_dispentry_t *resp;
519	dns_dispatchevent_t *rev;
520	unsigned int bucket;
521	isc_boolean_t killit;
522	isc_boolean_t queue_response;
523	dns_dispatchmgr_t *mgr;
524	dns_qid_t *qid;
525	isc_netaddr_t netaddr;
526	int match;
527
528	UNUSED(task);
529
530	LOCK(&disp->lock);
531
532	mgr = disp->mgr;
533	qid = mgr->qid;
534
535	dispatch_log(disp, LVL(90),
536		     "got packet: requests %d, buffers %d, recvs %d",
537		     disp->requests, disp->mgr->buffers, disp->recv_pending);
538
539	if (ev->ev_type == ISC_SOCKEVENT_RECVDONE) {
540		/*
541		 * Unless the receive event was imported from a listening
542		 * interface, in which case the event type is
543		 * DNS_EVENT_IMPORTRECVDONE, receive operation must be pending.
544		 */
545		INSIST(disp->recv_pending != 0);
546		disp->recv_pending = 0;
547	}
548
549	if (disp->shutting_down) {
550		/*
551		 * This dispatcher is shutting down.
552		 */
553		free_buffer(disp, ev->region.base, ev->region.length);
554
555		isc_event_free(&ev_in);
556		ev = NULL;
557
558		killit = destroy_disp_ok(disp);
559		UNLOCK(&disp->lock);
560		if (killit)
561			isc_task_send(disp->task, &disp->ctlevent);
562
563		return;
564	}
565
566	if (ev->result != ISC_R_SUCCESS) {
567		free_buffer(disp, ev->region.base, ev->region.length);
568
569		if (ev->result != ISC_R_CANCELED)
570			dispatch_log(disp, ISC_LOG_ERROR,
571				     "odd socket result in udp_recv(): %s",
572				     isc_result_totext(ev->result));
573
574		UNLOCK(&disp->lock);
575		isc_event_free(&ev_in);
576		return;
577	}
578
579	/*
580	 * If this is from a blackholed address, drop it.
581	 */
582	isc_netaddr_fromsockaddr(&netaddr, &ev->address);
583	if (disp->mgr->blackhole != NULL &&
584	    dns_acl_match(&netaddr, NULL, disp->mgr->blackhole,
585		    	  NULL, &match, NULL) == ISC_R_SUCCESS &&
586	    match > 0)
587	{
588		if (isc_log_wouldlog(dns_lctx, LVL(10))) {
589			char netaddrstr[ISC_NETADDR_FORMATSIZE];
590			isc_netaddr_format(&netaddr, netaddrstr,
591					   sizeof(netaddrstr));
592			dispatch_log(disp, LVL(10),
593				     "blackholed packet from %s",
594				     netaddrstr);
595		}
596		free_buffer(disp, ev->region.base, ev->region.length);
597		goto restart;
598	}
599
600	/*
601	 * Peek into the buffer to see what we can see.
602	 */
603	isc_buffer_init(&source, ev->region.base, ev->region.length);
604	isc_buffer_add(&source, ev->n);
605	dres = dns_message_peekheader(&source, &id, &flags);
606	if (dres != ISC_R_SUCCESS) {
607		free_buffer(disp, ev->region.base, ev->region.length);
608		dispatch_log(disp, LVL(10), "got garbage packet");
609		goto restart;
610	}
611
612	dispatch_log(disp, LVL(92),
613		     "got valid DNS message header, /QR %c, id %u",
614		     ((flags & DNS_MESSAGEFLAG_QR) ? '1' : '0'), id);
615
616	/*
617	 * Look at flags.  If query, drop it. If response,
618	 * look to see where it goes.
619	 */
620	queue_response = ISC_FALSE;
621	if ((flags & DNS_MESSAGEFLAG_QR) == 0) {
622		/* query */
623		free_buffer(disp, ev->region.base, ev->region.length);
624		goto restart;
625	}
626
627	dns_dispatch_hash(&ev->timestamp, sizeof(&ev->timestamp));
628	dns_dispatch_hash(ev->region.base, ev->region.length);
629
630	/* response */
631	bucket = dns_hash(qid, &ev->address, id);
632	LOCK(&qid->lock);
633	resp = bucket_search(qid, &ev->address, id, bucket);
634	dispatch_log(disp, LVL(90),
635		     "search for response in bucket %d: %s",
636		     bucket, (resp == NULL ? "not found" : "found"));
637
638	if (resp == NULL) {
639		free_buffer(disp, ev->region.base, ev->region.length);
640		goto unlock;
641	}
642
643	/*
644	 * Now that we have the original dispatch the query was sent
645	 * from check that the address and port the response was
646	 * sent to make sense.
647	 */
648	if (disp != resp->disp) {
649		isc_sockaddr_t a1;
650		isc_sockaddr_t a2;
651
652		/*
653		 * Check that the socket types and ports match.
654		 */
655		if (disp->socktype != resp->disp->socktype ||
656		    isc_sockaddr_getport(&disp->local) !=
657		    isc_sockaddr_getport(&resp->disp->local)) {
658			free_buffer(disp, ev->region.base, ev->region.length);
659			goto unlock;
660		}
661
662		/*
663		 * If both dispatches are bound to an address then fail as
664		 * the addresses can't be equal (enforced by the IP stack).
665		 *
666		 * Note under Linux a packet can be sent out via IPv4 socket
667		 * and the response be received via a IPv6 socket.
668		 *
669		 * Requests sent out via IPv6 should always come back in
670		 * via IPv6.
671		 */
672		if (isc_sockaddr_pf(&resp->disp->local) == PF_INET6 &&
673		    isc_sockaddr_pf(&disp->local) != PF_INET6) {
674			free_buffer(disp, ev->region.base, ev->region.length);
675			goto unlock;
676		}
677		isc_sockaddr_anyofpf(&a1, isc_sockaddr_pf(&resp->disp->local));
678		isc_sockaddr_anyofpf(&a2, isc_sockaddr_pf(&disp->local));
679		if (!isc_sockaddr_eqaddr(&a1, &resp->disp->local) &&
680		    !isc_sockaddr_eqaddr(&a2, &disp->local)) {
681			free_buffer(disp, ev->region.base, ev->region.length);
682			goto unlock;
683		}
684	}
685
686	queue_response = resp->item_out;
687	rev = allocate_event(resp->disp);
688	if (rev == NULL) {
689		free_buffer(disp, ev->region.base, ev->region.length);
690		goto unlock;
691	}
692
693	/*
694	 * At this point, rev contains the event we want to fill in, and
695	 * resp contains the information on the place to send it to.
696	 * Send the event off.
697	 */
698	isc_buffer_init(&rev->buffer, ev->region.base, ev->region.length);
699	isc_buffer_add(&rev->buffer, ev->n);
700	rev->result = ISC_R_SUCCESS;
701	rev->id = id;
702	rev->addr = ev->address;
703	rev->pktinfo = ev->pktinfo;
704	rev->attributes = ev->attributes;
705	if (queue_response) {
706		ISC_LIST_APPEND(resp->items, rev, ev_link);
707	} else {
708		ISC_EVENT_INIT(rev, sizeof(*rev), 0, NULL,
709			       DNS_EVENT_DISPATCH,
710			       resp->action, resp->arg, resp, NULL, NULL);
711		request_log(disp, resp, LVL(90),
712			    "[a] Sent event %p buffer %p len %d to task %p",
713			    rev, rev->buffer.base, rev->buffer.length,
714			    resp->task);
715		resp->item_out = ISC_TRUE;
716		isc_task_send(resp->task, ISC_EVENT_PTR(&rev));
717	}
718 unlock:
719	UNLOCK(&qid->lock);
720
721	/*
722	 * Restart recv() to get the next packet.
723	 */
724 restart:
725	startrecv(disp);
726
727	UNLOCK(&disp->lock);
728
729	isc_event_free(&ev_in);
730}
731
732/*
733 * General flow:
734 *
735 * If I/O result == CANCELED, EOF, or error, notify everyone as the
736 * various queues drain.
737 *
738 * If query, restart.
739 *
740 * If response:
741 *	Allocate event, fill in details.
742 *		If cannot allocate, restart.
743 *	find target.  If not found, restart.
744 *	if event queue is not empty, queue.  else, send.
745 *	restart.
746 */
747static void
748tcp_recv(isc_task_t *task, isc_event_t *ev_in) {
749	dns_dispatch_t *disp = ev_in->ev_arg;
750	dns_tcpmsg_t *tcpmsg = &disp->tcpmsg;
751	dns_messageid_t id;
752	isc_result_t dres;
753	unsigned int flags;
754	dns_dispentry_t *resp;
755	dns_dispatchevent_t *rev;
756	unsigned int bucket;
757	isc_boolean_t killit;
758	isc_boolean_t queue_response;
759	dns_qid_t *qid;
760	int level;
761	char buf[ISC_SOCKADDR_FORMATSIZE];
762
763	UNUSED(task);
764
765	REQUIRE(VALID_DISPATCH(disp));
766
767	qid = disp->qid;
768
769	dispatch_log(disp, LVL(90),
770		     "got TCP packet: requests %d, buffers %d, recvs %d",
771		     disp->requests, disp->tcpbuffers, disp->recv_pending);
772
773	LOCK(&disp->lock);
774
775	INSIST(disp->recv_pending != 0);
776	disp->recv_pending = 0;
777
778	if (disp->refcount == 0) {
779		/*
780		 * This dispatcher is shutting down.  Force cancelation.
781		 */
782		tcpmsg->result = ISC_R_CANCELED;
783	}
784
785	if (tcpmsg->result != ISC_R_SUCCESS) {
786		switch (tcpmsg->result) {
787		case ISC_R_CANCELED:
788			break;
789
790		case ISC_R_EOF:
791			dispatch_log(disp, LVL(90), "shutting down on EOF");
792			do_cancel(disp);
793			break;
794
795		case ISC_R_CONNECTIONRESET:
796			level = ISC_LOG_INFO;
797			goto logit;
798
799		default:
800			level = ISC_LOG_ERROR;
801		logit:
802			isc_sockaddr_format(&tcpmsg->address, buf, sizeof(buf));
803			dispatch_log(disp, level, "shutting down due to TCP "
804				     "receive error: %s: %s", buf,
805				     isc_result_totext(tcpmsg->result));
806			do_cancel(disp);
807			break;
808		}
809
810		/*
811		 * The event is statically allocated in the tcpmsg
812		 * structure, and destroy_disp() frees the tcpmsg, so we must
813		 * free the event *before* calling destroy_disp().
814		 */
815		isc_event_free(&ev_in);
816
817		disp->shutting_down = 1;
818		disp->shutdown_why = tcpmsg->result;
819
820		/*
821		 * If the recv() was canceled pass the word on.
822		 */
823		killit = destroy_disp_ok(disp);
824		UNLOCK(&disp->lock);
825		if (killit)
826			isc_task_send(disp->task, &disp->ctlevent);
827		return;
828	}
829
830	dispatch_log(disp, LVL(90), "result %d, length == %d, addr = %p",
831		     tcpmsg->result,
832		     tcpmsg->buffer.length, tcpmsg->buffer.base);
833
834	/*
835	 * Peek into the buffer to see what we can see.
836	 */
837	dres = dns_message_peekheader(&tcpmsg->buffer, &id, &flags);
838	if (dres != ISC_R_SUCCESS) {
839		dispatch_log(disp, LVL(10), "got garbage packet");
840		goto restart;
841	}
842
843	dispatch_log(disp, LVL(92),
844		     "got valid DNS message header, /QR %c, id %u",
845		     ((flags & DNS_MESSAGEFLAG_QR) ? '1' : '0'), id);
846
847	/*
848	 * Allocate an event to send to the query or response client, and
849	 * allocate a new buffer for our use.
850	 */
851
852	/*
853	 * Look at flags.  If query, drop it. If response,
854	 * look to see where it goes.
855	 */
856	queue_response = ISC_FALSE;
857	if ((flags & DNS_MESSAGEFLAG_QR) == 0) {
858		/*
859		 * Query.
860		 */
861		goto restart;
862	}
863
864	dns_dispatch_hash(tcpmsg->buffer.base, tcpmsg->buffer.length);
865
866	/*
867	 * Response.
868	 */
869	bucket = dns_hash(qid, &tcpmsg->address, id);
870	LOCK(&qid->lock);
871	resp = bucket_search(qid, &tcpmsg->address, id, bucket);
872	dispatch_log(disp, LVL(90),
873		     "search for response in bucket %d: %s",
874		     bucket, (resp == NULL ? "not found" : "found"));
875
876	if (resp == NULL)
877		goto unlock;
878	queue_response = resp->item_out;
879	rev = allocate_event(disp);
880	if (rev == NULL)
881		goto unlock;
882
883	/*
884	 * At this point, rev contains the event we want to fill in, and
885	 * resp contains the information on the place to send it to.
886	 * Send the event off.
887	 */
888	dns_tcpmsg_keepbuffer(tcpmsg, &rev->buffer);
889	disp->tcpbuffers++;
890	rev->result = ISC_R_SUCCESS;
891	rev->id = id;
892	rev->addr = tcpmsg->address;
893	if (queue_response) {
894		ISC_LIST_APPEND(resp->items, rev, ev_link);
895	} else {
896		ISC_EVENT_INIT(rev, sizeof(*rev), 0, NULL, DNS_EVENT_DISPATCH,
897			       resp->action, resp->arg, resp, NULL, NULL);
898		request_log(disp, resp, LVL(90),
899			    "[b] Sent event %p buffer %p len %d to task %p",
900			    rev, rev->buffer.base, rev->buffer.length,
901			    resp->task);
902		resp->item_out = ISC_TRUE;
903		isc_task_send(resp->task, ISC_EVENT_PTR(&rev));
904	}
905 unlock:
906	UNLOCK(&qid->lock);
907
908	/*
909	 * Restart recv() to get the next packet.
910	 */
911 restart:
912	startrecv(disp);
913
914	UNLOCK(&disp->lock);
915
916	isc_event_free(&ev_in);
917}
918
919/*
920 * disp must be locked.
921 */
922static void
923startrecv(dns_dispatch_t *disp) {
924	isc_result_t res;
925	isc_region_t region;
926
927	if (disp->shutting_down == 1)
928		return;
929
930	if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) != 0)
931		return;
932
933	if (disp->recv_pending != 0)
934		return;
935
936	if (disp->mgr->buffers >= disp->mgr->maxbuffers)
937		return;
938
939	switch (disp->socktype) {
940		/*
941		 * UDP reads are always maximal.
942		 */
943	case isc_sockettype_udp:
944		region.length = disp->mgr->buffersize;
945		region.base = allocate_udp_buffer(disp);
946		if (region.base == NULL)
947			return;
948		res = isc_socket_recv(disp->socket, &region, 1,
949				      disp->task, udp_recv, disp);
950		if (res != ISC_R_SUCCESS) {
951			free_buffer(disp, region.base, region.length);
952			disp->shutdown_why = res;
953			disp->shutting_down = 1;
954			do_cancel(disp);
955			return;
956		}
957		INSIST(disp->recv_pending == 0);
958		disp->recv_pending = 1;
959		break;
960
961	case isc_sockettype_tcp:
962		res = dns_tcpmsg_readmessage(&disp->tcpmsg, disp->task,
963					     tcp_recv, disp);
964		if (res != ISC_R_SUCCESS) {
965			disp->shutdown_why = res;
966			disp->shutting_down = 1;
967			do_cancel(disp);
968			return;
969		}
970		INSIST(disp->recv_pending == 0);
971		disp->recv_pending = 1;
972		break;
973	default:
974		INSIST(0);
975		break;
976	}
977}
978
979/*
980 * Mgr must be locked when calling this function.
981 */
982static isc_boolean_t
983destroy_mgr_ok(dns_dispatchmgr_t *mgr) {
984	mgr_log(mgr, LVL(90),
985		"destroy_mgr_ok: shuttingdown=%d, listnonempty=%d, "
986		"epool=%d, rpool=%d, dpool=%d",
987		MGR_IS_SHUTTINGDOWN(mgr), !ISC_LIST_EMPTY(mgr->list),
988		isc_mempool_getallocated(mgr->epool),
989		isc_mempool_getallocated(mgr->rpool),
990		isc_mempool_getallocated(mgr->dpool));
991	if (!MGR_IS_SHUTTINGDOWN(mgr))
992		return (ISC_FALSE);
993	if (!ISC_LIST_EMPTY(mgr->list))
994		return (ISC_FALSE);
995	if (isc_mempool_getallocated(mgr->epool) != 0)
996		return (ISC_FALSE);
997	if (isc_mempool_getallocated(mgr->rpool) != 0)
998		return (ISC_FALSE);
999	if (isc_mempool_getallocated(mgr->dpool) != 0)
1000		return (ISC_FALSE);
1001
1002	return (ISC_TRUE);
1003}
1004
1005/*
1006 * Mgr must be unlocked when calling this function.
1007 */
1008static void
1009destroy_mgr(dns_dispatchmgr_t **mgrp) {
1010	isc_mem_t *mctx;
1011	dns_dispatchmgr_t *mgr;
1012
1013	mgr = *mgrp;
1014	*mgrp = NULL;
1015
1016	mctx = mgr->mctx;
1017
1018	mgr->magic = 0;
1019	mgr->mctx = NULL;
1020	DESTROYLOCK(&mgr->lock);
1021	mgr->state = 0;
1022
1023	isc_mempool_destroy(&mgr->epool);
1024	isc_mempool_destroy(&mgr->rpool);
1025	isc_mempool_destroy(&mgr->dpool);
1026	isc_mempool_destroy(&mgr->bpool);
1027
1028	DESTROYLOCK(&mgr->pool_lock);
1029
1030	if (mgr->entropy != NULL)
1031		isc_entropy_detach(&mgr->entropy);
1032	if (mgr->qid != NULL)
1033		qid_destroy(mctx, &mgr->qid);
1034
1035	DESTROYLOCK(&mgr->buffer_lock);
1036
1037	if (mgr->blackhole != NULL)
1038		dns_acl_detach(&mgr->blackhole);
1039
1040	if (mgr->portlist != NULL)
1041		dns_portlist_detach(&mgr->portlist);
1042
1043	isc_mem_put(mctx, mgr, sizeof(dns_dispatchmgr_t));
1044	isc_mem_detach(&mctx);
1045}
1046
1047static isc_result_t
1048create_socket(isc_socketmgr_t *mgr, isc_sockaddr_t *local,
1049	      isc_socket_t **sockp)
1050{
1051	isc_socket_t *sock;
1052	isc_result_t result;
1053
1054	sock = NULL;
1055	result = isc_socket_create(mgr, isc_sockaddr_pf(local),
1056				   isc_sockettype_udp, &sock);
1057	if (result != ISC_R_SUCCESS)
1058		return (result);
1059
1060#ifndef ISC_ALLOW_MAPPED
1061	isc_socket_ipv6only(sock, ISC_TRUE);
1062#endif
1063	result = isc_socket_bind(sock, local);
1064	if (result != ISC_R_SUCCESS) {
1065		isc_socket_detach(&sock);
1066		return (result);
1067	}
1068
1069	*sockp = sock;
1070	return (ISC_R_SUCCESS);
1071}
1072
1073/*
1074 * Publics.
1075 */
1076
1077isc_result_t
1078dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy,
1079		       dns_dispatchmgr_t **mgrp)
1080{
1081	dns_dispatchmgr_t *mgr;
1082	isc_result_t result;
1083
1084	REQUIRE(mctx != NULL);
1085	REQUIRE(mgrp != NULL && *mgrp == NULL);
1086
1087	mgr = isc_mem_get(mctx, sizeof(dns_dispatchmgr_t));
1088	if (mgr == NULL)
1089		return (ISC_R_NOMEMORY);
1090
1091	mgr->mctx = NULL;
1092	isc_mem_attach(mctx, &mgr->mctx);
1093
1094	mgr->blackhole = NULL;
1095	mgr->portlist = NULL;
1096
1097	result = isc_mutex_init(&mgr->lock);
1098	if (result != ISC_R_SUCCESS)
1099		goto deallocate;
1100
1101	result = isc_mutex_init(&mgr->buffer_lock);
1102	if (result != ISC_R_SUCCESS)
1103		goto kill_lock;
1104
1105	result = isc_mutex_init(&mgr->pool_lock);
1106	if (result != ISC_R_SUCCESS)
1107		goto kill_buffer_lock;
1108
1109	mgr->epool = NULL;
1110	if (isc_mempool_create(mgr->mctx, sizeof(dns_dispatchevent_t),
1111			       &mgr->epool) != ISC_R_SUCCESS) {
1112		result = ISC_R_NOMEMORY;
1113		goto kill_pool_lock;
1114	}
1115
1116	mgr->rpool = NULL;
1117	if (isc_mempool_create(mgr->mctx, sizeof(dns_dispentry_t),
1118			       &mgr->rpool) != ISC_R_SUCCESS) {
1119		result = ISC_R_NOMEMORY;
1120		goto kill_epool;
1121	}
1122
1123	mgr->dpool = NULL;
1124	if (isc_mempool_create(mgr->mctx, sizeof(dns_dispatch_t),
1125			       &mgr->dpool) != ISC_R_SUCCESS) {
1126		result = ISC_R_NOMEMORY;
1127		goto kill_rpool;
1128	}
1129
1130	isc_mempool_setname(mgr->epool, "dispmgr_epool");
1131	isc_mempool_setfreemax(mgr->epool, 1024);
1132	isc_mempool_associatelock(mgr->epool, &mgr->pool_lock);
1133
1134	isc_mempool_setname(mgr->rpool, "dispmgr_rpool");
1135	isc_mempool_setfreemax(mgr->rpool, 1024);
1136	isc_mempool_associatelock(mgr->rpool, &mgr->pool_lock);
1137
1138	isc_mempool_setname(mgr->dpool, "dispmgr_dpool");
1139	isc_mempool_setfreemax(mgr->dpool, 1024);
1140	isc_mempool_associatelock(mgr->dpool, &mgr->pool_lock);
1141
1142	mgr->buffers = 0;
1143	mgr->buffersize = 0;
1144	mgr->maxbuffers = 0;
1145	mgr->bpool = NULL;
1146	mgr->entropy = NULL;
1147	mgr->qid = NULL;
1148	mgr->state = 0;
1149	ISC_LIST_INIT(mgr->list);
1150	mgr->magic = DNS_DISPATCHMGR_MAGIC;
1151
1152	if (entropy != NULL)
1153		isc_entropy_attach(entropy, &mgr->entropy);
1154
1155	*mgrp = mgr;
1156	return (ISC_R_SUCCESS);
1157
1158 kill_rpool:
1159	isc_mempool_destroy(&mgr->rpool);
1160 kill_epool:
1161	isc_mempool_destroy(&mgr->epool);
1162 kill_pool_lock:
1163	DESTROYLOCK(&mgr->pool_lock);
1164 kill_buffer_lock:
1165	DESTROYLOCK(&mgr->buffer_lock);
1166 kill_lock:
1167	DESTROYLOCK(&mgr->lock);
1168 deallocate:
1169	isc_mem_put(mctx, mgr, sizeof(dns_dispatchmgr_t));
1170	isc_mem_detach(&mctx);
1171
1172	return (result);
1173}
1174
1175void
1176dns_dispatchmgr_setblackhole(dns_dispatchmgr_t *mgr, dns_acl_t *blackhole) {
1177	REQUIRE(VALID_DISPATCHMGR(mgr));
1178	if (mgr->blackhole != NULL)
1179		dns_acl_detach(&mgr->blackhole);
1180	dns_acl_attach(blackhole, &mgr->blackhole);
1181}
1182
1183dns_acl_t *
1184dns_dispatchmgr_getblackhole(dns_dispatchmgr_t *mgr) {
1185	REQUIRE(VALID_DISPATCHMGR(mgr));
1186	return (mgr->blackhole);
1187}
1188
1189void
1190dns_dispatchmgr_setblackportlist(dns_dispatchmgr_t *mgr,
1191				 dns_portlist_t *portlist)
1192{
1193	REQUIRE(VALID_DISPATCHMGR(mgr));
1194	if (mgr->portlist != NULL)
1195		dns_portlist_detach(&mgr->portlist);
1196	if (portlist != NULL)
1197		dns_portlist_attach(portlist, &mgr->portlist);
1198}
1199
1200dns_portlist_t *
1201dns_dispatchmgr_getblackportlist(dns_dispatchmgr_t *mgr) {
1202	REQUIRE(VALID_DISPATCHMGR(mgr));
1203	return (mgr->portlist);
1204}
1205
1206static isc_result_t
1207dns_dispatchmgr_setudp(dns_dispatchmgr_t *mgr,
1208			unsigned int buffersize, unsigned int maxbuffers,
1209			unsigned int buckets, unsigned int increment)
1210{
1211	isc_result_t result;
1212
1213	REQUIRE(VALID_DISPATCHMGR(mgr));
1214	REQUIRE(buffersize >= 512 && buffersize < (64 * 1024));
1215	REQUIRE(maxbuffers > 0);
1216	REQUIRE(buckets < 2097169);  /* next prime > 65536 * 32 */
1217	REQUIRE(increment > buckets);
1218
1219	/*
1220	 * Keep some number of items around.  This should be a config
1221	 * option.  For now, keep 8, but later keep at least two even
1222	 * if the caller wants less.  This allows us to ensure certain
1223	 * things, like an event can be "freed" and the next allocation
1224	 * will always succeed.
1225	 *
1226	 * Note that if limits are placed on anything here, we use one
1227	 * event internally, so the actual limit should be "wanted + 1."
1228	 *
1229	 * XXXMLG
1230	 */
1231
1232	if (maxbuffers < 8)
1233		maxbuffers = 8;
1234
1235	LOCK(&mgr->buffer_lock);
1236	if (mgr->bpool != NULL) {
1237		isc_mempool_setmaxalloc(mgr->bpool, maxbuffers);
1238		mgr->maxbuffers = maxbuffers;
1239		UNLOCK(&mgr->buffer_lock);
1240		return (ISC_R_SUCCESS);
1241	}
1242
1243	if (isc_mempool_create(mgr->mctx, buffersize,
1244			       &mgr->bpool) != ISC_R_SUCCESS) {
1245		UNLOCK(&mgr->buffer_lock);
1246		return (ISC_R_NOMEMORY);
1247	}
1248
1249	isc_mempool_setname(mgr->bpool, "dispmgr_bpool");
1250	isc_mempool_setmaxalloc(mgr->bpool, maxbuffers);
1251	isc_mempool_associatelock(mgr->bpool, &mgr->pool_lock);
1252
1253	result = qid_allocate(mgr, buckets, increment, ISC_TRUE, &mgr->qid);
1254	if (result != ISC_R_SUCCESS)
1255		goto cleanup;
1256
1257	mgr->buffersize = buffersize;
1258	mgr->maxbuffers = maxbuffers;
1259	UNLOCK(&mgr->buffer_lock);
1260	return (ISC_R_SUCCESS);
1261
1262 cleanup:
1263	isc_mempool_destroy(&mgr->bpool);
1264	UNLOCK(&mgr->buffer_lock);
1265	return (ISC_R_NOMEMORY);
1266}
1267
1268void
1269dns_dispatchmgr_destroy(dns_dispatchmgr_t **mgrp) {
1270	dns_dispatchmgr_t *mgr;
1271	isc_boolean_t killit;
1272
1273	REQUIRE(mgrp != NULL);
1274	REQUIRE(VALID_DISPATCHMGR(*mgrp));
1275
1276	mgr = *mgrp;
1277	*mgrp = NULL;
1278
1279	LOCK(&mgr->lock);
1280	mgr->state |= MGR_SHUTTINGDOWN;
1281
1282	killit = destroy_mgr_ok(mgr);
1283	UNLOCK(&mgr->lock);
1284
1285	mgr_log(mgr, LVL(90), "destroy: killit=%d", killit);
1286
1287	if (killit)
1288		destroy_mgr(&mgr);
1289}
1290
1291static isc_boolean_t
1292blacklisted(dns_dispatchmgr_t *mgr, isc_socket_t *sock) {
1293	isc_sockaddr_t sockaddr;
1294	isc_result_t result;
1295
1296	if (mgr->portlist == NULL)
1297		return (ISC_FALSE);
1298
1299	result = isc_socket_getsockname(sock, &sockaddr);
1300	if (result != ISC_R_SUCCESS)
1301		return (ISC_FALSE);
1302
1303	if (mgr->portlist != NULL &&
1304	    dns_portlist_match(mgr->portlist, isc_sockaddr_pf(&sockaddr),
1305			       isc_sockaddr_getport(&sockaddr)))
1306		return (ISC_TRUE);
1307	return (ISC_FALSE);
1308}
1309
1310#define ATTRMATCH(_a1, _a2, _mask) (((_a1) & (_mask)) == ((_a2) & (_mask)))
1311
1312static isc_boolean_t
1313local_addr_match(dns_dispatch_t *disp, isc_sockaddr_t *addr) {
1314	isc_sockaddr_t sockaddr;
1315	isc_result_t result;
1316
1317	if (addr == NULL)
1318		return (ISC_TRUE);
1319
1320	/*
1321	 * Don't match wildcard ports against newly blacklisted ports.
1322	 */
1323	if (disp->mgr->portlist != NULL &&
1324	    isc_sockaddr_getport(addr) == 0 &&
1325	    isc_sockaddr_getport(&disp->local) == 0 &&
1326	    blacklisted(disp->mgr, disp->socket))
1327		return (ISC_FALSE);
1328
1329	/*
1330	 * Check if we match the binding <address,port>.
1331	 * Wildcard ports match/fail here.
1332	 */
1333	if (isc_sockaddr_equal(&disp->local, addr))
1334		return (ISC_TRUE);
1335	if (isc_sockaddr_getport(addr) == 0)
1336		return (ISC_FALSE);
1337
1338	/*
1339	 * Check if we match a bound wildcard port <address,port>.
1340	 */
1341	if (!isc_sockaddr_eqaddr(&disp->local, addr))
1342		return (ISC_FALSE);
1343	result = isc_socket_getsockname(disp->socket, &sockaddr);
1344	if (result != ISC_R_SUCCESS)
1345		return (ISC_FALSE);
1346
1347	return (isc_sockaddr_equal(&sockaddr, addr));
1348}
1349
1350/*
1351 * Requires mgr be locked.
1352 *
1353 * No dispatcher can be locked by this thread when calling this function.
1354 *
1355 *
1356 * NOTE:
1357 *	If a matching dispatcher is found, it is locked after this function
1358 *	returns, and must be unlocked by the caller.
1359 */
1360static isc_result_t
1361dispatch_find(dns_dispatchmgr_t *mgr, isc_sockaddr_t *local,
1362	      unsigned int attributes, unsigned int mask,
1363	      dns_dispatch_t **dispp)
1364{
1365	dns_dispatch_t *disp;
1366	isc_result_t result;
1367
1368	/*
1369	 * Make certain that we will not match a private dispatch.
1370	 */
1371	attributes &= ~DNS_DISPATCHATTR_PRIVATE;
1372	mask |= DNS_DISPATCHATTR_PRIVATE;
1373
1374	disp = ISC_LIST_HEAD(mgr->list);
1375	while (disp != NULL) {
1376		LOCK(&disp->lock);
1377		if ((disp->shutting_down == 0)
1378		    && ATTRMATCH(disp->attributes, attributes, mask)
1379		    && local_addr_match(disp, local))
1380			break;
1381		UNLOCK(&disp->lock);
1382		disp = ISC_LIST_NEXT(disp, link);
1383	}
1384
1385	if (disp == NULL) {
1386		result = ISC_R_NOTFOUND;
1387		goto out;
1388	}
1389
1390	*dispp = disp;
1391	result = ISC_R_SUCCESS;
1392 out:
1393
1394	return (result);
1395}
1396
1397static isc_result_t
1398qid_allocate(dns_dispatchmgr_t *mgr, unsigned int buckets,
1399	     unsigned int increment, isc_boolean_t usepool, dns_qid_t **qidp)
1400{
1401	dns_qid_t *qid;
1402	unsigned int i;
1403	isc_result_t result;
1404
1405	REQUIRE(VALID_DISPATCHMGR(mgr));
1406	REQUIRE(buckets < 2097169);  /* next prime > 65536 * 32 */
1407	REQUIRE(increment > buckets);
1408	REQUIRE(qidp != NULL && *qidp == NULL);
1409
1410	qid = isc_mem_get(mgr->mctx, sizeof(*qid));
1411	if (qid == NULL)
1412		return (ISC_R_NOMEMORY);
1413
1414	qid->qid_table = isc_mem_get(mgr->mctx,
1415				     buckets * sizeof(dns_displist_t));
1416	if (qid->qid_table == NULL) {
1417		isc_mem_put(mgr->mctx, qid, sizeof(*qid));
1418		return (ISC_R_NOMEMORY);
1419	}
1420
1421	result = nsid_init(mgr->mctx, &qid->nsid, usepool);
1422	if (result != ISC_R_SUCCESS) {
1423		isc_mem_put(mgr->mctx, qid->qid_table,
1424			    buckets * sizeof(dns_displist_t));
1425		isc_mem_put(mgr->mctx, qid, sizeof(*qid));
1426		return (ISC_R_NOMEMORY);
1427	}
1428
1429	result = isc_mutex_init(&qid->lock);
1430	if (result != ISC_R_SUCCESS) {
1431		nsid_destroy(mgr->mctx, &qid->nsid);
1432		isc_mem_put(mgr->mctx, qid->qid_table,
1433			    buckets * sizeof(dns_displist_t));
1434		isc_mem_put(mgr->mctx, qid, sizeof(*qid));
1435		return (result);
1436	}
1437
1438	for (i = 0; i < buckets; i++)
1439		ISC_LIST_INIT(qid->qid_table[i]);
1440
1441	qid->qid_nbuckets = buckets;
1442	qid->qid_increment = increment;
1443	qid->magic = QID_MAGIC;
1444	*qidp = qid;
1445	return (ISC_R_SUCCESS);
1446}
1447
1448static void
1449qid_destroy(isc_mem_t *mctx, dns_qid_t **qidp) {
1450	dns_qid_t *qid;
1451
1452	REQUIRE(qidp != NULL);
1453	qid = *qidp;
1454
1455	REQUIRE(VALID_QID(qid));
1456
1457	*qidp = NULL;
1458	qid->magic = 0;
1459	nsid_destroy(mctx, &qid->nsid);
1460	isc_mem_put(mctx, qid->qid_table,
1461		    qid->qid_nbuckets * sizeof(dns_displist_t));
1462	DESTROYLOCK(&qid->lock);
1463	isc_mem_put(mctx, qid, sizeof(*qid));
1464}
1465
1466/*
1467 * Allocate and set important limits.
1468 */
1469static isc_result_t
1470dispatch_allocate(dns_dispatchmgr_t *mgr, unsigned int maxrequests,
1471		  dns_dispatch_t **dispp)
1472{
1473	dns_dispatch_t *disp;
1474	isc_result_t result;
1475
1476	REQUIRE(VALID_DISPATCHMGR(mgr));
1477	REQUIRE(dispp != NULL && *dispp == NULL);
1478
1479	/*
1480	 * Set up the dispatcher, mostly.  Don't bother setting some of
1481	 * the options that are controlled by tcp vs. udp, etc.
1482	 */
1483
1484	disp = isc_mempool_get(mgr->dpool);
1485	if (disp == NULL)
1486		return (ISC_R_NOMEMORY);
1487
1488	disp->magic = 0;
1489	disp->mgr = mgr;
1490	disp->maxrequests = maxrequests;
1491	disp->attributes = 0;
1492	ISC_LINK_INIT(disp, link);
1493	disp->refcount = 1;
1494	disp->recv_pending = 0;
1495	memset(&disp->local, 0, sizeof(disp->local));
1496	disp->shutting_down = 0;
1497	disp->shutdown_out = 0;
1498	disp->connected = 0;
1499	disp->tcpmsg_valid = 0;
1500	disp->shutdown_why = ISC_R_UNEXPECTED;
1501	disp->requests = 0;
1502	disp->tcpbuffers = 0;
1503	disp->qid = NULL;
1504
1505	result = isc_mutex_init(&disp->lock);
1506	if (result != ISC_R_SUCCESS)
1507		goto deallocate;
1508
1509	disp->failsafe_ev = allocate_event(disp);
1510	if (disp->failsafe_ev == NULL) {
1511		result = ISC_R_NOMEMORY;
1512		goto kill_lock;
1513	}
1514
1515	disp->magic = DISPATCH_MAGIC;
1516
1517	*dispp = disp;
1518	return (ISC_R_SUCCESS);
1519
1520	/*
1521	 * error returns
1522	 */
1523 kill_lock:
1524	DESTROYLOCK(&disp->lock);
1525 deallocate:
1526	isc_mempool_put(mgr->dpool, disp);
1527
1528	return (result);
1529}
1530
1531
1532/*
1533 * MUST be unlocked, and not used by anthing.
1534 */
1535static void
1536dispatch_free(dns_dispatch_t **dispp)
1537{
1538	dns_dispatch_t *disp;
1539	dns_dispatchmgr_t *mgr;
1540
1541	REQUIRE(VALID_DISPATCH(*dispp));
1542	disp = *dispp;
1543	*dispp = NULL;
1544
1545	mgr = disp->mgr;
1546	REQUIRE(VALID_DISPATCHMGR(mgr));
1547
1548	if (disp->tcpmsg_valid) {
1549		dns_tcpmsg_invalidate(&disp->tcpmsg);
1550		disp->tcpmsg_valid = 0;
1551	}
1552
1553	INSIST(disp->tcpbuffers == 0);
1554	INSIST(disp->requests == 0);
1555	INSIST(disp->recv_pending == 0);
1556
1557	isc_mempool_put(mgr->epool, disp->failsafe_ev);
1558	disp->failsafe_ev = NULL;
1559
1560	if (disp->qid != NULL)
1561		qid_destroy(mgr->mctx, &disp->qid);
1562	disp->mgr = NULL;
1563	DESTROYLOCK(&disp->lock);
1564	disp->magic = 0;
1565	isc_mempool_put(mgr->dpool, disp);
1566}
1567
1568isc_result_t
1569dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
1570		       isc_taskmgr_t *taskmgr, unsigned int buffersize,
1571		       unsigned int maxbuffers, unsigned int maxrequests,
1572		       unsigned int buckets, unsigned int increment,
1573		       unsigned int attributes, dns_dispatch_t **dispp)
1574{
1575	isc_result_t result;
1576	dns_dispatch_t *disp;
1577
1578	UNUSED(maxbuffers);
1579	UNUSED(buffersize);
1580
1581	REQUIRE(VALID_DISPATCHMGR(mgr));
1582	REQUIRE(isc_socket_gettype(sock) == isc_sockettype_tcp);
1583	REQUIRE((attributes & DNS_DISPATCHATTR_TCP) != 0);
1584	REQUIRE((attributes & DNS_DISPATCHATTR_UDP) == 0);
1585
1586	attributes |= DNS_DISPATCHATTR_PRIVATE;  /* XXXMLG */
1587
1588	LOCK(&mgr->lock);
1589
1590	/*
1591	 * dispatch_allocate() checks mgr for us.
1592	 * qid_allocate() checks buckets and increment for us.
1593	 */
1594	disp = NULL;
1595	result = dispatch_allocate(mgr, maxrequests, &disp);
1596	if (result != ISC_R_SUCCESS) {
1597		UNLOCK(&mgr->lock);
1598		return (result);
1599	}
1600
1601	result = qid_allocate(mgr, buckets, increment, ISC_FALSE, &disp->qid);
1602	if (result != ISC_R_SUCCESS)
1603		goto deallocate_dispatch;
1604
1605	disp->socktype = isc_sockettype_tcp;
1606	disp->socket = NULL;
1607	isc_socket_attach(sock, &disp->socket);
1608
1609	disp->task = NULL;
1610	result = isc_task_create(taskmgr, 0, &disp->task);
1611	if (result != ISC_R_SUCCESS)
1612		goto kill_socket;
1613
1614	disp->ctlevent = isc_event_allocate(mgr->mctx, disp,
1615					    DNS_EVENT_DISPATCHCONTROL,
1616					    destroy_disp, disp,
1617					    sizeof(isc_event_t));
1618	if (disp->ctlevent == NULL)
1619		goto kill_task;
1620
1621	isc_task_setname(disp->task, "tcpdispatch", disp);
1622
1623	dns_tcpmsg_init(mgr->mctx, disp->socket, &disp->tcpmsg);
1624	disp->tcpmsg_valid = 1;
1625
1626	disp->attributes = attributes;
1627
1628	/*
1629	 * Append it to the dispatcher list.
1630	 */
1631	ISC_LIST_APPEND(mgr->list, disp, link);
1632	UNLOCK(&mgr->lock);
1633
1634	mgr_log(mgr, LVL(90), "created TCP dispatcher %p", disp);
1635	dispatch_log(disp, LVL(90), "created task %p", disp->task);
1636
1637	*dispp = disp;
1638
1639	return (ISC_R_SUCCESS);
1640
1641	/*
1642	 * Error returns.
1643	 */
1644 kill_task:
1645	isc_task_detach(&disp->task);
1646 kill_socket:
1647	isc_socket_detach(&disp->socket);
1648 deallocate_dispatch:
1649	dispatch_free(&disp);
1650
1651	UNLOCK(&mgr->lock);
1652
1653	return (result);
1654}
1655
1656isc_result_t
1657dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
1658		    isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr,
1659		    unsigned int buffersize,
1660		    unsigned int maxbuffers, unsigned int maxrequests,
1661		    unsigned int buckets, unsigned int increment,
1662		    unsigned int attributes, unsigned int mask,
1663		    dns_dispatch_t **dispp)
1664{
1665	isc_result_t result;
1666	dns_dispatch_t *disp;
1667
1668	REQUIRE(VALID_DISPATCHMGR(mgr));
1669	REQUIRE(sockmgr != NULL);
1670	REQUIRE(localaddr != NULL);
1671	REQUIRE(taskmgr != NULL);
1672	REQUIRE(buffersize >= 512 && buffersize < (64 * 1024));
1673	REQUIRE(maxbuffers > 0);
1674	REQUIRE(buckets < 2097169);  /* next prime > 65536 * 32 */
1675	REQUIRE(increment > buckets);
1676	REQUIRE(dispp != NULL && *dispp == NULL);
1677	REQUIRE((attributes & DNS_DISPATCHATTR_TCP) == 0);
1678
1679	result = dns_dispatchmgr_setudp(mgr, buffersize, maxbuffers,
1680					buckets, increment);
1681	if (result != ISC_R_SUCCESS)
1682		return (result);
1683
1684	LOCK(&mgr->lock);
1685
1686	/*
1687	 * First, see if we have a dispatcher that matches.
1688	 */
1689	disp = NULL;
1690	result = dispatch_find(mgr, localaddr, attributes, mask, &disp);
1691	if (result == ISC_R_SUCCESS) {
1692		disp->refcount++;
1693
1694		if (disp->maxrequests < maxrequests)
1695			disp->maxrequests = maxrequests;
1696
1697		if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) == 0 &&
1698		    (attributes & DNS_DISPATCHATTR_NOLISTEN) != 0)
1699		{
1700			disp->attributes |= DNS_DISPATCHATTR_NOLISTEN;
1701			if (disp->recv_pending != 0)
1702				isc_socket_cancel(disp->socket, disp->task,
1703						  ISC_SOCKCANCEL_RECV);
1704		}
1705
1706		UNLOCK(&disp->lock);
1707		UNLOCK(&mgr->lock);
1708
1709		*dispp = disp;
1710
1711		return (ISC_R_SUCCESS);
1712	}
1713
1714	/*
1715	 * Nope, create one.
1716	 */
1717	result = dispatch_createudp(mgr, sockmgr, taskmgr, localaddr,
1718				    maxrequests, attributes, &disp);
1719	if (result != ISC_R_SUCCESS) {
1720		UNLOCK(&mgr->lock);
1721		return (result);
1722	}
1723
1724	UNLOCK(&mgr->lock);
1725	*dispp = disp;
1726	return (ISC_R_SUCCESS);
1727}
1728
1729/*
1730 * mgr should be locked.
1731 */
1732
1733#ifndef DNS_DISPATCH_HELD
1734#define DNS_DISPATCH_HELD 20U
1735#endif
1736
1737static isc_result_t
1738dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
1739		   isc_taskmgr_t *taskmgr,
1740		   isc_sockaddr_t *localaddr,
1741		   unsigned int maxrequests,
1742		   unsigned int attributes,
1743		   dns_dispatch_t **dispp)
1744{
1745	isc_result_t result;
1746	dns_dispatch_t *disp;
1747	isc_socket_t *sock = NULL;
1748	isc_socket_t *held[DNS_DISPATCH_HELD];
1749	unsigned int i = 0, j = 0;
1750
1751	/*
1752	 * dispatch_allocate() checks mgr for us.
1753	 */
1754	disp = NULL;
1755	result = dispatch_allocate(mgr, maxrequests, &disp);
1756	if (result != ISC_R_SUCCESS)
1757		return (result);
1758
1759	/*
1760	 * Try to allocate a socket that is not on the blacklist.
1761	 * Hold up to DNS_DISPATCH_HELD sockets to prevent the OS
1762	 * from returning the same port to us too quickly.
1763	 */
1764	memset(held, 0, sizeof(held));
1765 getsocket:
1766	result = create_socket(sockmgr, localaddr, &sock);
1767	if (result != ISC_R_SUCCESS)
1768		goto deallocate_dispatch;
1769	if (isc_sockaddr_getport(localaddr) == 0 && blacklisted(mgr, sock)) {
1770		if (held[i] != NULL)
1771			isc_socket_detach(&held[i]);
1772		held[i++] = sock;
1773		sock = NULL;
1774		if (i == DNS_DISPATCH_HELD)
1775			i = 0;
1776		if (j++ == 0xffffU) {
1777			mgr_log(mgr, ISC_LOG_ERROR, "avoid-v%s-udp-ports: "
1778				"unable to allocate a non-blacklisted port",
1779				isc_sockaddr_pf(localaddr) == AF_INET ?
1780					"4" : "6");
1781			result = ISC_R_FAILURE;
1782			goto deallocate_dispatch;
1783		}
1784		goto getsocket;
1785	}
1786
1787	disp->socktype = isc_sockettype_udp;
1788	disp->socket = sock;
1789	disp->local = *localaddr;
1790
1791	disp->task = NULL;
1792	result = isc_task_create(taskmgr, 0, &disp->task);
1793	if (result != ISC_R_SUCCESS)
1794		goto kill_socket;
1795
1796	disp->ctlevent = isc_event_allocate(mgr->mctx, disp,
1797					    DNS_EVENT_DISPATCHCONTROL,
1798					    destroy_disp, disp,
1799					    sizeof(isc_event_t));
1800	if (disp->ctlevent == NULL)
1801		goto kill_task;
1802
1803	isc_task_setname(disp->task, "udpdispatch", disp);
1804
1805	attributes &= ~DNS_DISPATCHATTR_TCP;
1806	attributes |= DNS_DISPATCHATTR_UDP;
1807	disp->attributes = attributes;
1808
1809	/*
1810	 * Append it to the dispatcher list.
1811	 */
1812	ISC_LIST_APPEND(mgr->list, disp, link);
1813
1814	mgr_log(mgr, LVL(90), "created UDP dispatcher %p", disp);
1815	dispatch_log(disp, LVL(90), "created task %p", disp->task);
1816	dispatch_log(disp, LVL(90), "created socket %p", disp->socket);
1817
1818	*dispp = disp;
1819
1820	goto cleanheld;
1821
1822	/*
1823	 * Error returns.
1824	 */
1825 kill_task:
1826	isc_task_detach(&disp->task);
1827 kill_socket:
1828	isc_socket_detach(&disp->socket);
1829 deallocate_dispatch:
1830	dispatch_free(&disp);
1831 cleanheld:
1832	for (i = 0; i < DNS_DISPATCH_HELD; i++)
1833		if (held[i] != NULL)
1834			isc_socket_detach(&held[i]);
1835	return (result);
1836}
1837
1838void
1839dns_dispatch_attach(dns_dispatch_t *disp, dns_dispatch_t **dispp) {
1840	REQUIRE(VALID_DISPATCH(disp));
1841	REQUIRE(dispp != NULL && *dispp == NULL);
1842
1843	LOCK(&disp->lock);
1844	disp->refcount++;
1845	UNLOCK(&disp->lock);
1846
1847	*dispp = disp;
1848}
1849
1850/*
1851 * It is important to lock the manager while we are deleting the dispatch,
1852 * since dns_dispatch_getudp will call dispatch_find, which returns to
1853 * the caller a dispatch but does not attach to it until later.  _getudp
1854 * locks the manager, however, so locking it here will keep us from attaching
1855 * to a dispatcher that is in the process of going away.
1856 */
1857void
1858dns_dispatch_detach(dns_dispatch_t **dispp) {
1859	dns_dispatch_t *disp;
1860	isc_boolean_t killit;
1861
1862	REQUIRE(dispp != NULL && VALID_DISPATCH(*dispp));
1863
1864	disp = *dispp;
1865	*dispp = NULL;
1866
1867	LOCK(&disp->lock);
1868
1869	INSIST(disp->refcount > 0);
1870	disp->refcount--;
1871	killit = ISC_FALSE;
1872	if (disp->refcount == 0) {
1873		if (disp->recv_pending > 0)
1874			isc_socket_cancel(disp->socket, disp->task,
1875					  ISC_SOCKCANCEL_RECV);
1876		disp->shutting_down = 1;
1877	}
1878
1879	dispatch_log(disp, LVL(90), "detach: refcount %d", disp->refcount);
1880
1881	killit = destroy_disp_ok(disp);
1882	UNLOCK(&disp->lock);
1883	if (killit)
1884		isc_task_send(disp->task, &disp->ctlevent);
1885}
1886
1887isc_result_t
1888dns_dispatch_addresponse(dns_dispatch_t *disp, isc_sockaddr_t *dest,
1889			 isc_task_t *task, isc_taskaction_t action, void *arg,
1890			 dns_messageid_t *idp, dns_dispentry_t **resp)
1891{
1892	dns_dispentry_t *res;
1893	unsigned int bucket;
1894	dns_messageid_t id;
1895	int i;
1896	isc_boolean_t ok;
1897	dns_qid_t *qid;
1898
1899	REQUIRE(VALID_DISPATCH(disp));
1900	REQUIRE(task != NULL);
1901	REQUIRE(dest != NULL);
1902	REQUIRE(resp != NULL && *resp == NULL);
1903	REQUIRE(idp != NULL);
1904
1905	LOCK(&disp->lock);
1906
1907	if (disp->shutting_down == 1) {
1908		UNLOCK(&disp->lock);
1909		return (ISC_R_SHUTTINGDOWN);
1910	}
1911
1912	if (disp->requests >= disp->maxrequests) {
1913		UNLOCK(&disp->lock);
1914		return (ISC_R_QUOTA);
1915	}
1916
1917	/*
1918	 * Try somewhat hard to find an unique ID.
1919	 */
1920	qid = DNS_QID(disp);
1921	LOCK(&qid->lock);
1922	id = dns_randomid(&qid->nsid);
1923	bucket = dns_hash(qid, dest, id);
1924	ok = ISC_FALSE;
1925	for (i = 0; i < 64; i++) {
1926		if (bucket_search(qid, dest, id, bucket) == NULL) {
1927			ok = ISC_TRUE;
1928			break;
1929		}
1930		id += qid->qid_increment;
1931		id &= 0x0000ffff;
1932		bucket = dns_hash(qid, dest, id);
1933	}
1934
1935	if (!ok) {
1936		UNLOCK(&qid->lock);
1937		UNLOCK(&disp->lock);
1938		return (ISC_R_NOMORE);
1939	}
1940
1941	res = isc_mempool_get(disp->mgr->rpool);
1942	if (res == NULL) {
1943		UNLOCK(&qid->lock);
1944		UNLOCK(&disp->lock);
1945		return (ISC_R_NOMEMORY);
1946	}
1947
1948	disp->refcount++;
1949	disp->requests++;
1950	res->task = NULL;
1951	isc_task_attach(task, &res->task);
1952	res->disp = disp;
1953	res->id = id;
1954	res->bucket = bucket;
1955	res->host = *dest;
1956	res->action = action;
1957	res->arg = arg;
1958	res->item_out = ISC_FALSE;
1959	ISC_LIST_INIT(res->items);
1960	ISC_LINK_INIT(res, link);
1961	res->magic = RESPONSE_MAGIC;
1962	ISC_LIST_APPEND(qid->qid_table[bucket], res, link);
1963	UNLOCK(&qid->lock);
1964
1965	request_log(disp, res, LVL(90),
1966		    "attached to task %p", res->task);
1967
1968	if (((disp->attributes & DNS_DISPATCHATTR_UDP) != 0) ||
1969	    ((disp->attributes & DNS_DISPATCHATTR_CONNECTED) != 0))
1970		startrecv(disp);
1971
1972	UNLOCK(&disp->lock);
1973
1974	*idp = id;
1975	*resp = res;
1976
1977	return (ISC_R_SUCCESS);
1978}
1979
1980void
1981dns_dispatch_starttcp(dns_dispatch_t *disp) {
1982
1983	REQUIRE(VALID_DISPATCH(disp));
1984
1985	dispatch_log(disp, LVL(90), "starttcp %p", disp->task);
1986
1987	LOCK(&disp->lock);
1988	disp->attributes |= DNS_DISPATCHATTR_CONNECTED;
1989	startrecv(disp);
1990	UNLOCK(&disp->lock);
1991}
1992
1993void
1994dns_dispatch_removeresponse(dns_dispentry_t **resp,
1995			    dns_dispatchevent_t **sockevent)
1996{
1997	dns_dispatchmgr_t *mgr;
1998	dns_dispatch_t *disp;
1999	dns_dispentry_t *res;
2000	dns_dispatchevent_t *ev;
2001	unsigned int bucket;
2002	isc_boolean_t killit;
2003	unsigned int n;
2004	isc_eventlist_t events;
2005	dns_qid_t *qid;
2006
2007	REQUIRE(resp != NULL);
2008	REQUIRE(VALID_RESPONSE(*resp));
2009
2010	res = *resp;
2011	*resp = NULL;
2012
2013	disp = res->disp;
2014	REQUIRE(VALID_DISPATCH(disp));
2015	mgr = disp->mgr;
2016	REQUIRE(VALID_DISPATCHMGR(mgr));
2017
2018	qid = DNS_QID(disp);
2019
2020	if (sockevent != NULL) {
2021		REQUIRE(*sockevent != NULL);
2022		ev = *sockevent;
2023		*sockevent = NULL;
2024	} else {
2025		ev = NULL;
2026	}
2027
2028	LOCK(&disp->lock);
2029
2030	INSIST(disp->requests > 0);
2031	disp->requests--;
2032	INSIST(disp->refcount > 0);
2033	disp->refcount--;
2034	killit = ISC_FALSE;
2035	if (disp->refcount == 0) {
2036		if (disp->recv_pending > 0)
2037			isc_socket_cancel(disp->socket, disp->task,
2038					  ISC_SOCKCANCEL_RECV);
2039		disp->shutting_down = 1;
2040	}
2041
2042	bucket = res->bucket;
2043
2044	LOCK(&qid->lock);
2045	ISC_LIST_UNLINK(qid->qid_table[bucket], res, link);
2046	UNLOCK(&qid->lock);
2047
2048	if (ev == NULL && res->item_out) {
2049		/*
2050		 * We've posted our event, but the caller hasn't gotten it
2051		 * yet.  Take it back.
2052		 */
2053		ISC_LIST_INIT(events);
2054		n = isc_task_unsend(res->task, res, DNS_EVENT_DISPATCH,
2055				    NULL, &events);
2056		/*
2057		 * We had better have gotten it back.
2058		 */
2059		INSIST(n == 1);
2060		ev = (dns_dispatchevent_t *)ISC_LIST_HEAD(events);
2061	}
2062
2063	if (ev != NULL) {
2064		REQUIRE(res->item_out == ISC_TRUE);
2065		res->item_out = ISC_FALSE;
2066		if (ev->buffer.base != NULL)
2067			free_buffer(disp, ev->buffer.base, ev->buffer.length);
2068		free_event(disp, ev);
2069	}
2070
2071	request_log(disp, res, LVL(90), "detaching from task %p", res->task);
2072	isc_task_detach(&res->task);
2073
2074	/*
2075	 * Free any buffered requests as well
2076	 */
2077	ev = ISC_LIST_HEAD(res->items);
2078	while (ev != NULL) {
2079		ISC_LIST_UNLINK(res->items, ev, ev_link);
2080		if (ev->buffer.base != NULL)
2081			free_buffer(disp, ev->buffer.base, ev->buffer.length);
2082		free_event(disp, ev);
2083		ev = ISC_LIST_HEAD(res->items);
2084	}
2085	res->magic = 0;
2086	isc_mempool_put(disp->mgr->rpool, res);
2087	if (disp->shutting_down == 1)
2088		do_cancel(disp);
2089	else
2090		startrecv(disp);
2091
2092	killit = destroy_disp_ok(disp);
2093	UNLOCK(&disp->lock);
2094	if (killit)
2095		isc_task_send(disp->task, &disp->ctlevent);
2096}
2097
2098static void
2099do_cancel(dns_dispatch_t *disp) {
2100	dns_dispatchevent_t *ev;
2101	dns_dispentry_t *resp;
2102	dns_qid_t *qid;
2103
2104	if (disp->shutdown_out == 1)
2105		return;
2106
2107	qid = DNS_QID(disp);
2108
2109	/*
2110	 * Search for the first response handler without packets outstanding.
2111	 */
2112	LOCK(&qid->lock);
2113	for (resp = linear_first(qid);
2114	     resp != NULL && resp->item_out != ISC_FALSE;
2115	     /* Empty. */)
2116		resp = linear_next(qid, resp);
2117	/*
2118	 * No one to send the cancel event to, so nothing to do.
2119	 */
2120	if (resp == NULL)
2121		goto unlock;
2122
2123	/*
2124	 * Send the shutdown failsafe event to this resp.
2125	 */
2126	ev = disp->failsafe_ev;
2127	ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, DNS_EVENT_DISPATCH,
2128		       resp->action, resp->arg, resp, NULL, NULL);
2129	ev->result = disp->shutdown_why;
2130	ev->buffer.base = NULL;
2131	ev->buffer.length = 0;
2132	disp->shutdown_out = 1;
2133	request_log(disp, resp, LVL(10),
2134		    "cancel: failsafe event %p -> task %p",
2135		    ev, resp->task);
2136	resp->item_out = ISC_TRUE;
2137	isc_task_send(resp->task, ISC_EVENT_PTR(&ev));
2138 unlock:
2139	UNLOCK(&qid->lock);
2140}
2141
2142isc_socket_t *
2143dns_dispatch_getsocket(dns_dispatch_t *disp) {
2144	REQUIRE(VALID_DISPATCH(disp));
2145
2146	return (disp->socket);
2147}
2148
2149isc_result_t
2150dns_dispatch_getlocaladdress(dns_dispatch_t *disp, isc_sockaddr_t *addrp) {
2151
2152	REQUIRE(VALID_DISPATCH(disp));
2153	REQUIRE(addrp != NULL);
2154
2155	if (disp->socktype == isc_sockettype_udp) {
2156		*addrp = disp->local;
2157		return (ISC_R_SUCCESS);
2158	}
2159	return (ISC_R_NOTIMPLEMENTED);
2160}
2161
2162void
2163dns_dispatch_cancel(dns_dispatch_t *disp) {
2164	REQUIRE(VALID_DISPATCH(disp));
2165
2166	LOCK(&disp->lock);
2167
2168	if (disp->shutting_down == 1) {
2169		UNLOCK(&disp->lock);
2170		return;
2171	}
2172
2173	disp->shutdown_why = ISC_R_CANCELED;
2174	disp->shutting_down = 1;
2175	do_cancel(disp);
2176
2177	UNLOCK(&disp->lock);
2178
2179	return;
2180}
2181
2182void
2183dns_dispatch_changeattributes(dns_dispatch_t *disp,
2184			      unsigned int attributes, unsigned int mask)
2185{
2186	REQUIRE(VALID_DISPATCH(disp));
2187
2188	/* XXXMLG
2189	 * Should check for valid attributes here!
2190	 */
2191
2192	LOCK(&disp->lock);
2193
2194	if ((mask & DNS_DISPATCHATTR_NOLISTEN) != 0) {
2195		if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) != 0 &&
2196		    (attributes & DNS_DISPATCHATTR_NOLISTEN) == 0) {
2197			disp->attributes &= ~DNS_DISPATCHATTR_NOLISTEN;
2198			startrecv(disp);
2199		} else if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN)
2200			   == 0 &&
2201			   (attributes & DNS_DISPATCHATTR_NOLISTEN) != 0) {
2202			disp->attributes |= DNS_DISPATCHATTR_NOLISTEN;
2203			if (disp->recv_pending != 0)
2204				isc_socket_cancel(disp->socket, disp->task,
2205						  ISC_SOCKCANCEL_RECV);
2206		}
2207	}
2208
2209	disp->attributes &= ~mask;
2210	disp->attributes |= (attributes & mask);
2211	UNLOCK(&disp->lock);
2212}
2213
2214void
2215dns_dispatch_importrecv(dns_dispatch_t *disp, isc_event_t *event) {
2216	void *buf;
2217	isc_socketevent_t *sevent, *newsevent;
2218
2219	REQUIRE(VALID_DISPATCH(disp));
2220	REQUIRE((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) != 0);
2221	REQUIRE(event != NULL);
2222
2223	sevent = (isc_socketevent_t *)event;
2224
2225	INSIST(sevent->n <= disp->mgr->buffersize);
2226	newsevent = (isc_socketevent_t *)
2227		    isc_event_allocate(disp->mgr->mctx, NULL,
2228				      DNS_EVENT_IMPORTRECVDONE, udp_recv,
2229				      disp, sizeof(isc_socketevent_t));
2230	if (newsevent == NULL)
2231		return;
2232
2233	buf = allocate_udp_buffer(disp);
2234	if (buf == NULL) {
2235		isc_event_free(ISC_EVENT_PTR(&newsevent));
2236		return;
2237	}
2238	memcpy(buf, sevent->region.base, sevent->n);
2239	newsevent->region.base = buf;
2240	newsevent->region.length = disp->mgr->buffersize;
2241	newsevent->n = sevent->n;
2242	newsevent->result = sevent->result;
2243	newsevent->address = sevent->address;
2244	newsevent->timestamp = sevent->timestamp;
2245	newsevent->pktinfo = sevent->pktinfo;
2246	newsevent->attributes = sevent->attributes;
2247
2248	isc_task_send(disp->task, ISC_EVENT_PTR(&newsevent));
2249}
2250
2251#if 0
2252void
2253dns_dispatchmgr_dump(dns_dispatchmgr_t *mgr) {
2254	dns_dispatch_t *disp;
2255	char foo[1024];
2256
2257	disp = ISC_LIST_HEAD(mgr->list);
2258	while (disp != NULL) {
2259		isc_sockaddr_format(&disp->local, foo, sizeof(foo));
2260		printf("\tdispatch %p, addr %s\n", disp, foo);
2261		disp = ISC_LIST_NEXT(disp, link);
2262	}
2263}
2264#endif
2265
2266/*
2267 * Allow the user to pick one of two ID randomization algorithms.
2268 *
2269 * The first algorithm is an adaptation of the sequence shuffling
2270 * algorithm discovered by Carter Bays and S. D. Durham [ACM Trans. Math.
2271 * Software 2 (1976), 59-64], as documented as Algorithm B in Chapter
2272 * 3.2.2 in Volume 2 of Knuth's "The Art of Computer Programming".  We use
2273 * a randomly selected linear congruential random number generator with a
2274 * modulus of 2^16, whose increment is a randomly picked odd number, and
2275 * whose multiplier is picked from a set which meets the following
2276 * criteria:
2277 *     Is of the form 8*n+5, which ensures "high potency" according to
2278 *     principle iii in the summary chapter 3.6.  This form also has a
2279 *     gcd(a-1,m) of 4 which is good according to principle iv.
2280 *
2281 *     Is between 0.01 and 0.99 times the modulus as specified by
2282 *     principle iv.
2283 *
2284 *     Passes the spectral test "with flying colors" (ut >= 1) in
2285 *     dimensions 2 through 6 as calculated by Algorithm S in Chapter
2286 *     3.3.4 and the ratings calculated by formula 35 in section E.
2287 *
2288 *     Of the multipliers that pass this test, pick the set that is
2289 *     best according to the theoretical bounds of the serial
2290 *     correlation test.  This was calculated using a simplified
2291 *     version of Knuth's Theorem K in Chapter 3.3.3.
2292 *
2293 * These criteria may not be important for this use, but we might as well
2294 * pick from the best generators since there are so many possible ones and
2295 * we don't have that many random bits to do the picking.
2296 *
2297 * We use a modulus of 2^16 instead of something bigger so that we will
2298 * tend to cycle through all the possible IDs before repeating any,
2299 * however the shuffling will perturb this somewhat.  Theoretically there
2300 * is no minimimum interval between two uses of the same ID, but in
2301 * practice it seems to be >64000.
2302 *
2303 * Our adaptatation  of Algorithm B mixes the hash state which has
2304 * captured various random events into the shuffler to perturb the
2305 * sequence.
2306 *
2307 * One disadvantage of this algorithm is that if the generator parameters
2308 * were to be guessed, it would be possible to mount a limited brute force
2309 * attack on the ID space since the IDs are only shuffled within a limited
2310 * range.
2311 *
2312 * The second algorithm uses the same random number generator to populate
2313 * a pool of 65536 IDs.  The hash state is used to pick an ID from a window
2314 * of 4096 IDs in this pool, then the chosen ID is swapped with the ID
2315 * at the beginning of the window and the window position is advanced.
2316 * This means that the interval between uses of the ID will be no less
2317 * than 65536-4096.  The ID sequence in the pool will become more random
2318 * over time.
2319 *
2320 * For both algorithms, two more linear congruential random number generators
2321 * are selected.  The ID from the first part of algorithm is used to seed
2322 * the first of these generators, and its output is used to seed the second.
2323 * The strategy is use these generators as 1 to 1 hashes to obfuscate the
2324 * properties of the generator used in the first part of either algorithm.
2325 *
2326 * The first algorithm may be suitable for use in a client resolver since
2327 * its memory requirements are fairly low and it's pretty random out of
2328 * the box.  It is somewhat succeptible to a limited brute force attack,
2329 * so the second algorithm is probably preferable for a longer running
2330 * program that issues a large number of queries and has time to randomize
2331 * the pool.
2332 */
2333
2334#define NSID_SHUFFLE_TABLE_SIZE 100 /* Suggested by Knuth */
2335/*
2336 * Pick one of the next 4096 IDs in the pool.
2337 * There is a tradeoff here between randomness and how often and ID is reused.
2338 */
2339#define NSID_LOOKAHEAD 4096     /* Must be a power of 2 */
2340#define NSID_SHUFFLE_ONLY 1     /* algorithm 1 */
2341#define NSID_USE_POOL 2         /* algorithm 2 */
2342#define NSID_HASHSHIFT       3
2343#define NSID_HASHROTATE(v) \
2344        (((v) << NSID_HASHSHIFT) | ((v) >> ((sizeof(v) * 8) - NSID_HASHSHIFT)))
2345
2346static isc_uint32_t	nsid_hash_state;
2347
2348/*
2349 * Keep a running hash of various bits of data that we'll use to
2350 * stir the ID pool or perturb the ID generator
2351 */
2352static void
2353nsid_hash(void *data, size_t len) {
2354	unsigned char *p = data;
2355	/*
2356	 * Hash function similar to the one we use for hashing names.
2357	 * We don't fold case or toss the upper bit here, though.
2358	 * This hash doesn't do much interesting when fed binary zeros,
2359	 * so there may be a better hash function.
2360	 * This function doesn't need to be very strong since we're
2361	 * only using it to stir the pool, but it should be reasonably
2362	 * fast.
2363	 */
2364	/*
2365	 * We don't care about locking access to nsid_hash_state.
2366	 * In fact races make the result even more non deteministic.
2367	 */
2368	while (len-- > 0U) {
2369		nsid_hash_state = NSID_HASHROTATE(nsid_hash_state);
2370		nsid_hash_state += *p++;
2371	}
2372}
2373
2374/*
2375 * Table of good linear congruential multipliers for modulus 2^16
2376 * in order of increasing serial correlation bounds (so trim from
2377 * the end).
2378 */
2379static const isc_uint16_t nsid_multiplier_table[] = {
2380	17565, 25013, 11733, 19877, 23989, 23997, 24997, 25421,
2381	26781, 27413, 35901, 35917, 35973, 36229, 38317, 38437,
2382	39941, 40493, 41853, 46317, 50581, 51429, 53453, 53805,
2383	11317, 11789, 12045, 12413, 14277, 14821, 14917, 18989,
2384	19821, 23005, 23533, 23573, 23693, 27549, 27709, 28461,
2385	29365, 35605, 37693, 37757, 38309, 41285, 45261, 47061,
2386	47269, 48133, 48597, 50277, 50717, 50757, 50805, 51341,
2387	51413, 51581, 51597, 53445, 11493, 14229, 20365, 20653,
2388	23485, 25541, 27429, 29421, 30173, 35445, 35653, 36789,
2389	36797, 37109, 37157, 37669, 38661, 39773, 40397, 41837,
2390	41877, 45293, 47277, 47845, 49853, 51085, 51349, 54085,
2391	56933,  8877,  8973,  9885, 11365, 11813, 13581, 13589,
2392	13613, 14109, 14317, 15765, 15789, 16925, 17069, 17205,
2393	17621, 17941, 19077, 19381, 20245, 22845, 23733, 24869,
2394	25453, 27213, 28381, 28965, 29245, 29997, 30733, 30901,
2395	34877, 35485, 35613, 36133, 36661, 36917, 38597, 40285,
2396	40693, 41413, 41541, 41637, 42053, 42349, 45245, 45469,
2397	46493, 48205, 48613, 50861, 51861, 52877, 53933, 54397,
2398	55669, 56453, 56965, 58021,  7757,  7781,  8333,  9661,
2399	12229, 14373, 14453, 17549, 18141, 19085, 20773, 23701,
2400	24205, 24333, 25261, 25317, 27181, 30117, 30477, 34757,
2401	34885, 35565, 35885, 36541, 37957, 39733, 39813, 41157,
2402	41893, 42317, 46621, 48117, 48181, 49525, 55261, 55389,
2403	56845,  7045,  7749,  7965,  8469,  9133,  9549,  9789,
2404	10173, 11181, 11285, 12253, 13453, 13533, 13757, 14477,
2405	15053, 16901, 17213, 17269, 17525, 17629, 18605, 19013,
2406	19829, 19933, 20069, 20093, 23261, 23333, 24949, 25309,
2407	27613, 28453, 28709, 29301, 29541, 34165, 34413, 37301,
2408	37773, 38045, 38405, 41077, 41781, 41925, 42717, 44437,
2409	44525, 44613, 45933, 45941, 47077, 50077, 50893, 52117,
2410	 5293, 55069, 55989, 58125, 59205,  6869, 14685, 15453,
2411	16821, 17045, 17613, 18437, 21029, 22773, 22909, 25445,
2412	25757, 26541, 30709, 30909, 31093, 31149, 37069, 37725,
2413	37925, 38949, 39637, 39701, 40765, 40861, 42965, 44813,
2414	45077, 45733, 47045, 50093, 52861, 52957, 54181, 56325,
2415	56365, 56381, 56877, 57013,  5741, 58101, 58669,  8613,
2416	10045, 10261, 10653, 10733, 11461, 12261, 14069, 15877,
2417	17757, 21165, 23885, 24701, 26429, 26645, 27925, 28765,
2418	29197, 30189, 31293, 39781, 39909, 40365, 41229, 41453,
2419	41653, 42165, 42365, 47421, 48029, 48085, 52773,  5573,
2420	57037, 57637, 58341, 58357, 58901,  6357,  7789,  9093,
2421	10125, 10709, 10765, 11957, 12469, 13437, 13509, 14773,
2422	15437, 15773, 17813, 18829, 19565, 20237, 23461, 23685,
2423	23725, 23941, 24877, 25461, 26405, 29509, 30285, 35181,
2424	37229, 37893, 38565, 40293, 44189, 44581, 45701, 47381,
2425	47589, 48557,  4941, 51069,  5165, 52797, 53149,  5341,
2426	56301, 56765, 58581, 59493, 59677,  6085,  6349,  8293,
2427	 8501,  8517, 11597, 11709, 12589, 12693, 13517, 14909,
2428	17397, 18085, 21101, 21269, 22717, 25237, 25661, 29189,
2429	30101, 31397, 33933, 34213, 34661, 35533, 36493, 37309,
2430	40037,  4189, 42909, 44309, 44357, 44389,  4541, 45461,
2431	46445, 48237, 54149, 55301, 55853, 56621, 56717, 56901,
2432	 5813, 58437, 12493, 15365, 15989, 17829, 18229, 19341,
2433	21013, 21357, 22925, 24885, 26053, 27581, 28221, 28485,
2434	30605, 30613, 30789, 35437, 36285, 37189,  3941, 41797,
2435	 4269, 42901, 43293, 44645, 45221, 46893,  4893, 50301,
2436	50325,  5189, 52109, 53517, 54053, 54485,  5525, 55949,
2437	56973, 59069, 59421, 60733, 61253,  6421,  6701,  6709,
2438	 7101,  8669, 15797, 19221, 19837, 20133, 20957, 21293,
2439	21461, 22461, 29085, 29861, 30869, 34973, 36469, 37565,
2440	38125, 38829, 39469, 40061, 40117, 44093, 47429, 48341,
2441	50597, 51757,  5541, 57629, 58405, 59621, 59693, 59701,
2442	61837,  7061, 10421, 11949, 15405, 20861, 25397, 25509,
2443	25893, 26037, 28629, 28869, 29605, 30213, 34205, 35637,
2444	36365, 37285,  3773, 39117,  4021, 41061, 42653, 44509,
2445	 4461, 44829,  4725,  5125, 52269, 56469, 59085,  5917,
2446	60973,  8349, 17725, 18637, 19773, 20293, 21453, 22533,
2447	24285, 26333, 26997, 31501, 34541, 34805, 37509, 38477,
2448	41333, 44125, 46285, 46997, 47637, 48173,  4925, 50253,
2449	50381, 50917, 51205, 51325, 52165, 52229,  5253,  5269,
2450	53509, 56253, 56341,  5821, 58373, 60301, 61653, 61973,
2451	62373,  8397, 11981, 14341, 14509, 15077, 22261, 22429,
2452	24261, 28165, 28685, 30661, 34021, 34445, 39149,  3917,
2453	43013, 43317, 44053, 44101,  4533, 49541, 49981,  5277,
2454	54477, 56357, 57261, 57765, 58573, 59061, 60197, 61197,
2455	62189,  7725,  8477,  9565, 10229, 11437, 14613, 14709,
2456	16813, 20029, 20677, 31445,  3165, 31957,  3229, 33541,
2457	36645,  3805, 38973,  3965,  4029, 44293, 44557, 46245,
2458	48917,  4909, 51749, 53709, 55733, 56445,  5925,  6093,
2459	61053, 62637,  8661,  9109, 10821, 11389, 13813, 14325,
2460	15501, 16149, 18845, 22669, 26437, 29869, 31837, 33709,
2461	33973, 34173,  3677,  3877,  3981, 39885, 42117,  4421,
2462	44221, 44245, 44693, 46157, 47309,  5005, 51461, 52037,
2463	55333, 55693, 56277, 58949,  6205, 62141, 62469,  6293,
2464	10101, 12509, 14029, 17997, 20469, 21149, 25221, 27109,
2465	 2773,  2877, 29405, 31493, 31645,  4077, 42005, 42077,
2466	42469, 42501, 44013, 48653, 49349,  4997, 50101, 55405,
2467	56957, 58037, 59429, 60749, 61797, 62381, 62837,  6605,
2468	10541, 23981, 24533,  2701, 27333, 27341, 31197, 33805,
2469	 3621, 37381,  3749,  3829, 38533, 42613, 44381, 45901,
2470	48517, 51269, 57725, 59461, 60045, 62029, 13805, 14013,
2471	15461, 16069, 16157, 18573,  2309, 23501, 28645,  3077,
2472	31541, 36357, 36877,  3789, 39429, 39805, 47685, 47949,
2473	49413,  5485, 56757, 57549, 57805, 58317, 59549, 62213,
2474	62613, 62853, 62933,  8909, 12941, 16677, 20333, 21541,
2475	24429, 26077, 26421,  2885, 31269, 33381,  3661, 40925,
2476	42925, 45173,  4525,  4709, 53133, 55941, 57413, 57797,
2477	62125, 62237, 62733,  6773, 12317, 13197, 16533, 16933,
2478	18245,  2213,  2477, 29757, 33293, 35517, 40133, 40749,
2479	 4661, 49941, 62757,  7853,  8149,  8573, 11029, 13421,
2480	21549, 22709, 22725, 24629,  2469, 26125,  2669, 34253,
2481	36709, 41013, 45597, 46637, 52285, 52333, 54685, 59013,
2482	60997, 61189, 61981, 62605, 62821,  7077,  7525,  8781,
2483	10861, 15277,  2205, 22077, 28517, 28949, 32109, 33493,
2484	 4661, 49941, 62757,  7853,  8149,  8573, 11029, 13421,
2485	21549, 22709, 22725, 24629,  2469, 26125,  2669, 34253,
2486	36709, 41013, 45597, 46637, 52285, 52333, 54685, 59013,
2487	60997, 61189, 61981, 62605, 62821,  7077,  7525,  8781,
2488	10861, 15277,  2205, 22077, 28517, 28949, 32109, 33493,
2489	 3685, 39197, 39869, 42621, 44997, 48565,  5221, 57381,
2490	61749, 62317, 63245, 63381, 23149,  2549, 28661, 31653,
2491	33885, 36341, 37053, 39517, 42805, 45853, 48997, 59349,
2492	60053, 62509, 63069,  6525,  1893, 20181,  2365, 24893,
2493	27397, 31357, 32277, 33357, 34437, 36677, 37661, 43469,
2494	43917, 50997, 53869,  5653, 13221, 16741, 17893,  2157,
2495	28653, 31789, 35301, 35821, 61613, 62245, 12405, 14517,
2496	17453, 18421,  3149,  3205, 40341,  4109, 43941, 46869,
2497	48837, 50621, 57405, 60509, 62877,  8157, 12933, 12957,
2498	16501, 19533,  3461, 36829, 52357, 58189, 58293, 63053,
2499	17109,  1933, 32157, 37701, 59005, 61621, 13029, 15085,
2500	16493, 32317, 35093,  5061, 51557, 62221, 20765, 24613,
2501	 2629, 30861, 33197, 33749, 35365, 37933, 40317, 48045,
2502	56229, 61157, 63797,  7917, 17965,  1917,  1973, 20301,
2503	 2253, 33157, 58629, 59861, 61085, 63909,  8141,  9221,
2504	14757,  1581, 21637, 26557, 33869, 34285, 35733, 40933,
2505	42517, 43501, 53653, 61885, 63805,  7141, 21653, 54973,
2506	31189, 60061, 60341, 63357, 16045,  2053, 26069, 33997,
2507	43901, 54565, 63837,  8949, 17909, 18693, 32349, 33125,
2508	37293, 48821, 49053, 51309, 64037,  7117,  1445, 20405,
2509	23085, 26269, 26293, 27349, 32381, 33141, 34525, 36461,
2510	37581, 43525,  4357, 43877,  5069, 55197, 63965,  9845,
2511	12093,  2197,  2229, 32165, 33469, 40981, 42397,  8749,
2512	10853,  1453, 18069, 21693, 30573, 36261, 37421, 42533
2513};
2514
2515#define NSID_MULT_TABLE_SIZE \
2516        ((sizeof nsid_multiplier_table)/(sizeof nsid_multiplier_table[0]))
2517#define NSID_RANGE_MASK (NSID_LOOKAHEAD - 1)
2518#define NSID_POOL_MASK 0xFFFF /* used to wrap the pool index */
2519#define NSID_SHUFFLE_ONLY 1
2520#define NSID_USE_POOL 2
2521
2522static isc_uint16_t
2523nsid_next(dns_nsid_t *nsid) {
2524        isc_uint16_t id, compressed_hash;
2525	isc_uint16_t j;
2526
2527        compressed_hash = ((nsid_hash_state >> 16) ^
2528			   (nsid_hash_state)) & 0xFFFF;
2529
2530	if (nsid->nsid_usepool) {
2531	        isc_uint16_t pick;
2532
2533                pick = compressed_hash & NSID_RANGE_MASK;
2534		pick = (nsid->nsid_state + pick) & NSID_POOL_MASK;
2535                id = nsid->nsid_pool[pick];
2536                if (pick != 0) {
2537                        /* Swap two IDs to stir the pool */
2538                        nsid->nsid_pool[pick] =
2539                                nsid->nsid_pool[nsid->nsid_state];
2540                        nsid->nsid_pool[nsid->nsid_state] = id;
2541                }
2542
2543                /* increment the base pointer into the pool */
2544                if (nsid->nsid_state == 65535)
2545                        nsid->nsid_state = 0;
2546                else
2547                        nsid->nsid_state++;
2548	} else {
2549		/*
2550		 * This is the original Algorithm B
2551		 * j = ((u_long) NSID_SHUFFLE_TABLE_SIZE * nsid_state2) >> 16;
2552		 *
2553		 * We'll perturb it with some random stuff  ...
2554		 */
2555		j = ((isc_uint32_t) NSID_SHUFFLE_TABLE_SIZE *
2556		     (nsid->nsid_state2 ^ compressed_hash)) >> 16;
2557		nsid->nsid_state2 = id = nsid->nsid_vtable[j];
2558		nsid->nsid_state = (((isc_uint32_t) nsid->nsid_a1 * nsid->nsid_state) +
2559				      nsid->nsid_c1) & 0xFFFF;
2560		nsid->nsid_vtable[j] = nsid->nsid_state;
2561	}
2562
2563        /* Now lets obfuscate ... */
2564        id = (((isc_uint32_t) nsid->nsid_a2 * id) + nsid->nsid_c2) & 0xFFFF;
2565        id = (((isc_uint32_t) nsid->nsid_a3 * id) + nsid->nsid_c3) & 0xFFFF;
2566
2567        return (id);
2568}
2569
2570static isc_result_t
2571nsid_init(isc_mem_t *mctx, dns_nsid_t *nsid, isc_boolean_t usepool) {
2572        isc_time_t now;
2573        pid_t mypid;
2574        isc_uint16_t a1ndx, a2ndx, a3ndx, c1ndx, c2ndx, c3ndx;
2575        int i;
2576
2577	isc_time_now(&now);
2578        mypid = getpid();
2579
2580        /* Initialize the state */
2581	memset(nsid, 0, sizeof(*nsid));
2582        nsid_hash(&now, sizeof now);
2583        nsid_hash(&mypid, sizeof mypid);
2584
2585        /*
2586         * Select our random number generators and initial seed.
2587         * We could really use more random bits at this point,
2588         * but we'll try to make a silk purse out of a sows ear ...
2589         */
2590        /* generator 1 */
2591        a1ndx = ((isc_uint32_t) NSID_MULT_TABLE_SIZE *
2592                 (nsid_hash_state & 0xFFFF)) >> 16;
2593        nsid->nsid_a1 = nsid_multiplier_table[a1ndx];
2594        c1ndx = (nsid_hash_state >> 9) & 0x7FFF;
2595        nsid->nsid_c1 = 2 * c1ndx + 1;
2596
2597        /* generator 2, distinct from 1 */
2598        a2ndx = ((isc_uint32_t) (NSID_MULT_TABLE_SIZE - 1) *
2599                 ((nsid_hash_state >> 10) & 0xFFFF)) >> 16;
2600        if (a2ndx >= a1ndx)
2601                a2ndx++;
2602        nsid->nsid_a2 = nsid_multiplier_table[a2ndx];
2603        c2ndx = nsid_hash_state % 32767;
2604        if (c2ndx >= c1ndx)
2605                c2ndx++;
2606        nsid->nsid_c2 = 2*c2ndx + 1;
2607
2608        /* generator 3, distinct from 1 and 2 */
2609        a3ndx = ((isc_uint32_t) (NSID_MULT_TABLE_SIZE - 2) *
2610                 ((nsid_hash_state >> 20) & 0xFFFF)) >> 16;
2611        if (a3ndx >= a1ndx || a3ndx >= a2ndx)
2612                a3ndx++;
2613        if (a3ndx >= a1ndx && a3ndx >= a2ndx)
2614                a3ndx++;
2615        nsid->nsid_a3 = nsid_multiplier_table[a3ndx];
2616        c3ndx = nsid_hash_state % 32766;
2617        if (c3ndx >= c1ndx || c3ndx >= c2ndx)
2618                c3ndx++;
2619        if (c3ndx >= c1ndx && c3ndx >= c2ndx)
2620                c3ndx++;
2621        nsid->nsid_c3 = 2*c3ndx + 1;
2622
2623        nsid->nsid_state =
2624		((nsid_hash_state >> 16) ^ (nsid_hash_state)) & 0xFFFF;
2625
2626	nsid->nsid_usepool = usepool;
2627	if (nsid->nsid_usepool) {
2628                nsid->nsid_pool = isc_mem_get(mctx, 0x10000 * sizeof(isc_uint16_t));
2629		if (nsid->nsid_pool == NULL)
2630			return (ISC_R_NOMEMORY);
2631                for (i = 0; ; i++) {
2632                        nsid->nsid_pool[i] = nsid->nsid_state;
2633                        nsid->nsid_state =
2634				 (((u_long) nsid->nsid_a1 * nsid->nsid_state) +
2635				   nsid->nsid_c1) & 0xFFFF;
2636                        if (i == 0xFFFF)
2637                                break;
2638                }
2639	} else {
2640		nsid->nsid_vtable = isc_mem_get(mctx, NSID_SHUFFLE_TABLE_SIZE *
2641						(sizeof(isc_uint16_t)) );
2642		if (nsid->nsid_vtable == NULL)
2643			return (ISC_R_NOMEMORY);
2644
2645		for (i = 0; i < NSID_SHUFFLE_TABLE_SIZE; i++) {
2646			nsid->nsid_vtable[i] = nsid->nsid_state;
2647			nsid->nsid_state =
2648				   (((isc_uint32_t) nsid->nsid_a1 * nsid->nsid_state) +
2649					 nsid->nsid_c1) & 0xFFFF;
2650		}
2651		nsid->nsid_state2 = nsid->nsid_state;
2652	}
2653	return (ISC_R_SUCCESS);
2654}
2655
2656static void
2657nsid_destroy(isc_mem_t *mctx, dns_nsid_t *nsid) {
2658	if (nsid->nsid_usepool)
2659		isc_mem_put(mctx, nsid->nsid_pool,
2660			    0x10000 * sizeof(isc_uint16_t));
2661	else
2662		isc_mem_put(mctx, nsid->nsid_vtable,
2663			    NSID_SHUFFLE_TABLE_SIZE * (sizeof(isc_uint16_t)) );
2664	memset(nsid, 0, sizeof(*nsid));
2665}
2666
2667void
2668dns_dispatch_hash(void *data, size_t len) {
2669	nsid_hash(data, len);
2670}
2671