xref: /openbsd-src/sbin/unwind/libunbound/util/netevent.h (revision 7037e34cdfd270b3989fb1829c7cd3439048bd3a)
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