comparison src/event/ngx_event_quic.c @ 7729:1295b293d09a quic

Connection states code cleanup. + ngx_quic_init_ssl_methods() is no longer there, we setup methods on SSL connection directly. + the handshake_handler is actually a generic quic input handler + updated c->log->action and debug to reflect changes and be more informative + c->quic is always set in ngx_quic_input() + the quic connection state is set by the results of SSL_do_handshake();
author Vladimir Homutov <vl@nginx.com>
date Mon, 23 Mar 2020 14:53:04 +0300
parents f388c0ad3477
children d45325e90221
comparison
equal deleted inserted replaced
7728:66f59c67adf4 7729:1295b293d09a
5 5
6 6
7 #include <ngx_config.h> 7 #include <ngx_config.h>
8 #include <ngx_core.h> 8 #include <ngx_core.h>
9 #include <ngx_event.h> 9 #include <ngx_event.h>
10
11
12 typedef enum {
13 NGX_QUIC_ST_INITIAL, /* connection just created */
14 NGX_QUIC_ST_HANDSHAKE, /* handshake started */
15 NGX_QUIC_ST_APPLICATION /* handshake complete */
16 } ngx_quic_state_t;
10 17
11 18
12 typedef struct { 19 typedef struct {
13 ngx_rbtree_node_t node; 20 ngx_rbtree_node_t node;
14 ngx_buf_t *b; 21 ngx_buf_t *b;
32 ngx_str_t dcid; 39 ngx_str_t dcid;
33 ngx_str_t token; 40 ngx_str_t token;
34 41
35 ngx_uint_t client_tp_done; 42 ngx_uint_t client_tp_done;
36 ngx_quic_tp_t tp; 43 ngx_quic_tp_t tp;
44
45 ngx_quic_state_t state;
37 46
38 /* current packet numbers for each namespace */ 47 /* current packet numbers for each namespace */
39 ngx_uint_t initial_pn; 48 ngx_uint_t initial_pn;
40 ngx_uint_t handshake_pn; 49 ngx_uint_t handshake_pn;
41 ngx_uint_t appdata_pn; 50 ngx_uint_t appdata_pn;
73 82
74 83
75 static ngx_int_t ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl, 84 static ngx_int_t ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl,
76 ngx_quic_tp_t *tp, ngx_quic_header_t *pkt); 85 ngx_quic_tp_t *tp, ngx_quic_header_t *pkt);
77 static ngx_int_t ngx_quic_init_connection(ngx_connection_t *c); 86 static ngx_int_t ngx_quic_init_connection(ngx_connection_t *c);
78 static void ngx_quic_handshake_handler(ngx_event_t *rev); 87 static void ngx_quic_input_handler(ngx_event_t *rev);
79 static void ngx_quic_close_connection(ngx_connection_t *c); 88 static void ngx_quic_close_connection(ngx_connection_t *c);
80 89
81 static ngx_int_t ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b); 90 static ngx_int_t ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b);
82 static ngx_int_t ngx_quic_initial_input(ngx_connection_t *c, 91 static ngx_int_t ngx_quic_initial_input(ngx_connection_t *c,
83 ngx_quic_header_t *pkt); 92 ngx_quic_header_t *pkt);
326 ngx_msec_t timeout, ngx_connection_handler_pt handler) 335 ngx_msec_t timeout, ngx_connection_handler_pt handler)
327 { 336 {
328 ngx_buf_t *b; 337 ngx_buf_t *b;
329 ngx_quic_header_t pkt; 338 ngx_quic_header_t pkt;
330 339
331 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic handshake"); 340 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic run");
332 341
333 c->log->action = "QUIC handshaking"; 342 c->log->action = "QUIC initialization";
334 343
335 ngx_memzero(&pkt, sizeof(ngx_quic_header_t)); 344 ngx_memzero(&pkt, sizeof(ngx_quic_header_t));
336 345
337 b = c->buffer; 346 b = c->buffer;
338 347
350 c->quic->streams.handler = handler; 359 c->quic->streams.handler = handler;
351 c->quic->streams.timeout = timeout; 360 c->quic->streams.timeout = timeout;
352 361
353 ngx_add_timer(c->read, timeout); 362 ngx_add_timer(c->read, timeout);
354 363
355 c->read->handler = ngx_quic_handshake_handler; 364 c->read->handler = ngx_quic_input_handler;
356 365
357 return; 366 return;
358 } 367 }
359 368
360 369
385 394
386 qc = ngx_pcalloc(c->pool, sizeof(ngx_quic_connection_t)); 395 qc = ngx_pcalloc(c->pool, sizeof(ngx_quic_connection_t));
387 if (qc == NULL) { 396 if (qc == NULL) {
388 return NGX_ERROR; 397 return NGX_ERROR;
389 } 398 }
399
400 qc->state = NGX_QUIC_ST_INITIAL;
390 401
391 ngx_rbtree_init(&qc->streams.tree, &qc->streams.sentinel, 402 ngx_rbtree_init(&qc->streams.tree, &qc->streams.sentinel,
392 ngx_quic_rbtree_insert_stream); 403 ngx_quic_rbtree_insert_stream);
393 404
394 c->quic = qc; 405 c->quic = qc;
478 ngx_log_error(NGX_LOG_INFO, c->log, 0, 489 ngx_log_error(NGX_LOG_INFO, c->log, 0,
479 "SSL_set_quic_transport_params() failed"); 490 "SSL_set_quic_transport_params() failed");
480 return NGX_ERROR; 491 return NGX_ERROR;
481 } 492 }
482 493
494 qc->state = NGX_QUIC_ST_HANDSHAKE;
495
483 n = SSL_do_handshake(ssl_conn); 496 n = SSL_do_handshake(ssl_conn);
484 497
485 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n); 498 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n);
486 499
487 if (n == -1) { 500 if (n == -1) {
499 return NGX_OK; 512 return NGX_OK;
500 } 513 }
501 514
502 515
503 static void 516 static void
504 ngx_quic_handshake_handler(ngx_event_t *rev) 517 ngx_quic_input_handler(ngx_event_t *rev)
505 { 518 {
506 ssize_t n; 519 ssize_t n;
507 ngx_buf_t b; 520 ngx_buf_t b;
508 ngx_connection_t *c; 521 ngx_connection_t *c;
509 522
513 b.end = buf + 512; 526 b.end = buf + 512;
514 b.pos = b.last = b.start; 527 b.pos = b.last = b.start;
515 528
516 c = rev->data; 529 c = rev->data;
517 530
518 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, rev->log, 0, "quic handshake handler"); 531 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, rev->log, 0, "quic input handler");
519 532
520 if (rev->timedout) { 533 if (rev->timedout) {
521 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); 534 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
522 ngx_quic_close_connection(c); 535 ngx_quic_close_connection(c);
523 return; 536 return;
584 { 597 {
585 u_char *p; 598 u_char *p;
586 ngx_int_t rc; 599 ngx_int_t rc;
587 ngx_quic_header_t pkt; 600 ngx_quic_header_t pkt;
588 601
589 if (c->quic == NULL) {
590 // XXX: possible?
591 ngx_log_error(NGX_LOG_INFO, c->log, 0, "BUG: no QUIC in connection");
592 return NGX_ERROR;
593 }
594
595 p = b->start; 602 p = b->start;
596 603
597 do { 604 do {
605 c->log->action = "processing quic packet";
606
598 ngx_memzero(&pkt, sizeof(ngx_quic_header_t)); 607 ngx_memzero(&pkt, sizeof(ngx_quic_header_t));
599 pkt.raw = b; 608 pkt.raw = b;
600 pkt.data = p; 609 pkt.data = p;
601 pkt.len = b->last - p; 610 pkt.len = b->last - p;
602 pkt.log = c->log; 611 pkt.log = c->log;
645 ngx_quic_initial_input(ngx_connection_t *c, ngx_quic_header_t *pkt) 654 ngx_quic_initial_input(ngx_connection_t *c, ngx_quic_header_t *pkt)
646 { 655 {
647 ngx_ssl_conn_t *ssl_conn; 656 ngx_ssl_conn_t *ssl_conn;
648 ngx_quic_connection_t *qc; 657 ngx_quic_connection_t *qc;
649 658
659 c->log->action = "processing initial quic packet";
660
650 qc = c->quic; 661 qc = c->quic;
651 ssl_conn = c->ssl->connection; 662 ssl_conn = c->ssl->connection;
652 663
653 if (ngx_quic_parse_long_header(pkt) != NGX_OK) { 664 if (ngx_quic_parse_long_header(pkt) != NGX_OK) {
654 return NGX_ERROR; 665 return NGX_ERROR;
671 682
672 static ngx_int_t 683 static ngx_int_t
673 ngx_quic_handshake_input(ngx_connection_t *c, ngx_quic_header_t *pkt) 684 ngx_quic_handshake_input(ngx_connection_t *c, ngx_quic_header_t *pkt)
674 { 685 {
675 ngx_quic_connection_t *qc; 686 ngx_quic_connection_t *qc;
687
688 c->log->action = "processing handshake quic packet";
676 689
677 qc = c->quic; 690 qc = c->quic;
678 691
679 /* extract cleartext data into pkt */ 692 /* extract cleartext data into pkt */
680 if (ngx_quic_parse_long_header(pkt) != NGX_OK) { 693 if (ngx_quic_parse_long_header(pkt) != NGX_OK) {
724 737
725 static ngx_int_t 738 static ngx_int_t
726 ngx_quic_app_input(ngx_connection_t *c, ngx_quic_header_t *pkt) 739 ngx_quic_app_input(ngx_connection_t *c, ngx_quic_header_t *pkt)
727 { 740 {
728 ngx_quic_connection_t *qc; 741 ngx_quic_connection_t *qc;
742
743 c->log->action = "processing application data quic packet";
729 744
730 qc = c->quic; 745 qc = c->quic;
731 746
732 if (qc->secrets.client.ad.key.len == 0) { 747 if (qc->secrets.client.ad.key.len == 0) {
733 ngx_log_error(NGX_LOG_INFO, c->log, 0, 748 ngx_log_error(NGX_LOG_INFO, c->log, 0,
756 u_char *end, *p; 771 u_char *end, *p;
757 ssize_t len; 772 ssize_t len;
758 ngx_uint_t ack_this, do_close; 773 ngx_uint_t ack_this, do_close;
759 ngx_quic_frame_t frame, *ack_frame; 774 ngx_quic_frame_t frame, *ack_frame;
760 ngx_quic_connection_t *qc; 775 ngx_quic_connection_t *qc;
776
777 c->log->action = "processing quic payload";
761 778
762 qc = c->quic; 779 qc = c->quic;
763 780
764 p = pkt->payload.data; 781 p = pkt->payload.data;
765 end = p + pkt->payload.len; 782 end = p + pkt->payload.len;
955 sslerr); 972 sslerr);
956 973
957 if (sslerr == SSL_ERROR_SSL) { 974 if (sslerr == SSL_ERROR_SSL) {
958 ngx_ssl_error(NGX_LOG_ERR, c->log, 0, "SSL_do_handshake() failed"); 975 ngx_ssl_error(NGX_LOG_ERR, c->log, 0, "SSL_do_handshake() failed");
959 } 976 }
960 } 977
961 978 } else if (n == 1) {
962 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, 979 c->quic->state = NGX_QUIC_ST_APPLICATION;
980
981 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
963 "quic ssl cipher: %s", SSL_get_cipher(ssl_conn)); 982 "quic ssl cipher: %s", SSL_get_cipher(ssl_conn));
983
984 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
985 "handshake completed successfully");
986 }
964 987
965 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, 988 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
966 "SSL_quic_read_level: %d, SSL_quic_write_level: %d", 989 "SSL_quic_read_level: %d, SSL_quic_write_level: %d",
967 (int) SSL_quic_read_level(ssl_conn), 990 (int) SSL_quic_read_level(ssl_conn),
968 (int) SSL_quic_write_level(ssl_conn)); 991 (int) SSL_quic_write_level(ssl_conn));