1 /* $NetBSD: interfacemgr.c,v 1.19 2026/08/29 14:55:19 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16 /*! \file */ 17 18 #include <stdbool.h> 19 20 #include <isc/interfaceiter.h> 21 #include <isc/loop.h> 22 #include <isc/netmgr.h> 23 #include <isc/os.h> 24 #include <isc/random.h> 25 #include <isc/string.h> 26 #include <isc/tid.h> 27 #include <isc/util.h> 28 29 #include <dns/acl.h> 30 #include <dns/dispatch.h> 31 32 #include <ns/client.h> 33 #include <ns/interfacemgr.h> 34 #include <ns/log.h> 35 #include <ns/server.h> 36 #include <ns/stats.h> 37 38 #ifdef HAVE_NET_ROUTE_H 39 #include <net/route.h> 40 #if defined(RTM_VERSION) && defined(RTM_NEWADDR) && defined(RTM_DELADDR) 41 #define MSGHDR rt_msghdr 42 #define MSGTYPE rtm_type 43 #endif /* if defined(RTM_VERSION) && defined(RTM_NEWADDR) && \ 44 * defined(RTM_DELADDR) */ 45 #endif /* ifdef HAVE_NET_ROUTE_H */ 46 47 #if defined(HAVE_LINUX_NETLINK_H) && defined(HAVE_LINUX_RTNETLINK_H) 48 #define LINUX_NETLINK_AVAILABLE 49 #include <linux/netlink.h> 50 #include <linux/rtnetlink.h> 51 #if defined(RTM_NEWADDR) && defined(RTM_DELADDR) 52 #define MSGHDR nlmsghdr 53 #define MSGTYPE nlmsg_type 54 #endif /* if defined(RTM_NEWADDR) && defined(RTM_DELADDR) */ 55 #endif /* if defined(HAVE_LINUX_NETLINK_H) && defined(HAVE_LINUX_RTNETLINK_H) \ 56 */ 57 58 #define LISTENING(ifp) (((ifp)->flags & NS_INTERFACEFLAG_LISTENING) != 0) 59 60 #define IFMGR_MAGIC ISC_MAGIC('I', 'F', 'M', 'G') 61 #define NS_INTERFACEMGR_VALID(t) ISC_MAGIC_VALID(t, IFMGR_MAGIC) 62 63 #define IFMGR_COMMON_LOGARGS \ 64 ns_lctx, NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR 65 66 /*% nameserver interface manager structure */ 67 struct ns_interfacemgr { 68 unsigned int magic; /*%< Magic number */ 69 isc_refcount_t references; 70 isc_mutex_t lock; 71 isc_mem_t *mctx; /*%< Memory context */ 72 ns_server_t *sctx; /*%< Server context */ 73 isc_loopmgr_t *loopmgr; /*%< Loop manager */ 74 isc_nm_t *nm; /*%< Net manager */ 75 uint32_t ncpus; /*%< Number of workers */ 76 dns_dispatchmgr_t *dispatchmgr; 77 unsigned int generation; /*%< Current generation no */ 78 ns_listenlist_t *listenon4; 79 ns_listenlist_t *listenon6; 80 dns_aclenv_t *aclenv; /*%< Localhost/localnets ACLs */ 81 ISC_LIST(ns_interface_t) interfaces; /*%< List of interfaces */ 82 ISC_LIST(isc_sockaddr_t) listenon; 83 int backlog; /*%< Listen queue size */ 84 atomic_bool shuttingdown; /*%< Interfacemgr shutting down */ 85 ns_clientmgr_t **clientmgrs; /*%< Client managers */ 86 isc_nmhandle_t *route; 87 }; 88 89 static void 90 purge_old_interfaces(ns_interfacemgr_t *mgr); 91 92 static void 93 clearlistenon(ns_interfacemgr_t *mgr); 94 95 #if defined(RTM_NEWADDR) && defined(RTM_DELADDR) 96 static bool 97 need_rescan(ns_interfacemgr_t *mgr, struct MSGHDR *rtm, size_t len) { 98 if (rtm->MSGTYPE != RTM_NEWADDR && rtm->MSGTYPE != RTM_DELADDR) { 99 return false; 100 } 101 102 #ifndef LINUX_NETLINK_AVAILABLE 103 UNUSED(mgr); 104 UNUSED(len); 105 /* On most systems, any NEWADDR or DELADDR means we rescan */ 106 return true; 107 #else /* LINUX_NETLINK_AVAILABLE */ 108 /* ...but on linux we need to check the messages more carefully */ 109 for (struct MSGHDR *nlh = rtm; 110 NLMSG_OK(nlh, len) && nlh->nlmsg_type != NLMSG_DONE; 111 nlh = NLMSG_NEXT(nlh, len)) 112 { 113 struct ifaddrmsg *ifa = (struct ifaddrmsg *)NLMSG_DATA(nlh); 114 struct rtattr *rth = IFA_RTA(ifa); 115 size_t rtl = IFA_PAYLOAD(nlh); 116 117 while (rtl > 0 && RTA_OK(rth, rtl)) { 118 /* 119 * Look for IFA_ADDRESS to detect IPv6 interface 120 * state changes. 121 */ 122 if (rth->rta_type == IFA_ADDRESS && 123 ifa->ifa_family == AF_INET6) 124 { 125 bool existed = false; 126 bool was_listening = false; 127 isc_netaddr_t addr = { 0 }; 128 ns_interface_t *ifp = NULL; 129 130 isc_netaddr_fromin6(&addr, RTA_DATA(rth)); 131 INSIST(isc_netaddr_getzone(&addr) == 0); 132 133 /* 134 * Check whether we were listening on the 135 * address. We need to do this as the 136 * Linux kernel seems to issue messages 137 * containing IFA_ADDRESS far more often 138 * than the actual state changes (on 139 * router advertisements?) 140 */ 141 LOCK(&mgr->lock); 142 for (ifp = ISC_LIST_HEAD(mgr->interfaces); 143 ifp != NULL; 144 ifp = ISC_LIST_NEXT(ifp, link)) 145 { 146 isc_netaddr_t tmp = { 0 }; 147 isc_netaddr_fromsockaddr(&tmp, 148 &ifp->addr); 149 if (tmp.family != AF_INET6) { 150 continue; 151 } 152 153 /* 154 * We have to nullify the zone (IPv6 155 * scope ID) because we haven't got one 156 * from the kernel. Otherwise match 157 * could fail even for an existing 158 * address. 159 */ 160 isc_netaddr_setzone(&tmp, 0); 161 if (isc_netaddr_equal(&tmp, &addr)) { 162 was_listening = LISTENING(ifp); 163 existed = true; 164 break; 165 } 166 } 167 UNLOCK(&mgr->lock); 168 169 /* 170 * Do rescan if the state of the interface 171 * has changed. 172 */ 173 if ((!existed && rtm->MSGTYPE == RTM_NEWADDR) || 174 (existed && was_listening && 175 rtm->MSGTYPE == RTM_DELADDR)) 176 { 177 return true; 178 } 179 } else if (rth->rta_type == IFA_ADDRESS && 180 ifa->ifa_family == AF_INET) 181 { 182 /* 183 * It seems that the IPv4 P2P link state 184 * has changed. 185 */ 186 return true; 187 } else if (rth->rta_type == IFA_LOCAL) { 188 /* 189 * Local address state has changed - do 190 * rescan. 191 */ 192 return true; 193 } 194 rth = RTA_NEXT(rth, rtl); 195 } 196 } 197 #endif /* LINUX_NETLINK_AVAILABLE */ 198 199 return false; 200 } 201 #endif /* if defined(RTM_NEWADDR) && defined(RTM_DELADDR) */ 202 203 static void 204 route_recv(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, 205 void *arg) { 206 ns_interfacemgr_t *mgr = (ns_interfacemgr_t *)arg; 207 struct MSGHDR *rtm = NULL; 208 size_t rtmlen; 209 210 isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_DEBUG(9), "route_recv: %s", 211 isc_result_totext(eresult)); 212 213 if (handle == NULL) { 214 return; 215 } 216 217 switch (eresult) { 218 case ISC_R_SUCCESS: 219 break; 220 default: 221 isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, 222 "automatic interface scanning terminated: %s", 223 isc_result_totext(eresult)); 224 FALLTHROUGH; 225 case ISC_R_CANCELED: 226 case ISC_R_SHUTTINGDOWN: 227 case ISC_R_EOF: 228 ns_interfacemgr_routedisconnect(mgr); 229 return; 230 } 231 232 rtm = (struct MSGHDR *)region->base; 233 rtmlen = region->length; 234 235 #ifdef RTM_VERSION 236 if (rtm->rtm_version != RTM_VERSION) { 237 isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, 238 "automatic interface rescanning disabled: " 239 "rtm->rtm_version mismatch (%u != %u) " 240 "recompile required", 241 rtm->rtm_version, RTM_VERSION); 242 isc_nmhandle_detach(&mgr->route); 243 ns_interfacemgr_detach(&mgr); 244 return; 245 } 246 #endif /* ifdef RTM_VERSION */ 247 248 REQUIRE(mgr->route != NULL); 249 250 #if defined(RTM_NEWADDR) && defined(RTM_DELADDR) 251 if (need_rescan(mgr, rtm, rtmlen) && mgr->sctx->interface_auto) { 252 ns_interfacemgr_scan(mgr, false, false); 253 } 254 #endif /* if defined(RTM_NEWADDR) && defined(RTM_DELADDR) */ 255 256 isc_nm_read(handle, route_recv, mgr); 257 return; 258 } 259 260 static void 261 route_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) { 262 ns_interfacemgr_t *mgr = (ns_interfacemgr_t *)arg; 263 264 isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_DEBUG(9), 265 "route_connected: %s", isc_result_totext(eresult)); 266 267 if (eresult != ISC_R_SUCCESS) { 268 ns_interfacemgr_detach(&mgr); 269 return; 270 } 271 272 INSIST(mgr->route == NULL); 273 274 isc_nmhandle_attach(handle, &mgr->route); 275 isc_nm_read(handle, route_recv, mgr); 276 } 277 278 isc_result_t 279 ns_interfacemgr_create(isc_mem_t *mctx, ns_server_t *sctx, 280 isc_loopmgr_t *loopmgr, isc_nm_t *nm, 281 dns_dispatchmgr_t *dispatchmgr, 282 dns_geoip_databases_t *geoip, ns_interfacemgr_t **mgrp) { 283 isc_result_t result; 284 ns_interfacemgr_t *mgr = NULL; 285 286 REQUIRE(mctx != NULL); 287 REQUIRE(mgrp != NULL); 288 REQUIRE(*mgrp == NULL); 289 290 mgr = isc_mem_get(mctx, sizeof(*mgr)); 291 *mgr = (ns_interfacemgr_t){ 292 .loopmgr = loopmgr, 293 .nm = nm, 294 .dispatchmgr = dispatchmgr, 295 .generation = 1, 296 .ncpus = isc_loopmgr_nloops(loopmgr), 297 }; 298 299 isc_mem_attach(mctx, &mgr->mctx); 300 ns_server_attach(sctx, &mgr->sctx); 301 302 isc_mutex_init(&mgr->lock); 303 304 atomic_init(&mgr->shuttingdown, false); 305 306 ISC_LIST_INIT(mgr->interfaces); 307 ISC_LIST_INIT(mgr->listenon); 308 309 /* 310 * The listen-on lists are initially empty. 311 */ 312 result = ns_listenlist_create(mctx, &mgr->listenon4); 313 if (result != ISC_R_SUCCESS) { 314 goto cleanup_lock; 315 } 316 ns_listenlist_attach(mgr->listenon4, &mgr->listenon6); 317 318 dns_aclenv_create(mctx, &mgr->aclenv); 319 #if defined(HAVE_GEOIP2) 320 mgr->aclenv->geoip = geoip; 321 #else /* if defined(HAVE_GEOIP2) */ 322 UNUSED(geoip); 323 #endif /* if defined(HAVE_GEOIP2) */ 324 325 isc_refcount_init(&mgr->references, 1); 326 mgr->magic = IFMGR_MAGIC; 327 *mgrp = mgr; 328 329 mgr->clientmgrs = isc_mem_cget(mgr->mctx, mgr->ncpus, 330 sizeof(mgr->clientmgrs[0])); 331 for (size_t i = 0; i < mgr->ncpus; i++) { 332 result = ns_clientmgr_create(mgr->sctx, mgr->loopmgr, 333 mgr->aclenv, (int)i, 334 &mgr->clientmgrs[i]); 335 RUNTIME_CHECK(result == ISC_R_SUCCESS); 336 } 337 338 return ISC_R_SUCCESS; 339 340 cleanup_lock: 341 isc_mutex_destroy(&mgr->lock); 342 ns_server_detach(&mgr->sctx); 343 isc_mem_putanddetach(&mgr->mctx, mgr, sizeof(*mgr)); 344 return result; 345 } 346 347 void 348 ns_interfacemgr_routeconnect(ns_interfacemgr_t *mgr) { 349 REQUIRE(NS_INTERFACEMGR_VALID(mgr)); 350 REQUIRE(isc_tid() == 0); 351 352 if (mgr->route != NULL) { 353 return; 354 } 355 356 ns_interfacemgr_ref(mgr); 357 358 isc_result_t result = isc_nm_routeconnect(mgr->nm, route_connected, 359 mgr); 360 if (result != ISC_R_SUCCESS) { 361 isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_INFO, 362 "unable to open route socket: %s", 363 isc_result_totext(result)); 364 ns_interfacemgr_unref(mgr); 365 } 366 } 367 368 void 369 ns_interfacemgr_routedisconnect(ns_interfacemgr_t *mgr) { 370 REQUIRE(NS_INTERFACEMGR_VALID(mgr)); 371 REQUIRE(isc_tid() == 0); 372 373 if (mgr->route == NULL) { 374 return; 375 } 376 377 isc_nmhandle_close(mgr->route); 378 isc_nmhandle_detach(&mgr->route); 379 ns_interfacemgr_detach(&mgr); 380 } 381 382 static void 383 ns_interfacemgr__destroy(ns_interfacemgr_t *mgr) { 384 REQUIRE(NS_INTERFACEMGR_VALID(mgr)); 385 386 isc_refcount_destroy(&mgr->references); 387 388 dns_aclenv_detach(&mgr->aclenv); 389 ns_listenlist_detach(&mgr->listenon4); 390 ns_listenlist_detach(&mgr->listenon6); 391 clearlistenon(mgr); 392 isc_mutex_destroy(&mgr->lock); 393 for (size_t i = 0; i < mgr->ncpus; i++) { 394 ns_clientmgr_detach(&mgr->clientmgrs[i]); 395 } 396 isc_mem_cput(mgr->mctx, mgr->clientmgrs, mgr->ncpus, 397 sizeof(mgr->clientmgrs[0])); 398 399 if (mgr->sctx != NULL) { 400 ns_server_detach(&mgr->sctx); 401 } 402 mgr->magic = 0; 403 isc_mem_putanddetach(&mgr->mctx, mgr, sizeof(*mgr)); 404 } 405 406 void 407 ns_interfacemgr_setbacklog(ns_interfacemgr_t *mgr, int backlog) { 408 REQUIRE(NS_INTERFACEMGR_VALID(mgr)); 409 LOCK(&mgr->lock); 410 mgr->backlog = backlog; 411 UNLOCK(&mgr->lock); 412 } 413 414 dns_aclenv_t * 415 ns_interfacemgr_getaclenv(ns_interfacemgr_t *mgr) { 416 dns_aclenv_t *aclenv = NULL; 417 418 REQUIRE(NS_INTERFACEMGR_VALID(mgr)); 419 420 LOCK(&mgr->lock); 421 aclenv = mgr->aclenv; 422 UNLOCK(&mgr->lock); 423 424 return aclenv; 425 } 426 427 ISC_REFCOUNT_IMPL(ns_interfacemgr, ns_interfacemgr__destroy); 428 429 void 430 ns_interfacemgr_shutdown(ns_interfacemgr_t *mgr) { 431 REQUIRE(NS_INTERFACEMGR_VALID(mgr)); 432 433 /*% 434 * Shut down and detach all interfaces. 435 * By incrementing the generation count, we make 436 * purge_old_interfaces() consider all interfaces "old". 437 */ 438 mgr->generation++; 439 atomic_store(&mgr->shuttingdown, true); 440 441 purge_old_interfaces(mgr); 442 443 if (mgr->route != NULL) { 444 isc_nm_cancelread(mgr->route); 445 } 446 447 for (size_t i = 0; i < mgr->ncpus; i++) { 448 ns_clientmgr_shutdown(mgr->clientmgrs[i]); 449 } 450 } 451 452 void 453 ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, 454 const char *name, ns_interface_t **ifpret) { 455 ns_interface_t *ifp = NULL; 456 const char *default_name = "default"; 457 458 REQUIRE(NS_INTERFACEMGR_VALID(mgr)); 459 460 ifp = isc_mem_get(mgr->mctx, sizeof(*ifp)); 461 *ifp = (ns_interface_t){ .generation = mgr->generation, 462 .addr = *addr, 463 .proxy_type = ISC_NM_PROXY_NONE }; 464 465 if (name == NULL) { 466 name = default_name; 467 } 468 strlcpy(ifp->name, name, sizeof(ifp->name)); 469 470 isc_mutex_init(&ifp->lock); 471 472 isc_refcount_init(&ifp->ntcpaccepting, 0); 473 isc_refcount_init(&ifp->ntcpactive, 0); 474 475 ISC_LINK_INIT(ifp, link); 476 477 ns_interfacemgr_attach(mgr, &ifp->mgr); 478 ifp->magic = IFACE_MAGIC; 479 480 LOCK(&mgr->lock); 481 ISC_LIST_APPEND(mgr->interfaces, ifp, link); 482 UNLOCK(&mgr->lock); 483 484 *ifpret = ifp; 485 } 486 487 static isc_result_t 488 ns_interface_listenudp(ns_interface_t *ifp, isc_nm_proxy_type_t proxy) { 489 isc_result_t result; 490 491 /* Reserve space for an ns_client_t with the netmgr handle */ 492 if (proxy == ISC_NM_PROXY_NONE) { 493 result = isc_nm_listenudp(ifp->mgr->nm, ISC_NM_LISTEN_ALL, 494 &ifp->addr, ns_client_request, ifp, 495 &ifp->udplistensocket); 496 } else { 497 INSIST(proxy == ISC_NM_PROXY_PLAIN); 498 result = isc_nm_listenproxyudp(ifp->mgr->nm, ISC_NM_LISTEN_ALL, 499 &ifp->addr, ns_client_request, 500 ifp, &ifp->udplistensocket); 501 } 502 return result; 503 } 504 505 static isc_result_t 506 ns_interface_listentcp(ns_interface_t *ifp, isc_nm_proxy_type_t proxy) { 507 isc_result_t result; 508 509 result = isc_nm_listenstreamdns( 510 ifp->mgr->nm, ISC_NM_LISTEN_ALL, &ifp->addr, ns_client_request, 511 ifp, ns__client_tcpconn, ifp, ifp->mgr->backlog, 512 &ifp->mgr->sctx->tcpquota, NULL, proxy, &ifp->tcplistensocket); 513 if (result != ISC_R_SUCCESS) { 514 isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, 515 "creating TCP socket: %s", 516 isc_result_totext(result)); 517 } 518 519 /* 520 * We call this now to update the tcp-highwater statistic: 521 * this is necessary because we are adding to the TCP quota just 522 * by listening. 523 */ 524 result = ns__client_tcpconn(NULL, ISC_R_SUCCESS, ifp); 525 if (result != ISC_R_SUCCESS) { 526 isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, 527 "connecting TCP socket: %s", 528 isc_result_totext(result)); 529 } 530 531 return result; 532 } 533 534 /* 535 * XXXWPK we should probably pass a complete object with key, cert, and other 536 * TLS related options. 537 */ 538 static isc_result_t 539 ns_interface_listentls(ns_interface_t *ifp, isc_nm_proxy_type_t proxy, 540 isc_tlsctx_t *sslctx) { 541 isc_result_t result; 542 543 result = isc_nm_listenstreamdns( 544 ifp->mgr->nm, ISC_NM_LISTEN_ALL, &ifp->addr, ns_client_request, 545 ifp, ns__client_tcpconn, ifp, ifp->mgr->backlog, 546 &ifp->mgr->sctx->tcpquota, sslctx, proxy, 547 &ifp->tlslistensocket); 548 549 if (result != ISC_R_SUCCESS) { 550 isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, 551 "creating TLS socket: %s", 552 isc_result_totext(result)); 553 return result; 554 } 555 556 /* 557 * We call this now to update the tcp-highwater statistic: 558 * this is necessary because we are adding to the TCP quota just 559 * by listening. 560 */ 561 result = ns__client_tcpconn(NULL, ISC_R_SUCCESS, ifp); 562 if (result != ISC_R_SUCCESS) { 563 isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, 564 "updating TCP stats: %s", 565 isc_result_totext(result)); 566 } 567 568 return result; 569 } 570 571 #ifdef HAVE_LIBNGHTTP2 572 static isc_result_t 573 load_http_endpoints(isc_nm_http_endpoints_t *epset, ns_interface_t *ifp, 574 char **eps, size_t neps) { 575 isc_result_t result = ISC_R_FAILURE; 576 577 for (size_t i = 0; i < neps; i++) { 578 result = isc_nm_http_endpoints_add(epset, eps[i], 579 ns_client_request, ifp); 580 if (result != ISC_R_SUCCESS) { 581 break; 582 } 583 } 584 585 return result; 586 } 587 #endif /* HAVE_LIBNGHTTP2 */ 588 589 static isc_result_t 590 ns_interface_listenhttp(ns_interface_t *ifp, isc_nm_proxy_type_t proxy, 591 isc_tlsctx_t *sslctx, char **eps, size_t neps, 592 uint32_t max_clients, uint32_t max_concurrent_streams) { 593 #if HAVE_LIBNGHTTP2 594 isc_result_t result = ISC_R_FAILURE; 595 isc_nmsocket_t *sock = NULL; 596 isc_nm_http_endpoints_t *epset = NULL; 597 isc_quota_t *quota = NULL; 598 599 epset = isc_nm_http_endpoints_new(ifp->mgr->mctx); 600 601 result = load_http_endpoints(epset, ifp, eps, neps); 602 603 if (result == ISC_R_SUCCESS) { 604 quota = isc_mem_get(ifp->mgr->mctx, sizeof(*quota)); 605 isc_quota_init(quota, max_clients); 606 result = isc_nm_listenhttp( 607 ifp->mgr->nm, ISC_NM_LISTEN_ALL, &ifp->addr, 608 ifp->mgr->backlog, quota, sslctx, epset, 609 max_concurrent_streams, proxy, &sock); 610 } 611 612 isc_nm_http_endpoints_detach(&epset); 613 614 if (quota != NULL) { 615 if (result != ISC_R_SUCCESS) { 616 isc_quota_destroy(quota); 617 isc_mem_put(ifp->mgr->mctx, quota, sizeof(*quota)); 618 } else { 619 ifp->http_quota = quota; 620 ns_server_append_http_quota(ifp->mgr->sctx, quota); 621 } 622 } 623 624 if (result != ISC_R_SUCCESS) { 625 isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, 626 "creating %s socket: %s", 627 sslctx ? "HTTPS" : "HTTP", 628 isc_result_totext(result)); 629 return result; 630 } 631 632 if (sslctx) { 633 ifp->http_secure_listensocket = sock; 634 } else { 635 ifp->http_listensocket = sock; 636 } 637 638 /* 639 * We call this now to update the tcp-highwater statistic: 640 * this is necessary because we are adding to the TCP quota just 641 * by listening. 642 */ 643 result = ns__client_tcpconn(NULL, ISC_R_SUCCESS, ifp); 644 if (result != ISC_R_SUCCESS) { 645 isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, 646 "updating TCP stats: %s", 647 isc_result_totext(result)); 648 } 649 650 return result; 651 #else 652 UNUSED(ifp); 653 UNUSED(proxy); 654 UNUSED(sslctx); 655 UNUSED(eps); 656 UNUSED(neps); 657 UNUSED(max_clients); 658 UNUSED(max_concurrent_streams); 659 return ISC_R_NOTIMPLEMENTED; 660 #endif 661 } 662 663 static isc_result_t 664 interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, const char *name, 665 ns_interface_t **ifpret, ns_listenelt_t *elt, 666 bool *addr_in_use) { 667 isc_result_t result; 668 ns_interface_t *ifp = NULL; 669 670 REQUIRE(ifpret != NULL); 671 REQUIRE(addr_in_use == NULL || !*addr_in_use); 672 673 ifp = *ifpret; 674 675 if (ifp == NULL) { 676 ns_interface_create(mgr, addr, name, &ifp); 677 } else { 678 REQUIRE(!LISTENING(ifp)); 679 LOCK(&mgr->lock); 680 ifp->generation = mgr->generation; 681 UNLOCK(&mgr->lock); 682 } 683 684 ifp->flags |= NS_INTERFACEFLAG_LISTENING; 685 ifp->proxy_type = elt->proxy; 686 687 if (elt->is_http) { 688 result = ns_interface_listenhttp( 689 ifp, elt->proxy, elt->sslctx, elt->http_endpoints, 690 elt->http_endpoints_number, elt->http_max_clients, 691 elt->max_concurrent_streams); 692 if (result != ISC_R_SUCCESS) { 693 goto cleanup_interface; 694 } 695 *ifpret = ifp; 696 return result; 697 } 698 699 if (elt->sslctx != NULL) { 700 result = ns_interface_listentls(ifp, elt->proxy, elt->sslctx); 701 if (result != ISC_R_SUCCESS) { 702 goto cleanup_interface; 703 } 704 *ifpret = ifp; 705 return result; 706 } 707 708 result = ns_interface_listenudp(ifp, elt->proxy); 709 if (result != ISC_R_SUCCESS) { 710 if ((result == ISC_R_ADDRINUSE) && (addr_in_use != NULL)) { 711 *addr_in_use = true; 712 } 713 goto cleanup_interface; 714 } 715 716 if ((mgr->sctx->options & NS_SERVER_NOTCP) == 0) { 717 result = ns_interface_listentcp(ifp, elt->proxy); 718 if (result != ISC_R_SUCCESS) { 719 if ((result == ISC_R_ADDRINUSE) && 720 (addr_in_use != NULL)) 721 { 722 *addr_in_use = true; 723 } 724 725 /* 726 * XXXRTH We don't currently have a way to easily stop 727 * dispatch service, so we currently return 728 * ISC_R_SUCCESS (the UDP stuff will work even if TCP 729 * creation failed). This will be fixed later. 730 */ 731 result = ISC_R_SUCCESS; 732 } 733 } 734 *ifpret = ifp; 735 return result; 736 737 cleanup_interface: 738 ns_interface_shutdown(ifp); 739 return result; 740 } 741 742 void 743 ns_interface_shutdown(ns_interface_t *ifp) { 744 ifp->flags &= ~NS_INTERFACEFLAG_LISTENING; 745 746 if (ifp->udplistensocket != NULL) { 747 isc_nm_stoplistening(ifp->udplistensocket); 748 isc_nmsocket_close(&ifp->udplistensocket); 749 } 750 if (ifp->tcplistensocket != NULL) { 751 isc_nm_stoplistening(ifp->tcplistensocket); 752 isc_nmsocket_close(&ifp->tcplistensocket); 753 } 754 if (ifp->tlslistensocket != NULL) { 755 isc_nm_stoplistening(ifp->tlslistensocket); 756 isc_nmsocket_close(&ifp->tlslistensocket); 757 } 758 if (ifp->http_listensocket != NULL) { 759 isc_nm_stoplistening(ifp->http_listensocket); 760 isc_nmsocket_close(&ifp->http_listensocket); 761 } 762 if (ifp->http_secure_listensocket != NULL) { 763 isc_nm_stoplistening(ifp->http_secure_listensocket); 764 isc_nmsocket_close(&ifp->http_secure_listensocket); 765 } 766 ifp->http_quota = NULL; 767 } 768 769 static void 770 interface_destroy(ns_interface_t **interfacep) { 771 ns_interface_t *ifp = NULL; 772 ns_interfacemgr_t *mgr = NULL; 773 774 REQUIRE(interfacep != NULL); 775 776 ifp = *interfacep; 777 *interfacep = NULL; 778 779 REQUIRE(NS_INTERFACE_VALID(ifp)); 780 781 mgr = ifp->mgr; 782 783 ns_interface_shutdown(ifp); 784 785 ifp->magic = 0; 786 isc_mutex_destroy(&ifp->lock); 787 ns_interfacemgr_detach(&ifp->mgr); 788 isc_refcount_destroy(&ifp->ntcpactive); 789 isc_refcount_destroy(&ifp->ntcpaccepting); 790 791 isc_mem_put(mgr->mctx, ifp, sizeof(*ifp)); 792 } 793 794 /*% 795 * Search the interface list for an interface whose address and port 796 * both match those of 'addr'. Return a pointer to it, or NULL if not found. 797 */ 798 static ns_interface_t * 799 find_matching_interface(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr) { 800 ns_interface_t *ifp; 801 LOCK(&mgr->lock); 802 for (ifp = ISC_LIST_HEAD(mgr->interfaces); ifp != NULL; 803 ifp = ISC_LIST_NEXT(ifp, link)) 804 { 805 if (isc_sockaddr_equal(&ifp->addr, addr)) { 806 break; 807 } 808 } 809 UNLOCK(&mgr->lock); 810 return ifp; 811 } 812 813 static void 814 log_interface_shutdown(const ns_interface_t *ifp) { 815 char sabuf[ISC_SOCKADDR_FORMATSIZE]; 816 isc_sockaddr_format(&ifp->addr, sabuf, sizeof(sabuf)); 817 isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_INFO, 818 "no longer listening on %s", sabuf); 819 } 820 821 /*% 822 * Remove any interfaces whose generation number is not the current one. 823 */ 824 static void 825 purge_old_interfaces(ns_interfacemgr_t *mgr) { 826 ns_interface_t *ifp = NULL, *next = NULL; 827 ISC_LIST(ns_interface_t) interfaces; 828 829 ISC_LIST_INIT(interfaces); 830 831 LOCK(&mgr->lock); 832 for (ifp = ISC_LIST_HEAD(mgr->interfaces); ifp != NULL; ifp = next) { 833 INSIST(NS_INTERFACE_VALID(ifp)); 834 next = ISC_LIST_NEXT(ifp, link); 835 if (ifp->generation != mgr->generation) { 836 ISC_LIST_UNLINK(ifp->mgr->interfaces, ifp, link); 837 ISC_LIST_APPEND(interfaces, ifp, link); 838 } 839 } 840 UNLOCK(&mgr->lock); 841 842 for (ifp = ISC_LIST_HEAD(interfaces); ifp != NULL; ifp = next) { 843 next = ISC_LIST_NEXT(ifp, link); 844 if (LISTENING(ifp)) { 845 log_interface_shutdown(ifp); 846 ns_interface_shutdown(ifp); 847 } 848 ISC_LIST_UNLINK(interfaces, ifp, link); 849 interface_destroy(&ifp); 850 } 851 } 852 853 static bool 854 listenon_is_ip6_any(ns_listenelt_t *elt) { 855 REQUIRE(elt && elt->acl); 856 return dns_acl_isany(elt->acl); 857 } 858 859 static isc_result_t 860 setup_locals(isc_interface_t *interface, dns_acl_t *localhost, 861 dns_acl_t *localnets) { 862 isc_result_t result; 863 unsigned int prefixlen; 864 isc_netaddr_t *netaddr; 865 866 netaddr = &interface->address; 867 868 /* First add localhost address */ 869 prefixlen = (netaddr->family == AF_INET) ? 32 : 128; 870 result = dns_iptable_addprefix(localhost->iptable, netaddr, prefixlen, 871 true); 872 if (result != ISC_R_SUCCESS) { 873 return result; 874 } 875 876 /* Then add localnets prefix */ 877 result = isc_netaddr_masktoprefixlen(&interface->netmask, &prefixlen); 878 879 /* Non contiguous netmasks not allowed by IPv6 arch. */ 880 if (result != ISC_R_SUCCESS && netaddr->family == AF_INET6) { 881 return result; 882 } 883 884 if (result != ISC_R_SUCCESS) { 885 isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_WARNING, 886 "omitting IPv4 interface %s from " 887 "localnets ACL: %s", 888 interface->name, isc_result_totext(result)); 889 return ISC_R_SUCCESS; 890 } 891 892 if (prefixlen == 0U) { 893 isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_WARNING, 894 "omitting %s interface %s from localnets ACL: " 895 "zero prefix length detected", 896 (netaddr->family == AF_INET) ? "IPv4" : "IPv6", 897 interface->name); 898 return ISC_R_SUCCESS; 899 } 900 901 result = dns_iptable_addprefix(localnets->iptable, netaddr, prefixlen, 902 true); 903 if (result != ISC_R_SUCCESS) { 904 return result; 905 } 906 907 return ISC_R_SUCCESS; 908 } 909 910 static void 911 setup_listenon(ns_interfacemgr_t *mgr, isc_interface_t *interface, 912 in_port_t port) { 913 isc_sockaddr_t *addr; 914 isc_sockaddr_t *old; 915 916 addr = isc_mem_get(mgr->mctx, sizeof(*addr)); 917 918 isc_sockaddr_fromnetaddr(addr, &interface->address, port); 919 920 LOCK(&mgr->lock); 921 for (old = ISC_LIST_HEAD(mgr->listenon); old != NULL; 922 old = ISC_LIST_NEXT(old, link)) 923 { 924 if (isc_sockaddr_equal(addr, old)) { 925 /* We found an existing address */ 926 isc_mem_put(mgr->mctx, addr, sizeof(*addr)); 927 goto unlock; 928 } 929 } 930 931 ISC_LIST_APPEND(mgr->listenon, addr, link); 932 unlock: 933 UNLOCK(&mgr->lock); 934 } 935 936 static void 937 clearlistenon(ns_interfacemgr_t *mgr) { 938 ISC_LIST(isc_sockaddr_t) listenon; 939 isc_sockaddr_t *old; 940 941 ISC_LIST_INIT(listenon); 942 943 LOCK(&mgr->lock); 944 ISC_LIST_MOVE(listenon, mgr->listenon); 945 UNLOCK(&mgr->lock); 946 947 old = ISC_LIST_HEAD(listenon); 948 while (old != NULL) { 949 ISC_LIST_UNLINK(listenon, old, link); 950 isc_mem_put(mgr->mctx, old, sizeof(*old)); 951 old = ISC_LIST_HEAD(listenon); 952 } 953 } 954 955 static void 956 replace_listener_tlsctx(ns_interface_t *ifp, isc_tlsctx_t *newctx) { 957 char sabuf[ISC_SOCKADDR_FORMATSIZE]; 958 959 isc_sockaddr_format(&ifp->addr, sabuf, sizeof(sabuf)); 960 isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_INFO, 961 "updating TLS context on %s", sabuf); 962 if (ifp->tlslistensocket != NULL) { 963 isc_nmsocket_set_tlsctx(ifp->tlslistensocket, newctx); 964 } else if (ifp->http_secure_listensocket != NULL) { 965 isc_nmsocket_set_tlsctx(ifp->http_secure_listensocket, newctx); 966 } 967 } 968 969 #ifdef HAVE_LIBNGHTTP2 970 static void 971 update_http_settings(ns_interface_t *ifp, ns_listenelt_t *le) { 972 isc_result_t result; 973 isc_nmsocket_t *listener; 974 isc_nm_http_endpoints_t *epset; 975 976 REQUIRE(le->is_http); 977 978 INSIST(ifp->http_quota != NULL); 979 isc_quota_max(ifp->http_quota, le->http_max_clients); 980 981 if (ifp->http_secure_listensocket != NULL) { 982 listener = ifp->http_secure_listensocket; 983 } else { 984 INSIST(ifp->http_listensocket != NULL); 985 listener = ifp->http_listensocket; 986 } 987 988 isc_nmsocket_set_max_streams(listener, le->max_concurrent_streams); 989 990 epset = isc_nm_http_endpoints_new(ifp->mgr->mctx); 991 992 result = load_http_endpoints(epset, ifp, le->http_endpoints, 993 le->http_endpoints_number); 994 995 if (result == ISC_R_SUCCESS) { 996 isc_nm_http_set_endpoints(listener, epset); 997 } 998 999 isc_nm_http_endpoints_detach(&epset); 1000 } 1001 #endif /* HAVE_LIBNGHTTP2 */ 1002 1003 static void 1004 update_listener_configuration(ns_interfacemgr_t *mgr, ns_interface_t *ifp, 1005 ns_listenelt_t *le) { 1006 REQUIRE(NS_INTERFACEMGR_VALID(mgr)); 1007 REQUIRE(NS_INTERFACE_VALID(ifp)); 1008 REQUIRE(le != NULL); 1009 1010 LOCK(&mgr->lock); 1011 /* 1012 * We need to update the TLS contexts 1013 * inside the TLS/HTTPS listeners during 1014 * a reconfiguration because the 1015 * certificates could have been changed. 1016 */ 1017 if (le->sslctx != NULL) { 1018 replace_listener_tlsctx(ifp, le->sslctx); 1019 } 1020 1021 #ifdef HAVE_LIBNGHTTP2 1022 /* 1023 * Let's update HTTP listener settings 1024 * on reconfiguration. 1025 */ 1026 if (le->is_http) { 1027 update_http_settings(ifp, le); 1028 } 1029 #endif /* HAVE_LIBNGHTTP2 */ 1030 1031 UNLOCK(&mgr->lock); 1032 } 1033 1034 static bool 1035 same_listener_type(ns_interface_t *ifp, ns_listenelt_t *new_le) { 1036 bool same_transport_type = false; 1037 1038 /* See 'interface_setup()' above */ 1039 if (new_le->is_http) { 1040 /* HTTP/DoH */ 1041 same_transport_type = (new_le->sslctx != NULL && 1042 ifp->http_secure_listensocket != NULL) || 1043 (new_le->sslctx == NULL && 1044 ifp->http_listensocket != NULL); 1045 } else if (new_le->sslctx != NULL && ifp->tlslistensocket != NULL) { 1046 /* TLS/DoT */ 1047 same_transport_type = true; 1048 } else if (new_le->sslctx == NULL && (ifp->udplistensocket != NULL || 1049 ifp->tcplistensocket != NULL)) 1050 { 1051 /* "plain" DNS/Do53 */ 1052 same_transport_type = true; 1053 } 1054 1055 /* 1056 * Check if transport type of the listener has not changed. That 1057 * implies that PROXY type has not been changed as well. 1058 */ 1059 return same_transport_type && new_le->proxy == ifp->proxy_type; 1060 } 1061 1062 static bool 1063 interface_update_or_shutdown(ns_interfacemgr_t *mgr, ns_interface_t *ifp, 1064 ns_listenelt_t *le, const bool config) { 1065 if (LISTENING(ifp) && config && !same_listener_type(ifp, le)) { 1066 /* 1067 * DNS listener type has been changed on re-configuration. We 1068 * will need to recreate the listener anew. 1069 */ 1070 log_interface_shutdown(ifp); 1071 ns_interface_shutdown(ifp); 1072 } else { 1073 LOCK(&mgr->lock); 1074 ifp->generation = mgr->generation; 1075 UNLOCK(&mgr->lock); 1076 if (LISTENING(ifp)) { 1077 if (config) { 1078 update_listener_configuration(mgr, ifp, le); 1079 } 1080 return true; 1081 } 1082 } 1083 return false; 1084 } 1085 1086 static isc_result_t 1087 do_scan(ns_interfacemgr_t *mgr, bool verbose, bool config) { 1088 isc_interfaceiter_t *iter = NULL; 1089 bool scan_ipv4 = false; 1090 bool scan_ipv6 = false; 1091 bool ipv6only = true; 1092 bool ipv6pktinfo = true; 1093 isc_result_t result; 1094 isc_netaddr_t zero_address, zero_address6; 1095 ns_listenelt_t *le = NULL; 1096 isc_sockaddr_t listen_addr; 1097 ns_interface_t *ifp = NULL; 1098 bool log_explicit = false; 1099 bool dolistenon; 1100 char sabuf[ISC_SOCKADDR_FORMATSIZE]; 1101 bool tried_listening; 1102 bool all_addresses_in_use; 1103 dns_acl_t *localhost = NULL; 1104 dns_acl_t *localnets = NULL; 1105 1106 if (isc_net_probeipv6() == ISC_R_SUCCESS) { 1107 scan_ipv6 = true; 1108 } else if ((mgr->sctx->options & NS_SERVER_DISABLE6) == 0) { 1109 isc_log_write(IFMGR_COMMON_LOGARGS, 1110 verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1), 1111 "no IPv6 interfaces found"); 1112 } 1113 1114 if (isc_net_probeipv4() == ISC_R_SUCCESS) { 1115 scan_ipv4 = true; 1116 } else if ((mgr->sctx->options & NS_SERVER_DISABLE4) == 0) { 1117 isc_log_write(IFMGR_COMMON_LOGARGS, 1118 verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1), 1119 "no IPv4 interfaces found"); 1120 } 1121 1122 /* 1123 * A special, but typical case; listen-on-v6 { any; }. 1124 * When we can make the socket IPv6-only, open a single wildcard 1125 * socket for IPv6 communication. Otherwise, make separate 1126 * socket for each IPv6 address in order to avoid accepting IPv4 1127 * packets as the form of mapped addresses unintentionally 1128 * unless explicitly allowed. 1129 */ 1130 if (scan_ipv6 && isc_net_probe_ipv6only() != ISC_R_SUCCESS) { 1131 ipv6only = false; 1132 log_explicit = true; 1133 } 1134 if (scan_ipv6 && isc_net_probe_ipv6pktinfo() != ISC_R_SUCCESS) { 1135 ipv6pktinfo = false; 1136 log_explicit = true; 1137 } 1138 if (scan_ipv6 && ipv6only && ipv6pktinfo) { 1139 for (le = ISC_LIST_HEAD(mgr->listenon6->elts); le != NULL; 1140 le = ISC_LIST_NEXT(le, link)) 1141 { 1142 struct in6_addr in6a; 1143 1144 if (!listenon_is_ip6_any(le)) { 1145 continue; 1146 } 1147 1148 in6a = in6addr_any; 1149 isc_sockaddr_fromin6(&listen_addr, &in6a, le->port); 1150 1151 ifp = find_matching_interface(mgr, &listen_addr); 1152 if (ifp != NULL) { 1153 bool cont = interface_update_or_shutdown( 1154 mgr, ifp, le, config); 1155 if (cont) { 1156 continue; 1157 } 1158 } 1159 1160 isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_INFO, 1161 "listening on IPv6 " 1162 "interfaces, port %u", 1163 le->port); 1164 result = interface_setup(mgr, &listen_addr, "<any>", 1165 &ifp, le, NULL); 1166 if (result == ISC_R_SUCCESS) { 1167 ifp->flags |= NS_INTERFACEFLAG_ANYADDR; 1168 } else { 1169 isc_log_write(IFMGR_COMMON_LOGARGS, 1170 ISC_LOG_ERROR, 1171 "listening on all IPv6 " 1172 "interfaces failed"); 1173 } 1174 /* Continue. */ 1175 } 1176 } 1177 1178 isc_netaddr_any(&zero_address); 1179 isc_netaddr_any6(&zero_address6); 1180 1181 result = isc_interfaceiter_create(mgr->mctx, &iter); 1182 if (result != ISC_R_SUCCESS) { 1183 return result; 1184 } 1185 1186 dns_acl_create(mgr->mctx, 0, &localhost); 1187 dns_acl_create(mgr->mctx, 0, &localnets); 1188 1189 clearlistenon(mgr); 1190 1191 tried_listening = false; 1192 all_addresses_in_use = true; 1193 for (result = isc_interfaceiter_first(iter); result == ISC_R_SUCCESS; 1194 result = isc_interfaceiter_next(iter)) 1195 { 1196 isc_interface_t interface; 1197 ns_listenlist_t *ll = NULL; 1198 unsigned int family; 1199 1200 result = isc_interfaceiter_current(iter, &interface); 1201 if (result != ISC_R_SUCCESS) { 1202 break; 1203 } 1204 1205 family = interface.address.family; 1206 if (family != AF_INET && family != AF_INET6) { 1207 continue; 1208 } 1209 if (!scan_ipv4 && family == AF_INET) { 1210 continue; 1211 } 1212 if (!scan_ipv6 && family == AF_INET6) { 1213 continue; 1214 } 1215 1216 /* 1217 * Test for the address being nonzero rather than testing 1218 * INTERFACE_F_UP, because on some systems the latter 1219 * follows the media state and we could end up ignoring 1220 * the interface for an entire rescan interval due to 1221 * a temporary media glitch at rescan time. 1222 */ 1223 if (family == AF_INET && 1224 isc_netaddr_equal(&interface.address, &zero_address)) 1225 { 1226 continue; 1227 } 1228 if (family == AF_INET6 && 1229 isc_netaddr_equal(&interface.address, &zero_address6)) 1230 { 1231 continue; 1232 } 1233 1234 /* 1235 * If running with -T fixedlocal, then we only 1236 * want 127.0.0.1 and ::1 in the localhost ACL. 1237 */ 1238 if (((mgr->sctx->options & NS_SERVER_FIXEDLOCAL) != 0) && 1239 !isc_netaddr_isloopback(&interface.address)) 1240 { 1241 goto listenon; 1242 } 1243 1244 result = setup_locals(&interface, localhost, localnets); 1245 if (result != ISC_R_SUCCESS) { 1246 goto ignore_interface; 1247 } 1248 1249 listenon: 1250 ll = (family == AF_INET) ? mgr->listenon4 : mgr->listenon6; 1251 dolistenon = true; 1252 for (le = ISC_LIST_HEAD(ll->elts); le != NULL; 1253 le = ISC_LIST_NEXT(le, link)) 1254 { 1255 int match; 1256 bool addr_in_use = false; 1257 bool ipv6_wildcard = false; 1258 isc_sockaddr_t listen_sockaddr; 1259 1260 isc_sockaddr_fromnetaddr(&listen_sockaddr, 1261 &interface.address, le->port); 1262 1263 /* 1264 * See if the address matches the listen-on statement; 1265 * if not, ignore the interface, but store it in 1266 * the interface table so we know we've seen it 1267 * before. 1268 */ 1269 (void)dns_acl_match(&interface.address, NULL, le->acl, 1270 mgr->aclenv, &match, NULL); 1271 if (match <= 0) { 1272 ns_interface_t *new = NULL; 1273 ns_interface_create(mgr, &listen_sockaddr, 1274 interface.name, &new); 1275 continue; 1276 } 1277 1278 if (dolistenon) { 1279 setup_listenon(mgr, &interface, le->port); 1280 dolistenon = false; 1281 } 1282 1283 /* 1284 * The case of "any" IPv6 address will require 1285 * special considerations later, so remember it. 1286 */ 1287 if (family == AF_INET6 && ipv6only && ipv6pktinfo && 1288 listenon_is_ip6_any(le)) 1289 { 1290 ipv6_wildcard = true; 1291 } 1292 1293 ifp = find_matching_interface(mgr, &listen_sockaddr); 1294 if (ifp != NULL) { 1295 bool cont = interface_update_or_shutdown( 1296 mgr, ifp, le, config); 1297 if (cont) { 1298 continue; 1299 } 1300 } 1301 1302 if (ipv6_wildcard) { 1303 continue; 1304 } 1305 1306 if (log_explicit && family == AF_INET6 && 1307 listenon_is_ip6_any(le)) 1308 { 1309 isc_log_write(IFMGR_COMMON_LOGARGS, 1310 verbose ? ISC_LOG_INFO 1311 : ISC_LOG_DEBUG(1), 1312 "IPv6 socket API is " 1313 "incomplete; explicitly " 1314 "binding to each IPv6 " 1315 "address separately"); 1316 log_explicit = false; 1317 } 1318 isc_sockaddr_format(&listen_sockaddr, sabuf, 1319 sizeof(sabuf)); 1320 isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_INFO, 1321 "listening on %s interface " 1322 "%s, %s", 1323 (family == AF_INET) ? "IPv4" : "IPv6", 1324 interface.name, sabuf); 1325 1326 result = interface_setup(mgr, &listen_sockaddr, 1327 interface.name, &ifp, le, 1328 &addr_in_use); 1329 1330 tried_listening = true; 1331 if (!addr_in_use) { 1332 all_addresses_in_use = false; 1333 } 1334 1335 if (result != ISC_R_SUCCESS) { 1336 isc_log_write( 1337 IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, 1338 "creating %s interface " 1339 "%s failed; interface ignored", 1340 (family == AF_INET) ? "IPv4" : "IPv6", 1341 interface.name); 1342 } 1343 /* Continue. */ 1344 } 1345 continue; 1346 1347 ignore_interface: 1348 isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, 1349 "ignoring %s interface %s: %s", 1350 (family == AF_INET) ? "IPv4" : "IPv6", 1351 interface.name, isc_result_totext(result)); 1352 continue; 1353 } 1354 if (result != ISC_R_NOMORE) { 1355 UNEXPECTED_ERROR("interface iteration failed: %s", 1356 isc_result_totext(result)); 1357 } else { 1358 result = ((tried_listening && all_addresses_in_use) 1359 ? ISC_R_ADDRINUSE 1360 : ISC_R_SUCCESS); 1361 } 1362 1363 dns_aclenv_set(mgr->aclenv, localhost, localnets); 1364 1365 dns_acl_detach(&localnets); 1366 dns_acl_detach(&localhost); 1367 1368 isc_interfaceiter_destroy(&iter); 1369 return result; 1370 } 1371 1372 isc_result_t 1373 ns_interfacemgr_scan(ns_interfacemgr_t *mgr, bool verbose, bool config) { 1374 isc_result_t result; 1375 bool purge = true; 1376 1377 REQUIRE(NS_INTERFACEMGR_VALID(mgr)); 1378 REQUIRE(isc_tid() == 0); 1379 1380 mgr->generation++; /* Increment the generation count. */ 1381 1382 result = do_scan(mgr, verbose, config); 1383 if ((result != ISC_R_SUCCESS) && (result != ISC_R_ADDRINUSE)) { 1384 purge = false; 1385 } 1386 1387 /* 1388 * Now go through the interface list and delete anything that 1389 * does not have the current generation number. This is 1390 * how we catch interfaces that go away or change their 1391 * addresses. 1392 */ 1393 if (purge) { 1394 purge_old_interfaces(mgr); 1395 } 1396 1397 /* 1398 * Warn if we are not listening on any interface. 1399 */ 1400 if (ISC_LIST_EMPTY(mgr->interfaces)) { 1401 isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_WARNING, 1402 "not listening on any interfaces"); 1403 } 1404 1405 return result; 1406 } 1407 1408 void 1409 ns_interfacemgr_setlistenon4(ns_interfacemgr_t *mgr, ns_listenlist_t *value) { 1410 REQUIRE(NS_INTERFACEMGR_VALID(mgr)); 1411 1412 LOCK(&mgr->lock); 1413 ns_listenlist_detach(&mgr->listenon4); 1414 ns_listenlist_attach(value, &mgr->listenon4); 1415 UNLOCK(&mgr->lock); 1416 } 1417 1418 void 1419 ns_interfacemgr_setlistenon6(ns_interfacemgr_t *mgr, ns_listenlist_t *value) { 1420 REQUIRE(NS_INTERFACEMGR_VALID(mgr)); 1421 1422 LOCK(&mgr->lock); 1423 ns_listenlist_detach(&mgr->listenon6); 1424 ns_listenlist_attach(value, &mgr->listenon6); 1425 UNLOCK(&mgr->lock); 1426 } 1427 1428 void 1429 ns_interfacemgr_dumprecursing(FILE *f, ns_interfacemgr_t *mgr) { 1430 REQUIRE(NS_INTERFACEMGR_VALID(mgr)); 1431 1432 LOCK(&mgr->lock); 1433 for (size_t i = 0; i < mgr->ncpus; i++) { 1434 ns_client_dumprecursing(f, mgr->clientmgrs[i]); 1435 } 1436 UNLOCK(&mgr->lock); 1437 } 1438 1439 bool 1440 ns_interfacemgr_listeningon(ns_interfacemgr_t *mgr, 1441 const isc_sockaddr_t *addr) { 1442 isc_sockaddr_t *old; 1443 bool result = false; 1444 1445 REQUIRE(NS_INTERFACEMGR_VALID(mgr)); 1446 /* 1447 * If the manager is shutting down it's safer to 1448 * return true. 1449 */ 1450 if (atomic_load(&mgr->shuttingdown)) { 1451 return true; 1452 } 1453 LOCK(&mgr->lock); 1454 for (old = ISC_LIST_HEAD(mgr->listenon); old != NULL; 1455 old = ISC_LIST_NEXT(old, link)) 1456 { 1457 if (isc_sockaddr_equal(old, addr)) { 1458 result = true; 1459 break; 1460 } 1461 } 1462 UNLOCK(&mgr->lock); 1463 1464 return result; 1465 } 1466 1467 ns_server_t * 1468 ns_interfacemgr_getserver(ns_interfacemgr_t *mgr) { 1469 REQUIRE(NS_INTERFACEMGR_VALID(mgr)); 1470 1471 return mgr->sctx; 1472 } 1473 1474 ns_clientmgr_t * 1475 ns_interfacemgr_getclientmgr(ns_interfacemgr_t *mgr) { 1476 int tid = isc_tid(); 1477 1478 REQUIRE(NS_INTERFACEMGR_VALID(mgr)); 1479 REQUIRE(tid >= 0); 1480 REQUIRE((uint32_t)tid < mgr->ncpus); 1481 1482 return mgr->clientmgrs[tid]; 1483 } 1484 1485 bool 1486 ns_interfacemgr_dynamic_updates_are_reliable(void) { 1487 #if defined(LINUX_NETLINK_AVAILABLE) 1488 /* 1489 * Let's disable periodic interface rescans on Linux, as there a 1490 * reliable kernel-based mechanism for tracking interface state 1491 * changes is available. 1492 */ 1493 return true; 1494 #else 1495 return false; 1496 #endif /* LINUX_NETLINK_AVAILABLE */ 1497 } 1498