From 3b3264dc25a6d5da80c1641671737fc6505c45f1 Mon Sep 17 00:00:00 2001 From: Vladimir Homutov Date: Tue, 16 Jun 2020 11:54:05 +0300 Subject: [PATCH] QUIC: further limiting maximum QUIC packet size. quic-transport draft 29, section 14: QUIC depends upon a minimum IP packet size of at least 1280 bytes. This is the IPv6 minimum size [RFC8200] and is also supported by most modern IPv4 networks. Assuming the minimum IP header size, this results in a QUIC maximum packet size of 1232 bytes for IPv6 and 1252 bytes for IPv4. Since the packet size can change during connection lifetime, the ngx_quic_max_udp_payload() function is introduced that currently returns minimal allowed size, depending on address family. --- src/event/ngx_event_quic.c | 22 +++++++++++++++++++--- src/event/ngx_event_quic.h | 3 ++- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/event/ngx_event_quic.c b/src/event/ngx_event_quic.c index 0fd25bb64..ce07930d6 100644 --- a/src/event/ngx_event_quic.c +++ b/src/event/ngx_event_quic.c @@ -157,6 +157,7 @@ static ngx_int_t ngx_quic_new_token(ngx_connection_t *c, ngx_str_t *token); static ngx_int_t ngx_quic_validate_token(ngx_connection_t *c, ngx_quic_header_t *pkt); static ngx_int_t ngx_quic_init_connection(ngx_connection_t *c); +static ngx_inline size_t ngx_quic_max_udp_payload(ngx_connection_t *c); static void ngx_quic_input_handler(ngx_event_t *rev); static void ngx_quic_close_connection(ngx_connection_t *c, ngx_int_t rc); @@ -439,8 +440,8 @@ ngx_quic_add_handshake_data(ngx_ssl_conn_t *ssl_conn, return 0; } - if (qc->ctp.max_udp_payload_size > NGX_QUIC_MAX_UDP_PAYLOAD_OUT) { - qc->ctp.max_udp_payload_size = NGX_QUIC_MAX_UDP_PAYLOAD_OUT; + if (qc->ctp.max_udp_payload_size > ngx_quic_max_udp_payload(c)) { + qc->ctp.max_udp_payload_size = ngx_quic_max_udp_payload(c); ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic client maximum packet size truncated"); } @@ -655,7 +656,7 @@ ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_quic_tp_t *tp, qc->streams.handler = handler; ctp = &qc->ctp; - ctp->max_udp_payload_size = NGX_QUIC_MAX_UDP_PAYLOAD_OUT; + ctp->max_udp_payload_size = ngx_quic_max_udp_payload(c); ctp->ack_delay_exponent = NGX_QUIC_DEFAULT_ACK_DELAY_EXPONENT; ctp->max_ack_delay = NGX_QUIC_DEFAULT_MAX_ACK_DELAY; @@ -1122,6 +1123,21 @@ ngx_quic_init_connection(ngx_connection_t *c) } +static ngx_inline size_t +ngx_quic_max_udp_payload(ngx_connection_t *c) +{ + /* TODO: path MTU discovery */ + +#if (NGX_HAVE_INET6) + if (c->sockaddr->sa_family == AF_INET6) { + return NGX_QUIC_MAX_UDP_PAYLOAD_OUT6; + } +#endif + + return NGX_QUIC_MAX_UDP_PAYLOAD_OUT; +} + + static void ngx_quic_input_handler(ngx_event_t *rev) { diff --git a/src/event/ngx_event_quic.h b/src/event/ngx_event_quic.h index 495e07996..fe67c3e6a 100644 --- a/src/event/ngx_event_quic.h +++ b/src/event/ngx_event_quic.h @@ -23,7 +23,8 @@ /* 1 flags + 4 version + 2 x (1 + 20) s/dcid + 4 pn + 4 len + token len */ #define NGX_QUIC_MAX_UDP_PAYLOAD_SIZE 65527 -#define NGX_QUIC_MAX_UDP_PAYLOAD_OUT 1300 /* TODO */ +#define NGX_QUIC_MAX_UDP_PAYLOAD_OUT 1252 +#define NGX_QUIC_MAX_UDP_PAYLOAD_OUT6 1232 #define NGX_QUIC_DEFAULT_ACK_DELAY_EXPONENT 3 #define NGX_QUIC_DEFAULT_MAX_ACK_DELAY 25