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