]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: handle CONNECTION_CLOSE frame
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 13 Oct 2021 14:34:49 +0000 (16:34 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 13 Oct 2021 14:38:56 +0000 (16:38 +0200)
On receiving CONNECTION_CLOSE frame, the mux is flagged for immediate
connection close. A stream is closed even if there is data not ACKed
left if CONNECTION_CLOSE has been received.

include/haproxy/mux_quic-t.h
src/mux_quic.c
src/xprt_quic.c

index 7cf9afdb358b457c1a0fcc4002192d39aab547f4..09e0585f67d764e44302d4842feafa8b06984685 100644 (file)
@@ -77,6 +77,8 @@
 /* other flags */
 #define QC_CF_IS_BACK           0x00008000  // this is an outgoing connection
 
+#define QC_CF_CC_RECV           0x00010000  // CONNECTION_CLOSE received
+
 extern struct pool_head *pool_head_qcs;
 
 /* Stream types */
index 4794a5066e9950f03358523450feabef610d17d5..d60df2b6c075c360d19321dd0c95758c7e30d964 100644 (file)
@@ -1498,14 +1498,18 @@ static void qc_detach(struct conn_stream *cs)
        struct qcc *qcc = qcs->qcc;
 
        TRACE_ENTER(QC_EV_STRM_END, qcs ? qcs->qcc->conn : NULL, qcs);
-       if (b_data(&qcs->tx.buf) || b_data(&qcs->tx.xprt_buf)) {
+       if (b_data(&qcs->tx.buf) ||
+           (b_data(&qcs->tx.xprt_buf) && !(qcc->flags & QC_CF_CC_RECV))) {
                qcs->flags |= QC_SF_DETACH;
                goto out;
        }
 
        qcs_destroy(qcs);
-       if (qcc_is_dead(qcc))
+       if (qcc_is_dead(qcc)) {
                qc_release(qcc);
+               TRACE_LEAVE(QC_EV_STRM_END, NULL);
+               return;
+       }
 
  out:
        TRACE_LEAVE(QC_EV_STRM_END, qcs ? qcs->qcc->conn : NULL);
index 70bcea8d9424c54766fe2990f46fd5c0bc757469..eed8b2fe6e0dcfbd55e4328a8c97cee0d0321d0e 100644 (file)
@@ -2040,6 +2040,7 @@ static int qc_parse_pkt_frms(struct quic_rx_packet *pkt, struct ssl_sock_ctx *ct
                        break;
                case QUIC_FT_CONNECTION_CLOSE:
                case QUIC_FT_CONNECTION_CLOSE_APP:
+                       conn->qcc->flags |= QC_CF_CC_RECV;
                        break;
                case QUIC_FT_HANDSHAKE_DONE:
                        if (objt_listener(ctx->conn->target))