1ae8c6e27Sflorian /* 2ae8c6e27Sflorian * util/netevent.h - event notification 3ae8c6e27Sflorian * 4ae8c6e27Sflorian * Copyright (c) 2007, NLnet Labs. All rights reserved. 5ae8c6e27Sflorian * 6ae8c6e27Sflorian * This software is open source. 7ae8c6e27Sflorian * 8ae8c6e27Sflorian * Redistribution and use in source and binary forms, with or without 9ae8c6e27Sflorian * modification, are permitted provided that the following conditions 10ae8c6e27Sflorian * are met: 11ae8c6e27Sflorian * 12ae8c6e27Sflorian * Redistributions of source code must retain the above copyright notice, 13ae8c6e27Sflorian * this list of conditions and the following disclaimer. 14ae8c6e27Sflorian * 15ae8c6e27Sflorian * Redistributions in binary form must reproduce the above copyright notice, 16ae8c6e27Sflorian * this list of conditions and the following disclaimer in the documentation 17ae8c6e27Sflorian * and/or other materials provided with the distribution. 18ae8c6e27Sflorian * 19ae8c6e27Sflorian * Neither the name of the NLNET LABS nor the names of its contributors may 20ae8c6e27Sflorian * be used to endorse or promote products derived from this software without 21ae8c6e27Sflorian * specific prior written permission. 22ae8c6e27Sflorian * 23ae8c6e27Sflorian * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24ae8c6e27Sflorian * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25ae8c6e27Sflorian * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26ae8c6e27Sflorian * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27ae8c6e27Sflorian * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28ae8c6e27Sflorian * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29ae8c6e27Sflorian * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30ae8c6e27Sflorian * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31ae8c6e27Sflorian * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32ae8c6e27Sflorian * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33ae8c6e27Sflorian * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34ae8c6e27Sflorian */ 35ae8c6e27Sflorian 36ae8c6e27Sflorian /** 37ae8c6e27Sflorian * \file 38ae8c6e27Sflorian * 39ae8c6e27Sflorian * This file contains event notification functions. 40ae8c6e27Sflorian * 41ae8c6e27Sflorian * There are three types of communication points 42ae8c6e27Sflorian * o UDP socket - perthread buffer. 43ae8c6e27Sflorian * o TCP-accept socket - array of TCP-sockets, socketcount. 44ae8c6e27Sflorian * o TCP socket - own buffer, parent-TCPaccept, read/write state, 45ae8c6e27Sflorian * number of bytes read/written, timeout. 46ae8c6e27Sflorian * 47ae8c6e27Sflorian * There are sockets aimed towards our clients and towards the internet. 48ae8c6e27Sflorian * o frontside - aimed towards our clients, queries come in, answers back. 49ae8c6e27Sflorian * o behind - aimed towards internet, to the authoritative DNS servers. 50ae8c6e27Sflorian * 51ae8c6e27Sflorian * Several event types are available: 52ae8c6e27Sflorian * o comm_base - for thread safety of the comm points, one per thread. 53ae8c6e27Sflorian * o comm_point - udp and tcp networking, with callbacks. 54ae8c6e27Sflorian * o comm_timer - a timeout with callback. 55ae8c6e27Sflorian * o comm_signal - callbacks when signal is caught. 56ae8c6e27Sflorian * o comm_reply - holds reply info during networking callback. 57ae8c6e27Sflorian * 58ae8c6e27Sflorian */ 59ae8c6e27Sflorian 60ae8c6e27Sflorian #ifndef NET_EVENT_H 61ae8c6e27Sflorian #define NET_EVENT_H 62ae8c6e27Sflorian 63d500c338Sflorian #include <sys/time.h> 64ae8c6e27Sflorian #include "dnscrypt/dnscrypt.h" 65f4f0f0ceSflorian #ifdef HAVE_NGHTTP2_NGHTTP2_H 66f4f0f0ceSflorian #include <nghttp2/nghttp2.h> 67f4f0f0ceSflorian #endif 68ae8c6e27Sflorian 69ae8c6e27Sflorian struct sldns_buffer; 70ae8c6e27Sflorian struct comm_point; 71ae8c6e27Sflorian struct comm_reply; 72ae8c6e27Sflorian struct tcl_list; 73ae8c6e27Sflorian struct ub_event_base; 74411c5950Sflorian struct unbound_socket; 75ae8c6e27Sflorian 76f4f0f0ceSflorian struct mesh_state; 77f4f0f0ceSflorian struct mesh_area; 78f4f0f0ceSflorian 79ae8c6e27Sflorian /* internal event notification data storage structure. */ 80ae8c6e27Sflorian struct internal_event; 81ae8c6e27Sflorian struct internal_base; 82ae8c6e27Sflorian struct internal_timer; /* A sub struct of the comm_timer super struct */ 83ae8c6e27Sflorian 84f4f0f0ceSflorian enum listen_type; 85f4f0f0ceSflorian 86ae8c6e27Sflorian /** callback from communication point function type */ 87ae8c6e27Sflorian typedef int comm_point_callback_type(struct comm_point*, void*, int, 88ae8c6e27Sflorian struct comm_reply*); 89ae8c6e27Sflorian 90ae8c6e27Sflorian /** to pass no_error to callback function */ 91ae8c6e27Sflorian #define NETEVENT_NOERROR 0 92ae8c6e27Sflorian /** to pass closed connection to callback function */ 93ae8c6e27Sflorian #define NETEVENT_CLOSED -1 94ae8c6e27Sflorian /** to pass timeout happened to callback function */ 95ae8c6e27Sflorian #define NETEVENT_TIMEOUT -2 96ae8c6e27Sflorian /** to pass fallback from capsforID to callback function; 0x20 failed */ 97ae8c6e27Sflorian #define NETEVENT_CAPSFAIL -3 98ae8c6e27Sflorian /** to pass done transfer to callback function; http file is complete */ 99ae8c6e27Sflorian #define NETEVENT_DONE -4 100853e076fSflorian /** to pass write of the write packet is done to callback function 101853e076fSflorian * used when tcp_write_and_read is enabled */ 102853e076fSflorian #define NETEVENT_PKT_WRITTEN -5 103ae8c6e27Sflorian 104ae8c6e27Sflorian /** timeout to slow accept calls when not possible, in msec. */ 105ae8c6e27Sflorian #define NETEVENT_SLOW_ACCEPT_TIME 2000 1065c45b740Sflorian /** timeout to slow down log print, so it does not spam the logs, in sec */ 1075c45b740Sflorian #define SLOW_LOG_TIME 10 108ae8c6e27Sflorian 109ae8c6e27Sflorian /** 110ae8c6e27Sflorian * A communication point dispatcher. Thread specific. 111ae8c6e27Sflorian */ 112ae8c6e27Sflorian struct comm_base { 113ae8c6e27Sflorian /** behind the scenes structure. with say libevent info. alloced */ 114ae8c6e27Sflorian struct internal_base* eb; 115ae8c6e27Sflorian /** callback to stop listening on accept sockets, 116ae8c6e27Sflorian * performed when accept() will not function properly */ 117ae8c6e27Sflorian void (*stop_accept)(void*); 118ae8c6e27Sflorian /** callback to start listening on accept sockets, performed 119ae8c6e27Sflorian * after stop_accept() then a timeout has passed. */ 120ae8c6e27Sflorian void (*start_accept)(void*); 121ae8c6e27Sflorian /** user argument for stop_accept and start_accept functions */ 122ae8c6e27Sflorian void* cb_arg; 123ae8c6e27Sflorian }; 124ae8c6e27Sflorian 125ae8c6e27Sflorian /** 126ae8c6e27Sflorian * Reply information for a communication point. 127ae8c6e27Sflorian */ 128ae8c6e27Sflorian struct comm_reply { 129ae8c6e27Sflorian /** the comm_point with fd to send reply on to. */ 130ae8c6e27Sflorian struct comm_point* c; 131ae8c6e27Sflorian /** the address (for UDP based communication) */ 1325c45b740Sflorian struct sockaddr_storage remote_addr; 133ae8c6e27Sflorian /** length of address */ 1345c45b740Sflorian socklen_t remote_addrlen; 1355c45b740Sflorian /** return type 0 (none), 4(IP4), 6(IP6) 1365c45b740Sflorian * used only with listen_type_udp_ancil* */ 137ae8c6e27Sflorian int srctype; 138ae8c6e27Sflorian /* DnsCrypt context */ 139ae8c6e27Sflorian #ifdef USE_DNSCRYPT 140ae8c6e27Sflorian uint8_t client_nonce[crypto_box_HALF_NONCEBYTES]; 141ae8c6e27Sflorian uint8_t nmkey[crypto_box_BEFORENMBYTES]; 142ae8c6e27Sflorian const dnsccert *dnsc_cert; 143ae8c6e27Sflorian int is_dnscrypted; 144ae8c6e27Sflorian #endif 145ae8c6e27Sflorian /** the return source interface data */ 146ae8c6e27Sflorian union { 147ae8c6e27Sflorian #ifdef IPV6_PKTINFO 148ae8c6e27Sflorian struct in6_pktinfo v6info; 149ae8c6e27Sflorian #endif 150ae8c6e27Sflorian #ifdef IP_PKTINFO 151ae8c6e27Sflorian struct in_pktinfo v4info; 152ae8c6e27Sflorian #elif defined(IP_RECVDSTADDR) 153ae8c6e27Sflorian struct in_addr v4addr; 154ae8c6e27Sflorian #endif 155ae8c6e27Sflorian } 156ae8c6e27Sflorian /** variable with return source data */ 157ae8c6e27Sflorian pktinfo; 158ae8c6e27Sflorian /** max udp size for udp packets */ 159ae8c6e27Sflorian size_t max_udp_size; 1605c45b740Sflorian /* if set, the request came through a proxy */ 1615c45b740Sflorian int is_proxied; 1625c45b740Sflorian /** the client address 1635c45b740Sflorian * the same as remote_addr if not proxied */ 1645c45b740Sflorian struct sockaddr_storage client_addr; 1655c45b740Sflorian /** the original address length */ 1665c45b740Sflorian socklen_t client_addrlen; 167ae8c6e27Sflorian }; 168ae8c6e27Sflorian 169ae8c6e27Sflorian /** 170ae8c6e27Sflorian * Communication point to the network 171ae8c6e27Sflorian * These behaviours can be accomplished by setting the flags 172ae8c6e27Sflorian * and passing return values from the callback. 173ae8c6e27Sflorian * udp frontside: called after readdone. sendafter. 174ae8c6e27Sflorian * tcp frontside: called readdone, sendafter. close. 175ae8c6e27Sflorian * udp behind: called after readdone. No send after. 176ae8c6e27Sflorian * tcp behind: write done, read done, then called. No send after. 177ae8c6e27Sflorian */ 178ae8c6e27Sflorian struct comm_point { 179ae8c6e27Sflorian /** behind the scenes structure, with say libevent info. alloced. */ 180ae8c6e27Sflorian struct internal_event* ev; 181a8eaceedSflorian /** if the event is added or not */ 182a8eaceedSflorian int event_added; 183ae8c6e27Sflorian 184096314feSflorian /** Reference to struct that is part of the listening ports, 185096314feSflorian * where for listening ports information is kept about the address. */ 186411c5950Sflorian struct unbound_socket* socket; 187411c5950Sflorian 188ae8c6e27Sflorian /** file descriptor for communication point */ 189ae8c6e27Sflorian int fd; 190ae8c6e27Sflorian 191ae8c6e27Sflorian /** timeout (NULL if it does not). Malloced. */ 192ae8c6e27Sflorian struct timeval* timeout; 193ae8c6e27Sflorian 194ae8c6e27Sflorian /** buffer pointer. Either to perthread, or own buffer or NULL */ 195ae8c6e27Sflorian struct sldns_buffer* buffer; 196ae8c6e27Sflorian 197ae8c6e27Sflorian /* -------- TCP Handler -------- */ 198ae8c6e27Sflorian /** Read/Write state for TCP */ 199ae8c6e27Sflorian int tcp_is_reading; 200ae8c6e27Sflorian /** The current read/write count for TCP */ 201ae8c6e27Sflorian size_t tcp_byte_count; 202ae8c6e27Sflorian /** parent communication point (for TCP sockets) */ 203ae8c6e27Sflorian struct comm_point* tcp_parent; 204ae8c6e27Sflorian /** sockaddr from peer, for TCP handlers */ 205ae8c6e27Sflorian struct comm_reply repinfo; 206ae8c6e27Sflorian 207ae8c6e27Sflorian /* -------- TCP Accept -------- */ 208ae8c6e27Sflorian /** the number of TCP handlers for this tcp-accept socket */ 209ae8c6e27Sflorian int max_tcp_count; 210ae8c6e27Sflorian /** current number of tcp handler in-use for this accept socket */ 211ae8c6e27Sflorian int cur_tcp_count; 212ae8c6e27Sflorian /** malloced array of tcp handlers for a tcp-accept, 213ae8c6e27Sflorian of size max_tcp_count. */ 214ae8c6e27Sflorian struct comm_point** tcp_handlers; 215ae8c6e27Sflorian /** linked list of free tcp_handlers to use for new queries. 216ae8c6e27Sflorian For tcp_accept the first entry, for tcp_handlers the next one. */ 217ae8c6e27Sflorian struct comm_point* tcp_free; 218ae8c6e27Sflorian 219ae8c6e27Sflorian /* -------- SSL TCP DNS ------- */ 220ae8c6e27Sflorian /** the SSL object with rw bio (owned) or for commaccept ctx ref */ 221ae8c6e27Sflorian void* ssl; 222ae8c6e27Sflorian /** handshake state for init and renegotiate */ 223ae8c6e27Sflorian enum { 224ae8c6e27Sflorian /** no handshake, it has been done */ 225ae8c6e27Sflorian comm_ssl_shake_none = 0, 226ae8c6e27Sflorian /** ssl initial handshake wants to read */ 227ae8c6e27Sflorian comm_ssl_shake_read, 228ae8c6e27Sflorian /** ssl initial handshake wants to write */ 229ae8c6e27Sflorian comm_ssl_shake_write, 230ae8c6e27Sflorian /** ssl_write wants to read */ 231ae8c6e27Sflorian comm_ssl_shake_hs_read, 232ae8c6e27Sflorian /** ssl_read wants to write */ 233ae8c6e27Sflorian comm_ssl_shake_hs_write 234ae8c6e27Sflorian } ssl_shake_state; 235ae8c6e27Sflorian 236ae8c6e27Sflorian /* -------- HTTP ------- */ 237f4f0f0ceSflorian /** Do not allow connection to use HTTP version lower than this. 0=no 238f4f0f0ceSflorian * minimum. */ 239f4f0f0ceSflorian enum { 240f4f0f0ceSflorian http_version_none = 0, 241f4f0f0ceSflorian http_version_2 = 2 242f4f0f0ceSflorian } http_min_version; 243f4f0f0ceSflorian /** http endpoint */ 244f4f0f0ceSflorian char* http_endpoint; 245f4f0f0ceSflorian /* -------- HTTP/1.1 ------- */ 246ae8c6e27Sflorian /** Currently reading in http headers */ 247ae8c6e27Sflorian int http_in_headers; 248ae8c6e27Sflorian /** Currently reading in chunk headers, 0=not, 1=firstline, 2=unused 249ae8c6e27Sflorian * (more lines), 3=trailer headers after chunk */ 250ae8c6e27Sflorian int http_in_chunk_headers; 251ae8c6e27Sflorian /** chunked transfer */ 252ae8c6e27Sflorian int http_is_chunked; 253ae8c6e27Sflorian /** http temp buffer (shared buffer for temporary work) */ 254ae8c6e27Sflorian struct sldns_buffer* http_temp; 255ae8c6e27Sflorian /** http stored content in buffer */ 256ae8c6e27Sflorian size_t http_stored; 257f4f0f0ceSflorian /* -------- HTTP/2 ------- */ 258f4f0f0ceSflorian /** http2 session */ 259f4f0f0ceSflorian struct http2_session* h2_session; 260f4f0f0ceSflorian /** set to 1 if h2 is negotiated to be used (using alpn) */ 261f4f0f0ceSflorian int use_h2; 262f4f0f0ceSflorian /** stream currently being handled */ 263f4f0f0ceSflorian struct http2_stream* h2_stream; 264f4f0f0ceSflorian /** maximum allowed query buffer size, per stream */ 265f4f0f0ceSflorian size_t http2_stream_max_qbuffer_size; 266f4f0f0ceSflorian /** maximum number of HTTP/2 streams per connection. Send in HTTP/2 267f4f0f0ceSflorian * SETTINGS frame. */ 268f4f0f0ceSflorian uint32_t http2_max_streams; 269ae8c6e27Sflorian 270ae8c6e27Sflorian /* -------- dnstap ------- */ 271ae8c6e27Sflorian /** the dnstap environment */ 272ae8c6e27Sflorian struct dt_env* dtenv; 273ae8c6e27Sflorian 274ae8c6e27Sflorian /** is this a UDP, TCP-accept or TCP socket. */ 275ae8c6e27Sflorian enum comm_point_type { 276ae8c6e27Sflorian /** UDP socket - handle datagrams. */ 277ae8c6e27Sflorian comm_udp, 278ae8c6e27Sflorian /** TCP accept socket - only creates handlers if readable. */ 279ae8c6e27Sflorian comm_tcp_accept, 280ae8c6e27Sflorian /** TCP handler socket - handle byteperbyte readwrite. */ 281ae8c6e27Sflorian comm_tcp, 282ae8c6e27Sflorian /** HTTP handler socket */ 283ae8c6e27Sflorian comm_http, 284ae8c6e27Sflorian /** AF_UNIX socket - for internal commands. */ 285ae8c6e27Sflorian comm_local, 286ae8c6e27Sflorian /** raw - not DNS format - for pipe readers and writers */ 287ae8c6e27Sflorian comm_raw 288ae8c6e27Sflorian } 289ae8c6e27Sflorian /** variable with type of socket, UDP,TCP-accept,TCP,pipe */ 290ae8c6e27Sflorian type; 291ae8c6e27Sflorian 2925c45b740Sflorian /* -------- PROXYv2 ------- */ 2935c45b740Sflorian /** if set, PROXYv2 is expected on this connection */ 2945c45b740Sflorian int pp2_enabled; 2955c45b740Sflorian /** header state for the PROXYv2 header (for TCP) */ 2965c45b740Sflorian enum { 2975c45b740Sflorian /** no header encounter yet */ 2985c45b740Sflorian pp2_header_none = 0, 2995c45b740Sflorian /** read the static part of the header */ 3005c45b740Sflorian pp2_header_init, 3015c45b740Sflorian /** read the full header */ 3025c45b740Sflorian pp2_header_done 3035c45b740Sflorian } pp2_header_state; 3045c45b740Sflorian 305ae8c6e27Sflorian /* ---------- Behaviour ----------- */ 306ae8c6e27Sflorian /** if set the connection is NOT closed on delete. */ 307ae8c6e27Sflorian int do_not_close; 308ae8c6e27Sflorian 309ae8c6e27Sflorian /** if set, the connection is closed on error, on timeout, 310ae8c6e27Sflorian and after read/write completes. No callback is done. */ 311ae8c6e27Sflorian int tcp_do_close; 312ae8c6e27Sflorian 313853e076fSflorian /** flag that indicates the stream is both written and read from. */ 314853e076fSflorian int tcp_write_and_read; 315853e076fSflorian 316853e076fSflorian /** byte count for written length over write channel, for when 317853e076fSflorian * tcp_write_and_read is enabled. When tcp_write_and_read is enabled, 318853e076fSflorian * this is the counter for writing, the one for reading is in the 319853e076fSflorian * commpoint.buffer sldns buffer. The counter counts from 0 to 320853e076fSflorian * 2+tcp_write_pkt_len, and includes the tcp length bytes. */ 321853e076fSflorian size_t tcp_write_byte_count; 322853e076fSflorian 323853e076fSflorian /** packet to write currently over the write channel. for when 324853e076fSflorian * tcp_write_and_read is enabled. When tcp_write_and_read is enabled, 325853e076fSflorian * this is the buffer for the written packet, the commpoint.buffer 326853e076fSflorian * sldns buffer is the buffer for the received packet. */ 327853e076fSflorian uint8_t* tcp_write_pkt; 328853e076fSflorian /** length of tcp_write_pkt in bytes */ 329853e076fSflorian size_t tcp_write_pkt_len; 330853e076fSflorian 331853e076fSflorian /** if set try to read another packet again (over connection with 332853e076fSflorian * multiple packets), once set, tries once, then zero again, 333853e076fSflorian * so set it in the packet complete section. 334853e076fSflorian * The pointer itself has to be set before the callback is invoked, 335853e076fSflorian * when you set things up, and continue to exist also after the 336853e076fSflorian * commpoint is closed and deleted in your callback. So that after 337853e076fSflorian * the callback cleans up netevent can see what it has to do. 338853e076fSflorian * Or leave NULL if it is not used at all. */ 339853e076fSflorian int* tcp_more_read_again; 340853e076fSflorian 341853e076fSflorian /** if set try to write another packet (over connection with 342853e076fSflorian * multiple packets), once set, tries once, then zero again, 343853e076fSflorian * so set it in the packet complete section. 344853e076fSflorian * The pointer itself has to be set before the callback is invoked, 345853e076fSflorian * when you set things up, and continue to exist also after the 346853e076fSflorian * commpoint is closed and deleted in your callback. So that after 347853e076fSflorian * the callback cleans up netevent can see what it has to do. 348853e076fSflorian * Or leave NULL if it is not used at all. */ 349853e076fSflorian int* tcp_more_write_again; 350853e076fSflorian 351ae8c6e27Sflorian /** if set, read/write completes: 352ae8c6e27Sflorian read/write state of tcp is toggled. 353ae8c6e27Sflorian buffer reset/bytecount reset. 354ae8c6e27Sflorian this flag cleared. 355ae8c6e27Sflorian So that when that is done the callback is called. */ 356ae8c6e27Sflorian int tcp_do_toggle_rw; 357ae8c6e27Sflorian 358ae8c6e27Sflorian /** timeout in msec for TCP wait times for this connection */ 359ae8c6e27Sflorian int tcp_timeout_msec; 360ae8c6e27Sflorian 361ae8c6e27Sflorian /** if set, tcp keepalive is enabled on this connection */ 362ae8c6e27Sflorian int tcp_keepalive; 363ae8c6e27Sflorian 364ae8c6e27Sflorian /** if set, checks for pending error from nonblocking connect() call.*/ 365ae8c6e27Sflorian int tcp_check_nb_connect; 366ae8c6e27Sflorian 367ae8c6e27Sflorian /** if set, check for connection limit on tcp accept. */ 368ae8c6e27Sflorian struct tcl_list* tcp_conn_limit; 369ae8c6e27Sflorian /** the entry for the connection. */ 370ae8c6e27Sflorian struct tcl_addr* tcl_addr; 371ae8c6e27Sflorian 372e97c6e54Ssthen /** the structure to keep track of open requests on this channel */ 373e97c6e54Ssthen struct tcp_req_info* tcp_req_info; 374e97c6e54Ssthen 375ae8c6e27Sflorian #ifdef USE_MSG_FASTOPEN 376ae8c6e27Sflorian /** used to track if the sendto() call should be done when using TFO. */ 377ae8c6e27Sflorian int tcp_do_fastopen; 378ae8c6e27Sflorian #endif 379ae8c6e27Sflorian 380ae8c6e27Sflorian #ifdef USE_DNSCRYPT 381ae8c6e27Sflorian /** Is this a dnscrypt channel */ 382ae8c6e27Sflorian int dnscrypt; 383ae8c6e27Sflorian /** encrypted buffer pointer. Either to perthread, or own buffer or NULL */ 384ae8c6e27Sflorian struct sldns_buffer* dnscrypt_buffer; 385ae8c6e27Sflorian #endif 386ae8c6e27Sflorian /** number of queries outstanding on this socket, used by 387ae8c6e27Sflorian * outside network for udp ports */ 388ae8c6e27Sflorian int inuse; 389d500c338Sflorian /** the timestamp when the packet was received by the kernel */ 390d500c338Sflorian struct timeval recv_tv; 391ae8c6e27Sflorian /** callback when done. 392ae8c6e27Sflorian tcp_accept does not get called back, is NULL then. 393ae8c6e27Sflorian If a timeout happens, callback with timeout=1 is called. 394ae8c6e27Sflorian If an error happens, callback is called with error set 395ae8c6e27Sflorian nonzero. If not NETEVENT_NOERROR, it is an errno value. 396ae8c6e27Sflorian If the connection is closed (by remote end) then the 397ae8c6e27Sflorian callback is called with error set to NETEVENT_CLOSED=-1. 398ae8c6e27Sflorian If a timeout happens on the connection, the error is set to 399ae8c6e27Sflorian NETEVENT_TIMEOUT=-2. 400ae8c6e27Sflorian The reply_info can be copied if the reply needs to happen at a 401ae8c6e27Sflorian later time. It consists of a struct with commpoint and address. 402ae8c6e27Sflorian It can be passed to a msg send routine some time later. 403ae8c6e27Sflorian Note the reply information is temporary and must be copied. 404ae8c6e27Sflorian NULL is passed for_reply info, in cases where error happened. 405ae8c6e27Sflorian 406ae8c6e27Sflorian declare as: 407ae8c6e27Sflorian int my_callback(struct comm_point* c, void* my_arg, int error, 408ae8c6e27Sflorian struct comm_reply *reply_info); 409ae8c6e27Sflorian 410ae8c6e27Sflorian if the routine returns 0, nothing is done. 411ae8c6e27Sflorian Notzero, the buffer will be sent back to client. 412ae8c6e27Sflorian For UDP this is done without changing the commpoint. 413ae8c6e27Sflorian In TCP it sets write state. 414ae8c6e27Sflorian */ 415ae8c6e27Sflorian comm_point_callback_type* callback; 416ae8c6e27Sflorian /** argument to pass to callback. */ 417ae8c6e27Sflorian void *cb_arg; 418ae8c6e27Sflorian }; 419ae8c6e27Sflorian 420ae8c6e27Sflorian /** 421ae8c6e27Sflorian * Structure only for making timeout events. 422ae8c6e27Sflorian */ 423ae8c6e27Sflorian struct comm_timer { 424ae8c6e27Sflorian /** the internal event stuff (derived) */ 425ae8c6e27Sflorian struct internal_timer* ev_timer; 426ae8c6e27Sflorian 427ae8c6e27Sflorian /** callback function, takes user arg only */ 428ae8c6e27Sflorian void (*callback)(void*); 429ae8c6e27Sflorian 430ae8c6e27Sflorian /** callback user argument */ 431ae8c6e27Sflorian void* cb_arg; 432ae8c6e27Sflorian }; 433ae8c6e27Sflorian 434ae8c6e27Sflorian /** 435ae8c6e27Sflorian * Structure only for signal events. 436ae8c6e27Sflorian */ 437ae8c6e27Sflorian struct comm_signal { 438ae8c6e27Sflorian /** the communication base */ 439ae8c6e27Sflorian struct comm_base* base; 440ae8c6e27Sflorian 441ae8c6e27Sflorian /** the internal event stuff */ 442ae8c6e27Sflorian struct internal_signal* ev_signal; 443ae8c6e27Sflorian 444ae8c6e27Sflorian /** callback function, takes signal number and user arg */ 445ae8c6e27Sflorian void (*callback)(int, void*); 446ae8c6e27Sflorian 447ae8c6e27Sflorian /** callback user argument */ 448ae8c6e27Sflorian void* cb_arg; 449ae8c6e27Sflorian }; 450ae8c6e27Sflorian 451ae8c6e27Sflorian /** 452ae8c6e27Sflorian * Create a new comm base. 453ae8c6e27Sflorian * @param sigs: if true it attempts to create a default loop for 454ae8c6e27Sflorian * signal handling. 455ae8c6e27Sflorian * @return: the new comm base. NULL on error. 456ae8c6e27Sflorian */ 457ae8c6e27Sflorian struct comm_base* comm_base_create(int sigs); 458ae8c6e27Sflorian 459ae8c6e27Sflorian /** 460ae8c6e27Sflorian * Create comm base that uses the given ub_event_base (underlying pluggable 461ae8c6e27Sflorian * event mechanism pointer). 462ae8c6e27Sflorian * @param base: underlying pluggable event base. 463ae8c6e27Sflorian * @return: the new comm base. NULL on error. 464ae8c6e27Sflorian */ 465ae8c6e27Sflorian struct comm_base* comm_base_create_event(struct ub_event_base* base); 466ae8c6e27Sflorian 467ae8c6e27Sflorian /** 468ae8c6e27Sflorian * Delete comm base structure but not the underlying lib event base. 469ae8c6e27Sflorian * All comm points must have been deleted. 470ae8c6e27Sflorian * @param b: the base to delete. 471ae8c6e27Sflorian */ 472ae8c6e27Sflorian void comm_base_delete_no_base(struct comm_base* b); 473ae8c6e27Sflorian 474ae8c6e27Sflorian /** 475ae8c6e27Sflorian * Destroy a comm base. 476ae8c6e27Sflorian * All comm points must have been deleted. 477ae8c6e27Sflorian * @param b: the base to delete. 478ae8c6e27Sflorian */ 479ae8c6e27Sflorian void comm_base_delete(struct comm_base* b); 480ae8c6e27Sflorian 481ae8c6e27Sflorian /** 482ae8c6e27Sflorian * Obtain two pointers. The pointers never change (until base_delete()). 483ae8c6e27Sflorian * The pointers point to time values that are updated regularly. 484ae8c6e27Sflorian * @param b: the communication base that will update the time values. 485ae8c6e27Sflorian * @param tt: pointer to time in seconds is returned. 486ae8c6e27Sflorian * @param tv: pointer to time in microseconds is returned. 487ae8c6e27Sflorian */ 488ae8c6e27Sflorian void comm_base_timept(struct comm_base* b, time_t** tt, struct timeval** tv); 489ae8c6e27Sflorian 490ae8c6e27Sflorian /** 491ae8c6e27Sflorian * Dispatch the comm base events. 492ae8c6e27Sflorian * @param b: the communication to perform. 493ae8c6e27Sflorian */ 494ae8c6e27Sflorian void comm_base_dispatch(struct comm_base* b); 495ae8c6e27Sflorian 496ae8c6e27Sflorian /** 497ae8c6e27Sflorian * Exit from dispatch loop. 498ae8c6e27Sflorian * @param b: the communication base that is in dispatch(). 499ae8c6e27Sflorian */ 500ae8c6e27Sflorian void comm_base_exit(struct comm_base* b); 501ae8c6e27Sflorian 502ae8c6e27Sflorian /** 503ae8c6e27Sflorian * Set the slow_accept mode handlers. You can not provide these if you do 504ae8c6e27Sflorian * not perform accept() calls. 505ae8c6e27Sflorian * @param b: comm base 506ae8c6e27Sflorian * @param stop_accept: function that stops listening to accept fds. 507ae8c6e27Sflorian * @param start_accept: function that resumes listening to accept fds. 508ae8c6e27Sflorian * @param arg: callback arg to pass to the functions. 509ae8c6e27Sflorian */ 510ae8c6e27Sflorian void comm_base_set_slow_accept_handlers(struct comm_base* b, 511ae8c6e27Sflorian void (*stop_accept)(void*), void (*start_accept)(void*), void* arg); 512ae8c6e27Sflorian 513ae8c6e27Sflorian /** 514ae8c6e27Sflorian * Access internal data structure (for util/tube.c on windows) 515ae8c6e27Sflorian * @param b: comm base 516ae8c6e27Sflorian * @return ub_event_base. 517ae8c6e27Sflorian */ 518ae8c6e27Sflorian struct ub_event_base* comm_base_internal(struct comm_base* b); 519ae8c6e27Sflorian 520ae8c6e27Sflorian /** 521ae8c6e27Sflorian * Create an UDP comm point. Calls malloc. 522ae8c6e27Sflorian * setups the structure with the parameters you provide. 523ae8c6e27Sflorian * @param base: in which base to alloc the commpoint. 524ae8c6e27Sflorian * @param fd: file descriptor of open UDP socket. 525ae8c6e27Sflorian * @param buffer: shared buffer by UDP sockets from this thread. 5265c45b740Sflorian * @param pp2_enabled: if the comm point will support PROXYv2. 527ae8c6e27Sflorian * @param callback: callback function pointer. 528ae8c6e27Sflorian * @param callback_arg: will be passed to your callback function. 529411c5950Sflorian * @param socket: and opened socket properties will be passed to your callback function. 530ae8c6e27Sflorian * @return: returns the allocated communication point. NULL on error. 531ae8c6e27Sflorian * Sets timeout to NULL. Turns off TCP options. 532ae8c6e27Sflorian */ 533ae8c6e27Sflorian struct comm_point* comm_point_create_udp(struct comm_base* base, 5345c45b740Sflorian int fd, struct sldns_buffer* buffer, int pp2_enabled, 535411c5950Sflorian comm_point_callback_type* callback, void* callback_arg, struct unbound_socket* socket); 536ae8c6e27Sflorian 537ae8c6e27Sflorian /** 538ae8c6e27Sflorian * Create an UDP with ancillary data comm point. Calls malloc. 539ae8c6e27Sflorian * Uses recvmsg instead of recv to get udp message. 540ae8c6e27Sflorian * setups the structure with the parameters you provide. 541ae8c6e27Sflorian * @param base: in which base to alloc the commpoint. 542ae8c6e27Sflorian * @param fd: file descriptor of open UDP socket. 543ae8c6e27Sflorian * @param buffer: shared buffer by UDP sockets from this thread. 5445c45b740Sflorian * @param pp2_enabled: if the comm point will support PROXYv2. 545ae8c6e27Sflorian * @param callback: callback function pointer. 546ae8c6e27Sflorian * @param callback_arg: will be passed to your callback function. 547411c5950Sflorian * @param socket: and opened socket properties will be passed to your callback function. 548ae8c6e27Sflorian * @return: returns the allocated communication point. NULL on error. 549ae8c6e27Sflorian * Sets timeout to NULL. Turns off TCP options. 550ae8c6e27Sflorian */ 551ae8c6e27Sflorian struct comm_point* comm_point_create_udp_ancil(struct comm_base* base, 5525c45b740Sflorian int fd, struct sldns_buffer* buffer, int pp2_enabled, 553411c5950Sflorian comm_point_callback_type* callback, void* callback_arg, struct unbound_socket* socket); 554ae8c6e27Sflorian 555ae8c6e27Sflorian /** 556ae8c6e27Sflorian * Create a TCP listener comm point. Calls malloc. 557ae8c6e27Sflorian * Setups the structure with the parameters you provide. 558ae8c6e27Sflorian * Also Creates TCP Handlers, pre allocated for you. 559ae8c6e27Sflorian * Uses the parameters you provide. 560ae8c6e27Sflorian * @param base: in which base to alloc the commpoint. 561ae8c6e27Sflorian * @param fd: file descriptor of open TCP socket set to listen nonblocking. 562ae8c6e27Sflorian * @param num: becomes max_tcp_count, the routine allocates that 563ae8c6e27Sflorian * many tcp handler commpoints. 564ae8c6e27Sflorian * @param idle_timeout: TCP idle timeout in ms. 565f4f0f0ceSflorian * @param harden_large_queries: whether query size should be limited. 566f4f0f0ceSflorian * @param http_max_streams: maximum number of HTTP/2 streams per connection. 567f4f0f0ceSflorian * @param http_endpoint: HTTP endpoint to service queries on 568ae8c6e27Sflorian * @param tcp_conn_limit: TCP connection limit info. 569ae8c6e27Sflorian * @param bufsize: size of buffer to create for handlers. 570e97c6e54Ssthen * @param spoolbuf: shared spool buffer for tcp_req_info structures. 571e97c6e54Ssthen * or NULL to not create those structures in the tcp handlers. 572f4f0f0ceSflorian * @param port_type: the type of port we are creating a TCP listener for. Used 573f4f0f0ceSflorian * to select handler type to use. 5745c45b740Sflorian * @param pp2_enabled: if the comm point will support PROXYv2. 575ae8c6e27Sflorian * @param callback: callback function pointer for TCP handlers. 576ae8c6e27Sflorian * @param callback_arg: will be passed to your callback function. 577411c5950Sflorian * @param socket: and opened socket properties will be passed to your callback function. 578ae8c6e27Sflorian * @return: returns the TCP listener commpoint. You can find the 579ae8c6e27Sflorian * TCP handlers in the array inside the listener commpoint. 580ae8c6e27Sflorian * returns NULL on error. 581ae8c6e27Sflorian * Inits timeout to NULL. All handlers are on the free list. 582ae8c6e27Sflorian */ 583ae8c6e27Sflorian struct comm_point* comm_point_create_tcp(struct comm_base* base, 584f4f0f0ceSflorian int fd, int num, int idle_timeout, int harden_large_queries, 585f4f0f0ceSflorian uint32_t http_max_streams, char* http_endpoint, 586f4f0f0ceSflorian struct tcl_list* tcp_conn_limit, 587e97c6e54Ssthen size_t bufsize, struct sldns_buffer* spoolbuf, 5885c45b740Sflorian enum listen_type port_type, int pp2_enabled, 589411c5950Sflorian comm_point_callback_type* callback, void* callback_arg, struct unbound_socket* socket); 590ae8c6e27Sflorian 591ae8c6e27Sflorian /** 592ae8c6e27Sflorian * Create an outgoing TCP commpoint. No file descriptor is opened, left at -1. 593ae8c6e27Sflorian * @param base: in which base to alloc the commpoint. 594ae8c6e27Sflorian * @param bufsize: size of buffer to create for handlers. 595ae8c6e27Sflorian * @param callback: callback function pointer for the handler. 596ae8c6e27Sflorian * @param callback_arg: will be passed to your callback function. 597ae8c6e27Sflorian * @return: the commpoint or NULL on error. 598ae8c6e27Sflorian */ 599ae8c6e27Sflorian struct comm_point* comm_point_create_tcp_out(struct comm_base* base, 600ae8c6e27Sflorian size_t bufsize, comm_point_callback_type* callback, void* callback_arg); 601ae8c6e27Sflorian 602ae8c6e27Sflorian /** 603ae8c6e27Sflorian * Create an outgoing HTTP commpoint. No file descriptor is opened, left at -1. 604ae8c6e27Sflorian * @param base: in which base to alloc the commpoint. 605ae8c6e27Sflorian * @param bufsize: size of buffer to create for handlers. 606ae8c6e27Sflorian * @param callback: callback function pointer for the handler. 607ae8c6e27Sflorian * @param callback_arg: will be passed to your callback function. 608ae8c6e27Sflorian * @param temp: sldns buffer, shared between other http_out commpoints, for 609ae8c6e27Sflorian * temporary data when performing callbacks. 610ae8c6e27Sflorian * @return: the commpoint or NULL on error. 611ae8c6e27Sflorian */ 612ae8c6e27Sflorian struct comm_point* comm_point_create_http_out(struct comm_base* base, 613ae8c6e27Sflorian size_t bufsize, comm_point_callback_type* callback, 614ae8c6e27Sflorian void* callback_arg, struct sldns_buffer* temp); 615ae8c6e27Sflorian 616ae8c6e27Sflorian /** 617ae8c6e27Sflorian * Create commpoint to listen to a local domain file descriptor. 618ae8c6e27Sflorian * @param base: in which base to alloc the commpoint. 619ae8c6e27Sflorian * @param fd: file descriptor of open AF_UNIX socket set to listen nonblocking. 620ae8c6e27Sflorian * @param bufsize: size of buffer to create for handlers. 621ae8c6e27Sflorian * @param callback: callback function pointer for the handler. 622ae8c6e27Sflorian * @param callback_arg: will be passed to your callback function. 623ae8c6e27Sflorian * @return: the commpoint or NULL on error. 624ae8c6e27Sflorian */ 625ae8c6e27Sflorian struct comm_point* comm_point_create_local(struct comm_base* base, 626ae8c6e27Sflorian int fd, size_t bufsize, 627ae8c6e27Sflorian comm_point_callback_type* callback, void* callback_arg); 628ae8c6e27Sflorian 629ae8c6e27Sflorian /** 630ae8c6e27Sflorian * Create commpoint to listen to a local domain pipe descriptor. 631ae8c6e27Sflorian * @param base: in which base to alloc the commpoint. 632ae8c6e27Sflorian * @param fd: file descriptor. 633ae8c6e27Sflorian * @param writing: true if you want to listen to writes, false for reads. 634ae8c6e27Sflorian * @param callback: callback function pointer for the handler. 635ae8c6e27Sflorian * @param callback_arg: will be passed to your callback function. 636ae8c6e27Sflorian * @return: the commpoint or NULL on error. 637ae8c6e27Sflorian */ 638ae8c6e27Sflorian struct comm_point* comm_point_create_raw(struct comm_base* base, 639ae8c6e27Sflorian int fd, int writing, 640ae8c6e27Sflorian comm_point_callback_type* callback, void* callback_arg); 641ae8c6e27Sflorian 642ae8c6e27Sflorian /** 643ae8c6e27Sflorian * Close a comm point fd. 644ae8c6e27Sflorian * @param c: comm point to close. 645ae8c6e27Sflorian */ 646ae8c6e27Sflorian void comm_point_close(struct comm_point* c); 647ae8c6e27Sflorian 648ae8c6e27Sflorian /** 649ae8c6e27Sflorian * Close and deallocate (free) the comm point. If the comm point is 650ae8c6e27Sflorian * a tcp-accept point, also its tcp-handler points are deleted. 651ae8c6e27Sflorian * @param c: comm point to delete. 652ae8c6e27Sflorian */ 653ae8c6e27Sflorian void comm_point_delete(struct comm_point* c); 654ae8c6e27Sflorian 655ae8c6e27Sflorian /** 656ae8c6e27Sflorian * Send reply. Put message into commpoint buffer. 657ae8c6e27Sflorian * @param repinfo: The reply info copied from a commpoint callback call. 658ae8c6e27Sflorian */ 659ae8c6e27Sflorian void comm_point_send_reply(struct comm_reply* repinfo); 660ae8c6e27Sflorian 661ae8c6e27Sflorian /** 662ae8c6e27Sflorian * Drop reply. Cleans up. 663ae8c6e27Sflorian * @param repinfo: The reply info copied from a commpoint callback call. 664ae8c6e27Sflorian */ 665ae8c6e27Sflorian void comm_point_drop_reply(struct comm_reply* repinfo); 666ae8c6e27Sflorian 667ae8c6e27Sflorian /** 668ae8c6e27Sflorian * Send an udp message over a commpoint. 669ae8c6e27Sflorian * @param c: commpoint to send it from. 670ae8c6e27Sflorian * @param packet: what to send. 671853e076fSflorian * @param addr: where to send it to. If NULL, send is performed, 672853e076fSflorian * for connected sockets, to the connected address. 673ae8c6e27Sflorian * @param addrlen: length of addr. 674a8eaceedSflorian * @param is_connected: if the UDP socket is connect()ed. 675ae8c6e27Sflorian * @return: false on a failure. 676ae8c6e27Sflorian */ 677ae8c6e27Sflorian int comm_point_send_udp_msg(struct comm_point* c, struct sldns_buffer* packet, 678a8eaceedSflorian struct sockaddr* addr, socklen_t addrlen,int is_connected); 679ae8c6e27Sflorian 680ae8c6e27Sflorian /** 681ae8c6e27Sflorian * Stop listening for input on the commpoint. No callbacks will happen. 682ae8c6e27Sflorian * @param c: commpoint to disable. The fd is not closed. 683ae8c6e27Sflorian */ 684ae8c6e27Sflorian void comm_point_stop_listening(struct comm_point* c); 685ae8c6e27Sflorian 686ae8c6e27Sflorian /** 687ae8c6e27Sflorian * Start listening again for input on the comm point. 688ae8c6e27Sflorian * @param c: commpoint to enable again. 689ae8c6e27Sflorian * @param newfd: new fd, or -1 to leave fd be. 690ae8c6e27Sflorian * @param msec: timeout in milliseconds, or -1 for no (change to the) timeout. 691ae8c6e27Sflorian * So seconds*1000. 692ae8c6e27Sflorian */ 693ae8c6e27Sflorian void comm_point_start_listening(struct comm_point* c, int newfd, int msec); 694ae8c6e27Sflorian 695ae8c6e27Sflorian /** 696ae8c6e27Sflorian * Stop listening and start listening again for reading or writing. 697ae8c6e27Sflorian * @param c: commpoint 698ae8c6e27Sflorian * @param rd: if true, listens for reading. 699ae8c6e27Sflorian * @param wr: if true, listens for writing. 700ae8c6e27Sflorian */ 701ae8c6e27Sflorian void comm_point_listen_for_rw(struct comm_point* c, int rd, int wr); 702ae8c6e27Sflorian 703ae8c6e27Sflorian /** 704a8eaceedSflorian * For TCP handlers that use c->tcp_timeout_msec, this routine adjusts 705a8eaceedSflorian * it with the minimum. Otherwise, a 0 value advertised without the 706a8eaceedSflorian * minimum applied moves to a 0 in comm_point_start_listening and that 707a8eaceedSflorian * routine treats it as no timeout, listen forever, which is not wanted. 708a8eaceedSflorian * @param c: comm point to use the tcp_timeout_msec of. 709a8eaceedSflorian * @return adjusted tcp_timeout_msec value with the minimum if smaller. 710a8eaceedSflorian */ 711a8eaceedSflorian int adjusted_tcp_timeout(struct comm_point* c); 712a8eaceedSflorian 713a8eaceedSflorian /** 714ae8c6e27Sflorian * Get size of memory used by comm point. 715ae8c6e27Sflorian * For TCP handlers this includes subhandlers. 716ae8c6e27Sflorian * For UDP handlers, this does not include the (shared) UDP buffer. 717ae8c6e27Sflorian * @param c: commpoint. 718ae8c6e27Sflorian * @return size in bytes. 719ae8c6e27Sflorian */ 720ae8c6e27Sflorian size_t comm_point_get_mem(struct comm_point* c); 721ae8c6e27Sflorian 722ae8c6e27Sflorian /** 723ae8c6e27Sflorian * create timer. Not active upon creation. 724ae8c6e27Sflorian * @param base: event handling base. 725ae8c6e27Sflorian * @param cb: callback function: void myfunc(void* myarg); 726ae8c6e27Sflorian * @param cb_arg: user callback argument. 727ae8c6e27Sflorian * @return: the new timer or NULL on error. 728ae8c6e27Sflorian */ 729ae8c6e27Sflorian struct comm_timer* comm_timer_create(struct comm_base* base, 730ae8c6e27Sflorian void (*cb)(void*), void* cb_arg); 731ae8c6e27Sflorian 732ae8c6e27Sflorian /** 733ae8c6e27Sflorian * disable timer. Stops callbacks from happening. 734ae8c6e27Sflorian * @param timer: to disable. 735ae8c6e27Sflorian */ 736ae8c6e27Sflorian void comm_timer_disable(struct comm_timer* timer); 737ae8c6e27Sflorian 738ae8c6e27Sflorian /** 739ae8c6e27Sflorian * reset timevalue for timer. 740ae8c6e27Sflorian * @param timer: timer to (re)set. 741ae8c6e27Sflorian * @param tv: when the timer should activate. if NULL timer is disabled. 742ae8c6e27Sflorian */ 743ae8c6e27Sflorian void comm_timer_set(struct comm_timer* timer, struct timeval* tv); 744ae8c6e27Sflorian 745ae8c6e27Sflorian /** 746ae8c6e27Sflorian * delete timer. 747ae8c6e27Sflorian * @param timer: to delete. 748ae8c6e27Sflorian */ 749ae8c6e27Sflorian void comm_timer_delete(struct comm_timer* timer); 750ae8c6e27Sflorian 751ae8c6e27Sflorian /** 752ae8c6e27Sflorian * see if timeout has been set to a value. 753ae8c6e27Sflorian * @param timer: the timer to examine. 754ae8c6e27Sflorian * @return: false if disabled or not set. 755ae8c6e27Sflorian */ 756ae8c6e27Sflorian int comm_timer_is_set(struct comm_timer* timer); 757ae8c6e27Sflorian 758ae8c6e27Sflorian /** 759ae8c6e27Sflorian * Get size of memory used by comm timer. 760ae8c6e27Sflorian * @param timer: the timer to examine. 761ae8c6e27Sflorian * @return size in bytes. 762ae8c6e27Sflorian */ 763ae8c6e27Sflorian size_t comm_timer_get_mem(struct comm_timer* timer); 764ae8c6e27Sflorian 765ae8c6e27Sflorian /** 766ae8c6e27Sflorian * Create a signal handler. Call signal_bind() later to bind to a signal. 767ae8c6e27Sflorian * @param base: communication base to use. 768ae8c6e27Sflorian * @param callback: called when signal is caught. 769ae8c6e27Sflorian * @param cb_arg: user argument to callback 770ae8c6e27Sflorian * @return: the signal struct or NULL on error. 771ae8c6e27Sflorian */ 772ae8c6e27Sflorian struct comm_signal* comm_signal_create(struct comm_base* base, 773ae8c6e27Sflorian void (*callback)(int, void*), void* cb_arg); 774ae8c6e27Sflorian 775ae8c6e27Sflorian /** 776a1a7ba80Sflorian * Bind signal struct to catch a signal. A single comm_signal can be bound 777ae8c6e27Sflorian * to multiple signals, calling comm_signal_bind multiple times. 778ae8c6e27Sflorian * @param comsig: the communication point, with callback information. 779ae8c6e27Sflorian * @param sig: signal number. 780ae8c6e27Sflorian * @return: true on success. false on error. 781ae8c6e27Sflorian */ 782ae8c6e27Sflorian int comm_signal_bind(struct comm_signal* comsig, int sig); 783ae8c6e27Sflorian 784ae8c6e27Sflorian /** 785ae8c6e27Sflorian * Delete the signal communication point. 786ae8c6e27Sflorian * @param comsig: to delete. 787ae8c6e27Sflorian */ 788ae8c6e27Sflorian void comm_signal_delete(struct comm_signal* comsig); 789ae8c6e27Sflorian 790ae8c6e27Sflorian /** 791ae8c6e27Sflorian * perform accept(2) with error checking. 792ae8c6e27Sflorian * @param c: commpoint with accept fd. 793ae8c6e27Sflorian * @param addr: remote end returned here. 794ae8c6e27Sflorian * @param addrlen: length of remote end returned here. 795ae8c6e27Sflorian * @return new fd, or -1 on error. 796ae8c6e27Sflorian * if -1, error message has been printed if necessary, simply drop 797ae8c6e27Sflorian * out of the reading handler. 798ae8c6e27Sflorian */ 799ae8c6e27Sflorian int comm_point_perform_accept(struct comm_point* c, 800ae8c6e27Sflorian struct sockaddr_storage* addr, socklen_t* addrlen); 801ae8c6e27Sflorian 802ae8c6e27Sflorian /**** internal routines ****/ 803ae8c6e27Sflorian 804ae8c6e27Sflorian /** 805ae8c6e27Sflorian * This routine is published for checks and tests, and is only used internally. 806ae8c6e27Sflorian * handle libevent callback for udp comm point. 807ae8c6e27Sflorian * @param fd: file descriptor. 808ae8c6e27Sflorian * @param event: event bits from libevent: 809ae8c6e27Sflorian * EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT. 810ae8c6e27Sflorian * @param arg: the comm_point structure. 811ae8c6e27Sflorian */ 812ae8c6e27Sflorian void comm_point_udp_callback(int fd, short event, void* arg); 813ae8c6e27Sflorian 814ae8c6e27Sflorian /** 815ae8c6e27Sflorian * This routine is published for checks and tests, and is only used internally. 816ae8c6e27Sflorian * handle libevent callback for udp ancillary data comm point. 817ae8c6e27Sflorian * @param fd: file descriptor. 818ae8c6e27Sflorian * @param event: event bits from libevent: 819ae8c6e27Sflorian * EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT. 820ae8c6e27Sflorian * @param arg: the comm_point structure. 821ae8c6e27Sflorian */ 822ae8c6e27Sflorian void comm_point_udp_ancil_callback(int fd, short event, void* arg); 823ae8c6e27Sflorian 824ae8c6e27Sflorian /** 825ae8c6e27Sflorian * This routine is published for checks and tests, and is only used internally. 826ae8c6e27Sflorian * handle libevent callback for tcp accept comm point 827ae8c6e27Sflorian * @param fd: file descriptor. 828ae8c6e27Sflorian * @param event: event bits from libevent: 829ae8c6e27Sflorian * EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT. 830ae8c6e27Sflorian * @param arg: the comm_point structure. 831ae8c6e27Sflorian */ 832ae8c6e27Sflorian void comm_point_tcp_accept_callback(int fd, short event, void* arg); 833ae8c6e27Sflorian 834ae8c6e27Sflorian /** 835ae8c6e27Sflorian * This routine is published for checks and tests, and is only used internally. 836ae8c6e27Sflorian * handle libevent callback for tcp data comm point 837ae8c6e27Sflorian * @param fd: file descriptor. 838ae8c6e27Sflorian * @param event: event bits from libevent: 839ae8c6e27Sflorian * EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT. 840ae8c6e27Sflorian * @param arg: the comm_point structure. 841ae8c6e27Sflorian */ 842ae8c6e27Sflorian void comm_point_tcp_handle_callback(int fd, short event, void* arg); 843ae8c6e27Sflorian 844ae8c6e27Sflorian /** 845ae8c6e27Sflorian * This routine is published for checks and tests, and is only used internally. 846ae8c6e27Sflorian * handle libevent callback for tcp data comm point 847ae8c6e27Sflorian * @param fd: file descriptor. 848ae8c6e27Sflorian * @param event: event bits from libevent: 849ae8c6e27Sflorian * EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT. 850ae8c6e27Sflorian * @param arg: the comm_point structure. 851ae8c6e27Sflorian */ 852ae8c6e27Sflorian void comm_point_http_handle_callback(int fd, short event, void* arg); 853ae8c6e27Sflorian 854ae8c6e27Sflorian /** 855f4f0f0ceSflorian * HTTP2 session. HTTP2 related info per comm point. 856f4f0f0ceSflorian */ 857f4f0f0ceSflorian struct http2_session { 858f4f0f0ceSflorian /** first item in list of streams */ 859f4f0f0ceSflorian struct http2_stream* first_stream; 860f4f0f0ceSflorian #ifdef HAVE_NGHTTP2 861f4f0f0ceSflorian /** nghttp2 session */ 862f4f0f0ceSflorian nghttp2_session *session; 863f4f0f0ceSflorian /** store nghttp2 callbacks for easy reuse */ 864f4f0f0ceSflorian nghttp2_session_callbacks* callbacks; 865f4f0f0ceSflorian #endif 866f4f0f0ceSflorian /** comm point containing buffer used to build answer in worker or 867f4f0f0ceSflorian * module */ 868f4f0f0ceSflorian struct comm_point* c; 869f4f0f0ceSflorian /** session is instructed to get dropped (comm port will be closed) */ 870f4f0f0ceSflorian int is_drop; 871f4f0f0ceSflorian /** postpone dropping the session, can be used to prevent dropping 872f4f0f0ceSflorian * while being in a callback */ 873f4f0f0ceSflorian int postpone_drop; 874f4f0f0ceSflorian }; 875f4f0f0ceSflorian 876f4f0f0ceSflorian /** enum of HTTP status */ 877f4f0f0ceSflorian enum http_status { 878f4f0f0ceSflorian HTTP_STATUS_OK = 200, 879f4f0f0ceSflorian HTTP_STATUS_BAD_REQUEST = 400, 880f4f0f0ceSflorian HTTP_STATUS_NOT_FOUND = 404, 881f4f0f0ceSflorian HTTP_STATUS_PAYLOAD_TOO_LARGE = 413, 882f4f0f0ceSflorian HTTP_STATUS_URI_TOO_LONG = 414, 883f4f0f0ceSflorian HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE = 415, 884f4f0f0ceSflorian HTTP_STATUS_NOT_IMPLEMENTED = 501 885f4f0f0ceSflorian }; 886f4f0f0ceSflorian 887f4f0f0ceSflorian /** 888f4f0f0ceSflorian * HTTP stream. Part of list of HTTP2 streams per session. 889f4f0f0ceSflorian */ 890f4f0f0ceSflorian struct http2_stream { 891f4f0f0ceSflorian /** next stream in list per session */ 892f4f0f0ceSflorian struct http2_stream* next; 893f4f0f0ceSflorian /** previous stream in list per session */ 894f4f0f0ceSflorian struct http2_stream* prev; 895f4f0f0ceSflorian /** HTTP2 stream ID is an unsigned 31-bit integer */ 896f4f0f0ceSflorian int32_t stream_id; 897f4f0f0ceSflorian /** HTTP method used for this stream */ 898f4f0f0ceSflorian enum { 899f4f0f0ceSflorian HTTP_METHOD_POST = 1, 900f4f0f0ceSflorian HTTP_METHOD_GET, 901f4f0f0ceSflorian HTTP_METHOD_UNSUPPORTED 902f4f0f0ceSflorian } http_method; 903f4f0f0ceSflorian /** message contains invalid content type */ 904f4f0f0ceSflorian int invalid_content_type; 905f4f0f0ceSflorian /** message body content type */ 906f4f0f0ceSflorian size_t content_length; 907f4f0f0ceSflorian /** HTTP response status */ 908f4f0f0ceSflorian enum http_status status; 909f4f0f0ceSflorian /** request for non existing endpoint */ 910f4f0f0ceSflorian int invalid_endpoint; 911f4f0f0ceSflorian /** query in request is too large */ 912f4f0f0ceSflorian int query_too_large; 913f4f0f0ceSflorian /** buffer to store query into. Can't use session shared buffer as query 914f4f0f0ceSflorian * can arrive in parts, intertwined with frames for other queries. */ 915f4f0f0ceSflorian struct sldns_buffer* qbuffer; 916f4f0f0ceSflorian /** buffer to store response into. Can't use shared buffer as a next 917f4f0f0ceSflorian * query read callback can overwrite it before it is send out. */ 918f4f0f0ceSflorian struct sldns_buffer* rbuffer; 919f4f0f0ceSflorian /** mesh area containing mesh state */ 920f4f0f0ceSflorian struct mesh_area* mesh; 921f4f0f0ceSflorian /** mesh state for query. Used to remove mesh reply before closing 922f4f0f0ceSflorian * stream. */ 923f4f0f0ceSflorian struct mesh_state* mesh_state; 924f4f0f0ceSflorian }; 925f4f0f0ceSflorian 926f4f0f0ceSflorian #ifdef HAVE_NGHTTP2 927f4f0f0ceSflorian /** nghttp2 receive cb. Read from SSL connection into nghttp2 buffer */ 928f4f0f0ceSflorian ssize_t http2_recv_cb(nghttp2_session* session, uint8_t* buf, 929f4f0f0ceSflorian size_t len, int flags, void* cb_arg); 930f4f0f0ceSflorian /** nghttp2 send callback. Send from nghttp2 buffer to ssl socket */ 931f4f0f0ceSflorian ssize_t http2_send_cb(nghttp2_session* session, const uint8_t* buf, 932f4f0f0ceSflorian size_t len, int flags, void* cb_arg); 933f4f0f0ceSflorian /** nghttp2 callback on closing stream */ 934f4f0f0ceSflorian int http2_stream_close_cb(nghttp2_session* session, int32_t stream_id, 935f4f0f0ceSflorian uint32_t error_code, void* cb_arg); 936f4f0f0ceSflorian #endif 937f4f0f0ceSflorian 938f4f0f0ceSflorian /** 939f4f0f0ceSflorian * Create new http2 stream 940f4f0f0ceSflorian * @param stream_id: ID for stream to create. 941f4f0f0ceSflorian * @return malloc'ed stream, NULL on error 942f4f0f0ceSflorian */ 943f4f0f0ceSflorian struct http2_stream* http2_stream_create(int32_t stream_id); 944f4f0f0ceSflorian 945f4f0f0ceSflorian /** 946f4f0f0ceSflorian * Add new stream to session linked list 947f4f0f0ceSflorian * @param h2_session: http2 session to add stream to 948f4f0f0ceSflorian * @param h2_stream: stream to add to session list 949f4f0f0ceSflorian */ 950f4f0f0ceSflorian void http2_session_add_stream(struct http2_session* h2_session, 951f4f0f0ceSflorian struct http2_stream* h2_stream); 952f4f0f0ceSflorian 953f4f0f0ceSflorian /** Add mesh state to stream. To be able to remove mesh reply on stream closure 954f4f0f0ceSflorian */ 955f4f0f0ceSflorian void http2_stream_add_meshstate(struct http2_stream* h2_stream, 956f4f0f0ceSflorian struct mesh_area* mesh, struct mesh_state* m); 957f4f0f0ceSflorian 958*7037e34cSflorian /** Remove mesh state from stream. When the mesh state has been removed. */ 959*7037e34cSflorian void http2_stream_remove_mesh_state(struct http2_stream* h2_stream); 960*7037e34cSflorian 961f4f0f0ceSflorian /** 962ae8c6e27Sflorian * This routine is published for checks and tests, and is only used internally. 963ae8c6e27Sflorian * handle libevent callback for timer comm. 964ae8c6e27Sflorian * @param fd: file descriptor (always -1). 965ae8c6e27Sflorian * @param event: event bits from libevent: 966ae8c6e27Sflorian * EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT. 967ae8c6e27Sflorian * @param arg: the comm_timer structure. 968ae8c6e27Sflorian */ 969ae8c6e27Sflorian void comm_timer_callback(int fd, short event, void* arg); 970ae8c6e27Sflorian 971ae8c6e27Sflorian /** 972ae8c6e27Sflorian * This routine is published for checks and tests, and is only used internally. 973ae8c6e27Sflorian * handle libevent callback for signal comm. 974ae8c6e27Sflorian * @param fd: file descriptor (used for the signal number). 975ae8c6e27Sflorian * @param event: event bits from libevent: 976ae8c6e27Sflorian * EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT. 977ae8c6e27Sflorian * @param arg: the internal commsignal structure. 978ae8c6e27Sflorian */ 979ae8c6e27Sflorian void comm_signal_callback(int fd, short event, void* arg); 980ae8c6e27Sflorian 981ae8c6e27Sflorian /** 982ae8c6e27Sflorian * This routine is published for checks and tests, and is only used internally. 983ae8c6e27Sflorian * libevent callback for AF_UNIX fds 984ae8c6e27Sflorian * @param fd: file descriptor. 985ae8c6e27Sflorian * @param event: event bits from libevent: 986ae8c6e27Sflorian * EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT. 987ae8c6e27Sflorian * @param arg: the comm_point structure. 988ae8c6e27Sflorian */ 989ae8c6e27Sflorian void comm_point_local_handle_callback(int fd, short event, void* arg); 990ae8c6e27Sflorian 991ae8c6e27Sflorian /** 992ae8c6e27Sflorian * This routine is published for checks and tests, and is only used internally. 993ae8c6e27Sflorian * libevent callback for raw fd access. 994ae8c6e27Sflorian * @param fd: file descriptor. 995ae8c6e27Sflorian * @param event: event bits from libevent: 996ae8c6e27Sflorian * EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT. 997ae8c6e27Sflorian * @param arg: the comm_point structure. 998ae8c6e27Sflorian */ 999ae8c6e27Sflorian void comm_point_raw_handle_callback(int fd, short event, void* arg); 1000ae8c6e27Sflorian 1001ae8c6e27Sflorian /** 1002ae8c6e27Sflorian * This routine is published for checks and tests, and is only used internally. 1003ae8c6e27Sflorian * libevent callback for timeout on slow accept. 1004ae8c6e27Sflorian * @param fd: file descriptor. 1005ae8c6e27Sflorian * @param event: event bits from libevent: 1006ae8c6e27Sflorian * EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT. 1007ae8c6e27Sflorian * @param arg: the comm_point structure. 1008ae8c6e27Sflorian */ 1009ae8c6e27Sflorian void comm_base_handle_slow_accept(int fd, short event, void* arg); 1010ae8c6e27Sflorian 1011ae8c6e27Sflorian #ifdef USE_WINSOCK 1012ae8c6e27Sflorian /** 1013ae8c6e27Sflorian * Callback for openssl BIO to on windows detect WSAEWOULDBLOCK and notify 1014ae8c6e27Sflorian * the winsock_event of this for proper TCP nonblocking implementation. 1015ae8c6e27Sflorian * @param c: comm_point, fd must be set its struct event is registered. 1016ae8c6e27Sflorian * @param ssl: openssl SSL, fd must be set so it has a bio. 1017ae8c6e27Sflorian */ 1018ae8c6e27Sflorian void comm_point_tcp_win_bio_cb(struct comm_point* c, void* ssl); 1019ae8c6e27Sflorian #endif 1020ae8c6e27Sflorian 1021e47fef9eSflorian /** 1022e47fef9eSflorian * See if errno for tcp connect has to be logged or not. This uses errno 1023e47fef9eSflorian * @param addr: apart from checking errno, the addr is checked for ip4mapped 1024e47fef9eSflorian * and broadcast type, hence passed. 1025e47fef9eSflorian * @param addrlen: length of the addr parameter. 1026e47fef9eSflorian * @return true if it needs to be logged. 1027e47fef9eSflorian */ 1028ae8c6e27Sflorian int tcp_connect_errno_needs_log(struct sockaddr* addr, socklen_t addrlen); 1029ae8c6e27Sflorian 1030e47fef9eSflorian #ifdef HAVE_SSL 1031e47fef9eSflorian /** 1032e47fef9eSflorian * True if the ssl handshake error has to be squelched from the logs 1033e47fef9eSflorian * @param err: the error returned by the openssl routine, ERR_get_error. 1034e47fef9eSflorian * This is a packed structure with elements that are examined. 1035e47fef9eSflorian * @return true if the error is squelched (not logged). 1036e47fef9eSflorian */ 1037e47fef9eSflorian int squelch_err_ssl_handshake(unsigned long err); 1038e47fef9eSflorian #endif 1039e47fef9eSflorian 1040ae8c6e27Sflorian #endif /* NET_EVENT_H */ 1041