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 7cf9afd..09e0585 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 4794a50..d60df2b 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 70bcea8..eed8b2f 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))