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