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