comparison src/event/ngx_event_quic.c @ 8560:d0d3fc0697a0 quic

QUIC: packet processing refactoring. All packet header parsing is now performed by ngx_quic_parse_packet() function, located in the ngx_quic_transport.c file. The packet processing is centralized in the ngx_quic_process_packet() function which decides if the packet should be accepted, ignored or connection should be closed, depending on the connection state. As a result of refactoring, behavior has changed in some places: - minimal size of Initial packet is now always tested - connection IDs are always tested in existing connections - old keys are discarded on encryption level switch
author Vladimir Homutov <vl@nginx.com>
date Wed, 30 Sep 2020 15:14:09 +0300
parents a89a58c642ef
children b4ef79ef1c23
comparison
equal deleted inserted replaced
8559:a89a58c642ef 8560:d0d3fc0697a0
185 static ngx_int_t ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl, 185 static ngx_int_t ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl,
186 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt); 186 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt);
187 static ngx_int_t ngx_quic_negotiate_version(ngx_connection_t *c, 187 static ngx_int_t ngx_quic_negotiate_version(ngx_connection_t *c,
188 ngx_quic_header_t *inpkt); 188 ngx_quic_header_t *inpkt);
189 static ngx_int_t ngx_quic_new_dcid(ngx_connection_t *c, ngx_str_t *odcid); 189 static ngx_int_t ngx_quic_new_dcid(ngx_connection_t *c, ngx_str_t *odcid);
190 static ngx_int_t ngx_quic_retry(ngx_connection_t *c); 190 static ngx_int_t ngx_quic_send_retry(ngx_connection_t *c);
191 static ngx_int_t ngx_quic_new_token(ngx_connection_t *c, ngx_str_t *token); 191 static ngx_int_t ngx_quic_new_token(ngx_connection_t *c, ngx_str_t *token);
192 static ngx_int_t ngx_quic_validate_token(ngx_connection_t *c, 192 static ngx_int_t ngx_quic_validate_token(ngx_connection_t *c,
193 ngx_quic_header_t *pkt); 193 ngx_quic_header_t *pkt);
194 static ngx_int_t ngx_quic_init_connection(ngx_connection_t *c); 194 static ngx_int_t ngx_quic_init_connection(ngx_connection_t *c);
195 static ngx_inline size_t ngx_quic_max_udp_payload(ngx_connection_t *c); 195 static ngx_inline size_t ngx_quic_max_udp_payload(ngx_connection_t *c);
199 static ngx_int_t ngx_quic_close_quic(ngx_connection_t *c, ngx_int_t rc); 199 static ngx_int_t ngx_quic_close_quic(ngx_connection_t *c, ngx_int_t rc);
200 static void ngx_quic_close_timer_handler(ngx_event_t *ev); 200 static void ngx_quic_close_timer_handler(ngx_event_t *ev);
201 static ngx_int_t ngx_quic_close_streams(ngx_connection_t *c, 201 static ngx_int_t ngx_quic_close_streams(ngx_connection_t *c,
202 ngx_quic_connection_t *qc); 202 ngx_quic_connection_t *qc);
203 203
204 static ngx_int_t ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b); 204 static ngx_int_t ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b,
205 static ngx_inline u_char *ngx_quic_skip_zero_padding(ngx_buf_t *b); 205 ngx_ssl_t *ssl, ngx_quic_conf_t *conf);
206 static ngx_int_t ngx_quic_retry_input(ngx_connection_t *c, 206 static ngx_int_t ngx_quic_process_packet(ngx_connection_t *c, ngx_ssl_t *ssl,
207 ngx_quic_header_t *pkt); 207 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt);
208 static ngx_int_t ngx_quic_initial_input(ngx_connection_t *c, 208 static void ngx_quic_discard_ctx(ngx_connection_t *c,
209 ngx_quic_header_t *pkt); 209 enum ssl_encryption_level_t level);
210 static ngx_int_t ngx_quic_handshake_input(ngx_connection_t *c,
211 ngx_quic_header_t *pkt);
212 static ngx_int_t ngx_quic_early_input(ngx_connection_t *c,
213 ngx_quic_header_t *pkt);
214 static ngx_int_t ngx_quic_check_peer(ngx_quic_connection_t *qc, 210 static ngx_int_t ngx_quic_check_peer(ngx_quic_connection_t *qc,
215 ngx_quic_header_t *pkt);
216 static ngx_int_t ngx_quic_app_input(ngx_connection_t *c,
217 ngx_quic_header_t *pkt); 211 ngx_quic_header_t *pkt);
218 static ngx_int_t ngx_quic_payload_handler(ngx_connection_t *c, 212 static ngx_int_t ngx_quic_payload_handler(ngx_connection_t *c,
219 ngx_quic_header_t *pkt); 213 ngx_quic_header_t *pkt);
220 static ngx_int_t ngx_quic_send_ack(ngx_connection_t *c, ngx_quic_header_t *pkt); 214 static ngx_int_t ngx_quic_send_ack(ngx_connection_t *c, ngx_quic_header_t *pkt);
221 static ngx_int_t ngx_quic_ack_delay(ngx_connection_t *c, 215 static ngx_int_t ngx_quic_ack_delay(ngx_connection_t *c,
628 622
629 623
630 void 624 void
631 ngx_quic_run(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_quic_conf_t *conf) 625 ngx_quic_run(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_quic_conf_t *conf)
632 { 626 {
633 ngx_int_t rc; 627 ngx_int_t rc;
634 ngx_buf_t *b;
635 ngx_quic_header_t pkt;
636 628
637 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic run"); 629 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic run");
638 630
639 c->log->action = "QUIC initialization"; 631 c->log->action = "QUIC initialization";
640 632
641 ngx_memzero(&pkt, sizeof(ngx_quic_header_t)); 633 rc = ngx_quic_input(c, c->buffer, ssl, conf);
642
643 b = c->buffer;
644
645 pkt.log = c->log;
646 pkt.raw = b;
647 pkt.data = b->start;
648 pkt.len = b->last - b->start;
649
650 rc = ngx_quic_new_connection(c, ssl, conf, &pkt);
651 if (rc != NGX_OK) { 634 if (rc != NGX_OK) {
652 ngx_quic_close_connection(c, rc == NGX_DECLINED ? NGX_DONE : NGX_ERROR); 635 ngx_quic_close_connection(c, rc == NGX_DECLINED ? NGX_DONE : NGX_ERROR);
653 return; 636 return;
654 } 637 }
655 638
664 647
665 static ngx_int_t 648 static ngx_int_t
666 ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl, 649 ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl,
667 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt) 650 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt)
668 { 651 {
669 ngx_int_t rc;
670 ngx_uint_t i; 652 ngx_uint_t i;
671 ngx_quic_tp_t *ctp; 653 ngx_quic_tp_t *ctp;
672 ngx_quic_secrets_t *keys;
673 ngx_quic_send_ctx_t *ctx;
674 ngx_quic_client_id_t *cid; 654 ngx_quic_client_id_t *cid;
675 ngx_quic_connection_t *qc; 655 ngx_quic_connection_t *qc;
676 static u_char buf[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE];
677
678 if (ngx_buf_size(pkt->raw) < NGX_QUIC_MIN_INITIAL_SIZE) {
679 ngx_log_error(NGX_LOG_INFO, c->log, 0,
680 "quic UDP datagram is too small for initial packet");
681 return NGX_ERROR;
682 }
683
684 if (ngx_quic_parse_long_header(pkt) != NGX_OK) {
685 return NGX_ERROR;
686 }
687
688 if (pkt->version != NGX_QUIC_VERSION) {
689 return ngx_quic_negotiate_version(c, pkt);
690 }
691
692 if (!ngx_quic_pkt_in(pkt->flags)) {
693 ngx_log_error(NGX_LOG_INFO, c->log, 0,
694 "quic invalid initial packet: 0x%xd", pkt->flags);
695 return NGX_ERROR;
696 }
697
698 if (ngx_quic_parse_initial_header(pkt) != NGX_OK) {
699 return NGX_ERROR;
700 }
701
702 if (pkt->dcid.len < NGX_QUIC_CID_LEN_MIN) {
703 /* 7.2. Negotiating Connection IDs */
704 ngx_log_error(NGX_LOG_INFO, c->log, 0,
705 "quic too short dcid in initial packet: length %i",
706 pkt->dcid.len);
707 return NGX_ERROR;
708 }
709 656
710 c->log->action = "creating new quic connection"; 657 c->log->action = "creating new quic connection";
711 658
712 qc = ngx_pcalloc(c->pool, sizeof(ngx_quic_connection_t)); 659 qc = ngx_pcalloc(c->pool, sizeof(ngx_quic_connection_t));
713 if (qc == NULL) { 660 if (qc == NULL) {
802 749
803 ngx_queue_insert_tail(&qc->client_ids, &cid->queue); 750 ngx_queue_insert_tail(&qc->client_ids, &cid->queue);
804 qc->nclient_ids++; 751 qc->nclient_ids++;
805 qc->curr_seqnum = 0; 752 qc->curr_seqnum = 0;
806 753
807 keys = &c->quic->keys[ssl_encryption_initial];
808
809 if (ngx_quic_set_initial_secret(c->pool, &keys->client, &keys->server,
810 &qc->odcid)
811 != NGX_OK)
812 {
813 return NGX_ERROR;
814 }
815
816 qc->initialized = 1; 754 qc->initialized = 1;
817 755
818 if (ngx_terminate || ngx_exiting) { 756 if (ngx_terminate || ngx_exiting) {
819 qc->error = NGX_QUIC_ERR_CONNECTION_REFUSED; 757 qc->error = NGX_QUIC_ERR_CONNECTION_REFUSED;
820 return NGX_ERROR; 758 return NGX_ERROR;
821 } 759 }
822
823 if (pkt->token.len) {
824 rc = ngx_quic_validate_token(c, pkt);
825
826 if (rc == NGX_ERROR) {
827 ngx_log_error(NGX_LOG_INFO, c->log, 0, "quic invalid token");
828 return NGX_ERROR;
829 }
830
831 if (rc == NGX_DECLINED) {
832 ngx_log_error(NGX_LOG_INFO, c->log, 0, "quic expired token");
833 return ngx_quic_retry(c);
834 }
835
836 /* NGX_OK */
837 qc->validated = 1;
838
839 } else if (conf->retry) {
840 return ngx_quic_retry(c);
841 }
842
843 pkt->secret = &keys->client;
844 pkt->level = ssl_encryption_initial;
845 pkt->plaintext = buf;
846
847 ctx = ngx_quic_get_send_ctx(qc, pkt->level);
848
849 rc = ngx_quic_decrypt(pkt, NULL, &ctx->largest_pn);
850 if (rc != NGX_OK) {
851 qc->error = pkt->error;
852 qc->error_reason = "failed to decrypt packet";
853 return rc;
854 }
855
856 if (ngx_quic_init_connection(c) != NGX_OK) {
857 return NGX_ERROR;
858 }
859
860 if (ngx_quic_payload_handler(c, pkt) != NGX_OK) {
861 return NGX_ERROR;
862 }
863
864 /* pos is at header end, adjust by actual packet length */
865 pkt->raw->pos += pkt->len;
866
867 (void) ngx_quic_skip_zero_padding(pkt->raw);
868
869 rc = ngx_quic_input(c, pkt->raw);
870
871 if (rc == NGX_ERROR) {
872 return NGX_ERROR;
873 }
874
875 /* rc == NGX_OK || rc == NGX_DECLINED */
876 760
877 return NGX_OK; 761 return NGX_OK;
878 } 762 }
879 763
880 764
937 return NGX_OK; 821 return NGX_OK;
938 } 822 }
939 823
940 824
941 static ngx_int_t 825 static ngx_int_t
942 ngx_quic_retry(ngx_connection_t *c) 826 ngx_quic_send_retry(ngx_connection_t *c)
943 { 827 {
944 ssize_t len; 828 ssize_t len;
945 ngx_str_t res, token; 829 ngx_str_t res, token;
946 ngx_quic_header_t pkt; 830 ngx_quic_header_t pkt;
947 u_char buf[NGX_QUIC_RETRY_BUFFER_SIZE]; 831 u_char buf[NGX_QUIC_RETRY_BUFFER_SIZE];
1192 } 1076 }
1193 1077
1194 ngx_memcpy(&msec, tdec + len, sizeof(msec)); 1078 ngx_memcpy(&msec, tdec + len, sizeof(msec));
1195 1079
1196 if (ngx_current_msec - msec > NGX_QUIC_RETRY_LIFETIME) { 1080 if (ngx_current_msec - msec > NGX_QUIC_RETRY_LIFETIME) {
1081 ngx_log_error(NGX_LOG_INFO, c->log, 0, "quic expired token");
1197 return NGX_DECLINED; 1082 return NGX_DECLINED;
1198 } 1083 }
1199 1084
1200 return NGX_OK; 1085 return NGX_OK;
1201 1086
1202 bad_token: 1087 bad_token:
1088
1089 ngx_log_error(NGX_LOG_INFO, c->log, 0, "quic invalid token");
1203 1090
1204 qc->error = NGX_QUIC_ERR_INVALID_TOKEN; 1091 qc->error = NGX_QUIC_ERR_INVALID_TOKEN;
1205 qc->error_reason = "invalid_token"; 1092 qc->error_reason = "invalid_token";
1206 1093
1207 return NGX_ERROR; 1094 return NGX_ERROR;
1337 } 1224 }
1338 1225
1339 b.last += n; 1226 b.last += n;
1340 qc->received += n; 1227 qc->received += n;
1341 1228
1342 rc = ngx_quic_input(c, &b); 1229 rc = ngx_quic_input(c, &b, NULL, NULL);
1343 1230
1344 if (rc == NGX_ERROR) { 1231 if (rc == NGX_ERROR) {
1345 ngx_quic_close_connection(c, NGX_ERROR); 1232 ngx_quic_close_connection(c, NGX_ERROR);
1346 return; 1233 return;
1347 } 1234 }
1601 return NGX_AGAIN; 1488 return NGX_AGAIN;
1602 } 1489 }
1603 1490
1604 1491
1605 static ngx_int_t 1492 static ngx_int_t
1606 ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b) 1493 ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b, ngx_ssl_t *ssl,
1494 ngx_quic_conf_t *conf)
1607 { 1495 {
1608 u_char *p; 1496 u_char *p;
1609 ngx_int_t rc; 1497 ngx_int_t rc;
1610 ngx_uint_t good; 1498 ngx_uint_t good;
1611 ngx_quic_header_t pkt; 1499 ngx_quic_header_t pkt;
1623 pkt.len = b->last - p; 1511 pkt.len = b->last - p;
1624 pkt.log = c->log; 1512 pkt.log = c->log;
1625 pkt.flags = p[0]; 1513 pkt.flags = p[0];
1626 pkt.raw->pos++; 1514 pkt.raw->pos++;
1627 1515
1628 if (c->quic->in_retry) { 1516 rc = ngx_quic_process_packet(c, ssl, conf, &pkt);
1629 rc = ngx_quic_retry_input(c, &pkt);
1630
1631 } else if (ngx_quic_long_pkt(pkt.flags)) {
1632
1633 if (ngx_quic_pkt_in(pkt.flags)) {
1634 rc = ngx_quic_initial_input(c, &pkt);
1635
1636 } else if (ngx_quic_pkt_hs(pkt.flags)) {
1637 rc = ngx_quic_handshake_input(c, &pkt);
1638
1639 } else if (ngx_quic_pkt_zrtt(pkt.flags)) {
1640 rc = ngx_quic_early_input(c, &pkt);
1641
1642 } else {
1643 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1644 "quic unknown long packet type");
1645 rc = NGX_DECLINED;
1646 }
1647
1648 } else {
1649 rc = ngx_quic_app_input(c, &pkt);
1650 }
1651 1517
1652 if (rc == NGX_ERROR) { 1518 if (rc == NGX_ERROR) {
1653 return NGX_ERROR; 1519 return NGX_ERROR;
1654 } 1520 }
1655 1521
1676 * or cannot be parsed properly. 1542 * or cannot be parsed properly.
1677 */ 1543 */
1678 1544
1679 /* b->pos is at header end, adjust by actual packet length */ 1545 /* b->pos is at header end, adjust by actual packet length */
1680 b->pos = pkt.data + pkt.len; 1546 b->pos = pkt.data + pkt.len;
1681 p = ngx_quic_skip_zero_padding(b); 1547
1548 /* firefox workaround: skip zero padding at the end of quic packet */
1549 while (b->pos < b->last && *(b->pos) == 0) {
1550 b->pos++;
1551 }
1552
1553 p = b->pos;
1682 } 1554 }
1683 1555
1684 return good ? NGX_OK : NGX_DECLINED; 1556 return good ? NGX_OK : NGX_DECLINED;
1685 } 1557 }
1686 1558
1687 1559
1688 /* firefox workaround: skip zero padding at the end of quic packet */
1689 static ngx_inline u_char *
1690 ngx_quic_skip_zero_padding(ngx_buf_t *b)
1691 {
1692 while (b->pos < b->last && *(b->pos) == 0) {
1693 b->pos++;
1694 }
1695
1696 return b->pos;
1697 }
1698
1699
1700 static ngx_int_t 1560 static ngx_int_t
1701 ngx_quic_retry_input(ngx_connection_t *c, ngx_quic_header_t *pkt) 1561 ngx_quic_process_packet(ngx_connection_t *c, ngx_ssl_t *ssl,
1562 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt)
1702 { 1563 {
1703 ngx_int_t rc; 1564 ngx_int_t rc;
1704 ngx_quic_secrets_t *keys; 1565 ngx_ssl_conn_t *ssl_conn;
1566 ngx_quic_secrets_t *keys, *next, tmp;
1705 ngx_quic_send_ctx_t *ctx; 1567 ngx_quic_send_ctx_t *ctx;
1706 ngx_quic_connection_t *qc; 1568 ngx_quic_connection_t *qc;
1569
1707 static u_char buf[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE]; 1570 static u_char buf[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE];
1708 1571
1709 c->log->action = "retrying quic connection"; 1572 rc = ngx_quic_parse_packet(pkt);
1710 1573
1711 if (ngx_buf_size(pkt->raw) < NGX_QUIC_MIN_INITIAL_SIZE) { 1574 if (rc == NGX_DECLINED || rc == NGX_ERROR) {
1575 return rc;
1576 }
1577
1578 qc = c->quic;
1579
1580 if (qc) {
1581
1582 if (rc == NGX_ABORT) {
1583 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1584 "quic unsupported version: 0x%xD", pkt->version);
1585 return NGX_DECLINED;
1586 }
1587
1588 if (ngx_quic_check_peer(qc, pkt) != NGX_OK) {
1589 return NGX_DECLINED;
1590 }
1591
1592 if (qc->in_retry) {
1593
1594 c->log->action = "retrying quic connection";
1595
1596 if (pkt->level != ssl_encryption_initial) {
1597 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1598 "quic discard late retry packet");
1599 return NGX_DECLINED;
1600 }
1601
1602 if (!pkt->token.len) {
1603 return NGX_DECLINED;
1604 }
1605
1606 if (ngx_quic_new_dcid(c, &pkt->dcid) != NGX_OK) {
1607 return NGX_ERROR;
1608 }
1609
1610 qc->tp.initial_scid = qc->dcid;
1611 qc->in_retry = 0;
1612
1613 keys = &qc->keys[ssl_encryption_initial];
1614
1615 if (ngx_quic_set_initial_secret(c->pool, &keys->client,
1616 &keys->server, &qc->odcid)
1617 != NGX_OK)
1618 {
1619 return NGX_ERROR;
1620 }
1621
1622 if (ngx_quic_validate_token(c, pkt) != NGX_OK) {
1623 return NGX_ERROR;
1624 }
1625
1626 qc->validated = 1;
1627 }
1628
1629 } else {
1630
1631 if (rc == NGX_ABORT) {
1632 return ngx_quic_negotiate_version(c, pkt);
1633 }
1634
1635 if (pkt->level == ssl_encryption_initial) {
1636
1637 if (pkt->dcid.len < NGX_QUIC_CID_LEN_MIN) {
1638 /* 7.2. Negotiating Connection IDs */
1639 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1640 "quic too short dcid in initial"
1641 " packet: length %i", pkt->dcid.len);
1642 return NGX_ERROR;
1643 }
1644
1645 rc = ngx_quic_new_connection(c, ssl, conf, pkt);
1646 if (rc != NGX_OK) {
1647 return rc;
1648 }
1649
1650 if (pkt->token.len) {
1651 if (ngx_quic_validate_token(c, pkt) != NGX_OK) {
1652 return NGX_ERROR;
1653 }
1654
1655 } else if (conf->retry) {
1656 return ngx_quic_send_retry(c);
1657 }
1658
1659 qc = c->quic;
1660
1661 keys = &qc->keys[ssl_encryption_initial];
1662
1663 if (ngx_quic_set_initial_secret(c->pool, &keys->client,
1664 &keys->server, &qc->odcid)
1665 != NGX_OK)
1666 {
1667 return NGX_ERROR;
1668 }
1669
1670 } else if (pkt->level == ssl_encryption_application) {
1671 return NGX_DECLINED;
1672
1673 } else {
1674 return NGX_ERROR;
1675 }
1676 }
1677
1678 keys = &qc->keys[pkt->level];
1679
1680 if (keys->client.key.len == 0) {
1712 ngx_log_error(NGX_LOG_INFO, c->log, 0, 1681 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1713 "quic UDP datagram is too small for initial packet"); 1682 "quic no level %d keys yet, ignoring packet", pkt->level);
1714 return NGX_DECLINED; 1683 return NGX_DECLINED;
1715 } 1684 }
1716 1685
1717 if (ngx_quic_parse_long_header(pkt) != NGX_OK) { 1686 next = &qc->next_key;
1718 return NGX_DECLINED;
1719 }
1720
1721 if (pkt->version != NGX_QUIC_VERSION) {
1722 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1723 "quic unsupported version: 0x%xD", pkt->version);
1724 return NGX_DECLINED;
1725 }
1726
1727 if (ngx_quic_pkt_zrtt(pkt->flags)) {
1728 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1729 "quic discard inflight 0-RTT packet");
1730 return NGX_DECLINED;
1731 }
1732
1733 if (!ngx_quic_pkt_in(pkt->flags)) {
1734 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1735 "quic invalid initial packet: 0x%xd", pkt->flags);
1736 return NGX_DECLINED;
1737 }
1738
1739 if (ngx_quic_parse_initial_header(pkt) != NGX_OK) {
1740 return NGX_DECLINED;
1741 }
1742
1743 if (!pkt->token.len) {
1744 return NGX_DECLINED;
1745 }
1746
1747 if (ngx_quic_new_dcid(c, &pkt->dcid) != NGX_OK) {
1748 return NGX_ERROR;
1749 }
1750
1751 qc = c->quic;
1752 qc->tp.initial_scid = c->quic->dcid;
1753
1754 keys = &c->quic->keys[ssl_encryption_initial];
1755
1756 if (ngx_quic_set_initial_secret(c->pool, &keys->client, &keys->server,
1757 &qc->odcid)
1758 != NGX_OK)
1759 {
1760 return NGX_ERROR;
1761 }
1762
1763 c->quic->in_retry = 0;
1764
1765 if (ngx_quic_validate_token(c, pkt) != NGX_OK) {
1766 ngx_log_error(NGX_LOG_INFO, c->log, 0, "quic invalid token");
1767 return NGX_ERROR;
1768 }
1769
1770 qc->validated = 1;
1771 1687
1772 pkt->secret = &keys->client; 1688 pkt->secret = &keys->client;
1773 pkt->level = ssl_encryption_initial; 1689 pkt->next = &next->client;
1690 pkt->key_phase = qc->key_phase;
1774 pkt->plaintext = buf; 1691 pkt->plaintext = buf;
1775 1692
1776 ctx = ngx_quic_get_send_ctx(qc, pkt->level); 1693 ctx = ngx_quic_get_send_ctx(qc, pkt->level);
1777 1694
1778 rc = ngx_quic_decrypt(pkt, NULL, &ctx->largest_pn); 1695 ssl_conn = c->ssl ? c->ssl->connection : NULL;
1779 if (rc != NGX_OK) {
1780 qc->error = pkt->error;
1781 qc->error_reason = "failed to decrypt packet";
1782 return rc;
1783 }
1784
1785 if (ngx_quic_init_connection(c) != NGX_OK) {
1786 return NGX_ERROR;
1787 }
1788
1789 if (ngx_quic_payload_handler(c, pkt) != NGX_OK) {
1790 return NGX_ERROR;
1791 }
1792
1793 return NGX_OK;
1794 }
1795
1796
1797 static ngx_int_t
1798 ngx_quic_initial_input(ngx_connection_t *c, ngx_quic_header_t *pkt)
1799 {
1800 ngx_int_t rc;
1801 ngx_ssl_conn_t *ssl_conn;
1802 ngx_quic_secrets_t *keys;
1803 ngx_quic_send_ctx_t *ctx;
1804 ngx_quic_connection_t *qc;
1805 static u_char buf[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE];
1806
1807 c->log->action = "processing initial quic packet";
1808
1809 ssl_conn = c->ssl->connection;
1810
1811 if (ngx_quic_parse_long_header(pkt) != NGX_OK) {
1812 return NGX_DECLINED;
1813 }
1814
1815 if (pkt->version != NGX_QUIC_VERSION) {
1816 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1817 "quic unsupported version: 0x%xD", pkt->version);
1818 return NGX_DECLINED;
1819 }
1820
1821 qc = c->quic;
1822
1823 if (ngx_quic_check_peer(qc, pkt) != NGX_OK) {
1824 return NGX_DECLINED;
1825 }
1826
1827 if (ngx_quic_parse_initial_header(pkt) != NGX_OK) {
1828 return NGX_DECLINED;
1829 }
1830
1831 keys = &qc->keys[ssl_encryption_initial];
1832
1833 pkt->secret = &keys->client;
1834 pkt->level = ssl_encryption_initial;
1835 pkt->plaintext = buf;
1836
1837 ctx = ngx_quic_get_send_ctx(qc, pkt->level);
1838 1696
1839 rc = ngx_quic_decrypt(pkt, ssl_conn, &ctx->largest_pn); 1697 rc = ngx_quic_decrypt(pkt, ssl_conn, &ctx->largest_pn);
1840 if (rc != NGX_OK) { 1698 if (rc != NGX_OK) {
1841 qc->error = pkt->error; 1699 qc->error = pkt->error;
1842 qc->error_reason = "failed to decrypt packet"; 1700 qc->error_reason = "failed to decrypt packet";
1843 return rc; 1701 return rc;
1844 } 1702 }
1845 1703
1846 return ngx_quic_payload_handler(c, pkt); 1704 if (c->ssl == NULL) {
1847 } 1705 if (ngx_quic_init_connection(c) != NGX_OK) {
1848 1706 return NGX_ERROR;
1849 1707 }
1850 static ngx_int_t 1708 }
1851 ngx_quic_handshake_input(ngx_connection_t *c, ngx_quic_header_t *pkt) 1709
1852 { 1710 if (pkt->level == ssl_encryption_handshake) {
1853 ngx_int_t rc; 1711 /*
1712 * 4.10.1. The successful use of Handshake packets indicates
1713 * that no more Initial packets need to be exchanged
1714 */
1715 ngx_quic_discard_ctx(c, ssl_encryption_initial);
1716 qc->validated = 1;
1717 }
1718
1719 if (pkt->level != ssl_encryption_application) {
1720 return ngx_quic_payload_handler(c, pkt);
1721 }
1722
1723 ngx_gettimeofday(&pkt->received);
1724
1725 /* switch keys on Key Phase change */
1726
1727 if (pkt->key_update) {
1728 qc->key_phase ^= 1;
1729
1730 tmp = *keys;
1731 *keys = *next;
1732 *next = tmp;
1733 }
1734
1735 rc = ngx_quic_payload_handler(c, pkt);
1736 if (rc != NGX_OK) {
1737 return rc;
1738 }
1739
1740 /* generate next keys */
1741
1742 if (pkt->key_update) {
1743 if (ngx_quic_key_update(c, keys, next) != NGX_OK) {
1744 return NGX_ERROR;
1745 }
1746 }
1747
1748 return NGX_OK;
1749 }
1750
1751
1752 static void
1753 ngx_quic_discard_ctx(ngx_connection_t *c, enum ssl_encryption_level_t level)
1754 {
1854 ngx_queue_t *q; 1755 ngx_queue_t *q;
1855 ngx_quic_frame_t *f; 1756 ngx_quic_frame_t *f;
1856 ngx_quic_secrets_t *keys;
1857 ngx_quic_send_ctx_t *ctx; 1757 ngx_quic_send_ctx_t *ctx;
1858 ngx_quic_connection_t *qc; 1758 ngx_quic_connection_t *qc;
1859 static u_char buf[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE];
1860
1861 c->log->action = "processing handshake quic packet";
1862 1759
1863 qc = c->quic; 1760 qc = c->quic;
1864 1761
1865 keys = &c->quic->keys[ssl_encryption_handshake]; 1762 if (qc->keys[level].client.key.len == 0) {
1866 1763 return;
1867 if (keys->client.key.len == 0) { 1764 }
1868 ngx_log_error(NGX_LOG_INFO, c->log, 0, 1765
1869 "quic no read keys yet, packet ignored"); 1766 qc->keys[level].client.key.len = 0;
1870 return NGX_DECLINED; 1767 qc->pto_count = 0;
1871 } 1768
1872 1769 ctx = ngx_quic_get_send_ctx(qc, level);
1873 /* extract cleartext data into pkt */
1874 if (ngx_quic_parse_long_header(pkt) != NGX_OK) {
1875 return NGX_DECLINED;
1876 }
1877
1878 if (pkt->version != NGX_QUIC_VERSION) {
1879 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1880 "quic unsupported version: 0x%xD", pkt->version);
1881 return NGX_DECLINED;
1882 }
1883
1884 if (ngx_quic_check_peer(qc, pkt) != NGX_OK) {
1885 return NGX_DECLINED;
1886 }
1887
1888 if (ngx_quic_parse_handshake_header(pkt) != NGX_OK) {
1889 return NGX_DECLINED;
1890 }
1891
1892 pkt->secret = &keys->client;
1893 pkt->level = ssl_encryption_handshake;
1894 pkt->plaintext = buf;
1895
1896 ctx = ngx_quic_get_send_ctx(qc, pkt->level);
1897
1898 rc = ngx_quic_decrypt(pkt, c->ssl->connection, &ctx->largest_pn);
1899 if (rc != NGX_OK) {
1900 qc->error = pkt->error;
1901 qc->error_reason = "failed to decrypt packet";
1902 return rc;
1903 }
1904
1905 /*
1906 * 4.10.1. The successful use of Handshake packets indicates
1907 * that no more Initial packets need to be exchanged
1908 */
1909 ctx = ngx_quic_get_send_ctx(c->quic, ssl_encryption_initial);
1910 1770
1911 while (!ngx_queue_empty(&ctx->sent)) { 1771 while (!ngx_queue_empty(&ctx->sent)) {
1912 q = ngx_queue_head(&ctx->sent); 1772 q = ngx_queue_head(&ctx->sent);
1913 ngx_queue_remove(q); 1773 ngx_queue_remove(q);
1914 1774
1915 f = ngx_queue_data(q, ngx_quic_frame_t, queue); 1775 f = ngx_queue_data(q, ngx_quic_frame_t, queue);
1916 ngx_quic_congestion_ack(c, f); 1776 ngx_quic_congestion_ack(c, f);
1917 ngx_quic_free_frame(c, f); 1777 ngx_quic_free_frame(c, f);
1918 } 1778 }
1919
1920 qc->validated = 1;
1921 qc->pto_count = 0;
1922
1923 return ngx_quic_payload_handler(c, pkt);
1924 }
1925
1926
1927 static ngx_int_t
1928 ngx_quic_early_input(ngx_connection_t *c, ngx_quic_header_t *pkt)
1929 {
1930 ngx_int_t rc;
1931 ngx_quic_secrets_t *keys;
1932 ngx_quic_send_ctx_t *ctx;
1933 ngx_quic_connection_t *qc;
1934 static u_char buf[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE];
1935
1936 c->log->action = "processing early data quic packet";
1937
1938 qc = c->quic;
1939
1940 /* extract cleartext data into pkt */
1941 if (ngx_quic_parse_long_header(pkt) != NGX_OK) {
1942 return NGX_DECLINED;
1943 }
1944
1945 if (pkt->version != NGX_QUIC_VERSION) {
1946 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1947 "quic unsupported version: 0x%xD", pkt->version);
1948 return NGX_DECLINED;
1949 }
1950
1951 if (ngx_quic_check_peer(qc, pkt) != NGX_OK) {
1952 return NGX_DECLINED;
1953 }
1954
1955 if (ngx_quic_parse_handshake_header(pkt) != NGX_OK) {
1956 return NGX_DECLINED;
1957 }
1958
1959 keys = &c->quic->keys[ssl_encryption_early_data];
1960
1961 if (keys->client.key.len == 0) {
1962 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1963 "quic no 0-RTT keys yet, packet ignored");
1964 return NGX_DECLINED;
1965 }
1966
1967
1968 pkt->secret = &keys->client;
1969 pkt->level = ssl_encryption_early_data;
1970 pkt->plaintext = buf;
1971
1972 ctx = ngx_quic_get_send_ctx(qc, pkt->level);
1973
1974 rc = ngx_quic_decrypt(pkt, c->ssl->connection, &ctx->largest_pn);
1975 if (rc != NGX_OK) {
1976 qc->error = pkt->error;
1977 qc->error_reason = "failed to decrypt packet";
1978 return rc;
1979 }
1980
1981 return ngx_quic_payload_handler(c, pkt);
1982 } 1779 }
1983 1780
1984 1781
1985 static ngx_int_t 1782 static ngx_int_t
1986 ngx_quic_check_peer(ngx_quic_connection_t *qc, ngx_quic_header_t *pkt) 1783 ngx_quic_check_peer(ngx_quic_connection_t *qc, ngx_quic_header_t *pkt)
1987 { 1784 {
1785 ngx_str_t *dcid;
1988 ngx_queue_t *q; 1786 ngx_queue_t *q;
1989 ngx_quic_send_ctx_t *ctx; 1787 ngx_quic_send_ctx_t *ctx;
1990 ngx_quic_client_id_t *cid; 1788 ngx_quic_client_id_t *cid;
1991 1789
1790 dcid = (pkt->level == ssl_encryption_early_data) ? &qc->odcid : &qc->dcid;
1791
1792 if (pkt->dcid.len == dcid->len
1793 && ngx_memcmp(pkt->dcid.data, dcid->data, dcid->len) == 0)
1794 {
1795 if (pkt->level == ssl_encryption_application) {
1796 return NGX_OK;
1797 }
1798
1799 goto found;
1800 }
1801
1802 /*
1803 * a packet sent in response to an initial client packet might be lost,
1804 * thus check also for old dcid
1805 */
1992 ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_initial); 1806 ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_initial);
1993 1807
1994 if (ngx_quic_pkt_zrtt(pkt->flags) 1808 if (pkt->level == ssl_encryption_initial
1995 || (ngx_quic_pkt_in(pkt->flags) && ctx->largest_ack == (uint64_t) -1)) 1809 && ctx->largest_ack == (uint64_t) -1)
1996 { 1810 {
1997 if (pkt->dcid.len == qc->odcid.len 1811 if (pkt->dcid.len == qc->odcid.len
1998 && ngx_memcmp(pkt->dcid.data, qc->odcid.data, qc->odcid.len) == 0) 1812 && ngx_memcmp(pkt->dcid.data, qc->odcid.data, qc->odcid.len) == 0)
1999 { 1813 {
2000 goto found; 1814 goto found;
2001 } 1815 }
2002 } 1816 }
2003 1817
2004 if (!ngx_quic_pkt_zrtt(pkt->flags)) {
2005 if (pkt->dcid.len == qc->dcid.len
2006 && ngx_memcmp(pkt->dcid.data, qc->dcid.data, qc->dcid.len) == 0)
2007 {
2008 goto found;
2009 }
2010 }
2011
2012 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic unexpected quic dcid"); 1818 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic unexpected quic dcid");
2013 return NGX_ERROR; 1819 return NGX_ERROR;
2014 1820
2015 found: 1821 found:
2016 1822
2025 { 1831 {
2026 return NGX_OK; 1832 return NGX_OK;
2027 } 1833 }
2028 } 1834 }
2029 1835
2030 1836 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic unexpected quic scid");
2031 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic unexpected quic scid"); 1837 return NGX_ERROR;
2032 return NGX_ERROR;
2033 }
2034
2035
2036 static ngx_int_t
2037 ngx_quic_app_input(ngx_connection_t *c, ngx_quic_header_t *pkt)
2038 {
2039 ngx_int_t rc;
2040 ngx_quic_secrets_t *keys, *next, tmp;
2041 ngx_quic_send_ctx_t *ctx;
2042 ngx_quic_connection_t *qc;
2043 static u_char buf[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE];
2044
2045 c->log->action = "processing application data quic packet";
2046
2047 qc = c->quic;
2048
2049 keys = &c->quic->keys[ssl_encryption_application];
2050 next = &c->quic->next_key;
2051
2052 if (keys->client.key.len == 0) {
2053 ngx_log_error(NGX_LOG_INFO, c->log, 0,
2054 "quic no read keys yet, packet ignored");
2055 return NGX_DECLINED;
2056 }
2057
2058 if (ngx_quic_parse_short_header(pkt, &qc->dcid) != NGX_OK) {
2059 return NGX_DECLINED;
2060 }
2061
2062 pkt->secret = &keys->client;
2063 pkt->next = &next->client;
2064 pkt->key_phase = c->quic->key_phase;
2065 pkt->level = ssl_encryption_application;
2066 pkt->plaintext = buf;
2067
2068 ctx = ngx_quic_get_send_ctx(qc, pkt->level);
2069
2070 rc = ngx_quic_decrypt(pkt, c->ssl->connection, &ctx->largest_pn);
2071 if (rc != NGX_OK) {
2072 qc->error = pkt->error;
2073 qc->error_reason = "failed to decrypt packet";
2074 return rc;
2075 }
2076
2077 ngx_gettimeofday(&pkt->received);
2078
2079 /* switch keys on Key Phase change */
2080
2081 if (pkt->key_update) {
2082 c->quic->key_phase ^= 1;
2083
2084 tmp = *keys;
2085 *keys = *next;
2086 *next = tmp;
2087 }
2088
2089 rc = ngx_quic_payload_handler(c, pkt);
2090
2091 if (rc == NGX_ERROR) {
2092 return NGX_ERROR;
2093 }
2094
2095 /* generate next keys */
2096
2097 if (pkt->key_update) {
2098 if (ngx_quic_key_update(c, keys, next) != NGX_OK) {
2099 return NGX_ERROR;
2100 }
2101 }
2102
2103 return rc;
2104 } 1838 }
2105 1839
2106 1840
2107 static ngx_int_t 1841 static ngx_int_t
2108 ngx_quic_payload_handler(ngx_connection_t *c, ngx_quic_header_t *pkt) 1842 ngx_quic_payload_handler(ngx_connection_t *c, ngx_quic_header_t *pkt)
2979 2713
2980 static ngx_int_t 2714 static ngx_int_t
2981 ngx_quic_crypto_input(ngx_connection_t *c, ngx_quic_frame_t *frame, void *data) 2715 ngx_quic_crypto_input(ngx_connection_t *c, ngx_quic_frame_t *frame, void *data)
2982 { 2716 {
2983 int n, sslerr; 2717 int n, sslerr;
2984 ngx_queue_t *q;
2985 ngx_ssl_conn_t *ssl_conn; 2718 ngx_ssl_conn_t *ssl_conn;
2986 ngx_quic_send_ctx_t *ctx;
2987 ngx_quic_crypto_frame_t *f; 2719 ngx_quic_crypto_frame_t *f;
2988 2720
2989 f = &frame->u.crypto; 2721 f = &frame->u.crypto;
2990 2722
2991 ssl_conn = c->ssl->connection; 2723 ssl_conn = c->ssl->connection;
3058 2790
3059 /* 2791 /*
3060 * 4.10.2 An endpoint MUST discard its handshake keys 2792 * 4.10.2 An endpoint MUST discard its handshake keys
3061 * when the TLS handshake is confirmed 2793 * when the TLS handshake is confirmed
3062 */ 2794 */
3063 ctx = ngx_quic_get_send_ctx(c->quic, ssl_encryption_handshake); 2795 ngx_quic_discard_ctx(c, ssl_encryption_handshake);
3064
3065 while (!ngx_queue_empty(&ctx->sent)) {
3066 q = ngx_queue_head(&ctx->sent);
3067 ngx_queue_remove(q);
3068
3069 frame = ngx_queue_data(q, ngx_quic_frame_t, queue);
3070 ngx_quic_congestion_ack(c, frame);
3071 ngx_quic_free_frame(c, frame);
3072 }
3073
3074 c->quic->pto_count = 0;
3075 } 2796 }
3076 2797
3077 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, 2798 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
3078 "quic SSL_quic_read_level: %d, SSL_quic_write_level: %d", 2799 "quic SSL_quic_read_level: %d, SSL_quic_write_level: %d",
3079 (int) SSL_quic_read_level(ssl_conn), 2800 (int) SSL_quic_read_level(ssl_conn),