xref: /freebsd/contrib/unbound/testcode/doqclient.c (revision b2efd602aea8b3cbc3fb215b9611946d04fceb10)
1 /*
2  * testcode/doqclient.c - debug program. Perform multiple DNS queries using DoQ.
3  *
4  * Copyright (c) 2022, NLnet Labs. All rights reserved.
5  *
6  * This software is open source.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * Neither the name of the NLNET LABS nor the names of its contributors may
20  * be used to endorse or promote products derived from this software without
21  * specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 /**
37  * \file
38  *
39  * Simple DNS-over-QUIC client. For testing and debugging purposes.
40  * No authentication of TLS cert.
41  */
42 
43 #include "config.h"
44 #ifdef HAVE_GETOPT_H
45 #include <getopt.h>
46 #endif
47 
48 #ifdef HAVE_NGTCP2
49 #include <ngtcp2/ngtcp2.h>
50 #include <ngtcp2/ngtcp2_crypto.h>
51 #ifdef HAVE_NGTCP2_NGTCP2_CRYPTO_OSSL_H
52 #include <ngtcp2/ngtcp2_crypto_ossl.h>
53 #elif defined(HAVE_NGTCP2_NGTCP2_CRYPTO_QUICTLS_H)
54 #include <ngtcp2/ngtcp2_crypto_quictls.h>
55 #elif defined(HAVE_NGTCP2_NGTCP2_CRYPTO_OPENSSL_H)
56 #include <ngtcp2/ngtcp2_crypto_openssl.h>
57 #define MAKE_QUIC_METHOD 1
58 #endif
59 #include <openssl/ssl.h>
60 #include <openssl/rand.h>
61 #ifdef HAVE_TIME_H
62 #include <time.h>
63 #endif
64 #include <sys/time.h>
65 #include "util/locks.h"
66 #include "util/net_help.h"
67 #include "sldns/sbuffer.h"
68 #include "sldns/str2wire.h"
69 #include "sldns/wire2str.h"
70 #include "util/data/msgreply.h"
71 #include "util/data/msgencode.h"
72 #include "util/data/msgparse.h"
73 #include "util/data/dname.h"
74 #include "util/random.h"
75 #include "util/ub_event.h"
76 struct doq_client_stream_list;
77 struct doq_client_stream;
78 
79 /** the local client data for the DoQ connection */
80 struct doq_client_data {
81 	/** file descriptor */
82 	int fd;
83 	/** the event base for the events */
84 	struct ub_event_base* base;
85 	/** the ub event */
86 	struct ub_event* ev;
87 	/** the expiry timer */
88 	struct ub_event* expire_timer;
89 	/** is the expire_timer added */
90 	int expire_timer_added;
91 	/** the ngtcp2 connection information */
92 	struct ngtcp2_conn* conn;
93 	/** random state */
94 	struct ub_randstate* rnd;
95 	/** server connected to as a string */
96 	const char* svr;
97 	/** the static secret */
98 	uint8_t* static_secret_data;
99 	/** the static secret size */
100 	size_t static_secret_size;
101 	/** destination address sockaddr */
102 	struct sockaddr_storage dest_addr;
103 	/** length of dest addr */
104 	socklen_t dest_addr_len;
105 	/** local address sockaddr */
106 	struct sockaddr_storage local_addr;
107 	/** length of local addr */
108 	socklen_t local_addr_len;
109 	/** SSL context */
110 	SSL_CTX* ctx;
111 	/** SSL object */
112 	SSL* ssl;
113 #if defined(USE_NGTCP2_CRYPTO_OSSL) || defined(HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT)
114 	/** the connection reference for ngtcp2_conn and userdata in ssl */
115 	struct ngtcp2_crypto_conn_ref conn_ref;
116 #endif
117 #ifdef USE_NGTCP2_CRYPTO_OSSL
118 	/** the per-connection state for ngtcp2_crypto_ossl */
119 	struct ngtcp2_crypto_ossl_ctx* ossl_ctx;
120 #endif
121 	/** the quic version to use */
122 	uint32_t quic_version;
123 	/** the last error */
124 #ifdef HAVE_NGTCP2_CCERR_DEFAULT
125 	struct ngtcp2_ccerr ccerr;
126 #else
127 	struct ngtcp2_connection_close_error last_error;
128 #endif
129 	/** the recent tls alert error code */
130 	uint8_t tls_alert;
131 	/** the buffer for packet operations */
132 	struct sldns_buffer* pkt_buf;
133 	/** The list of queries to start. They have no stream associated.
134 	 * Once they do, they move to the send list. */
135 	struct doq_client_stream_list* query_list_start;
136 	/** The list of queries to send. They have a stream, and they are
137 	 * sending data. Data could also be received, like errors. */
138 	struct doq_client_stream_list* query_list_send;
139 	/** The list of queries to receive. They have a stream, and the
140 	 * send is done, it is possible to read data. */
141 	struct doq_client_stream_list* query_list_receive;
142 	/** The list of queries that are stopped. They have no stream
143 	 * active any more. Write and read are done. The query is done,
144 	 * and it may be in error and then have no answer or partial answer. */
145 	struct doq_client_stream_list* query_list_stop;
146 	/** is there a blocked packet in the blocked_pkt buffer */
147 	int have_blocked_pkt;
148 	/** store blocked packet, a packet that could not be sent on the
149 	 * nonblocking socket. */
150 	struct sldns_buffer* blocked_pkt;
151 	/** ecn info for the blocked packet */
152 	struct ngtcp2_pkt_info blocked_pkt_pi;
153 	/** the congestion control algorithm */
154 	ngtcp2_cc_algo cc_algo;
155 	/** the transport parameters file, for early data transmission */
156 	const char* transport_file;
157 	/** the tls session file, for session resumption */
158 	const char* session_file;
159 	/** if early data is enabled for the connection */
160 	int early_data_enabled;
161 	/** how quiet is the output */
162 	int quiet;
163 	/** the configured port for the destination */
164 	int port;
165 };
166 
167 /** the local client stream list, for appending streams to */
168 struct doq_client_stream_list {
169 	/** first and last members of the list */
170 	struct doq_client_stream* first, *last;
171 };
172 
173 /** the local client data for a DoQ stream */
174 struct doq_client_stream {
175 	/** next stream in list, and prev in list */
176 	struct doq_client_stream* next, *prev;
177 	/** the data buffer */
178 	uint8_t* data;
179 	/** length of the data buffer */
180 	size_t data_len;
181 	/** if the client query has a stream, that is active, associated with
182 	 * it. The stream_id is in stream_id. */
183 	int has_stream;
184 	/** the stream id */
185 	int64_t stream_id;
186 	/** data written position */
187 	size_t nwrite;
188 	/** the data length for write, in network format */
189 	uint16_t data_tcplen;
190 	/** if the write of the query data is done. That means the
191 	 * write channel has FIN, is closed for writing. */
192 	int write_is_done;
193 	/** data read position */
194 	size_t nread;
195 	/** the answer length, in network byte order */
196 	uint16_t answer_len;
197 	/** the answer buffer */
198 	struct sldns_buffer* answer;
199 	/** the answer is complete */
200 	int answer_is_complete;
201 	/** the query has an error, it has no answer, or no complete answer */
202 	int query_has_error;
203 	/** if the query is done */
204 	int query_is_done;
205 };
206 
207 #ifdef MAKE_QUIC_METHOD
208 /** the quic method struct, must remain valid during the QUIC connection. */
209 static SSL_QUIC_METHOD quic_method;
210 #endif
211 
212 #if defined(USE_NGTCP2_CRYPTO_OSSL) || defined(HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT)
213 /** Get the connection ngtcp2_conn from the ssl app data
214  * ngtcp2_crypto_conn_ref */
conn_ref_get_conn(ngtcp2_crypto_conn_ref * conn_ref)215 static ngtcp2_conn* conn_ref_get_conn(ngtcp2_crypto_conn_ref* conn_ref)
216 {
217 	struct doq_client_data* data = (struct doq_client_data*)
218 		conn_ref->user_data;
219 	return data->conn;
220 }
221 #endif
222 
223 static void
set_app_data(SSL * ssl,struct doq_client_data * data)224 set_app_data(SSL* ssl, struct doq_client_data* data)
225 {
226 #if defined(USE_NGTCP2_CRYPTO_OSSL) || defined(HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT)
227 	data->conn_ref.get_conn = &conn_ref_get_conn;
228 	data->conn_ref.user_data = data;
229 	SSL_set_app_data(ssl, &data->conn_ref);
230 #else
231 	SSL_set_app_data(ssl, data);
232 #endif
233 }
234 
235 static struct doq_client_data*
get_app_data(SSL * ssl)236 get_app_data(SSL* ssl)
237 {
238 	struct doq_client_data* data;
239 #if defined(USE_NGTCP2_CRYPTO_OSSL) || defined(HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT)
240 	data = (struct doq_client_data*)((struct ngtcp2_crypto_conn_ref*)
241 		SSL_get_app_data(ssl))->user_data;
242 #else
243 	data = (struct doq_client_data*) SSL_get_app_data(ssl);
244 #endif
245 	return data;
246 }
247 
248 
249 
250 /** write handle routine */
251 static void on_write(struct doq_client_data* data);
252 /** update the timer */
253 static void update_timer(struct doq_client_data* data);
254 /** disconnect we are done */
255 static void disconnect(struct doq_client_data* data);
256 /** fetch and write the transport file */
257 static void early_data_write_transport(struct doq_client_data* data);
258 
259 /** usage of doqclient */
usage(char * argv[])260 static void usage(char* argv[])
261 {
262 	printf("usage: %s [options] name type class ...\n", argv[0]);
263 	printf("	sends the name-type-class queries over "
264 			"DNS-over-QUIC.\n");
265 	printf("-s server	IP address to send the queries to, "
266 			"default: 127.0.0.1\n");
267 	printf("-p		Port to connect to, default: %d\n",
268 		UNBOUND_DNS_OVER_QUIC_PORT);
269 	printf("-v 		verbose output\n");
270 	printf("-q 		quiet, short output of answer\n");
271 	printf("-x file		transport file, for read/write of transport parameters.\n\t\tIf it exists, it is used to send early data. It is then\n\t\twritten to contain the last used transport parameters.\n\t\tAlso -y must be enabled for early data to succeed.\n");
272 	printf("-y file		session file, for read/write of TLS session. If it exists,\n\t\tit is used for TLS session resumption. It is then written\n\t\tto contain the last session used.\n\t\tOn its own, without also -x, resumes TLS session.\n");
273 	printf("-h 		This help text\n");
274 	exit(1);
275 }
276 
277 /** get the dest address */
278 static void
get_dest_addr(struct doq_client_data * data,const char * svr,int port)279 get_dest_addr(struct doq_client_data* data, const char* svr, int port)
280 {
281 	if(!ipstrtoaddr(svr, port, &data->dest_addr, &data->dest_addr_len)) {
282 		printf("fatal: bad server specs '%s'\n", svr);
283 		exit(1);
284 	}
285 }
286 
287 /** open UDP socket to svr */
288 static int
open_svr_udp(struct doq_client_data * data)289 open_svr_udp(struct doq_client_data* data)
290 {
291 	int fd = -1;
292 	int r;
293 	fd = socket(addr_is_ip6(&data->dest_addr, data->dest_addr_len)?
294 		PF_INET6:PF_INET, SOCK_DGRAM, 0);
295 	if(fd == -1) {
296 		perror("socket() error");
297 		exit(1);
298 	}
299 	r = connect(fd, (struct sockaddr*)&data->dest_addr,
300 		data->dest_addr_len);
301 	if(r < 0 && r != EINPROGRESS) {
302 		perror("connect() error");
303 		exit(1);
304 	}
305 	fd_set_nonblock(fd);
306 	return fd;
307 }
308 
309 /** get the local address of the connection */
310 static void
get_local_addr(struct doq_client_data * data)311 get_local_addr(struct doq_client_data* data)
312 {
313 	memset(&data->local_addr, 0, sizeof(data->local_addr));
314 	data->local_addr_len = (socklen_t)sizeof(data->local_addr);
315 	if(getsockname(data->fd, (struct sockaddr*)&data->local_addr,
316 		&data->local_addr_len) == -1) {
317 		perror("getsockname() error");
318 		exit(1);
319 	}
320 	log_addr(1, "local_addr", &data->local_addr, data->local_addr_len);
321 	log_addr(1, "dest_addr", &data->dest_addr, data->dest_addr_len);
322 }
323 
324 static sldns_buffer*
make_query(char * qname,char * qtype,char * qclass)325 make_query(char* qname, char* qtype, char* qclass)
326 {
327 	struct query_info qinfo;
328 	struct edns_data edns;
329 	sldns_buffer* buf = sldns_buffer_new(65553);
330 	if(!buf) fatal_exit("out of memory");
331 	qinfo.qname = sldns_str2wire_dname(qname, &qinfo.qname_len);
332 	if(!qinfo.qname) {
333 		printf("cannot parse query name: '%s'\n", qname);
334 		exit(1);
335 	}
336 
337 	qinfo.qtype = sldns_get_rr_type_by_name(qtype);
338 	qinfo.qclass = sldns_get_rr_class_by_name(qclass);
339 	qinfo.local_alias = NULL;
340 
341 	qinfo_query_encode(buf, &qinfo); /* flips buffer */
342 	free(qinfo.qname);
343 	sldns_buffer_write_u16_at(buf, 0, 0x0000);
344 	sldns_buffer_write_u16_at(buf, 2, BIT_RD);
345 	memset(&edns, 0, sizeof(edns));
346 	edns.edns_present = 1;
347 	edns.bits = EDNS_DO;
348 	edns.udp_size = 4096;
349 	if(sldns_buffer_capacity(buf) >=
350 		sldns_buffer_limit(buf)+calc_edns_field_size(&edns))
351 		attach_edns_record(buf, &edns);
352 	return buf;
353 }
354 
355 /** create client stream structure */
356 static struct doq_client_stream*
client_stream_create(struct sldns_buffer * query_data)357 client_stream_create(struct sldns_buffer* query_data)
358 {
359 	struct doq_client_stream* str = calloc(1, sizeof(*str));
360 	if(!str)
361 		fatal_exit("calloc failed: out of memory");
362 	str->data = memdup(sldns_buffer_begin(query_data),
363 		sldns_buffer_limit(query_data));
364 	if(!str->data)
365 		fatal_exit("alloc data failed: out of memory");
366 	str->data_len = sldns_buffer_limit(query_data);
367 	str->stream_id = -1;
368 	return str;
369 }
370 
371 /** free client stream structure */
372 static void
client_stream_free(struct doq_client_stream * str)373 client_stream_free(struct doq_client_stream* str)
374 {
375 	if(!str)
376 		return;
377 	free(str->data);
378 	sldns_buffer_free(str->answer);
379 	free(str);
380 }
381 
382 /** setup the stream to start the write process */
383 static void
client_stream_start_setup(struct doq_client_stream * str,int64_t stream_id)384 client_stream_start_setup(struct doq_client_stream* str, int64_t stream_id)
385 {
386 	str->has_stream = 1;
387 	str->stream_id = stream_id;
388 	str->nwrite = 0;
389 	str->nread = 0;
390 	str->answer_len = 0;
391 	str->query_is_done = 0;
392 	str->answer_is_complete = 0;
393 	str->query_has_error = 0;
394 	if(str->answer) {
395 		sldns_buffer_free(str->answer);
396 		str->answer = NULL;
397 	}
398 }
399 
400 /** Return string for log purposes with query name. */
401 static char*
client_stream_string(struct doq_client_stream * str)402 client_stream_string(struct doq_client_stream* str)
403 {
404 	char* s;
405 	size_t dname_len;
406 	char dname[256], tpstr[32], result[256+32+16];
407 	uint16_t tp;
408 	if(str->data_len <= LDNS_HEADER_SIZE) {
409 		s = strdup("query_with_no_question");
410 		if(!s)
411 			fatal_exit("strdup failed: out of memory");
412 		return s;
413 	}
414 	dname_len = dname_valid(str->data+LDNS_HEADER_SIZE,
415 		str->data_len-LDNS_HEADER_SIZE);
416 	if(!dname_len) {
417 		s = strdup("query_dname_not_valid");
418 		if(!s)
419 			fatal_exit("strdup failed: out of memory");
420 		return s;
421 	}
422 	(void)sldns_wire2str_dname_buf(str->data+LDNS_HEADER_SIZE, dname_len,
423 		dname, sizeof(dname));
424 	tp = sldns_wirerr_get_type(str->data+LDNS_HEADER_SIZE,
425 		str->data_len-LDNS_HEADER_SIZE, dname_len);
426 	(void)sldns_wire2str_type_buf(tp, tpstr, sizeof(tpstr));
427 	snprintf(result, sizeof(result), "%s %s", dname, tpstr);
428 	s = strdup(result);
429 	if(!s)
430 		fatal_exit("strdup failed: out of memory");
431 	return s;
432 }
433 
434 /** create query stream list */
435 static struct doq_client_stream_list*
stream_list_create(void)436 stream_list_create(void)
437 {
438 	struct doq_client_stream_list* list = calloc(1, sizeof(*list));
439 	if(!list)
440 		fatal_exit("calloc failed: out of memory");
441 	return list;
442 }
443 
444 /** free the query stream list */
445 static void
stream_list_free(struct doq_client_stream_list * list)446 stream_list_free(struct doq_client_stream_list* list)
447 {
448 	struct doq_client_stream* str;
449 	if(!list)
450 		return;
451 	str = list->first;
452 	while(str) {
453 		struct doq_client_stream* next = str->next;
454 		client_stream_free(str);
455 		str = next;
456 	}
457 	free(list);
458 }
459 
460 /** append item to list */
461 static void
stream_list_append(struct doq_client_stream_list * list,struct doq_client_stream * str)462 stream_list_append(struct doq_client_stream_list* list,
463 	struct doq_client_stream* str)
464 {
465 	if(list->last) {
466 		str->prev = list->last;
467 		list->last->next = str;
468 	} else {
469 		str->prev = NULL;
470 		list->first = str;
471 	}
472 	str->next = NULL;
473 	list->last = str;
474 }
475 
476 /** delete the item from the list */
477 static void
stream_list_delete(struct doq_client_stream_list * list,struct doq_client_stream * str)478 stream_list_delete(struct doq_client_stream_list* list,
479 	struct doq_client_stream* str)
480 {
481 	if(str->next) {
482 		str->next->prev = str->prev;
483 	} else {
484 		list->last = str->prev;
485 	}
486 	if(str->prev) {
487 		str->prev->next = str->next;
488 	} else {
489 		list->first = str->next;
490 	}
491 	str->prev = NULL;
492 	str->next = NULL;
493 }
494 
495 /** move the item from list1 to list2 */
496 static void
stream_list_move(struct doq_client_stream * str,struct doq_client_stream_list * list1,struct doq_client_stream_list * list2)497 stream_list_move(struct doq_client_stream* str,
498 	struct doq_client_stream_list* list1,
499 	struct doq_client_stream_list* list2)
500 {
501 	stream_list_delete(list1, str);
502 	stream_list_append(list2, str);
503 }
504 
505 /** allocate stream data buffer, then answer length is complete */
506 static void
client_stream_datalen_complete(struct doq_client_stream * str)507 client_stream_datalen_complete(struct doq_client_stream* str)
508 {
509 	verbose(1, "answer length %d", (int)ntohs(str->answer_len));
510 	str->answer = sldns_buffer_new(ntohs(str->answer_len));
511 	if(!str->answer)
512 		fatal_exit("sldns_buffer_new failed: out of memory");
513 	sldns_buffer_set_limit(str->answer, ntohs(str->answer_len));
514 }
515 
516 /** print the answer rrs */
517 static void
print_answer_rrs(uint8_t * pkt,size_t pktlen)518 print_answer_rrs(uint8_t* pkt, size_t pktlen)
519 {
520 	char buf[65535];
521 	char* str;
522 	size_t str_len;
523 	int i, qdcount, ancount;
524 	uint8_t* data = pkt;
525 	size_t data_len = pktlen;
526 	int comprloop = 0;
527 	if(data_len < LDNS_HEADER_SIZE)
528 		return;
529 	qdcount = LDNS_QDCOUNT(data);
530 	ancount = LDNS_ANCOUNT(data);
531 	data += LDNS_HEADER_SIZE;
532 	data_len -= LDNS_HEADER_SIZE;
533 
534 	for(i=0; i<qdcount; i++) {
535 		str = buf;
536 		str_len = sizeof(buf);
537 		(void)sldns_wire2str_rrquestion_scan(&data, &data_len,
538 			&str, &str_len, pkt, pktlen, &comprloop);
539 	}
540 	for(i=0; i<ancount; i++) {
541 		str = buf;
542 		str_len = sizeof(buf);
543 		(void)sldns_wire2str_rr_scan(&data, &data_len, &str, &str_len,
544 			pkt, pktlen, &comprloop);
545 		/* terminate string */
546 		if(str_len == 0)
547 			buf[sizeof(buf)-1] = 0;
548 		else	*str = 0;
549 		printf("%s", buf);
550 	}
551 }
552 
553 /** short output of answer, short error or rcode or answer section RRs. */
554 static void
client_stream_print_short(struct doq_client_stream * str)555 client_stream_print_short(struct doq_client_stream* str)
556 {
557 	int rcode, ancount;
558 	if(str->query_has_error) {
559 		char* logs = client_stream_string(str);
560 		printf("%s has error, there is no answer\n", logs);
561 		free(logs);
562 		return;
563 	}
564 	if(sldns_buffer_limit(str->answer) < LDNS_HEADER_SIZE) {
565 		char* logs = client_stream_string(str);
566 		printf("%s received short packet, smaller than header\n",
567 			logs);
568 		free(logs);
569 		return;
570 	}
571 	rcode = LDNS_RCODE_WIRE(sldns_buffer_begin(str->answer));
572 	if(rcode != 0) {
573 		char* logs = client_stream_string(str);
574 		char rc[16];
575 		(void)sldns_wire2str_rcode_buf(rcode, rc, sizeof(rc));
576 		printf("%s rcode %s\n", logs, rc);
577 		free(logs);
578 		return;
579 	}
580 	ancount = LDNS_ANCOUNT(sldns_buffer_begin(str->answer));
581 	if(ancount == 0) {
582 		char* logs = client_stream_string(str);
583 		printf("%s nodata answer\n", logs);
584 		free(logs);
585 		return;
586 	}
587 	print_answer_rrs(sldns_buffer_begin(str->answer),
588 		sldns_buffer_limit(str->answer));
589 }
590 
591 /** print the stream output answer */
592 static void
client_stream_print_long(struct doq_client_data * data,struct doq_client_stream * str)593 client_stream_print_long(struct doq_client_data* data,
594 	struct doq_client_stream* str)
595 {
596 	char* s;
597 	if(str->query_has_error) {
598 		char* logs = client_stream_string(str);
599 		printf("%s has error, there is no answer\n", logs);
600 		free(logs);
601 		return;
602 	}
603 	s = sldns_wire2str_pkt(sldns_buffer_begin(str->answer),
604 		sldns_buffer_limit(str->answer));
605 	printf("%s", (s?s:";sldns_wire2str_pkt failed\n"));
606 	printf(";; SERVER: %s %d\n", data->svr, data->port);
607 	free(s);
608 }
609 
610 /** the stream has completed the data */
611 static void
client_stream_data_complete(struct doq_client_stream * str)612 client_stream_data_complete(struct doq_client_stream* str)
613 {
614 	verbose(1, "received all answer content");
615 	if(verbosity > 0) {
616 		char* logs = client_stream_string(str);
617 		char* s;
618 		log_buf(1, "received answer", str->answer);
619 		s = sldns_wire2str_pkt(sldns_buffer_begin(str->answer),
620 			sldns_buffer_limit(str->answer));
621 		if(!s) verbose(1, "could not sldns_wire2str_pkt");
622 		else verbose(1, "query %s received:\n%s", logs, s);
623 		free(s);
624 		free(logs);
625 	}
626 	str->answer_is_complete = 1;
627 }
628 
629 /** the stream has completed but with an error */
630 static void
client_stream_answer_error(struct doq_client_stream * str)631 client_stream_answer_error(struct doq_client_stream* str)
632 {
633 	if(verbosity > 0) {
634 		char* logs = client_stream_string(str);
635 		if(str->answer)
636 			verbose(1, "query %s has an error. received %d/%d bytes.",
637 				logs, (int)sldns_buffer_position(str->answer),
638 				(int)sldns_buffer_limit(str->answer));
639 		else
640 			verbose(1, "query %s has an error. received no data.",
641 				logs);
642 		free(logs);
643 	}
644 	str->query_has_error = 1;
645 }
646 
647 /** receive data for a stream */
648 static void
client_stream_recv_data(struct doq_client_stream * str,const uint8_t * data,size_t datalen)649 client_stream_recv_data(struct doq_client_stream* str, const uint8_t* data,
650 	size_t datalen)
651 {
652 	int got_data = 0;
653 	/* read the tcplength uint16_t at the start of the DNS message */
654 	if(str->nread < 2) {
655 		size_t to_move = datalen;
656 		if(datalen > 2-str->nread)
657 			to_move = 2-str->nread;
658 		memmove(((uint8_t*)&str->answer_len)+str->nread, data,
659 			to_move);
660 		str->nread += to_move;
661 		data += to_move;
662 		datalen -= to_move;
663 		if(str->nread == 2) {
664 			/* we can allocate the data buffer */
665 			client_stream_datalen_complete(str);
666 		}
667 	}
668 	/* if we have data bytes */
669 	if(datalen > 0) {
670 		size_t to_write = datalen;
671 		if(datalen > sldns_buffer_remaining(str->answer))
672 			to_write = sldns_buffer_remaining(str->answer);
673 		if(to_write > 0) {
674 			sldns_buffer_write(str->answer, data, to_write);
675 			str->nread += to_write;
676 			data += to_write;
677 			datalen -= to_write;
678 			got_data = 1;
679 		}
680 	}
681 	/* extra received bytes after end? */
682 	if(datalen > 0) {
683 		verbose(1, "extra bytes after end of DNS length");
684 		if(verbosity > 0)
685 			log_hex("extradata", (void*)data, datalen);
686 	}
687 	/* are we done with it? */
688 	if(got_data && str->nread >= (size_t)(ntohs(str->answer_len))+2) {
689 		client_stream_data_complete(str);
690 	}
691 }
692 
693 /** receive FIN from remote end on client stream, no more data to be
694  * received on the stream. */
695 static void
client_stream_recv_fin(struct doq_client_data * data,struct doq_client_stream * str,int is_fin)696 client_stream_recv_fin(struct doq_client_data* data,
697 	struct doq_client_stream* str, int is_fin)
698 {
699 	if(verbosity > 0) {
700 		char* logs = client_stream_string(str);
701 		if(is_fin)
702 			verbose(1, "query %s: received FIN from remote", logs);
703 		else
704 			verbose(1, "query %s: stream reset from remote", logs);
705 		free(logs);
706 	}
707 	if(str->write_is_done)
708 		stream_list_move(str, data->query_list_receive,
709 			data->query_list_stop);
710 	else
711 		stream_list_move(str, data->query_list_send,
712 			data->query_list_stop);
713 	if(!str->answer_is_complete) {
714 		client_stream_answer_error(str);
715 	}
716 	str->query_is_done = 1;
717 	if(data->quiet)
718 		client_stream_print_short(str);
719 	else client_stream_print_long(data, str);
720 	if(data->query_list_send->first==NULL &&
721 		data->query_list_receive->first==NULL)
722 		disconnect(data);
723 }
724 
725 /** fill a buffer with random data */
fill_rand(struct ub_randstate * rnd,uint8_t * buf,size_t len)726 static void fill_rand(struct ub_randstate* rnd, uint8_t* buf, size_t len)
727 {
728 	if(RAND_bytes(buf, len) != 1) {
729 		size_t i;
730 		for(i=0; i<len; i++)
731 			buf[i] = ub_random(rnd)&0xff;
732 	}
733 }
734 
735 /** create the static secret */
generate_static_secret(struct doq_client_data * data,size_t len)736 static void generate_static_secret(struct doq_client_data* data, size_t len)
737 {
738 	data->static_secret_data = malloc(len);
739 	if(!data->static_secret_data)
740 		fatal_exit("malloc failed: out of memory");
741 	data->static_secret_size = len;
742 	fill_rand(data->rnd, data->static_secret_data, len);
743 }
744 
745 /** fill cid structure with random data */
cid_randfill(struct ngtcp2_cid * cid,size_t datalen,struct ub_randstate * rnd)746 static void cid_randfill(struct ngtcp2_cid* cid, size_t datalen,
747 	struct ub_randstate* rnd)
748 {
749 	uint8_t buf[32];
750 	if(datalen > sizeof(buf))
751 		datalen = sizeof(buf);
752 	fill_rand(rnd, buf, datalen);
753 	ngtcp2_cid_init(cid, buf, datalen);
754 }
755 
756 /** send buf on the client stream */
757 static int
client_bidi_stream(struct doq_client_data * data,int64_t * ret_stream_id,void * stream_user_data)758 client_bidi_stream(struct doq_client_data* data, int64_t* ret_stream_id,
759 	void* stream_user_data)
760 {
761 	int64_t stream_id;
762 	int rv;
763 
764 	/* open new bidirectional stream */
765 	rv = ngtcp2_conn_open_bidi_stream(data->conn, &stream_id,
766 		stream_user_data);
767 	if(rv != 0) {
768 		if(rv == NGTCP2_ERR_STREAM_ID_BLOCKED) {
769 			/* no bidi stream count for this new stream */
770 			return 0;
771 		}
772 		fatal_exit("could not ngtcp2_conn_open_bidi_stream: %s",
773 			ngtcp2_strerror(rv));
774 	}
775 	*ret_stream_id = stream_id;
776 	return 1;
777 }
778 
779 /** See if we can start query streams, by creating bidirectional streams
780  * on the QUIC transport for them. */
781 static void
query_streams_start(struct doq_client_data * data)782 query_streams_start(struct doq_client_data* data)
783 {
784 	while(data->query_list_start->first) {
785 		struct doq_client_stream* str = data->query_list_start->first;
786 		int64_t stream_id = 0;
787 		if(!client_bidi_stream(data, &stream_id, str)) {
788 			/* no more bidi streams allowed */
789 			break;
790 		}
791 		if(verbosity > 0) {
792 			char* logs = client_stream_string(str);
793 			verbose(1, "query %s start on bidi stream id %lld",
794 				logs, (long long int)stream_id);
795 			free(logs);
796 		}
797 		/* setup the stream to start */
798 		client_stream_start_setup(str, stream_id);
799 		/* move the query entry to the send list to write it */
800 		stream_list_move(str, data->query_list_start,
801 			data->query_list_send);
802 	}
803 }
804 
805 /** the rand callback routine from ngtcp2 */
rand_cb(uint8_t * dest,size_t destlen,const ngtcp2_rand_ctx * rand_ctx)806 static void rand_cb(uint8_t* dest, size_t destlen,
807 	const ngtcp2_rand_ctx* rand_ctx)
808 {
809 	struct ub_randstate* rnd = (struct ub_randstate*)
810 		rand_ctx->native_handle;
811 	fill_rand(rnd, dest, destlen);
812 }
813 
814 /** the get_new_connection_id callback routine from ngtcp2 */
get_new_connection_id_cb(struct ngtcp2_conn * ATTR_UNUSED (conn),struct ngtcp2_cid * cid,uint8_t * token,size_t cidlen,void * user_data)815 static int get_new_connection_id_cb(struct ngtcp2_conn* ATTR_UNUSED(conn),
816 	struct ngtcp2_cid* cid, uint8_t* token, size_t cidlen, void* user_data)
817 {
818 	struct doq_client_data* data = (struct doq_client_data*)user_data;
819 	cid_randfill(cid, cidlen, data->rnd);
820 	if(ngtcp2_crypto_generate_stateless_reset_token(token,
821 		data->static_secret_data, data->static_secret_size, cid) != 0)
822 		return NGTCP2_ERR_CALLBACK_FAILURE;
823 	return 0;
824 }
825 
826 /** handle that early data is rejected */
827 static void
early_data_is_rejected(struct doq_client_data * data)828 early_data_is_rejected(struct doq_client_data* data)
829 {
830 	int rv;
831 	verbose(1, "early data was rejected by the server");
832 #ifdef HAVE_NGTCP2_CONN_TLS_EARLY_DATA_REJECTED
833 	rv = ngtcp2_conn_tls_early_data_rejected(data->conn);
834 #else
835 	rv = ngtcp2_conn_early_data_rejected(data->conn);
836 #endif
837 	if(rv != 0) {
838 		log_err("ngtcp2_conn_early_data_rejected failed: %s",
839 			ngtcp2_strerror(rv));
840 		return;
841 	}
842 	/* move the streams back to the start state */
843 	while(data->query_list_send->first) {
844 		struct doq_client_stream* str = data->query_list_send->first;
845 		/* move it back to the start list */
846 		stream_list_move(str, data->query_list_send,
847 			data->query_list_start);
848 		str->has_stream = 0;
849 		/* remove stream id */
850 		str->stream_id = 0;
851 		/* initialise other members, in case they are altered,
852 		 * but unlikely, because early streams are rejected. */
853 		str->nwrite = 0;
854 		str->nread = 0;
855 		str->answer_len = 0;
856 		str->query_is_done = 0;
857 		str->answer_is_complete = 0;
858 		str->query_has_error = 0;
859 		if(str->answer) {
860 			sldns_buffer_free(str->answer);
861 			str->answer = NULL;
862 		}
863 	}
864 }
865 
866 /** the handshake completed callback from ngtcp2 */
867 static int
handshake_completed(ngtcp2_conn * ATTR_UNUSED (conn),void * user_data)868 handshake_completed(ngtcp2_conn* ATTR_UNUSED(conn), void* user_data)
869 {
870 	struct doq_client_data* data = (struct doq_client_data*)user_data;
871 	verbose(1, "handshake_completed callback");
872 	verbose(1, "ngtcp2_conn_get_max_data_left is %d",
873 		(int)ngtcp2_conn_get_max_data_left(data->conn));
874 #ifdef HAVE_NGTCP2_CONN_GET_MAX_LOCAL_STREAMS_UNI
875 	verbose(1, "ngtcp2_conn_get_max_local_streams_uni is %d",
876 		(int)ngtcp2_conn_get_max_local_streams_uni(data->conn));
877 #endif
878 	verbose(1, "ngtcp2_conn_get_streams_uni_left is %d",
879 		(int)ngtcp2_conn_get_streams_uni_left(data->conn));
880 	verbose(1, "ngtcp2_conn_get_streams_bidi_left is %d",
881 		(int)ngtcp2_conn_get_streams_bidi_left(data->conn));
882 	verbose(1, "negotiated cipher name is %s",
883 		SSL_get_cipher_name(data->ssl));
884 	if(verbosity > 0) {
885 		const unsigned char* alpn = NULL;
886 		unsigned int alpnlen = 0;
887 		char alpnstr[128];
888 		SSL_get0_alpn_selected(data->ssl, &alpn, &alpnlen);
889 		if(alpnlen > sizeof(alpnstr)-1)
890 			alpnlen = sizeof(alpnstr)-1;
891 		memmove(alpnstr, alpn, alpnlen);
892 		alpnstr[alpnlen]=0;
893 		verbose(1, "negotiated ALPN is '%s'", alpnstr);
894 	}
895 	/* The SSL_get_early_data_status call works after the handshake
896 	 * completes. */
897 	if(data->early_data_enabled) {
898 		if(SSL_get_early_data_status(data->ssl) !=
899 			SSL_EARLY_DATA_ACCEPTED) {
900 			early_data_is_rejected(data);
901 		} else {
902 			verbose(1, "early data was accepted by the server");
903 		}
904 	}
905 #if defined(USE_NGTCP2_CRYPTO_OSSL) || defined(HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT)
906 	if(data->transport_file) {
907 		early_data_write_transport(data);
908 	}
909 #endif
910 	return 0;
911 }
912 
913 /** the extend_max_local_streams_bidi callback from ngtcp2 */
914 static int
extend_max_local_streams_bidi(ngtcp2_conn * ATTR_UNUSED (conn),uint64_t max_streams,void * user_data)915 extend_max_local_streams_bidi(ngtcp2_conn* ATTR_UNUSED(conn),
916 	uint64_t max_streams, void* user_data)
917 {
918 	struct doq_client_data* data = (struct doq_client_data*)user_data;
919 	verbose(1, "extend_max_local_streams_bidi callback, %d max_streams",
920 		(int)max_streams);
921 	verbose(1, "ngtcp2_conn_get_max_data_left is %d",
922 		(int)ngtcp2_conn_get_max_data_left(data->conn));
923 #ifdef HAVE_NGTCP2_CONN_GET_MAX_LOCAL_STREAMS_UNI
924 	verbose(1, "ngtcp2_conn_get_max_local_streams_uni is %d",
925 		(int)ngtcp2_conn_get_max_local_streams_uni(data->conn));
926 #endif
927 	verbose(1, "ngtcp2_conn_get_streams_uni_left is %d",
928 		(int)ngtcp2_conn_get_streams_uni_left(data->conn));
929 	verbose(1, "ngtcp2_conn_get_streams_bidi_left is %d",
930 		(int)ngtcp2_conn_get_streams_bidi_left(data->conn));
931 	query_streams_start(data);
932 	return 0;
933 }
934 
935 /** the recv_stream_data callback from ngtcp2 */
936 static int
recv_stream_data(ngtcp2_conn * ATTR_UNUSED (conn),uint32_t flags,int64_t stream_id,uint64_t offset,const uint8_t * data,size_t datalen,void * user_data,void * stream_user_data)937 recv_stream_data(ngtcp2_conn* ATTR_UNUSED(conn), uint32_t flags,
938 	int64_t stream_id, uint64_t offset, const uint8_t* data,
939 	size_t datalen, void* user_data, void* stream_user_data)
940 {
941 	struct doq_client_data* doqdata = (struct doq_client_data*)user_data;
942 	struct doq_client_stream* str = (struct doq_client_stream*)
943 		stream_user_data;
944 	verbose(1, "recv_stream_data stream %d offset %d datalen %d%s%s",
945 		(int)stream_id, (int)offset, (int)datalen,
946 		((flags&NGTCP2_STREAM_DATA_FLAG_FIN)!=0?" FIN":""),
947 #ifdef NGTCP2_STREAM_DATA_FLAG_0RTT
948 		((flags&NGTCP2_STREAM_DATA_FLAG_0RTT)!=0?" 0RTT":"")
949 #else
950 		((flags&NGTCP2_STREAM_DATA_FLAG_EARLY)!=0?" EARLY":"")
951 #endif
952 		);
953 	if(verbosity > 0)
954 		log_hex("data", (void*)data, datalen);
955 	if(verbosity > 0) {
956 		char* logs = client_stream_string(str);
957 		verbose(1, "the stream_user_data is %s stream id %d, nread %d",
958 			logs, (int)str->stream_id, (int)str->nread);
959 		free(logs);
960 	}
961 
962 	/* append the data, if there is data */
963 	if(datalen > 0) {
964 		client_stream_recv_data(str, data, datalen);
965 	}
966 	if((flags&NGTCP2_STREAM_DATA_FLAG_FIN)!=0) {
967 		client_stream_recv_fin(doqdata, str, 1);
968 	}
969 	ngtcp2_conn_extend_max_stream_offset(doqdata->conn, stream_id, datalen);
970 	ngtcp2_conn_extend_max_offset(doqdata->conn, datalen);
971 	return 0;
972 }
973 
974 /** the stream reset callback from ngtcp2 */
975 static int
stream_reset(ngtcp2_conn * ATTR_UNUSED (conn),int64_t stream_id,uint64_t final_size,uint64_t app_error_code,void * user_data,void * stream_user_data)976 stream_reset(ngtcp2_conn* ATTR_UNUSED(conn), int64_t stream_id,
977 	uint64_t final_size, uint64_t app_error_code, void* user_data,
978 	void* stream_user_data)
979 {
980 	struct doq_client_data* doqdata = (struct doq_client_data*)user_data;
981 	struct doq_client_stream* str = (struct doq_client_stream*)
982 		stream_user_data;
983 	verbose(1, "stream reset for stream %d final size %d app error code %d",
984 		(int)stream_id, (int)final_size, (int)app_error_code);
985 	client_stream_recv_fin(doqdata, str, 0);
986 	return 0;
987 }
988 
989 /** copy sockaddr into ngtcp2 addr */
990 static void
copy_ngaddr(struct ngtcp2_addr * ngaddr,struct sockaddr_storage * addr,socklen_t addrlen)991 copy_ngaddr(struct ngtcp2_addr* ngaddr, struct sockaddr_storage* addr,
992 	socklen_t addrlen)
993 {
994 	if(addr_is_ip6(addr, addrlen)) {
995 #if defined(NGTCP2_USE_GENERIC_SOCKADDR) || defined(NGTCP2_USE_GENERIC_IPV6_SOCKADDR)
996 		struct sockaddr_in* i6 = (struct sockaddr_in6*)addr;
997 		struct ngtcp2_sockaddr_in6 a6;
998 		ngaddr->addr = calloc(1, sizeof(a6));
999 		if(!ngaddr->addr) fatal_exit("calloc failed: out of memory");
1000 		ngaddr->addrlen = sizeof(a6);
1001 		memset(&a6, 0, sizeof(a6));
1002 		a6.sin6_family = i6->sin6_family;
1003 		a6.sin6_port = i6->sin6_port;
1004 		a6.sin6_flowinfo = i6->sin6_flowinfo;
1005 		memmove(&a6.sin6_addr, i6->sin6_addr, sizeof(a6.sin6_addr);
1006 		a6.sin6_scope_id = i6->sin6_scope_id;
1007 		memmove(ngaddr->addr, &a6, sizeof(a6));
1008 #else
1009 		ngaddr->addr = (ngtcp2_sockaddr*)addr;
1010 		ngaddr->addrlen = addrlen;
1011 #endif
1012 	} else {
1013 #ifdef NGTCP2_USE_GENERIC_SOCKADDR
1014 		struct sockaddr_in* i4 = (struct sockaddr_in*)addr;
1015 		struct ngtcp2_sockaddr_in a4;
1016 		ngaddr->addr = calloc(1, sizeof(a4));
1017 		if(!ngaddr->addr) fatal_exit("calloc failed: out of memory");
1018 		ngaddr->addrlen = sizeof(a4);
1019 		memset(&a4, 0, sizeof(a4));
1020 		a4.sin_family = i4->sin_family;
1021 		a4.sin_port = i4->sin_port;
1022 		memmove(&a4.sin_addr, i4->sin_addr, sizeof(a4.sin_addr);
1023 		memmove(ngaddr->addr, &a4, sizeof(a4));
1024 #else
1025 		ngaddr->addr = (ngtcp2_sockaddr*)addr;
1026 		ngaddr->addrlen = addrlen;
1027 #endif
1028 	}
1029 }
1030 
1031 /** debug log printf for ngtcp2 connections */
1032 static void log_printf_for_doq(void* ATTR_UNUSED(user_data),
1033 	const char* fmt, ...)
1034 {
1035 	va_list ap;
1036 	va_start(ap, fmt);
1037 	fprintf(stderr, "libngtcp2: ");
1038 	vfprintf(stderr, fmt, ap);
1039 	va_end(ap);
1040 	fprintf(stderr, "\n");
1041 }
1042 
1043 /** get a timestamp in nanoseconds */
1044 static ngtcp2_tstamp get_timestamp_nanosec(void)
1045 {
1046 #ifdef CLOCK_REALTIME
1047 	struct timespec tp;
1048 	memset(&tp, 0, sizeof(tp));
1049 #ifdef CLOCK_MONOTONIC
1050 	if(clock_gettime(CLOCK_MONOTONIC, &tp) == -1) {
1051 #endif
1052 		if(clock_gettime(CLOCK_REALTIME, &tp) == -1) {
1053 			log_err("clock_gettime failed: %s", strerror(errno));
1054 		}
1055 #ifdef CLOCK_MONOTONIC
1056 	}
1057 #endif
1058 	return ((uint64_t)tp.tv_sec)*((uint64_t)1000000000) +
1059 		((uint64_t)tp.tv_nsec);
1060 #else
1061 	struct timeval tv;
1062 	if(gettimeofday(&tv, NULL) < 0) {
1063 		log_err("gettimeofday failed: %s", strerror(errno));
1064 	}
1065 	return ((uint64_t)tv.tv_sec)*((uint64_t)1000000000) +
1066 		((uint64_t)tv.tv_usec)*((uint64_t)1000);
1067 #endif /* CLOCK_REALTIME */
1068 }
1069 
1070 /** create ngtcp2 client connection and set up. */
1071 static struct ngtcp2_conn* conn_client_setup(struct doq_client_data* data)
1072 {
1073 	struct ngtcp2_conn* conn = NULL;
1074 	int rv;
1075 	struct ngtcp2_cid dcid, scid;
1076 	struct ngtcp2_path path;
1077 	uint32_t client_chosen_version = NGTCP2_PROTO_VER_V1;
1078 	struct ngtcp2_callbacks cbs;
1079 	struct ngtcp2_settings settings;
1080 	struct ngtcp2_transport_params params;
1081 
1082 	memset(&cbs, 0, sizeof(cbs));
1083 	memset(&settings, 0, sizeof(settings));
1084 	memset(&params, 0, sizeof(params));
1085 	memset(&dcid, 0, sizeof(dcid));
1086 	memset(&scid, 0, sizeof(scid));
1087 	memset(&path, 0, sizeof(path));
1088 
1089 	data->quic_version = client_chosen_version;
1090 	ngtcp2_settings_default(&settings);
1091 	if(str_is_ip6(data->svr)) {
1092 #ifdef HAVE_STRUCT_NGTCP2_SETTINGS_MAX_TX_UDP_PAYLOAD_SIZE
1093 		settings.max_tx_udp_payload_size = 1232;
1094 #else
1095 		settings.max_udp_payload_size = 1232;
1096 #endif
1097 	}
1098 	settings.rand_ctx.native_handle = data->rnd;
1099 	if(verbosity > 0) {
1100 		/* make debug logs */
1101 		settings.log_printf = log_printf_for_doq;
1102 	}
1103 	settings.initial_ts = get_timestamp_nanosec();
1104 	ngtcp2_transport_params_default(&params);
1105 	params.initial_max_stream_data_bidi_local = 256*1024;
1106 	params.initial_max_stream_data_bidi_remote = 256*1024;
1107 	params.initial_max_stream_data_uni = 256*1024;
1108 	params.initial_max_data = 1024*1024;
1109 	params.initial_max_streams_bidi = 0;
1110 	params.initial_max_streams_uni = 100;
1111 	params.max_idle_timeout = 30*NGTCP2_SECONDS;
1112 	params.active_connection_id_limit = 7;
1113 	cid_randfill(&dcid, 16, data->rnd);
1114 	cid_randfill(&scid, 16, data->rnd);
1115 	cbs.client_initial = ngtcp2_crypto_client_initial_cb;
1116 	cbs.recv_crypto_data = ngtcp2_crypto_recv_crypto_data_cb;
1117 	cbs.encrypt = ngtcp2_crypto_encrypt_cb;
1118 	cbs.decrypt = ngtcp2_crypto_decrypt_cb;
1119 	cbs.hp_mask = ngtcp2_crypto_hp_mask_cb;
1120 	cbs.recv_retry = ngtcp2_crypto_recv_retry_cb;
1121 	cbs.update_key = ngtcp2_crypto_update_key_cb;
1122 	cbs.delete_crypto_aead_ctx = ngtcp2_crypto_delete_crypto_aead_ctx_cb;
1123 	cbs.delete_crypto_cipher_ctx =
1124 		ngtcp2_crypto_delete_crypto_cipher_ctx_cb;
1125 	cbs.get_path_challenge_data = ngtcp2_crypto_get_path_challenge_data_cb;
1126 	cbs.version_negotiation = ngtcp2_crypto_version_negotiation_cb;
1127 	cbs.get_new_connection_id = get_new_connection_id_cb;
1128 	cbs.handshake_completed = handshake_completed;
1129 	cbs.extend_max_local_streams_bidi = extend_max_local_streams_bidi;
1130 	cbs.rand = rand_cb;
1131 	cbs.recv_stream_data = recv_stream_data;
1132 	cbs.stream_reset = stream_reset;
1133 	copy_ngaddr(&path.local, &data->local_addr, data->local_addr_len);
1134 	copy_ngaddr(&path.remote, &data->dest_addr, data->dest_addr_len);
1135 
1136 	rv = ngtcp2_conn_client_new(&conn, &dcid, &scid, &path,
1137 		client_chosen_version, &cbs, &settings, &params,
1138 		NULL, /* ngtcp2_mem allocator, use default */
1139 		data /* callback argument */);
1140 	if(!conn) fatal_exit("could not ngtcp2_conn_client_new: %s",
1141 		ngtcp2_strerror(rv));
1142 	data->cc_algo = settings.cc_algo;
1143 	return conn;
1144 }
1145 
1146 #ifndef HAVE_NGTCP2_CONN_ENCODE_0RTT_TRANSPORT_PARAMS
1147 /** write the transport file */
1148 static void
1149 transport_file_write(const char* file, struct ngtcp2_transport_params* params)
1150 {
1151 	FILE* out;
1152 	out = fopen(file, "w");
1153 	if(!out) {
1154 		perror(file);
1155 		return;
1156 	}
1157 	fprintf(out, "initial_max_streams_bidi=%u\n",
1158 		(unsigned)params->initial_max_streams_bidi);
1159 	fprintf(out, "initial_max_streams_uni=%u\n",
1160 		(unsigned)params->initial_max_streams_uni);
1161 	fprintf(out, "initial_max_stream_data_bidi_local=%u\n",
1162 		(unsigned)params->initial_max_stream_data_bidi_local);
1163 	fprintf(out, "initial_max_stream_data_bidi_remote=%u\n",
1164 		(unsigned)params->initial_max_stream_data_bidi_remote);
1165 	fprintf(out, "initial_max_stream_data_uni=%u\n",
1166 		(unsigned)params->initial_max_stream_data_uni);
1167 	fprintf(out, "initial_max_data=%u\n",
1168 		(unsigned)params->initial_max_data);
1169 	fprintf(out, "active_connection_id_limit=%u\n",
1170 		(unsigned)params->active_connection_id_limit);
1171 	fprintf(out, "max_datagram_frame_size=%u\n",
1172 		(unsigned)params->max_datagram_frame_size);
1173 	if(ferror(out)) {
1174 		verbose(1, "There was an error writing %s: %s",
1175 			file, strerror(errno));
1176 		fclose(out);
1177 		return;
1178 	}
1179 	fclose(out);
1180 }
1181 #endif /* HAVE_NGTCP2_CONN_ENCODE_0RTT_TRANSPORT_PARAMS */
1182 
1183 /** fetch and write the transport file */
1184 static void
1185 early_data_write_transport(struct doq_client_data* data)
1186 {
1187 #ifdef HAVE_NGTCP2_CONN_ENCODE_0RTT_TRANSPORT_PARAMS
1188 	FILE* out;
1189 	uint8_t buf[1024];
1190 	ngtcp2_ssize len = ngtcp2_conn_encode_0rtt_transport_params(data->conn,
1191 		buf, sizeof(buf));
1192 	if(len < 0) {
1193 		log_err("ngtcp2_conn_encode_0rtt_transport_params failed: %s",
1194 			ngtcp2_strerror(len));
1195 		return;
1196 	}
1197 	out = fopen(data->transport_file, "w");
1198 	if(!out) {
1199 		perror(data->transport_file);
1200 		return;
1201 	}
1202 	if(fwrite(buf, 1, len, out) != (size_t)len) {
1203 		log_err("fwrite %s failed: %s", data->transport_file,
1204 			strerror(errno));
1205 	}
1206 	if(ferror(out)) {
1207 		verbose(1, "There was an error writing %s: %s",
1208 			data->transport_file, strerror(errno));
1209 	}
1210 	fclose(out);
1211 #else
1212 	struct ngtcp2_transport_params params;
1213 	memset(&params, 0, sizeof(params));
1214 	ngtcp2_conn_get_remote_transport_params(data->conn, &params);
1215 	transport_file_write(data->transport_file, &params);
1216 #endif
1217 }
1218 
1219 #ifdef MAKE_QUIC_METHOD
1220 /** applicatation rx key callback, this is where the rx key is set,
1221  * and streams can be opened, like http3 unidirectional streams, like
1222  * the http3 control and http3 qpack encode and decoder streams. */
1223 static int
1224 application_rx_key_cb(struct doq_client_data* data)
1225 {
1226 	verbose(1, "application_rx_key_cb callback");
1227 	verbose(1, "ngtcp2_conn_get_max_data_left is %d",
1228 		(int)ngtcp2_conn_get_max_data_left(data->conn));
1229 #ifdef HAVE_NGTCP2_CONN_GET_MAX_LOCAL_STREAMS_UNI
1230 	verbose(1, "ngtcp2_conn_get_max_local_streams_uni is %d",
1231 		(int)ngtcp2_conn_get_max_local_streams_uni(data->conn));
1232 #endif
1233 	verbose(1, "ngtcp2_conn_get_streams_uni_left is %d",
1234 		(int)ngtcp2_conn_get_streams_uni_left(data->conn));
1235 	verbose(1, "ngtcp2_conn_get_streams_bidi_left is %d",
1236 		(int)ngtcp2_conn_get_streams_bidi_left(data->conn));
1237 	if(data->transport_file) {
1238 		early_data_write_transport(data);
1239 	}
1240 	return 1;
1241 }
1242 
1243 /** quic_method set_encryption_secrets function */
1244 static int
1245 set_encryption_secrets(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level,
1246 	const uint8_t *read_secret, const uint8_t *write_secret,
1247 	size_t secret_len)
1248 {
1249 	struct doq_client_data* data = get_app_data(ssl);
1250 #ifdef HAVE_NGTCP2_ENCRYPTION_LEVEL
1251 	ngtcp2_encryption_level
1252 #else
1253 	ngtcp2_crypto_level
1254 #endif
1255 		level =
1256 #ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL
1257 		ngtcp2_crypto_quictls_from_ossl_encryption_level(ossl_level);
1258 #else
1259 		ngtcp2_crypto_openssl_from_ossl_encryption_level(ossl_level);
1260 #endif
1261 
1262 	if(read_secret) {
1263 		if(ngtcp2_crypto_derive_and_install_rx_key(data->conn, NULL,
1264 			NULL, NULL, level, read_secret, secret_len) != 0) {
1265 			log_err("ngtcp2_crypto_derive_and_install_rx_key failed");
1266 			return 0;
1267 		}
1268 		if(level == NGTCP2_CRYPTO_LEVEL_APPLICATION) {
1269 			if(!application_rx_key_cb(data))
1270 				return 0;
1271 		}
1272 	}
1273 
1274 	if(write_secret) {
1275 		if(ngtcp2_crypto_derive_and_install_tx_key(data->conn, NULL,
1276 			NULL, NULL, level, write_secret, secret_len) != 0) {
1277 			log_err("ngtcp2_crypto_derive_and_install_tx_key failed");
1278 			return 0;
1279 		}
1280 	}
1281 	return 1;
1282 }
1283 
1284 /** quic_method add_handshake_data function */
1285 static int
1286 add_handshake_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level,
1287 	const uint8_t *data, size_t len)
1288 {
1289 	struct doq_client_data* doqdata = get_app_data(ssl);
1290 #ifdef HAVE_NGTCP2_ENCRYPTION_LEVEL
1291 	ngtcp2_encryption_level
1292 #else
1293 	ngtcp2_crypto_level
1294 #endif
1295 		level =
1296 #ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL
1297 		ngtcp2_crypto_quictls_from_ossl_encryption_level(ossl_level);
1298 #else
1299 		ngtcp2_crypto_openssl_from_ossl_encryption_level(ossl_level);
1300 #endif
1301 	int rv;
1302 
1303 	rv = ngtcp2_conn_submit_crypto_data(doqdata->conn, level, data, len);
1304 	if(rv != 0) {
1305 		log_err("ngtcp2_conn_submit_crypto_data failed: %s",
1306 			ngtcp2_strerror(rv));
1307 		ngtcp2_conn_set_tls_error(doqdata->conn, rv);
1308 		return 0;
1309 	}
1310 	return 1;
1311 }
1312 
1313 /** quic_method flush_flight function */
1314 static int
1315 flush_flight(SSL* ATTR_UNUSED(ssl))
1316 {
1317 	return 1;
1318 }
1319 
1320 /** quic_method send_alert function */
1321 static int
1322 send_alert(SSL *ssl, enum ssl_encryption_level_t ATTR_UNUSED(level),
1323 	uint8_t alert)
1324 {
1325 	struct doq_client_data* data = get_app_data(ssl);
1326 	data->tls_alert = alert;
1327 	return 1;
1328 }
1329 #endif /* MAKE_QUIC_METHOD */
1330 
1331 /** new session callback. We can write it to file for resumption later. */
1332 static int
1333 new_session_cb(SSL* ssl, SSL_SESSION* session)
1334 {
1335 	struct doq_client_data* data = get_app_data(ssl);
1336 	BIO *f;
1337 	log_assert(data->session_file);
1338 	verbose(1, "new session cb: the ssl session max_early_data_size is %u",
1339 		(unsigned)SSL_SESSION_get_max_early_data(session));
1340 	f = BIO_new_file(data->session_file, "w");
1341 	if(!f) {
1342 		log_err("Could not open %s: %s", data->session_file,
1343 			strerror(errno));
1344 		return 0;
1345 	}
1346 	PEM_write_bio_SSL_SESSION(f, session);
1347 	BIO_free(f);
1348 	verbose(1, "written tls session to %s", data->session_file);
1349 	return 0;
1350 }
1351 
1352 /** setup the TLS context */
1353 static SSL_CTX*
1354 ctx_client_setup(void)
1355 {
1356 	SSL_CTX* ctx = SSL_CTX_new(TLS_client_method());
1357 	if(!ctx) {
1358 		log_crypto_err("Could not SSL_CTX_new");
1359 		exit(1);
1360 	}
1361 	SSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION);
1362 	SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION);
1363 	SSL_CTX_set_default_verify_paths(ctx);
1364 #ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT
1365 	if(ngtcp2_crypto_quictls_configure_client_context(ctx) != 0) {
1366 		log_err("ngtcp2_crypto_quictls_configure_client_context failed");
1367 		exit(1);
1368 	}
1369 #elif defined(MAKE_QUIC_METHOD)
1370 	memset(&quic_method, 0, sizeof(quic_method));
1371 	quic_method.set_encryption_secrets = &set_encryption_secrets;
1372 	quic_method.add_handshake_data = &add_handshake_data;
1373 	quic_method.flush_flight = &flush_flight;
1374 	quic_method.send_alert = &send_alert;
1375 	SSL_CTX_set_quic_method(ctx, &quic_method);
1376 #endif
1377 	return ctx;
1378 }
1379 
1380 
1381 /* setup the TLS object */
1382 static SSL*
1383 ssl_client_setup(struct doq_client_data* data)
1384 {
1385 #ifdef USE_NGTCP2_CRYPTO_OSSL
1386 	int ret;
1387 #endif
1388 	SSL* ssl = SSL_new(data->ctx);
1389 	if(!ssl) {
1390 		log_crypto_err("Could not SSL_new");
1391 		exit(1);
1392 	}
1393 #ifdef USE_NGTCP2_CRYPTO_OSSL
1394 	if((ret=ngtcp2_crypto_ossl_ctx_new(&data->ossl_ctx, NULL)) != 0) {
1395 		log_err("ngtcp2_crypto_ossl_ctx_new failed: %s",
1396 			ngtcp2_strerror(ret));
1397 		exit(1);
1398 	}
1399 	ngtcp2_crypto_ossl_ctx_set_ssl(data->ossl_ctx, ssl);
1400 	if(ngtcp2_crypto_ossl_configure_client_session(ssl) != 0) {
1401 		log_err("ngtcp2_crypto_ossl_configure_client_session failed");
1402 		exit(1);
1403 	}
1404 #endif
1405 	set_app_data(ssl, data);
1406 	SSL_set_connect_state(ssl);
1407 	if(!SSL_set_fd(ssl, data->fd)) {
1408 		log_crypto_err("Could not SSL_set_fd");
1409 		exit(1);
1410 	}
1411 #ifndef USE_NGTCP2_CRYPTO_OSSL
1412 	if((data->quic_version & 0xff000000) == 0xff000000) {
1413 		SSL_set_quic_use_legacy_codepoint(ssl, 1);
1414 	} else {
1415 		SSL_set_quic_use_legacy_codepoint(ssl, 0);
1416 	}
1417 #endif
1418 	SSL_set_alpn_protos(ssl, (const unsigned char *)"\x03""doq", 4);
1419 	/* send the SNI host name */
1420 	SSL_set_tlsext_host_name(ssl, "localhost");
1421 	return ssl;
1422 }
1423 
1424 /** get packet ecn information */
1425 static uint32_t
1426 msghdr_get_ecn(struct msghdr* msg, int family)
1427 {
1428 #ifndef S_SPLINT_S
1429 	struct cmsghdr* cmsg;
1430 	if(family == AF_INET6) {
1431 		for(cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL;
1432 			cmsg = CMSG_NXTHDR(msg, cmsg)) {
1433 			if(cmsg->cmsg_level == IPPROTO_IPV6 &&
1434 				cmsg->cmsg_type == IPV6_TCLASS &&
1435 				cmsg->cmsg_len != 0) {
1436 				uint8_t* ecn = (uint8_t*)CMSG_DATA(cmsg);
1437 				return *ecn;
1438 			}
1439 		}
1440 		return 0;
1441 	}
1442 	for(cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL;
1443 		cmsg = CMSG_NXTHDR(msg, cmsg)) {
1444 		if(cmsg->cmsg_level == IPPROTO_IP &&
1445 			cmsg->cmsg_type == IP_TOS &&
1446 			cmsg->cmsg_len != 0) {
1447 			uint8_t* ecn = (uint8_t*)CMSG_DATA(cmsg);
1448 			return *ecn;
1449 		}
1450 	}
1451 	return 0;
1452 #endif /* S_SPLINT_S */
1453 }
1454 
1455 /** set the ecn on the transmission */
1456 static void
1457 set_ecn(int fd, int family, uint32_t ecn)
1458 {
1459 	unsigned int val = ecn;
1460 	if(family == AF_INET6) {
1461 		if(setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &val,
1462 			(socklen_t)sizeof(val)) == -1) {
1463 			log_err("setsockopt(.. IPV6_TCLASS ..): %s",
1464 				strerror(errno));
1465 		}
1466 		return;
1467 	}
1468 	if(setsockopt(fd, IPPROTO_IP, IP_TOS, &val,
1469 		(socklen_t)sizeof(val)) == -1) {
1470 		log_err("setsockopt(.. IP_TOS ..): %s",
1471 			strerror(errno));
1472 	}
1473 }
1474 
1475 /** send a packet */
1476 static int
1477 doq_client_send_pkt(struct doq_client_data* data, uint32_t ecn, uint8_t* buf,
1478 	size_t buf_len, int is_blocked_pkt, int* send_is_blocked)
1479 {
1480 	struct msghdr msg;
1481 	struct iovec iov[1];
1482 	ssize_t ret;
1483 	iov[0].iov_base = buf;
1484 	iov[0].iov_len = buf_len;
1485 	memset(&msg, 0, sizeof(msg));
1486 	msg.msg_name = (void*)&data->dest_addr;
1487 	msg.msg_namelen = data->dest_addr_len;
1488 	msg.msg_iov = iov;
1489 	msg.msg_iovlen = 1;
1490 	set_ecn(data->fd, data->dest_addr.ss_family, ecn);
1491 
1492 	for(;;) {
1493 		ret = sendmsg(data->fd, &msg, MSG_DONTWAIT);
1494 		if(ret == -1 && errno == EINTR)
1495 			continue;
1496 		break;
1497 	}
1498 	if(ret == -1) {
1499 		if(errno == EAGAIN) {
1500 			if(buf_len >
1501 				sldns_buffer_capacity(data->blocked_pkt))
1502 				return 0; /* Cannot store it, but the buffers
1503 				are equal length and large enough, so this
1504 				should not happen. */
1505 			data->have_blocked_pkt = 1;
1506 			if(send_is_blocked)
1507 				*send_is_blocked = 1;
1508 			/* If we already send the previously blocked packet,
1509 			 * no need to copy it, otherwise store the packet for
1510 			 * later. */
1511 			if(!is_blocked_pkt) {
1512 				data->blocked_pkt_pi.ecn = ecn;
1513 				sldns_buffer_clear(data->blocked_pkt);
1514 				sldns_buffer_write(data->blocked_pkt, buf,
1515 					buf_len);
1516 				sldns_buffer_flip(data->blocked_pkt);
1517 			}
1518 			return 0;
1519 		}
1520 		log_err("doq sendmsg: %s", strerror(errno));
1521 #ifdef HAVE_NGTCP2_CCERR_DEFAULT
1522 		ngtcp2_ccerr_set_application_error(&data->ccerr, -1, NULL, 0);
1523 #else
1524 		ngtcp2_connection_close_error_set_application_error(&data->last_error, -1, NULL, 0);
1525 #endif
1526 		return 0;
1527 	}
1528 	return 1;
1529 }
1530 
1531 /** change event write on fd to when we have data or when congested */
1532 static void
1533 event_change_write(struct doq_client_data* data, int do_write)
1534 {
1535 	ub_event_del(data->ev);
1536 	if(do_write) {
1537 		ub_event_add_bits(data->ev, UB_EV_WRITE);
1538 	} else {
1539 		ub_event_del_bits(data->ev, UB_EV_WRITE);
1540 	}
1541 	if(ub_event_add(data->ev, NULL) != 0) {
1542 		fatal_exit("could not ub_event_add");
1543 	}
1544 }
1545 
1546 /** write the connection close, with possible error */
1547 static void
1548 write_conn_close(struct doq_client_data* data)
1549 {
1550 	struct ngtcp2_path_storage ps;
1551 	struct ngtcp2_pkt_info pi;
1552 	ngtcp2_ssize ret;
1553 	if(!data->conn ||
1554 #ifdef HAVE_NGTCP2_CONN_IN_CLOSING_PERIOD
1555 		ngtcp2_conn_in_closing_period(data->conn) ||
1556 #else
1557 		ngtcp2_conn_is_in_closing_period(data->conn) ||
1558 #endif
1559 #ifdef HAVE_NGTCP2_CONN_IN_DRAINING_PERIOD
1560 		ngtcp2_conn_in_draining_period(data->conn)
1561 #else
1562 		ngtcp2_conn_is_in_draining_period(data->conn)
1563 #endif
1564 		)
1565 		return;
1566 	/* Drop blocked packet if there is one, the connection is being
1567 	 * closed. And thus no further data traffic. */
1568 	data->have_blocked_pkt = 0;
1569 	if(
1570 #ifdef HAVE_NGTCP2_CCERR_DEFAULT
1571 		data->ccerr.type == NGTCP2_CCERR_TYPE_IDLE_CLOSE
1572 #else
1573 		data->last_error.type ==
1574 		NGTCP2_CONNECTION_CLOSE_ERROR_CODE_TYPE_TRANSPORT_IDLE_CLOSE
1575 #endif
1576 		) {
1577 		/* do not call ngtcp2_conn_write_connection_close on the
1578 		 * connection because the ngtcp2_conn_handle_expiry call
1579 		 * has returned NGTCP2_ERR_IDLE_CLOSE. But continue to close
1580 		 * the connection. */
1581 		return;
1582 	}
1583 	verbose(1, "write connection close");
1584 	ngtcp2_path_storage_zero(&ps);
1585 	sldns_buffer_clear(data->pkt_buf);
1586 	ret = ngtcp2_conn_write_connection_close(
1587 		data->conn, &ps.path, &pi, sldns_buffer_begin(data->pkt_buf),
1588 		sldns_buffer_remaining(data->pkt_buf),
1589 #ifdef HAVE_NGTCP2_CCERR_DEFAULT
1590 		&data->ccerr
1591 #else
1592 		&data->last_error
1593 #endif
1594 		, get_timestamp_nanosec());
1595 	if(ret < 0) {
1596 		log_err("ngtcp2_conn_write_connection_close failed: %s",
1597 			ngtcp2_strerror(ret));
1598 		return;
1599 	}
1600 	verbose(1, "write connection close packet length %d", (int)ret);
1601 	if(ret == 0)
1602 		return;
1603 	doq_client_send_pkt(data, pi.ecn, sldns_buffer_begin(data->pkt_buf),
1604 		ret, 0, NULL);
1605 }
1606 
1607 /** disconnect we are done */
1608 static void
1609 disconnect(struct doq_client_data* data)
1610 {
1611 	verbose(1, "disconnect");
1612 	write_conn_close(data);
1613 	ub_event_base_loopexit(data->base);
1614 }
1615 
1616 /** the expire timer callback */
1617 void doq_client_timer_cb(int ATTR_UNUSED(fd),
1618 	short ATTR_UNUSED(bits), void* arg)
1619 {
1620 	struct doq_client_data* data = (struct doq_client_data*)arg;
1621 	ngtcp2_tstamp now = get_timestamp_nanosec();
1622 	int rv;
1623 
1624 	verbose(1, "doq expire_timer");
1625 	data->expire_timer_added = 0;
1626 	rv = ngtcp2_conn_handle_expiry(data->conn, now);
1627 	if(rv != 0) {
1628 		log_err("ngtcp2_conn_handle_expiry failed: %s",
1629 			ngtcp2_strerror(rv));
1630 #ifdef HAVE_NGTCP2_CCERR_DEFAULT
1631 		ngtcp2_ccerr_set_liberr(&data->ccerr, rv, NULL, 0);
1632 #else
1633 		ngtcp2_connection_close_error_set_transport_error_liberr(
1634 			&data->last_error, rv, NULL, 0);
1635 #endif
1636 		disconnect(data);
1637 		return;
1638 	}
1639 	update_timer(data);
1640 	on_write(data);
1641 }
1642 
1643 /** update the timers */
1644 static void
1645 update_timer(struct doq_client_data* data)
1646 {
1647 	ngtcp2_tstamp expiry = ngtcp2_conn_get_expiry(data->conn);
1648 	ngtcp2_tstamp now = get_timestamp_nanosec();
1649 	ngtcp2_tstamp t;
1650 	struct timeval tv;
1651 
1652 	if(expiry <= now) {
1653 		/* the timer has already expired, add with zero timeout */
1654 		t = 0;
1655 	} else {
1656 		t = expiry - now;
1657 	}
1658 
1659 	/* set the timer */
1660 	if(data->expire_timer_added) {
1661 		ub_timer_del(data->expire_timer);
1662 		data->expire_timer_added = 0;
1663 	}
1664 	memset(&tv, 0, sizeof(tv));
1665 	tv.tv_sec = t / NGTCP2_SECONDS;
1666 	tv.tv_usec = (t / NGTCP2_MICROSECONDS)%1000000;
1667 	verbose(1, "update_timer in %d.%6.6d secs", (int)tv.tv_sec,
1668 		(int)tv.tv_usec);
1669 	if(ub_timer_add(data->expire_timer, data->base,
1670 		&doq_client_timer_cb, data, &tv) != 0) {
1671 		log_err("timer_add failed: could not add expire timer");
1672 		return;
1673 	}
1674 	data->expire_timer_added = 1;
1675 }
1676 
1677 /** perform read operations on fd */
1678 static void
1679 on_read(struct doq_client_data* data)
1680 {
1681 	struct sockaddr_storage addr;
1682 	struct iovec iov[1];
1683 	struct msghdr msg;
1684 	union {
1685 		struct cmsghdr hdr;
1686 		char buf[256];
1687 	} ancil;
1688 	int i;
1689 	ssize_t rcv;
1690 	ngtcp2_pkt_info pi;
1691 	int rv;
1692 	struct ngtcp2_path path;
1693 
1694 	for(i=0; i<10; i++) {
1695 		msg.msg_name = &addr;
1696 		msg.msg_namelen = (socklen_t)sizeof(addr);
1697 		iov[0].iov_base = sldns_buffer_begin(data->pkt_buf);
1698 		iov[0].iov_len = sldns_buffer_remaining(data->pkt_buf);
1699 		msg.msg_iov = iov;
1700 		msg.msg_iovlen = 1;
1701 		msg.msg_control = ancil.buf;
1702 #ifndef S_SPLINT_S
1703 		msg.msg_controllen = sizeof(ancil.buf);
1704 #endif /* S_SPLINT_S */
1705 		msg.msg_flags = 0;
1706 
1707 		rcv = recvmsg(data->fd, &msg, MSG_DONTWAIT);
1708 		if(rcv == -1) {
1709 			if(errno == EINTR || errno == EAGAIN)
1710 				break;
1711 			log_err_addr("doq recvmsg", strerror(errno),
1712 				&data->dest_addr, sizeof(data->dest_addr_len));
1713 			break;
1714 		}
1715 
1716 		pi.ecn = msghdr_get_ecn(&msg, addr.ss_family);
1717 		verbose(1, "recvmsg %d ecn=0x%x", (int)rcv, (int)pi.ecn);
1718 
1719 		memset(&path, 0, sizeof(path));
1720 		path.local.addr = (void*)&data->local_addr;
1721 		path.local.addrlen = data->local_addr_len;
1722 		path.remote.addr = (void*)msg.msg_name;
1723 		path.remote.addrlen = msg.msg_namelen;
1724 		rv = ngtcp2_conn_read_pkt(data->conn, &path, &pi,
1725 			iov[0].iov_base, rcv, get_timestamp_nanosec());
1726 		if(rv != 0) {
1727 			log_err("ngtcp2_conn_read_pkt failed: %s",
1728 				ngtcp2_strerror(rv));
1729 			if(
1730 #ifdef HAVE_NGTCP2_CCERR_DEFAULT
1731 				data->ccerr.error_code == 0
1732 #else
1733 				data->last_error.error_code == 0
1734 #endif
1735 				) {
1736 				if(rv == NGTCP2_ERR_CRYPTO) {
1737 					/* in picotls the tls alert may need
1738 					 * to be copied, but this is with
1739 					 * openssl. And we have the value
1740 					 * data.tls_alert. */
1741 #ifdef HAVE_NGTCP2_CCERR_DEFAULT
1742 					ngtcp2_ccerr_set_tls_alert(
1743 						&data->ccerr, data->tls_alert,
1744 						NULL, 0);
1745 #else
1746 					ngtcp2_connection_close_error_set_transport_error_tls_alert(
1747 						&data->last_error,
1748 						data->tls_alert, NULL, 0);
1749 #endif
1750 				} else {
1751 #ifdef HAVE_NGTCP2_CCERR_DEFAULT
1752 					ngtcp2_ccerr_set_liberr(&data->ccerr,
1753 						rv, NULL, 0);
1754 #else
1755 					ngtcp2_connection_close_error_set_transport_error_liberr(
1756 						&data->last_error, rv, NULL,
1757 						0);
1758 #endif
1759 				}
1760 			}
1761 			disconnect(data);
1762 			return;
1763 		}
1764 	}
1765 
1766 	update_timer(data);
1767 }
1768 
1769 /** the write of this query has completed, it has spooled to packets,
1770  * set it to have the write done and move it to the list of receive streams. */
1771 static void
1772 query_write_is_done(struct doq_client_data* data,
1773 	struct doq_client_stream* str)
1774 {
1775 	if(verbosity > 0) {
1776 		char* logs = client_stream_string(str);
1777 		verbose(1, "query %s write is done", logs);
1778 		free(logs);
1779 	}
1780 	str->write_is_done = 1;
1781 	stream_list_move(str, data->query_list_send, data->query_list_receive);
1782 }
1783 
1784 /** write the data streams, if possible */
1785 static int
1786 write_streams(struct doq_client_data* data)
1787 {
1788 	ngtcp2_path_storage ps;
1789 	ngtcp2_tstamp ts = get_timestamp_nanosec();
1790 	struct doq_client_stream* str, *next;
1791 	uint32_t flags;
1792 	/* number of bytes that can be sent without packet pacing */
1793 	size_t send_quantum = ngtcp2_conn_get_send_quantum(data->conn);
1794 	/* Overhead is the stream overhead of adding a header onto the data,
1795 	 * this make sure the number of bytes to send in data bytes plus
1796 	 * the overhead overshoots the target quantum by a smaller margin,
1797 	 * and then it stops sending more bytes. With zero it would overshoot
1798 	 * more, an accurate number would not overshoot. It is based on the
1799 	 * stream frame header size. */
1800 	size_t accumulated_send = 0, overhead_stream = 24, overhead_pkt = 60,
1801 		max_packet_size = 1200;
1802 	size_t num_packets = 0, max_packets = 65535;
1803 	ngtcp2_path_storage_zero(&ps);
1804 	str = data->query_list_send->first;
1805 
1806 	if(data->cc_algo != NGTCP2_CC_ALGO_BBR
1807 #ifdef NGTCP2_CC_ALGO_BBR_V2
1808 		&& data->cc_algo != NGTCP2_CC_ALGO_BBR_V2
1809 #endif
1810 #ifdef NGTCP2_CC_ALGO_BBR2
1811 		&& data->cc_algo != NGTCP2_CC_ALGO_BBR2
1812 #endif
1813 		) {
1814 		/* If we do not have a packet pacing congestion control
1815 		 * algorithm, limit the number of packets. */
1816 		max_packets = 10;
1817 	}
1818 
1819 	/* loop like this, because at the start, the send list is empty,
1820 	 * and we want to send handshake packets. But when there is a
1821 	 * send_list, loop through that. */
1822 	for(;;) {
1823 		int64_t stream_id;
1824 		ngtcp2_pkt_info pi;
1825 		ngtcp2_vec datav[2];
1826 		size_t datav_count = 0;
1827 		int fin;
1828 		ngtcp2_ssize ret;
1829 		ngtcp2_ssize ndatalen = 0;
1830 		int send_is_blocked = 0;
1831 
1832 		if(str) {
1833 			/* pick up next in case this one is deleted */
1834 			next = str->next;
1835 			if(verbosity > 0) {
1836 				char* logs = client_stream_string(str);
1837 				verbose(1, "query %s write stream", logs);
1838 				free(logs);
1839 			}
1840 			stream_id = str->stream_id;
1841 			fin = 1;
1842 			if(str->nwrite < 2) {
1843 				str->data_tcplen = htons(str->data_len);
1844 				datav[0].base = ((uint8_t*)&str->data_tcplen)+str->nwrite;
1845 				datav[0].len = 2-str->nwrite;
1846 				datav[1].base = str->data;
1847 				datav[1].len = str->data_len;
1848 				datav_count = 2;
1849 			} else {
1850 				datav[0].base = str->data + (str->nwrite-2);
1851 				datav[0].len = str->data_len - (str->nwrite-2);
1852 				datav_count = 1;
1853 			}
1854 		} else {
1855 			next = NULL;
1856 			verbose(1, "write stream -1.");
1857 			stream_id = -1;
1858 			fin = 0;
1859 			datav[0].base = NULL;
1860 			datav[0].len = 0;
1861 			datav_count = 1;
1862 		}
1863 
1864 		/* Does the first data entry fit into the send quantum? */
1865 		/* Check if the data size sent, with a max of one full packet,
1866 		 * with added stream header and packet header is allowed
1867 		 * within the send quantum number of bytes. If not, it does
1868 		 * not fit, and wait. */
1869 		if(accumulated_send == 0 && ((datav_count == 1 &&
1870 			(datav[0].len>max_packet_size?max_packet_size:
1871 			datav[0].len)+overhead_stream+overhead_pkt >
1872 			send_quantum) ||
1873 			(datav_count == 2 &&
1874 			(datav[0].len+datav[1].len>max_packet_size?
1875 			max_packet_size:datav[0].len+datav[1].len)
1876 			+overhead_stream+overhead_pkt > send_quantum))) {
1877 			/* congestion limited */
1878 			ngtcp2_conn_update_pkt_tx_time(data->conn, ts);
1879 			event_change_write(data, 0);
1880 			/* update the timer to wait until it is possible to
1881 			 * write again */
1882 			update_timer(data);
1883 			return 0;
1884 		}
1885 		flags = 0;
1886 		if(str && str->next != NULL) {
1887 			/* Coalesce more data from more streams into this
1888 			 * packet, if possible */
1889 			/* There is more than one data entry in this send
1890 			 * quantum, does the next one fit in the quantum? */
1891 			size_t this_send, possible_next_send;
1892 			if(datav_count == 1)
1893 				this_send = datav[0].len;
1894 			else	this_send = datav[0].len + datav[1].len;
1895 			if(this_send > max_packet_size)
1896 				this_send = max_packet_size;
1897 			if(str->next->nwrite < 2)
1898 				possible_next_send = (2-str->next->nwrite) +
1899 					str->next->data_len;
1900 			else	possible_next_send = str->next->data_len -
1901 					(str->next->nwrite - 2);
1902 			if(possible_next_send > max_packet_size)
1903 				possible_next_send = max_packet_size;
1904 			/* Check if the data lengths that writev returned
1905 			 * with stream headers added up so far, in
1906 			 * accumulated_send, with added the data length
1907 			 * of this send, with a max of one full packet, and
1908 			 * the data length of the next possible send, with
1909 			 * a max of one full packet, with a stream header for
1910 			 * this_send and a stream header for the next possible
1911 			 * send and a packet header, fit in the send quantum
1912 			 * number of bytes. If so, ask to add more content
1913 			 * to the packet with the more flag. */
1914 			if(accumulated_send + this_send + possible_next_send
1915 				+2*overhead_stream+ overhead_pkt < send_quantum)
1916 				flags |= NGTCP2_WRITE_STREAM_FLAG_MORE;
1917 		}
1918 		if(fin) {
1919 			/* This is the final part of data for this stream */
1920 			flags |= NGTCP2_WRITE_STREAM_FLAG_FIN;
1921 		}
1922 		sldns_buffer_clear(data->pkt_buf);
1923 		ret = ngtcp2_conn_writev_stream(data->conn, &ps.path, &pi,
1924 			sldns_buffer_begin(data->pkt_buf),
1925 			sldns_buffer_remaining(data->pkt_buf), &ndatalen,
1926 			flags, stream_id, datav, datav_count, ts);
1927 		if(ret < 0) {
1928 			if(ret == NGTCP2_ERR_WRITE_MORE) {
1929 				if(str) {
1930 					str->nwrite += ndatalen;
1931 					if(str->nwrite >= str->data_len+2)
1932 						query_write_is_done(data, str);
1933 					str = next;
1934 					accumulated_send += ndatalen + overhead_stream;
1935 					continue;
1936 				}
1937 			}
1938 			log_err("ngtcp2_conn_writev_stream failed: %s",
1939 				ngtcp2_strerror(ret));
1940 #ifdef HAVE_NGTCP2_CCERR_DEFAULT
1941 			ngtcp2_ccerr_set_liberr(&data->ccerr, ret, NULL, 0);
1942 #else
1943 			ngtcp2_connection_close_error_set_transport_error_liberr(
1944 				&data->last_error, ret, NULL, 0);
1945 #endif
1946 			disconnect(data);
1947 			return 0;
1948 		}
1949 		verbose(1, "writev_stream pkt size %d ndatawritten %d",
1950 			(int)ret, (int)ndatalen);
1951 		if(ndatalen >= 0 && str) {
1952 			/* add the new write offset */
1953 			str->nwrite += ndatalen;
1954 			if(str->nwrite >= str->data_len+2)
1955 				query_write_is_done(data, str);
1956 		}
1957 		if(ret == 0) {
1958 			/* congestion limited */
1959 			ngtcp2_conn_update_pkt_tx_time(data->conn, ts);
1960 			event_change_write(data, 0);
1961 			/* update the timer to wait until it is possible to
1962 			 * write again */
1963 			update_timer(data);
1964 			return 0;
1965 		}
1966 		if(!doq_client_send_pkt(data, pi.ecn,
1967 			sldns_buffer_begin(data->pkt_buf), ret, 0,
1968 			&send_is_blocked)) {
1969 			if(send_is_blocked) {
1970 				/* Blocked packet, wait until it is possible
1971 				 * to write again and also set a timer. */
1972 				event_change_write(data, 1);
1973 				update_timer(data);
1974 				return 0;
1975 			}
1976 			/* Packet could not be sent. Like lost and timeout. */
1977 			ngtcp2_conn_update_pkt_tx_time(data->conn, ts);
1978 			event_change_write(data, 0);
1979 			update_timer(data);
1980 			return 0;
1981 		}
1982 		/* continue */
1983 		if((size_t)ret >= send_quantum)
1984 			break;
1985 		send_quantum -= ret;
1986 		accumulated_send = 0;
1987 		str = next;
1988 		if(str == NULL)
1989 			break;
1990 		if(++num_packets == max_packets)
1991 			break;
1992 	}
1993 	ngtcp2_conn_update_pkt_tx_time(data->conn, ts);
1994 	event_change_write(data, 1);
1995 	return 1;
1996 }
1997 
1998 /** send the blocked packet now that the stream is writable again. */
1999 static int
2000 send_blocked_pkt(struct doq_client_data* data)
2001 {
2002 	ngtcp2_tstamp ts = get_timestamp_nanosec();
2003 	int send_is_blocked = 0;
2004 	if(!doq_client_send_pkt(data, data->blocked_pkt_pi.ecn,
2005 		sldns_buffer_begin(data->pkt_buf),
2006 		sldns_buffer_limit(data->pkt_buf), 1, &send_is_blocked)) {
2007 		if(send_is_blocked) {
2008 			/* Send was blocked, again. Wait, again to retry. */
2009 			event_change_write(data, 1);
2010 			/* make sure the timer is set while waiting */
2011 			update_timer(data);
2012 			return 0;
2013 		}
2014 		/* The packed could not be sent. Like it was lost, timeout. */
2015 		data->have_blocked_pkt = 0;
2016 		ngtcp2_conn_update_pkt_tx_time(data->conn, ts);
2017 		event_change_write(data, 0);
2018 		update_timer(data);
2019 		return 0;
2020 	}
2021 	/* The blocked packet has been sent, the holding buffer can be
2022 	 * cleared. */
2023 	data->have_blocked_pkt = 0;
2024 	ngtcp2_conn_update_pkt_tx_time(data->conn, ts);
2025 	return 1;
2026 }
2027 
2028 /** perform write operations, if any, on fd */
2029 static void
2030 on_write(struct doq_client_data* data)
2031 {
2032 	if(data->have_blocked_pkt) {
2033 		if(!send_blocked_pkt(data))
2034 			return;
2035 	}
2036 	if(
2037 #ifdef HAVE_NGTCP2_CONN_IN_CLOSING_PERIOD
2038 		ngtcp2_conn_in_closing_period(data->conn)
2039 #else
2040 		ngtcp2_conn_is_in_closing_period(data->conn)
2041 #endif
2042 		)
2043 		return;
2044 	if(!write_streams(data))
2045 		return;
2046 	update_timer(data);
2047 }
2048 
2049 /** callback for main listening file descriptor */
2050 void
2051 doq_client_event_cb(int ATTR_UNUSED(fd), short bits, void* arg)
2052 {
2053 	struct doq_client_data* data = (struct doq_client_data*)arg;
2054 	verbose(1, "doq_client_event_cb %s%s%s",
2055 		((bits&UB_EV_READ)!=0?"EV_READ":""),
2056 		((bits&(UB_EV_READ|UB_EV_WRITE))==(UB_EV_READ|UB_EV_WRITE)?
2057 		" ":""),
2058 		((bits&UB_EV_WRITE)!=0?"EV_WRITE":""));
2059 	if((bits&UB_EV_READ)) {
2060 		on_read(data);
2061 	}
2062 	/* Perform the write operation anyway. The read operation may
2063 	 * have produced data, or there is content waiting and it is possible
2064 	 * to write that. */
2065 	on_write(data);
2066 }
2067 
2068 /** read the TLS session from file */
2069 static int
2070 early_data_setup_session(struct doq_client_data* data)
2071 {
2072 	SSL_SESSION* session;
2073 	BIO* f = BIO_new_file(data->session_file, "r");
2074 	if(f == NULL) {
2075 		if(errno == ENOENT) {
2076 			verbose(1, "session file %s does not exist",
2077 				data->session_file);
2078 			return 0;
2079 		}
2080 		log_err("Could not read %s: %s", data->session_file,
2081 			strerror(errno));
2082 		return 0;
2083 	}
2084 	session = PEM_read_bio_SSL_SESSION(f, NULL, 0, NULL);
2085 	if(session == NULL) {
2086 		log_crypto_err("Could not read session file with PEM_read_bio_SSL_SESSION");
2087 		BIO_free(f);
2088 		return 0;
2089 	}
2090 	BIO_free(f);
2091 	if(!SSL_set_session(data->ssl, session)) {
2092 		log_crypto_err("Could not SSL_set_session");
2093 		SSL_SESSION_free(session);
2094 		return 0;
2095 	}
2096 	if(SSL_SESSION_get_max_early_data(session) == 0) {
2097 		log_err("TLS session early data is 0");
2098 		SSL_SESSION_free(session);
2099 		return 0;
2100 	}
2101 #ifdef USE_NGTCP2_CRYPTO_OSSL
2102 	SSL_set_quic_tls_early_data_enabled(data->ssl, 1);
2103 #else
2104 	SSL_set_quic_early_data_enabled(data->ssl, 1);
2105 #endif
2106 	SSL_SESSION_free(session);
2107 	return 1;
2108 }
2109 
2110 #ifndef HAVE_NGTCP2_CONN_ENCODE_0RTT_TRANSPORT_PARAMS
2111 /** parse one line from the transport file */
2112 static int
2113 transport_parse_line(struct ngtcp2_transport_params* params, char* line)
2114 {
2115 	if(strncmp(line, "initial_max_streams_bidi=", 25) == 0) {
2116 		params->initial_max_streams_bidi = atoi(line+25);
2117 		return 1;
2118 	}
2119 	if(strncmp(line, "initial_max_streams_uni=", 24) == 0) {
2120 		params->initial_max_streams_uni = atoi(line+24);
2121 		return 1;
2122 	}
2123 	if(strncmp(line, "initial_max_stream_data_bidi_local=", 35) == 0) {
2124 		params->initial_max_stream_data_bidi_local = atoi(line+35);
2125 		return 1;
2126 	}
2127 	if(strncmp(line, "initial_max_stream_data_bidi_remote=", 36) == 0) {
2128 		params->initial_max_stream_data_bidi_remote = atoi(line+36);
2129 		return 1;
2130 	}
2131 	if(strncmp(line, "initial_max_stream_data_uni=", 28) == 0) {
2132 		params->initial_max_stream_data_uni = atoi(line+28);
2133 		return 1;
2134 	}
2135 	if(strncmp(line, "initial_max_data=", 17) == 0) {
2136 		params->initial_max_data = atoi(line+17);
2137 		return 1;
2138 	}
2139 	if(strncmp(line, "active_connection_id_limit=", 27) == 0) {
2140 		params->active_connection_id_limit = atoi(line+27);
2141 		return 1;
2142 	}
2143 	if(strncmp(line, "max_datagram_frame_size=", 24) == 0) {
2144 		params->max_datagram_frame_size = atoi(line+24);
2145 		return 1;
2146 	}
2147 	return 0;
2148 }
2149 #endif /* HAVE_NGTCP2_CONN_ENCODE_0RTT_TRANSPORT_PARAMS */
2150 
2151 /** setup the early data transport file and read it */
2152 static int
2153 early_data_setup_transport(struct doq_client_data* data)
2154 {
2155 #ifdef HAVE_NGTCP2_CONN_ENCODE_0RTT_TRANSPORT_PARAMS
2156 	FILE* in;
2157 	uint8_t buf[1024];
2158 	size_t len;
2159 	int rv;
2160 	in = fopen(data->transport_file, "r");
2161 	if(!in) {
2162 		if(errno == ENOENT) {
2163 			verbose(1, "transport file %s does not exist",
2164 				data->transport_file);
2165 			return 0;
2166 		}
2167 		perror(data->transport_file);
2168 		return 0;
2169 	}
2170 	len = fread(buf, 1, sizeof(buf), in);
2171 	if(ferror(in)) {
2172 		log_err("%s: read failed: %s", data->transport_file,
2173 			strerror(errno));
2174 		fclose(in);
2175 		return 0;
2176 	}
2177 	fclose(in);
2178 	rv = ngtcp2_conn_decode_and_set_0rtt_transport_params(data->conn,
2179 		buf, len);
2180 	if(rv != 0) {
2181 		log_err("ngtcp2_conn_decode_and_set_0rtt_transport_params failed: %s",
2182 			ngtcp2_strerror(rv));
2183 		return 0;
2184 	}
2185 	return 1;
2186 #else
2187 	FILE* in;
2188 	char buf[1024];
2189 	struct ngtcp2_transport_params params;
2190 	memset(&params, 0, sizeof(params));
2191 	in = fopen(data->transport_file, "r");
2192 	if(!in) {
2193 		if(errno == ENOENT) {
2194 			verbose(1, "transport file %s does not exist",
2195 				data->transport_file);
2196 			return 0;
2197 		}
2198 		perror(data->transport_file);
2199 		return 0;
2200 	}
2201 	while(!feof(in)) {
2202 		if(!fgets(buf, sizeof(buf), in)) {
2203 			log_err("%s: read failed: %s", data->transport_file,
2204 				strerror(errno));
2205 			fclose(in);
2206 			return 0;
2207 		}
2208 		if(!transport_parse_line(&params, buf)) {
2209 			log_err("%s: could not parse line '%s'",
2210 				data->transport_file, buf);
2211 			fclose(in);
2212 			return 0;
2213 		}
2214 	}
2215 	fclose(in);
2216 	ngtcp2_conn_set_early_remote_transport_params(data->conn, &params);
2217 #endif
2218 	return 1;
2219 }
2220 
2221 /** setup for early data, read the transport file and session file */
2222 static void
2223 early_data_setup(struct doq_client_data* data)
2224 {
2225 	if(!early_data_setup_session(data)) {
2226 		verbose(1, "TLS session resumption failed, early data is disabled");
2227 		data->early_data_enabled = 0;
2228 		return;
2229 	}
2230 	if(!early_data_setup_transport(data)) {
2231 		verbose(1, "Transport parameters set failed, early data is disabled");
2232 		data->early_data_enabled = 0;
2233 		return;
2234 	}
2235 }
2236 
2237 /** start the early data transmission */
2238 static void
2239 early_data_start(struct doq_client_data* data)
2240 {
2241 	query_streams_start(data);
2242 	on_write(data);
2243 }
2244 
2245 /** create doq_client_data */
2246 static struct doq_client_data*
2247 create_doq_client_data(const char* svr, int port, struct ub_event_base* base,
2248 	const char* transport_file, const char* session_file, int quiet)
2249 {
2250 	struct doq_client_data* data;
2251 	data = calloc(1, sizeof(*data));
2252 	if(!data) fatal_exit("calloc failed: out of memory");
2253 	data->base = base;
2254 #ifdef USE_NGTCP2_CRYPTO_OSSL
2255 	/* Initialize the ossl crypto, it is harmless to call twice,
2256 	 * and this is before use of doq connections. */
2257 	if(ngtcp2_crypto_ossl_init() != 0)
2258 		fatal_exit("ngtcp2_crypto_oss_init failed");
2259 #elif defined(HAVE_NGTCP2_CRYPTO_QUICTLS_INIT)
2260 	if(ngtcp2_crypto_quictls_init() != 0)
2261 		fatal_exit("ngtcp2_crypto_quictls_init failed");
2262 #endif
2263 	data->rnd = ub_initstate(NULL);
2264 	if(!data->rnd) fatal_exit("ub_initstate failed: out of memory");
2265 	data->svr = svr;
2266 	get_dest_addr(data, svr, port);
2267 	data->port = port;
2268 	data->quiet = quiet;
2269 	data->pkt_buf = sldns_buffer_new(65552);
2270 	if(!data->pkt_buf)
2271 		fatal_exit("sldns_buffer_new failed: out of memory");
2272 	data->blocked_pkt = sldns_buffer_new(65552);
2273 	if(!data->blocked_pkt)
2274 		fatal_exit("sldns_buffer_new failed: out of memory");
2275 	data->fd = open_svr_udp(data);
2276 	get_local_addr(data);
2277 	data->conn = conn_client_setup(data);
2278 #ifdef HAVE_NGTCP2_CCERR_DEFAULT
2279 	ngtcp2_ccerr_default(&data->ccerr);
2280 #else
2281 	ngtcp2_connection_close_error_default(&data->last_error);
2282 #endif
2283 	data->transport_file = transport_file;
2284 	data->session_file = session_file;
2285 	if(data->transport_file && data->session_file)
2286 		data->early_data_enabled = 1;
2287 
2288 	generate_static_secret(data, 32);
2289 	data->ctx = ctx_client_setup();
2290 	if(data->session_file) {
2291 		SSL_CTX_set_session_cache_mode(data->ctx,
2292 			SSL_SESS_CACHE_CLIENT |
2293 			SSL_SESS_CACHE_NO_INTERNAL_STORE);
2294 		SSL_CTX_sess_set_new_cb(data->ctx, new_session_cb);
2295 	}
2296 	data->ssl = ssl_client_setup(data);
2297 #ifdef USE_NGTCP2_CRYPTO_OSSL
2298 	ngtcp2_conn_set_tls_native_handle(data->conn, data->ossl_ctx);
2299 #else
2300 	ngtcp2_conn_set_tls_native_handle(data->conn, data->ssl);
2301 #endif
2302 	if(data->early_data_enabled)
2303 		early_data_setup(data);
2304 
2305 	data->ev = ub_event_new(base, data->fd, UB_EV_READ | UB_EV_WRITE |
2306 		UB_EV_PERSIST, doq_client_event_cb, data);
2307 	if(!data->ev) {
2308 		fatal_exit("could not ub_event_new");
2309 	}
2310 	if(ub_event_add(data->ev, NULL) != 0) {
2311 		fatal_exit("could not ub_event_add");
2312 	}
2313 	data->expire_timer = ub_event_new(data->base, -1,
2314 		UB_EV_TIMEOUT, &doq_client_timer_cb, data);
2315 	if(!data->expire_timer)
2316 		fatal_exit("could not ub_event_new");
2317 	data->query_list_start = stream_list_create();
2318 	data->query_list_send = stream_list_create();
2319 	data->query_list_receive = stream_list_create();
2320 	data->query_list_stop = stream_list_create();
2321 	return data;
2322 }
2323 
2324 /** delete doq_client_data */
2325 static void
2326 delete_doq_client_data(struct doq_client_data* data)
2327 {
2328 	if(!data)
2329 		return;
2330 #if defined(NGTCP2_USE_GENERIC_SOCKADDR) || defined(NGTCP2_USE_GENERIC_IPV6_SOCKADDR)
2331 	if(data->conn && data->dest_addr_len != 0) {
2332 		if(addr_is_ip6(&data->dest_addr, data->dest_addr_len)) {
2333 #  if defined(NGTCP2_USE_GENERIC_SOCKADDR) || defined(NGTCP2_USE_GENERIC_IPV6_SOCKADDR)
2334 			const struct ngtcp2_path* path6 = ngtcp2_conn_get_path(data->conn);
2335 			free(path6->local.addr);
2336 			free(path6->remote.addr);
2337 #  endif
2338 		} else {
2339 #  if defined(NGTCP2_USE_GENERIC_SOCKADDR)
2340 			const struct ngtcp2_path* path = ngtcp2_conn_get_path(data->conn);
2341 			free(path->local.addr);
2342 			free(path->remote.addr);
2343 #  endif
2344 		}
2345 	}
2346 #endif
2347 	/* Remove the app data from ngtcp2 before SSL_free of conn->ssl,
2348 	 * because the ngtcp2 conn is deleted. */
2349 	SSL_set_app_data(data->ssl, NULL);
2350 	SSL_free(data->ssl);
2351 #ifdef USE_NGTCP2_CRYPTO_OSSL
2352 	ngtcp2_crypto_ossl_ctx_del(data->ossl_ctx);
2353 #endif
2354 	ngtcp2_conn_del(data->conn);
2355 	sldns_buffer_free(data->pkt_buf);
2356 	sldns_buffer_free(data->blocked_pkt);
2357 	if(data->fd != -1)
2358 		sock_close(data->fd);
2359 	SSL_CTX_free(data->ctx);
2360 	stream_list_free(data->query_list_start);
2361 	stream_list_free(data->query_list_send);
2362 	stream_list_free(data->query_list_receive);
2363 	stream_list_free(data->query_list_stop);
2364 	ub_randfree(data->rnd);
2365 	if(data->ev) {
2366 		ub_event_del(data->ev);
2367 		ub_event_free(data->ev);
2368 	}
2369 	if(data->expire_timer_added)
2370 		ub_timer_del(data->expire_timer);
2371 	ub_event_free(data->expire_timer);
2372 	free(data->static_secret_data);
2373 	free(data);
2374 }
2375 
2376 /** create the event base that registers events and timers */
2377 static struct ub_event_base*
2378 create_event_base(time_t* secs, struct timeval* now)
2379 {
2380 	struct ub_event_base* base;
2381 	const char *evnm="event", *evsys="", *evmethod="";
2382 
2383 	memset(now, 0, sizeof(*now));
2384 	base = ub_default_event_base(1, secs, now);
2385 	if(!base) fatal_exit("could not create ub_event base");
2386 
2387 	ub_get_event_sys(base, &evnm, &evsys, &evmethod);
2388 	if(verbosity) log_info("%s %s uses %s method", evnm, evsys, evmethod);
2389 
2390 	return base;
2391 }
2392 
2393 /** enter a query into the query list */
2394 static void
2395 client_enter_query_buf(struct doq_client_data* data, struct sldns_buffer* buf)
2396 {
2397 	struct doq_client_stream* str;
2398 	str = client_stream_create(buf);
2399 	if(!str)
2400 		fatal_exit("client_stream_create failed: out of memory");
2401 	stream_list_append(data->query_list_start, str);
2402 }
2403 
2404 /** enter the queries into the query list */
2405 static void
2406 client_enter_queries(struct doq_client_data* data, char** qs, int count)
2407 {
2408 	int i;
2409 	for(i=0; i<count; i+=3) {
2410 		struct sldns_buffer* buf = NULL;
2411 		buf = make_query(qs[i], qs[i+1], qs[i+2]);
2412 		if(verbosity > 0) {
2413 			char* str;
2414 			log_buf(1, "send query", buf);
2415 			str = sldns_wire2str_pkt(sldns_buffer_begin(buf),
2416 				sldns_buffer_limit(buf));
2417 			if(!str) verbose(1, "could not sldns_wire2str_pkt");
2418 			else verbose(1, "send query:\n%s", str);
2419 			free(str);
2420 		}
2421 		client_enter_query_buf(data, buf);
2422 		sldns_buffer_free(buf);
2423 	}
2424 }
2425 
2426 /** run the dohclient queries */
2427 static void run(const char* svr, int port, char** qs, int count,
2428 	const char* transport_file, const char* session_file, int quiet)
2429 {
2430 	time_t secs = 0;
2431 	struct timeval now;
2432 	struct ub_event_base* base;
2433 	struct doq_client_data* data;
2434 
2435 	/* setup */
2436 	base = create_event_base(&secs, &now);
2437 	data = create_doq_client_data(svr, port, base, transport_file,
2438 		session_file, quiet);
2439 	client_enter_queries(data, qs, count);
2440 	if(data->early_data_enabled)
2441 		early_data_start(data);
2442 
2443 	/* run the queries */
2444 	ub_event_base_dispatch(base);
2445 
2446 	/* cleanup */
2447 	delete_doq_client_data(data);
2448 	ub_event_base_free(base);
2449 }
2450 #endif /* HAVE_NGTCP2 */
2451 
2452 #ifdef HAVE_NGTCP2
2453 /** getopt global, in case header files fail to declare it. */
2454 extern int optind;
2455 /** getopt global, in case header files fail to declare it. */
2456 extern char* optarg;
2457 int main(int ATTR_UNUSED(argc), char** ATTR_UNUSED(argv))
2458 {
2459 	int c;
2460 	int port = UNBOUND_DNS_OVER_QUIC_PORT, quiet = 0;
2461 	const char* svr = "127.0.0.1", *transport_file = NULL,
2462 		*session_file = NULL;
2463 #ifdef USE_WINSOCK
2464 	WSADATA wsa_data;
2465 	if(WSAStartup(MAKEWORD(2,2), &wsa_data) != 0) {
2466 		printf("WSAStartup failed\n");
2467 		return 1;
2468 	}
2469 #endif
2470 	checklock_set_output_name("ublocktrace-doqclient");
2471 	checklock_start();
2472 	log_init(0, 0, 0);
2473 	log_ident_set("doqclient");
2474 
2475 	while((c=getopt(argc, argv, "hp:qs:vx:y:")) != -1) {
2476 		switch(c) {
2477 			case 'p':
2478 				if(atoi(optarg)==0 && strcmp(optarg,"0")!=0) {
2479 					printf("error parsing port, "
2480 					    "number expected: %s\n", optarg);
2481 					return 1;
2482 				}
2483 				port = atoi(optarg);
2484 				break;
2485 			case 'q':
2486 				quiet++;
2487 				break;
2488 			case 's':
2489 				svr = optarg;
2490 				break;
2491 			case 'v':
2492 				verbosity++;
2493 				break;
2494 			case 'x':
2495 				transport_file = optarg;
2496 				break;
2497 			case 'y':
2498 				session_file = optarg;
2499 				break;
2500 			case 'h':
2501 			case '?':
2502 			default:
2503 				usage(argv);
2504 		}
2505 	}
2506 
2507 	argc -= optind;
2508 	argv += optind;
2509 
2510 	if(argc%3!=0) {
2511 		printf("Invalid input. Specify qname, qtype, and qclass.\n");
2512 		return 1;
2513 	}
2514 	if(port == 53) {
2515 		printf("Error: port number 53 not for DNS over QUIC. Port number 53 is not allowed to be used with DNS over QUIC. It is used for DNS datagrams.\n");
2516 		return 1;
2517 	}
2518 
2519 	run(svr, port, argv, argc, transport_file, session_file, quiet);
2520 
2521 	checklock_stop();
2522 #ifdef USE_WINSOCK
2523 	WSACleanup();
2524 #endif
2525 	return 0;
2526 }
2527 #else /* HAVE_NGTCP2 */
2528 int main(int ATTR_UNUSED(argc), char** ATTR_UNUSED(argv))
2529 {
2530 	printf("Compiled without ngtcp2 for QUIC, cannot run doqclient.\n");
2531 	return 1;
2532 }
2533 #endif /* HAVE_NGTCP2 */
2534 
2535 /***--- definitions to make fptr_wlist work. ---***/
2536 /* These are callbacks, similar to smallapp callbacks, except the debug
2537  * tool callbacks are not in it */
2538 struct tube;
2539 struct query_info;
2540 #include "util/data/packed_rrset.h"
2541 #include "daemon/worker.h"
2542 #include "daemon/remote.h"
2543 #include "util/fptr_wlist.h"
2544 #include "libunbound/context.h"
2545 
2546 void worker_handle_control_cmd(struct tube* ATTR_UNUSED(tube),
2547 	uint8_t* ATTR_UNUSED(buffer), size_t ATTR_UNUSED(len),
2548 	int ATTR_UNUSED(error), void* ATTR_UNUSED(arg))
2549 {
2550 	log_assert(0);
2551 }
2552 
2553 int worker_handle_request(struct comm_point* ATTR_UNUSED(c),
2554 	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
2555         struct comm_reply* ATTR_UNUSED(repinfo))
2556 {
2557 	log_assert(0);
2558 	return 0;
2559 }
2560 
2561 int worker_handle_service_reply(struct comm_point* ATTR_UNUSED(c),
2562 	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
2563         struct comm_reply* ATTR_UNUSED(reply_info))
2564 {
2565 	log_assert(0);
2566 	return 0;
2567 }
2568 
2569 int remote_accept_callback(struct comm_point* ATTR_UNUSED(c),
2570 	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
2571         struct comm_reply* ATTR_UNUSED(repinfo))
2572 {
2573 	log_assert(0);
2574 	return 0;
2575 }
2576 
2577 int remote_control_callback(struct comm_point* ATTR_UNUSED(c),
2578 	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
2579         struct comm_reply* ATTR_UNUSED(repinfo))
2580 {
2581 	log_assert(0);
2582 	return 0;
2583 }
2584 
2585 void worker_sighandler(int ATTR_UNUSED(sig), void* ATTR_UNUSED(arg))
2586 {
2587 	log_assert(0);
2588 }
2589 
2590 struct outbound_entry* worker_send_query(
2591 	struct query_info* ATTR_UNUSED(qinfo), uint16_t ATTR_UNUSED(flags),
2592 	int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec),
2593 	int ATTR_UNUSED(nocaps), int ATTR_UNUSED(check_ratelimit),
2594 	struct sockaddr_storage* ATTR_UNUSED(addr),
2595 	socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
2596 	size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream),
2597 	int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name),
2598 	struct module_qstate* ATTR_UNUSED(q), int* ATTR_UNUSED(was_ratelimited))
2599 {
2600 	log_assert(0);
2601 	return 0;
2602 }
2603 
2604 #ifdef UB_ON_WINDOWS
2605 void
2606 worker_win_stop_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), void*
2607 	ATTR_UNUSED(arg)) {
2608 	log_assert(0);
2609 }
2610 
2611 void
2612 wsvc_cron_cb(void* ATTR_UNUSED(arg))
2613 {
2614 	log_assert(0);
2615 }
2616 #endif /* UB_ON_WINDOWS */
2617 
2618 void
2619 worker_alloc_cleanup(void* ATTR_UNUSED(arg))
2620 {
2621 	log_assert(0);
2622 }
2623 
2624 struct outbound_entry* libworker_send_query(
2625 	struct query_info* ATTR_UNUSED(qinfo), uint16_t ATTR_UNUSED(flags),
2626 	int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec),
2627 	int ATTR_UNUSED(nocaps), int ATTR_UNUSED(check_ratelimit),
2628 	struct sockaddr_storage* ATTR_UNUSED(addr),
2629 	socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
2630 	size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream),
2631 	int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name),
2632 	struct module_qstate* ATTR_UNUSED(q), int* ATTR_UNUSED(was_ratelimited))
2633 {
2634 	log_assert(0);
2635 	return 0;
2636 }
2637 
2638 int libworker_handle_service_reply(struct comm_point* ATTR_UNUSED(c),
2639 	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
2640         struct comm_reply* ATTR_UNUSED(reply_info))
2641 {
2642 	log_assert(0);
2643 	return 0;
2644 }
2645 
2646 void libworker_handle_control_cmd(struct tube* ATTR_UNUSED(tube),
2647         uint8_t* ATTR_UNUSED(buffer), size_t ATTR_UNUSED(len),
2648         int ATTR_UNUSED(error), void* ATTR_UNUSED(arg))
2649 {
2650         log_assert(0);
2651 }
2652 
2653 void libworker_fg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
2654 	struct sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
2655 	char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
2656 {
2657 	log_assert(0);
2658 }
2659 
2660 void libworker_bg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
2661 	struct sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
2662 	char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
2663 {
2664 	log_assert(0);
2665 }
2666 
2667 void libworker_event_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
2668 	struct sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
2669 	char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
2670 {
2671 	log_assert(0);
2672 }
2673 
2674 int context_query_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
2675 {
2676 	log_assert(0);
2677 	return 0;
2678 }
2679 
2680 void worker_stat_timer_cb(void* ATTR_UNUSED(arg))
2681 {
2682 	log_assert(0);
2683 }
2684 
2685 void worker_probe_timer_cb(void* ATTR_UNUSED(arg))
2686 {
2687 	log_assert(0);
2688 }
2689 
2690 void worker_start_accept(void* ATTR_UNUSED(arg))
2691 {
2692 	log_assert(0);
2693 }
2694 
2695 void worker_stop_accept(void* ATTR_UNUSED(arg))
2696 {
2697 	log_assert(0);
2698 }
2699 
2700 /** keep track of lock id in lock-verify application */
2701 struct order_id {
2702         /** the thread id that created it */
2703         int thr;
2704         /** the instance number of creation */
2705         int instance;
2706 };
2707 
2708 int order_lock_cmp(const void* e1, const void* e2)
2709 {
2710         const struct order_id* o1 = e1;
2711         const struct order_id* o2 = e2;
2712         if(o1->thr < o2->thr) return -1;
2713         if(o1->thr > o2->thr) return 1;
2714         if(o1->instance < o2->instance) return -1;
2715         if(o1->instance > o2->instance) return 1;
2716         return 0;
2717 }
2718 
2719 int
2720 codeline_cmp(const void* a, const void* b)
2721 {
2722         return strcmp(a, b);
2723 }
2724 
2725 int replay_var_compare(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
2726 {
2727         log_assert(0);
2728         return 0;
2729 }
2730 
2731 void remote_get_opt_ssl(char* ATTR_UNUSED(str), void* ATTR_UNUSED(arg))
2732 {
2733         log_assert(0);
2734 }
2735 
2736 #ifdef USE_DNSTAP
2737 void dtio_tap_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
2738 	void* ATTR_UNUSED(arg))
2739 {
2740 	log_assert(0);
2741 }
2742 #endif
2743 
2744 #ifdef USE_DNSTAP
2745 void dtio_mainfdcallback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
2746 	void* ATTR_UNUSED(arg))
2747 {
2748 	log_assert(0);
2749 }
2750 #endif
2751 
2752 void fast_reload_service_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
2753 	void* ATTR_UNUSED(arg))
2754 {
2755 	log_assert(0);
2756 }
2757 
2758 int fast_reload_client_callback(struct comm_point* ATTR_UNUSED(c),
2759 	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
2760         struct comm_reply* ATTR_UNUSED(repinfo))
2761 {
2762 	log_assert(0);
2763 	return 0;
2764 }
2765