# HG changeset patch # User Roman Arutyunyan # Date 1584978437 -10800 # Node ID d45325e9022150e7740172c7b673467e2e6bdf85 # Parent c58bbe31e87dc2ac5f5784c974266c4e1f10ad60 Limit output QUIC packets with client max_packet_size. Additionally, receive larger packets than 512 bytes. diff --git a/src/event/ngx_event_quic.c b/src/event/ngx_event_quic.c --- a/src/event/ngx_event_quic.c +++ b/src/event/ngx_event_quic.c @@ -41,6 +41,7 @@ struct ngx_quic_connection_s { ngx_uint_t client_tp_done; ngx_quic_tp_t tp; + ngx_quic_tp_t ctp; ngx_quic_state_t state; @@ -219,7 +220,6 @@ ngx_quic_add_handshake_data(ngx_ssl_conn u_char *p, *end; size_t client_params_len; const uint8_t *client_params; - ngx_quic_tp_t ctp; ngx_quic_frame_t *frame; ngx_connection_t *c; ngx_quic_connection_t *qc; @@ -244,15 +244,12 @@ ngx_quic_add_handshake_data(ngx_ssl_conn p = (u_char *) client_params; end = p + client_params_len; - ngx_memzero(&ctp, sizeof(ngx_quic_tp_t)); - - if (ngx_quic_parse_transport_params(p, end, &ctp, c->log) != NGX_OK) + if (ngx_quic_parse_transport_params(p, end, &qc->ctp, c->log) + != NGX_OK) { return NGX_ERROR; } - /* TODO: save/use obtained client parameters: merge with ours? */ - qc->client_tp_done = 1; } } @@ -371,6 +368,7 @@ static ngx_int_t ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_quic_tp_t *tp, ngx_quic_header_t *pkt) { + ngx_quic_tp_t *ctp; ngx_quic_connection_t *qc; if (ngx_buf_size(pkt->raw) < 1200) { @@ -406,6 +404,11 @@ ngx_quic_new_connection(ngx_connection_t qc->ssl = ssl; qc->tp = *tp; + ctp = &qc->ctp; + ctp->max_packet_size = NGX_QUIC_DEFAULT_MAX_PACKET_SIZE; + ctp->ack_delay_exponent = NGX_QUIC_DEFAULT_ACK_DELAY_EXPONENT; + ctp->max_ack_delay = NGX_QUIC_DEFAULT_MAX_ACK_DELAY; + qc->dcid.len = pkt->dcid.len; qc->dcid.data = ngx_pnalloc(c->pool, pkt->dcid.len); if (qc->dcid.data == NULL) { @@ -520,10 +523,10 @@ ngx_quic_input_handler(ngx_event_t *rev) ngx_buf_t b; ngx_connection_t *c; - u_char buf[512]; + static u_char buf[65535]; b.start = buf; - b.end = buf + 512; + b.end = buf + sizeof(buf); b.pos = b.last = b.start; c = rev->data; @@ -1092,7 +1095,7 @@ ngx_quic_queue_frame(ngx_quic_connection static ngx_int_t ngx_quic_output(ngx_connection_t *c) { - size_t len; + size_t len, hlen, n; ngx_uint_t lvl; ngx_quic_frame_t *f, *start; ngx_quic_connection_t *qc; @@ -1110,10 +1113,19 @@ ngx_quic_output(ngx_connection_t *c) do { len = 0; + hlen = (lvl == ssl_encryption_application) ? NGX_QUIC_MAX_SHORT_HEADER + : NGX_QUIC_MAX_LONG_HEADER; + do { /* process same-level group of frames */ - len += ngx_quic_create_frame(NULL, NULL, f);// TODO: handle overflow, max size + n = ngx_quic_create_frame(NULL, NULL, f); + + if (len && hlen + len + n > qc->ctp.max_packet_size) { + break; + } + + len += n; f = f->next; } while (f && f->level == lvl); diff --git a/src/event/ngx_event_quic.h b/src/event/ngx_event_quic.h --- a/src/event/ngx_event_quic.h +++ b/src/event/ngx_event_quic.h @@ -14,6 +14,13 @@ #define quic_version 0xff000018 /* draft-24 (ngtcp2) */ //#define quic_version 0xff00001b /* draft-27 (FFN 76) */ +#define NGX_QUIC_MAX_SHORT_HEADER 25 +#define NGX_QUIC_MAX_LONG_HEADER 346 + +#define NGX_QUIC_DEFAULT_MAX_PACKET_SIZE 65527 +#define NGX_QUIC_DEFAULT_ACK_DELAY_EXPONENT 3 +#define NGX_QUIC_DEFAULT_MAX_ACK_DELAY 25 + typedef struct { /* configurable */ diff --git a/src/event/ngx_event_quic_protection.c b/src/event/ngx_event_quic_protection.c --- a/src/event/ngx_event_quic_protection.c +++ b/src/event/ngx_event_quic_protection.c @@ -697,7 +697,7 @@ ngx_quic_create_long_packet(ngx_pool_t * out.len = payload->len + EVP_GCM_TLS_TAG_LEN; - ad.data = ngx_alloc(346 /*max header*/, log); + ad.data = ngx_alloc(NGX_QUIC_MAX_LONG_HEADER, log); if (ad.data == 0) { return NGX_ERROR; } @@ -766,7 +766,7 @@ ngx_quic_create_short_packet(ngx_pool_t out.len = payload->len + EVP_GCM_TLS_TAG_LEN; - ad.data = ngx_alloc(25 /*max header*/, log); + ad.data = ngx_alloc(NGX_QUIC_MAX_SHORT_HEADER, log); if (ad.data == 0) { return NGX_ERROR; } diff --git a/src/http/v3/ngx_http_v3_module.c b/src/http/v3/ngx_http_v3_module.c --- a/src/http/v3/ngx_http_v3_module.c +++ b/src/http/v3/ngx_http_v3_module.c @@ -233,11 +233,13 @@ ngx_http_v3_merge_srv_conf(ngx_conf_t *c // > 2 ^ 14 is invalid ngx_conf_merge_msec_value(conf->quic.max_ack_delay, - prev->quic.max_ack_delay, 25); + prev->quic.max_ack_delay, + NGX_QUIC_DEFAULT_MAX_ACK_DELAY); // < 1200 is invalid ngx_conf_merge_uint_value(conf->quic.max_packet_size, - prev->quic.max_packet_size, 65527); + prev->quic.max_packet_size, + NGX_QUIC_DEFAULT_MAX_PACKET_SIZE); ngx_conf_merge_uint_value(conf->quic.initial_max_data, prev->quic.initial_max_data, 10000000); @@ -261,7 +263,8 @@ ngx_http_v3_merge_srv_conf(ngx_conf_t *c // > 20 is invalid ngx_conf_merge_uint_value(conf->quic.ack_delay_exponent, - prev->quic.ack_delay_exponent, 3); + prev->quic.ack_delay_exponent, + NGX_QUIC_DEFAULT_ACK_DELAY_EXPONENT); ngx_conf_merge_uint_value(conf->quic.disable_active_migration, prev->quic.disable_active_migration, 1);