#define QUIC_FL_CONN_LISTENER (1U << 3)
#define QUIC_FL_CONN_ACCEPT_REGISTERED (1U << 4)
#define QUIC_FL_CONN_IDLE_TIMER_RESTARTED_AFTER_READ (1U << 6)
+#define QUIC_FL_CONN_NOTIFY_CLOSE (1U << 27) /* MUX notified about quic-conn imminent closure (idle-timeout or CONNECTION_CLOSE emission/reception) */
#define QUIC_FL_CONN_EXP_TIMER (1U << 28) /* timer has expired, quic-conn can be freed */
#define QUIC_FL_CONN_CLOSING (1U << 29)
#define QUIC_FL_CONN_DRAINING (1U << 30)
struct qc_stream_desc *qc_stream_desc_new(uint64_t id, void *ctx);
void qc_stream_desc_release(struct qc_stream_desc *stream, struct quic_conn *qc);
+void qc_notify_close(struct quic_conn *qc);
+
#endif /* USE_QUIC */
#endif /* _HAPROXY_XPRT_QUIC_H */
if (unlikely(prx->flags & (PR_FL_DISABLED|PR_FL_STOPPED)))
goto release;
+ if (conn->qc->flags & QUIC_FL_CONN_NOTIFY_CLOSE)
+ qcc->conn->flags |= (CO_FL_SOCK_RD_SH|CO_FL_SOCK_WR_SH);
+
qc_send(qcc);
qc_wake_some_streams(qcc);
*/
qc_idle_timer_do_rearm(qc);
qc->flags |= QUIC_FL_CONN_DRAINING|QUIC_FL_CONN_IMMEDIATE_CLOSE;
+ qc_notify_close(qc);
}
break;
case QUIC_FT_HANDSHAKE_DONE:
if (!(qc->flags & QUIC_FL_CONN_CLOSING) &&
(pkt->flags & QUIC_FL_TX_PACKET_CC)) {
qc->flags |= QUIC_FL_CONN_CLOSING;
+ qc_notify_close(qc);
+
/* RFC 9000 10.2. Immediate Close:
* The closing and draining connection states exist to ensure
* that connections close cleanly and that delayed or reordered
{
struct quic_conn *qc = ctx;
+ /* Notify the MUX before settings QUIC_FL_CONN_EXP_TIMER or the MUX
+ * might free the quic-conn too early via quic_close().
+ */
+ qc_notify_close(qc);
+
/* If the MUX is still alive, keep the quic-conn. The MUX is
* responsible to call quic_close to release it.
*/
eb64_insert(&qc->streams_by_id, &stream->by_id);
}
+/* Notify the MUX layer if alive about an imminent close of <qc>. */
+void qc_notify_close(struct quic_conn *qc)
+{
+ if (qc->flags & QUIC_FL_CONN_NOTIFY_CLOSE)
+ return;
+
+ qc->flags |= QUIC_FL_CONN_NOTIFY_CLOSE;
+
+ /* wake up the MUX */
+ if (qc->mux_state == QC_MUX_READY && qc->conn->mux->wake)
+ qc->conn->mux->wake(qc->conn);
+}
+
/* Function to automatically activate QUIC traces on stdout.
* Activated via the compilation flag -DENABLE_QUIC_STDOUT_TRACES.
* Main use for now is in the docker image for QUIC interop testing.