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 */ 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 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* 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 */ 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 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 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 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* 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* 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 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 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* 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* 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 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 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 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 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 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 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 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 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 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 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 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 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 */ 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 */ 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 */ 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 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 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 */ 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 */ 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 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 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 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 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 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 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(¶ms, 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(¶ms); 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, ¶ms, 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(¶ms, 0, sizeof(params)); 1214 ngtcp2_conn_get_remote_transport_params(data->conn, ¶ms); 1215 transport_file_write(data->transport_file, ¶ms); 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(¶ms, 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(¶ms, 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, ¶ms); 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