xref: /netbsd-src/external/mpl/bind/dist/lib/isc/netmgr/netmgr-int.h (revision 32d1c65c71fbdb65a012e8392a62a757dd6853e9)
1 /*	$NetBSD: netmgr-int.h,v 1.12 2024/09/22 00:14:09 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 #include <unistd.h>
19 #include <uv.h>
20 
21 #include <openssl/err.h>
22 #include <openssl/ssl.h>
23 
24 #include <isc/astack.h>
25 #include <isc/atomic.h>
26 #include <isc/barrier.h>
27 #include <isc/buffer.h>
28 #include <isc/condition.h>
29 #include <isc/magic.h>
30 #include <isc/mem.h>
31 #include <isc/netmgr.h>
32 #include <isc/quota.h>
33 #include <isc/random.h>
34 #include <isc/refcount.h>
35 #include <isc/region.h>
36 #include <isc/result.h>
37 #include <isc/sockaddr.h>
38 #include <isc/stats.h>
39 #include <isc/thread.h>
40 #include <isc/tls.h>
41 #include <isc/util.h>
42 
43 #include "uv-compat.h"
44 
45 #define ISC_NETMGR_TID_UNKNOWN -1
46 
47 /* Must be different from ISC_NETMGR_TID_UNKNOWN */
48 #define ISC_NETMGR_NON_INTERLOCKED -2
49 
50 /*
51  * Receive buffers
52  */
53 #if HAVE_DECL_UV_UDP_MMSG_CHUNK
54 /*
55  * The value 20 here is UV__MMSG_MAXWIDTH taken from the current libuv source,
56  * libuv will not receive more that 20 datagrams in a single recvmmsg call.
57  */
58 #define ISC_NETMGR_UDP_RECVBUF_SIZE (20 * UINT16_MAX)
59 #else
60 /*
61  * A single DNS message size
62  */
63 #define ISC_NETMGR_UDP_RECVBUF_SIZE UINT16_MAX
64 #endif
65 
66 /*
67  * The TCP send and receive buffers can fit one maximum sized DNS message plus
68  * its size, the receive buffer here affects TCP, DoT and DoH.
69  */
70 #define ISC_NETMGR_TCP_SENDBUF_SIZE (sizeof(uint16_t) + UINT16_MAX)
71 #define ISC_NETMGR_TCP_RECVBUF_SIZE (sizeof(uint16_t) + UINT16_MAX)
72 
73 /* Pick the larger buffer */
74 #define ISC_NETMGR_RECVBUF_SIZE                                     \
75 	(ISC_NETMGR_UDP_RECVBUF_SIZE >= ISC_NETMGR_TCP_RECVBUF_SIZE \
76 		 ? ISC_NETMGR_UDP_RECVBUF_SIZE                      \
77 		 : ISC_NETMGR_TCP_RECVBUF_SIZE)
78 
79 /*
80  * Send buffer
81  */
82 #define ISC_NETMGR_SENDBUF_SIZE (sizeof(uint16_t) + UINT16_MAX)
83 
84 /*
85  * Make sure our RECVBUF size is large enough
86  */
87 
88 STATIC_ASSERT(ISC_NETMGR_UDP_RECVBUF_SIZE <= ISC_NETMGR_RECVBUF_SIZE,
89 	      "UDP receive buffer size must be smaller or equal than worker "
90 	      "receive buffer size");
91 
92 STATIC_ASSERT(ISC_NETMGR_TCP_RECVBUF_SIZE <= ISC_NETMGR_RECVBUF_SIZE,
93 	      "TCP receive buffer size must be smaller or equal than worker "
94 	      "receive buffer size");
95 
96 /*%
97  * Regular TCP buffer size.
98  */
99 #define NM_REG_BUF 4096
100 
101 /*%
102  * Larger buffer for when the regular one isn't enough; this will
103  * hold two full DNS packets with lengths.  netmgr receives 64k at
104  * most in TCPDNS or TLSDNS connections, so there's no risk of overrun
105  * when using a buffer this size.
106  */
107 #define NM_BIG_BUF ISC_NETMGR_TCP_RECVBUF_SIZE * 2
108 
109 /*%
110  * Maximum segment size (MSS) of TCP socket on which the server responds to
111  * queries. Value lower than common MSS on Ethernet (1220, that is 1280 (IPv6
112  * minimum link MTU) - 40 (IPv6 fixed header) - 20 (TCP fixed header)) will
113  * address path MTU problem.
114  */
115 #define NM_MAXSEG (1280 - 20 - 40)
116 
117 /*
118  * Define NETMGR_TRACE to activate tracing of handles and sockets.
119  * This will impair performance but enables us to quickly determine,
120  * if netmgr resources haven't been cleaned up on shutdown, which ones
121  * are still in use.
122  */
123 #ifdef NETMGR_TRACE
124 #define TRACE_SIZE 8
125 
126 void
127 isc__nm_dump_active(isc_nm_t *nm);
128 
129 #if defined(__linux__)
130 #include <syscall.h>
131 #define gettid() (uint32_t)syscall(SYS_gettid)
132 #else
133 #define gettid() (uint32_t)pthread_self()
134 #endif
135 
136 #ifdef NETMGR_TRACE_VERBOSE
137 #define NETMGR_TRACE_LOG(format, ...)                                \
138 	fprintf(stderr, "%" PRIu32 ":%d:%s:%u:%s:" format, gettid(), \
139 		isc_nm_tid(), file, line, func, __VA_ARGS__)
140 #else
141 #define NETMGR_TRACE_LOG(format, ...) \
142 	(void)file;                   \
143 	(void)line;                   \
144 	(void)func;
145 #endif
146 
147 #define FLARG_PASS , file, line, func
148 #define FLARG                                              \
149 	, const char *file __attribute__((unused)),        \
150 		unsigned int line __attribute__((unused)), \
151 		const char *func __attribute__((unused))
152 #define FLARG_IEVENT(ievent)              \
153 	const char *file = ievent->file;  \
154 	unsigned int line = ievent->line; \
155 	const char *func = ievent->func;
156 #define FLARG_IEVENT_PASS(ievent) \
157 	ievent->file = file;      \
158 	ievent->line = line;      \
159 	ievent->func = func;
160 #define isc__nm_uvreq_get(req, sock) \
161 	isc___nm_uvreq_get(req, sock, __FILE__, __LINE__, __func__)
162 #define isc__nm_uvreq_put(req, sock) \
163 	isc___nm_uvreq_put(req, sock, __FILE__, __LINE__, __func__)
164 #define isc__nmsocket_init(sock, mgr, type, iface)                      \
165 	isc___nmsocket_init(sock, mgr, type, iface, __FILE__, __LINE__, \
166 			    __func__)
167 #define isc__nmsocket_put(sockp) \
168 	isc___nmsocket_put(sockp, __FILE__, __LINE__, __func__)
169 #define isc__nmsocket_attach(sock, target) \
170 	isc___nmsocket_attach(sock, target, __FILE__, __LINE__, __func__)
171 #define isc__nmsocket_detach(socketp) \
172 	isc___nmsocket_detach(socketp, __FILE__, __LINE__, __func__)
173 #define isc__nmsocket_close(socketp) \
174 	isc___nmsocket_close(socketp, __FILE__, __LINE__, __func__)
175 #define isc__nmhandle_get(sock, peer, local) \
176 	isc___nmhandle_get(sock, peer, local, __FILE__, __LINE__, __func__)
177 #define isc__nmsocket_prep_destroy(sock) \
178 	isc___nmsocket_prep_destroy(sock, __FILE__, __LINE__, __func__)
179 #else
180 #define NETMGR_TRACE_LOG(format, ...)
181 
182 #define FLARG_PASS
183 #define FLARG
184 #define FLARG_IEVENT(ievent)
185 #define FLARG_IEVENT_PASS(ievent)
186 #define isc__nm_uvreq_get(req, sock) isc___nm_uvreq_get(req, sock)
187 #define isc__nm_uvreq_put(req, sock) isc___nm_uvreq_put(req, sock)
188 #define isc__nmsocket_init(sock, mgr, type, iface) \
189 	isc___nmsocket_init(sock, mgr, type, iface)
190 #define isc__nmsocket_put(sockp)	   isc___nmsocket_put(sockp)
191 #define isc__nmsocket_attach(sock, target) isc___nmsocket_attach(sock, target)
192 #define isc__nmsocket_detach(socketp)	   isc___nmsocket_detach(socketp)
193 #define isc__nmsocket_close(socketp)	   isc___nmsocket_close(socketp)
194 #define isc__nmhandle_get(sock, peer, local) \
195 	isc___nmhandle_get(sock, peer, local)
196 #define isc__nmsocket_prep_destroy(sock) isc___nmsocket_prep_destroy(sock)
197 #endif
198 
199 /*
200  * Queue types in the order of processing priority.
201  */
202 typedef enum {
203 	NETIEVENT_PRIORITY = 0,
204 	NETIEVENT_PRIVILEGED = 1,
205 	NETIEVENT_TASK = 2,
206 	NETIEVENT_NORMAL = 3,
207 	NETIEVENT_MAX = 4,
208 } netievent_type_t;
209 
210 typedef struct isc__nm_uvreq isc__nm_uvreq_t;
211 typedef struct isc__netievent isc__netievent_t;
212 
213 typedef ISC_LIST(isc__netievent_t) isc__netievent_list_t;
214 
215 typedef struct ievent {
216 	isc_mutex_t lock;
217 	isc_condition_t cond;
218 	isc__netievent_list_t list;
219 } ievent_t;
220 
221 /*
222  * Single network event loop worker.
223  */
224 typedef struct isc__networker {
225 	isc_nm_t *mgr;
226 	int id;		  /* thread id */
227 	uv_loop_t loop;	  /* libuv loop structure */
228 	uv_async_t async; /* async channel to send
229 			   * data to this networker */
230 	bool paused;
231 	bool finished;
232 	isc_thread_t thread;
233 	ievent_t ievents[NETIEVENT_MAX];
234 
235 	isc_refcount_t references;
236 	atomic_int_fast64_t pktcount;
237 	char *recvbuf;
238 	char *sendbuf;
239 	bool recvbuf_inuse;
240 } isc__networker_t;
241 
242 /*
243  * A general handle for a connection bound to a networker.  For UDP
244  * connections we have peer address here, so both TCP and UDP can be
245  * handled with a simple send-like function
246  */
247 #define NMHANDLE_MAGIC ISC_MAGIC('N', 'M', 'H', 'D')
248 #define VALID_NMHANDLE(t)                      \
249 	(ISC_MAGIC_VALID(t, NMHANDLE_MAGIC) && \
250 	 atomic_load(&(t)->references) > 0)
251 
252 typedef void (*isc__nm_closecb)(isc_nmhandle_t *);
253 typedef struct isc_nm_http_session isc_nm_http_session_t;
254 
255 struct isc_nmhandle {
256 	int magic;
257 	isc_refcount_t references;
258 
259 	/*
260 	 * The socket is not 'attached' in the traditional
261 	 * reference-counting sense. Instead, we keep all handles in an
262 	 * array in the socket object.  This way, we don't have circular
263 	 * dependencies and we can close all handles when we're destroying
264 	 * the socket.
265 	 */
266 	isc_nmsocket_t *sock;
267 
268 	isc_nm_http_session_t *httpsession;
269 
270 	isc_sockaddr_t peer;
271 	isc_sockaddr_t local;
272 	isc_nm_opaquecb_t doreset; /* reset extra callback, external */
273 	isc_nm_opaquecb_t dofree;  /* free extra callback, external */
274 #ifdef NETMGR_TRACE
275 	void *backtrace[TRACE_SIZE];
276 	int backtrace_size;
277 	LINK(isc_nmhandle_t) active_link;
278 #endif
279 	void *opaque;
280 	max_align_t extra[];
281 };
282 
283 typedef enum isc__netievent_type {
284 	netievent_udpconnect,
285 	netievent_udpclose,
286 	netievent_udpsend,
287 	netievent_udpread,
288 	netievent_udpcancel,
289 
290 	netievent_routeconnect,
291 
292 	netievent_tcpconnect,
293 	netievent_tcpclose,
294 	netievent_tcpsend,
295 	netievent_tcpstartread,
296 	netievent_tcppauseread,
297 	netievent_tcpaccept,
298 	netievent_tcpcancel,
299 
300 	netievent_tcpdnsaccept,
301 	netievent_tcpdnsconnect,
302 	netievent_tcpdnsclose,
303 	netievent_tcpdnssend,
304 	netievent_tcpdnsread,
305 	netievent_tcpdnscancel,
306 
307 	netievent_tlsclose,
308 	netievent_tlssend,
309 	netievent_tlsstartread,
310 	netievent_tlsconnect,
311 	netievent_tlsdobio,
312 	netievent_tlscancel,
313 
314 	netievent_tlsdnsaccept,
315 	netievent_tlsdnsconnect,
316 	netievent_tlsdnsclose,
317 	netievent_tlsdnssend,
318 	netievent_tlsdnsread,
319 	netievent_tlsdnscancel,
320 	netievent_tlsdnscycle,
321 	netievent_tlsdnsshutdown,
322 
323 	netievent_httpclose,
324 	netievent_httpsend,
325 	netievent_httpendpoints,
326 
327 	netievent_shutdown,
328 	netievent_stop,
329 	netievent_pause,
330 
331 	netievent_connectcb,
332 	netievent_readcb,
333 	netievent_sendcb,
334 
335 	netievent_detach,
336 	netievent_close,
337 
338 	netievent_task,
339 	netievent_privilegedtask,
340 
341 	netievent_settlsctx,
342 
343 	/*
344 	 * event type values higher than this will be treated
345 	 * as high-priority events, which can be processed
346 	 * while the netmgr is pausing or paused.
347 	 */
348 	netievent_prio = 0xff,
349 
350 	netievent_udplisten,
351 	netievent_udpstop,
352 	netievent_tcplisten,
353 	netievent_tcpstop,
354 	netievent_tcpdnslisten,
355 	netievent_tcpdnsstop,
356 	netievent_tlsdnslisten,
357 	netievent_tlsdnsstop,
358 	netievent_sockstop, /* for multilayer sockets */
359 
360 	netievent_resume,
361 } isc__netievent_type;
362 
363 typedef union {
364 	isc_nm_recv_cb_t recv;
365 	isc_nm_cb_t send;
366 	isc_nm_cb_t connect;
367 	isc_nm_accept_cb_t accept;
368 } isc__nm_cb_t;
369 
370 /*
371  * Wrapper around uv_req_t with 'our' fields in it.  req->data should
372  * always point to its parent.  Note that we always allocate more than
373  * sizeof(struct) because we make room for different req types;
374  */
375 #define UVREQ_MAGIC    ISC_MAGIC('N', 'M', 'U', 'R')
376 #define VALID_UVREQ(t) ISC_MAGIC_VALID(t, UVREQ_MAGIC)
377 
378 struct isc__nm_uvreq {
379 	int magic;
380 	isc_nmsocket_t *sock;
381 	isc_nmhandle_t *handle;
382 	char tcplen[2]; /* The TCP DNS message length */
383 	uv_buf_t uvbuf; /* translated isc_region_t, to be
384 			 * sent or received */
385 	isc_region_t userbuf;
386 	isc_sockaddr_t local;  /* local address */
387 	isc_sockaddr_t peer;   /* peer address */
388 	isc__nm_cb_t cb;       /* callback */
389 	void *cbarg;	       /* callback argument */
390 	isc_nm_timer_t *timer; /* TCP write timer */
391 	int connect_tries;     /* connect retries */
392 
393 	union {
394 		uv_handle_t handle;
395 		uv_req_t req;
396 		uv_getaddrinfo_t getaddrinfo;
397 		uv_getnameinfo_t getnameinfo;
398 		uv_shutdown_t shutdown;
399 		uv_write_t write;
400 		uv_connect_t connect;
401 		uv_udp_send_t udp_send;
402 		uv_fs_t fs;
403 		uv_work_t work;
404 	} uv_req;
405 	ISC_LINK(isc__nm_uvreq_t) link;
406 };
407 
408 void *
409 isc__nm_get_netievent(isc_nm_t *mgr, isc__netievent_type type);
410 /*%<
411  * Allocate an ievent and set the type.
412  */
413 void
414 isc__nm_put_netievent(isc_nm_t *mgr, void *ievent);
415 
416 /*
417  * The macros here are used to simulate the "inheritance" in C, there's the base
418  * netievent structure that contains just its own type and socket, and there are
419  * extended netievent types that also have handles or requests or other data.
420  *
421  * The macros here ensure that:
422  *
423  *   1. every netievent type has matching definition, declaration and
424  *      implementation
425  *
426  *   2. we handle all the netievent types of same subclass the same, e.g. if the
427  *      extended netievent contains handle, we always attach to the handle in
428  *      the ctor and detach from the handle in dtor.
429  *
430  * There are three macros here for each netievent subclass:
431  *
432  *   1. NETIEVENT_*_TYPE(type) creates the typedef for each type; used below in
433  *   this header
434  *
435  *   2. NETIEVENT_*_DECL(type) generates the declaration of the get and put
436  *      functions (isc__nm_get_netievent_* and isc__nm_put_netievent_*); used
437  *      below in this header
438  *
439  *   3. NETIEVENT_*_DEF(type) generates the definition of the functions; used
440  *   either in netmgr.c or matching protocol file (e.g. udp.c, tcp.c, etc.)
441  */
442 
443 #define NETIEVENT__SOCKET                \
444 	isc__netievent_type type;        \
445 	ISC_LINK(isc__netievent_t) link; \
446 	isc_nmsocket_t *sock;            \
447 	const char *file;                \
448 	unsigned int line;               \
449 	const char *func;
450 
451 typedef struct isc__netievent__socket {
452 	NETIEVENT__SOCKET;
453 } isc__netievent__socket_t;
454 
455 #define NETIEVENT_SOCKET_TYPE(type) \
456 	typedef isc__netievent__socket_t isc__netievent_##type##_t
457 
458 #define NETIEVENT_SOCKET_DECL(type)                              \
459 	isc__netievent_##type##_t *isc__nm_get_netievent_##type( \
460 		isc_nm_t *nm, isc_nmsocket_t *sock);             \
461 	void isc__nm_put_netievent_##type(isc_nm_t *nm,          \
462 					  isc__netievent_##type##_t *ievent)
463 
464 #define NETIEVENT_SOCKET_DEF(type)                                             \
465 	isc__netievent_##type##_t *isc__nm_get_netievent_##type(               \
466 		isc_nm_t *nm, isc_nmsocket_t *sock) {                          \
467 		isc__netievent_##type##_t *ievent =                            \
468 			isc__nm_get_netievent(nm, netievent_##type);           \
469 		isc__nmsocket_attach(sock, &ievent->sock);                     \
470                                                                                \
471 		return (ievent);                                               \
472 	}                                                                      \
473                                                                                \
474 	void isc__nm_put_netievent_##type(isc_nm_t *nm,                        \
475 					  isc__netievent_##type##_t *ievent) { \
476 		isc__nmsocket_detach(&ievent->sock);                           \
477 		isc__nm_put_netievent(nm, ievent);                             \
478 	}
479 
480 typedef struct isc__netievent__socket_req {
481 	NETIEVENT__SOCKET;
482 	isc__nm_uvreq_t *req;
483 } isc__netievent__socket_req_t;
484 
485 #define NETIEVENT_SOCKET_REQ_TYPE(type) \
486 	typedef isc__netievent__socket_req_t isc__netievent_##type##_t
487 
488 #define NETIEVENT_SOCKET_REQ_DECL(type)                                    \
489 	isc__netievent_##type##_t *isc__nm_get_netievent_##type(           \
490 		isc_nm_t *nm, isc_nmsocket_t *sock, isc__nm_uvreq_t *req); \
491 	void isc__nm_put_netievent_##type(isc_nm_t *nm,                    \
492 					  isc__netievent_##type##_t *ievent)
493 
494 #define NETIEVENT_SOCKET_REQ_DEF(type)                                         \
495 	isc__netievent_##type##_t *isc__nm_get_netievent_##type(               \
496 		isc_nm_t *nm, isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {    \
497 		isc__netievent_##type##_t *ievent =                            \
498 			isc__nm_get_netievent(nm, netievent_##type);           \
499 		isc__nmsocket_attach(sock, &ievent->sock);                     \
500 		ievent->req = req;                                             \
501                                                                                \
502 		return (ievent);                                               \
503 	}                                                                      \
504                                                                                \
505 	void isc__nm_put_netievent_##type(isc_nm_t *nm,                        \
506 					  isc__netievent_##type##_t *ievent) { \
507 		isc__nmsocket_detach(&ievent->sock);                           \
508 		isc__nm_put_netievent(nm, ievent);                             \
509 	}
510 
511 typedef struct isc__netievent__socket_req_result {
512 	NETIEVENT__SOCKET;
513 	isc__nm_uvreq_t *req;
514 	isc_result_t result;
515 } isc__netievent__socket_req_result_t;
516 
517 #define NETIEVENT_SOCKET_REQ_RESULT_TYPE(type) \
518 	typedef isc__netievent__socket_req_result_t isc__netievent_##type##_t
519 
520 #define NETIEVENT_SOCKET_REQ_RESULT_DECL(type)                            \
521 	isc__netievent_##type##_t *isc__nm_get_netievent_##type(          \
522 		isc_nm_t *nm, isc_nmsocket_t *sock, isc__nm_uvreq_t *req, \
523 		isc_result_t result);                                     \
524 	void isc__nm_put_netievent_##type(isc_nm_t *nm,                   \
525 					  isc__netievent_##type##_t *ievent)
526 
527 #define NETIEVENT_SOCKET_REQ_RESULT_DEF(type)                                  \
528 	isc__netievent_##type##_t *isc__nm_get_netievent_##type(               \
529 		isc_nm_t *nm, isc_nmsocket_t *sock, isc__nm_uvreq_t *req,      \
530 		isc_result_t result) {                                         \
531 		isc__netievent_##type##_t *ievent =                            \
532 			isc__nm_get_netievent(nm, netievent_##type);           \
533 		isc__nmsocket_attach(sock, &ievent->sock);                     \
534 		ievent->req = req;                                             \
535 		ievent->result = result;                                       \
536                                                                                \
537 		return (ievent);                                               \
538 	}                                                                      \
539                                                                                \
540 	void isc__nm_put_netievent_##type(isc_nm_t *nm,                        \
541 					  isc__netievent_##type##_t *ievent) { \
542 		isc__nmsocket_detach(&ievent->sock);                           \
543 		isc__nm_put_netievent(nm, ievent);                             \
544 	}
545 
546 typedef struct isc__netievent__socket_handle {
547 	NETIEVENT__SOCKET;
548 	isc_nmhandle_t *handle;
549 } isc__netievent__socket_handle_t;
550 
551 #define NETIEVENT_SOCKET_HANDLE_TYPE(type) \
552 	typedef isc__netievent__socket_handle_t isc__netievent_##type##_t
553 
554 #define NETIEVENT_SOCKET_HANDLE_DECL(type)                                   \
555 	isc__netievent_##type##_t *isc__nm_get_netievent_##type(             \
556 		isc_nm_t *nm, isc_nmsocket_t *sock, isc_nmhandle_t *handle); \
557 	void isc__nm_put_netievent_##type(isc_nm_t *nm,                      \
558 					  isc__netievent_##type##_t *ievent)
559 
560 #define NETIEVENT_SOCKET_HANDLE_DEF(type)                                      \
561 	isc__netievent_##type##_t *isc__nm_get_netievent_##type(               \
562 		isc_nm_t *nm, isc_nmsocket_t *sock, isc_nmhandle_t *handle) {  \
563 		isc__netievent_##type##_t *ievent =                            \
564 			isc__nm_get_netievent(nm, netievent_##type);           \
565 		isc__nmsocket_attach(sock, &ievent->sock);                     \
566 		isc_nmhandle_attach(handle, &ievent->handle);                  \
567                                                                                \
568 		return (ievent);                                               \
569 	}                                                                      \
570                                                                                \
571 	void isc__nm_put_netievent_##type(isc_nm_t *nm,                        \
572 					  isc__netievent_##type##_t *ievent) { \
573 		isc__nmsocket_detach(&ievent->sock);                           \
574 		isc_nmhandle_detach(&ievent->handle);                          \
575 		isc__nm_put_netievent(nm, ievent);                             \
576 	}
577 
578 typedef struct isc__netievent__socket_quota {
579 	NETIEVENT__SOCKET;
580 	isc_quota_t *quota;
581 } isc__netievent__socket_quota_t;
582 
583 #define NETIEVENT_SOCKET_QUOTA_TYPE(type) \
584 	typedef isc__netievent__socket_quota_t isc__netievent_##type##_t
585 
586 #define NETIEVENT_SOCKET_QUOTA_DECL(type)                                \
587 	isc__netievent_##type##_t *isc__nm_get_netievent_##type(         \
588 		isc_nm_t *nm, isc_nmsocket_t *sock, isc_quota_t *quota); \
589 	void isc__nm_put_netievent_##type(isc_nm_t *nm,                  \
590 					  isc__netievent_##type##_t *ievent)
591 
592 #define NETIEVENT_SOCKET_QUOTA_DEF(type)                                       \
593 	isc__netievent_##type##_t *isc__nm_get_netievent_##type(               \
594 		isc_nm_t *nm, isc_nmsocket_t *sock, isc_quota_t *quota) {      \
595 		isc__netievent_##type##_t *ievent =                            \
596 			isc__nm_get_netievent(nm, netievent_##type);           \
597 		isc__nmsocket_attach(sock, &ievent->sock);                     \
598 		ievent->quota = quota;                                         \
599                                                                                \
600 		return (ievent);                                               \
601 	}                                                                      \
602                                                                                \
603 	void isc__nm_put_netievent_##type(isc_nm_t *nm,                        \
604 					  isc__netievent_##type##_t *ievent) { \
605 		isc__nmsocket_detach(&ievent->sock);                           \
606 		isc__nm_put_netievent(nm, ievent);                             \
607 	}
608 
609 typedef struct isc__netievent__task {
610 	isc__netievent_type type;
611 	ISC_LINK(isc__netievent_t) link;
612 	isc_task_t *task;
613 } isc__netievent__task_t;
614 
615 #define NETIEVENT_TASK_TYPE(type) \
616 	typedef isc__netievent__task_t isc__netievent_##type##_t;
617 
618 #define NETIEVENT_TASK_DECL(type)                                \
619 	isc__netievent_##type##_t *isc__nm_get_netievent_##type( \
620 		isc_nm_t *nm, isc_task_t *task);                 \
621 	void isc__nm_put_netievent_##type(isc_nm_t *nm,          \
622 					  isc__netievent_##type##_t *ievent);
623 
624 #define NETIEVENT_TASK_DEF(type)                                               \
625 	isc__netievent_##type##_t *isc__nm_get_netievent_##type(               \
626 		isc_nm_t *nm, isc_task_t *task) {                              \
627 		isc__netievent_##type##_t *ievent =                            \
628 			isc__nm_get_netievent(nm, netievent_##type);           \
629 		ievent->task = task;                                           \
630                                                                                \
631 		return (ievent);                                               \
632 	}                                                                      \
633                                                                                \
634 	void isc__nm_put_netievent_##type(isc_nm_t *nm,                        \
635 					  isc__netievent_##type##_t *ievent) { \
636 		ievent->task = NULL;                                           \
637 		isc__nm_put_netievent(nm, ievent);                             \
638 	}
639 
640 typedef struct isc__netievent_udpsend {
641 	NETIEVENT__SOCKET;
642 	isc_sockaddr_t peer;
643 	isc__nm_uvreq_t *req;
644 } isc__netievent_udpsend_t;
645 
646 typedef struct isc__netievent_tlsconnect {
647 	NETIEVENT__SOCKET;
648 	SSL_CTX *ctx;
649 	isc_sockaddr_t local; /* local address */
650 	isc_sockaddr_t peer;  /* peer address */
651 } isc__netievent_tlsconnect_t;
652 
653 typedef struct isc__netievent {
654 	isc__netievent_type type;
655 	ISC_LINK(isc__netievent_t) link;
656 } isc__netievent_t;
657 
658 #define NETIEVENT_TYPE(type) typedef isc__netievent_t isc__netievent_##type##_t
659 
660 #define NETIEVENT_DECL(type)                                                   \
661 	isc__netievent_##type##_t *isc__nm_get_netievent_##type(isc_nm_t *nm); \
662 	void isc__nm_put_netievent_##type(isc_nm_t *nm,                        \
663 					  isc__netievent_##type##_t *ievent)
664 
665 #define NETIEVENT_DEF(type)                                                    \
666 	isc__netievent_##type##_t *isc__nm_get_netievent_##type(               \
667 		isc_nm_t *nm) {                                                \
668 		isc__netievent_##type##_t *ievent =                            \
669 			isc__nm_get_netievent(nm, netievent_##type);           \
670                                                                                \
671 		return (ievent);                                               \
672 	}                                                                      \
673                                                                                \
674 	void isc__nm_put_netievent_##type(isc_nm_t *nm,                        \
675 					  isc__netievent_##type##_t *ievent) { \
676 		isc__nm_put_netievent(nm, ievent);                             \
677 	}
678 
679 typedef struct isc__netievent__tlsctx {
680 	NETIEVENT__SOCKET;
681 	isc_tlsctx_t *tlsctx;
682 } isc__netievent__tlsctx_t;
683 
684 #define NETIEVENT_SOCKET_TLSCTX_TYPE(type) \
685 	typedef isc__netievent__tlsctx_t isc__netievent_##type##_t;
686 
687 #define NETIEVENT_SOCKET_TLSCTX_DECL(type)                                 \
688 	isc__netievent_##type##_t *isc__nm_get_netievent_##type(           \
689 		isc_nm_t *nm, isc_nmsocket_t *sock, isc_tlsctx_t *tlsctx); \
690 	void isc__nm_put_netievent_##type(isc_nm_t *nm,                    \
691 					  isc__netievent_##type##_t *ievent);
692 
693 #define NETIEVENT_SOCKET_TLSCTX_DEF(type)                                      \
694 	isc__netievent_##type##_t *isc__nm_get_netievent_##type(               \
695 		isc_nm_t *nm, isc_nmsocket_t *sock, isc_tlsctx_t *tlsctx) {    \
696 		isc__netievent_##type##_t *ievent =                            \
697 			isc__nm_get_netievent(nm, netievent_##type);           \
698 		isc__nmsocket_attach(sock, &ievent->sock);                     \
699 		isc_tlsctx_attach(tlsctx, &ievent->tlsctx);                    \
700                                                                                \
701 		return (ievent);                                               \
702 	}                                                                      \
703                                                                                \
704 	void isc__nm_put_netievent_##type(isc_nm_t *nm,                        \
705 					  isc__netievent_##type##_t *ievent) { \
706 		isc_tlsctx_free(&ievent->tlsctx);                              \
707 		isc__nmsocket_detach(&ievent->sock);                           \
708 		isc__nm_put_netievent(nm, ievent);                             \
709 	}
710 
711 #ifdef HAVE_LIBNGHTTP2
712 typedef struct isc__netievent__http_eps {
713 	NETIEVENT__SOCKET;
714 	isc_nm_http_endpoints_t *endpoints;
715 } isc__netievent__http_eps_t;
716 
717 #define NETIEVENT_SOCKET_HTTP_EPS_TYPE(type) \
718 	typedef isc__netievent__http_eps_t isc__netievent_##type##_t;
719 
720 #define NETIEVENT_SOCKET_HTTP_EPS_DECL(type)                     \
721 	isc__netievent_##type##_t *isc__nm_get_netievent_##type( \
722 		isc_nm_t *nm, isc_nmsocket_t *sock,              \
723 		isc_nm_http_endpoints_t *endpoints);             \
724 	void isc__nm_put_netievent_##type(isc_nm_t *nm,          \
725 					  isc__netievent_##type##_t *ievent);
726 
727 #define NETIEVENT_SOCKET_HTTP_EPS_DEF(type)                                    \
728 	isc__netievent_##type##_t *isc__nm_get_netievent_##type(               \
729 		isc_nm_t *nm, isc_nmsocket_t *sock,                            \
730 		isc_nm_http_endpoints_t *endpoints) {                          \
731 		isc__netievent_##type##_t *ievent =                            \
732 			isc__nm_get_netievent(nm, netievent_##type);           \
733 		isc__nmsocket_attach(sock, &ievent->sock);                     \
734 		isc_nm_http_endpoints_attach(endpoints, &ievent->endpoints);   \
735                                                                                \
736 		return (ievent);                                               \
737 	}                                                                      \
738                                                                                \
739 	void isc__nm_put_netievent_##type(isc_nm_t *nm,                        \
740 					  isc__netievent_##type##_t *ievent) { \
741 		isc_nm_http_endpoints_detach(&ievent->endpoints);              \
742 		isc__nmsocket_detach(&ievent->sock);                           \
743 		isc__nm_put_netievent(nm, ievent);                             \
744 	}
745 #endif /* HAVE_LIBNGHTTP2 */
746 
747 typedef union {
748 	isc__netievent_t ni;
749 	isc__netievent__socket_t nis;
750 	isc__netievent__socket_req_t nisr;
751 	isc__netievent_udpsend_t nius;
752 	isc__netievent__socket_quota_t nisq;
753 	isc__netievent_tlsconnect_t nitc;
754 	isc__netievent__tlsctx_t nitls;
755 #ifdef HAVE_LIBNGHTTP2
756 	isc__netievent__http_eps_t nihttpeps;
757 #endif /* HAVE_LIBNGHTTP2 */
758 } isc__netievent_storage_t;
759 
760 /*
761  * Work item for a uv_work threadpool.
762  */
763 typedef struct isc__nm_work {
764 	isc_nm_t *netmgr;
765 	uv_work_t req;
766 	isc_nm_workcb_t cb;
767 	isc_nm_after_workcb_t after_cb;
768 	void *data;
769 } isc__nm_work_t;
770 
771 /*
772  * Network manager
773  */
774 #define NM_MAGIC    ISC_MAGIC('N', 'E', 'T', 'M')
775 #define VALID_NM(t) ISC_MAGIC_VALID(t, NM_MAGIC)
776 
777 struct isc_nm {
778 	int magic;
779 	isc_refcount_t references;
780 	isc_mem_t *mctx;
781 	int nworkers;
782 	int nlisteners;
783 	isc_mutex_t lock;
784 	isc_condition_t wkstatecond;
785 	isc_condition_t wkpausecond;
786 	isc__networker_t *workers;
787 
788 	isc_stats_t *stats;
789 
790 	uint_fast32_t workers_running;
791 	atomic_uint_fast32_t workers_paused;
792 	atomic_uint_fast32_t maxudp;
793 
794 	bool load_balance_sockets;
795 
796 	atomic_bool paused;
797 
798 	/*
799 	 * Active connections are being closed and new connections are
800 	 * no longer allowed.
801 	 */
802 	atomic_bool closing;
803 
804 	/*
805 	 * A worker is actively waiting for other workers, for example to
806 	 * stop listening; that means no other thread can do the same thing
807 	 * or pause, or we'll deadlock. We have to either re-enqueue our
808 	 * event or wait for the other one to finish if we want to pause.
809 	 */
810 	atomic_int interlocked;
811 
812 	/*
813 	 * Timeout values for TCP connections, corresponding to
814 	 * tcp-intiial-timeout, tcp-idle-timeout, tcp-keepalive-timeout,
815 	 * and tcp-advertised-timeout. Note that these are stored in
816 	 * milliseconds so they can be used directly with the libuv timer,
817 	 * but they are configured in tenths of seconds.
818 	 */
819 	atomic_uint_fast32_t init;
820 	atomic_uint_fast32_t idle;
821 	atomic_uint_fast32_t keepalive;
822 	atomic_uint_fast32_t advertised;
823 
824 	isc_barrier_t pausing;
825 	isc_barrier_t resuming;
826 
827 	/*
828 	 * Socket SO_RCVBUF and SO_SNDBUF values
829 	 */
830 	atomic_int_fast32_t recv_udp_buffer_size;
831 	atomic_int_fast32_t send_udp_buffer_size;
832 	atomic_int_fast32_t recv_tcp_buffer_size;
833 	atomic_int_fast32_t send_tcp_buffer_size;
834 
835 #ifdef NETMGR_TRACE
836 	ISC_LIST(isc_nmsocket_t) active_sockets;
837 #endif
838 };
839 
840 /*%
841  * A universal structure for either a single socket or a group of
842  * dup'd/SO_REUSE_PORT-using sockets listening on the same interface.
843  */
844 #define NMSOCK_MAGIC	ISC_MAGIC('N', 'M', 'S', 'K')
845 #define VALID_NMSOCK(t) ISC_MAGIC_VALID(t, NMSOCK_MAGIC)
846 
847 /*%
848  * Index into socket stat counter arrays.
849  */
850 typedef enum {
851 	STATID_OPEN = 0,
852 	STATID_OPENFAIL = 1,
853 	STATID_CLOSE = 2,
854 	STATID_BINDFAIL = 3,
855 	STATID_CONNECTFAIL = 4,
856 	STATID_CONNECT = 5,
857 	STATID_ACCEPTFAIL = 6,
858 	STATID_ACCEPT = 7,
859 	STATID_SENDFAIL = 8,
860 	STATID_RECVFAIL = 9,
861 	STATID_ACTIVE = 10,
862 	STATID_CLIENTS = 11,
863 	STATID_MAX = 12,
864 } isc__nm_statid_t;
865 
866 #if HAVE_LIBNGHTTP2
867 typedef struct isc_nmsocket_tls_send_req {
868 	isc_nmsocket_t *tlssock;
869 	isc_region_t data;
870 	isc_nm_cb_t cb;
871 	void *cbarg;
872 	isc_nmhandle_t *handle;
873 	bool finish;
874 	uint8_t smallbuf[512];
875 } isc_nmsocket_tls_send_req_t;
876 
877 typedef enum isc_http_request_type {
878 	ISC_HTTP_REQ_GET,
879 	ISC_HTTP_REQ_POST,
880 	ISC_HTTP_REQ_UNSUPPORTED
881 } isc_http_request_type_t;
882 
883 typedef enum isc_http_scheme_type {
884 	ISC_HTTP_SCHEME_HTTP,
885 	ISC_HTTP_SCHEME_HTTP_SECURE,
886 	ISC_HTTP_SCHEME_UNSUPPORTED
887 } isc_http_scheme_type_t;
888 
889 typedef struct isc_nm_httphandler {
890 	int magic;
891 	char *path;
892 	isc_nm_recv_cb_t cb;
893 	void *cbarg;
894 	size_t extrahandlesize;
895 	LINK(struct isc_nm_httphandler) link;
896 } isc_nm_httphandler_t;
897 
898 struct isc_nm_http_endpoints {
899 	uint32_t magic;
900 	isc_mem_t *mctx;
901 
902 	ISC_LIST(isc_nm_httphandler_t) handlers;
903 
904 	isc_refcount_t references;
905 	atomic_bool in_use;
906 };
907 
908 typedef struct isc_nmsocket_h2 {
909 	isc_nmsocket_t *psock; /* owner of the structure */
910 	char *request_path;
911 	char *query_data;
912 	size_t query_data_len;
913 	bool query_too_large;
914 
915 	isc_buffer_t rbuf;
916 	isc_buffer_t wbuf;
917 
918 	int32_t stream_id;
919 	isc_nm_http_session_t *session;
920 
921 	isc_nmsocket_t *httpserver;
922 
923 	/* maximum concurrent streams (server-side) */
924 	atomic_uint_fast32_t max_concurrent_streams;
925 
926 	uint32_t min_ttl; /* used to set "max-age" in responses */
927 
928 	isc_http_request_type_t request_type;
929 	isc_http_scheme_type_t request_scheme;
930 
931 	size_t content_length;
932 	char clenbuf[128];
933 
934 	char cache_control_buf[128];
935 
936 	int headers_error_code;
937 	size_t headers_data_processed;
938 
939 	isc_nm_recv_cb_t cb;
940 	void *cbarg;
941 	LINK(struct isc_nmsocket_h2) link;
942 
943 	isc_nm_http_endpoints_t **listener_endpoints;
944 	size_t n_listener_endpoints;
945 
946 	isc_nm_http_endpoints_t *peer_endpoints;
947 
948 	bool response_submitted;
949 	struct {
950 		char *uri;
951 		bool post;
952 		isc_tlsctx_t *tlsctx;
953 		isc_sockaddr_t local_interface;
954 		void *cstream;
955 		const char *tls_peer_verify_string;
956 	} connect;
957 } isc_nmsocket_h2_t;
958 #endif /* HAVE_LIBNGHTTP2 */
959 
960 typedef void (*isc_nm_closehandlecb_t)(void *arg);
961 /*%<
962  * Opaque callback function, used for isc_nmhandle 'reset' and 'free'
963  * callbacks.
964  */
965 
966 struct isc_nmsocket {
967 	/*% Unlocked, RO */
968 	int magic;
969 	int tid;
970 	isc_nmsocket_type type;
971 	isc_nm_t *mgr;
972 
973 	/*% Parent socket for multithreaded listeners */
974 	isc_nmsocket_t *parent;
975 	/*% Listener socket this connection was accepted on */
976 	isc_nmsocket_t *listener;
977 	/*% Self socket */
978 	isc_nmsocket_t *self;
979 
980 	isc_barrier_t startlistening;
981 	isc_barrier_t stoplistening;
982 
983 	/*% TLS stuff */
984 	struct tls {
985 		isc_tls_t *tls;
986 		isc_tlsctx_t *ctx;
987 		isc_tlsctx_client_session_cache_t *client_sess_cache;
988 		bool client_session_saved;
989 		BIO *app_rbio;
990 		BIO *app_wbio;
991 		BIO *ssl_rbio;
992 		BIO *ssl_wbio;
993 		enum {
994 			TLS_STATE_NONE,
995 			TLS_STATE_HANDSHAKE,
996 			TLS_STATE_IO,
997 			TLS_STATE_ERROR,
998 			TLS_STATE_CLOSING
999 		} state;
1000 		ISC_LIST(isc__nm_uvreq_t) sendreqs;
1001 		bool cycle;
1002 		isc_result_t pending_error;
1003 		/* List of active send requests. */
1004 		isc__nm_uvreq_t *pending_req;
1005 		bool alpn_negotiated;
1006 		const char *tls_verify_errmsg;
1007 	} tls;
1008 
1009 #if HAVE_LIBNGHTTP2
1010 	/*% TLS stuff */
1011 	struct tlsstream {
1012 		bool server;
1013 		BIO *bio_in;
1014 		BIO *bio_out;
1015 		isc_tls_t *tls;
1016 		isc_tlsctx_t *ctx;
1017 		isc_tlsctx_t **listener_tls_ctx; /*%< A context reference per
1018 						    worker */
1019 		size_t n_listener_tls_ctx;
1020 		isc_tlsctx_client_session_cache_t *client_sess_cache;
1021 		bool client_session_saved;
1022 		isc_nmsocket_t *tlslistener;
1023 		isc_nmsocket_t *tlssocket;
1024 		atomic_bool result_updated;
1025 		enum {
1026 			TLS_INIT,
1027 			TLS_HANDSHAKE,
1028 			TLS_IO,
1029 			TLS_CLOSED
1030 		} state; /*%< The order of these is significant */
1031 		size_t nsending;
1032 		bool reading;
1033 	} tlsstream;
1034 
1035 	isc_nmsocket_h2_t h2;
1036 #endif /* HAVE_LIBNGHTTP2 */
1037 	/*%
1038 	 * quota is the TCP client, attached when a TCP connection
1039 	 * is established. pquota is a non-attached pointer to the
1040 	 * TCP client quota, stored in listening sockets but only
1041 	 * attached in connected sockets.
1042 	 */
1043 	isc_quota_t *quota;
1044 	isc_quota_t *pquota;
1045 	isc_quota_cb_t quotacb;
1046 
1047 	/*%
1048 	 * Socket statistics
1049 	 */
1050 	const isc_statscounter_t *statsindex;
1051 
1052 	/*%
1053 	 * TCP read/connect timeout timers.
1054 	 */
1055 	uv_timer_t read_timer;
1056 	uint64_t read_timeout;
1057 	uint64_t connect_timeout;
1058 
1059 	/*%
1060 	 * TCP write timeout timer.
1061 	 */
1062 	uint64_t write_timeout;
1063 
1064 	/*
1065 	 * Reading was throttled over TCP as the peer does not read the
1066 	 * data we are sending back.
1067 	 */
1068 	bool reading_throttled;
1069 
1070 	/*% outer socket is for 'wrapped' sockets - e.g. tcpdns in tcp */
1071 	isc_nmsocket_t *outer;
1072 
1073 	/*% server socket for connections */
1074 	isc_nmsocket_t *server;
1075 
1076 	/*% Child sockets for multi-socket setups */
1077 	isc_nmsocket_t *children;
1078 	uint_fast32_t nchildren;
1079 	isc_sockaddr_t iface;
1080 	isc_nmhandle_t *statichandle;
1081 	isc_nmhandle_t *outerhandle;
1082 
1083 	/*% Extra data allocated at the end of each isc_nmhandle_t */
1084 	size_t extrahandlesize;
1085 
1086 	/*% TCP backlog */
1087 	int backlog;
1088 
1089 	/*% libuv data */
1090 	uv_os_sock_t fd;
1091 	union uv_any_handle uv_handle;
1092 
1093 	/*% Peer address */
1094 	isc_sockaddr_t peer;
1095 
1096 	/* Atomic */
1097 	/*% Number of running (e.g. listening) child sockets */
1098 	atomic_uint_fast32_t rchildren;
1099 
1100 	/*%
1101 	 * Socket is active if it's listening, working, etc. If it's
1102 	 * closing, then it doesn't make a sense, for example, to
1103 	 * push handles or reqs for reuse.
1104 	 */
1105 	atomic_bool active;
1106 	atomic_bool destroying;
1107 
1108 	bool route_sock;
1109 
1110 	/*%
1111 	 * Socket is closed if it's not active and all the possible
1112 	 * callbacks were fired, there are no active handles, etc.
1113 	 * If active==false but closed==false, that means the socket
1114 	 * is closing.
1115 	 */
1116 	atomic_bool closing;
1117 	atomic_bool closed;
1118 	atomic_bool listening;
1119 	atomic_bool connecting;
1120 	atomic_bool connected;
1121 	atomic_bool accepting;
1122 	atomic_bool reading;
1123 	atomic_bool timedout;
1124 	isc_refcount_t references;
1125 
1126 	/*%
1127 	 * Established an outgoing connection, as client not server.
1128 	 */
1129 	atomic_bool client;
1130 
1131 	/*%
1132 	 * TCPDNS socket has been set not to pipeline.
1133 	 */
1134 	atomic_bool sequential;
1135 
1136 	/*%
1137 	 * The socket is processing read callback, this is guard to not read
1138 	 * data before the readcb is back.
1139 	 */
1140 	bool processing;
1141 
1142 	/*%
1143 	 * A TCP socket has had isc_nm_pauseread() called.
1144 	 */
1145 	atomic_bool readpaused;
1146 
1147 	/*%
1148 	 * A TCP or TCPDNS socket has been set to use the keepalive
1149 	 * timeout instead of the default idle timeout.
1150 	 */
1151 	atomic_bool keepalive;
1152 
1153 	/*%
1154 	 * 'spare' handles for that can be reused to avoid allocations,
1155 	 * for UDP.
1156 	 */
1157 	isc_astack_t *inactivehandles;
1158 	isc_astack_t *inactivereqs;
1159 
1160 	/*%
1161 	 * Used to wait for TCP listening events to complete, and
1162 	 * for the number of running children to reach zero during
1163 	 * shutdown.
1164 	 *
1165 	 * We use two condition variables to prevent the race where the netmgr
1166 	 * threads would be able to finish and destroy the socket before it's
1167 	 * unlocked by the isc_nm_listen<proto>() function.  So, the flow is as
1168 	 * follows:
1169 	 *
1170 	 *   1. parent thread creates all children sockets and passes then to
1171 	 *      netthreads, looks at the signaling variable and WAIT(cond) until
1172 	 *      the childrens are done initializing
1173 	 *
1174 	 *   2. the events get picked by netthreads, calls the libuv API (and
1175 	 *      either succeeds or fails) and WAIT(scond) until all other
1176 	 *      children sockets in netthreads are initialized and the listening
1177 	 *      socket lock is unlocked
1178 	 *
1179 	 *   3. the control is given back to the parent thread which now either
1180 	 *      returns success or shutdowns the listener if an error has
1181 	 *      occured in the children netthread
1182 	 *
1183 	 * NOTE: The other approach would be doing an extra attach to the parent
1184 	 * listening socket, and then detach it in the parent thread, but that
1185 	 * breaks the promise that once the libuv socket is initialized on the
1186 	 * nmsocket, the nmsocket needs to be handled only by matching
1187 	 * netthread, so in fact that would add a complexity in a way that
1188 	 * isc__nmsocket_detach would have to be converted to use an
1189 	 * asynchrounous netievent.
1190 	 */
1191 	isc_mutex_t lock;
1192 	isc_condition_t cond;
1193 	isc_condition_t scond;
1194 
1195 	/*%
1196 	 * Used to pass a result back from listen or connect events.
1197 	 */
1198 	isc_result_t result;
1199 
1200 	/*%
1201 	 * Current number of active handles.
1202 	 */
1203 	atomic_int_fast32_t ah;
1204 
1205 	/*% Buffer for TCPDNS processing */
1206 	size_t buf_size;
1207 	size_t buf_len;
1208 	unsigned char *buf;
1209 
1210 	/*%
1211 	 * This function will be called with handle->sock
1212 	 * as the argument whenever a handle's references drop
1213 	 * to zero, after its reset callback has been called.
1214 	 */
1215 	isc_nm_closehandlecb_t closehandle_cb;
1216 
1217 	isc_nmhandle_t *recv_handle;
1218 	isc_nm_recv_cb_t recv_cb;
1219 	void *recv_cbarg;
1220 	bool recv_read;
1221 
1222 	isc_nm_cb_t connect_cb;
1223 	void *connect_cbarg;
1224 
1225 	isc_nm_accept_cb_t accept_cb;
1226 	void *accept_cbarg;
1227 
1228 	atomic_int_fast32_t active_child_connections;
1229 
1230 	isc_barrier_t barrier;
1231 	bool barrier_initialised;
1232 #ifdef NETMGR_TRACE
1233 	void *backtrace[TRACE_SIZE];
1234 	int backtrace_size;
1235 	LINK(isc_nmsocket_t) active_link;
1236 	ISC_LIST(isc_nmhandle_t) active_handles;
1237 #endif
1238 };
1239 
1240 bool
1241 isc__nm_in_netthread(void);
1242 /*%<
1243  * Returns 'true' if we're in the network thread.
1244  */
1245 
1246 void
1247 isc__nm_maybe_enqueue_ievent(isc__networker_t *worker, isc__netievent_t *event);
1248 /*%<
1249  * If the caller is already in the matching nmthread, process the netievent
1250  * directly, if not enqueue using isc__nm_enqueue_ievent().
1251  */
1252 
1253 void
1254 isc__nm_enqueue_ievent(isc__networker_t *worker, isc__netievent_t *event);
1255 /*%<
1256  * Enqueue an ievent onto a specific worker queue. (This the only safe
1257  * way to use an isc__networker_t from another thread.)
1258  */
1259 
1260 void
1261 isc__nm_free_uvbuf(isc_nmsocket_t *sock, const uv_buf_t *buf);
1262 /*%<
1263  * Free a buffer allocated for a receive operation.
1264  *
1265  * Note that as currently implemented, this doesn't actually
1266  * free anything, marks the isc__networker's UDP receive buffer
1267  * as "not in use".
1268  */
1269 
1270 isc_nmhandle_t *
1271 isc___nmhandle_get(isc_nmsocket_t *sock, isc_sockaddr_t *peer,
1272 		   isc_sockaddr_t *local FLARG);
1273 /*%<
1274  * Get a handle for the socket 'sock', allocating a new one
1275  * if there isn't one available in 'sock->inactivehandles'.
1276  *
1277  * If 'peer' is not NULL, set the handle's peer address to 'peer',
1278  * otherwise set it to 'sock->peer'.
1279  *
1280  * If 'local' is not NULL, set the handle's local address to 'local',
1281  * otherwise set it to 'sock->iface->addr'.
1282  *
1283  * 'sock' will be attached to 'handle->sock'. The caller may need
1284  * to detach the socket afterward.
1285  */
1286 
1287 isc__nm_uvreq_t *
1288 isc___nm_uvreq_get(isc_nm_t *mgr, isc_nmsocket_t *sock FLARG);
1289 /*%<
1290  * Get a UV request structure for the socket 'sock', allocating a
1291  * new one if there isn't one available in 'sock->inactivereqs'.
1292  */
1293 
1294 void
1295 isc___nm_uvreq_put(isc__nm_uvreq_t **req, isc_nmsocket_t *sock FLARG);
1296 /*%<
1297  * Completes the use of a UV request structure, setting '*req' to NULL.
1298  *
1299  * The UV request is pushed onto the 'sock->inactivereqs' stack or,
1300  * if that doesn't work, freed.
1301  */
1302 
1303 void
1304 isc___nmsocket_init(isc_nmsocket_t *sock, isc_nm_t *mgr, isc_nmsocket_type type,
1305 		    isc_sockaddr_t *iface FLARG);
1306 /*%<
1307  * Initialize socket 'sock', attach it to 'mgr', and set it to type 'type'
1308  * and its interface to 'iface'.
1309  */
1310 
1311 void
1312 isc___nmsocket_attach(isc_nmsocket_t *sock, isc_nmsocket_t **target FLARG);
1313 /*%<
1314  * Attach to a socket, increasing refcount
1315  */
1316 
1317 void
1318 isc___nmsocket_detach(isc_nmsocket_t **socketp FLARG);
1319 /*%<
1320  * Detach from socket, decreasing refcount and possibly destroying the
1321  * socket if it's no longer referenced.
1322  */
1323 
1324 void
1325 isc___nmsocket_prep_destroy(isc_nmsocket_t *sock FLARG);
1326 /*%<
1327  * Market 'sock' as inactive, close it if necessary, and destroy it
1328  * if there are no remaining references or active handles.
1329  */
1330 
1331 void
1332 isc__nmsocket_shutdown(isc_nmsocket_t *sock);
1333 /*%<
1334  * Initiate the socket shutdown which actively calls the active
1335  * callbacks.
1336  */
1337 
1338 void
1339 isc__nmsocket_reset(isc_nmsocket_t *sock);
1340 /*%<
1341  * Reset and close the socket.
1342  */
1343 
1344 bool
1345 isc__nmsocket_active(isc_nmsocket_t *sock);
1346 /*%<
1347  * Determine whether 'sock' is active by checking 'sock->active'
1348  * or, for child sockets, 'sock->parent->active'.
1349  */
1350 
1351 bool
1352 isc__nmsocket_deactivate(isc_nmsocket_t *sock);
1353 /*%<
1354  * @brief Deactivate active socket
1355  *
1356  * Atomically deactive the socket by setting @p sock->active or, for child
1357  * sockets, @p sock->parent->active to @c false
1358  *
1359  * @param[in] sock - valid nmsocket
1360  * @return @c false if the socket was already inactive, @c true otherwise
1361  */
1362 
1363 void
1364 isc__nmsocket_clearcb(isc_nmsocket_t *sock);
1365 /*%<
1366  * Clear the recv and accept callbacks in 'sock'.
1367  */
1368 
1369 void
1370 isc__nmsocket_timer_stop(isc_nmsocket_t *sock);
1371 void
1372 isc__nmsocket_timer_start(isc_nmsocket_t *sock);
1373 void
1374 isc__nmsocket_timer_restart(isc_nmsocket_t *sock);
1375 bool
1376 isc__nmsocket_timer_running(isc_nmsocket_t *sock);
1377 /*%<
1378  * Start/stop/restart/check the timeout on the socket
1379  */
1380 
1381 void
1382 isc__nm_connectcb(isc_nmsocket_t *sock, isc__nm_uvreq_t *uvreq,
1383 		  isc_result_t eresult, bool async);
1384 
1385 void
1386 isc__nm_async_connectcb(isc__networker_t *worker, isc__netievent_t *ev0);
1387 /*%<
1388  * Issue a connect callback on the socket, used to call the callback
1389  */
1390 
1391 void
1392 isc__nm_readcb(isc_nmsocket_t *sock, isc__nm_uvreq_t *uvreq,
1393 	       isc_result_t eresult);
1394 void
1395 isc__nm_async_readcb(isc__networker_t *worker, isc__netievent_t *ev0);
1396 
1397 /*%<
1398  * Issue a read callback on the socket, used to call the callback
1399  * on failed conditions when the event can't be scheduled on the uv loop.
1400  *
1401  */
1402 
1403 void
1404 isc__nm_sendcb(isc_nmsocket_t *sock, isc__nm_uvreq_t *uvreq,
1405 	       isc_result_t eresult, bool async);
1406 void
1407 isc__nm_async_sendcb(isc__networker_t *worker, isc__netievent_t *ev0);
1408 /*%<
1409  * Issue a write callback on the socket, used to call the callback
1410  * on failed conditions when the event can't be scheduled on the uv loop.
1411  */
1412 
1413 void
1414 isc__nm_async_shutdown(isc__networker_t *worker, isc__netievent_t *ev0);
1415 /*%<
1416  * Walk through all uv handles, get the underlying sockets and issue
1417  * close on them.
1418  */
1419 
1420 void
1421 isc__nm_udp_send(isc_nmhandle_t *handle, const isc_region_t *region,
1422 		 isc_nm_cb_t cb, void *cbarg);
1423 /*%<
1424  * Back-end implementation of isc_nm_send() for UDP handles.
1425  */
1426 
1427 void
1428 isc__nm_udp_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg);
1429 /*
1430  * Back-end implementation of isc_nm_read() for UDP handles.
1431  */
1432 
1433 void
1434 isc__nm_udp_close(isc_nmsocket_t *sock);
1435 /*%<
1436  * Close a UDP socket.
1437  */
1438 
1439 void
1440 isc__nm_udp_cancelread(isc_nmhandle_t *handle);
1441 /*%<
1442  * Stop reading on a connected UDP handle.
1443  */
1444 
1445 void
1446 isc__nm_udp_shutdown(isc_nmsocket_t *sock);
1447 /*%<
1448  * Called during the shutdown process to close and clean up connected
1449  * sockets.
1450  */
1451 
1452 void
1453 isc__nm_udp_stoplistening(isc_nmsocket_t *sock);
1454 /*%<
1455  * Stop listening on 'sock'.
1456  */
1457 
1458 void
1459 isc__nm_udp_settimeout(isc_nmhandle_t *handle, uint32_t timeout);
1460 /*%<
1461  * Set or clear the recv timeout for the UDP socket associated with 'handle'.
1462  */
1463 
1464 void
1465 isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0);
1466 void
1467 isc__nm_async_udpconnect(isc__networker_t *worker, isc__netievent_t *ev0);
1468 void
1469 isc__nm_async_udpstop(isc__networker_t *worker, isc__netievent_t *ev0);
1470 void
1471 isc__nm_async_udpsend(isc__networker_t *worker, isc__netievent_t *ev0);
1472 void
1473 isc__nm_async_udpread(isc__networker_t *worker, isc__netievent_t *ev0);
1474 void
1475 isc__nm_async_udpcancel(isc__networker_t *worker, isc__netievent_t *ev0);
1476 void
1477 isc__nm_async_udpclose(isc__networker_t *worker, isc__netievent_t *ev0);
1478 /*%<
1479  * Callback handlers for asynchronous UDP events (listen, stoplisten, send).
1480  */
1481 
1482 void
1483 isc__nm_async_routeconnect(isc__networker_t *worker, isc__netievent_t *ev0);
1484 /*%<
1485  * Callback handler for route socket events.
1486  */
1487 
1488 void
1489 isc__nm_tcp_send(isc_nmhandle_t *handle, const isc_region_t *region,
1490 		 isc_nm_cb_t cb, void *cbarg);
1491 /*%<
1492  * Back-end implementation of isc_nm_send() for TCP handles.
1493  */
1494 
1495 void
1496 isc__nm_tcp_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg);
1497 /*
1498  * Back-end implementation of isc_nm_read() for TCP handles.
1499  */
1500 
1501 void
1502 isc__nm_tcp_close(isc_nmsocket_t *sock);
1503 /*%<
1504  * Close a TCP socket.
1505  */
1506 void
1507 isc__nm_tcp_pauseread(isc_nmhandle_t *handle);
1508 /*%<
1509  * Pause reading on this handle, while still remembering the callback.
1510  */
1511 
1512 void
1513 isc__nm_tcp_resumeread(isc_nmhandle_t *handle);
1514 /*%<
1515  * Resume reading from socket.
1516  *
1517  */
1518 
1519 void
1520 isc__nm_tcp_shutdown(isc_nmsocket_t *sock);
1521 /*%<
1522  * Called during the shutdown process to close and clean up connected
1523  * sockets.
1524  */
1525 
1526 void
1527 isc__nm_tcp_cancelread(isc_nmhandle_t *handle);
1528 /*%<
1529  * Stop reading on a connected TCP handle.
1530  */
1531 
1532 void
1533 isc__nm_tcp_stoplistening(isc_nmsocket_t *sock);
1534 /*%<
1535  * Stop listening on 'sock'.
1536  */
1537 
1538 int_fast32_t
1539 isc__nm_tcp_listener_nactive(isc_nmsocket_t *sock);
1540 /*%<
1541  * Returns the number of active connections for the TCP listener socket.
1542  */
1543 
1544 void
1545 isc__nm_tcp_settimeout(isc_nmhandle_t *handle, uint32_t timeout);
1546 /*%<
1547  * Set the read timeout for the TCP socket associated with 'handle'.
1548  */
1549 
1550 void
1551 isc__nm_async_tcpconnect(isc__networker_t *worker, isc__netievent_t *ev0);
1552 void
1553 isc__nm_async_tcplisten(isc__networker_t *worker, isc__netievent_t *ev0);
1554 void
1555 isc__nm_async_tcpaccept(isc__networker_t *worker, isc__netievent_t *ev0);
1556 void
1557 isc__nm_async_tcpstop(isc__networker_t *worker, isc__netievent_t *ev0);
1558 void
1559 isc__nm_async_tcpsend(isc__networker_t *worker, isc__netievent_t *ev0);
1560 void
1561 isc__nm_async_startread(isc__networker_t *worker, isc__netievent_t *ev0);
1562 void
1563 isc__nm_async_pauseread(isc__networker_t *worker, isc__netievent_t *ev0);
1564 void
1565 isc__nm_async_tcpstartread(isc__networker_t *worker, isc__netievent_t *ev0);
1566 void
1567 isc__nm_async_tcppauseread(isc__networker_t *worker, isc__netievent_t *ev0);
1568 void
1569 isc__nm_async_tcpcancel(isc__networker_t *worker, isc__netievent_t *ev0);
1570 void
1571 isc__nm_async_tcpclose(isc__networker_t *worker, isc__netievent_t *ev0);
1572 /*%<
1573  * Callback handlers for asynchronous TCP events (connect, listen,
1574  * stoplisten, send, read, pause, close).
1575  */
1576 
1577 void
1578 isc__nm_async_tlsclose(isc__networker_t *worker, isc__netievent_t *ev0);
1579 
1580 void
1581 isc__nm_async_tlssend(isc__networker_t *worker, isc__netievent_t *ev0);
1582 
1583 void
1584 isc__nm_async_tlsstartread(isc__networker_t *worker, isc__netievent_t *ev0);
1585 
1586 void
1587 isc__nm_async_tlsdobio(isc__networker_t *worker, isc__netievent_t *ev0);
1588 
1589 void
1590 isc__nm_async_tlscancel(isc__networker_t *worker, isc__netievent_t *ev0);
1591 /*%<
1592  * Callback handlers for asynchronous TLS events.
1593  */
1594 
1595 void
1596 isc__nm_tcpdns_send(isc_nmhandle_t *handle, isc_region_t *region,
1597 		    isc_nm_cb_t cb, void *cbarg);
1598 /*%<
1599  * Back-end implementation of isc_nm_send() for TCPDNS handles.
1600  */
1601 
1602 void
1603 isc__nm_tcpdns_shutdown(isc_nmsocket_t *sock);
1604 
1605 void
1606 isc__nm_tcpdns_close(isc_nmsocket_t *sock);
1607 /*%<
1608  * Close a TCPDNS socket.
1609  */
1610 
1611 void
1612 isc__nm_tcpdns_stoplistening(isc_nmsocket_t *sock);
1613 /*%<
1614  * Stop listening on 'sock'.
1615  */
1616 
1617 void
1618 isc__nm_tcpdns_settimeout(isc_nmhandle_t *handle, uint32_t timeout);
1619 /*%<
1620  * Set the read timeout and reset the timer for the TCPDNS socket
1621  * associated with 'handle', and the TCP socket it wraps around.
1622  */
1623 
1624 void
1625 isc__nm_async_tcpdnsaccept(isc__networker_t *worker, isc__netievent_t *ev0);
1626 void
1627 isc__nm_async_tcpdnsconnect(isc__networker_t *worker, isc__netievent_t *ev0);
1628 void
1629 isc__nm_async_tcpdnslisten(isc__networker_t *worker, isc__netievent_t *ev0);
1630 void
1631 isc__nm_async_tcpdnscancel(isc__networker_t *worker, isc__netievent_t *ev0);
1632 void
1633 isc__nm_async_tcpdnsclose(isc__networker_t *worker, isc__netievent_t *ev0);
1634 void
1635 isc__nm_async_tcpdnssend(isc__networker_t *worker, isc__netievent_t *ev0);
1636 void
1637 isc__nm_async_tcpdnsstop(isc__networker_t *worker, isc__netievent_t *ev0);
1638 void
1639 isc__nm_async_tcpdnsread(isc__networker_t *worker, isc__netievent_t *ev0);
1640 /*%<
1641  * Callback handlers for asynchronous TCPDNS events.
1642  */
1643 
1644 void
1645 isc__nm_tcpdns_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg);
1646 /*
1647  * Back-end implementation of isc_nm_read() for TCPDNS handles.
1648  */
1649 
1650 void
1651 isc__nm_tcpdns_cancelread(isc_nmhandle_t *handle);
1652 /*%<
1653  * Stop reading on a connected TCPDNS handle.
1654  */
1655 
1656 void
1657 isc__nm_tlsdns_send(isc_nmhandle_t *handle, isc_region_t *region,
1658 		    isc_nm_cb_t cb, void *cbarg);
1659 
1660 void
1661 isc__nm_tlsdns_shutdown(isc_nmsocket_t *sock);
1662 
1663 void
1664 isc__nm_tlsdns_close(isc_nmsocket_t *sock);
1665 /*%<
1666  * Close a TLSDNS socket.
1667  */
1668 
1669 void
1670 isc__nm_tlsdns_stoplistening(isc_nmsocket_t *sock);
1671 /*%<
1672  * Stop listening on 'sock'.
1673  */
1674 
1675 void
1676 isc__nm_tlsdns_settimeout(isc_nmhandle_t *handle, uint32_t timeout);
1677 /*%<
1678  * Set the read timeout and reset the timer for the TLSDNS socket
1679  * associated with 'handle', and the TCP socket it wraps around.
1680  */
1681 
1682 void
1683 isc__nm_tlsdns_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg);
1684 /*
1685  * Back-end implementation of isc_nm_read() for TLSDNS handles.
1686  */
1687 
1688 void
1689 isc__nm_tlsdns_cancelread(isc_nmhandle_t *handle);
1690 /*%<
1691  * Stop reading on a connected TLSDNS handle.
1692  */
1693 
1694 const char *
1695 isc__nm_tlsdns_verify_tls_peer_result_string(const isc_nmhandle_t *handle);
1696 
1697 void
1698 isc__nm_async_tlsdnscycle(isc__networker_t *worker, isc__netievent_t *ev0);
1699 void
1700 isc__nm_async_tlsdnsaccept(isc__networker_t *worker, isc__netievent_t *ev0);
1701 void
1702 isc__nm_async_tlsdnsconnect(isc__networker_t *worker, isc__netievent_t *ev0);
1703 void
1704 isc__nm_async_tlsdnslisten(isc__networker_t *worker, isc__netievent_t *ev0);
1705 void
1706 isc__nm_async_tlsdnscancel(isc__networker_t *worker, isc__netievent_t *ev0);
1707 void
1708 isc__nm_async_tlsdnsclose(isc__networker_t *worker, isc__netievent_t *ev0);
1709 void
1710 isc__nm_async_tlsdnssend(isc__networker_t *worker, isc__netievent_t *ev0);
1711 void
1712 isc__nm_async_tlsdnsstop(isc__networker_t *worker, isc__netievent_t *ev0);
1713 void
1714 isc__nm_async_tlsdnsshutdown(isc__networker_t *worker, isc__netievent_t *ev0);
1715 void
1716 isc__nm_async_tlsdnsread(isc__networker_t *worker, isc__netievent_t *ev0);
1717 void
1718 isc__nm_async_tlsdns_set_tlsctx(isc_nmsocket_t *listener, isc_tlsctx_t *tlsctx,
1719 				const int tid);
1720 /*%<
1721  * Callback handlers for asynchronous TLSDNS events.
1722  */
1723 
1724 isc_result_t
1725 isc__nm_tlsdns_xfr_checkperm(isc_nmsocket_t *sock);
1726 /*%<
1727  * Check if it is permitted to do a zone transfer over the given TLSDNS
1728  * socket.
1729  *
1730  * Returns:
1731  * \li	#ISC_R_SUCCESS		Success, permission check passed successfully
1732  * \li	#ISC_R_DOTALPNERROR	No permission because of ALPN tag mismatch
1733  * \li  any other result indicates failure (i.e. no permission)
1734  *
1735  * Requires:
1736  * \li	'sock' is a valid TLSDNS socket.
1737  */
1738 
1739 void
1740 isc__nm_tlsdns_cleanup_data(isc_nmsocket_t *sock);
1741 
1742 #if HAVE_LIBNGHTTP2
1743 void
1744 isc__nm_tls_send(isc_nmhandle_t *handle, const isc_region_t *region,
1745 		 isc_nm_cb_t cb, void *cbarg);
1746 
1747 void
1748 isc__nm_tls_cancelread(isc_nmhandle_t *handle);
1749 
1750 /*%<
1751  * Back-end implementation of isc_nm_send() for TLSDNS handles.
1752  */
1753 
1754 void
1755 isc__nm_tls_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg);
1756 
1757 void
1758 isc__nm_tls_close(isc_nmsocket_t *sock);
1759 /*%<
1760  * Close a TLS socket.
1761  */
1762 
1763 void
1764 isc__nm_tls_pauseread(isc_nmhandle_t *handle);
1765 /*%<
1766  * Pause reading on this handle, while still remembering the callback.
1767  */
1768 
1769 void
1770 isc__nm_tls_resumeread(isc_nmhandle_t *handle);
1771 /*%<
1772  * Resume reading from the handle.
1773  *
1774  */
1775 
1776 void
1777 isc__nm_tls_cleanup_data(isc_nmsocket_t *sock);
1778 
1779 void
1780 isc__nm_tls_stoplistening(isc_nmsocket_t *sock);
1781 
1782 void
1783 isc__nm_tls_settimeout(isc_nmhandle_t *handle, uint32_t timeout);
1784 void
1785 isc__nm_tls_cleartimeout(isc_nmhandle_t *handle);
1786 /*%<
1787  * Set the read timeout and reset the timer for the socket
1788  * associated with 'handle', and the TCP socket it wraps
1789  * around.
1790  */
1791 
1792 const char *
1793 isc__nm_tls_verify_tls_peer_result_string(const isc_nmhandle_t *handle);
1794 
1795 void
1796 isc__nmhandle_tls_keepalive(isc_nmhandle_t *handle, bool value);
1797 /*%<
1798  * Set the keepalive value on the underlying TCP handle.
1799  */
1800 
1801 void
1802 isc__nm_async_tls_set_tlsctx(isc_nmsocket_t *listener, isc_tlsctx_t *tlsctx,
1803 			     const int tid);
1804 
1805 void
1806 isc__nmhandle_tls_setwritetimeout(isc_nmhandle_t *handle,
1807 				  uint64_t write_timeout);
1808 
1809 void
1810 isc__nm_http_stoplistening(isc_nmsocket_t *sock);
1811 
1812 void
1813 isc__nm_http_settimeout(isc_nmhandle_t *handle, uint32_t timeout);
1814 void
1815 isc__nm_http_cleartimeout(isc_nmhandle_t *handle);
1816 /*%<
1817  * Set the read timeout and reset the timer for the socket
1818  * associated with 'handle', and the TLS/TCP socket it wraps
1819  * around.
1820  */
1821 
1822 void
1823 isc__nmhandle_http_keepalive(isc_nmhandle_t *handle, bool value);
1824 /*%<
1825  * Set the keepalive value on the underlying session handle
1826  */
1827 
1828 void
1829 isc__nm_http_initsocket(isc_nmsocket_t *sock);
1830 
1831 void
1832 isc__nm_http_cleanup_data(isc_nmsocket_t *sock);
1833 
1834 isc_result_t
1835 isc__nm_http_request(isc_nmhandle_t *handle, isc_region_t *region,
1836 		     isc_nm_recv_cb_t reply_cb, void *cbarg);
1837 
1838 void
1839 isc__nm_http_send(isc_nmhandle_t *handle, const isc_region_t *region,
1840 		  isc_nm_cb_t cb, void *cbarg);
1841 
1842 void
1843 isc__nm_http_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg);
1844 
1845 void
1846 isc__nm_http_close(isc_nmsocket_t *sock);
1847 
1848 void
1849 isc__nm_http_bad_request(isc_nmhandle_t *handle);
1850 /*%<
1851  * Respond to the request with 400 "Bad Request" status.
1852  *
1853  * Requires:
1854  * \li 'handle' is a valid HTTP netmgr handle object, referencing a server-side
1855  * socket
1856  */
1857 
1858 bool
1859 isc__nm_http_has_encryption(const isc_nmhandle_t *handle);
1860 
1861 void
1862 isc__nm_http_set_maxage(isc_nmhandle_t *handle, const uint32_t ttl);
1863 
1864 const char *
1865 isc__nm_http_verify_tls_peer_result_string(const isc_nmhandle_t *handle);
1866 
1867 void
1868 isc__nm_async_httpsend(isc__networker_t *worker, isc__netievent_t *ev0);
1869 
1870 void
1871 isc__nm_async_httpclose(isc__networker_t *worker, isc__netievent_t *ev0);
1872 
1873 void
1874 isc__nm_async_httpendpoints(isc__networker_t *worker, isc__netievent_t *ev0);
1875 
1876 bool
1877 isc__nm_parse_httpquery(const char *query_string, const char **start,
1878 			size_t *len);
1879 
1880 char *
1881 isc__nm_base64url_to_base64(isc_mem_t *mem, const char *base64url,
1882 			    const size_t base64url_len, size_t *res_len);
1883 
1884 char *
1885 isc__nm_base64_to_base64url(isc_mem_t *mem, const char *base64,
1886 			    const size_t base64_len, size_t *res_len);
1887 
1888 void
1889 isc__nm_httpsession_attach(isc_nm_http_session_t *source,
1890 			   isc_nm_http_session_t **targetp);
1891 void
1892 isc__nm_httpsession_detach(isc_nm_http_session_t **sessionp);
1893 
1894 void
1895 isc__nm_http_set_tlsctx(isc_nmsocket_t *sock, isc_tlsctx_t *tlsctx);
1896 
1897 void
1898 isc__nm_http_set_max_streams(isc_nmsocket_t *listener,
1899 			     const uint32_t max_concurrent_streams);
1900 
1901 #endif
1902 
1903 void
1904 isc__nm_async_settlsctx(isc__networker_t *worker, isc__netievent_t *ev0);
1905 
1906 #define isc__nm_uverr2result(x) \
1907 	isc___nm_uverr2result(x, true, __FILE__, __LINE__, __func__)
1908 isc_result_t
1909 isc___nm_uverr2result(int uverr, bool dolog, const char *file,
1910 		      unsigned int line, const char *func);
1911 /*%<
1912  * Convert a libuv error value into an isc_result_t.  The
1913  * list of supported error values is not complete; new users
1914  * of this function should add any expected errors that are
1915  * not already there.
1916  */
1917 
1918 bool
1919 isc__nm_acquire_interlocked(isc_nm_t *mgr);
1920 /*%<
1921  * Try to acquire interlocked state; return true if successful.
1922  */
1923 
1924 void
1925 isc__nm_drop_interlocked(isc_nm_t *mgr);
1926 /*%<
1927  * Drop interlocked state; signal waiters.
1928  */
1929 
1930 void
1931 isc__nm_acquire_interlocked_force(isc_nm_t *mgr);
1932 /*%<
1933  * Actively wait for interlocked state.
1934  */
1935 
1936 void
1937 isc__nm_async_sockstop(isc__networker_t *worker, isc__netievent_t *ev0);
1938 
1939 void
1940 isc__nm_incstats(isc_nmsocket_t *sock, isc__nm_statid_t id);
1941 /*%<
1942  * Increment socket-related statistics counters.
1943  */
1944 
1945 void
1946 isc__nm_decstats(isc_nmsocket_t *sock, isc__nm_statid_t id);
1947 /*%<
1948  * Decrement socket-related statistics counters.
1949  */
1950 
1951 isc_result_t
1952 isc__nm_socket(int domain, int type, int protocol, uv_os_sock_t *sockp);
1953 /*%<
1954  * Platform independent socket() version
1955  */
1956 
1957 void
1958 isc__nm_closesocket(uv_os_sock_t sock);
1959 /*%<
1960  * Platform independent closesocket() version
1961  */
1962 
1963 isc_result_t
1964 isc__nm_socket_freebind(uv_os_sock_t fd, sa_family_t sa_family);
1965 /*%<
1966  * Set the IP_FREEBIND (or equivalent) socket option on the uv_handle
1967  */
1968 
1969 isc_result_t
1970 isc__nm_socket_reuse(uv_os_sock_t fd);
1971 /*%<
1972  * Set the SO_REUSEADDR or SO_REUSEPORT (or equivalent) socket option on the fd
1973  */
1974 
1975 isc_result_t
1976 isc__nm_socket_reuse_lb(uv_os_sock_t fd);
1977 /*%<
1978  * Set the SO_REUSEPORT_LB (or equivalent) socket option on the fd
1979  */
1980 
1981 isc_result_t
1982 isc__nm_socket_incoming_cpu(uv_os_sock_t fd);
1983 /*%<
1984  * Set the SO_INCOMING_CPU socket option on the fd if available
1985  */
1986 
1987 isc_result_t
1988 isc__nm_socket_disable_pmtud(uv_os_sock_t fd, sa_family_t sa_family);
1989 /*%<
1990  * Disable the Path MTU Discovery, either by disabling IP(V6)_DONTFRAG socket
1991  * option, or setting the IP(V6)_MTU_DISCOVER socket option to IP_PMTUDISC_OMIT
1992  */
1993 
1994 isc_result_t
1995 isc__nm_socket_v6only(uv_os_sock_t fd, sa_family_t sa_family);
1996 /*%<
1997  * Restrict the socket to sending and receiving IPv6 packets only
1998  */
1999 
2000 isc_result_t
2001 isc__nm_socket_connectiontimeout(uv_os_sock_t fd, int timeout_ms);
2002 /*%<
2003  * Set the connection timeout in milliseconds, on non-Linux platforms,
2004  * the minimum value must be at least 1000 (1 second).
2005  */
2006 
2007 isc_result_t
2008 isc__nm_socket_tcp_nodelay(uv_os_sock_t fd);
2009 /*%<
2010  * Disables Nagle's algorithm on a TCP socket (sets TCP_NODELAY).
2011  */
2012 
2013 isc_result_t
2014 isc__nm_socket_tcp_maxseg(uv_os_sock_t fd, int size);
2015 /*%<
2016  * Set the TCP maximum segment size
2017  */
2018 
2019 isc_result_t
2020 isc__nm_socket_min_mtu(uv_os_sock_t fd, sa_family_t sa_family);
2021 /*%<
2022  * Use minimum MTU on IPv6 sockets
2023  */
2024 
2025 void
2026 isc__nm_set_network_buffers(isc_nm_t *nm, uv_handle_t *handle);
2027 /*%>
2028  * Sets the pre-configured network buffers size on the handle.
2029  */
2030 
2031 void
2032 isc__nmsocket_barrier_init(isc_nmsocket_t *listener);
2033 /*%>
2034  * Initialise the socket synchronisation barrier according to the
2035  * number of children.
2036  */
2037 
2038 void
2039 isc__nmsocket_stop(isc_nmsocket_t *listener);
2040 /*%>
2041  * Broadcast "stop" event for a listener socket across all workers and
2042  * wait its processing completion - then, stop and close the underlying
2043  * transport listener socket.
2044  *
2045  * The primitive is used in multi-layer transport listener sockets to
2046  * implement shutdown properly: after the broadcasted events has been
2047  * processed it is safe to destroy the shared data within the listener
2048  * socket (including shutting down the underlying transport listener
2049  * socket).
2050  */
2051 
2052 /*
2053  * typedef all the netievent types
2054  */
2055 
2056 NETIEVENT_SOCKET_TYPE(close);
2057 NETIEVENT_SOCKET_TYPE(tcpclose);
2058 NETIEVENT_SOCKET_TYPE(tcplisten);
2059 NETIEVENT_SOCKET_TYPE(tcppauseread);
2060 NETIEVENT_SOCKET_TYPE(tcpstop);
2061 NETIEVENT_SOCKET_TYPE(tlsclose);
2062 /* NETIEVENT_SOCKET_TYPE(tlsconnect); */ /* unique type, defined independently
2063 					  */
2064 NETIEVENT_SOCKET_TYPE(tlsdobio);
2065 NETIEVENT_SOCKET_TYPE(tlsstartread);
2066 NETIEVENT_SOCKET_HANDLE_TYPE(tlscancel);
2067 NETIEVENT_SOCKET_TYPE(udpclose);
2068 NETIEVENT_SOCKET_TYPE(udplisten);
2069 NETIEVENT_SOCKET_TYPE(udpread);
2070 /* NETIEVENT_SOCKET_TYPE(udpsend); */ /* unique type, defined independently */
2071 NETIEVENT_SOCKET_TYPE(udpstop);
2072 
2073 NETIEVENT_SOCKET_TYPE(tcpdnsclose);
2074 NETIEVENT_SOCKET_TYPE(tcpdnsread);
2075 NETIEVENT_SOCKET_TYPE(tcpdnsstop);
2076 NETIEVENT_SOCKET_TYPE(tcpdnslisten);
2077 NETIEVENT_SOCKET_REQ_TYPE(tcpdnsconnect);
2078 NETIEVENT_SOCKET_REQ_TYPE(tcpdnssend);
2079 NETIEVENT_SOCKET_HANDLE_TYPE(tcpdnscancel);
2080 NETIEVENT_SOCKET_QUOTA_TYPE(tcpdnsaccept);
2081 
2082 NETIEVENT_SOCKET_TYPE(tlsdnsclose);
2083 NETIEVENT_SOCKET_TYPE(tlsdnsread);
2084 NETIEVENT_SOCKET_TYPE(tlsdnsstop);
2085 NETIEVENT_SOCKET_TYPE(tlsdnsshutdown);
2086 NETIEVENT_SOCKET_TYPE(tlsdnslisten);
2087 NETIEVENT_SOCKET_REQ_TYPE(tlsdnsconnect);
2088 NETIEVENT_SOCKET_REQ_TYPE(tlsdnssend);
2089 NETIEVENT_SOCKET_HANDLE_TYPE(tlsdnscancel);
2090 NETIEVENT_SOCKET_QUOTA_TYPE(tlsdnsaccept);
2091 NETIEVENT_SOCKET_TYPE(tlsdnscycle);
2092 
2093 #ifdef HAVE_LIBNGHTTP2
2094 NETIEVENT_SOCKET_REQ_TYPE(httpsend);
2095 NETIEVENT_SOCKET_TYPE(httpclose);
2096 NETIEVENT_SOCKET_HTTP_EPS_TYPE(httpendpoints);
2097 #endif /* HAVE_LIBNGHTTP2 */
2098 
2099 NETIEVENT_SOCKET_REQ_TYPE(tcpconnect);
2100 NETIEVENT_SOCKET_REQ_TYPE(tcpsend);
2101 NETIEVENT_SOCKET_TYPE(tcpstartread);
2102 NETIEVENT_SOCKET_REQ_TYPE(tlssend);
2103 NETIEVENT_SOCKET_REQ_TYPE(udpconnect);
2104 
2105 NETIEVENT_SOCKET_REQ_TYPE(routeconnect);
2106 
2107 NETIEVENT_SOCKET_REQ_RESULT_TYPE(connectcb);
2108 NETIEVENT_SOCKET_REQ_RESULT_TYPE(readcb);
2109 NETIEVENT_SOCKET_REQ_RESULT_TYPE(sendcb);
2110 
2111 NETIEVENT_SOCKET_HANDLE_TYPE(detach);
2112 NETIEVENT_SOCKET_HANDLE_TYPE(tcpcancel);
2113 NETIEVENT_SOCKET_HANDLE_TYPE(udpcancel);
2114 
2115 NETIEVENT_SOCKET_QUOTA_TYPE(tcpaccept);
2116 
2117 NETIEVENT_TYPE(pause);
2118 NETIEVENT_TYPE(resume);
2119 NETIEVENT_TYPE(shutdown);
2120 NETIEVENT_TYPE(stop);
2121 
2122 NETIEVENT_TASK_TYPE(task);
2123 NETIEVENT_TASK_TYPE(privilegedtask);
2124 
2125 NETIEVENT_SOCKET_TLSCTX_TYPE(settlsctx);
2126 NETIEVENT_SOCKET_TYPE(sockstop);
2127 
2128 /* Now declared the helper functions */
2129 
2130 NETIEVENT_SOCKET_DECL(close);
2131 NETIEVENT_SOCKET_DECL(tcpclose);
2132 NETIEVENT_SOCKET_DECL(tcplisten);
2133 NETIEVENT_SOCKET_DECL(tcppauseread);
2134 NETIEVENT_SOCKET_DECL(tcpstartread);
2135 NETIEVENT_SOCKET_DECL(tcpstop);
2136 NETIEVENT_SOCKET_DECL(tlsclose);
2137 NETIEVENT_SOCKET_DECL(tlsconnect);
2138 NETIEVENT_SOCKET_DECL(tlsdobio);
2139 NETIEVENT_SOCKET_DECL(tlsstartread);
2140 NETIEVENT_SOCKET_HANDLE_DECL(tlscancel);
2141 NETIEVENT_SOCKET_DECL(udpclose);
2142 NETIEVENT_SOCKET_DECL(udplisten);
2143 NETIEVENT_SOCKET_DECL(udpread);
2144 NETIEVENT_SOCKET_DECL(udpsend);
2145 NETIEVENT_SOCKET_DECL(udpstop);
2146 
2147 NETIEVENT_SOCKET_DECL(tcpdnsclose);
2148 NETIEVENT_SOCKET_DECL(tcpdnsread);
2149 NETIEVENT_SOCKET_DECL(tcpdnsstop);
2150 NETIEVENT_SOCKET_DECL(tcpdnslisten);
2151 NETIEVENT_SOCKET_REQ_DECL(tcpdnsconnect);
2152 NETIEVENT_SOCKET_REQ_DECL(tcpdnssend);
2153 NETIEVENT_SOCKET_HANDLE_DECL(tcpdnscancel);
2154 NETIEVENT_SOCKET_QUOTA_DECL(tcpdnsaccept);
2155 
2156 NETIEVENT_SOCKET_DECL(tlsdnsclose);
2157 NETIEVENT_SOCKET_DECL(tlsdnsread);
2158 NETIEVENT_SOCKET_DECL(tlsdnsstop);
2159 NETIEVENT_SOCKET_DECL(tlsdnsshutdown);
2160 NETIEVENT_SOCKET_DECL(tlsdnslisten);
2161 NETIEVENT_SOCKET_REQ_DECL(tlsdnsconnect);
2162 NETIEVENT_SOCKET_REQ_DECL(tlsdnssend);
2163 NETIEVENT_SOCKET_HANDLE_DECL(tlsdnscancel);
2164 NETIEVENT_SOCKET_QUOTA_DECL(tlsdnsaccept);
2165 NETIEVENT_SOCKET_DECL(tlsdnscycle);
2166 
2167 #ifdef HAVE_LIBNGHTTP2
2168 NETIEVENT_SOCKET_REQ_DECL(httpsend);
2169 NETIEVENT_SOCKET_DECL(httpclose);
2170 NETIEVENT_SOCKET_HTTP_EPS_DECL(httpendpoints);
2171 #endif /* HAVE_LIBNGHTTP2 */
2172 
2173 NETIEVENT_SOCKET_REQ_DECL(tcpconnect);
2174 NETIEVENT_SOCKET_REQ_DECL(tcpsend);
2175 NETIEVENT_SOCKET_REQ_DECL(tlssend);
2176 NETIEVENT_SOCKET_REQ_DECL(udpconnect);
2177 
2178 NETIEVENT_SOCKET_REQ_DECL(routeconnect);
2179 
2180 NETIEVENT_SOCKET_REQ_RESULT_DECL(connectcb);
2181 NETIEVENT_SOCKET_REQ_RESULT_DECL(readcb);
2182 NETIEVENT_SOCKET_REQ_RESULT_DECL(sendcb);
2183 
2184 NETIEVENT_SOCKET_HANDLE_DECL(udpcancel);
2185 NETIEVENT_SOCKET_HANDLE_DECL(tcpcancel);
2186 NETIEVENT_SOCKET_DECL(detach);
2187 
2188 NETIEVENT_SOCKET_QUOTA_DECL(tcpaccept);
2189 
2190 NETIEVENT_DECL(pause);
2191 NETIEVENT_DECL(resume);
2192 NETIEVENT_DECL(shutdown);
2193 NETIEVENT_DECL(stop);
2194 
2195 NETIEVENT_TASK_DECL(task);
2196 NETIEVENT_TASK_DECL(privilegedtask);
2197 
2198 NETIEVENT_SOCKET_TLSCTX_DECL(settlsctx);
2199 NETIEVENT_SOCKET_DECL(sockstop);
2200 
2201 void
2202 isc__nm_udp_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result);
2203 void
2204 isc__nm_tcp_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result);
2205 void
2206 isc__nm_tcpdns_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result);
2207 void
2208 isc__nm_tlsdns_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result,
2209 			      bool async);
2210 
2211 isc_result_t
2212 isc__nm_tcpdns_processbuffer(isc_nmsocket_t *sock);
2213 isc_result_t
2214 isc__nm_tlsdns_processbuffer(isc_nmsocket_t *sock);
2215 
2216 isc__nm_uvreq_t *
2217 isc__nm_get_read_req(isc_nmsocket_t *sock, isc_sockaddr_t *sockaddr);
2218 
2219 void
2220 isc__nm_alloc_cb(uv_handle_t *handle, size_t size, uv_buf_t *buf);
2221 
2222 void
2223 isc__nm_udp_read_cb(uv_udp_t *handle, ssize_t nrecv, const uv_buf_t *buf,
2224 		    const struct sockaddr *addr, unsigned flags);
2225 void
2226 isc__nm_tcp_read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf);
2227 void
2228 isc__nm_tcpdns_read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf);
2229 void
2230 isc__nm_tlsdns_read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf);
2231 
2232 isc_result_t
2233 isc__nm_start_reading(isc_nmsocket_t *sock);
2234 void
2235 isc__nm_stop_reading(isc_nmsocket_t *sock);
2236 isc_result_t
2237 isc__nm_process_sock_buffer(isc_nmsocket_t *sock);
2238 void
2239 isc__nm_resume_processing(void *arg);
2240 bool
2241 isc__nmsocket_closing(isc_nmsocket_t *sock);
2242 bool
2243 isc__nm_closing(isc_nmsocket_t *sock);
2244 
2245 void
2246 isc__nm_alloc_dnsbuf(isc_nmsocket_t *sock, size_t len);
2247 
2248 void
2249 isc__nm_failed_send_cb(isc_nmsocket_t *sock, isc__nm_uvreq_t *req,
2250 		       isc_result_t eresult);
2251 void
2252 isc__nm_failed_accept_cb(isc_nmsocket_t *sock, isc_result_t eresult);
2253 void
2254 isc__nm_failed_connect_cb(isc_nmsocket_t *sock, isc__nm_uvreq_t *req,
2255 			  isc_result_t eresult, bool async);
2256 void
2257 isc__nm_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result, bool async);
2258 
2259 void
2260 isc__nm_accept_connection_log(isc_result_t result, bool can_log_quota);
2261 
2262 /*
2263  * Timeout callbacks
2264  */
2265 void
2266 isc__nmsocket_connecttimeout_cb(uv_timer_t *timer);
2267 void
2268 isc__nmsocket_readtimeout_cb(uv_timer_t *timer);
2269 void
2270 isc__nmsocket_writetimeout_cb(void *data, isc_result_t eresult);
2271 
2272 /*%<
2273  *
2274  * Maximum number of simultaneous handles in flight supported for a single
2275  * connected TCPDNS socket. This value was chosen arbitrarily, and may be
2276  * changed in the future.
2277  */
2278 #define STREAM_CLIENTS_PER_CONN 23
2279 
2280 #define UV_RUNTIME_CHECK(func, ret)                                      \
2281 	if (ret != 0) {                                                  \
2282 		FATAL_ERROR("%s failed: %s\n", #func, uv_strerror(ret)); \
2283 	}
2284 
2285 void
2286 isc__nmsocket_log_tls_session_reuse(isc_nmsocket_t *sock, isc_tls_t *tls);
2287