b = qcs_b_dup(&qcs->rx.ncbuf);
- /* Signal FIN to application if STREAM FIN received and there is no gap
- * in the Rx buffer.
- */
- if (qcs->flags & QC_SF_SIZE_KNOWN && !ncb_is_fragmented(&qcs->rx.ncbuf))
+ /* Signal FIN to application if STREAM FIN received with all data. */
+ if (qcs_is_close_remote(qcs))
fin = 1;
ret = qcc->app_ops->decode_qcs(qcs, &b, fin);
}
if (offset + len <= qcs->rx.offset) {
+ /* TODO offset may have been received without FIN first and now
+ * with it. In this case, it must be notified to be able to
+ * close the stream.
+ */
TRACE_DATA("already received offset", QMUX_EV_QCC_RECV|QMUX_EV_QCS_RECV, qcc->conn, qcs);
goto out;
}
if (fin)
qcs->flags |= QC_SF_SIZE_KNOWN;
- if (qcs->flags & QC_SF_SIZE_KNOWN && !ncb_is_fragmented(&qcs->rx.ncbuf))
+ if (qcs->flags & QC_SF_SIZE_KNOWN &&
+ qcs->rx.offset_max == qcs->rx.offset + ncb_data(&qcs->rx.ncbuf, 0)) {
qcs_close_remote(qcs);
+ }
if (ncb_data(&qcs->rx.ncbuf, 0) && !(qcs->flags & QC_SF_DEM_FULL)) {
qcc_decode_qcs(qcc, qcs);