Mercurial > hg > nginx-quic
comparison src/event/ngx_event_quic.c @ 8060:fc89d02bdca2 quic
QUIC: added version negotiation support.
If a client attemtps to start a new connection with unsupported version,
a version negotiation packet is sent that contains a list of supported
versions (currently this is a single version, selected at compile time).
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Thu, 20 Aug 2020 17:11:04 +0300 |
parents | de7d6d943f68 |
children | 0609ea17ca23 |
comparison
equal
deleted
inserted
replaced
8059:a748095bf94e | 8060:fc89d02bdca2 |
---|---|
167 enum ssl_encryption_level_t level, uint8_t alert); | 167 enum ssl_encryption_level_t level, uint8_t alert); |
168 | 168 |
169 | 169 |
170 static ngx_int_t ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl, | 170 static ngx_int_t ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl, |
171 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt); | 171 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt); |
172 static ngx_int_t ngx_quic_negotiate_version(ngx_connection_t *c, | |
173 ngx_quic_header_t *inpkt); | |
172 static ngx_int_t ngx_quic_new_dcid(ngx_connection_t *c, ngx_str_t *odcid); | 174 static ngx_int_t ngx_quic_new_dcid(ngx_connection_t *c, ngx_str_t *odcid); |
173 static ngx_int_t ngx_quic_retry(ngx_connection_t *c); | 175 static ngx_int_t ngx_quic_retry(ngx_connection_t *c); |
174 static ngx_int_t ngx_quic_new_token(ngx_connection_t *c, ngx_str_t *token); | 176 static ngx_int_t ngx_quic_new_token(ngx_connection_t *c, ngx_str_t *token); |
175 static ngx_int_t ngx_quic_validate_token(ngx_connection_t *c, | 177 static ngx_int_t ngx_quic_validate_token(ngx_connection_t *c, |
176 ngx_quic_header_t *pkt); | 178 ngx_quic_header_t *pkt); |
657 rc = ngx_quic_parse_long_header(pkt); | 659 rc = ngx_quic_parse_long_header(pkt); |
658 if (rc != NGX_OK) { | 660 if (rc != NGX_OK) { |
659 return rc; | 661 return rc; |
660 } | 662 } |
661 | 663 |
664 if (pkt->version != NGX_QUIC_VERSION) { | |
665 return ngx_quic_negotiate_version(c, pkt); | |
666 } | |
667 | |
662 if (!ngx_quic_pkt_in(pkt->flags)) { | 668 if (!ngx_quic_pkt_in(pkt->flags)) { |
663 ngx_log_error(NGX_LOG_INFO, c->log, 0, | 669 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
664 "quic invalid initial packet: 0x%xd", pkt->flags); | 670 "quic invalid initial packet: 0x%xd", pkt->flags); |
665 return NGX_ERROR; | 671 return NGX_ERROR; |
666 } | 672 } |
818 pkt->raw->pos += pkt->len; | 824 pkt->raw->pos += pkt->len; |
819 | 825 |
820 (void) ngx_quic_skip_zero_padding(pkt->raw); | 826 (void) ngx_quic_skip_zero_padding(pkt->raw); |
821 | 827 |
822 return ngx_quic_input(c, pkt->raw); | 828 return ngx_quic_input(c, pkt->raw); |
829 } | |
830 | |
831 | |
832 static ngx_int_t | |
833 ngx_quic_negotiate_version(ngx_connection_t *c, ngx_quic_header_t *inpkt) | |
834 { | |
835 size_t len; | |
836 ngx_quic_header_t pkt; | |
837 | |
838 /* buffer size is calculated assuming a single supported version */ | |
839 static u_char buf[NGX_QUIC_MAX_LONG_HEADER + sizeof(uint32_t)]; | |
840 | |
841 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
842 "sending version negotiation packet"); | |
843 | |
844 pkt.log = c->log; | |
845 pkt.flags = NGX_QUIC_PKT_LONG | NGX_QUIC_PKT_FIXED_BIT; | |
846 pkt.dcid = inpkt->scid; | |
847 pkt.scid = inpkt->dcid; | |
848 | |
849 len = ngx_quic_create_version_negotiation(&pkt, buf); | |
850 | |
851 #ifdef NGX_QUIC_DEBUG_PACKETS | |
852 ngx_quic_hexdump(c->log, "quic vnego packet to send", buf, len); | |
853 #endif | |
854 | |
855 (void) c->send(c, buf, len); | |
856 | |
857 return NGX_ERROR; | |
823 } | 858 } |
824 | 859 |
825 | 860 |
826 static ngx_int_t | 861 static ngx_int_t |
827 ngx_quic_new_dcid(ngx_connection_t *c, ngx_str_t *odcid) | 862 ngx_quic_new_dcid(ngx_connection_t *c, ngx_str_t *odcid) |
1626 rc = ngx_quic_parse_long_header(pkt); | 1661 rc = ngx_quic_parse_long_header(pkt); |
1627 if (rc != NGX_OK) { | 1662 if (rc != NGX_OK) { |
1628 return rc; | 1663 return rc; |
1629 } | 1664 } |
1630 | 1665 |
1666 if (pkt->version != NGX_QUIC_VERSION) { | |
1667 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
1668 "quic unsupported version: 0x%xD", pkt->version); | |
1669 return NGX_ERROR; | |
1670 } | |
1671 | |
1631 if (ngx_quic_pkt_zrtt(pkt->flags)) { | 1672 if (ngx_quic_pkt_zrtt(pkt->flags)) { |
1632 ngx_log_error(NGX_LOG_INFO, c->log, 0, | 1673 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
1633 "quic discard inflight 0-RTT packet"); | 1674 "quic discard inflight 0-RTT packet"); |
1634 return NGX_OK; | 1675 return NGX_OK; |
1635 } | 1676 } |
1711 ssl_conn = c->ssl->connection; | 1752 ssl_conn = c->ssl->connection; |
1712 | 1753 |
1713 rc = ngx_quic_parse_long_header(pkt); | 1754 rc = ngx_quic_parse_long_header(pkt); |
1714 if (rc != NGX_OK) { | 1755 if (rc != NGX_OK) { |
1715 return rc; | 1756 return rc; |
1757 } | |
1758 | |
1759 if (pkt->version != NGX_QUIC_VERSION) { | |
1760 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
1761 "quic unsupported version: 0x%xD", pkt->version); | |
1762 return NGX_ERROR; | |
1716 } | 1763 } |
1717 | 1764 |
1718 if (ngx_quic_parse_initial_header(pkt) != NGX_OK) { | 1765 if (ngx_quic_parse_initial_header(pkt) != NGX_OK) { |
1719 return NGX_ERROR; | 1766 return NGX_ERROR; |
1720 } | 1767 } |
1763 rc = ngx_quic_parse_long_header(pkt); | 1810 rc = ngx_quic_parse_long_header(pkt); |
1764 if (rc != NGX_OK) { | 1811 if (rc != NGX_OK) { |
1765 return rc; | 1812 return rc; |
1766 } | 1813 } |
1767 | 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_ERROR; | |
1819 } | |
1820 | |
1768 if (ngx_quic_check_peer(qc, pkt) != NGX_OK) { | 1821 if (ngx_quic_check_peer(qc, pkt) != NGX_OK) { |
1769 return NGX_ERROR; | 1822 return NGX_ERROR; |
1770 } | 1823 } |
1771 | 1824 |
1772 if (ngx_quic_parse_handshake_header(pkt) != NGX_OK) { | 1825 if (ngx_quic_parse_handshake_header(pkt) != NGX_OK) { |
1821 | 1874 |
1822 /* extract cleartext data into pkt */ | 1875 /* extract cleartext data into pkt */ |
1823 rc = ngx_quic_parse_long_header(pkt); | 1876 rc = ngx_quic_parse_long_header(pkt); |
1824 if (rc != NGX_OK) { | 1877 if (rc != NGX_OK) { |
1825 return rc; | 1878 return rc; |
1879 } | |
1880 | |
1881 if (pkt->version != NGX_QUIC_VERSION) { | |
1882 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
1883 "quic unsupported version: 0x%xD", pkt->version); | |
1884 return NGX_ERROR; | |
1826 } | 1885 } |
1827 | 1886 |
1828 if (ngx_quic_check_peer(qc, pkt) != NGX_OK) { | 1887 if (ngx_quic_check_peer(qc, pkt) != NGX_OK) { |
1829 return NGX_ERROR; | 1888 return NGX_ERROR; |
1830 } | 1889 } |