summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorVladimir Homutov <vl@nginx.com>2020-05-22 18:14:35 +0300
committerVladimir Homutov <vl@nginx.com>2020-05-22 18:14:35 +0300
commit57696b56e91de2d60675df35587fe7aa4a756529 (patch)
tree7229818b129cf0c35898886a58574b5cab6cf901 /src
parent76605fa07a0b9579e00952528eb7dc455fa98d01 (diff)
downloadnginx-57696b56e91de2d60675df35587fe7aa4a756529.tar.gz
nginx-57696b56e91de2d60675df35587fe7aa4a756529.tar.bz2
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.
Diffstat (limited to 'src')
-rw-r--r--src/event/ngx_event_quic.c63
1 files changed, 36 insertions, 27 deletions
diff --git a/src/event/ngx_event_quic.c b/src/event/ngx_event_quic.c
index 32c9faff3..e2ccf5e43 100644
--- a/src/event/ngx_event_quic.c
+++ b/src/event/ngx_event_quic.c
@@ -1189,24 +1189,32 @@ ngx_quic_close_quic(ngx_connection_t *c, ngx_int_t rc)
ngx_quic_free_frames(c, &ctx->sent);
}
- level = (qc->state == ssl_encryption_early_data)
- ? ssl_encryption_application
- : qc->state;
+ if (rc == NGX_DONE) {
- if (rc == NGX_OK) {
+ /*
+ * 10.2. Idle Timeout
+ *
+ * If the idle timeout is enabled by either peer, a connection is
+ * silently closed and its state is discarded when it remains idle
+ */
+
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "quic closing %s connection",
+ qc->draining ? "drained" : "idle");
+
+ } else {
/*
* 10.3. Immediate Close
*
- * An endpoint sends a CONNECTION_CLOSE frame (Section 19.19) to
- * terminate the connection immediately.
+ * 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)
- {
+ 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;
@@ -1214,29 +1222,30 @@ ngx_quic_close_quic(ngx_connection_t *c, ngx_int_t rc)
qc->close.cancelable = 1;
ngx_add_timer(&qc->close, 3 * NGX_QUIC_HARDCODED_PTO);
- }
- } else if (rc == NGX_DONE) {
+ err = NGX_QUIC_ERR_NO_ERROR;
- /*
- * 10.2. Idle Timeout
- *
- * If the idle timeout is enabled by either peer, a connection is
- * silently closed and its state is discarded when it remains idle
- */
+ } else {
+ err = qc->error ? qc->error : NGX_QUIC_ERR_INTERNAL_ERROR;
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "quic closing %s connection",
- qc->draining ? "drained" : "idle");
+ 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 : "");
+ }
- } else {
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "quic immediate close due to fatal error: %ui",
- qc->error);
+ level = (qc->state == ssl_encryption_early_data)
+ ? ssl_encryption_handshake
+ : qc->state;
- err = qc->error ? qc->error : NGX_QUIC_ERR_INTERNAL_ERROR;
(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;