1 /* $NetBSD: interfacemgr.h,v 1.12 2025/01/26 16:25:46 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 #pragma once 17 18 /***** 19 ***** Module Info 20 *****/ 21 22 /*! \file 23 * \brief 24 * The interface manager monitors the operating system's list 25 * of network interfaces, creating and destroying listeners 26 * as needed. 27 * 28 * Reliability: 29 *\li No impact expected. 30 * 31 * Resources: 32 * 33 * Security: 34 * \li The server will only be able to bind to the DNS port on 35 * newly discovered interfaces if it is running as root. 36 * 37 * Standards: 38 *\li The API for scanning varies greatly among operating systems. 39 * This module attempts to hide the differences. 40 */ 41 42 /*** 43 *** Imports 44 ***/ 45 46 #include <stdbool.h> 47 48 #include <isc/loop.h> 49 #include <isc/magic.h> 50 #include <isc/mem.h> 51 #include <isc/netmgr.h> 52 #include <isc/refcount.h> 53 #include <isc/result.h> 54 #include <isc/sockaddr.h> 55 56 #include <dns/geoip.h> 57 58 #include <ns/listenlist.h> 59 #include <ns/types.h> 60 61 /*** 62 *** Types 63 ***/ 64 65 #define IFACE_MAGIC ISC_MAGIC('I', ':', '-', ')') 66 #define NS_INTERFACE_VALID(t) ISC_MAGIC_VALID(t, IFACE_MAGIC) 67 68 #define NS_INTERFACEFLAG_ANYADDR 0x01U /*%< bound to "any" address */ 69 #define NS_INTERFACEFLAG_LISTENING 0x02U /*%< listening */ 70 /*% The nameserver interface structure */ 71 struct ns_interface { 72 unsigned int magic; /*%< Magic number. */ 73 ns_interfacemgr_t *mgr; /*%< Interface manager. */ 74 isc_mutex_t lock; 75 unsigned int generation; /*%< Generation number. */ 76 isc_sockaddr_t addr; /*%< Address and port. */ 77 unsigned int flags; /*%< Interface flags */ 78 char name[32]; /*%< Null terminated. */ 79 isc_nmsocket_t *udplistensocket; 80 isc_nmsocket_t *tcplistensocket; 81 isc_nmsocket_t *tlslistensocket; 82 isc_nmsocket_t *http_listensocket; 83 isc_nmsocket_t *http_secure_listensocket; 84 isc_quota_t *http_quota; 85 isc_refcount_t ntcpaccepting; /*%< Number of clients 86 * ready to accept new 87 * TCP connections on this 88 * interface */ 89 isc_refcount_t ntcpactive; /*%< Number of clients 90 * servicing TCP queries 91 * (whether accepting or 92 * connected) */ 93 ns_clientmgr_t *clientmgr; /*%< Client manager. */ 94 isc_nm_proxy_type_t proxy_type; 95 ISC_LINK(ns_interface_t) link; 96 }; 97 98 /*** 99 *** Functions 100 ***/ 101 102 isc_result_t 103 ns_interfacemgr_create(isc_mem_t *mctx, ns_server_t *sctx, 104 isc_loopmgr_t *loopmgr, isc_nm_t *nm, 105 dns_dispatchmgr_t *dispatchmgr, 106 dns_geoip_databases_t *geoip, ns_interfacemgr_t **mgrp); 107 /*%< 108 * Create a new interface manager. 109 * 110 * Initially, the new manager will not listen on any interfaces. 111 * Call ns_interfacemgr_setlistenon() and/or ns_interfacemgr_setlistenon6() 112 * to set nonempty listen-on lists. 113 */ 114 115 ISC_REFCOUNT_DECL(ns_interfacemgr); 116 117 void 118 ns_interfacemgr_shutdown(ns_interfacemgr_t *mgr); 119 120 void 121 ns_interfacemgr_routeconnect(ns_interfacemgr_t *mgr); 122 /*% 123 * Connect to the route socket. 124 * 125 * NOTE: This function is idempotent. Calling it on an ns_interfacemgr_t object 126 * with route socket already connected will do nothing. 127 */ 128 129 void 130 ns_interfacemgr_routedisconnect(ns_interfacemgr_t *mgr); 131 /*% 132 * Disconnect the route socket. 133 * 134 * NOTE: This function is idempotent. Calling it on an ns_interfacemgr_t object 135 * that has no routing socket will do nothing. 136 */ 137 138 void 139 ns_interfacemgr_setbacklog(ns_interfacemgr_t *mgr, int backlog); 140 /*%< 141 * Set the size of the listen() backlog queue. 142 */ 143 144 isc_result_t 145 ns_interfacemgr_scan(ns_interfacemgr_t *mgr, bool verbose, bool config); 146 /*%< 147 * Scan the operatings system's list of network interfaces 148 * and create listeners when new interfaces are discovered. 149 * Shut down the sockets for interfaces that go away. 150 * 151 * When 'config' is true, also shut down and recreate any existing TLS and HTTPS 152 * interfaces in order to use their new configuration. 153 * 154 * This should be called once on server startup and then 155 * periodically according to the 'interface-interval' option 156 * in named.conf. 157 */ 158 159 void 160 ns_interfacemgr_setlistenon4(ns_interfacemgr_t *mgr, ns_listenlist_t *value); 161 /*%< 162 * Set the IPv4 "listen-on" list of 'mgr' to 'value'. 163 * The previous IPv4 listen-on list is freed. 164 */ 165 166 void 167 ns_interfacemgr_setlistenon6(ns_interfacemgr_t *mgr, ns_listenlist_t *value); 168 /*%< 169 * Set the IPv6 "listen-on" list of 'mgr' to 'value'. 170 * The previous IPv6 listen-on list is freed. 171 */ 172 173 dns_aclenv_t * 174 ns_interfacemgr_getaclenv(ns_interfacemgr_t *mgr); 175 176 void 177 ns_interface_shutdown(ns_interface_t *ifp); 178 /*%< 179 * Stop listening for queries on interface 'ifp'. 180 * May safely be called multiple times. 181 */ 182 183 void 184 ns_interfacemgr_dumprecursing(FILE *f, ns_interfacemgr_t *mgr); 185 186 bool 187 ns_interfacemgr_listeningon(ns_interfacemgr_t *mgr, const isc_sockaddr_t *addr); 188 189 ns_server_t * 190 ns_interfacemgr_getserver(ns_interfacemgr_t *mgr); 191 /*%< 192 * Returns the ns_server object associated with the interface manager. 193 */ 194 195 ns_clientmgr_t * 196 ns_interfacemgr_getclientmgr(ns_interfacemgr_t *mgr); 197 /*%< 198 * 199 * Returns the client manager for the current worker thread. 200 * (This cannot be run from outside a network manager thread.) 201 */ 202 203 bool 204 ns_interfacemgr_dynamic_updates_are_reliable(void); 205 /*%< 206 * Returns 'true' if periodic interface re-scans timer should be 207 * disabled. That is the case on the platforms where kernel-based 208 * mechanisms for tracking networking interface states is reliable enough. 209 */ 210 211 void 212 ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, 213 const char *name, ns_interface_t **ifpret); 214 /*%< 215 * Create an interface 'name' associated with address 'addr'. If 216 * 'name' is NULL then it is set to "default". 217 */ 218