xref: /netbsd-src/external/mpl/bind/dist/lib/isc/netmgr/netmgr-int.h (revision bcda20f65a8566e103791ec395f7f499ef322704)
1 /*	$NetBSD: netmgr-int.h,v 1.13 2025/01/26 16:25:43 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 
20 #include <openssl/err.h>
21 #include <openssl/ssl.h>
22 
23 #include <isc/atomic.h>
24 #include <isc/barrier.h>
25 #include <isc/buffer.h>
26 #include <isc/condition.h>
27 #include <isc/dnsstream.h>
28 #include <isc/magic.h>
29 #include <isc/mem.h>
30 #include <isc/netmgr.h>
31 #include <isc/proxy2.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/tid.h>
41 #include <isc/time.h>
42 #include <isc/tls.h>
43 #include <isc/util.h>
44 #include <isc/uv.h>
45 
46 #include "../loop_p.h"
47 
48 #define ISC_NETMGR_TID_UNKNOWN -1
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 #define ISC_NETMGR_UDP_SENDBUF_SIZE UINT16_MAX
66 
67 /*
68  * The TCP send and receive buffers can fit one maximum sized DNS message plus
69  * its size, the receive buffer here affects TCP, DoT and DoH.
70  */
71 #define ISC_NETMGR_TCP_SENDBUF_SIZE (sizeof(uint16_t) + UINT16_MAX)
72 #define ISC_NETMGR_TCP_RECVBUF_SIZE (sizeof(uint16_t) + UINT16_MAX)
73 
74 /* Pick the larger buffer */
75 #define ISC_NETMGR_RECVBUF_SIZE                                     \
76 	(ISC_NETMGR_UDP_RECVBUF_SIZE >= ISC_NETMGR_TCP_RECVBUF_SIZE \
77 		 ? ISC_NETMGR_UDP_RECVBUF_SIZE                      \
78 		 : ISC_NETMGR_TCP_RECVBUF_SIZE)
79 
80 /*
81  * Make sure our RECVBUF size is large enough
82  */
83 
84 STATIC_ASSERT(ISC_NETMGR_UDP_RECVBUF_SIZE <= ISC_NETMGR_RECVBUF_SIZE,
85 	      "UDP receive buffer size must be smaller or equal than worker "
86 	      "receive buffer size");
87 
88 STATIC_ASSERT(ISC_NETMGR_TCP_RECVBUF_SIZE <= ISC_NETMGR_RECVBUF_SIZE,
89 	      "TCP receive buffer size must be smaller or equal than worker "
90 	      "receive buffer size");
91 
92 /*%
93  * Maximum outstanding DNS message that we process in a single TCP read.
94  */
95 #define ISC_NETMGR_MAX_STREAM_CLIENTS_PER_CONN 23
96 
97 /*%
98  * Regular TCP buffer size.
99  */
100 #define NM_REG_BUF 4096
101 
102 /*%
103  * Larger buffer for when the regular one isn't enough; this will
104  * hold two full DNS packets with lengths.  netmgr receives 64k at
105  * most in TCPDNS or TLSDNS connections, so there's no risk of overrun
106  * when using a buffer this size.
107  */
108 #define NM_BIG_BUF ISC_NETMGR_TCP_RECVBUF_SIZE * 2
109 
110 /*%
111  * Maximum segment size (MSS) of TCP socket on which the server responds to
112  * queries. Value lower than common MSS on Ethernet (1220, that is 1280 (IPv6
113  * minimum link MTU) - 40 (IPv6 fixed header) - 20 (TCP fixed header)) will
114  * address path MTU problem.
115  */
116 #define NM_MAXSEG (1280 - 20 - 40)
117 
118 /*%
119  * How many isc_nmhandles and isc_nm_uvreqs will we be
120  * caching for reuse in a socket.
121  */
122 #define ISC_NM_NMSOCKET_MAX  64
123 #define ISC_NM_NMHANDLES_MAX 64
124 #define ISC_NM_UVREQS_MAX    64
125 
126 /*% ISC_PROXY2_MIN_AF_UNIX_SIZE is the largest type when TLVs are not used */
127 #define ISC_NM_PROXY2_DEFAULT_BUFFER_SIZE (ISC_PROXY2_MIN_AF_UNIX_SIZE)
128 
129 /*
130  * Define ISC_NETMGR_TRACE to activate tracing of handles and sockets.
131  * This will impair performance but enables us to quickly determine,
132  * if netmgr resources haven't been cleaned up on shutdown, which ones
133  * are still in use.
134  */
135 #if ISC_NETMGR_TRACE
136 #define TRACE_SIZE 8
137 
138 #if defined(__linux__)
139 #include <syscall.h>
140 #define gettid() (uint64_t)syscall(SYS_gettid)
141 #elif defined(__FreeBSD__)
142 #include <pthread_np.h>
143 #define gettid() (uint64_t)(pthread_getthreadid_np())
144 #elif defined(__OpenBSD__)
145 #include <unistd.h>
146 #define gettid() (uint64_t)(getthrid())
147 #elif defined(__NetBSD__)
148 #include <lwp.h>
149 #define gettid() (uint64_t)(_lwp_self())
150 #elif defined(__DragonFly__)
151 #include <unistd.h>
152 #define gettid() (uint64_t)(lwp_gettid())
153 #else
154 #define gettid() (uint64_t)(pthread_self())
155 #endif
156 
157 #define NETMGR_TRACE_LOG(format, ...)                                \
158 	fprintf(stderr, "%" PRIu64 ":%d:%s:%u:%s:" format, gettid(), \
159 		isc_tid(), file, line, func, __VA_ARGS__)
160 
161 #define FLARG                                                                 \
162 	, const char *func ISC_ATTR_UNUSED, const char *file ISC_ATTR_UNUSED, \
163 		unsigned int line ISC_ATTR_UNUSED
164 
165 #define FLARG_PASS , func, file, line
166 #define isc__nm_uvreq_get(sock) \
167 	isc___nm_uvreq_get(sock, __func__, __FILE__, __LINE__)
168 #define isc__nm_uvreq_put(req) \
169 	isc___nm_uvreq_put(req, __func__, __FILE__, __LINE__)
170 #define isc__nmsocket_init(sock, mgr, type, iface, parent)            \
171 	isc___nmsocket_init(sock, mgr, type, iface, parent, __func__, \
172 			    __FILE__, __LINE__)
173 #define isc__nmsocket_put(sockp) \
174 	isc___nmsocket_put(sockp, __func__, __FILE__, __LINE__)
175 #define isc__nmsocket_attach(sock, target) \
176 	isc___nmsocket_attach(sock, target, __func__, __FILE__, __LINE__)
177 #define isc__nmsocket_detach(socketp) \
178 	isc___nmsocket_detach(socketp, __func__, __FILE__, __LINE__)
179 #define isc__nmsocket_close(socketp) \
180 	isc___nmsocket_close(socketp, __func__, __FILE__, __LINE__)
181 #define isc__nmhandle_get(sock, peer, local) \
182 	isc___nmhandle_get(sock, peer, local, __func__, __FILE__, __LINE__)
183 #define isc__nmsocket_prep_destroy(sock) \
184 	isc___nmsocket_prep_destroy(sock, __func__, __FILE__, __LINE__)
185 #define isc__nm_get_read_req(sock, sockaddr) \
186 	isc___nm_get_read_req(sock, sockaddr, __func__, __FILE__, __LINE__)
187 #else
188 #define NETMGR_TRACE_LOG(format, ...)
189 
190 #define FLARG
191 #define FLARG_PASS
192 #define isc__nm_uvreq_get(sock) isc___nm_uvreq_get(sock)
193 #define isc__nm_uvreq_put(req)	isc___nm_uvreq_put(req)
194 #define isc__nmsocket_init(sock, mgr, type, iface, parent) \
195 	isc___nmsocket_init(sock, mgr, type, iface, parent)
196 #define isc__nmsocket_put(sockp)	   isc___nmsocket_put(sockp)
197 #define isc__nmsocket_attach(sock, target) isc___nmsocket_attach(sock, target)
198 #define isc__nmsocket_detach(socketp)	   isc___nmsocket_detach(socketp)
199 #define isc__nmsocket_close(socketp)	   isc___nmsocket_close(socketp)
200 #define isc__nmhandle_get(sock, peer, local) \
201 	isc___nmhandle_get(sock, peer, local)
202 #define isc__nmsocket_prep_destroy(sock) isc___nmsocket_prep_destroy(sock)
203 #define isc__nm_get_read_req(sock, sockaddr) \
204 	isc___nm_get_read_req(sock, sockaddr)
205 #endif
206 
207 typedef struct isc__nm_uvreq isc__nm_uvreq_t;
208 
209 /*
210  * Single network event loop worker.
211  */
212 typedef struct isc__networker {
213 	isc_mem_t *mctx;
214 	isc_refcount_t references;
215 	isc_loop_t *loop;
216 	isc_nm_t *netmgr;
217 	bool shuttingdown;
218 
219 	char *recvbuf;
220 	bool recvbuf_inuse;
221 
222 	ISC_LIST(isc_nmsocket_t) active_sockets;
223 
224 	isc_mempool_t *nmsocket_pool;
225 	isc_mempool_t *uvreq_pool;
226 } isc__networker_t;
227 
228 ISC_REFCOUNT_DECL(isc__networker);
229 
230 #ifdef ISC_NETMGR_TRACE
231 void
232 isc__nm_dump_active(isc__networker_t *worker);
233 
234 void
235 isc__nm_dump_active_manager(isc_nm_t *netmgr);
236 #endif /* ISC_NETMGR_TRACE */
237 
238 /*
239  * A general handle for a connection bound to a networker.  For UDP
240  * connections we have peer address here, so both TCP and UDP can be
241  * handled with a simple send-like function
242  */
243 #define NMHANDLE_MAGIC ISC_MAGIC('N', 'M', 'H', 'D')
244 #define VALID_NMHANDLE(t)                      \
245 	(ISC_MAGIC_VALID(t, NMHANDLE_MAGIC) && \
246 	 atomic_load(&(t)->references) > 0)
247 
248 typedef void (*isc__nm_closecb)(isc_nmhandle_t *);
249 typedef struct isc_nm_http_session isc_nm_http_session_t;
250 
251 struct isc_nmhandle {
252 	int magic;
253 	isc_refcount_t references;
254 
255 	/*
256 	 * The socket is not 'attached' in the traditional
257 	 * reference-counting sense. Instead, we keep all handles in an
258 	 * array in the socket object.  This way, we don't have circular
259 	 * dependencies and we can close all handles when we're destroying
260 	 * the socket.
261 	 */
262 	isc_nmsocket_t *sock;
263 
264 	isc_nm_http_session_t *httpsession;
265 
266 	isc_sockaddr_t peer;
267 	isc_sockaddr_t local;
268 	bool proxy_is_unspec;
269 	struct isc_nmhandle *proxy_udphandle;
270 	isc_nm_opaquecb_t doreset; /* reset extra callback, external */
271 	isc_nm_opaquecb_t dofree;  /* free extra callback, external */
272 #if ISC_NETMGR_TRACE
273 	void *backtrace[TRACE_SIZE];
274 	int backtrace_size;
275 #endif
276 	LINK(isc_nmhandle_t) active_link;
277 	LINK(isc_nmhandle_t) inactive_link;
278 
279 	void *opaque;
280 
281 	isc_job_t job;
282 };
283 
284 typedef union {
285 	isc_nm_recv_cb_t recv;
286 	isc_nm_cb_t send;
287 	isc_nm_cb_t connect;
288 } isc__nm_cb_t;
289 
290 /*
291  * Wrapper around uv_req_t with 'our' fields in it.  req->data should
292  * always point to its parent.  Note that we always allocate more than
293  * sizeof(struct) because we make room for different req types;
294  */
295 #define UVREQ_MAGIC    ISC_MAGIC('N', 'M', 'U', 'R')
296 #define VALID_UVREQ(t) ISC_MAGIC_VALID(t, UVREQ_MAGIC)
297 
298 typedef struct isc__nm_uvreq isc__nm_uvreq_t;
299 struct isc__nm_uvreq {
300 	int magic;
301 	isc_nmsocket_t *sock;
302 	isc_nmhandle_t *handle;
303 	char tcplen[2];	       /* The TCP DNS message length */
304 	uv_buf_t uvbuf;	       /* translated isc_region_t, to be
305 				* sent or received */
306 	isc_sockaddr_t local;  /* local address */
307 	isc_sockaddr_t peer;   /* peer address */
308 	isc__nm_cb_t cb;       /* callback */
309 	void *cbarg;	       /* callback argument */
310 	isc_nm_timer_t *timer; /* TCP write timer */
311 	int connect_tries;     /* connect retries */
312 	isc_result_t result;
313 
314 	union {
315 		uv_handle_t handle;
316 		uv_write_t write;
317 		uv_connect_t connect;
318 		uv_udp_send_t udp_send;
319 	} uv_req;
320 	ISC_LINK(isc__nm_uvreq_t) link;
321 	ISC_LINK(isc__nm_uvreq_t) active_link;
322 
323 	isc_job_t job;
324 };
325 
326 /*
327  * Network manager
328  */
329 #define NM_MAGIC    ISC_MAGIC('N', 'E', 'T', 'M')
330 #define VALID_NM(t) ISC_MAGIC_VALID(t, NM_MAGIC)
331 
332 struct isc_nm {
333 	int magic;
334 	isc_refcount_t references;
335 	isc_mem_t *mctx;
336 	isc_loopmgr_t *loopmgr;
337 	uint32_t nloops;
338 	isc__networker_t *workers;
339 
340 	isc_stats_t *stats;
341 
342 	atomic_uint_fast32_t maxudp;
343 
344 	bool load_balance_sockets;
345 
346 	/*
347 	 * Active connections are being closed and new connections are
348 	 * no longer allowed.
349 	 */
350 	atomic_bool shuttingdown;
351 
352 	/*
353 	 * Timeout values for TCP connections, corresponding to
354 	 * tcp-intiial-timeout, tcp-idle-timeout, tcp-keepalive-timeout,
355 	 * and tcp-advertised-timeout. Note that these are stored in
356 	 * milliseconds so they can be used directly with the libuv timer,
357 	 * but they are configured in tenths of seconds.
358 	 */
359 	atomic_uint_fast32_t init;
360 	atomic_uint_fast32_t idle;
361 	atomic_uint_fast32_t keepalive;
362 	atomic_uint_fast32_t advertised;
363 
364 	/*
365 	 * Socket SO_RCVBUF and SO_SNDBUF values
366 	 */
367 	atomic_int_fast32_t recv_udp_buffer_size;
368 	atomic_int_fast32_t send_udp_buffer_size;
369 	atomic_int_fast32_t recv_tcp_buffer_size;
370 	atomic_int_fast32_t send_tcp_buffer_size;
371 };
372 
373 /*%
374  * A universal structure for either a single socket or a group of
375  * dup'd/SO_REUSE_PORT-using sockets listening on the same interface.
376  */
377 #define NMSOCK_MAGIC	ISC_MAGIC('N', 'M', 'S', 'K')
378 #define VALID_NMSOCK(t) ISC_MAGIC_VALID(t, NMSOCK_MAGIC)
379 
380 /*%
381  * Index into socket stat counter arrays.
382  */
383 typedef enum {
384 	STATID_OPEN = 0,
385 	STATID_OPENFAIL = 1,
386 	STATID_CLOSE = 2,
387 	STATID_BINDFAIL = 3,
388 	STATID_CONNECTFAIL = 4,
389 	STATID_CONNECT = 5,
390 	STATID_ACCEPTFAIL = 6,
391 	STATID_ACCEPT = 7,
392 	STATID_SENDFAIL = 8,
393 	STATID_RECVFAIL = 9,
394 	STATID_ACTIVE = 10,
395 	STATID_CLIENTS = 11,
396 	STATID_MAX = 12,
397 } isc__nm_statid_t;
398 
399 typedef struct isc_nmsocket_tls_send_req {
400 	isc_nmsocket_t *tlssock;
401 	isc_buffer_t data;
402 	isc_nm_cb_t cb;
403 	void *cbarg;
404 	isc_nmhandle_t *handle;
405 	bool finish;
406 	uint8_t smallbuf[512];
407 } isc_nmsocket_tls_send_req_t;
408 
409 #if HAVE_LIBNGHTTP2
410 
411 typedef enum isc_http_request_type {
412 	ISC_HTTP_REQ_GET,
413 	ISC_HTTP_REQ_POST,
414 	ISC_HTTP_REQ_UNSUPPORTED
415 } isc_http_request_type_t;
416 
417 typedef enum isc_http_scheme_type {
418 	ISC_HTTP_SCHEME_HTTP,
419 	ISC_HTTP_SCHEME_HTTP_SECURE,
420 	ISC_HTTP_SCHEME_UNSUPPORTED
421 } isc_http_scheme_type_t;
422 
423 typedef struct isc_nm_httphandler {
424 	int magic;
425 	char *path;
426 	isc_nm_recv_cb_t cb;
427 	void *cbarg;
428 	LINK(struct isc_nm_httphandler) link;
429 } isc_nm_httphandler_t;
430 
431 struct isc_nm_http_endpoints {
432 	uint32_t magic;
433 	isc_mem_t *mctx;
434 
435 	ISC_LIST(isc_nm_httphandler_t) handlers;
436 
437 	isc_refcount_t references;
438 	atomic_bool in_use;
439 };
440 
441 typedef struct isc_nmsocket_h2 {
442 	isc_nmsocket_t *psock; /* owner of the structure */
443 	char *request_path;
444 	char *query_data;
445 	size_t query_data_len;
446 	bool query_too_large;
447 
448 	isc_buffer_t rbuf;
449 	isc_buffer_t wbuf;
450 
451 	int32_t stream_id;
452 	isc_nm_http_session_t *session;
453 
454 	/* maximum concurrent streams (server-side) */
455 	atomic_uint_fast32_t max_concurrent_streams;
456 
457 	uint32_t min_ttl; /* used to set "max-age" in responses */
458 
459 	isc_http_request_type_t request_type;
460 	isc_http_scheme_type_t request_scheme;
461 
462 	size_t content_length;
463 	char clenbuf[128];
464 
465 	char cache_control_buf[128];
466 
467 	int headers_error_code;
468 	size_t headers_data_processed;
469 
470 	isc_nm_recv_cb_t cb;
471 	void *cbarg;
472 	LINK(struct isc_nmsocket_h2) link;
473 
474 	isc_nm_http_endpoints_t **listener_endpoints;
475 	size_t n_listener_endpoints;
476 
477 	isc_nm_http_endpoints_t *peer_endpoints;
478 
479 	bool response_submitted;
480 	struct {
481 		char *uri;
482 		bool post;
483 		isc_tlsctx_t *tlsctx;
484 		isc_sockaddr_t local_interface;
485 		void *cstream;
486 		const char *tls_peer_verify_string;
487 	} connect;
488 } isc_nmsocket_h2_t;
489 #endif /* HAVE_LIBNGHTTP2 */
490 
491 typedef void (*isc_nm_closehandlecb_t)(void *arg);
492 /*%<
493  * Opaque callback function, used for isc_nmhandle 'reset' and 'free'
494  * callbacks.
495  */
496 
497 struct isc_nmsocket {
498 	/*% Unlocked, RO */
499 	int magic;
500 	uint32_t tid;
501 	isc_refcount_t references;
502 	isc_nmsocket_type type;
503 	isc__networker_t *worker;
504 
505 	isc_barrier_t listen_barrier;
506 	isc_barrier_t stop_barrier;
507 
508 	/*% Parent socket for multithreaded listeners */
509 	isc_nmsocket_t *parent;
510 
511 	/*% TLS stuff */
512 	struct tlsstream {
513 		bool server;
514 		BIO *bio_in;
515 		BIO *bio_out;
516 		isc_tls_t *tls;
517 		isc_tlsctx_t *ctx;
518 		isc_tlsctx_t **listener_tls_ctx; /*%< A context reference per
519 						    worker */
520 		size_t n_listener_tls_ctx;
521 		isc_tlsctx_client_session_cache_t *client_sess_cache;
522 		bool client_session_saved;
523 		isc_nmsocket_t *tlslistener;
524 		isc_nmsocket_t *tlssocket;
525 		atomic_bool result_updated;
526 		enum {
527 			TLS_INIT,
528 			TLS_HANDSHAKE,
529 			TLS_IO,
530 			TLS_CLOSED
531 		} state; /*%< The order of these is significant */
532 		size_t nsending;
533 		bool tcp_nodelay_value;
534 		isc_nmsocket_tls_send_req_t *send_req; /*%< Send req to reuse */
535 		bool reading;
536 	} tlsstream;
537 
538 #if HAVE_LIBNGHTTP2
539 	isc_nmsocket_h2_t *h2;
540 #endif /* HAVE_LIBNGHTTP2 */
541 
542 	struct {
543 		isc_dnsstream_assembler_t *input;
544 		bool reading;
545 		isc_nmsocket_t *listener;
546 		isc_nmsocket_t *sock;
547 		size_t nsending;
548 		void *send_req;
549 		bool dot_alpn_negotiated;
550 		const char *tls_verify_error;
551 	} streamdns;
552 
553 	struct {
554 		isc_nmsocket_t *sock;
555 		bool reading;
556 		size_t nsending;
557 		void *send_req;
558 		union {
559 			isc_proxy2_handler_t *handler; /* server */
560 			isc_buffer_t *outbuf;	       /* client */
561 		} proxy2;
562 		bool header_processed;
563 		bool extra_processed; /* data arrived past header processed */
564 		isc_nmsocket_t **udp_server_socks; /* UDP sockets */
565 		size_t udp_server_socks_num;
566 	} proxy;
567 
568 	/*%
569 	 * pquota is a non-attached pointer to the TCP client quota, stored in
570 	 * listening sockets.
571 	 */
572 	isc_quota_t *pquota;
573 	isc_job_t quotacb;
574 
575 	/*%
576 	 * Socket statistics
577 	 */
578 	const isc_statscounter_t *statsindex;
579 
580 	/*%
581 	 * TCP read/connect timeout timers.
582 	 */
583 	uv_timer_t read_timer;
584 	uint64_t read_timeout;
585 	uint64_t connect_timeout;
586 
587 	/*%
588 	 * TCP write timeout timer.
589 	 */
590 	uint64_t write_timeout;
591 
592 	/*
593 	 * Reading was throttled over TCP as the peer does not read the
594 	 * data we are sending back.
595 	 */
596 	bool reading_throttled;
597 
598 	/*% outer socket is for 'wrapped' sockets - e.g. tcpdns in tcp */
599 	isc_nmsocket_t *outer;
600 
601 	/*% server socket for connections */
602 	isc_nmsocket_t *server;
603 
604 	/*% client socket for connections */
605 	isc_nmsocket_t *listener;
606 
607 	/*% Child sockets for multi-socket setups */
608 	isc_nmsocket_t *children;
609 	uint_fast32_t nchildren;
610 	isc_sockaddr_t iface;
611 	isc_nmhandle_t *statichandle;
612 	isc_nmhandle_t *outerhandle;
613 
614 	/*% TCP backlog */
615 	int backlog;
616 
617 	/*% libuv data */
618 	uv_os_sock_t fd;
619 	union uv_any_handle uv_handle;
620 
621 	/*% Peer address */
622 	isc_sockaddr_t peer;
623 
624 	/*%
625 	 * Socket is active if it's listening, working, etc. If it's
626 	 * closing, then it doesn't make a sense, for example, to
627 	 * push handles or reqs for reuse.
628 	 */
629 	bool active;
630 	bool destroying;
631 
632 	bool route_sock;
633 
634 	/*%
635 	 * Socket is closed if it's not active and all the possible
636 	 * callbacks were fired, there are no active handles, etc.
637 	 * If active==false but closed==false, that means the socket
638 	 * is closing.
639 	 */
640 	bool closing;
641 	bool closed;
642 	bool connecting;
643 	bool connected;
644 	bool accepting;
645 	bool reading;
646 	bool timedout;
647 
648 	/*%
649 	 * A timestamp of when the connection acceptance was delayed due
650 	 * to quota.
651 	 */
652 	isc_nanosecs_t quota_accept_ts;
653 
654 	/*%
655 	 * Established an outgoing connection, as client not server.
656 	 */
657 	bool client;
658 
659 	/*%
660 	 * The socket is processing read callback, this is guard to not read
661 	 * data before the readcb is back.
662 	 */
663 	bool processing;
664 
665 	/*%
666 	 * A TCP or TCPDNS socket has been set to use the keepalive
667 	 * timeout instead of the default idle timeout.
668 	 */
669 	bool keepalive;
670 
671 	/*%
672 	 * 'spare' handles for that can be reused to avoid allocations, for UDP.
673 	 */
674 	ISC_LIST(isc_nmhandle_t) inactive_handles;
675 
676 	size_t inactive_handles_cur;
677 	size_t inactive_handles_max;
678 
679 	/*%
680 	 * 'active' handles and uvreqs, mostly for debugging purposes.
681 	 */
682 	ISC_LIST(isc_nmhandle_t) active_handles;
683 	ISC_LIST(isc__nm_uvreq_t) active_uvreqs;
684 
685 	size_t active_handles_cur;
686 	size_t active_handles_max;
687 
688 	/*%
689 	 * Used to pass a result back from listen or connect events.
690 	 */
691 	isc_result_t result;
692 
693 	/*%
694 	 * This function will be called with handle->sock
695 	 * as the argument whenever a handle's references drop
696 	 * to zero, after its reset callback has been called.
697 	 */
698 	isc_nm_closehandlecb_t closehandle_cb;
699 
700 	isc_nmhandle_t *recv_handle;
701 	isc_nm_recv_cb_t recv_cb;
702 	void *recv_cbarg;
703 
704 	isc_nm_cb_t connect_cb;
705 	void *connect_cbarg;
706 
707 	isc_nm_accept_cb_t accept_cb;
708 	void *accept_cbarg;
709 
710 	bool barriers_initialised;
711 	bool manual_read_timer;
712 #if ISC_NETMGR_TRACE
713 	void *backtrace[TRACE_SIZE];
714 	int backtrace_size;
715 #endif
716 	LINK(isc_nmsocket_t) active_link;
717 
718 	isc_job_t job;
719 };
720 
721 void
722 isc__nm_free_uvbuf(isc_nmsocket_t *sock, const uv_buf_t *buf);
723 /*%<
724  * Free a buffer allocated for a receive operation.
725  *
726  * Note that as currently implemented, this doesn't actually
727  * free anything, marks the isc__networker's UDP receive buffer
728  * as "not in use".
729  */
730 
731 isc_nmhandle_t *
732 isc___nmhandle_get(isc_nmsocket_t *sock, isc_sockaddr_t const *peer,
733 		   isc_sockaddr_t const *local FLARG);
734 /*%<
735  * Get a handle for the socket 'sock', allocating a new one
736  * if there isn't one available in 'sock->inactivehandles'.
737  *
738  * If 'peer' is not NULL, set the handle's peer address to 'peer',
739  * otherwise set it to 'sock->peer'.
740  *
741  * If 'local' is not NULL, set the handle's local address to 'local',
742  * otherwise set it to 'sock->iface->addr'.
743  *
744  * 'sock' will be attached to 'handle->sock'. The caller may need
745  * to detach the socket afterward.
746  */
747 
748 isc__nm_uvreq_t *
749 isc___nm_uvreq_get(isc_nmsocket_t *sock FLARG);
750 /*%<
751  * Get a UV request structure for the socket 'sock', allocating a
752  * new one if there isn't one available in 'sock->inactivereqs'.
753  */
754 
755 void
756 isc___nm_uvreq_put(isc__nm_uvreq_t **req FLARG);
757 /*%<
758  * Completes the use of a UV request structure, setting '*req' to NULL.
759  *
760  * The UV request is pushed onto the 'sock->inactivereqs' stack or,
761  * if that doesn't work, freed.
762  */
763 
764 void
765 isc___nmsocket_init(isc_nmsocket_t *sock, isc__networker_t *worker,
766 		    isc_nmsocket_type type, isc_sockaddr_t *iface,
767 		    isc_nmsocket_t *parent FLARG);
768 /*%<
769  * Initialize socket 'sock', attach it to 'mgr', and set it to type 'type'
770  * and its interface to 'iface'.
771  */
772 
773 void
774 isc___nmsocket_attach(isc_nmsocket_t *sock, isc_nmsocket_t **target FLARG);
775 /*%<
776  * Attach to a socket, increasing refcount
777  */
778 
779 void
780 isc___nmsocket_detach(isc_nmsocket_t **socketp FLARG);
781 /*%<
782  * Detach from socket, decreasing refcount and possibly destroying the
783  * socket if it's no longer referenced.
784  */
785 
786 void
787 isc___nmsocket_prep_destroy(isc_nmsocket_t *sock FLARG);
788 /*%<
789  * Market 'sock' as inactive, close it if necessary, and destroy it
790  * if there are no remaining references or active handles.
791  */
792 
793 void
794 isc__nmsocket_shutdown(isc_nmsocket_t *sock);
795 /*%<
796  * Initiate the socket shutdown which actively calls the active
797  * callbacks.
798  */
799 
800 void
801 isc__nmsocket_reset(isc_nmsocket_t *sock);
802 /*%<
803  * Reset and close the socket.
804  */
805 
806 bool
807 isc__nmsocket_active(isc_nmsocket_t *sock);
808 /*%<
809  * Determine whether 'sock' is active by checking 'sock->active'
810  * or, for child sockets, 'sock->parent->active'.
811  */
812 
813 void
814 isc__nmsocket_clearcb(isc_nmsocket_t *sock);
815 /*%<
816  * Clear the recv and accept callbacks in 'sock'.
817  */
818 
819 void
820 isc__nmsocket_timer_stop(isc_nmsocket_t *sock);
821 void
822 isc__nmsocket_timer_start(isc_nmsocket_t *sock);
823 void
824 isc__nmsocket_timer_restart(isc_nmsocket_t *sock);
825 bool
826 isc__nmsocket_timer_running(isc_nmsocket_t *sock);
827 /*%<
828  * Start/stop/restart/check the timeout on the socket
829  */
830 
831 void
832 isc__nm_connectcb(isc_nmsocket_t *sock, isc__nm_uvreq_t *uvreq,
833 		  isc_result_t eresult, bool async);
834 
835 void
836 isc__nm_readcb(isc_nmsocket_t *sock, isc__nm_uvreq_t *uvreq,
837 	       isc_result_t eresult, bool async);
838 /*%<
839  * Issue a read callback on the socket, used to call the callback
840  * on failed conditions when the event can't be scheduled on the uv loop.
841  *
842  */
843 
844 void
845 isc__nm_sendcb(isc_nmsocket_t *sock, isc__nm_uvreq_t *uvreq,
846 	       isc_result_t eresult, bool async);
847 /*%<
848  * Issue a write callback on the socket, used to call the callback
849  * on failed conditions when the event can't be scheduled on the uv loop.
850  */
851 
852 void
853 isc__nm_udp_send(isc_nmhandle_t *handle, const isc_region_t *region,
854 		 isc_nm_cb_t cb, void *cbarg);
855 /*%<
856  * Back-end implementation of isc_nm_send() for UDP handles.
857  */
858 
859 void
860 isc__nm_udp_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg);
861 /*
862  * Back-end implementation of isc_nm_read() for UDP handles.
863  */
864 
865 void
866 isc__nm_udp_close(isc_nmsocket_t *sock);
867 /*%<
868  * Close a UDP socket.
869  */
870 
871 void
872 isc__nm_udp_shutdown(isc_nmsocket_t *sock);
873 /*%<
874  * Called during the shutdown process to close and clean up connected
875  * sockets.
876  */
877 
878 void
879 isc__nm_udp_stoplistening(isc_nmsocket_t *sock);
880 /*%<
881  * Stop listening on 'sock'.
882  */
883 
884 void
885 isc__nm_udp_settimeout(isc_nmhandle_t *handle, uint32_t timeout);
886 /*%<
887  * Set or clear the recv timeout for the UDP socket associated with 'handle'.
888  */
889 
890 void
891 isc__nm_tcp_send(isc_nmhandle_t *handle, const isc_region_t *region,
892 		 isc_nm_cb_t cb, void *cbarg);
893 /*%<
894  * Back-end implementation of isc_nm_send() for TCP handles.
895  */
896 
897 void
898 isc__nm_tcp_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg);
899 /*
900  * Start reading on this handle.
901  */
902 
903 void
904 isc__nm_tcp_close(isc_nmsocket_t *sock);
905 /*%<
906  * Close a TCP socket.
907  */
908 void
909 isc__nm_tcp_read_stop(isc_nmhandle_t *handle);
910 /*%<
911  * Stop reading on this handle.
912  */
913 
914 void
915 isc__nm_tcp_shutdown(isc_nmsocket_t *sock);
916 /*%<
917  * Called during the shutdown process to close and clean up connected
918  * sockets.
919  */
920 
921 void
922 isc__nm_tcp_stoplistening(isc_nmsocket_t *sock);
923 /*%<
924  * Stop listening on 'sock'.
925  */
926 
927 void
928 isc__nm_tcp_settimeout(isc_nmhandle_t *handle, uint32_t timeout);
929 /*%<
930  * Set the read timeout for the TCP socket associated with 'handle'.
931  */
932 
933 void
934 isc__nmhandle_tcp_set_manual_timer(isc_nmhandle_t *handle, const bool manual);
935 
936 void
937 isc__nm_tcp_senddns(isc_nmhandle_t *handle, const isc_region_t *region,
938 		    isc_nm_cb_t cb, void *cbarg);
939 /*%<
940  * The same as 'isc__nm_tcp_send()', but with data length sent
941  * ahead of data (two bytes (16 bit) in big-endian format).
942  */
943 
944 void
945 isc__nm_tls_send(isc_nmhandle_t *handle, const isc_region_t *region,
946 		 isc_nm_cb_t cb, void *cbarg);
947 
948 /*%<
949  * Back-end implementation of isc_nm_send() for TLSDNS handles.
950  */
951 
952 void
953 isc__nm_tls_senddns(isc_nmhandle_t *handle, const isc_region_t *region,
954 		    isc_nm_cb_t cb, void *cbarg);
955 /*%<
956  * The same as 'isc__nm_tls_send()', but with data length sent
957  * ahead of data (two bytes (16 bit) in big-endian format).
958  */
959 
960 void
961 isc__nm_tls_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg);
962 /*%<
963  * Start reading on the TLS handle.
964  */
965 
966 void
967 isc__nm_tls_close(isc_nmsocket_t *sock);
968 /*%<
969  * Close a TLS socket.
970  */
971 
972 void
973 isc__nm_tls_read_stop(isc_nmhandle_t *handle);
974 /*%<
975  * Stop reading on the TLS handle.
976  */
977 
978 void
979 isc__nm_tls_cleanup_data(isc_nmsocket_t *sock);
980 
981 void
982 isc__nm_tls_stoplistening(isc_nmsocket_t *sock);
983 
984 void
985 isc__nm_tls_settimeout(isc_nmhandle_t *handle, uint32_t timeout);
986 void
987 isc__nm_tls_cleartimeout(isc_nmhandle_t *handle);
988 /*%<
989  * Set the read timeout and reset the timer for the socket
990  * associated with 'handle', and the TCP socket it wraps
991  * around.
992  */
993 
994 void
995 isc__nmsocket_tls_reset(isc_nmsocket_t *sock);
996 
997 void
998 isc__nmhandle_tls_set_manual_timer(isc_nmhandle_t *handle, const bool manual);
999 
1000 const char *
1001 isc__nm_tls_verify_tls_peer_result_string(const isc_nmhandle_t *handle);
1002 
1003 void
1004 isc__nmhandle_tls_keepalive(isc_nmhandle_t *handle, bool value);
1005 /*%<
1006  * Set the keepalive value on the underlying TCP handle.
1007  */
1008 
1009 void
1010 isc__nm_async_tls_set_tlsctx(isc_nmsocket_t *listener, isc_tlsctx_t *tlsctx,
1011 			     const int tid);
1012 
1013 void
1014 isc__nmhandle_tls_setwritetimeout(isc_nmhandle_t *handle,
1015 				  uint64_t write_timeout);
1016 
1017 bool
1018 isc__nmsocket_tls_timer_running(isc_nmsocket_t *sock);
1019 
1020 void
1021 isc__nmsocket_tls_timer_restart(isc_nmsocket_t *sock);
1022 
1023 void
1024 isc__nmsocket_tls_timer_stop(isc_nmsocket_t *sock);
1025 
1026 void
1027 isc__nm_tls_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result,
1028 			   bool async);
1029 
1030 void
1031 isc__nmhandle_tls_get_selected_alpn(isc_nmhandle_t *handle,
1032 				    const unsigned char **alpn,
1033 				    unsigned int *alpnlen);
1034 
1035 isc_result_t
1036 isc__nmhandle_tls_set_tcp_nodelay(isc_nmhandle_t *handle, const bool value);
1037 
1038 #if HAVE_LIBNGHTTP2
1039 
1040 void
1041 isc__nm_http_stoplistening(isc_nmsocket_t *sock);
1042 
1043 void
1044 isc__nm_http_settimeout(isc_nmhandle_t *handle, uint32_t timeout);
1045 void
1046 isc__nm_http_cleartimeout(isc_nmhandle_t *handle);
1047 /*%<
1048  * Set the read timeout and reset the timer for the socket
1049  * associated with 'handle', and the TLS/TCP socket it wraps
1050  * around.
1051  */
1052 
1053 void
1054 isc__nmhandle_http_keepalive(isc_nmhandle_t *handle, bool value);
1055 /*%<
1056  * Set the keepalive value on the underlying session handle
1057  */
1058 
1059 void
1060 isc__nm_http_cleanup_data(isc_nmsocket_t *sock);
1061 
1062 isc_result_t
1063 isc__nm_http_request(isc_nmhandle_t *handle, isc_region_t *region,
1064 		     isc_nm_recv_cb_t reply_cb, void *cbarg);
1065 
1066 void
1067 isc__nm_http_send(isc_nmhandle_t *handle, const isc_region_t *region,
1068 		  isc_nm_cb_t cb, void *cbarg);
1069 
1070 void
1071 isc__nm_http_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg);
1072 
1073 void
1074 isc__nm_http_close(isc_nmsocket_t *sock);
1075 
1076 void
1077 isc__nm_http_bad_request(isc_nmhandle_t *handle);
1078 /*%<
1079  * Respond to the request with 400 "Bad Request" status.
1080  *
1081  * Requires:
1082  * \li 'handle' is a valid HTTP netmgr handle object, referencing a server-side
1083  * socket
1084  */
1085 
1086 bool
1087 isc__nm_http_has_encryption(const isc_nmhandle_t *handle);
1088 
1089 void
1090 isc__nm_http_set_maxage(isc_nmhandle_t *handle, const uint32_t ttl);
1091 
1092 const char *
1093 isc__nm_http_verify_tls_peer_result_string(const isc_nmhandle_t *handle);
1094 
1095 bool
1096 isc__nm_parse_httpquery(const char *query_string, const char **start,
1097 			size_t *len);
1098 
1099 char *
1100 isc__nm_base64url_to_base64(isc_mem_t *mem, const char *base64url,
1101 			    const size_t base64url_len, size_t *res_len);
1102 
1103 char *
1104 isc__nm_base64_to_base64url(isc_mem_t *mem, const char *base64,
1105 			    const size_t base64_len, size_t *res_len);
1106 
1107 void
1108 isc__nm_httpsession_attach(isc_nm_http_session_t *source,
1109 			   isc_nm_http_session_t **targetp);
1110 void
1111 isc__nm_httpsession_detach(isc_nm_http_session_t **sessionp);
1112 
1113 isc_nmhandle_t *
1114 isc__nm_httpsession_handle(isc_nm_http_session_t *session);
1115 
1116 void
1117 isc__nm_http_set_tlsctx(isc_nmsocket_t *sock, isc_tlsctx_t *tlsctx);
1118 
1119 void
1120 isc__nm_http_set_max_streams(isc_nmsocket_t *listener,
1121 			     const uint32_t max_concurrent_streams);
1122 
1123 #endif
1124 
1125 void
1126 isc__nm_streamdns_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb,
1127 		       void *cbarg);
1128 
1129 void
1130 isc__nm_streamdns_send(isc_nmhandle_t *handle, const isc_region_t *region,
1131 		       isc_nm_cb_t cb, void *cbarg);
1132 
1133 void
1134 isc__nm_streamdns_close(isc_nmsocket_t *sock);
1135 
1136 void
1137 isc__nm_streamdns_stoplistening(isc_nmsocket_t *sock);
1138 
1139 void
1140 isc__nm_streamdns_cleanup_data(isc_nmsocket_t *sock);
1141 
1142 void
1143 isc__nmhandle_streamdns_cleartimeout(isc_nmhandle_t *handle);
1144 
1145 void
1146 isc__nmhandle_streamdns_settimeout(isc_nmhandle_t *handle, uint32_t timeout);
1147 
1148 void
1149 isc__nmhandle_streamdns_keepalive(isc_nmhandle_t *handle, bool value);
1150 
1151 void
1152 isc__nmhandle_streamdns_setwritetimeout(isc_nmhandle_t *handle,
1153 					uint32_t timeout);
1154 
1155 bool
1156 isc__nm_streamdns_has_encryption(const isc_nmhandle_t *handle);
1157 
1158 const char *
1159 isc__nm_streamdns_verify_tls_peer_result_string(const isc_nmhandle_t *handle);
1160 
1161 void
1162 isc__nm_streamdns_set_tlsctx(isc_nmsocket_t *listener, isc_tlsctx_t *tlsctx);
1163 
1164 isc_result_t
1165 isc__nm_streamdns_xfr_checkperm(isc_nmsocket_t *sock);
1166 
1167 void
1168 isc__nmsocket_streamdns_reset(isc_nmsocket_t *sock);
1169 
1170 bool
1171 isc__nmsocket_streamdns_timer_running(isc_nmsocket_t *sock);
1172 
1173 void
1174 isc__nmsocket_streamdns_timer_stop(isc_nmsocket_t *sock);
1175 
1176 void
1177 isc__nmsocket_streamdns_timer_restart(isc_nmsocket_t *sock);
1178 
1179 void
1180 isc__nm_streamdns_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result,
1181 				 bool async);
1182 
1183 bool
1184 isc__nm_valid_proxy_addresses(const isc_sockaddr_t *src,
1185 			      const isc_sockaddr_t *dst);
1186 
1187 void
1188 isc__nm_proxystream_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result,
1189 				   bool async);
1190 
1191 void
1192 isc__nm_proxystream_stoplistening(isc_nmsocket_t *sock);
1193 
1194 void
1195 isc__nm_proxystream_cleanup_data(isc_nmsocket_t *sock);
1196 
1197 void
1198 isc__nmhandle_proxystream_cleartimeout(isc_nmhandle_t *handle);
1199 
1200 void
1201 isc__nmhandle_proxystream_settimeout(isc_nmhandle_t *handle, uint32_t timeout);
1202 
1203 void
1204 isc__nmhandle_proxystream_keepalive(isc_nmhandle_t *handle, bool value);
1205 
1206 void
1207 isc__nmhandle_proxystream_setwritetimeout(isc_nmhandle_t *handle,
1208 					  uint64_t write_timeout);
1209 
1210 void
1211 isc__nmsocket_proxystream_reset(isc_nmsocket_t *sock);
1212 
1213 bool
1214 isc__nmsocket_proxystream_timer_running(isc_nmsocket_t *sock);
1215 
1216 void
1217 isc__nmsocket_proxystream_timer_restart(isc_nmsocket_t *sock);
1218 
1219 void
1220 isc__nmsocket_proxystream_timer_stop(isc_nmsocket_t *sock);
1221 
1222 void
1223 isc__nmhandle_proxystream_set_manual_timer(isc_nmhandle_t *handle,
1224 					   const bool manual);
1225 
1226 isc_result_t
1227 isc__nmhandle_proxystream_set_tcp_nodelay(isc_nmhandle_t *handle,
1228 					  const bool value);
1229 
1230 void
1231 isc__nm_proxystream_read_stop(isc_nmhandle_t *handle);
1232 
1233 void
1234 isc__nm_proxystream_close(isc_nmsocket_t *sock);
1235 
1236 void
1237 isc__nm_proxystream_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb,
1238 			 void *cbarg);
1239 
1240 void
1241 isc__nm_proxystream_send(isc_nmhandle_t *handle, isc_region_t *region,
1242 			 isc_nm_cb_t cb, void *cbarg);
1243 
1244 void
1245 isc__nm_proxystream_senddns(isc_nmhandle_t *handle, isc_region_t *region,
1246 			    isc_nm_cb_t cb, void *cbarg);
1247 
1248 void
1249 isc__nm_proxystream_set_tlsctx(isc_nmsocket_t *listener, isc_tlsctx_t *tlsctx);
1250 
1251 bool
1252 isc__nm_proxystream_has_encryption(const isc_nmhandle_t *handle);
1253 
1254 const char *
1255 isc__nm_proxystream_verify_tls_peer_result_string(const isc_nmhandle_t *handle);
1256 
1257 void
1258 isc__nmhandle_proxystream_get_selected_alpn(isc_nmhandle_t *handle,
1259 					    const unsigned char **alpn,
1260 					    unsigned int *alpnlen);
1261 
1262 void
1263 isc__nm_proxyudp_failed_read_cb(isc_nmsocket_t *sock, const isc_result_t result,
1264 				const bool async);
1265 
1266 void
1267 isc__nm_proxyudp_stoplistening(isc_nmsocket_t *listener);
1268 
1269 void
1270 isc__nm_proxyudp_cleanup_data(isc_nmsocket_t *sock);
1271 
1272 void
1273 isc__nmhandle_proxyudp_cleartimeout(isc_nmhandle_t *handle);
1274 
1275 void
1276 isc__nmhandle_proxyudp_settimeout(isc_nmhandle_t *handle, uint32_t timeout);
1277 
1278 void
1279 isc__nmhandle_proxyudp_setwritetimeout(isc_nmhandle_t *handle,
1280 				       uint64_t write_timeout);
1281 
1282 bool
1283 isc__nmsocket_proxyudp_timer_running(isc_nmsocket_t *sock);
1284 
1285 void
1286 isc__nmsocket_proxyudp_timer_restart(isc_nmsocket_t *sock);
1287 
1288 void
1289 isc__nmsocket_proxyudp_timer_stop(isc_nmsocket_t *sock);
1290 
1291 void
1292 isc__nm_proxyudp_close(isc_nmsocket_t *sock);
1293 
1294 void
1295 isc__nm_proxyudp_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg);
1296 
1297 void
1298 isc__nm_proxyudp_send(isc_nmhandle_t *handle, isc_region_t *region,
1299 		      isc_nm_cb_t cb, void *cbarg);
1300 
1301 void
1302 isc__nm_incstats(isc_nmsocket_t *sock, isc__nm_statid_t id);
1303 /*%<
1304  * Increment socket-related statistics counters.
1305  */
1306 
1307 void
1308 isc__nm_decstats(isc_nmsocket_t *sock, isc__nm_statid_t id);
1309 /*%<
1310  * Decrement socket-related statistics counters.
1311  */
1312 
1313 isc_result_t
1314 isc__nm_socket(int domain, int type, int protocol, uv_os_sock_t *sockp);
1315 /*%<
1316  * Platform independent socket() version
1317  */
1318 
1319 void
1320 isc__nm_closesocket(uv_os_sock_t sock);
1321 /*%<
1322  * Platform independent closesocket() version
1323  */
1324 
1325 isc_result_t
1326 isc__nm_socket_reuse(uv_os_sock_t fd, int val);
1327 /*%<
1328  * Set the SO_REUSEADDR or SO_REUSEPORT (or equivalent) socket option on the fd
1329  */
1330 
1331 isc_result_t
1332 isc__nm_socket_reuse_lb(uv_os_sock_t fd);
1333 /*%<
1334  * Set the SO_REUSEPORT_LB (or equivalent) socket option on the fd
1335  */
1336 
1337 isc_result_t
1338 isc__nm_socket_disable_pmtud(uv_os_sock_t fd, sa_family_t sa_family);
1339 /*%<
1340  * Disable the Path MTU Discovery, either by disabling IP(V6)_DONTFRAG socket
1341  * option, or setting the IP(V6)_MTU_DISCOVER socket option to IP_PMTUDISC_OMIT
1342  */
1343 
1344 isc_result_t
1345 isc__nm_socket_v6only(uv_os_sock_t fd, sa_family_t sa_family);
1346 /*%<
1347  * Restrict the socket to sending and receiving IPv6 packets only
1348  */
1349 
1350 isc_result_t
1351 isc__nm_socket_connectiontimeout(uv_os_sock_t fd, int timeout_ms);
1352 /*%<
1353  * Set the connection timeout in milliseconds, on non-Linux platforms,
1354  * the minimum value must be at least 1000 (1 second).
1355  */
1356 
1357 isc_result_t
1358 isc__nm_socket_tcp_nodelay(const uv_os_sock_t fd, bool value);
1359 /*%<
1360  * Disables/Enables Nagle's algorithm on a TCP socket (sets TCP_NODELAY if
1361  * 'value' equals 'true' or vice versa).
1362  */
1363 
1364 isc_result_t
1365 isc__nm_socket_tcp_maxseg(uv_os_sock_t fd, int size);
1366 /*%<
1367  * Set the TCP maximum segment size
1368  */
1369 
1370 isc_result_t
1371 isc__nm_socket_min_mtu(uv_os_sock_t fd, sa_family_t sa_family);
1372 /*%<
1373  * Use minimum MTU on IPv6 sockets
1374  */
1375 
1376 void
1377 isc__nm_set_network_buffers(isc_nm_t *nm, uv_handle_t *handle);
1378 /*%>
1379  * Sets the pre-configured network buffers size on the handle.
1380  */
1381 
1382 void
1383 isc__nmsocket_barrier_init(isc_nmsocket_t *listener);
1384 /*%>
1385  * Initialise the socket synchronisation barrier according to the
1386  * number of children.
1387  */
1388 
1389 void
1390 isc__nmsocket_stop(isc_nmsocket_t *listener);
1391 /*%>
1392  * Broadcast "stop" event for a listener socket across all workers and
1393  * wait its processing completion - then, stop and close the underlying
1394  * transport listener socket.
1395  *
1396  * The primitive is used in multi-layer transport listener sockets to
1397  * implement shutdown properly: after the broadcasted events has been
1398  * processed it is safe to destroy the shared data within the listener
1399  * socket (including shutting down the underlying transport listener
1400  * socket).
1401  */
1402 
1403 void
1404 isc__nm_udp_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result,
1405 			   bool async);
1406 void
1407 isc__nm_tcp_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result,
1408 			   bool async);
1409 
1410 isc__nm_uvreq_t *
1411 isc___nm_get_read_req(isc_nmsocket_t *sock, isc_sockaddr_t *sockaddr FLARG);
1412 
1413 void
1414 isc__nm_alloc_cb(uv_handle_t *handle, size_t size, uv_buf_t *buf);
1415 
1416 void
1417 isc__nm_udp_read_cb(uv_udp_t *handle, ssize_t nrecv, const uv_buf_t *buf,
1418 		    const struct sockaddr *addr, unsigned int flags);
1419 void
1420 isc__nm_tcp_read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf);
1421 
1422 isc_result_t
1423 isc__nm_start_reading(isc_nmsocket_t *sock);
1424 void
1425 isc__nm_stop_reading(isc_nmsocket_t *sock);
1426 bool
1427 isc__nmsocket_closing(isc_nmsocket_t *sock);
1428 bool
1429 isc__nm_closing(isc__networker_t *worker);
1430 
1431 void
1432 isc__nm_failed_send_cb(isc_nmsocket_t *sock, isc__nm_uvreq_t *req,
1433 		       isc_result_t eresult, bool async);
1434 void
1435 isc__nm_failed_connect_cb(isc_nmsocket_t *sock, isc__nm_uvreq_t *req,
1436 			  isc_result_t eresult, bool async);
1437 void
1438 isc__nm_failed_read_cb(isc_nmsocket_t *sock, isc_result_t result, bool async);
1439 
1440 void
1441 isc__nm_accept_connection_log(isc_nmsocket_t *sock, isc_result_t result,
1442 			      bool can_log_quota);
1443 
1444 /*
1445  * Timeout callbacks
1446  */
1447 void
1448 isc__nmsocket_connecttimeout_cb(uv_timer_t *timer);
1449 void
1450 isc__nmsocket_readtimeout_cb(uv_timer_t *timer);
1451 void
1452 isc__nmsocket_writetimeout_cb(void *data, isc_result_t eresult);
1453 
1454 /*
1455  * Bind to the socket, but allow binding to IPv6 tentative addresses reported by
1456  * the route socket by setting IP_FREEBIND (or equivalent).
1457  */
1458 int
1459 isc__nm_udp_freebind(uv_udp_t *handle, const struct sockaddr *addr,
1460 		     unsigned int flags);
1461 
1462 int
1463 isc__nm_tcp_freebind(uv_tcp_t *handle, const struct sockaddr *addr,
1464 		     unsigned int flags);
1465 
1466 void
1467 isc__nmsocket_log_tls_session_reuse(isc_nmsocket_t *sock, isc_tls_t *tls);
1468 
1469 /*
1470  * Logging helpers
1471  */
1472 void
1473 isc__netmgr_log(const isc_nm_t *netmgr, int level, const char *fmt, ...)
1474 	ISC_FORMAT_PRINTF(3, 4);
1475 void
1476 isc__nmsocket_log(const isc_nmsocket_t *sock, int level, const char *fmt, ...)
1477 	ISC_FORMAT_PRINTF(3, 4);
1478 void
1479 isc__nmhandle_log(const isc_nmhandle_t *handle, int level, const char *fmt, ...)
1480 	ISC_FORMAT_PRINTF(3, 4);
1481 
1482 void
1483 isc__nm_received_proxy_header_log(isc_nmhandle_t *handle,
1484 				  const isc_proxy2_command_t cmd,
1485 				  const int socktype,
1486 				  const isc_sockaddr_t *restrict src_addr,
1487 				  const isc_sockaddr_t *restrict dst_addr,
1488 				  const isc_region_t *restrict tlvs);
1489 
1490 void
1491 isc__nmhandle_set_manual_timer(isc_nmhandle_t *handle, const bool manual);
1492 /*
1493  * Set manual read timer control mode - so that it will not get reset
1494  * automatically on read nor get started when read is initiated.
1495  */
1496 
1497 void
1498 isc__nmhandle_get_selected_alpn(isc_nmhandle_t *handle,
1499 				const unsigned char **alpn,
1500 				unsigned int *alpnlen);
1501 /*
1502  * Returns a non zero terminated ALPN identifier via 'alpn'. The
1503  * length of the identifier is returned via 'alpnlen'. If after the
1504  * call either 'alpn == NULL' or 'alpnlen == 0', then identifier was
1505  * not negotiated of the underlying protocol of the connection
1506  * represented via the given handle does not support ALPN.
1507  */
1508 
1509 void
1510 isc__nm_senddns(isc_nmhandle_t *handle, isc_region_t *region, isc_nm_cb_t cb,
1511 		void *cbarg);
1512 /*%<
1513  * The same as 'isc_nm_send()', but with data length sent
1514  * ahead of data (two bytes (16 bit) in big-endian format).
1515  */
1516