1 /*
2  * Copyright (C) 2004-2009, 2012, 2014  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 2000, 2001, 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 
18 /* $Id: peer.c,v 1.33 2009/09/02 23:48:02 tbox Exp $ */
19 
20 /*! \file */
21 
22 #include <config.h>
23 
24 #include <isc/mem.h>
25 #include <isc/string.h>
26 #include <isc/util.h>
27 #include <isc/sockaddr.h>
28 
29 #include <dns/bit.h>
30 #include <dns/fixedname.h>
31 #include <dns/name.h>
32 #include <dns/peer.h>
33 
34 /*%
35  * Bit positions in the dns_peer_t structure flags field
36  */
37 #define BOGUS_BIT			0
38 #define SERVER_TRANSFER_FORMAT_BIT	1
39 #define TRANSFERS_BIT			2
40 #define PROVIDE_IXFR_BIT		3
41 #define REQUEST_IXFR_BIT		4
42 #define SUPPORT_EDNS_BIT		5
43 #define SERVER_UDPSIZE_BIT		6
44 #define SERVER_MAXUDP_BIT		7
45 #define REQUEST_NSID_BIT                8
46 
47 static void
48 peerlist_delete(dns_peerlist_t **list);
49 
50 static void
51 peer_delete(dns_peer_t **peer);
52 
53 isc_result_t
dns_peerlist_new(isc_mem_t * mem,dns_peerlist_t ** list)54 dns_peerlist_new(isc_mem_t *mem, dns_peerlist_t **list) {
55 	dns_peerlist_t *l;
56 
57 	REQUIRE(list != NULL);
58 
59 	l = isc_mem_get(mem, sizeof(*l));
60 	if (l == NULL)
61 		return (ISC_R_NOMEMORY);
62 
63 	ISC_LIST_INIT(l->elements);
64 	l->mem = mem;
65 	l->refs = 1;
66 	l->magic = DNS_PEERLIST_MAGIC;
67 
68 	*list = l;
69 
70 	return (ISC_R_SUCCESS);
71 }
72 
73 void
dns_peerlist_attach(dns_peerlist_t * source,dns_peerlist_t ** target)74 dns_peerlist_attach(dns_peerlist_t *source, dns_peerlist_t **target) {
75 	REQUIRE(DNS_PEERLIST_VALID(source));
76 	REQUIRE(target != NULL);
77 	REQUIRE(*target == NULL);
78 
79 	source->refs++;
80 
81 	ENSURE(source->refs != 0xffffffffU);
82 
83 	*target = source;
84 }
85 
86 void
dns_peerlist_detach(dns_peerlist_t ** list)87 dns_peerlist_detach(dns_peerlist_t **list) {
88 	dns_peerlist_t *plist;
89 
90 	REQUIRE(list != NULL);
91 	REQUIRE(*list != NULL);
92 	REQUIRE(DNS_PEERLIST_VALID(*list));
93 
94 	plist = *list;
95 	*list = NULL;
96 
97 	REQUIRE(plist->refs > 0);
98 
99 	plist->refs--;
100 
101 	if (plist->refs == 0)
102 		peerlist_delete(&plist);
103 }
104 
105 static void
peerlist_delete(dns_peerlist_t ** list)106 peerlist_delete(dns_peerlist_t **list) {
107 	dns_peerlist_t *l;
108 	dns_peer_t *server, *stmp;
109 
110 	REQUIRE(list != NULL);
111 	REQUIRE(DNS_PEERLIST_VALID(*list));
112 
113 	l = *list;
114 
115 	REQUIRE(l->refs == 0);
116 
117 	server = ISC_LIST_HEAD(l->elements);
118 	while (server != NULL) {
119 		stmp = ISC_LIST_NEXT(server, next);
120 		ISC_LIST_UNLINK(l->elements, server, next);
121 		dns_peer_detach(&server);
122 		server = stmp;
123 	}
124 
125 	l->magic = 0;
126 	isc_mem_put(l->mem, l, sizeof(*l));
127 
128 	*list = NULL;
129 }
130 
131 void
dns_peerlist_addpeer(dns_peerlist_t * peers,dns_peer_t * peer)132 dns_peerlist_addpeer(dns_peerlist_t *peers, dns_peer_t *peer) {
133 	dns_peer_t *p = NULL;
134 
135 	dns_peer_attach(peer, &p);
136 
137 	/*
138 	 * More specifics to front of list.
139 	 */
140 	for (p = ISC_LIST_HEAD(peers->elements);
141 	     p != NULL;
142 	     p = ISC_LIST_NEXT(p, next))
143 		if (p->prefixlen < peer->prefixlen)
144 			break;
145 
146 	if (p != NULL)
147 		ISC_LIST_INSERTBEFORE(peers->elements, p, peer, next);
148 	else
149 		ISC_LIST_APPEND(peers->elements, peer, next);
150 
151 }
152 
153 isc_result_t
dns_peerlist_peerbyaddr(dns_peerlist_t * servers,isc_netaddr_t * addr,dns_peer_t ** retval)154 dns_peerlist_peerbyaddr(dns_peerlist_t *servers,
155 			isc_netaddr_t *addr, dns_peer_t **retval)
156 {
157 	dns_peer_t *server;
158 	isc_result_t res;
159 
160 	REQUIRE(retval != NULL);
161 	REQUIRE(DNS_PEERLIST_VALID(servers));
162 
163 	server = ISC_LIST_HEAD(servers->elements);
164 	while (server != NULL) {
165 		if (isc_netaddr_eqprefix(addr, &server->address,
166 					 server->prefixlen))
167 			break;
168 
169 		server = ISC_LIST_NEXT(server, next);
170 	}
171 
172 	if (server != NULL) {
173 		*retval = server;
174 		res = ISC_R_SUCCESS;
175 	} else {
176 		res = ISC_R_NOTFOUND;
177 	}
178 
179 	return (res);
180 }
181 
182 
183 
184 isc_result_t
dns_peerlist_currpeer(dns_peerlist_t * peers,dns_peer_t ** retval)185 dns_peerlist_currpeer(dns_peerlist_t *peers, dns_peer_t **retval) {
186 	dns_peer_t *p = NULL;
187 
188 	p = ISC_LIST_TAIL(peers->elements);
189 
190 	dns_peer_attach(p, retval);
191 
192 	return (ISC_R_SUCCESS);
193 }
194 
195 isc_result_t
dns_peer_new(isc_mem_t * mem,isc_netaddr_t * addr,dns_peer_t ** peerptr)196 dns_peer_new(isc_mem_t *mem, isc_netaddr_t *addr, dns_peer_t **peerptr) {
197 	unsigned int prefixlen = 0;
198 
199 	REQUIRE(peerptr != NULL);
200 	switch(addr->family) {
201 	case AF_INET:
202 		prefixlen = 32;
203 		break;
204 	case AF_INET6:
205 		 prefixlen = 128;
206 		break;
207 	default:
208 		INSIST(0);
209 	}
210 
211 	return (dns_peer_newprefix(mem, addr, prefixlen, peerptr));
212 }
213 
214 isc_result_t
dns_peer_newprefix(isc_mem_t * mem,isc_netaddr_t * addr,unsigned int prefixlen,dns_peer_t ** peerptr)215 dns_peer_newprefix(isc_mem_t *mem, isc_netaddr_t *addr, unsigned int prefixlen,
216 		   dns_peer_t **peerptr)
217 {
218 	dns_peer_t *peer;
219 
220 	REQUIRE(peerptr != NULL);
221 
222 	peer = isc_mem_get(mem, sizeof(*peer));
223 	if (peer == NULL)
224 		return (ISC_R_NOMEMORY);
225 
226 	peer->magic = DNS_PEER_MAGIC;
227 	peer->address = *addr;
228 	peer->prefixlen = prefixlen;
229 	peer->mem = mem;
230 	peer->bogus = ISC_FALSE;
231 	peer->transfer_format = dns_one_answer;
232 	peer->transfers = 0;
233 	peer->request_ixfr = ISC_FALSE;
234 	peer->provide_ixfr = ISC_FALSE;
235 	peer->key = NULL;
236 	peer->refs = 1;
237 	peer->transfer_source = NULL;
238 	peer->notify_source = NULL;
239 	peer->query_source = NULL;
240 
241 	memset(&peer->bitflags, 0x0, sizeof(peer->bitflags));
242 
243 	ISC_LINK_INIT(peer, next);
244 
245 	*peerptr = peer;
246 
247 	return (ISC_R_SUCCESS);
248 }
249 
250 void
dns_peer_attach(dns_peer_t * source,dns_peer_t ** target)251 dns_peer_attach(dns_peer_t *source, dns_peer_t **target) {
252 	REQUIRE(DNS_PEER_VALID(source));
253 	REQUIRE(target != NULL);
254 	REQUIRE(*target == NULL);
255 
256 	source->refs++;
257 
258 	ENSURE(source->refs != 0xffffffffU);
259 
260 	*target = source;
261 }
262 
263 void
dns_peer_detach(dns_peer_t ** peer)264 dns_peer_detach(dns_peer_t **peer) {
265 	dns_peer_t *p;
266 
267 	REQUIRE(peer != NULL);
268 	REQUIRE(*peer != NULL);
269 	REQUIRE(DNS_PEER_VALID(*peer));
270 
271 	p = *peer;
272 
273 	REQUIRE(p->refs > 0);
274 
275 	*peer = NULL;
276 	p->refs--;
277 
278 	if (p->refs == 0)
279 		peer_delete(&p);
280 }
281 
282 static void
peer_delete(dns_peer_t ** peer)283 peer_delete(dns_peer_t **peer) {
284 	dns_peer_t *p;
285 	isc_mem_t *mem;
286 
287 	REQUIRE(peer != NULL);
288 	REQUIRE(DNS_PEER_VALID(*peer));
289 
290 	p = *peer;
291 
292 	REQUIRE(p->refs == 0);
293 
294 	mem = p->mem;
295 	p->mem = NULL;
296 	p->magic = 0;
297 
298 	if (p->key != NULL) {
299 		dns_name_free(p->key, mem);
300 		isc_mem_put(mem, p->key, sizeof(dns_name_t));
301 	}
302 
303 	if (p->query_source != NULL)
304 		isc_mem_put(mem, p->query_source, sizeof(*p->query_source));
305 
306 	if (p->notify_source != NULL)
307 		isc_mem_put(mem, p->notify_source, sizeof(*p->notify_source));
308 
309 	if (p->transfer_source != NULL)
310 		isc_mem_put(mem, p->transfer_source,
311 			    sizeof(*p->transfer_source));
312 
313 	isc_mem_put(mem, p, sizeof(*p));
314 
315 	*peer = NULL;
316 }
317 
318 isc_result_t
dns_peer_setbogus(dns_peer_t * peer,isc_boolean_t newval)319 dns_peer_setbogus(dns_peer_t *peer, isc_boolean_t newval) {
320 	isc_boolean_t existed;
321 
322 	REQUIRE(DNS_PEER_VALID(peer));
323 
324 	existed = DNS_BIT_CHECK(BOGUS_BIT, &peer->bitflags);
325 
326 	peer->bogus = newval;
327 	DNS_BIT_SET(BOGUS_BIT, &peer->bitflags);
328 
329 	return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
330 }
331 
332 isc_result_t
dns_peer_getbogus(dns_peer_t * peer,isc_boolean_t * retval)333 dns_peer_getbogus(dns_peer_t *peer, isc_boolean_t *retval) {
334 	REQUIRE(DNS_PEER_VALID(peer));
335 	REQUIRE(retval != NULL);
336 
337 	if (DNS_BIT_CHECK(BOGUS_BIT, &peer->bitflags)) {
338 		*retval = peer->bogus;
339 		return (ISC_R_SUCCESS);
340 	} else
341 		return (ISC_R_NOTFOUND);
342 }
343 
344 
345 isc_result_t
dns_peer_setprovideixfr(dns_peer_t * peer,isc_boolean_t newval)346 dns_peer_setprovideixfr(dns_peer_t *peer, isc_boolean_t newval) {
347 	isc_boolean_t existed;
348 
349 	REQUIRE(DNS_PEER_VALID(peer));
350 
351 	existed = DNS_BIT_CHECK(PROVIDE_IXFR_BIT, &peer->bitflags);
352 
353 	peer->provide_ixfr = newval;
354 	DNS_BIT_SET(PROVIDE_IXFR_BIT, &peer->bitflags);
355 
356 	return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
357 }
358 
359 isc_result_t
dns_peer_getprovideixfr(dns_peer_t * peer,isc_boolean_t * retval)360 dns_peer_getprovideixfr(dns_peer_t *peer, isc_boolean_t *retval) {
361 	REQUIRE(DNS_PEER_VALID(peer));
362 	REQUIRE(retval != NULL);
363 
364 	if (DNS_BIT_CHECK(PROVIDE_IXFR_BIT, &peer->bitflags)) {
365 		*retval = peer->provide_ixfr;
366 		return (ISC_R_SUCCESS);
367 	} else {
368 		return (ISC_R_NOTFOUND);
369 	}
370 }
371 
372 isc_result_t
dns_peer_setrequestixfr(dns_peer_t * peer,isc_boolean_t newval)373 dns_peer_setrequestixfr(dns_peer_t *peer, isc_boolean_t newval) {
374 	isc_boolean_t existed;
375 
376 	REQUIRE(DNS_PEER_VALID(peer));
377 
378 	existed = DNS_BIT_CHECK(REQUEST_IXFR_BIT, &peer->bitflags);
379 
380 	peer->request_ixfr = newval;
381 	DNS_BIT_SET(REQUEST_IXFR_BIT, &peer->bitflags);
382 
383 	return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
384 }
385 
386 isc_result_t
dns_peer_getrequestixfr(dns_peer_t * peer,isc_boolean_t * retval)387 dns_peer_getrequestixfr(dns_peer_t *peer, isc_boolean_t *retval) {
388 	REQUIRE(DNS_PEER_VALID(peer));
389 	REQUIRE(retval != NULL);
390 
391 	if (DNS_BIT_CHECK(REQUEST_IXFR_BIT, &peer->bitflags)) {
392 		*retval = peer->request_ixfr;
393 		return (ISC_R_SUCCESS);
394 	} else
395 		return (ISC_R_NOTFOUND);
396 }
397 
398 isc_result_t
dns_peer_setsupportedns(dns_peer_t * peer,isc_boolean_t newval)399 dns_peer_setsupportedns(dns_peer_t *peer, isc_boolean_t newval) {
400 	isc_boolean_t existed;
401 
402 	REQUIRE(DNS_PEER_VALID(peer));
403 
404 	existed = DNS_BIT_CHECK(SUPPORT_EDNS_BIT, &peer->bitflags);
405 
406 	peer->support_edns = newval;
407 	DNS_BIT_SET(SUPPORT_EDNS_BIT, &peer->bitflags);
408 
409 	return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
410 }
411 
412 isc_result_t
dns_peer_getsupportedns(dns_peer_t * peer,isc_boolean_t * retval)413 dns_peer_getsupportedns(dns_peer_t *peer, isc_boolean_t *retval) {
414 	REQUIRE(DNS_PEER_VALID(peer));
415 	REQUIRE(retval != NULL);
416 
417 	if (DNS_BIT_CHECK(SUPPORT_EDNS_BIT, &peer->bitflags)) {
418 		*retval = peer->support_edns;
419 		return (ISC_R_SUCCESS);
420 	} else
421 		return (ISC_R_NOTFOUND);
422 }
423 
424 isc_result_t
dns_peer_setrequestnsid(dns_peer_t * peer,isc_boolean_t newval)425 dns_peer_setrequestnsid(dns_peer_t *peer, isc_boolean_t newval) {
426 	isc_boolean_t existed;
427 
428 	REQUIRE(DNS_PEER_VALID(peer));
429 
430 	existed = DNS_BIT_CHECK(REQUEST_NSID_BIT, &peer->bitflags);
431 
432 	peer->request_nsid = newval;
433 	DNS_BIT_SET(REQUEST_NSID_BIT, &peer->bitflags);
434 
435 	return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
436 }
437 
438 isc_result_t
dns_peer_getrequestnsid(dns_peer_t * peer,isc_boolean_t * retval)439 dns_peer_getrequestnsid(dns_peer_t *peer, isc_boolean_t *retval) {
440 	REQUIRE(DNS_PEER_VALID(peer));
441 	REQUIRE(retval != NULL);
442 
443 	if (DNS_BIT_CHECK(REQUEST_NSID_BIT, &peer->bitflags)) {
444 		*retval = peer->request_nsid;
445 		return (ISC_R_SUCCESS);
446 	} else
447 		return (ISC_R_NOTFOUND);
448 }
449 
450 isc_result_t
dns_peer_settransfers(dns_peer_t * peer,isc_uint32_t newval)451 dns_peer_settransfers(dns_peer_t *peer, isc_uint32_t newval) {
452 	isc_boolean_t existed;
453 
454 	REQUIRE(DNS_PEER_VALID(peer));
455 
456 	existed = DNS_BIT_CHECK(TRANSFERS_BIT, &peer->bitflags);
457 
458 	peer->transfers = newval;
459 	DNS_BIT_SET(TRANSFERS_BIT, &peer->bitflags);
460 
461 	return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
462 }
463 
464 isc_result_t
dns_peer_gettransfers(dns_peer_t * peer,isc_uint32_t * retval)465 dns_peer_gettransfers(dns_peer_t *peer, isc_uint32_t *retval) {
466 	REQUIRE(DNS_PEER_VALID(peer));
467 	REQUIRE(retval != NULL);
468 
469 	if (DNS_BIT_CHECK(TRANSFERS_BIT, &peer->bitflags)) {
470 		*retval = peer->transfers;
471 		return (ISC_R_SUCCESS);
472 	} else {
473 		return (ISC_R_NOTFOUND);
474 	}
475 }
476 
477 isc_result_t
dns_peer_settransferformat(dns_peer_t * peer,dns_transfer_format_t newval)478 dns_peer_settransferformat(dns_peer_t *peer, dns_transfer_format_t newval) {
479 	isc_boolean_t existed;
480 
481 	REQUIRE(DNS_PEER_VALID(peer));
482 
483 	existed = DNS_BIT_CHECK(SERVER_TRANSFER_FORMAT_BIT,
484 				 &peer->bitflags);
485 
486 	peer->transfer_format = newval;
487 	DNS_BIT_SET(SERVER_TRANSFER_FORMAT_BIT, &peer->bitflags);
488 
489 	return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
490 }
491 
492 isc_result_t
dns_peer_gettransferformat(dns_peer_t * peer,dns_transfer_format_t * retval)493 dns_peer_gettransferformat(dns_peer_t *peer, dns_transfer_format_t *retval) {
494 	REQUIRE(DNS_PEER_VALID(peer));
495 	REQUIRE(retval != NULL);
496 
497 	if (DNS_BIT_CHECK(SERVER_TRANSFER_FORMAT_BIT, &peer->bitflags)) {
498 		*retval = peer->transfer_format;
499 		return (ISC_R_SUCCESS);
500 	} else {
501 		return (ISC_R_NOTFOUND);
502 	}
503 }
504 
505 isc_result_t
dns_peer_getkey(dns_peer_t * peer,dns_name_t ** retval)506 dns_peer_getkey(dns_peer_t *peer, dns_name_t **retval) {
507 	REQUIRE(DNS_PEER_VALID(peer));
508 	REQUIRE(retval != NULL);
509 
510 	if (peer->key != NULL) {
511 		*retval = peer->key;
512 	}
513 
514 	return (peer->key == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
515 }
516 
517 isc_result_t
dns_peer_setkey(dns_peer_t * peer,dns_name_t ** keyval)518 dns_peer_setkey(dns_peer_t *peer, dns_name_t **keyval) {
519 	isc_boolean_t exists = ISC_FALSE;
520 
521 	if (peer->key != NULL) {
522 		dns_name_free(peer->key, peer->mem);
523 		isc_mem_put(peer->mem, peer->key, sizeof(dns_name_t));
524 		exists = ISC_TRUE;
525 	}
526 
527 	peer->key = *keyval;
528 	*keyval = NULL;
529 
530 	return (exists ? ISC_R_EXISTS : ISC_R_SUCCESS);
531 }
532 
533 isc_result_t
dns_peer_setkeybycharp(dns_peer_t * peer,const char * keyval)534 dns_peer_setkeybycharp(dns_peer_t *peer, const char *keyval) {
535 	isc_buffer_t b;
536 	dns_fixedname_t fname;
537 	dns_name_t *name;
538 	isc_result_t result;
539 
540 	dns_fixedname_init(&fname);
541 	isc_buffer_constinit(&b, keyval, strlen(keyval));
542 	isc_buffer_add(&b, strlen(keyval));
543 	result = dns_name_fromtext(dns_fixedname_name(&fname), &b,
544 				   dns_rootname, 0, NULL);
545 	if (result != ISC_R_SUCCESS)
546 		return (result);
547 
548 	name = isc_mem_get(peer->mem, sizeof(dns_name_t));
549 	if (name == NULL)
550 		return (ISC_R_NOMEMORY);
551 
552 	dns_name_init(name, NULL);
553 	result = dns_name_dup(dns_fixedname_name(&fname), peer->mem, name);
554 	if (result != ISC_R_SUCCESS) {
555 		isc_mem_put(peer->mem, name, sizeof(dns_name_t));
556 		return (result);
557 	}
558 
559 	result = dns_peer_setkey(peer, &name);
560 	if (result != ISC_R_SUCCESS)
561 		isc_mem_put(peer->mem, name, sizeof(dns_name_t));
562 
563 	return (result);
564 }
565 
566 isc_result_t
dns_peer_settransfersource(dns_peer_t * peer,const isc_sockaddr_t * transfer_source)567 dns_peer_settransfersource(dns_peer_t *peer,
568 			   const isc_sockaddr_t *transfer_source)
569 {
570 	REQUIRE(DNS_PEER_VALID(peer));
571 
572 	if (peer->transfer_source != NULL) {
573 		isc_mem_put(peer->mem, peer->transfer_source,
574 			    sizeof(*peer->transfer_source));
575 		peer->transfer_source = NULL;
576 	}
577 	if (transfer_source != NULL) {
578 		peer->transfer_source = isc_mem_get(peer->mem,
579 						sizeof(*peer->transfer_source));
580 		if (peer->transfer_source == NULL)
581 			return (ISC_R_NOMEMORY);
582 
583 		*peer->transfer_source = *transfer_source;
584 	}
585 	return (ISC_R_SUCCESS);
586 }
587 
588 isc_result_t
dns_peer_gettransfersource(dns_peer_t * peer,isc_sockaddr_t * transfer_source)589 dns_peer_gettransfersource(dns_peer_t *peer, isc_sockaddr_t *transfer_source) {
590 	REQUIRE(DNS_PEER_VALID(peer));
591 	REQUIRE(transfer_source != NULL);
592 
593 	if (peer->transfer_source == NULL)
594 		return (ISC_R_NOTFOUND);
595 	*transfer_source = *peer->transfer_source;
596 	return (ISC_R_SUCCESS);
597 }
598 
599 isc_result_t
dns_peer_setnotifysource(dns_peer_t * peer,const isc_sockaddr_t * notify_source)600 dns_peer_setnotifysource(dns_peer_t *peer,
601 			 const isc_sockaddr_t *notify_source)
602 {
603 	REQUIRE(DNS_PEER_VALID(peer));
604 
605 	if (peer->notify_source != NULL) {
606 		isc_mem_put(peer->mem, peer->notify_source,
607 			    sizeof(*peer->notify_source));
608 		peer->notify_source = NULL;
609 	}
610 	if (notify_source != NULL) {
611 		peer->notify_source = isc_mem_get(peer->mem,
612 						sizeof(*peer->notify_source));
613 		if (peer->notify_source == NULL)
614 			return (ISC_R_NOMEMORY);
615 
616 		*peer->notify_source = *notify_source;
617 	}
618 	return (ISC_R_SUCCESS);
619 }
620 
621 isc_result_t
dns_peer_getnotifysource(dns_peer_t * peer,isc_sockaddr_t * notify_source)622 dns_peer_getnotifysource(dns_peer_t *peer, isc_sockaddr_t *notify_source) {
623 	REQUIRE(DNS_PEER_VALID(peer));
624 	REQUIRE(notify_source != NULL);
625 
626 	if (peer->notify_source == NULL)
627 		return (ISC_R_NOTFOUND);
628 	*notify_source = *peer->notify_source;
629 	return (ISC_R_SUCCESS);
630 }
631 
632 isc_result_t
dns_peer_setquerysource(dns_peer_t * peer,const isc_sockaddr_t * query_source)633 dns_peer_setquerysource(dns_peer_t *peer, const isc_sockaddr_t *query_source) {
634 	REQUIRE(DNS_PEER_VALID(peer));
635 
636 	if (peer->query_source != NULL) {
637 		isc_mem_put(peer->mem, peer->query_source,
638 			    sizeof(*peer->query_source));
639 		peer->query_source = NULL;
640 	}
641 	if (query_source != NULL) {
642 		peer->query_source = isc_mem_get(peer->mem,
643 						sizeof(*peer->query_source));
644 		if (peer->query_source == NULL)
645 			return (ISC_R_NOMEMORY);
646 
647 		*peer->query_source = *query_source;
648 	}
649 	return (ISC_R_SUCCESS);
650 }
651 
652 isc_result_t
dns_peer_getquerysource(dns_peer_t * peer,isc_sockaddr_t * query_source)653 dns_peer_getquerysource(dns_peer_t *peer, isc_sockaddr_t *query_source) {
654 	REQUIRE(DNS_PEER_VALID(peer));
655 	REQUIRE(query_source != NULL);
656 
657 	if (peer->query_source == NULL)
658 		return (ISC_R_NOTFOUND);
659 	*query_source = *peer->query_source;
660 	return (ISC_R_SUCCESS);
661 }
662 
663 isc_result_t
dns_peer_setudpsize(dns_peer_t * peer,isc_uint16_t udpsize)664 dns_peer_setudpsize(dns_peer_t *peer, isc_uint16_t udpsize) {
665 	isc_boolean_t existed;
666 
667 	REQUIRE(DNS_PEER_VALID(peer));
668 
669 	existed = DNS_BIT_CHECK(SERVER_UDPSIZE_BIT, &peer->bitflags);
670 
671 	peer->udpsize = udpsize;
672 	DNS_BIT_SET(SERVER_UDPSIZE_BIT, &peer->bitflags);
673 
674 	return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
675 }
676 
677 isc_result_t
dns_peer_getudpsize(dns_peer_t * peer,isc_uint16_t * udpsize)678 dns_peer_getudpsize(dns_peer_t *peer, isc_uint16_t *udpsize) {
679 
680 	REQUIRE(DNS_PEER_VALID(peer));
681 	REQUIRE(udpsize != NULL);
682 
683 	if (DNS_BIT_CHECK(SERVER_UDPSIZE_BIT, &peer->bitflags)) {
684 		*udpsize = peer->udpsize;
685 		return (ISC_R_SUCCESS);
686 	} else {
687 		return (ISC_R_NOTFOUND);
688 	}
689 }
690 
691 isc_result_t
dns_peer_setmaxudp(dns_peer_t * peer,isc_uint16_t maxudp)692 dns_peer_setmaxudp(dns_peer_t *peer, isc_uint16_t maxudp) {
693 	isc_boolean_t existed;
694 
695 	REQUIRE(DNS_PEER_VALID(peer));
696 
697 	existed = DNS_BIT_CHECK(SERVER_MAXUDP_BIT, &peer->bitflags);
698 
699 	peer->maxudp = maxudp;
700 	DNS_BIT_SET(SERVER_MAXUDP_BIT, &peer->bitflags);
701 
702 	return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
703 }
704 
705 isc_result_t
dns_peer_getmaxudp(dns_peer_t * peer,isc_uint16_t * maxudp)706 dns_peer_getmaxudp(dns_peer_t *peer, isc_uint16_t *maxudp) {
707 
708 	REQUIRE(DNS_PEER_VALID(peer));
709 	REQUIRE(maxudp != NULL);
710 
711 	if (DNS_BIT_CHECK(SERVER_MAXUDP_BIT, &peer->bitflags)) {
712 		*maxudp = peer->maxudp;
713 		return (ISC_R_SUCCESS);
714 	} else {
715 		return (ISC_R_NOTFOUND);
716 	}
717 }
718