Mercurial > hg > nginx
changeset 8400:d96ddef458cd quic
Added sending of extra CONNECTION_CLOSE frames.
According to quic-transport draft 28 section 10.3.1:
When sending CONNECTION_CLOSE, the goal is to ensure that the peer
will process the frame. Generally, this means sending the frame in a
packet with the highest level of packet protection to avoid the
packet being discarded. After the handshake is confirmed (see
Section 4.1.2 of [QUIC-TLS]), an endpoint MUST send any
CONNECTION_CLOSE frames in a 1-RTT packet. However, prior to
confirming the handshake, it is possible that more advanced packet
protection keys are not available to the peer, so another
CONNECTION_CLOSE frame MAY be sent in a packet that uses a lower
packet protection level.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Fri, 22 May 2020 18:14:35 +0300 |
parents | ffd362e87eb2 |
children | d3aa54242c37 |
files | src/event/ngx_event_quic.c |
diffstat | 1 files changed, 42 insertions(+), 33 deletions(-) [+] |
line wrap: on
line diff
--- a/src/event/ngx_event_quic.c Fri May 22 18:08:02 2020 +0300 +++ b/src/event/ngx_event_quic.c Fri May 22 18:14:35 2020 +0300 @@ -1189,34 +1189,7 @@ ngx_quic_free_frames(c, &ctx->sent); } - level = (qc->state == ssl_encryption_early_data) - ? ssl_encryption_application - : qc->state; - - if (rc == NGX_OK) { - - /* - * 10.3. Immediate Close - * - * An endpoint sends a CONNECTION_CLOSE frame (Section 19.19) to - * terminate the connection immediately. - */ - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, - "quic immediate close, drain = %d", qc->draining); - - if (ngx_quic_send_cc(c, level, NGX_QUIC_ERR_NO_ERROR, 0, NULL) - == NGX_OK) - { - - qc->close.log = c->log; - qc->close.data = c; - qc->close.handler = ngx_quic_close_timer_handler; - qc->close.cancelable = 1; - - ngx_add_timer(&qc->close, 3 * NGX_QUIC_HARDCODED_PTO); - } - - } else if (rc == NGX_DONE) { + if (rc == NGX_DONE) { /* * 10.2. Idle Timeout @@ -1230,13 +1203,49 @@ qc->draining ? "drained" : "idle"); } else { - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, - "quic immediate close due to fatal error: %ui", - qc->error); - - err = qc->error ? qc->error : NGX_QUIC_ERR_INTERNAL_ERROR; + + /* + * 10.3. Immediate Close + * + * An endpoint sends a CONNECTION_CLOSE frame (Section 19.19) + * to terminate the connection immediately. + */ + + if (rc == NGX_OK) { + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, + "quic immediate close, drain = %d", + qc->draining); + + qc->close.log = c->log; + qc->close.data = c; + qc->close.handler = ngx_quic_close_timer_handler; + qc->close.cancelable = 1; + + ngx_add_timer(&qc->close, 3 * NGX_QUIC_HARDCODED_PTO); + + err = NGX_QUIC_ERR_NO_ERROR; + + } else { + err = qc->error ? qc->error : NGX_QUIC_ERR_INTERNAL_ERROR; + + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, + "quic immediate close due to error: %ui %s", + qc->error, + qc->error_reason ? qc->error_reason : ""); + } + + level = (qc->state == ssl_encryption_early_data) + ? ssl_encryption_handshake + : qc->state; + (void) ngx_quic_send_cc(c, level, err, qc->error_ftype, qc->error_reason); + + if (level == ssl_encryption_handshake) { + /* for clients that might not have handshake keys */ + (void) ngx_quic_send_cc(c, ssl_encryption_initial, err, + qc->error_ftype, qc->error_reason); + } } qc->closing = 1;