comparison src/event/ngx_event_quic.c @ 8533:62b58f0a4711 quic

QUIC: discard incorrect packets instead of closing the connection. quic-transport 5.2: Packets that are matched to an existing connection are discarded if the packets are inconsistent with the state of that connection. 5.2.2: Servers MUST drop incoming packets under all other circumstances.
author Vladimir Homutov <vl@nginx.com>
date Tue, 01 Sep 2020 17:20:42 +0300
parents 4ff2a0b747d1
children eb5aa85294e9
comparison
equal deleted inserted replaced
8532:b13141d6d250 8533:62b58f0a4711
656 ngx_log_error(NGX_LOG_INFO, c->log, 0, 656 ngx_log_error(NGX_LOG_INFO, c->log, 0,
657 "quic UDP datagram is too small for initial packet"); 657 "quic UDP datagram is too small for initial packet");
658 return NGX_ERROR; 658 return NGX_ERROR;
659 } 659 }
660 660
661 rc = ngx_quic_parse_long_header(pkt); 661 if (ngx_quic_parse_long_header(pkt) != NGX_OK) {
662 if (rc != NGX_OK) { 662 return NGX_ERROR;
663 return rc;
664 } 663 }
665 664
666 if (pkt->version != NGX_QUIC_VERSION) { 665 if (pkt->version != NGX_QUIC_VERSION) {
667 return ngx_quic_negotiate_version(c, pkt); 666 return ngx_quic_negotiate_version(c, pkt);
668 } 667 }
1643 1642
1644 1643
1645 static ngx_int_t 1644 static ngx_int_t
1646 ngx_quic_retry_input(ngx_connection_t *c, ngx_quic_header_t *pkt) 1645 ngx_quic_retry_input(ngx_connection_t *c, ngx_quic_header_t *pkt)
1647 { 1646 {
1648 ngx_int_t rc;
1649 ngx_quic_secrets_t *keys; 1647 ngx_quic_secrets_t *keys;
1650 ngx_quic_send_ctx_t *ctx; 1648 ngx_quic_send_ctx_t *ctx;
1651 ngx_quic_connection_t *qc; 1649 ngx_quic_connection_t *qc;
1652 static u_char buf[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE]; 1650 static u_char buf[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE];
1653 1651
1657 ngx_log_error(NGX_LOG_INFO, c->log, 0, 1655 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1658 "quic UDP datagram is too small for initial packet"); 1656 "quic UDP datagram is too small for initial packet");
1659 return NGX_OK; 1657 return NGX_OK;
1660 } 1658 }
1661 1659
1662 rc = ngx_quic_parse_long_header(pkt); 1660 if (ngx_quic_parse_long_header(pkt) != NGX_OK) {
1663 if (rc != NGX_OK) { 1661 return NGX_DECLINED;
1664 return rc;
1665 } 1662 }
1666 1663
1667 if (pkt->version != NGX_QUIC_VERSION) { 1664 if (pkt->version != NGX_QUIC_VERSION) {
1668 ngx_log_error(NGX_LOG_INFO, c->log, 0, 1665 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1669 "quic unsupported version: 0x%xD", pkt->version); 1666 "quic unsupported version: 0x%xD", pkt->version);
1670 return NGX_ERROR; 1667 return NGX_DECLINED;
1671 } 1668 }
1672 1669
1673 if (ngx_quic_pkt_zrtt(pkt->flags)) { 1670 if (ngx_quic_pkt_zrtt(pkt->flags)) {
1674 ngx_log_error(NGX_LOG_INFO, c->log, 0, 1671 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1675 "quic discard inflight 0-RTT packet"); 1672 "quic discard inflight 0-RTT packet");
1677 } 1674 }
1678 1675
1679 if (!ngx_quic_pkt_in(pkt->flags)) { 1676 if (!ngx_quic_pkt_in(pkt->flags)) {
1680 ngx_log_error(NGX_LOG_INFO, c->log, 0, 1677 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1681 "quic invalid initial packet: 0x%xd", pkt->flags); 1678 "quic invalid initial packet: 0x%xd", pkt->flags);
1682 return NGX_ERROR; 1679 return NGX_DECLINED;
1683 } 1680 }
1684 1681
1685 if (ngx_quic_parse_initial_header(pkt) != NGX_OK) { 1682 if (ngx_quic_parse_initial_header(pkt) != NGX_OK) {
1686 return NGX_ERROR; 1683 return NGX_DECLINED;
1687 } 1684 }
1688 1685
1689 if (ngx_quic_new_dcid(c, &pkt->dcid) != NGX_OK) { 1686 if (ngx_quic_new_dcid(c, &pkt->dcid) != NGX_OK) {
1690 return NGX_ERROR; 1687 return NGX_ERROR;
1691 } 1688 }
1740 1737
1741 1738
1742 static ngx_int_t 1739 static ngx_int_t
1743 ngx_quic_initial_input(ngx_connection_t *c, ngx_quic_header_t *pkt) 1740 ngx_quic_initial_input(ngx_connection_t *c, ngx_quic_header_t *pkt)
1744 { 1741 {
1745 ngx_int_t rc;
1746 ngx_ssl_conn_t *ssl_conn; 1742 ngx_ssl_conn_t *ssl_conn;
1747 ngx_quic_secrets_t *keys; 1743 ngx_quic_secrets_t *keys;
1748 ngx_quic_send_ctx_t *ctx; 1744 ngx_quic_send_ctx_t *ctx;
1749 static u_char buf[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE]; 1745 static u_char buf[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE];
1750 1746
1751 c->log->action = "processing initial quic packet"; 1747 c->log->action = "processing initial quic packet";
1752 1748
1753 ssl_conn = c->ssl->connection; 1749 ssl_conn = c->ssl->connection;
1754 1750
1755 rc = ngx_quic_parse_long_header(pkt); 1751 if (ngx_quic_parse_long_header(pkt) != NGX_OK) {
1756 if (rc != NGX_OK) { 1752 return NGX_DECLINED;
1757 return rc;
1758 } 1753 }
1759 1754
1760 if (pkt->version != NGX_QUIC_VERSION) { 1755 if (pkt->version != NGX_QUIC_VERSION) {
1761 ngx_log_error(NGX_LOG_INFO, c->log, 0, 1756 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1762 "quic unsupported version: 0x%xD", pkt->version); 1757 "quic unsupported version: 0x%xD", pkt->version);
1763 return NGX_ERROR; 1758 return NGX_DECLINED;
1759 }
1760
1761 if (ngx_quic_check_peer(c->quic, pkt) != NGX_OK) {
1762 return NGX_DECLINED;
1764 } 1763 }
1765 1764
1766 if (ngx_quic_parse_initial_header(pkt) != NGX_OK) { 1765 if (ngx_quic_parse_initial_header(pkt) != NGX_OK) {
1767 return NGX_ERROR; 1766 return NGX_DECLINED;
1768 } 1767 }
1769 1768
1770 keys = &c->quic->keys[ssl_encryption_initial]; 1769 keys = &c->quic->keys[ssl_encryption_initial];
1771 1770
1772 pkt->secret = &keys->client; 1771 pkt->secret = &keys->client;
1785 1784
1786 1785
1787 static ngx_int_t 1786 static ngx_int_t
1788 ngx_quic_handshake_input(ngx_connection_t *c, ngx_quic_header_t *pkt) 1787 ngx_quic_handshake_input(ngx_connection_t *c, ngx_quic_header_t *pkt)
1789 { 1788 {
1790 ngx_int_t rc;
1791 ngx_queue_t *q; 1789 ngx_queue_t *q;
1792 ngx_quic_frame_t *f; 1790 ngx_quic_frame_t *f;
1793 ngx_quic_secrets_t *keys; 1791 ngx_quic_secrets_t *keys;
1794 ngx_quic_send_ctx_t *ctx; 1792 ngx_quic_send_ctx_t *ctx;
1795 ngx_quic_connection_t *qc; 1793 ngx_quic_connection_t *qc;
1806 "quic no read keys yet, packet ignored"); 1804 "quic no read keys yet, packet ignored");
1807 return NGX_DECLINED; 1805 return NGX_DECLINED;
1808 } 1806 }
1809 1807
1810 /* extract cleartext data into pkt */ 1808 /* extract cleartext data into pkt */
1811 rc = ngx_quic_parse_long_header(pkt); 1809 if (ngx_quic_parse_long_header(pkt) != NGX_OK) {
1812 if (rc != NGX_OK) { 1810 return NGX_DECLINED;
1813 return rc;
1814 } 1811 }
1815 1812
1816 if (pkt->version != NGX_QUIC_VERSION) { 1813 if (pkt->version != NGX_QUIC_VERSION) {
1817 ngx_log_error(NGX_LOG_INFO, c->log, 0, 1814 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1818 "quic unsupported version: 0x%xD", pkt->version); 1815 "quic unsupported version: 0x%xD", pkt->version);
1819 return NGX_ERROR; 1816 return NGX_DECLINED;
1820 } 1817 }
1821 1818
1822 if (ngx_quic_check_peer(qc, pkt) != NGX_OK) { 1819 if (ngx_quic_check_peer(qc, pkt) != NGX_OK) {
1823 return NGX_ERROR; 1820 return NGX_DECLINED;
1824 } 1821 }
1825 1822
1826 if (ngx_quic_parse_handshake_header(pkt) != NGX_OK) { 1823 if (ngx_quic_parse_handshake_header(pkt) != NGX_OK) {
1827 return NGX_ERROR; 1824 return NGX_DECLINED;
1828 } 1825 }
1829 1826
1830 pkt->secret = &keys->client; 1827 pkt->secret = &keys->client;
1831 pkt->level = ssl_encryption_handshake; 1828 pkt->level = ssl_encryption_handshake;
1832 pkt->plaintext = buf; 1829 pkt->plaintext = buf;
1861 1858
1862 1859
1863 static ngx_int_t 1860 static ngx_int_t
1864 ngx_quic_early_input(ngx_connection_t *c, ngx_quic_header_t *pkt) 1861 ngx_quic_early_input(ngx_connection_t *c, ngx_quic_header_t *pkt)
1865 { 1862 {
1866 ngx_int_t rc;
1867 ngx_quic_secrets_t *keys; 1863 ngx_quic_secrets_t *keys;
1868 ngx_quic_send_ctx_t *ctx; 1864 ngx_quic_send_ctx_t *ctx;
1869 ngx_quic_connection_t *qc; 1865 ngx_quic_connection_t *qc;
1870 static u_char buf[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE]; 1866 static u_char buf[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE];
1871 1867
1872 c->log->action = "processing early data quic packet"; 1868 c->log->action = "processing early data quic packet";
1873 1869
1874 qc = c->quic; 1870 qc = c->quic;
1875 1871
1876 /* extract cleartext data into pkt */ 1872 /* extract cleartext data into pkt */
1877 rc = ngx_quic_parse_long_header(pkt); 1873 if (ngx_quic_parse_long_header(pkt) != NGX_OK) {
1878 if (rc != NGX_OK) { 1874 return NGX_DECLINED;
1879 return rc;
1880 } 1875 }
1881 1876
1882 if (pkt->version != NGX_QUIC_VERSION) { 1877 if (pkt->version != NGX_QUIC_VERSION) {
1883 ngx_log_error(NGX_LOG_INFO, c->log, 0, 1878 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1884 "quic unsupported version: 0x%xD", pkt->version); 1879 "quic unsupported version: 0x%xD", pkt->version);
1885 return NGX_ERROR; 1880 return NGX_DECLINED;
1886 } 1881 }
1887 1882
1888 if (ngx_quic_check_peer(qc, pkt) != NGX_OK) { 1883 if (ngx_quic_check_peer(qc, pkt) != NGX_OK) {
1889 return NGX_ERROR; 1884 return NGX_DECLINED;
1890 } 1885 }
1891 1886
1892 if (ngx_quic_parse_handshake_header(pkt) != NGX_OK) { 1887 if (ngx_quic_parse_handshake_header(pkt) != NGX_OK) {
1893 return NGX_ERROR; 1888 return NGX_DECLINED;
1894 } 1889 }
1895 1890
1896 keys = &c->quic->keys[ssl_encryption_early_data]; 1891 keys = &c->quic->keys[ssl_encryption_early_data];
1897 1892
1898 if (keys->client.key.len == 0) { 1893 if (keys->client.key.len == 0) {
1968 ngx_log_error(NGX_LOG_INFO, c->log, 0, 1963 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1969 "quic no read keys yet, packet ignored"); 1964 "quic no read keys yet, packet ignored");
1970 return NGX_DECLINED; 1965 return NGX_DECLINED;
1971 } 1966 }
1972 1967
1973 rc = ngx_quic_parse_short_header(pkt, &qc->dcid); 1968 if (ngx_quic_parse_short_header(pkt, &qc->dcid) != NGX_OK) {
1974 if (rc != NGX_OK) { 1969 return NGX_DECLINED;
1975 return rc;
1976 } 1970 }
1977 1971
1978 pkt->secret = &keys->client; 1972 pkt->secret = &keys->client;
1979 pkt->next = &next->client; 1973 pkt->next = &next->client;
1980 pkt->key_phase = c->quic->key_phase; 1974 pkt->key_phase = c->quic->key_phase;