size_t qcs_http_snd_buf(struct qcs *qcs, struct buffer *buf, size_t count,
char *fin);
+size_t qcs_http_reset_buf(struct qcs *qcs, struct buffer *buf, size_t count);
#endif /* USE_QUIC */
TRACE_ENTER(QMUX_EV_STRM_SEND, qcs->qcc->conn, qcs);
- /* Sending forbidden if QCS is locally closed (FIN or RESET_STREAM sent). */
- BUG_ON(qcs_is_close_local(qcs) || (qcs->flags & QC_SF_TO_RESET));
-
/* stream layer has been detached so no transfer must occur after. */
BUG_ON_HOT(qcs->flags & QC_SF_DETACH);
goto end;
}
+ /* Cannot emit data after FIN/RESET_STREAM, drain extra payload. */
+ if (qcs_is_close_local(qcs) || (qcs->flags & QC_SF_TO_RESET)) {
+ ret = qcs_http_reset_buf(qcs, buf, count);
+ goto end;
+ }
+
if (LIST_INLIST(&qcs->el_buf)) {
TRACE_DEVEL("leaving on no buf avail", QMUX_EV_STRM_SEND, qcs->qcc->conn, qcs);
goto end;
TRACE_ENTER(QMUX_EV_STRM_SEND, qcs->qcc->conn, qcs);
- /* Sending forbidden if QCS is locally closed (FIN or RESET_STREAM sent). */
- BUG_ON(qcs_is_close_local(qcs) || (qcs->flags & QC_SF_TO_RESET));
-
/* stream layer has been detached so no transfer must occur after. */
BUG_ON_HOT(qcs->flags & QC_SF_DETACH);
return ret;
}
+
+/* QUIC MUX snd_buf reset. HTX data stored in <buf> of length <count> will be
+ * cleared. This can be used when data should not be transmitted any longer.
+ *
+ * Return the size in bytes of cleared data.
+ */
+size_t qcs_http_reset_buf(struct qcs *qcs, struct buffer *buf, size_t count)
+{
+ struct htx *htx;
+
+ TRACE_ENTER(QMUX_EV_STRM_SEND, qcs->qcc->conn, qcs);
+
+ htx = htx_from_buf(buf);
+ htx_reset(htx);
+ htx_to_buf(htx, buf);
+
+ TRACE_LEAVE(QMUX_EV_STRM_SEND, qcs->qcc->conn, qcs);
+
+ return count;
+}