1 /*
2  * Copyright (C) 2004-2009, 2011-2015  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 1999-2002  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: interfacemgr.c,v 1.101 2011/11/09 18:44:03 each Exp $ */
19 
20 /*! \file */
21 
22 #include <config.h>
23 
24 #include <isc/interfaceiter.h>
25 #include <isc/os.h>
26 #include <isc/string.h>
27 #include <isc/task.h>
28 #include <isc/util.h>
29 
30 #include <dns/acl.h>
31 #include <dns/dispatch.h>
32 
33 #include <named/client.h>
34 #include <named/log.h>
35 #include <named/interfacemgr.h>
36 
37 #define IFMGR_MAGIC			ISC_MAGIC('I', 'F', 'M', 'G')
38 #define NS_INTERFACEMGR_VALID(t)	ISC_MAGIC_VALID(t, IFMGR_MAGIC)
39 
40 #define IFMGR_COMMON_LOGARGS \
41 	ns_g_lctx, NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR
42 
43 /*% nameserver interface manager structure */
44 struct ns_interfacemgr {
45 	unsigned int		magic;		/*%< Magic number. */
46 	int			references;
47 	isc_mutex_t		lock;
48 	isc_mem_t *		mctx;		/*%< Memory context. */
49 	isc_taskmgr_t *		taskmgr;	/*%< Task manager. */
50 	isc_socketmgr_t *	socketmgr;	/*%< Socket manager. */
51 	dns_dispatchmgr_t *	dispatchmgr;
52 	unsigned int		generation;	/*%< Current generation no. */
53 	ns_listenlist_t *	listenon4;
54 	ns_listenlist_t *	listenon6;
55 	dns_aclenv_t		aclenv;		/*%< Localhost/localnets ACLs */
56 	ISC_LIST(ns_interface_t) interfaces;	/*%< List of interfaces. */
57 	ISC_LIST(isc_sockaddr_t) listenon;
58 };
59 
60 static void
61 purge_old_interfaces(ns_interfacemgr_t *mgr);
62 
63 static void
64 clearlistenon(ns_interfacemgr_t *mgr);
65 
66 isc_result_t
ns_interfacemgr_create(isc_mem_t * mctx,isc_taskmgr_t * taskmgr,isc_socketmgr_t * socketmgr,dns_dispatchmgr_t * dispatchmgr,ns_interfacemgr_t ** mgrp)67 ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
68 		       isc_socketmgr_t *socketmgr,
69 		       dns_dispatchmgr_t *dispatchmgr,
70 		       ns_interfacemgr_t **mgrp)
71 {
72 	isc_result_t result;
73 	ns_interfacemgr_t *mgr;
74 
75 	REQUIRE(mctx != NULL);
76 	REQUIRE(mgrp != NULL);
77 	REQUIRE(*mgrp == NULL);
78 
79 	mgr = isc_mem_get(mctx, sizeof(*mgr));
80 	if (mgr == NULL)
81 		return (ISC_R_NOMEMORY);
82 
83 	mgr->mctx = NULL;
84 	isc_mem_attach(mctx, &mgr->mctx);
85 
86 	result = isc_mutex_init(&mgr->lock);
87 	if (result != ISC_R_SUCCESS)
88 		goto cleanup_mem;
89 
90 	mgr->taskmgr = taskmgr;
91 	mgr->socketmgr = socketmgr;
92 	mgr->dispatchmgr = dispatchmgr;
93 	mgr->generation = 1;
94 	mgr->listenon4 = NULL;
95 	mgr->listenon6 = NULL;
96 
97 	ISC_LIST_INIT(mgr->interfaces);
98 	ISC_LIST_INIT(mgr->listenon);
99 
100 	/*
101 	 * The listen-on lists are initially empty.
102 	 */
103 	result = ns_listenlist_create(mctx, &mgr->listenon4);
104 	if (result != ISC_R_SUCCESS)
105 		goto cleanup_mem;
106 	ns_listenlist_attach(mgr->listenon4, &mgr->listenon6);
107 
108 	result = dns_aclenv_init(mctx, &mgr->aclenv);
109 	if (result != ISC_R_SUCCESS)
110 		goto cleanup_listenon;
111 
112 	mgr->references = 1;
113 	mgr->magic = IFMGR_MAGIC;
114 	*mgrp = mgr;
115 	return (ISC_R_SUCCESS);
116 
117  cleanup_listenon:
118 	ns_listenlist_detach(&mgr->listenon4);
119 	ns_listenlist_detach(&mgr->listenon6);
120  cleanup_mem:
121 	isc_mem_putanddetach(&mgr->mctx, mgr, sizeof(*mgr));
122 	return (result);
123 }
124 
125 static void
ns_interfacemgr_destroy(ns_interfacemgr_t * mgr)126 ns_interfacemgr_destroy(ns_interfacemgr_t *mgr) {
127 	REQUIRE(NS_INTERFACEMGR_VALID(mgr));
128 	dns_aclenv_destroy(&mgr->aclenv);
129 	ns_listenlist_detach(&mgr->listenon4);
130 	ns_listenlist_detach(&mgr->listenon6);
131 	clearlistenon(mgr);
132 	DESTROYLOCK(&mgr->lock);
133 	mgr->magic = 0;
134 	isc_mem_putanddetach(&mgr->mctx, mgr, sizeof(*mgr));
135 }
136 
137 dns_aclenv_t *
ns_interfacemgr_getaclenv(ns_interfacemgr_t * mgr)138 ns_interfacemgr_getaclenv(ns_interfacemgr_t *mgr) {
139 	return (&mgr->aclenv);
140 }
141 
142 void
ns_interfacemgr_attach(ns_interfacemgr_t * source,ns_interfacemgr_t ** target)143 ns_interfacemgr_attach(ns_interfacemgr_t *source, ns_interfacemgr_t **target) {
144 	REQUIRE(NS_INTERFACEMGR_VALID(source));
145 	LOCK(&source->lock);
146 	INSIST(source->references > 0);
147 	source->references++;
148 	UNLOCK(&source->lock);
149 	*target = source;
150 }
151 
152 void
ns_interfacemgr_detach(ns_interfacemgr_t ** targetp)153 ns_interfacemgr_detach(ns_interfacemgr_t **targetp) {
154 	isc_result_t need_destroy = ISC_FALSE;
155 	ns_interfacemgr_t *target = *targetp;
156 	REQUIRE(target != NULL);
157 	REQUIRE(NS_INTERFACEMGR_VALID(target));
158 	LOCK(&target->lock);
159 	REQUIRE(target->references > 0);
160 	target->references--;
161 	if (target->references == 0)
162 		need_destroy = ISC_TRUE;
163 	UNLOCK(&target->lock);
164 	if (need_destroy)
165 		ns_interfacemgr_destroy(target);
166 	*targetp = NULL;
167 }
168 
169 void
ns_interfacemgr_shutdown(ns_interfacemgr_t * mgr)170 ns_interfacemgr_shutdown(ns_interfacemgr_t *mgr) {
171 	REQUIRE(NS_INTERFACEMGR_VALID(mgr));
172 
173 	/*%
174 	 * Shut down and detach all interfaces.
175 	 * By incrementing the generation count, we make purge_old_interfaces()
176 	 * consider all interfaces "old".
177 	 */
178 	mgr->generation++;
179 	purge_old_interfaces(mgr);
180 }
181 
182 
183 static isc_result_t
ns_interface_create(ns_interfacemgr_t * mgr,isc_sockaddr_t * addr,const char * name,ns_interface_t ** ifpret)184 ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
185 		    const char *name, ns_interface_t **ifpret)
186 {
187 	ns_interface_t *ifp;
188 	isc_result_t result;
189 	int disp;
190 
191 	REQUIRE(NS_INTERFACEMGR_VALID(mgr));
192 
193 	ifp = isc_mem_get(mgr->mctx, sizeof(*ifp));
194 	if (ifp == NULL)
195 		return (ISC_R_NOMEMORY);
196 
197 	ifp->mgr = NULL;
198 	ifp->generation = mgr->generation;
199 	ifp->addr = *addr;
200 	ifp->flags = 0;
201 	strncpy(ifp->name, name, sizeof(ifp->name));
202 	ifp->name[sizeof(ifp->name)-1] = '\0';
203 	ifp->clientmgr = NULL;
204 
205 	result = isc_mutex_init(&ifp->lock);
206 	if (result != ISC_R_SUCCESS)
207 		goto lock_create_failure;
208 
209 	result = ns_clientmgr_create(mgr->mctx, mgr->taskmgr,
210 				     ns_g_timermgr,
211 				     &ifp->clientmgr);
212 	if (result != ISC_R_SUCCESS) {
213 		isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,
214 			      "ns_clientmgr_create() failed: %s",
215 			      isc_result_totext(result));
216 		goto clientmgr_create_failure;
217 	}
218 
219 	for (disp = 0; disp < MAX_UDP_DISPATCH; disp++)
220 		ifp->udpdispatch[disp] = NULL;
221 
222 	ifp->tcpsocket = NULL;
223 
224 	/*
225 	 * Create a single TCP client object.  It will replace itself
226 	 * with a new one as soon as it gets a connection, so the actual
227 	 * connections will be handled in parallel even though there is
228 	 * only one client initially.
229 	 */
230 	ifp->ntcptarget = 1;
231 	ifp->ntcpcurrent = 0;
232 	ifp->nudpdispatch = 0;
233 
234 	ISC_LINK_INIT(ifp, link);
235 
236 	ns_interfacemgr_attach(mgr, &ifp->mgr);
237 	ISC_LIST_APPEND(mgr->interfaces, ifp, link);
238 
239 	ifp->references = 1;
240 	ifp->magic = IFACE_MAGIC;
241 	*ifpret = ifp;
242 
243 	return (ISC_R_SUCCESS);
244 
245  clientmgr_create_failure:
246 	DESTROYLOCK(&ifp->lock);
247 
248  lock_create_failure:
249 	ifp->magic = 0;
250 	isc_mem_put(mgr->mctx, ifp, sizeof(*ifp));
251 
252 	return (ISC_R_UNEXPECTED);
253 }
254 
255 static isc_result_t
ns_interface_listenudp(ns_interface_t * ifp)256 ns_interface_listenudp(ns_interface_t *ifp) {
257 	isc_result_t result;
258 	unsigned int attrs;
259 	unsigned int attrmask;
260 	int disp, i;
261 
262 	attrs = 0;
263 	attrs |= DNS_DISPATCHATTR_UDP;
264 	if (isc_sockaddr_pf(&ifp->addr) == AF_INET)
265 		attrs |= DNS_DISPATCHATTR_IPV4;
266 	else
267 		attrs |= DNS_DISPATCHATTR_IPV6;
268 	attrs |= DNS_DISPATCHATTR_NOLISTEN;
269 	attrmask = 0;
270 	attrmask |= DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_TCP;
271 	attrmask |= DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_IPV6;
272 
273 	ifp->nudpdispatch = ISC_MIN(ns_g_udpdisp, MAX_UDP_DISPATCH);
274 	for (disp = 0; disp < ifp->nudpdispatch; disp++) {
275 		result = dns_dispatch_getudp_dup(ifp->mgr->dispatchmgr,
276 						 ns_g_socketmgr,
277 						 ns_g_taskmgr, &ifp->addr,
278 						 4096, 1000, 32768, 8219, 8237,
279 						 attrs, attrmask,
280 						 &ifp->udpdispatch[disp],
281 						 disp == 0
282 						    ? NULL
283 						    : ifp->udpdispatch[0]);
284 		if (result != ISC_R_SUCCESS) {
285 			isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,
286 				      "could not listen on UDP socket: %s",
287 				      isc_result_totext(result));
288 			goto udp_dispatch_failure;
289 		}
290 
291 	}
292 
293 	result = ns_clientmgr_createclients(ifp->clientmgr, ifp->nudpdispatch,
294 					    ifp, ISC_FALSE);
295 	if (result != ISC_R_SUCCESS) {
296 		UNEXPECTED_ERROR(__FILE__, __LINE__,
297 				 "UDP ns_clientmgr_createclients(): %s",
298 				 isc_result_totext(result));
299 		goto addtodispatch_failure;
300 	}
301 
302 	return (ISC_R_SUCCESS);
303 
304  addtodispatch_failure:
305 	for (i = disp - 1; i >= 0; i--) {
306 		dns_dispatch_changeattributes(ifp->udpdispatch[i], 0,
307 					      DNS_DISPATCHATTR_NOLISTEN);
308 		dns_dispatch_detach(&(ifp->udpdispatch[i]));
309 	}
310 	ifp->nudpdispatch = 0;
311 
312  udp_dispatch_failure:
313 	return (result);
314 }
315 
316 static isc_result_t
ns_interface_accepttcp(ns_interface_t * ifp)317 ns_interface_accepttcp(ns_interface_t *ifp) {
318 	isc_result_t result;
319 
320 	/*
321 	 * Open a TCP socket.
322 	 */
323 	result = isc_socket_create(ifp->mgr->socketmgr,
324 				   isc_sockaddr_pf(&ifp->addr),
325 				   isc_sockettype_tcp,
326 				   &ifp->tcpsocket);
327 	if (result != ISC_R_SUCCESS) {
328 		isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,
329 				 "creating TCP socket: %s",
330 				 isc_result_totext(result));
331 		goto tcp_socket_failure;
332 	}
333 	isc_socket_setname(ifp->tcpsocket, "dispatcher", NULL);
334 #ifndef ISC_ALLOW_MAPPED
335 	isc_socket_ipv6only(ifp->tcpsocket, ISC_TRUE);
336 #endif
337 	result = isc_socket_bind(ifp->tcpsocket, &ifp->addr,
338 				 ISC_SOCKET_REUSEADDRESS);
339 	if (result != ISC_R_SUCCESS) {
340 		isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,
341 				 "binding TCP socket: %s",
342 				 isc_result_totext(result));
343 		goto tcp_bind_failure;
344 	}
345 	result = isc_socket_listen(ifp->tcpsocket, ns_g_listen);
346 	if (result != ISC_R_SUCCESS) {
347 		isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,
348 				 "listening on TCP socket: %s",
349 				 isc_result_totext(result));
350 		goto tcp_listen_failure;
351 	}
352 
353 	/*
354 	 * If/when there a multiple filters listen to the
355 	 * result.
356 	 */
357 	(void)isc_socket_filter(ifp->tcpsocket, "dataready");
358 
359 	result = ns_clientmgr_createclients(ifp->clientmgr,
360 					    ifp->ntcptarget, ifp,
361 					    ISC_TRUE);
362 	if (result != ISC_R_SUCCESS) {
363 		UNEXPECTED_ERROR(__FILE__, __LINE__,
364 				 "TCP ns_clientmgr_createclients(): %s",
365 				 isc_result_totext(result));
366 		goto accepttcp_failure;
367 	}
368 	return (ISC_R_SUCCESS);
369 
370  accepttcp_failure:
371  tcp_listen_failure:
372  tcp_bind_failure:
373 	isc_socket_detach(&ifp->tcpsocket);
374  tcp_socket_failure:
375 	return (ISC_R_SUCCESS);
376 }
377 
378 static isc_result_t
ns_interface_setup(ns_interfacemgr_t * mgr,isc_sockaddr_t * addr,const char * name,ns_interface_t ** ifpret,isc_boolean_t accept_tcp)379 ns_interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
380 		   const char *name, ns_interface_t **ifpret,
381 		   isc_boolean_t accept_tcp)
382 {
383 	isc_result_t result;
384 	ns_interface_t *ifp = NULL;
385 	REQUIRE(ifpret != NULL && *ifpret == NULL);
386 
387 	result = ns_interface_create(mgr, addr, name, &ifp);
388 	if (result != ISC_R_SUCCESS)
389 		return (result);
390 
391 	result = ns_interface_listenudp(ifp);
392 	if (result != ISC_R_SUCCESS)
393 		goto cleanup_interface;
394 
395 	if (!ns_g_notcp && accept_tcp == ISC_TRUE) {
396 		result = ns_interface_accepttcp(ifp);
397 		if (result != ISC_R_SUCCESS) {
398 			/*
399 			 * XXXRTH We don't currently have a way to easily stop
400 			 * dispatch service, so we currently return
401 			 * ISC_R_SUCCESS (the UDP stuff will work even if TCP
402 			 * creation failed).  This will be fixed later.
403 			 */
404 			result = ISC_R_SUCCESS;
405 		}
406 	}
407 	*ifpret = ifp;
408 	return (result);
409 
410  cleanup_interface:
411 	ISC_LIST_UNLINK(ifp->mgr->interfaces, ifp, link);
412 	ns_interface_detach(&ifp);
413 	return (result);
414 }
415 
416 void
ns_interface_shutdown(ns_interface_t * ifp)417 ns_interface_shutdown(ns_interface_t *ifp) {
418 	if (ifp->clientmgr != NULL)
419 		ns_clientmgr_destroy(&ifp->clientmgr);
420 }
421 
422 static void
ns_interface_destroy(ns_interface_t * ifp)423 ns_interface_destroy(ns_interface_t *ifp) {
424 	isc_mem_t *mctx = ifp->mgr->mctx;
425 	int disp;
426 
427 	REQUIRE(NS_INTERFACE_VALID(ifp));
428 
429 	ns_interface_shutdown(ifp);
430 
431 	for (disp = 0; disp < ifp->nudpdispatch; disp++)
432 		if (ifp->udpdispatch[disp] != NULL) {
433 			dns_dispatch_changeattributes(ifp->udpdispatch[disp], 0,
434 						    DNS_DISPATCHATTR_NOLISTEN);
435 			dns_dispatch_detach(&(ifp->udpdispatch[disp]));
436 		}
437 
438 	if (ifp->tcpsocket != NULL)
439 		isc_socket_detach(&ifp->tcpsocket);
440 
441 	DESTROYLOCK(&ifp->lock);
442 
443 	ns_interfacemgr_detach(&ifp->mgr);
444 
445 	ifp->magic = 0;
446 	isc_mem_put(mctx, ifp, sizeof(*ifp));
447 }
448 
449 void
ns_interface_attach(ns_interface_t * source,ns_interface_t ** target)450 ns_interface_attach(ns_interface_t *source, ns_interface_t **target) {
451 	REQUIRE(NS_INTERFACE_VALID(source));
452 	LOCK(&source->lock);
453 	INSIST(source->references > 0);
454 	source->references++;
455 	UNLOCK(&source->lock);
456 	*target = source;
457 }
458 
459 void
ns_interface_detach(ns_interface_t ** targetp)460 ns_interface_detach(ns_interface_t **targetp) {
461 	isc_result_t need_destroy = ISC_FALSE;
462 	ns_interface_t *target = *targetp;
463 	REQUIRE(target != NULL);
464 	REQUIRE(NS_INTERFACE_VALID(target));
465 	LOCK(&target->lock);
466 	REQUIRE(target->references > 0);
467 	target->references--;
468 	if (target->references == 0)
469 		need_destroy = ISC_TRUE;
470 	UNLOCK(&target->lock);
471 	if (need_destroy)
472 		ns_interface_destroy(target);
473 	*targetp = NULL;
474 }
475 
476 /*%
477  * Search the interface list for an interface whose address and port
478  * both match those of 'addr'.  Return a pointer to it, or NULL if not found.
479  */
480 static ns_interface_t *
find_matching_interface(ns_interfacemgr_t * mgr,isc_sockaddr_t * addr)481 find_matching_interface(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr) {
482 	ns_interface_t *ifp;
483 	for (ifp = ISC_LIST_HEAD(mgr->interfaces); ifp != NULL;
484 	     ifp = ISC_LIST_NEXT(ifp, link)) {
485 		if (isc_sockaddr_equal(&ifp->addr, addr))
486 			break;
487 	}
488 	return (ifp);
489 }
490 
491 /*%
492  * Remove any interfaces whose generation number is not the current one.
493  */
494 static void
purge_old_interfaces(ns_interfacemgr_t * mgr)495 purge_old_interfaces(ns_interfacemgr_t *mgr) {
496 	ns_interface_t *ifp, *next;
497 	for (ifp = ISC_LIST_HEAD(mgr->interfaces); ifp != NULL; ifp = next) {
498 		INSIST(NS_INTERFACE_VALID(ifp));
499 		next = ISC_LIST_NEXT(ifp, link);
500 		if (ifp->generation != mgr->generation) {
501 			char sabuf[256];
502 			ISC_LIST_UNLINK(ifp->mgr->interfaces, ifp, link);
503 			isc_sockaddr_format(&ifp->addr, sabuf, sizeof(sabuf));
504 			isc_log_write(IFMGR_COMMON_LOGARGS,
505 				      ISC_LOG_INFO,
506 				      "no longer listening on %s", sabuf);
507 			ns_interface_shutdown(ifp);
508 			ns_interface_detach(&ifp);
509 		}
510 	}
511 }
512 
513 static isc_result_t
clearacl(isc_mem_t * mctx,dns_acl_t ** aclp)514 clearacl(isc_mem_t *mctx, dns_acl_t **aclp) {
515 	dns_acl_t *newacl = NULL;
516 	isc_result_t result;
517 	result = dns_acl_create(mctx, 0, &newacl);
518 	if (result != ISC_R_SUCCESS)
519 		return (result);
520 	dns_acl_detach(aclp);
521 	dns_acl_attach(newacl, aclp);
522 	dns_acl_detach(&newacl);
523 	return (ISC_R_SUCCESS);
524 }
525 
526 static isc_boolean_t
listenon_is_ip6_any(ns_listenelt_t * elt)527 listenon_is_ip6_any(ns_listenelt_t *elt) {
528 	REQUIRE(elt && elt->acl);
529 	return dns_acl_isany(elt->acl);
530 }
531 
532 static isc_result_t
setup_locals(ns_interfacemgr_t * mgr,isc_interface_t * interface)533 setup_locals(ns_interfacemgr_t *mgr, isc_interface_t *interface) {
534 	isc_result_t result;
535 	unsigned int prefixlen;
536 	isc_netaddr_t *netaddr;
537 
538 	netaddr = &interface->address;
539 
540 	/* First add localhost address */
541 	prefixlen = (netaddr->family == AF_INET) ? 32 : 128;
542 	result = dns_iptable_addprefix(mgr->aclenv.localhost->iptable,
543 				       netaddr, prefixlen, ISC_TRUE);
544 	if (result != ISC_R_SUCCESS)
545 		return (result);
546 
547 	/* Then add localnets prefix */
548 	result = isc_netaddr_masktoprefixlen(&interface->netmask,
549 					     &prefixlen);
550 
551 	/* Non contiguous netmasks not allowed by IPv6 arch. */
552 	if (result != ISC_R_SUCCESS && netaddr->family == AF_INET6)
553 		return (result);
554 
555 	if (result != ISC_R_SUCCESS) {
556 		isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_WARNING,
557 			      "omitting IPv4 interface %s from "
558 			      "localnets ACL: %s", interface->name,
559 			      isc_result_totext(result));
560 		return (ISC_R_SUCCESS);
561 	}
562 
563 	if (prefixlen == 0U) {
564 		isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_WARNING,
565 			      "omitting %s interface %s from localnets ACL: "
566 			      "zero prefix length detected",
567 			      (netaddr->family == AF_INET) ? "IPv4" : "IPv6",
568 			      interface->name);
569 		return (ISC_R_SUCCESS);
570 	}
571 
572 	result = dns_iptable_addprefix(mgr->aclenv.localnets->iptable,
573 				       netaddr, prefixlen, ISC_TRUE);
574 	if (result != ISC_R_SUCCESS)
575 		return (result);
576 
577 	return (ISC_R_SUCCESS);
578 }
579 
580 static void
setup_listenon(ns_interfacemgr_t * mgr,isc_interface_t * interface,in_port_t port)581 setup_listenon(ns_interfacemgr_t *mgr, isc_interface_t *interface,
582 	       in_port_t port)
583 {
584 	isc_sockaddr_t *addr;
585 	isc_sockaddr_t *old;
586 
587 	addr = isc_mem_get(mgr->mctx, sizeof(*addr));
588 	if (addr == NULL)
589 		return;
590 
591 	isc_sockaddr_fromnetaddr(addr, &interface->address, port);
592 
593 	for (old = ISC_LIST_HEAD(mgr->listenon);
594 	     old != NULL;
595 	     old = ISC_LIST_NEXT(old, link))
596 		if (isc_sockaddr_equal(addr, old))
597 			break;
598 
599 	if (old != NULL)
600 		isc_mem_put(mgr->mctx, addr, sizeof(*addr));
601 	else
602 		ISC_LIST_APPEND(mgr->listenon, addr, link);
603 }
604 
605 static void
clearlistenon(ns_interfacemgr_t * mgr)606 clearlistenon(ns_interfacemgr_t *mgr) {
607 	isc_sockaddr_t *old;
608 
609 	old = ISC_LIST_HEAD(mgr->listenon);
610 	while (old != NULL) {
611 		ISC_LIST_UNLINK(mgr->listenon, old, link);
612 		isc_mem_put(mgr->mctx, old, sizeof(*old));
613 		old = ISC_LIST_HEAD(mgr->listenon);
614 	}
615 }
616 
617 static isc_result_t
do_scan(ns_interfacemgr_t * mgr,ns_listenlist_t * ext_listen,isc_boolean_t verbose)618 do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
619 	isc_boolean_t verbose)
620 {
621 	isc_interfaceiter_t *iter = NULL;
622 	isc_boolean_t scan_ipv4 = ISC_FALSE;
623 	isc_boolean_t scan_ipv6 = ISC_FALSE;
624 	isc_boolean_t adjusting = ISC_FALSE;
625 	isc_boolean_t ipv6only = ISC_TRUE;
626 	isc_boolean_t ipv6pktinfo = ISC_TRUE;
627 	isc_result_t result;
628 	isc_netaddr_t zero_address, zero_address6;
629 	ns_listenelt_t *le;
630 	isc_sockaddr_t listen_addr;
631 	ns_interface_t *ifp;
632 	isc_boolean_t log_explicit = ISC_FALSE;
633 	isc_boolean_t dolistenon;
634 
635 	if (ext_listen != NULL)
636 		adjusting = ISC_TRUE;
637 
638 	if (isc_net_probeipv6() == ISC_R_SUCCESS)
639 		scan_ipv6 = ISC_TRUE;
640 #ifdef WANT_IPV6
641 	else if (!ns_g_disable6)
642 		isc_log_write(IFMGR_COMMON_LOGARGS,
643 			      verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1),
644 			      "no IPv6 interfaces found");
645 #endif
646 
647 	if (isc_net_probeipv4() == ISC_R_SUCCESS)
648 		scan_ipv4 = ISC_TRUE;
649 	else if (!ns_g_disable4)
650 		isc_log_write(IFMGR_COMMON_LOGARGS,
651 			      verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1),
652 			      "no IPv4 interfaces found");
653 
654 	/*
655 	 * A special, but typical case; listen-on-v6 { any; }.
656 	 * When we can make the socket IPv6-only, open a single wildcard
657 	 * socket for IPv6 communication.  Otherwise, make separate socket
658 	 * for each IPv6 address in order to avoid accepting IPv4 packets
659 	 * as the form of mapped addresses unintentionally unless explicitly
660 	 * allowed.
661 	 */
662 #ifndef ISC_ALLOW_MAPPED
663 	if (scan_ipv6 == ISC_TRUE &&
664 	    isc_net_probe_ipv6only() != ISC_R_SUCCESS) {
665 		ipv6only = ISC_FALSE;
666 		log_explicit = ISC_TRUE;
667 	}
668 #endif
669 	if (scan_ipv6 == ISC_TRUE &&
670 	    isc_net_probe_ipv6pktinfo() != ISC_R_SUCCESS) {
671 		ipv6pktinfo = ISC_FALSE;
672 		log_explicit = ISC_TRUE;
673 	}
674 	if (scan_ipv6 == ISC_TRUE && ipv6only && ipv6pktinfo) {
675 		for (le = ISC_LIST_HEAD(mgr->listenon6->elts);
676 		     le != NULL;
677 		     le = ISC_LIST_NEXT(le, link)) {
678 			struct in6_addr in6a;
679 
680 			if (!listenon_is_ip6_any(le))
681 				continue;
682 
683 			in6a = in6addr_any;
684 			isc_sockaddr_fromin6(&listen_addr, &in6a, le->port);
685 
686 			ifp = find_matching_interface(mgr, &listen_addr);
687 			if (ifp != NULL) {
688 				ifp->generation = mgr->generation;
689 			} else {
690 				isc_log_write(IFMGR_COMMON_LOGARGS,
691 					      ISC_LOG_INFO,
692 					      "listening on IPv6 "
693 					      "interfaces, port %u",
694 					      le->port);
695 				result = ns_interface_setup(mgr, &listen_addr,
696 							    "<any>", &ifp,
697 							    ISC_TRUE);
698 				if (result == ISC_R_SUCCESS)
699 					ifp->flags |= NS_INTERFACEFLAG_ANYADDR;
700 				else
701 					isc_log_write(IFMGR_COMMON_LOGARGS,
702 						      ISC_LOG_ERROR,
703 						      "listening on all IPv6 "
704 						      "interfaces failed");
705 				/* Continue. */
706 			}
707 		}
708 	}
709 
710 	isc_netaddr_any(&zero_address);
711 	isc_netaddr_any6(&zero_address6);
712 
713 	result = isc_interfaceiter_create(mgr->mctx, &iter);
714 	if (result != ISC_R_SUCCESS)
715 		return (result);
716 
717 	if (adjusting == ISC_FALSE) {
718 		result = clearacl(mgr->mctx, &mgr->aclenv.localhost);
719 		if (result != ISC_R_SUCCESS)
720 			goto cleanup_iter;
721 		result = clearacl(mgr->mctx, &mgr->aclenv.localnets);
722 		if (result != ISC_R_SUCCESS)
723 			goto cleanup_iter;
724 		clearlistenon(mgr);
725 	}
726 
727 	for (result = isc_interfaceiter_first(iter);
728 	     result == ISC_R_SUCCESS;
729 	     result = isc_interfaceiter_next(iter))
730 	{
731 		isc_interface_t interface;
732 		ns_listenlist_t *ll;
733 		unsigned int family;
734 
735 		result = isc_interfaceiter_current(iter, &interface);
736 		if (result != ISC_R_SUCCESS)
737 			break;
738 
739 		family = interface.address.family;
740 		if (family != AF_INET && family != AF_INET6)
741 			continue;
742 		if (scan_ipv4 == ISC_FALSE && family == AF_INET)
743 			continue;
744 		if (scan_ipv6 == ISC_FALSE && family == AF_INET6)
745 			continue;
746 
747 		/*
748 		 * Test for the address being nonzero rather than testing
749 		 * INTERFACE_F_UP, because on some systems the latter
750 		 * follows the media state and we could end up ignoring
751 		 * the interface for an entire rescan interval due to
752 		 * a temporary media glitch at rescan time.
753 		 */
754 		if (family == AF_INET &&
755 		    isc_netaddr_equal(&interface.address, &zero_address)) {
756 			continue;
757 		}
758 		if (family == AF_INET6 &&
759 		    isc_netaddr_equal(&interface.address, &zero_address6)) {
760 			continue;
761 		}
762 
763 		if (adjusting == ISC_FALSE) {
764 			result = setup_locals(mgr, &interface);
765 			if (result != ISC_R_SUCCESS)
766 				goto ignore_interface;
767 		}
768 
769 		ll = (family == AF_INET) ? mgr->listenon4 : mgr->listenon6;
770 		dolistenon = ISC_TRUE;
771 		for (le = ISC_LIST_HEAD(ll->elts);
772 		     le != NULL;
773 		     le = ISC_LIST_NEXT(le, link))
774 		{
775 			int match;
776 			isc_boolean_t ipv6_wildcard = ISC_FALSE;
777 			isc_netaddr_t listen_netaddr;
778 			isc_sockaddr_t listen_sockaddr;
779 
780 			/*
781 			 * Construct a socket address for this IP/port
782 			 * combination.
783 			 */
784 			if (family == AF_INET) {
785 				isc_netaddr_fromin(&listen_netaddr,
786 						   &interface.address.type.in);
787 			} else {
788 				isc_netaddr_fromin6(&listen_netaddr,
789 						    &interface.address.type.in6);
790 				isc_netaddr_setzone(&listen_netaddr,
791 						    interface.address.zone);
792 			}
793 			isc_sockaddr_fromnetaddr(&listen_sockaddr,
794 						 &listen_netaddr,
795 						 le->port);
796 
797 			/*
798 			 * See if the address matches the listen-on statement;
799 			 * if not, ignore the interface.
800 			 */
801 			(void)dns_acl_match(&listen_netaddr, NULL, le->acl,
802 					    &mgr->aclenv, &match, NULL);
803 			if (match <= 0)
804 				continue;
805 
806 			if (adjusting == ISC_FALSE && dolistenon == ISC_TRUE) {
807 				setup_listenon(mgr, &interface, le->port);
808 				dolistenon = ISC_FALSE;
809 			}
810 
811 			/*
812 			 * The case of "any" IPv6 address will require
813 			 * special considerations later, so remember it.
814 			 */
815 			if (family == AF_INET6 && ipv6only && ipv6pktinfo &&
816 			    listenon_is_ip6_any(le))
817 				ipv6_wildcard = ISC_TRUE;
818 
819 			/*
820 			 * When adjusting interfaces with extra a listening
821 			 * list, see if the address matches the extra list.
822 			 * If it does, and is also covered by a wildcard
823 			 * interface, we need to listen on the address
824 			 * explicitly.
825 			 */
826 			if (adjusting == ISC_TRUE) {
827 				ns_listenelt_t *ele;
828 
829 				match = 0;
830 				for (ele = ISC_LIST_HEAD(ext_listen->elts);
831 				     ele != NULL;
832 				     ele = ISC_LIST_NEXT(ele, link)) {
833 					(void)dns_acl_match(&listen_netaddr,
834 							    NULL, ele->acl,
835 							    NULL, &match, NULL);
836 					if (match > 0 &&
837 					    (ele->port == le->port ||
838 					    ele->port == 0))
839 						break;
840 					else
841 						match = 0;
842 				}
843 				if (ipv6_wildcard == ISC_TRUE && match == 0)
844 					continue;
845 			}
846 
847 			ifp = find_matching_interface(mgr, &listen_sockaddr);
848 			if (ifp != NULL) {
849 				ifp->generation = mgr->generation;
850 			} else {
851 				char sabuf[ISC_SOCKADDR_FORMATSIZE];
852 
853 				if (adjusting == ISC_FALSE &&
854 				    ipv6_wildcard == ISC_TRUE)
855 					continue;
856 
857 				if (log_explicit && family == AF_INET6 &&
858 				    !adjusting && listenon_is_ip6_any(le)) {
859 					isc_log_write(IFMGR_COMMON_LOGARGS,
860 						      verbose ? ISC_LOG_INFO :
861 							      ISC_LOG_DEBUG(1),
862 						      "IPv6 socket API is "
863 						      "incomplete; explicitly "
864 						      "binding to each IPv6 "
865 						      "address separately");
866 					log_explicit = ISC_FALSE;
867 				}
868 				isc_sockaddr_format(&listen_sockaddr,
869 						    sabuf, sizeof(sabuf));
870 				isc_log_write(IFMGR_COMMON_LOGARGS,
871 					      ISC_LOG_INFO,
872 					      "%s"
873 					      "listening on %s interface "
874 					      "%s, %s",
875 					      (adjusting == ISC_TRUE) ?
876 					      "additionally " : "",
877 					      (family == AF_INET) ?
878 					      "IPv4" : "IPv6",
879 					      interface.name, sabuf);
880 
881 				result = ns_interface_setup(mgr,
882 							    &listen_sockaddr,
883 							    interface.name,
884 							    &ifp,
885 							    (adjusting == ISC_TRUE) ?
886 							    ISC_FALSE :
887 							    ISC_TRUE);
888 
889 				if (result != ISC_R_SUCCESS) {
890 					isc_log_write(IFMGR_COMMON_LOGARGS,
891 						      ISC_LOG_ERROR,
892 						      "creating %s interface "
893 						      "%s failed; interface "
894 						      "ignored",
895 						      (family == AF_INET) ?
896 						      "IPv4" : "IPv6",
897 						      interface.name);
898 				}
899 				/* Continue. */
900 			}
901 
902 		}
903 		continue;
904 
905 	ignore_interface:
906 		isc_log_write(IFMGR_COMMON_LOGARGS,
907 			      ISC_LOG_ERROR,
908 			      "ignoring %s interface %s: %s",
909 			      (family == AF_INET) ? "IPv4" : "IPv6",
910 			      interface.name, isc_result_totext(result));
911 		continue;
912 	}
913 	if (result != ISC_R_NOMORE)
914 		UNEXPECTED_ERROR(__FILE__, __LINE__,
915 				 "interface iteration failed: %s",
916 				 isc_result_totext(result));
917 	else
918 		result = ISC_R_SUCCESS;
919  cleanup_iter:
920 	isc_interfaceiter_destroy(&iter);
921 	return (result);
922 }
923 
924 static void
ns_interfacemgr_scan0(ns_interfacemgr_t * mgr,ns_listenlist_t * ext_listen,isc_boolean_t verbose)925 ns_interfacemgr_scan0(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
926 		      isc_boolean_t verbose)
927 {
928 	isc_boolean_t purge = ISC_TRUE;
929 
930 	REQUIRE(NS_INTERFACEMGR_VALID(mgr));
931 
932 	mgr->generation++;	/* Increment the generation count. */
933 
934 	if (do_scan(mgr, ext_listen, verbose) != ISC_R_SUCCESS)
935 		purge = ISC_FALSE;
936 
937 	/*
938 	 * Now go through the interface list and delete anything that
939 	 * does not have the current generation number.  This is
940 	 * how we catch interfaces that go away or change their
941 	 * addresses.
942 	 */
943 	if (purge)
944 		purge_old_interfaces(mgr);
945 
946 	/*
947 	 * Warn if we are not listening on any interface, unless
948 	 * we're in lwresd-only mode, in which case that is to
949 	 * be expected.
950 	 */
951 	if (ext_listen == NULL &&
952 	    ISC_LIST_EMPTY(mgr->interfaces) && ! ns_g_lwresdonly) {
953 		isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_WARNING,
954 			      "not listening on any interfaces");
955 	}
956 }
957 
958 void
ns_interfacemgr_scan(ns_interfacemgr_t * mgr,isc_boolean_t verbose)959 ns_interfacemgr_scan(ns_interfacemgr_t *mgr, isc_boolean_t verbose) {
960 	ns_interfacemgr_scan0(mgr, NULL, verbose);
961 }
962 
963 void
ns_interfacemgr_adjust(ns_interfacemgr_t * mgr,ns_listenlist_t * list,isc_boolean_t verbose)964 ns_interfacemgr_adjust(ns_interfacemgr_t *mgr, ns_listenlist_t *list,
965 		       isc_boolean_t verbose)
966 {
967 	ns_interfacemgr_scan0(mgr, list, verbose);
968 }
969 
970 void
ns_interfacemgr_setlistenon4(ns_interfacemgr_t * mgr,ns_listenlist_t * value)971 ns_interfacemgr_setlistenon4(ns_interfacemgr_t *mgr, ns_listenlist_t *value) {
972 	LOCK(&mgr->lock);
973 	ns_listenlist_detach(&mgr->listenon4);
974 	ns_listenlist_attach(value, &mgr->listenon4);
975 	UNLOCK(&mgr->lock);
976 }
977 
978 void
ns_interfacemgr_setlistenon6(ns_interfacemgr_t * mgr,ns_listenlist_t * value)979 ns_interfacemgr_setlistenon6(ns_interfacemgr_t *mgr, ns_listenlist_t *value) {
980 	LOCK(&mgr->lock);
981 	ns_listenlist_detach(&mgr->listenon6);
982 	ns_listenlist_attach(value, &mgr->listenon6);
983 	UNLOCK(&mgr->lock);
984 }
985 
986 void
ns_interfacemgr_dumprecursing(FILE * f,ns_interfacemgr_t * mgr)987 ns_interfacemgr_dumprecursing(FILE *f, ns_interfacemgr_t *mgr) {
988 	ns_interface_t *interface;
989 
990 	LOCK(&mgr->lock);
991 	interface = ISC_LIST_HEAD(mgr->interfaces);
992 	while (interface != NULL) {
993 		if (interface->clientmgr != NULL)
994 			ns_client_dumprecursing(f, interface->clientmgr);
995 		interface = ISC_LIST_NEXT(interface, link);
996 	}
997 	UNLOCK(&mgr->lock);
998 }
999 
1000 isc_boolean_t
ns_interfacemgr_listeningon(ns_interfacemgr_t * mgr,isc_sockaddr_t * addr)1001 ns_interfacemgr_listeningon(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr) {
1002 	isc_sockaddr_t *old;
1003 
1004 	for (old = ISC_LIST_HEAD(mgr->listenon);
1005 	     old != NULL;
1006 	     old = ISC_LIST_NEXT(old, link))
1007 		if (isc_sockaddr_equal(old, addr))
1008 			return (ISC_TRUE);
1009 	return (ISC_FALSE);
1010 }
1011