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