if (htx)
htx_to_buf(htx, &htx_buf);
- /* buffer is transferred to the stream connector and set to NULL
- * except on stream creation error.
+ /* Buffer is transferred to the stream connector and set to NULL except
+ * on stream creation error or QCS already fully closed.
*/
if (b_size(&htx_buf)) {
b_free(&htx_buf);
* the first received request data. <fin> must be set if the whole request is
* already received.
*
- * Returns 0 on success else a negative error code.
+ * Note that if <qcs> is already fully closed, no streamdesc is instantiated.
+ * This is useful if a RESET_STREAM was already emitted in response to a
+ * STOP_SENDING.
+ *
+ * Returns 0 on success else a negative error code. If stream is already fully
+ * closed and nothing is performed, it is considered as a success case.
*/
int qcs_attach_sc(struct qcs *qcs, struct buffer *buf, char fin)
{
TRACE_ENTER(QMUX_EV_STRM_RECV, qcc->conn, qcs);
+ if (qcs->st == QC_SS_CLO) {
+ TRACE_STATE("skip attach on already closed stream", QMUX_EV_STRM_RECV, qcc->conn, qcs);
+ goto out;
+ }
+
/* TODO duplicated from mux_h2 */
sess->t_idle = ns_to_ms(now_ns - sess->accept_ts) - sess->t_handshake;
se_fl_set_error(qcs->sd);
}
+ out:
TRACE_LEAVE(QMUX_EV_STRM_RECV, qcc->conn, qcs);
return 0;
}
if (qcs_is_close_remote(qcs))
fin = 1;
- if (!(qcs->flags & QC_SF_READ_ABORTED) && !qcs_is_completed(qcs)) {
+ if (!(qcs->flags & QC_SF_READ_ABORTED)) {
ret = qcc->app_ops->rcv_buf(qcs, &b, fin);
if (qcc->glitches != prev_glitches)