xref: /freebsd/contrib/unbound/util/netevent.h (revision 46d2f61818f594174cafe31ee338c6e083fa1876)
1b7579f77SDag-Erling Smørgrav /*
2b7579f77SDag-Erling Smørgrav  * util/netevent.h - event notification
3b7579f77SDag-Erling Smørgrav  *
4b7579f77SDag-Erling Smørgrav  * Copyright (c) 2007, NLnet Labs. All rights reserved.
5b7579f77SDag-Erling Smørgrav  *
6b7579f77SDag-Erling Smørgrav  * This software is open source.
7b7579f77SDag-Erling Smørgrav  *
8b7579f77SDag-Erling Smørgrav  * Redistribution and use in source and binary forms, with or without
9b7579f77SDag-Erling Smørgrav  * modification, are permitted provided that the following conditions
10b7579f77SDag-Erling Smørgrav  * are met:
11b7579f77SDag-Erling Smørgrav  *
12b7579f77SDag-Erling Smørgrav  * Redistributions of source code must retain the above copyright notice,
13b7579f77SDag-Erling Smørgrav  * this list of conditions and the following disclaimer.
14b7579f77SDag-Erling Smørgrav  *
15b7579f77SDag-Erling Smørgrav  * Redistributions in binary form must reproduce the above copyright notice,
16b7579f77SDag-Erling Smørgrav  * this list of conditions and the following disclaimer in the documentation
17b7579f77SDag-Erling Smørgrav  * and/or other materials provided with the distribution.
18b7579f77SDag-Erling Smørgrav  *
19b7579f77SDag-Erling Smørgrav  * Neither the name of the NLNET LABS nor the names of its contributors may
20b7579f77SDag-Erling Smørgrav  * be used to endorse or promote products derived from this software without
21b7579f77SDag-Erling Smørgrav  * specific prior written permission.
22b7579f77SDag-Erling Smørgrav  *
23b7579f77SDag-Erling Smørgrav  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2417d15b25SDag-Erling Smørgrav  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2517d15b25SDag-Erling Smørgrav  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2617d15b25SDag-Erling Smørgrav  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2717d15b25SDag-Erling Smørgrav  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2817d15b25SDag-Erling Smørgrav  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
2917d15b25SDag-Erling Smørgrav  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
3017d15b25SDag-Erling Smørgrav  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
3117d15b25SDag-Erling Smørgrav  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3217d15b25SDag-Erling Smørgrav  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3317d15b25SDag-Erling Smørgrav  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34b7579f77SDag-Erling Smørgrav  */
35b7579f77SDag-Erling Smørgrav 
36b7579f77SDag-Erling Smørgrav /**
37b7579f77SDag-Erling Smørgrav  * \file
38b7579f77SDag-Erling Smørgrav  *
39b7579f77SDag-Erling Smørgrav  * This file contains event notification functions.
40b7579f77SDag-Erling Smørgrav  *
41b7579f77SDag-Erling Smørgrav  * There are three types of communication points
42b7579f77SDag-Erling Smørgrav  *    o UDP socket - perthread buffer.
43b7579f77SDag-Erling Smørgrav  *    o TCP-accept socket - array of TCP-sockets, socketcount.
44b7579f77SDag-Erling Smørgrav  *    o TCP socket - own buffer, parent-TCPaccept, read/write state,
45b7579f77SDag-Erling Smørgrav  *                   number of bytes read/written, timeout.
46b7579f77SDag-Erling Smørgrav  *
47b7579f77SDag-Erling Smørgrav  * There are sockets aimed towards our clients and towards the internet.
48b7579f77SDag-Erling Smørgrav  *    o frontside - aimed towards our clients, queries come in, answers back.
49b7579f77SDag-Erling Smørgrav  *    o behind - aimed towards internet, to the authoritative DNS servers.
50b7579f77SDag-Erling Smørgrav  *
51b7579f77SDag-Erling Smørgrav  * Several event types are available:
52b7579f77SDag-Erling Smørgrav  *    o comm_base - for thread safety of the comm points, one per thread.
53b7579f77SDag-Erling Smørgrav  *    o comm_point - udp and tcp networking, with callbacks.
54b7579f77SDag-Erling Smørgrav  *    o comm_timer - a timeout with callback.
55b7579f77SDag-Erling Smørgrav  *    o comm_signal - callbacks when signal is caught.
56b7579f77SDag-Erling Smørgrav  *    o comm_reply - holds reply info during networking callback.
57b7579f77SDag-Erling Smørgrav  *
58b7579f77SDag-Erling Smørgrav  */
59b7579f77SDag-Erling Smørgrav 
60b7579f77SDag-Erling Smørgrav #ifndef NET_EVENT_H
61b7579f77SDag-Erling Smørgrav #define NET_EVENT_H
62b7579f77SDag-Erling Smørgrav 
638f76bb7dSCy Schubert #include <sys/time.h>
6465b390aaSDag-Erling Smørgrav #include "dnscrypt/dnscrypt.h"
65c0caa2e2SCy Schubert #ifdef HAVE_NGHTTP2_NGHTTP2_H
66c0caa2e2SCy Schubert #include <nghttp2/nghttp2.h>
67c0caa2e2SCy Schubert #endif
68*46d2f618SCy Schubert #ifdef HAVE_NGTCP2
69*46d2f618SCy Schubert #include <ngtcp2/ngtcp2.h>
70*46d2f618SCy Schubert #endif
7165b390aaSDag-Erling Smørgrav 
7217d15b25SDag-Erling Smørgrav struct sldns_buffer;
73b7579f77SDag-Erling Smørgrav struct comm_point;
74b7579f77SDag-Erling Smørgrav struct comm_reply;
754c75e3aaSDag-Erling Smørgrav struct tcl_list;
76e2d15004SDag-Erling Smørgrav struct ub_event_base;
775469a995SCy Schubert struct unbound_socket;
78*46d2f618SCy Schubert struct doq_server_socket;
79*46d2f618SCy Schubert struct doq_table;
80*46d2f618SCy Schubert struct doq_conn;
81*46d2f618SCy Schubert struct config_file;
82*46d2f618SCy Schubert struct ub_randstate;
83b7579f77SDag-Erling Smørgrav 
84c0caa2e2SCy Schubert struct mesh_state;
85c0caa2e2SCy Schubert struct mesh_area;
86c0caa2e2SCy Schubert 
87b7579f77SDag-Erling Smørgrav /* internal event notification data storage structure. */
88b7579f77SDag-Erling Smørgrav struct internal_event;
89b7579f77SDag-Erling Smørgrav struct internal_base;
90e2d15004SDag-Erling Smørgrav struct internal_timer; /* A sub struct of the comm_timer super struct */
91b7579f77SDag-Erling Smørgrav 
92c0caa2e2SCy Schubert enum listen_type;
93c0caa2e2SCy Schubert 
94b7579f77SDag-Erling Smørgrav /** callback from communication point function type */
953005e0a3SDag-Erling Smørgrav typedef int comm_point_callback_type(struct comm_point*, void*, int,
96b7579f77SDag-Erling Smørgrav 	struct comm_reply*);
97b7579f77SDag-Erling Smørgrav 
98b7579f77SDag-Erling Smørgrav /** to pass no_error to callback function */
99b7579f77SDag-Erling Smørgrav #define NETEVENT_NOERROR 0
100b7579f77SDag-Erling Smørgrav /** to pass closed connection to callback function */
101b7579f77SDag-Erling Smørgrav #define NETEVENT_CLOSED -1
102b7579f77SDag-Erling Smørgrav /** to pass timeout happened to callback function */
103b7579f77SDag-Erling Smørgrav #define NETEVENT_TIMEOUT -2
104b7579f77SDag-Erling Smørgrav /** to pass fallback from capsforID to callback function; 0x20 failed */
105b7579f77SDag-Erling Smørgrav #define NETEVENT_CAPSFAIL -3
10657bddd21SDag-Erling Smørgrav /** to pass done transfer to callback function; http file is complete */
10757bddd21SDag-Erling Smørgrav #define NETEVENT_DONE -4
108369c6923SCy Schubert /** to pass write of the write packet is done to callback function
109369c6923SCy Schubert  * used when tcp_write_and_read is enabled */
110369c6923SCy Schubert #define NETEVENT_PKT_WRITTEN -5
111b7579f77SDag-Erling Smørgrav 
112b7579f77SDag-Erling Smørgrav /** timeout to slow accept calls when not possible, in msec. */
113b7579f77SDag-Erling Smørgrav #define NETEVENT_SLOW_ACCEPT_TIME 2000
114865f46b2SCy Schubert /** timeout to slow down log print, so it does not spam the logs, in sec */
115865f46b2SCy Schubert #define SLOW_LOG_TIME 10
116*46d2f618SCy Schubert /** for doq, the maximum dcid length, in ngtcp2 it is 20. */
117*46d2f618SCy Schubert #define DOQ_MAX_CIDLEN 24
118b7579f77SDag-Erling Smørgrav 
119b7579f77SDag-Erling Smørgrav /**
120b7579f77SDag-Erling Smørgrav  * A communication point dispatcher. Thread specific.
121b7579f77SDag-Erling Smørgrav  */
122b7579f77SDag-Erling Smørgrav struct comm_base {
123b7579f77SDag-Erling Smørgrav 	/** behind the scenes structure. with say libevent info. alloced */
124b7579f77SDag-Erling Smørgrav 	struct internal_base* eb;
125b7579f77SDag-Erling Smørgrav 	/** callback to stop listening on accept sockets,
126b7579f77SDag-Erling Smørgrav 	 * performed when accept() will not function properly */
127b7579f77SDag-Erling Smørgrav 	void (*stop_accept)(void*);
128b7579f77SDag-Erling Smørgrav 	/** callback to start listening on accept sockets, performed
129b7579f77SDag-Erling Smørgrav 	 * after stop_accept() then a timeout has passed. */
130b7579f77SDag-Erling Smørgrav 	void (*start_accept)(void*);
131b7579f77SDag-Erling Smørgrav 	/** user argument for stop_accept and start_accept functions */
132b7579f77SDag-Erling Smørgrav 	void* cb_arg;
133b7579f77SDag-Erling Smørgrav };
134b7579f77SDag-Erling Smørgrav 
135b7579f77SDag-Erling Smørgrav /**
136b7579f77SDag-Erling Smørgrav  * Reply information for a communication point.
137b7579f77SDag-Erling Smørgrav  */
138b7579f77SDag-Erling Smørgrav struct comm_reply {
139b7579f77SDag-Erling Smørgrav 	/** the comm_point with fd to send reply on to. */
140b7579f77SDag-Erling Smørgrav 	struct comm_point* c;
141b7579f77SDag-Erling Smørgrav 	/** the address (for UDP based communication) */
142865f46b2SCy Schubert 	struct sockaddr_storage remote_addr;
143b7579f77SDag-Erling Smørgrav 	/** length of address */
144865f46b2SCy Schubert 	socklen_t remote_addrlen;
145865f46b2SCy Schubert 	/** return type 0 (none), 4(IP4), 6(IP6)
146865f46b2SCy Schubert 	 *  used only with listen_type_udp_ancil* */
147b7579f77SDag-Erling Smørgrav 	int srctype;
14865b390aaSDag-Erling Smørgrav 	/* DnsCrypt context */
14965b390aaSDag-Erling Smørgrav #ifdef USE_DNSCRYPT
15065b390aaSDag-Erling Smørgrav 	uint8_t client_nonce[crypto_box_HALF_NONCEBYTES];
15165b390aaSDag-Erling Smørgrav 	uint8_t nmkey[crypto_box_BEFORENMBYTES];
152c7f4d7adSDag-Erling Smørgrav 	const dnsccert *dnsc_cert;
15365b390aaSDag-Erling Smørgrav 	int is_dnscrypted;
15465b390aaSDag-Erling Smørgrav #endif
155b7579f77SDag-Erling Smørgrav 	/** the return source interface data */
156b7579f77SDag-Erling Smørgrav 	union {
157b7579f77SDag-Erling Smørgrav #ifdef IPV6_PKTINFO
158b7579f77SDag-Erling Smørgrav 		struct in6_pktinfo v6info;
159b7579f77SDag-Erling Smørgrav #endif
160b7579f77SDag-Erling Smørgrav #ifdef IP_PKTINFO
161b7579f77SDag-Erling Smørgrav 		struct in_pktinfo v4info;
162b7579f77SDag-Erling Smørgrav #elif defined(IP_RECVDSTADDR)
163b7579f77SDag-Erling Smørgrav 		struct in_addr v4addr;
164b7579f77SDag-Erling Smørgrav #endif
165b7579f77SDag-Erling Smørgrav 	}
166b7579f77SDag-Erling Smørgrav 		/** variable with return source data */
167b7579f77SDag-Erling Smørgrav 		pktinfo;
16865b390aaSDag-Erling Smørgrav 	/** max udp size for udp packets */
16965b390aaSDag-Erling Smørgrav 	size_t max_udp_size;
170865f46b2SCy Schubert 	/* if set, the request came through a proxy */
171865f46b2SCy Schubert 	int is_proxied;
172865f46b2SCy Schubert 	/** the client address
173865f46b2SCy Schubert 	 *  the same as remote_addr if not proxied */
174865f46b2SCy Schubert 	struct sockaddr_storage client_addr;
175865f46b2SCy Schubert 	/** the original address length */
176865f46b2SCy Schubert 	socklen_t client_addrlen;
177*46d2f618SCy Schubert #ifdef HAVE_NGTCP2
178*46d2f618SCy Schubert 	/** the doq ifindex, together with addr and localaddr in pktinfo,
179*46d2f618SCy Schubert 	 * and dcid makes the doq_conn_key to find the connection */
180*46d2f618SCy Schubert 	int doq_ifindex;
181*46d2f618SCy Schubert 	/** the doq dcid, the connection id used to find the connection */
182*46d2f618SCy Schubert 	uint8_t doq_dcid[DOQ_MAX_CIDLEN];
183*46d2f618SCy Schubert 	/** the length of the doq dcid */
184*46d2f618SCy Schubert 	size_t doq_dcidlen;
185*46d2f618SCy Schubert 	/** the doq stream id where the query came in on */
186*46d2f618SCy Schubert 	int64_t doq_streamid;
187*46d2f618SCy Schubert 	/** port number for doq */
188*46d2f618SCy Schubert 	int doq_srcport;
189*46d2f618SCy Schubert #endif /* HAVE_NGTCP2 */
190b7579f77SDag-Erling Smørgrav };
191b7579f77SDag-Erling Smørgrav 
192b7579f77SDag-Erling Smørgrav /**
193b7579f77SDag-Erling Smørgrav  * Communication point to the network
194b7579f77SDag-Erling Smørgrav  * These behaviours can be accomplished by setting the flags
195b7579f77SDag-Erling Smørgrav  * and passing return values from the callback.
196b7579f77SDag-Erling Smørgrav  *    udp frontside: called after readdone. sendafter.
197b7579f77SDag-Erling Smørgrav  *    tcp frontside: called readdone, sendafter. close.
198b7579f77SDag-Erling Smørgrav  *    udp behind: called after readdone. No send after.
199b7579f77SDag-Erling Smørgrav  *    tcp behind: write done, read done, then called. No send after.
200b7579f77SDag-Erling Smørgrav  */
201b7579f77SDag-Erling Smørgrav struct comm_point {
202b7579f77SDag-Erling Smørgrav 	/** behind the scenes structure, with say libevent info. alloced. */
203b7579f77SDag-Erling Smørgrav 	struct internal_event* ev;
204f44e67d1SCy Schubert 	/** if the event is added or not */
205f44e67d1SCy Schubert 	int event_added;
206b7579f77SDag-Erling Smørgrav 
207335c7cdaSCy Schubert 	/** Reference to struct that is part of the listening ports,
208335c7cdaSCy Schubert 	 * where for listening ports information is kept about the address. */
2095469a995SCy Schubert 	struct unbound_socket* socket;
2105469a995SCy Schubert 
211b7579f77SDag-Erling Smørgrav 	/** file descriptor for communication point */
212b7579f77SDag-Erling Smørgrav 	int fd;
213b7579f77SDag-Erling Smørgrav 
214b7579f77SDag-Erling Smørgrav 	/** timeout (NULL if it does not). Malloced. */
215b7579f77SDag-Erling Smørgrav 	struct timeval* timeout;
216b7579f77SDag-Erling Smørgrav 
217b7579f77SDag-Erling Smørgrav 	/** buffer pointer. Either to perthread, or own buffer or NULL */
21817d15b25SDag-Erling Smørgrav 	struct sldns_buffer* buffer;
219b7579f77SDag-Erling Smørgrav 
220b7579f77SDag-Erling Smørgrav 	/* -------- TCP Handler -------- */
221b7579f77SDag-Erling Smørgrav 	/** Read/Write state for TCP */
222b7579f77SDag-Erling Smørgrav 	int tcp_is_reading;
223b7579f77SDag-Erling Smørgrav 	/** The current read/write count for TCP */
224b7579f77SDag-Erling Smørgrav 	size_t tcp_byte_count;
225b7579f77SDag-Erling Smørgrav 	/** parent communication point (for TCP sockets) */
226b7579f77SDag-Erling Smørgrav 	struct comm_point* tcp_parent;
227b7579f77SDag-Erling Smørgrav 	/** sockaddr from peer, for TCP handlers */
228b7579f77SDag-Erling Smørgrav 	struct comm_reply repinfo;
229b7579f77SDag-Erling Smørgrav 
230b7579f77SDag-Erling Smørgrav 	/* -------- TCP Accept -------- */
231b7579f77SDag-Erling Smørgrav 	/** the number of TCP handlers for this tcp-accept socket */
232b7579f77SDag-Erling Smørgrav 	int max_tcp_count;
23309a3aaf3SDag-Erling Smørgrav 	/** current number of tcp handler in-use for this accept socket */
23409a3aaf3SDag-Erling Smørgrav 	int cur_tcp_count;
235b7579f77SDag-Erling Smørgrav 	/** malloced array of tcp handlers for a tcp-accept,
236b7579f77SDag-Erling Smørgrav 	    of size max_tcp_count. */
237b7579f77SDag-Erling Smørgrav 	struct comm_point** tcp_handlers;
238b7579f77SDag-Erling Smørgrav 	/** linked list of free tcp_handlers to use for new queries.
239b7579f77SDag-Erling Smørgrav 	    For tcp_accept the first entry, for tcp_handlers the next one. */
240b7579f77SDag-Erling Smørgrav 	struct comm_point* tcp_free;
241b7579f77SDag-Erling Smørgrav 
242b7579f77SDag-Erling Smørgrav 	/* -------- SSL TCP DNS ------- */
243b7579f77SDag-Erling Smørgrav 	/** the SSL object with rw bio (owned) or for commaccept ctx ref */
244b7579f77SDag-Erling Smørgrav 	void* ssl;
245b7579f77SDag-Erling Smørgrav 	/** handshake state for init and renegotiate */
246b7579f77SDag-Erling Smørgrav 	enum {
247b7579f77SDag-Erling Smørgrav 		/** no handshake, it has been done */
248b7579f77SDag-Erling Smørgrav 		comm_ssl_shake_none = 0,
249b7579f77SDag-Erling Smørgrav 		/** ssl initial handshake wants to read */
250b7579f77SDag-Erling Smørgrav 		comm_ssl_shake_read,
251b7579f77SDag-Erling Smørgrav 		/** ssl initial handshake wants to write */
252b7579f77SDag-Erling Smørgrav 		comm_ssl_shake_write,
253b7579f77SDag-Erling Smørgrav 		/** ssl_write wants to read */
254b7579f77SDag-Erling Smørgrav 		comm_ssl_shake_hs_read,
255b7579f77SDag-Erling Smørgrav 		/** ssl_read wants to write */
256b7579f77SDag-Erling Smørgrav 		comm_ssl_shake_hs_write
257b7579f77SDag-Erling Smørgrav 	} ssl_shake_state;
258b7579f77SDag-Erling Smørgrav 
25957bddd21SDag-Erling Smørgrav 	/* -------- HTTP ------- */
260c0caa2e2SCy Schubert 	/** Do not allow connection to use HTTP version lower than this. 0=no
261c0caa2e2SCy Schubert 	 * minimum. */
262c0caa2e2SCy Schubert 	enum {
263c0caa2e2SCy Schubert 		http_version_none = 0,
264c0caa2e2SCy Schubert 		http_version_2 = 2
265c0caa2e2SCy Schubert 	} http_min_version;
266c0caa2e2SCy Schubert 	/** http endpoint */
267c0caa2e2SCy Schubert 	char* http_endpoint;
268c0caa2e2SCy Schubert 	/* -------- HTTP/1.1 ------- */
26957bddd21SDag-Erling Smørgrav 	/** Currently reading in http headers */
27057bddd21SDag-Erling Smørgrav 	int http_in_headers;
27157bddd21SDag-Erling Smørgrav 	/** Currently reading in chunk headers, 0=not, 1=firstline, 2=unused
27257bddd21SDag-Erling Smørgrav 	 * (more lines), 3=trailer headers after chunk */
27357bddd21SDag-Erling Smørgrav 	int http_in_chunk_headers;
27457bddd21SDag-Erling Smørgrav 	/** chunked transfer */
27557bddd21SDag-Erling Smørgrav 	int http_is_chunked;
27657bddd21SDag-Erling Smørgrav 	/** http temp buffer (shared buffer for temporary work) */
27757bddd21SDag-Erling Smørgrav 	struct sldns_buffer* http_temp;
27857bddd21SDag-Erling Smørgrav 	/** http stored content in buffer */
27957bddd21SDag-Erling Smørgrav 	size_t http_stored;
280c0caa2e2SCy Schubert 	/* -------- HTTP/2 ------- */
281c0caa2e2SCy Schubert 	/** http2 session */
282c0caa2e2SCy Schubert 	struct http2_session* h2_session;
283c0caa2e2SCy Schubert 	/** set to 1 if h2 is negotiated to be used (using alpn) */
284c0caa2e2SCy Schubert 	int use_h2;
285c0caa2e2SCy Schubert 	/** stream currently being handled */
286c0caa2e2SCy Schubert 	struct http2_stream* h2_stream;
287c0caa2e2SCy Schubert 	/** maximum allowed query buffer size, per stream */
288c0caa2e2SCy Schubert 	size_t http2_stream_max_qbuffer_size;
289c0caa2e2SCy Schubert 	/** maximum number of HTTP/2 streams per connection. Send in HTTP/2
290c0caa2e2SCy Schubert 	 * SETTINGS frame. */
291c0caa2e2SCy Schubert 	uint32_t http2_max_streams;
292*46d2f618SCy Schubert 	/* -------- DoQ ------- */
293*46d2f618SCy Schubert #ifdef HAVE_NGTCP2
294*46d2f618SCy Schubert 	/** the doq server socket, with list of doq connections */
295*46d2f618SCy Schubert 	struct doq_server_socket* doq_socket;
296*46d2f618SCy Schubert #endif
29757bddd21SDag-Erling Smørgrav 
298ff825849SDag-Erling Smørgrav 	/* -------- dnstap ------- */
299ff825849SDag-Erling Smørgrav 	/** the dnstap environment */
300ff825849SDag-Erling Smørgrav 	struct dt_env* dtenv;
301ff825849SDag-Erling Smørgrav 
302b7579f77SDag-Erling Smørgrav 	/** is this a UDP, TCP-accept or TCP socket. */
303b7579f77SDag-Erling Smørgrav 	enum comm_point_type {
304b7579f77SDag-Erling Smørgrav 		/** UDP socket - handle datagrams. */
305b7579f77SDag-Erling Smørgrav 		comm_udp,
306b7579f77SDag-Erling Smørgrav 		/** TCP accept socket - only creates handlers if readable. */
307b7579f77SDag-Erling Smørgrav 		comm_tcp_accept,
308b7579f77SDag-Erling Smørgrav 		/** TCP handler socket - handle byteperbyte readwrite. */
309b7579f77SDag-Erling Smørgrav 		comm_tcp,
31057bddd21SDag-Erling Smørgrav 		/** HTTP handler socket */
31157bddd21SDag-Erling Smørgrav 		comm_http,
312*46d2f618SCy Schubert 		/** DOQ handler socket */
313*46d2f618SCy Schubert 		comm_doq,
314b7579f77SDag-Erling Smørgrav 		/** AF_UNIX socket - for internal commands. */
315b7579f77SDag-Erling Smørgrav 		comm_local,
316b7579f77SDag-Erling Smørgrav 		/** raw - not DNS format - for pipe readers and writers */
317b7579f77SDag-Erling Smørgrav 		comm_raw
318b7579f77SDag-Erling Smørgrav 	}
319b7579f77SDag-Erling Smørgrav 		/** variable with type of socket, UDP,TCP-accept,TCP,pipe */
320b7579f77SDag-Erling Smørgrav 		type;
321b7579f77SDag-Erling Smørgrav 
322865f46b2SCy Schubert 	/* -------- PROXYv2 ------- */
323865f46b2SCy Schubert 	/** if set, PROXYv2 is expected on this connection */
324865f46b2SCy Schubert 	int pp2_enabled;
325865f46b2SCy Schubert 	/** header state for the PROXYv2 header (for TCP) */
326865f46b2SCy Schubert 	enum {
327865f46b2SCy Schubert 		/** no header encounter yet */
328865f46b2SCy Schubert 		pp2_header_none = 0,
329865f46b2SCy Schubert 		/** read the static part of the header */
330865f46b2SCy Schubert 		pp2_header_init,
331865f46b2SCy Schubert 		/** read the full header */
332865f46b2SCy Schubert 		pp2_header_done
333865f46b2SCy Schubert 	} pp2_header_state;
334865f46b2SCy Schubert 
335b7579f77SDag-Erling Smørgrav 	/* ---------- Behaviour ----------- */
336b7579f77SDag-Erling Smørgrav 	/** if set the connection is NOT closed on delete. */
337b7579f77SDag-Erling Smørgrav 	int do_not_close;
338b7579f77SDag-Erling Smørgrav 
339b7579f77SDag-Erling Smørgrav 	/** if set, the connection is closed on error, on timeout,
340b7579f77SDag-Erling Smørgrav 	    and after read/write completes. No callback is done. */
341b7579f77SDag-Erling Smørgrav 	int tcp_do_close;
342b7579f77SDag-Erling Smørgrav 
343369c6923SCy Schubert 	/** flag that indicates the stream is both written and read from. */
344369c6923SCy Schubert 	int tcp_write_and_read;
345369c6923SCy Schubert 
346369c6923SCy Schubert 	/** byte count for written length over write channel, for when
347369c6923SCy Schubert 	 * tcp_write_and_read is enabled.  When tcp_write_and_read is enabled,
348369c6923SCy Schubert 	 * this is the counter for writing, the one for reading is in the
349369c6923SCy Schubert 	 * commpoint.buffer sldns buffer.  The counter counts from 0 to
350369c6923SCy Schubert 	 * 2+tcp_write_pkt_len, and includes the tcp length bytes. */
351369c6923SCy Schubert 	size_t tcp_write_byte_count;
352369c6923SCy Schubert 
353369c6923SCy Schubert 	/** packet to write currently over the write channel. for when
354369c6923SCy Schubert 	 * tcp_write_and_read is enabled.  When tcp_write_and_read is enabled,
355369c6923SCy Schubert 	 * this is the buffer for the written packet, the commpoint.buffer
356369c6923SCy Schubert 	 * sldns buffer is the buffer for the received packet. */
357369c6923SCy Schubert 	uint8_t* tcp_write_pkt;
358369c6923SCy Schubert 	/** length of tcp_write_pkt in bytes */
359369c6923SCy Schubert 	size_t tcp_write_pkt_len;
360369c6923SCy Schubert 
361369c6923SCy Schubert 	/** if set try to read another packet again (over connection with
362369c6923SCy Schubert 	 * multiple packets), once set, tries once, then zero again,
363369c6923SCy Schubert 	 * so set it in the packet complete section.
364369c6923SCy Schubert 	 * The pointer itself has to be set before the callback is invoked,
365369c6923SCy Schubert 	 * when you set things up, and continue to exist also after the
366369c6923SCy Schubert 	 * commpoint is closed and deleted in your callback.  So that after
367369c6923SCy Schubert 	 * the callback cleans up netevent can see what it has to do.
368369c6923SCy Schubert 	 * Or leave NULL if it is not used at all. */
369369c6923SCy Schubert 	int* tcp_more_read_again;
370369c6923SCy Schubert 
371369c6923SCy Schubert 	/** if set try to write another packet (over connection with
372369c6923SCy Schubert 	 * multiple packets), once set, tries once, then zero again,
373369c6923SCy Schubert 	 * so set it in the packet complete section.
374369c6923SCy Schubert 	 * The pointer itself has to be set before the callback is invoked,
375369c6923SCy Schubert 	 * when you set things up, and continue to exist also after the
376369c6923SCy Schubert 	 * commpoint is closed and deleted in your callback.  So that after
377369c6923SCy Schubert 	 * the callback cleans up netevent can see what it has to do.
378369c6923SCy Schubert 	 * Or leave NULL if it is not used at all. */
379369c6923SCy Schubert 	int* tcp_more_write_again;
380369c6923SCy Schubert 
381b7579f77SDag-Erling Smørgrav 	/** if set, read/write completes:
382b7579f77SDag-Erling Smørgrav 		read/write state of tcp is toggled.
383b7579f77SDag-Erling Smørgrav 		buffer reset/bytecount reset.
384b7579f77SDag-Erling Smørgrav 		this flag cleared.
385b7579f77SDag-Erling Smørgrav 	    So that when that is done the callback is called. */
386b7579f77SDag-Erling Smørgrav 	int tcp_do_toggle_rw;
387b7579f77SDag-Erling Smørgrav 
388b5663de9SDag-Erling Smørgrav 	/** timeout in msec for TCP wait times for this connection */
389b5663de9SDag-Erling Smørgrav 	int tcp_timeout_msec;
390b5663de9SDag-Erling Smørgrav 
3914c75e3aaSDag-Erling Smørgrav 	/** if set, tcp keepalive is enabled on this connection */
3924c75e3aaSDag-Erling Smørgrav 	int tcp_keepalive;
3934c75e3aaSDag-Erling Smørgrav 
394b7579f77SDag-Erling Smørgrav 	/** if set, checks for pending error from nonblocking connect() call.*/
395b7579f77SDag-Erling Smørgrav 	int tcp_check_nb_connect;
396b7579f77SDag-Erling Smørgrav 
3974c75e3aaSDag-Erling Smørgrav 	/** if set, check for connection limit on tcp accept. */
3984c75e3aaSDag-Erling Smørgrav 	struct tcl_list* tcp_conn_limit;
3994c75e3aaSDag-Erling Smørgrav 	/** the entry for the connection. */
4004c75e3aaSDag-Erling Smørgrav 	struct tcl_addr* tcl_addr;
4014c75e3aaSDag-Erling Smørgrav 
402e86b9096SDag-Erling Smørgrav 	/** the structure to keep track of open requests on this channel */
403e86b9096SDag-Erling Smørgrav 	struct tcp_req_info* tcp_req_info;
404e86b9096SDag-Erling Smørgrav 
405b5663de9SDag-Erling Smørgrav #ifdef USE_MSG_FASTOPEN
406b5663de9SDag-Erling Smørgrav 	/** used to track if the sendto() call should be done when using TFO. */
407b5663de9SDag-Erling Smørgrav 	int tcp_do_fastopen;
408b5663de9SDag-Erling Smørgrav #endif
409b5663de9SDag-Erling Smørgrav 
41065b390aaSDag-Erling Smørgrav #ifdef USE_DNSCRYPT
41165b390aaSDag-Erling Smørgrav 	/** Is this a dnscrypt channel */
41265b390aaSDag-Erling Smørgrav 	int dnscrypt;
41365b390aaSDag-Erling Smørgrav 	/** encrypted buffer pointer. Either to perthread, or own buffer or NULL */
41465b390aaSDag-Erling Smørgrav 	struct sldns_buffer* dnscrypt_buffer;
41565b390aaSDag-Erling Smørgrav #endif
416b7579f77SDag-Erling Smørgrav 	/** number of queries outstanding on this socket, used by
417b7579f77SDag-Erling Smørgrav 	 * outside network for udp ports */
418b7579f77SDag-Erling Smørgrav 	int inuse;
4198f76bb7dSCy Schubert 	/** the timestamp when the packet was received by the kernel */
4208f76bb7dSCy Schubert 	struct timeval recv_tv;
421b7579f77SDag-Erling Smørgrav 	/** callback when done.
422b7579f77SDag-Erling Smørgrav 	    tcp_accept does not get called back, is NULL then.
423b7579f77SDag-Erling Smørgrav 	    If a timeout happens, callback with timeout=1 is called.
424b7579f77SDag-Erling Smørgrav 	    If an error happens, callback is called with error set
425b7579f77SDag-Erling Smørgrav 	    nonzero. If not NETEVENT_NOERROR, it is an errno value.
426b7579f77SDag-Erling Smørgrav 	    If the connection is closed (by remote end) then the
427b7579f77SDag-Erling Smørgrav 	    callback is called with error set to NETEVENT_CLOSED=-1.
428b7579f77SDag-Erling Smørgrav 	    If a timeout happens on the connection, the error is set to
429b7579f77SDag-Erling Smørgrav 	    NETEVENT_TIMEOUT=-2.
430b7579f77SDag-Erling Smørgrav 	    The reply_info can be copied if the reply needs to happen at a
431b7579f77SDag-Erling Smørgrav 	    later time. It consists of a struct with commpoint and address.
432b7579f77SDag-Erling Smørgrav 	    It can be passed to a msg send routine some time later.
433b7579f77SDag-Erling Smørgrav 	    Note the reply information is temporary and must be copied.
434b7579f77SDag-Erling Smørgrav 	    NULL is passed for_reply info, in cases where error happened.
435b7579f77SDag-Erling Smørgrav 
436b7579f77SDag-Erling Smørgrav 	    declare as:
437b7579f77SDag-Erling Smørgrav 	    int my_callback(struct comm_point* c, void* my_arg, int error,
438b7579f77SDag-Erling Smørgrav 		struct comm_reply *reply_info);
439b7579f77SDag-Erling Smørgrav 
440b7579f77SDag-Erling Smørgrav 	    if the routine returns 0, nothing is done.
441b7579f77SDag-Erling Smørgrav 	    Notzero, the buffer will be sent back to client.
442b7579f77SDag-Erling Smørgrav 	    		For UDP this is done without changing the commpoint.
443b7579f77SDag-Erling Smørgrav 			In TCP it sets write state.
444b7579f77SDag-Erling Smørgrav 	*/
4453005e0a3SDag-Erling Smørgrav 	comm_point_callback_type* callback;
446b7579f77SDag-Erling Smørgrav 	/** argument to pass to callback. */
447b7579f77SDag-Erling Smørgrav 	void *cb_arg;
448b7579f77SDag-Erling Smørgrav };
449b7579f77SDag-Erling Smørgrav 
450b7579f77SDag-Erling Smørgrav /**
451b7579f77SDag-Erling Smørgrav  * Structure only for making timeout events.
452b7579f77SDag-Erling Smørgrav  */
453b7579f77SDag-Erling Smørgrav struct comm_timer {
454e2d15004SDag-Erling Smørgrav 	/** the internal event stuff (derived) */
455b7579f77SDag-Erling Smørgrav 	struct internal_timer* ev_timer;
456b7579f77SDag-Erling Smørgrav 
457b7579f77SDag-Erling Smørgrav 	/** callback function, takes user arg only */
458b7579f77SDag-Erling Smørgrav 	void (*callback)(void*);
459b7579f77SDag-Erling Smørgrav 
460b7579f77SDag-Erling Smørgrav 	/** callback user argument */
461b7579f77SDag-Erling Smørgrav 	void* cb_arg;
462b7579f77SDag-Erling Smørgrav };
463b7579f77SDag-Erling Smørgrav 
464b7579f77SDag-Erling Smørgrav /**
465b7579f77SDag-Erling Smørgrav  * Structure only for signal events.
466b7579f77SDag-Erling Smørgrav  */
467b7579f77SDag-Erling Smørgrav struct comm_signal {
468b7579f77SDag-Erling Smørgrav 	/** the communication base */
469b7579f77SDag-Erling Smørgrav 	struct comm_base* base;
470b7579f77SDag-Erling Smørgrav 
471b7579f77SDag-Erling Smørgrav 	/** the internal event stuff */
472b7579f77SDag-Erling Smørgrav 	struct internal_signal* ev_signal;
473b7579f77SDag-Erling Smørgrav 
474b7579f77SDag-Erling Smørgrav 	/** callback function, takes signal number and user arg */
475b7579f77SDag-Erling Smørgrav 	void (*callback)(int, void*);
476b7579f77SDag-Erling Smørgrav 
477b7579f77SDag-Erling Smørgrav 	/** callback user argument */
478b7579f77SDag-Erling Smørgrav 	void* cb_arg;
479b7579f77SDag-Erling Smørgrav };
480b7579f77SDag-Erling Smørgrav 
481b7579f77SDag-Erling Smørgrav /**
482b7579f77SDag-Erling Smørgrav  * Create a new comm base.
483b7579f77SDag-Erling Smørgrav  * @param sigs: if true it attempts to create a default loop for
484b7579f77SDag-Erling Smørgrav  *   signal handling.
485b7579f77SDag-Erling Smørgrav  * @return: the new comm base. NULL on error.
486b7579f77SDag-Erling Smørgrav  */
487b7579f77SDag-Erling Smørgrav struct comm_base* comm_base_create(int sigs);
488b7579f77SDag-Erling Smørgrav 
489b7579f77SDag-Erling Smørgrav /**
490e2d15004SDag-Erling Smørgrav  * Create comm base that uses the given ub_event_base (underlying pluggable
491e2d15004SDag-Erling Smørgrav  * event mechanism pointer).
492e2d15004SDag-Erling Smørgrav  * @param base: underlying pluggable event base.
49317d15b25SDag-Erling Smørgrav  * @return: the new comm base. NULL on error.
49417d15b25SDag-Erling Smørgrav  */
495e2d15004SDag-Erling Smørgrav struct comm_base* comm_base_create_event(struct ub_event_base* base);
49617d15b25SDag-Erling Smørgrav 
49717d15b25SDag-Erling Smørgrav /**
49817d15b25SDag-Erling Smørgrav  * Delete comm base structure but not the underlying lib event base.
49917d15b25SDag-Erling Smørgrav  * All comm points must have been deleted.
50017d15b25SDag-Erling Smørgrav  * @param b: the base to delete.
50117d15b25SDag-Erling Smørgrav  */
50217d15b25SDag-Erling Smørgrav void comm_base_delete_no_base(struct comm_base* b);
50317d15b25SDag-Erling Smørgrav 
50417d15b25SDag-Erling Smørgrav /**
505b7579f77SDag-Erling Smørgrav  * Destroy a comm base.
506b7579f77SDag-Erling Smørgrav  * All comm points must have been deleted.
507b7579f77SDag-Erling Smørgrav  * @param b: the base to delete.
508b7579f77SDag-Erling Smørgrav  */
509b7579f77SDag-Erling Smørgrav void comm_base_delete(struct comm_base* b);
510b7579f77SDag-Erling Smørgrav 
511b7579f77SDag-Erling Smørgrav /**
512b7579f77SDag-Erling Smørgrav  * Obtain two pointers. The pointers never change (until base_delete()).
513b7579f77SDag-Erling Smørgrav  * The pointers point to time values that are updated regularly.
514b7579f77SDag-Erling Smørgrav  * @param b: the communication base that will update the time values.
515b7579f77SDag-Erling Smørgrav  * @param tt: pointer to time in seconds is returned.
516b7579f77SDag-Erling Smørgrav  * @param tv: pointer to time in microseconds is returned.
517b7579f77SDag-Erling Smørgrav  */
51817d15b25SDag-Erling Smørgrav void comm_base_timept(struct comm_base* b, time_t** tt, struct timeval** tv);
519b7579f77SDag-Erling Smørgrav 
520b7579f77SDag-Erling Smørgrav /**
521b7579f77SDag-Erling Smørgrav  * Dispatch the comm base events.
522b7579f77SDag-Erling Smørgrav  * @param b: the communication to perform.
523b7579f77SDag-Erling Smørgrav  */
524b7579f77SDag-Erling Smørgrav void comm_base_dispatch(struct comm_base* b);
525b7579f77SDag-Erling Smørgrav 
526b7579f77SDag-Erling Smørgrav /**
527b7579f77SDag-Erling Smørgrav  * Exit from dispatch loop.
528b7579f77SDag-Erling Smørgrav  * @param b: the communication base that is in dispatch().
529b7579f77SDag-Erling Smørgrav  */
530b7579f77SDag-Erling Smørgrav void comm_base_exit(struct comm_base* b);
531b7579f77SDag-Erling Smørgrav 
532b7579f77SDag-Erling Smørgrav /**
533b7579f77SDag-Erling Smørgrav  * Set the slow_accept mode handlers.  You can not provide these if you do
534b7579f77SDag-Erling Smørgrav  * not perform accept() calls.
535b7579f77SDag-Erling Smørgrav  * @param b: comm base
536b7579f77SDag-Erling Smørgrav  * @param stop_accept: function that stops listening to accept fds.
537b7579f77SDag-Erling Smørgrav  * @param start_accept: function that resumes listening to accept fds.
538b7579f77SDag-Erling Smørgrav  * @param arg: callback arg to pass to the functions.
539b7579f77SDag-Erling Smørgrav  */
540b7579f77SDag-Erling Smørgrav void comm_base_set_slow_accept_handlers(struct comm_base* b,
541b7579f77SDag-Erling Smørgrav 	void (*stop_accept)(void*), void (*start_accept)(void*), void* arg);
542b7579f77SDag-Erling Smørgrav 
543b7579f77SDag-Erling Smørgrav /**
544b7579f77SDag-Erling Smørgrav  * Access internal data structure (for util/tube.c on windows)
545b7579f77SDag-Erling Smørgrav  * @param b: comm base
546e2d15004SDag-Erling Smørgrav  * @return ub_event_base.
547b7579f77SDag-Erling Smørgrav  */
548e2d15004SDag-Erling Smørgrav struct ub_event_base* comm_base_internal(struct comm_base* b);
549b7579f77SDag-Erling Smørgrav 
550b7579f77SDag-Erling Smørgrav /**
551b7579f77SDag-Erling Smørgrav  * Create an UDP comm point. Calls malloc.
552b7579f77SDag-Erling Smørgrav  * setups the structure with the parameters you provide.
553b7579f77SDag-Erling Smørgrav  * @param base: in which base to alloc the commpoint.
554b7579f77SDag-Erling Smørgrav  * @param fd: file descriptor of open UDP socket.
555b7579f77SDag-Erling Smørgrav  * @param buffer: shared buffer by UDP sockets from this thread.
556865f46b2SCy Schubert  * @param pp2_enabled: if the comm point will support PROXYv2.
557b7579f77SDag-Erling Smørgrav  * @param callback: callback function pointer.
558b7579f77SDag-Erling Smørgrav  * @param callback_arg: will be passed to your callback function.
5595469a995SCy Schubert  * @param socket: and opened socket properties will be passed to your callback function.
560b7579f77SDag-Erling Smørgrav  * @return: returns the allocated communication point. NULL on error.
561b7579f77SDag-Erling Smørgrav  * Sets timeout to NULL. Turns off TCP options.
562b7579f77SDag-Erling Smørgrav  */
563b7579f77SDag-Erling Smørgrav struct comm_point* comm_point_create_udp(struct comm_base* base,
564865f46b2SCy Schubert 	int fd, struct sldns_buffer* buffer, int pp2_enabled,
5655469a995SCy Schubert 	comm_point_callback_type* callback, void* callback_arg, struct unbound_socket* socket);
566b7579f77SDag-Erling Smørgrav 
567b7579f77SDag-Erling Smørgrav /**
568b7579f77SDag-Erling Smørgrav  * Create an UDP with ancillary data comm point. Calls malloc.
569b7579f77SDag-Erling Smørgrav  * Uses recvmsg instead of recv to get udp message.
570b7579f77SDag-Erling Smørgrav  * setups the structure with the parameters you provide.
571b7579f77SDag-Erling Smørgrav  * @param base: in which base to alloc the commpoint.
572b7579f77SDag-Erling Smørgrav  * @param fd: file descriptor of open UDP socket.
573b7579f77SDag-Erling Smørgrav  * @param buffer: shared buffer by UDP sockets from this thread.
574865f46b2SCy Schubert  * @param pp2_enabled: if the comm point will support PROXYv2.
575b7579f77SDag-Erling Smørgrav  * @param callback: callback function pointer.
576b7579f77SDag-Erling Smørgrav  * @param callback_arg: will be passed to your callback function.
5775469a995SCy Schubert  * @param socket: and opened socket properties will be passed to your callback function.
578b7579f77SDag-Erling Smørgrav  * @return: returns the allocated communication point. NULL on error.
579b7579f77SDag-Erling Smørgrav  * Sets timeout to NULL. Turns off TCP options.
580b7579f77SDag-Erling Smørgrav  */
581b7579f77SDag-Erling Smørgrav struct comm_point* comm_point_create_udp_ancil(struct comm_base* base,
582865f46b2SCy Schubert 	int fd, struct sldns_buffer* buffer, int pp2_enabled,
5835469a995SCy Schubert 	comm_point_callback_type* callback, void* callback_arg, struct unbound_socket* socket);
584b7579f77SDag-Erling Smørgrav 
585b7579f77SDag-Erling Smørgrav /**
586*46d2f618SCy Schubert  * Create an UDP comm point for DoQ. Calls malloc.
587*46d2f618SCy Schubert  * setups the structure with the parameters you provide.
588*46d2f618SCy Schubert  * @param base: in which base to alloc the commpoint.
589*46d2f618SCy Schubert  * @param fd : file descriptor of open UDP socket.
590*46d2f618SCy Schubert  * @param buffer: shared buffer by UDP sockets from this thread.
591*46d2f618SCy Schubert  * @param callback: callback function pointer.
592*46d2f618SCy Schubert  * @param callback_arg: will be passed to your callback function.
593*46d2f618SCy Schubert  * @param socket: and opened socket properties will be passed to your callback function.
594*46d2f618SCy Schubert  * @param table: the doq connection table for the host.
595*46d2f618SCy Schubert  * @param rnd: random generator to use.
596*46d2f618SCy Schubert  * @param ssl_service_key: the ssl service key file.
597*46d2f618SCy Schubert  * @param ssl_service_pem: the ssl service pem file.
598*46d2f618SCy Schubert  * @param cfg: config file struct.
599*46d2f618SCy Schubert  * @return: returns the allocated communication point. NULL on error.
600*46d2f618SCy Schubert  * Sets timeout to NULL. Turns off TCP options.
601*46d2f618SCy Schubert  */
602*46d2f618SCy Schubert struct comm_point* comm_point_create_doq(struct comm_base* base,
603*46d2f618SCy Schubert 	int fd, struct sldns_buffer* buffer,
604*46d2f618SCy Schubert 	comm_point_callback_type* callback, void* callback_arg,
605*46d2f618SCy Schubert 	struct unbound_socket* socket, struct doq_table* table,
606*46d2f618SCy Schubert 	struct ub_randstate* rnd, const char* ssl_service_key,
607*46d2f618SCy Schubert 	const char* ssl_service_pem, struct config_file* cfg);
608*46d2f618SCy Schubert 
609*46d2f618SCy Schubert /**
610b7579f77SDag-Erling Smørgrav  * Create a TCP listener comm point. Calls malloc.
611b7579f77SDag-Erling Smørgrav  * Setups the structure with the parameters you provide.
612b7579f77SDag-Erling Smørgrav  * Also Creates TCP Handlers, pre allocated for you.
613b7579f77SDag-Erling Smørgrav  * Uses the parameters you provide.
614b7579f77SDag-Erling Smørgrav  * @param base: in which base to alloc the commpoint.
615b7579f77SDag-Erling Smørgrav  * @param fd: file descriptor of open TCP socket set to listen nonblocking.
616b7579f77SDag-Erling Smørgrav  * @param num: becomes max_tcp_count, the routine allocates that
617b7579f77SDag-Erling Smørgrav  *	many tcp handler commpoints.
6184c75e3aaSDag-Erling Smørgrav  * @param idle_timeout: TCP idle timeout in ms.
619c0caa2e2SCy Schubert  * @param harden_large_queries: whether query size should be limited.
620c0caa2e2SCy Schubert  * @param http_max_streams: maximum number of HTTP/2 streams per connection.
621c0caa2e2SCy Schubert  * @param http_endpoint: HTTP endpoint to service queries on
6224c75e3aaSDag-Erling Smørgrav  * @param tcp_conn_limit: TCP connection limit info.
623b7579f77SDag-Erling Smørgrav  * @param bufsize: size of buffer to create for handlers.
624e86b9096SDag-Erling Smørgrav  * @param spoolbuf: shared spool buffer for tcp_req_info structures.
625e86b9096SDag-Erling Smørgrav  * 	or NULL to not create those structures in the tcp handlers.
626c0caa2e2SCy Schubert  * @param port_type: the type of port we are creating a TCP listener for. Used
627c0caa2e2SCy Schubert  * 	to select handler type to use.
628865f46b2SCy Schubert  * @param pp2_enabled: if the comm point will support PROXYv2.
629b7579f77SDag-Erling Smørgrav  * @param callback: callback function pointer for TCP handlers.
630b7579f77SDag-Erling Smørgrav  * @param callback_arg: will be passed to your callback function.
6315469a995SCy Schubert  * @param socket: and opened socket properties will be passed to your callback function.
632b7579f77SDag-Erling Smørgrav  * @return: returns the TCP listener commpoint. You can find the
633b7579f77SDag-Erling Smørgrav  *  	TCP handlers in the array inside the listener commpoint.
634b7579f77SDag-Erling Smørgrav  *	returns NULL on error.
635b7579f77SDag-Erling Smørgrav  * Inits timeout to NULL. All handlers are on the free list.
636b7579f77SDag-Erling Smørgrav  */
637b7579f77SDag-Erling Smørgrav struct comm_point* comm_point_create_tcp(struct comm_base* base,
638c0caa2e2SCy Schubert 	int fd, int num, int idle_timeout, int harden_large_queries,
639c0caa2e2SCy Schubert 	uint32_t http_max_streams, char* http_endpoint,
640c0caa2e2SCy Schubert 	struct tcl_list* tcp_conn_limit,
641e86b9096SDag-Erling Smørgrav 	size_t bufsize, struct sldns_buffer* spoolbuf,
642865f46b2SCy Schubert 	enum listen_type port_type, int pp2_enabled,
6435469a995SCy Schubert 	comm_point_callback_type* callback, void* callback_arg, struct unbound_socket* socket);
644b7579f77SDag-Erling Smørgrav 
645b7579f77SDag-Erling Smørgrav /**
646b7579f77SDag-Erling Smørgrav  * Create an outgoing TCP commpoint. No file descriptor is opened, left at -1.
647b7579f77SDag-Erling Smørgrav  * @param base: in which base to alloc the commpoint.
648b7579f77SDag-Erling Smørgrav  * @param bufsize: size of buffer to create for handlers.
649b7579f77SDag-Erling Smørgrav  * @param callback: callback function pointer for the handler.
650b7579f77SDag-Erling Smørgrav  * @param callback_arg: will be passed to your callback function.
651b7579f77SDag-Erling Smørgrav  * @return: the commpoint or NULL on error.
652b7579f77SDag-Erling Smørgrav  */
653b7579f77SDag-Erling Smørgrav struct comm_point* comm_point_create_tcp_out(struct comm_base* base,
6543005e0a3SDag-Erling Smørgrav 	size_t bufsize, comm_point_callback_type* callback, void* callback_arg);
655b7579f77SDag-Erling Smørgrav 
656b7579f77SDag-Erling Smørgrav /**
65757bddd21SDag-Erling Smørgrav  * Create an outgoing HTTP commpoint. No file descriptor is opened, left at -1.
65857bddd21SDag-Erling Smørgrav  * @param base: in which base to alloc the commpoint.
65957bddd21SDag-Erling Smørgrav  * @param bufsize: size of buffer to create for handlers.
66057bddd21SDag-Erling Smørgrav  * @param callback: callback function pointer for the handler.
66157bddd21SDag-Erling Smørgrav  * @param callback_arg: will be passed to your callback function.
66257bddd21SDag-Erling Smørgrav  * @param temp: sldns buffer, shared between other http_out commpoints, for
66357bddd21SDag-Erling Smørgrav  * 	temporary data when performing callbacks.
66457bddd21SDag-Erling Smørgrav  * @return: the commpoint or NULL on error.
66557bddd21SDag-Erling Smørgrav  */
66657bddd21SDag-Erling Smørgrav struct comm_point* comm_point_create_http_out(struct comm_base* base,
66757bddd21SDag-Erling Smørgrav 	size_t bufsize, comm_point_callback_type* callback,
66857bddd21SDag-Erling Smørgrav 	void* callback_arg, struct sldns_buffer* temp);
66957bddd21SDag-Erling Smørgrav 
67057bddd21SDag-Erling Smørgrav /**
671b7579f77SDag-Erling Smørgrav  * Create commpoint to listen to a local domain file descriptor.
672b7579f77SDag-Erling Smørgrav  * @param base: in which base to alloc the commpoint.
673b7579f77SDag-Erling Smørgrav  * @param fd: file descriptor of open AF_UNIX socket set to listen nonblocking.
674b7579f77SDag-Erling Smørgrav  * @param bufsize: size of buffer to create for handlers.
675b7579f77SDag-Erling Smørgrav  * @param callback: callback function pointer for the handler.
676b7579f77SDag-Erling Smørgrav  * @param callback_arg: will be passed to your callback function.
677b7579f77SDag-Erling Smørgrav  * @return: the commpoint or NULL on error.
678b7579f77SDag-Erling Smørgrav  */
679b7579f77SDag-Erling Smørgrav struct comm_point* comm_point_create_local(struct comm_base* base,
680b7579f77SDag-Erling Smørgrav 	int fd, size_t bufsize,
6813005e0a3SDag-Erling Smørgrav 	comm_point_callback_type* callback, void* callback_arg);
682b7579f77SDag-Erling Smørgrav 
683b7579f77SDag-Erling Smørgrav /**
684b7579f77SDag-Erling Smørgrav  * Create commpoint to listen to a local domain pipe descriptor.
685b7579f77SDag-Erling Smørgrav  * @param base: in which base to alloc the commpoint.
686b7579f77SDag-Erling Smørgrav  * @param fd: file descriptor.
687b7579f77SDag-Erling Smørgrav  * @param writing: true if you want to listen to writes, false for reads.
688b7579f77SDag-Erling Smørgrav  * @param callback: callback function pointer for the handler.
689b7579f77SDag-Erling Smørgrav  * @param callback_arg: will be passed to your callback function.
690b7579f77SDag-Erling Smørgrav  * @return: the commpoint or NULL on error.
691b7579f77SDag-Erling Smørgrav  */
692b7579f77SDag-Erling Smørgrav struct comm_point* comm_point_create_raw(struct comm_base* base,
693b7579f77SDag-Erling Smørgrav 	int fd, int writing,
6943005e0a3SDag-Erling Smørgrav 	comm_point_callback_type* callback, void* callback_arg);
695b7579f77SDag-Erling Smørgrav 
696b7579f77SDag-Erling Smørgrav /**
697b7579f77SDag-Erling Smørgrav  * Close a comm point fd.
698b7579f77SDag-Erling Smørgrav  * @param c: comm point to close.
699b7579f77SDag-Erling Smørgrav  */
700b7579f77SDag-Erling Smørgrav void comm_point_close(struct comm_point* c);
701b7579f77SDag-Erling Smørgrav 
702b7579f77SDag-Erling Smørgrav /**
703b7579f77SDag-Erling Smørgrav  * Close and deallocate (free) the comm point. If the comm point is
704b7579f77SDag-Erling Smørgrav  * a tcp-accept point, also its tcp-handler points are deleted.
705b7579f77SDag-Erling Smørgrav  * @param c: comm point to delete.
706b7579f77SDag-Erling Smørgrav  */
707b7579f77SDag-Erling Smørgrav void comm_point_delete(struct comm_point* c);
708b7579f77SDag-Erling Smørgrav 
709b7579f77SDag-Erling Smørgrav /**
710b7579f77SDag-Erling Smørgrav  * Send reply. Put message into commpoint buffer.
711b7579f77SDag-Erling Smørgrav  * @param repinfo: The reply info copied from a commpoint callback call.
712b7579f77SDag-Erling Smørgrav  */
713b7579f77SDag-Erling Smørgrav void comm_point_send_reply(struct comm_reply* repinfo);
714b7579f77SDag-Erling Smørgrav 
715b7579f77SDag-Erling Smørgrav /**
716b7579f77SDag-Erling Smørgrav  * Drop reply. Cleans up.
717b7579f77SDag-Erling Smørgrav  * @param repinfo: The reply info copied from a commpoint callback call.
718b7579f77SDag-Erling Smørgrav  */
719b7579f77SDag-Erling Smørgrav void comm_point_drop_reply(struct comm_reply* repinfo);
720b7579f77SDag-Erling Smørgrav 
721b7579f77SDag-Erling Smørgrav /**
722b7579f77SDag-Erling Smørgrav  * Send an udp message over a commpoint.
723b7579f77SDag-Erling Smørgrav  * @param c: commpoint to send it from.
724b7579f77SDag-Erling Smørgrav  * @param packet: what to send.
725369c6923SCy Schubert  * @param addr: where to send it to.   If NULL, send is performed,
726369c6923SCy Schubert  * 	for connected sockets, to the connected address.
727b7579f77SDag-Erling Smørgrav  * @param addrlen: length of addr.
7287341cb0cSXin LI  * @param is_connected: if the UDP socket is connect()ed.
729b7579f77SDag-Erling Smørgrav  * @return: false on a failure.
730b7579f77SDag-Erling Smørgrav  */
73117d15b25SDag-Erling Smørgrav int comm_point_send_udp_msg(struct comm_point* c, struct sldns_buffer* packet,
7327341cb0cSXin LI 	struct sockaddr* addr, socklen_t addrlen,int is_connected);
733b7579f77SDag-Erling Smørgrav 
734b7579f77SDag-Erling Smørgrav /**
735b7579f77SDag-Erling Smørgrav  * Stop listening for input on the commpoint. No callbacks will happen.
736b7579f77SDag-Erling Smørgrav  * @param c: commpoint to disable. The fd is not closed.
737b7579f77SDag-Erling Smørgrav  */
738b7579f77SDag-Erling Smørgrav void comm_point_stop_listening(struct comm_point* c);
739b7579f77SDag-Erling Smørgrav 
740b7579f77SDag-Erling Smørgrav /**
741b7579f77SDag-Erling Smørgrav  * Start listening again for input on the comm point.
742b7579f77SDag-Erling Smørgrav  * @param c: commpoint to enable again.
743b7579f77SDag-Erling Smørgrav  * @param newfd: new fd, or -1 to leave fd be.
744b5663de9SDag-Erling Smørgrav  * @param msec: timeout in milliseconds, or -1 for no (change to the) timeout.
745b5663de9SDag-Erling Smørgrav  *	So seconds*1000.
746b7579f77SDag-Erling Smørgrav  */
747b5663de9SDag-Erling Smørgrav void comm_point_start_listening(struct comm_point* c, int newfd, int msec);
748b7579f77SDag-Erling Smørgrav 
749b7579f77SDag-Erling Smørgrav /**
750b7579f77SDag-Erling Smørgrav  * Stop listening and start listening again for reading or writing.
751b7579f77SDag-Erling Smørgrav  * @param c: commpoint
752b7579f77SDag-Erling Smørgrav  * @param rd: if true, listens for reading.
753b7579f77SDag-Erling Smørgrav  * @param wr: if true, listens for writing.
754b7579f77SDag-Erling Smørgrav  */
755b7579f77SDag-Erling Smørgrav void comm_point_listen_for_rw(struct comm_point* c, int rd, int wr);
756b7579f77SDag-Erling Smørgrav 
757b7579f77SDag-Erling Smørgrav /**
758f44e67d1SCy Schubert  * For TCP handlers that use c->tcp_timeout_msec, this routine adjusts
759f44e67d1SCy Schubert  * it with the minimum.  Otherwise, a 0 value advertised without the
760f44e67d1SCy Schubert  * minimum applied moves to a 0 in comm_point_start_listening and that
761f44e67d1SCy Schubert  * routine treats it as no timeout, listen forever, which is not wanted.
762f44e67d1SCy Schubert  * @param c: comm point to use the tcp_timeout_msec of.
763f44e67d1SCy Schubert  * @return adjusted tcp_timeout_msec value with the minimum if smaller.
764f44e67d1SCy Schubert  */
765f44e67d1SCy Schubert int adjusted_tcp_timeout(struct comm_point* c);
766f44e67d1SCy Schubert 
767f44e67d1SCy Schubert /**
768b7579f77SDag-Erling Smørgrav  * Get size of memory used by comm point.
769b7579f77SDag-Erling Smørgrav  * For TCP handlers this includes subhandlers.
770b7579f77SDag-Erling Smørgrav  * For UDP handlers, this does not include the (shared) UDP buffer.
771b7579f77SDag-Erling Smørgrav  * @param c: commpoint.
772b7579f77SDag-Erling Smørgrav  * @return size in bytes.
773b7579f77SDag-Erling Smørgrav  */
774b7579f77SDag-Erling Smørgrav size_t comm_point_get_mem(struct comm_point* c);
775b7579f77SDag-Erling Smørgrav 
776b7579f77SDag-Erling Smørgrav /**
777b7579f77SDag-Erling Smørgrav  * create timer. Not active upon creation.
778b7579f77SDag-Erling Smørgrav  * @param base: event handling base.
779b7579f77SDag-Erling Smørgrav  * @param cb: callback function: void myfunc(void* myarg);
780b7579f77SDag-Erling Smørgrav  * @param cb_arg: user callback argument.
781b7579f77SDag-Erling Smørgrav  * @return: the new timer or NULL on error.
782b7579f77SDag-Erling Smørgrav  */
783b7579f77SDag-Erling Smørgrav struct comm_timer* comm_timer_create(struct comm_base* base,
784b7579f77SDag-Erling Smørgrav 	void (*cb)(void*), void* cb_arg);
785b7579f77SDag-Erling Smørgrav 
786b7579f77SDag-Erling Smørgrav /**
787b7579f77SDag-Erling Smørgrav  * disable timer. Stops callbacks from happening.
788b7579f77SDag-Erling Smørgrav  * @param timer: to disable.
789b7579f77SDag-Erling Smørgrav  */
790b7579f77SDag-Erling Smørgrav void comm_timer_disable(struct comm_timer* timer);
791b7579f77SDag-Erling Smørgrav 
792b7579f77SDag-Erling Smørgrav /**
793b7579f77SDag-Erling Smørgrav  * reset timevalue for timer.
794b7579f77SDag-Erling Smørgrav  * @param timer: timer to (re)set.
795b7579f77SDag-Erling Smørgrav  * @param tv: when the timer should activate. if NULL timer is disabled.
796b7579f77SDag-Erling Smørgrav  */
797b7579f77SDag-Erling Smørgrav void comm_timer_set(struct comm_timer* timer, struct timeval* tv);
798b7579f77SDag-Erling Smørgrav 
799b7579f77SDag-Erling Smørgrav /**
800b7579f77SDag-Erling Smørgrav  * delete timer.
801b7579f77SDag-Erling Smørgrav  * @param timer: to delete.
802b7579f77SDag-Erling Smørgrav  */
803b7579f77SDag-Erling Smørgrav void comm_timer_delete(struct comm_timer* timer);
804b7579f77SDag-Erling Smørgrav 
805b7579f77SDag-Erling Smørgrav /**
806b7579f77SDag-Erling Smørgrav  * see if timeout has been set to a value.
807b7579f77SDag-Erling Smørgrav  * @param timer: the timer to examine.
808b7579f77SDag-Erling Smørgrav  * @return: false if disabled or not set.
809b7579f77SDag-Erling Smørgrav  */
810b7579f77SDag-Erling Smørgrav int comm_timer_is_set(struct comm_timer* timer);
811b7579f77SDag-Erling Smørgrav 
812b7579f77SDag-Erling Smørgrav /**
813b7579f77SDag-Erling Smørgrav  * Get size of memory used by comm timer.
814b7579f77SDag-Erling Smørgrav  * @param timer: the timer to examine.
815b7579f77SDag-Erling Smørgrav  * @return size in bytes.
816b7579f77SDag-Erling Smørgrav  */
817b7579f77SDag-Erling Smørgrav size_t comm_timer_get_mem(struct comm_timer* timer);
818b7579f77SDag-Erling Smørgrav 
819b7579f77SDag-Erling Smørgrav /**
820b7579f77SDag-Erling Smørgrav  * Create a signal handler. Call signal_bind() later to bind to a signal.
821b7579f77SDag-Erling Smørgrav  * @param base: communication base to use.
822b7579f77SDag-Erling Smørgrav  * @param callback: called when signal is caught.
823b7579f77SDag-Erling Smørgrav  * @param cb_arg: user argument to callback
824b7579f77SDag-Erling Smørgrav  * @return: the signal struct or NULL on error.
825b7579f77SDag-Erling Smørgrav  */
826b7579f77SDag-Erling Smørgrav struct comm_signal* comm_signal_create(struct comm_base* base,
827b7579f77SDag-Erling Smørgrav 	void (*callback)(int, void*), void* cb_arg);
828b7579f77SDag-Erling Smørgrav 
829b7579f77SDag-Erling Smørgrav /**
83024e36522SCy Schubert  * Bind signal struct to catch a signal. A single comm_signal can be bound
831b7579f77SDag-Erling Smørgrav  * to multiple signals, calling comm_signal_bind multiple times.
832b7579f77SDag-Erling Smørgrav  * @param comsig: the communication point, with callback information.
833b7579f77SDag-Erling Smørgrav  * @param sig: signal number.
834b7579f77SDag-Erling Smørgrav  * @return: true on success. false on error.
835b7579f77SDag-Erling Smørgrav  */
836b7579f77SDag-Erling Smørgrav int comm_signal_bind(struct comm_signal* comsig, int sig);
837b7579f77SDag-Erling Smørgrav 
838b7579f77SDag-Erling Smørgrav /**
839b7579f77SDag-Erling Smørgrav  * Delete the signal communication point.
840b7579f77SDag-Erling Smørgrav  * @param comsig: to delete.
841b7579f77SDag-Erling Smørgrav  */
842b7579f77SDag-Erling Smørgrav void comm_signal_delete(struct comm_signal* comsig);
843b7579f77SDag-Erling Smørgrav 
844b7579f77SDag-Erling Smørgrav /**
845b7579f77SDag-Erling Smørgrav  * perform accept(2) with error checking.
846b7579f77SDag-Erling Smørgrav  * @param c: commpoint with accept fd.
847b7579f77SDag-Erling Smørgrav  * @param addr: remote end returned here.
848b7579f77SDag-Erling Smørgrav  * @param addrlen: length of remote end returned here.
849b7579f77SDag-Erling Smørgrav  * @return new fd, or -1 on error.
850b7579f77SDag-Erling Smørgrav  *	if -1, error message has been printed if necessary, simply drop
851b7579f77SDag-Erling Smørgrav  *	out of the reading handler.
852b7579f77SDag-Erling Smørgrav  */
853b7579f77SDag-Erling Smørgrav int comm_point_perform_accept(struct comm_point* c,
854b7579f77SDag-Erling Smørgrav 	struct sockaddr_storage* addr, socklen_t* addrlen);
855b7579f77SDag-Erling Smørgrav 
856b7579f77SDag-Erling Smørgrav /**** internal routines ****/
857b7579f77SDag-Erling Smørgrav 
858b7579f77SDag-Erling Smørgrav /**
859b7579f77SDag-Erling Smørgrav  * This routine is published for checks and tests, and is only used internally.
860b7579f77SDag-Erling Smørgrav  * handle libevent callback for udp comm point.
861b7579f77SDag-Erling Smørgrav  * @param fd: file descriptor.
862b7579f77SDag-Erling Smørgrav  * @param event: event bits from libevent:
863b7579f77SDag-Erling Smørgrav  *	EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT.
864b7579f77SDag-Erling Smørgrav  * @param arg: the comm_point structure.
865b7579f77SDag-Erling Smørgrav  */
866b7579f77SDag-Erling Smørgrav void comm_point_udp_callback(int fd, short event, void* arg);
867b7579f77SDag-Erling Smørgrav 
868b7579f77SDag-Erling Smørgrav /**
869b7579f77SDag-Erling Smørgrav  * This routine is published for checks and tests, and is only used internally.
870b7579f77SDag-Erling Smørgrav  * handle libevent callback for udp ancillary data comm point.
871b7579f77SDag-Erling Smørgrav  * @param fd: file descriptor.
872b7579f77SDag-Erling Smørgrav  * @param event: event bits from libevent:
873b7579f77SDag-Erling Smørgrav  *	EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT.
874b7579f77SDag-Erling Smørgrav  * @param arg: the comm_point structure.
875b7579f77SDag-Erling Smørgrav  */
876b7579f77SDag-Erling Smørgrav void comm_point_udp_ancil_callback(int fd, short event, void* arg);
877b7579f77SDag-Erling Smørgrav 
878b7579f77SDag-Erling Smørgrav /**
879b7579f77SDag-Erling Smørgrav  * This routine is published for checks and tests, and is only used internally.
880*46d2f618SCy Schubert  * handle libevent callback for doq comm point.
881*46d2f618SCy Schubert  * @param fd: file descriptor.
882*46d2f618SCy Schubert  * @param event: event bits from libevent:
883*46d2f618SCy Schubert  *	EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT.
884*46d2f618SCy Schubert  * @param arg: the comm_point structure.
885*46d2f618SCy Schubert  */
886*46d2f618SCy Schubert void comm_point_doq_callback(int fd, short event, void* arg);
887*46d2f618SCy Schubert 
888*46d2f618SCy Schubert /**
889*46d2f618SCy Schubert  * This routine is published for checks and tests, and is only used internally.
890b7579f77SDag-Erling Smørgrav  * handle libevent callback for tcp accept comm point
891b7579f77SDag-Erling Smørgrav  * @param fd: file descriptor.
892b7579f77SDag-Erling Smørgrav  * @param event: event bits from libevent:
893b7579f77SDag-Erling Smørgrav  *	EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT.
894b7579f77SDag-Erling Smørgrav  * @param arg: the comm_point structure.
895b7579f77SDag-Erling Smørgrav  */
896b7579f77SDag-Erling Smørgrav void comm_point_tcp_accept_callback(int fd, short event, void* arg);
897b7579f77SDag-Erling Smørgrav 
898b7579f77SDag-Erling Smørgrav /**
899b7579f77SDag-Erling Smørgrav  * This routine is published for checks and tests, and is only used internally.
900b7579f77SDag-Erling Smørgrav  * handle libevent callback for tcp data comm point
901b7579f77SDag-Erling Smørgrav  * @param fd: file descriptor.
902b7579f77SDag-Erling Smørgrav  * @param event: event bits from libevent:
903b7579f77SDag-Erling Smørgrav  *	EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT.
904b7579f77SDag-Erling Smørgrav  * @param arg: the comm_point structure.
905b7579f77SDag-Erling Smørgrav  */
906b7579f77SDag-Erling Smørgrav void comm_point_tcp_handle_callback(int fd, short event, void* arg);
907b7579f77SDag-Erling Smørgrav 
908b7579f77SDag-Erling Smørgrav /**
909b7579f77SDag-Erling Smørgrav  * This routine is published for checks and tests, and is only used internally.
91057bddd21SDag-Erling Smørgrav  * handle libevent callback for tcp data comm point
91157bddd21SDag-Erling Smørgrav  * @param fd: file descriptor.
91257bddd21SDag-Erling Smørgrav  * @param event: event bits from libevent:
91357bddd21SDag-Erling Smørgrav  *	EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT.
91457bddd21SDag-Erling Smørgrav  * @param arg: the comm_point structure.
91557bddd21SDag-Erling Smørgrav  */
91657bddd21SDag-Erling Smørgrav void comm_point_http_handle_callback(int fd, short event, void* arg);
91757bddd21SDag-Erling Smørgrav 
91857bddd21SDag-Erling Smørgrav /**
919c0caa2e2SCy Schubert  * HTTP2 session.  HTTP2 related info per comm point.
920c0caa2e2SCy Schubert  */
921c0caa2e2SCy Schubert struct http2_session {
922c0caa2e2SCy Schubert 	/** first item in list of streams */
923c0caa2e2SCy Schubert 	struct http2_stream* first_stream;
924c0caa2e2SCy Schubert #ifdef HAVE_NGHTTP2
925c0caa2e2SCy Schubert 	/** nghttp2 session */
926c0caa2e2SCy Schubert 	nghttp2_session *session;
927c0caa2e2SCy Schubert 	/** store nghttp2 callbacks for easy reuse */
928c0caa2e2SCy Schubert 	nghttp2_session_callbacks* callbacks;
929c0caa2e2SCy Schubert #endif
930c0caa2e2SCy Schubert 	/** comm point containing buffer used to build answer in worker or
931c0caa2e2SCy Schubert 	 * module */
932c0caa2e2SCy Schubert 	struct comm_point* c;
933c0caa2e2SCy Schubert 	/** session is instructed to get dropped (comm port will be closed) */
934c0caa2e2SCy Schubert 	int is_drop;
935c0caa2e2SCy Schubert 	/** postpone dropping the session, can be used to prevent dropping
936c0caa2e2SCy Schubert 	 * while being in a callback */
937c0caa2e2SCy Schubert 	int postpone_drop;
938c0caa2e2SCy Schubert };
939c0caa2e2SCy Schubert 
940c0caa2e2SCy Schubert /** enum of HTTP status */
941c0caa2e2SCy Schubert enum http_status {
942c0caa2e2SCy Schubert 	HTTP_STATUS_OK = 200,
943c0caa2e2SCy Schubert 	HTTP_STATUS_BAD_REQUEST = 400,
944c0caa2e2SCy Schubert 	HTTP_STATUS_NOT_FOUND = 404,
945c0caa2e2SCy Schubert 	HTTP_STATUS_PAYLOAD_TOO_LARGE = 413,
946c0caa2e2SCy Schubert 	HTTP_STATUS_URI_TOO_LONG = 414,
947c0caa2e2SCy Schubert 	HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE = 415,
948c0caa2e2SCy Schubert 	HTTP_STATUS_NOT_IMPLEMENTED = 501
949c0caa2e2SCy Schubert };
950c0caa2e2SCy Schubert 
951c0caa2e2SCy Schubert /**
952c0caa2e2SCy Schubert  * HTTP stream. Part of list of HTTP2 streams per session.
953c0caa2e2SCy Schubert  */
954c0caa2e2SCy Schubert struct http2_stream {
955c0caa2e2SCy Schubert 	/** next stream in list per session */
956c0caa2e2SCy Schubert 	struct http2_stream* next;
957c0caa2e2SCy Schubert 	/** previous stream in list per session */
958c0caa2e2SCy Schubert 	struct http2_stream* prev;
959c0caa2e2SCy Schubert 	/** HTTP2 stream ID is an unsigned 31-bit integer */
960c0caa2e2SCy Schubert 	int32_t stream_id;
961c0caa2e2SCy Schubert 	/** HTTP method used for this stream */
962c0caa2e2SCy Schubert 	enum {
963c0caa2e2SCy Schubert 		HTTP_METHOD_POST = 1,
964c0caa2e2SCy Schubert 		HTTP_METHOD_GET,
965c0caa2e2SCy Schubert 		HTTP_METHOD_UNSUPPORTED
966c0caa2e2SCy Schubert 	} http_method;
967c0caa2e2SCy Schubert 	/** message contains invalid content type */
968c0caa2e2SCy Schubert 	int invalid_content_type;
969c0caa2e2SCy Schubert 	/** message body content type */
970c0caa2e2SCy Schubert 	size_t content_length;
971c0caa2e2SCy Schubert 	/** HTTP response status */
972c0caa2e2SCy Schubert 	enum http_status status;
973c0caa2e2SCy Schubert 	/** request for non existing endpoint */
974c0caa2e2SCy Schubert 	int invalid_endpoint;
975c0caa2e2SCy Schubert 	/** query in request is too large */
976c0caa2e2SCy Schubert 	int query_too_large;
977c0caa2e2SCy Schubert 	/** buffer to store query into. Can't use session shared buffer as query
978c0caa2e2SCy Schubert 	 * can arrive in parts, intertwined with frames for other queries. */
979c0caa2e2SCy Schubert 	struct sldns_buffer* qbuffer;
980c0caa2e2SCy Schubert 	/** buffer to store response into. Can't use shared buffer as a next
981c0caa2e2SCy Schubert 	 * query read callback can overwrite it before it is send out. */
982c0caa2e2SCy Schubert 	struct sldns_buffer* rbuffer;
983c0caa2e2SCy Schubert 	/** mesh area containing mesh state */
984c0caa2e2SCy Schubert 	struct mesh_area* mesh;
985c0caa2e2SCy Schubert 	/** mesh state for query. Used to remove mesh reply before closing
986c0caa2e2SCy Schubert 	 * stream. */
987c0caa2e2SCy Schubert 	struct mesh_state* mesh_state;
988c0caa2e2SCy Schubert };
989c0caa2e2SCy Schubert 
990c0caa2e2SCy Schubert #ifdef HAVE_NGHTTP2
991c0caa2e2SCy Schubert /** nghttp2 receive cb. Read from SSL connection into nghttp2 buffer */
992c0caa2e2SCy Schubert ssize_t http2_recv_cb(nghttp2_session* session, uint8_t* buf,
993c0caa2e2SCy Schubert 	size_t len, int flags, void* cb_arg);
994c0caa2e2SCy Schubert /** nghttp2 send callback. Send from nghttp2 buffer to ssl socket */
995c0caa2e2SCy Schubert ssize_t http2_send_cb(nghttp2_session* session, const uint8_t* buf,
996c0caa2e2SCy Schubert 	size_t len, int flags, void* cb_arg);
997c0caa2e2SCy Schubert /** nghttp2 callback on closing stream */
998c0caa2e2SCy Schubert int http2_stream_close_cb(nghttp2_session* session, int32_t stream_id,
999c0caa2e2SCy Schubert 	uint32_t error_code, void* cb_arg);
1000c0caa2e2SCy Schubert #endif
1001c0caa2e2SCy Schubert 
1002c0caa2e2SCy Schubert /**
1003c0caa2e2SCy Schubert  * Create new http2 stream
1004c0caa2e2SCy Schubert  * @param stream_id: ID for stream to create.
1005c0caa2e2SCy Schubert  * @return malloc'ed stream, NULL on error
1006c0caa2e2SCy Schubert  */
1007c0caa2e2SCy Schubert struct http2_stream* http2_stream_create(int32_t stream_id);
1008c0caa2e2SCy Schubert 
1009c0caa2e2SCy Schubert /**
1010c0caa2e2SCy Schubert  * Add new stream to session linked list
1011c0caa2e2SCy Schubert  * @param h2_session: http2 session to add stream to
1012c0caa2e2SCy Schubert  * @param h2_stream: stream to add to session list
1013c0caa2e2SCy Schubert  */
1014c0caa2e2SCy Schubert void http2_session_add_stream(struct http2_session* h2_session,
1015c0caa2e2SCy Schubert 	struct http2_stream* h2_stream);
1016c0caa2e2SCy Schubert 
1017c0caa2e2SCy Schubert /** Add mesh state to stream. To be able to remove mesh reply on stream closure
1018c0caa2e2SCy Schubert  */
1019c0caa2e2SCy Schubert void http2_stream_add_meshstate(struct http2_stream* h2_stream,
1020c0caa2e2SCy Schubert 	struct mesh_area* mesh, struct mesh_state* m);
1021c0caa2e2SCy Schubert 
102256850988SCy Schubert /** Remove mesh state from stream. When the mesh state has been removed. */
102356850988SCy Schubert void http2_stream_remove_mesh_state(struct http2_stream* h2_stream);
102456850988SCy Schubert 
1025c0caa2e2SCy Schubert /**
1026*46d2f618SCy Schubert  * DoQ socket address storage for IP4 or IP6 address. Smaller than
1027*46d2f618SCy Schubert  * the sockaddr_storage because not with af_unix pathnames.
1028*46d2f618SCy Schubert  */
1029*46d2f618SCy Schubert struct doq_addr_storage {
1030*46d2f618SCy Schubert 	union {
1031*46d2f618SCy Schubert 		struct sockaddr_in in;
1032*46d2f618SCy Schubert #ifdef AF_INET6
1033*46d2f618SCy Schubert 		struct sockaddr_in6 in6;
1034*46d2f618SCy Schubert #endif
1035*46d2f618SCy Schubert 	} sockaddr;
1036*46d2f618SCy Schubert };
1037*46d2f618SCy Schubert 
1038*46d2f618SCy Schubert /**
1039*46d2f618SCy Schubert  * The DoQ server socket information, for DNS over QUIC.
1040*46d2f618SCy Schubert  */
1041*46d2f618SCy Schubert struct doq_server_socket {
1042*46d2f618SCy Schubert 	/** the doq connection table */
1043*46d2f618SCy Schubert 	struct doq_table* table;
1044*46d2f618SCy Schubert 	/** random generator */
1045*46d2f618SCy Schubert 	struct ub_randstate* rnd;
1046*46d2f618SCy Schubert 	/** if address validation is enabled */
1047*46d2f618SCy Schubert 	uint8_t validate_addr;
1048*46d2f618SCy Schubert 	/** the ssl service key file */
1049*46d2f618SCy Schubert 	char* ssl_service_key;
1050*46d2f618SCy Schubert 	/** the ssl service pem file */
1051*46d2f618SCy Schubert 	char* ssl_service_pem;
1052*46d2f618SCy Schubert 	/** the ssl verify pem file */
1053*46d2f618SCy Schubert 	char* ssl_verify_pem;
1054*46d2f618SCy Schubert 	/** the server scid length */
1055*46d2f618SCy Schubert 	int sv_scidlen;
1056*46d2f618SCy Schubert 	/** the idle timeout in nanoseconds */
1057*46d2f618SCy Schubert 	uint64_t idle_timeout;
1058*46d2f618SCy Schubert 	/** the static secret for the server */
1059*46d2f618SCy Schubert 	uint8_t* static_secret;
1060*46d2f618SCy Schubert 	/** length of the static secret */
1061*46d2f618SCy Schubert 	size_t static_secret_len;
1062*46d2f618SCy Schubert 	/** ssl context, SSL_CTX* */
1063*46d2f618SCy Schubert 	void* ctx;
1064*46d2f618SCy Schubert #ifndef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT
1065*46d2f618SCy Schubert 	/** quic method functions, SSL_QUIC_METHOD* */
1066*46d2f618SCy Schubert 	void* quic_method;
1067*46d2f618SCy Schubert #endif
1068*46d2f618SCy Schubert 	/** the comm point for this doq server socket */
1069*46d2f618SCy Schubert 	struct comm_point* cp;
1070*46d2f618SCy Schubert 	/** the buffer for packets, doq in and out */
1071*46d2f618SCy Schubert 	struct sldns_buffer* pkt_buf;
1072*46d2f618SCy Schubert 	/** the current doq connection when we are in callbacks to worker,
1073*46d2f618SCy Schubert 	 * so that we have the already locked structure at our disposal. */
1074*46d2f618SCy Schubert 	struct doq_conn* current_conn;
1075*46d2f618SCy Schubert 	/** if the callback event on the fd has write flags */
1076*46d2f618SCy Schubert 	uint8_t event_has_write;
1077*46d2f618SCy Schubert 	/** if there is a blocked packet in the blocked_pkt buffer */
1078*46d2f618SCy Schubert 	int have_blocked_pkt;
1079*46d2f618SCy Schubert 	/** store blocked packet, a packet that could not be send on the
1080*46d2f618SCy Schubert 	 * nonblocking socket. It has to be sent later, when the write on
1081*46d2f618SCy Schubert 	 * the udp socket unblocks. */
1082*46d2f618SCy Schubert 	struct sldns_buffer* blocked_pkt;
1083*46d2f618SCy Schubert #ifdef HAVE_NGTCP2
1084*46d2f618SCy Schubert 	/** the ecn info for the blocked packet, congestion information. */
1085*46d2f618SCy Schubert 	struct ngtcp2_pkt_info blocked_pkt_pi;
1086*46d2f618SCy Schubert #endif
1087*46d2f618SCy Schubert 	/** the packet destination for the blocked packet. */
1088*46d2f618SCy Schubert 	struct doq_pkt_addr* blocked_paddr;
1089*46d2f618SCy Schubert 	/** timer for this worker on this comm_point to wait on. */
1090*46d2f618SCy Schubert 	struct comm_timer* timer;
1091*46d2f618SCy Schubert 	/** the timer that is marked by the doq_socket as waited on. */
1092*46d2f618SCy Schubert 	struct timeval marked_time;
1093*46d2f618SCy Schubert 	/** the current time for use by time functions, time_t. */
1094*46d2f618SCy Schubert 	time_t* now_tt;
1095*46d2f618SCy Schubert 	/** the current time for use by time functions, timeval. */
1096*46d2f618SCy Schubert 	struct timeval* now_tv;
1097*46d2f618SCy Schubert 	/** config file for the worker. */
1098*46d2f618SCy Schubert 	struct config_file* cfg;
1099*46d2f618SCy Schubert };
1100*46d2f618SCy Schubert 
1101*46d2f618SCy Schubert /**
1102*46d2f618SCy Schubert  * DoQ packet address information. From pktinfo, stores local and remote
1103*46d2f618SCy Schubert  * address and ifindex, so the packet can be sent there.
1104*46d2f618SCy Schubert  */
1105*46d2f618SCy Schubert struct doq_pkt_addr {
1106*46d2f618SCy Schubert 	/** the remote addr, and local addr */
1107*46d2f618SCy Schubert 	struct doq_addr_storage addr, localaddr;
1108*46d2f618SCy Schubert 	/** length of addr and length of localaddr */
1109*46d2f618SCy Schubert 	socklen_t addrlen, localaddrlen;
1110*46d2f618SCy Schubert 	/** interface index from pktinfo ancillary information */
1111*46d2f618SCy Schubert 	int ifindex;
1112*46d2f618SCy Schubert };
1113*46d2f618SCy Schubert 
1114*46d2f618SCy Schubert /** Initialize the pkt addr with lengths set to sizeof. That is ready for
1115*46d2f618SCy Schubert  * a call to recv. */
1116*46d2f618SCy Schubert void doq_pkt_addr_init(struct doq_pkt_addr* paddr);
1117*46d2f618SCy Schubert 
1118*46d2f618SCy Schubert /** send doq packet over UDP. */
1119*46d2f618SCy Schubert void doq_send_pkt(struct comm_point* c, struct doq_pkt_addr* paddr,
1120*46d2f618SCy Schubert 	uint32_t ecn);
1121*46d2f618SCy Schubert 
1122*46d2f618SCy Schubert /** doq timer callback function. */
1123*46d2f618SCy Schubert void doq_timer_cb(void* arg);
1124*46d2f618SCy Schubert 
1125*46d2f618SCy Schubert /**
112657bddd21SDag-Erling Smørgrav  * This routine is published for checks and tests, and is only used internally.
1127b7579f77SDag-Erling Smørgrav  * handle libevent callback for timer comm.
1128b7579f77SDag-Erling Smørgrav  * @param fd: file descriptor (always -1).
1129b7579f77SDag-Erling Smørgrav  * @param event: event bits from libevent:
1130b7579f77SDag-Erling Smørgrav  *	EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT.
1131b7579f77SDag-Erling Smørgrav  * @param arg: the comm_timer structure.
1132b7579f77SDag-Erling Smørgrav  */
1133b7579f77SDag-Erling Smørgrav void comm_timer_callback(int fd, short event, void* arg);
1134b7579f77SDag-Erling Smørgrav 
1135b7579f77SDag-Erling Smørgrav /**
1136b7579f77SDag-Erling Smørgrav  * This routine is published for checks and tests, and is only used internally.
1137b7579f77SDag-Erling Smørgrav  * handle libevent callback for signal comm.
1138b7579f77SDag-Erling Smørgrav  * @param fd: file descriptor (used for the signal number).
1139b7579f77SDag-Erling Smørgrav  * @param event: event bits from libevent:
1140b7579f77SDag-Erling Smørgrav  *	EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT.
1141b7579f77SDag-Erling Smørgrav  * @param arg: the internal commsignal structure.
1142b7579f77SDag-Erling Smørgrav  */
1143b7579f77SDag-Erling Smørgrav void comm_signal_callback(int fd, short event, void* arg);
1144b7579f77SDag-Erling Smørgrav 
1145b7579f77SDag-Erling Smørgrav /**
1146b7579f77SDag-Erling Smørgrav  * This routine is published for checks and tests, and is only used internally.
1147b7579f77SDag-Erling Smørgrav  * libevent callback for AF_UNIX fds
1148b7579f77SDag-Erling Smørgrav  * @param fd: file descriptor.
1149b7579f77SDag-Erling Smørgrav  * @param event: event bits from libevent:
1150b7579f77SDag-Erling Smørgrav  *	EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT.
1151b7579f77SDag-Erling Smørgrav  * @param arg: the comm_point structure.
1152b7579f77SDag-Erling Smørgrav  */
1153b7579f77SDag-Erling Smørgrav void comm_point_local_handle_callback(int fd, short event, void* arg);
1154b7579f77SDag-Erling Smørgrav 
1155b7579f77SDag-Erling Smørgrav /**
1156b7579f77SDag-Erling Smørgrav  * This routine is published for checks and tests, and is only used internally.
1157b7579f77SDag-Erling Smørgrav  * libevent callback for raw fd access.
1158b7579f77SDag-Erling Smørgrav  * @param fd: file descriptor.
1159b7579f77SDag-Erling Smørgrav  * @param event: event bits from libevent:
1160b7579f77SDag-Erling Smørgrav  *	EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT.
1161b7579f77SDag-Erling Smørgrav  * @param arg: the comm_point structure.
1162b7579f77SDag-Erling Smørgrav  */
1163b7579f77SDag-Erling Smørgrav void comm_point_raw_handle_callback(int fd, short event, void* arg);
1164b7579f77SDag-Erling Smørgrav 
1165b7579f77SDag-Erling Smørgrav /**
1166b7579f77SDag-Erling Smørgrav  * This routine is published for checks and tests, and is only used internally.
1167b7579f77SDag-Erling Smørgrav  * libevent callback for timeout on slow accept.
1168b7579f77SDag-Erling Smørgrav  * @param fd: file descriptor.
1169b7579f77SDag-Erling Smørgrav  * @param event: event bits from libevent:
1170b7579f77SDag-Erling Smørgrav  *	EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT.
1171b7579f77SDag-Erling Smørgrav  * @param arg: the comm_point structure.
1172b7579f77SDag-Erling Smørgrav  */
1173b7579f77SDag-Erling Smørgrav void comm_base_handle_slow_accept(int fd, short event, void* arg);
1174b7579f77SDag-Erling Smørgrav 
1175b7579f77SDag-Erling Smørgrav #ifdef USE_WINSOCK
1176b7579f77SDag-Erling Smørgrav /**
1177b7579f77SDag-Erling Smørgrav  * Callback for openssl BIO to on windows detect WSAEWOULDBLOCK and notify
1178b7579f77SDag-Erling Smørgrav  * the winsock_event of this for proper TCP nonblocking implementation.
1179b7579f77SDag-Erling Smørgrav  * @param c: comm_point, fd must be set its struct event is registered.
1180b7579f77SDag-Erling Smørgrav  * @param ssl: openssl SSL, fd must be set so it has a bio.
1181b7579f77SDag-Erling Smørgrav  */
1182b7579f77SDag-Erling Smørgrav void comm_point_tcp_win_bio_cb(struct comm_point* c, void* ssl);
1183b7579f77SDag-Erling Smørgrav #endif
1184b7579f77SDag-Erling Smørgrav 
118525039b37SCy Schubert /**
118625039b37SCy Schubert  * See if errno for tcp connect has to be logged or not. This uses errno
118725039b37SCy Schubert  * @param addr: apart from checking errno, the addr is checked for ip4mapped
118825039b37SCy Schubert  * 	and broadcast type, hence passed.
118925039b37SCy Schubert  * @param addrlen: length of the addr parameter.
119025039b37SCy Schubert  * @return true if it needs to be logged.
119125039b37SCy Schubert  */
1192b7579f77SDag-Erling Smørgrav int tcp_connect_errno_needs_log(struct sockaddr* addr, socklen_t addrlen);
1193b7579f77SDag-Erling Smørgrav 
119425039b37SCy Schubert #ifdef HAVE_SSL
119525039b37SCy Schubert /**
119625039b37SCy Schubert  * True if the ssl handshake error has to be squelched from the logs
119725039b37SCy Schubert  * @param err: the error returned by the openssl routine, ERR_get_error.
119825039b37SCy Schubert  * 	This is a packed structure with elements that are examined.
119925039b37SCy Schubert  * @return true if the error is squelched (not logged).
120025039b37SCy Schubert  */
120125039b37SCy Schubert int squelch_err_ssl_handshake(unsigned long err);
120225039b37SCy Schubert #endif
120325039b37SCy Schubert 
1204b7579f77SDag-Erling Smørgrav #endif /* NET_EVENT_H */
1205