diff --git a/src/liblsquic/lsquic_full_conn_ietf.c b/src/liblsquic/lsquic_full_conn_ietf.c index bc8e48d9..26e6f737 100644 --- a/src/liblsquic/lsquic_full_conn_ietf.c +++ b/src/liblsquic/lsquic_full_conn_ietf.c @@ -2428,46 +2428,6 @@ generate_max_stream_data_frame (struct ietf_full_conn *conn, } -/* Return true if generated, false otherwise */ -static int -generate_stream_blocked_frame (struct ietf_full_conn *conn, - struct lsquic_stream *stream) -{ - struct lsquic_packet_out *packet_out; - unsigned need; - uint64_t off; - int sz; - - off = lsquic_stream_combined_send_off(stream); - need = conn->ifc_conn.cn_pf->pf_stream_blocked_frame_size(stream->id, off); - packet_out = get_writeable_packet(conn, need); - if (!packet_out) - return 0; - sz = conn->ifc_conn.cn_pf->pf_gen_stream_blocked_frame( - packet_out->po_data + packet_out->po_data_sz, - lsquic_packet_out_avail(packet_out), stream->id, off); - if (sz < 0) - { - ABORT_ERROR("Generating STREAM_BLOCKED frame failed"); - return 0; - } - LSQ_DEBUG("generated %d-byte STREAM_BLOCKED " - "frame; stream_id: %"PRIu64"; offset: %"PRIu64, sz, stream->id, off); - EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "generated %d-byte STREAM_BLOCKED " - "frame; stream_id: %"PRIu64"; offset: %"PRIu64, sz, stream->id, off); - if (0 != lsquic_packet_out_add_frame(packet_out, conn->ifc_pub.mm, 0, - QUIC_FRAME_STREAM_BLOCKED, packet_out->po_data_sz, sz)) - { - ABORT_ERROR("adding frame to packet failed: %d", errno); - return 0; - } - lsquic_send_ctl_incr_pack_sz(&conn->ifc_send_ctl, packet_out, sz); - packet_out->po_frame_types |= 1 << QUIC_FRAME_STREAM_BLOCKED; - lsquic_stream_blocked_frame_sent(stream); - return 1; -} - - static int generate_stop_sending_frame_by_id (struct ietf_full_conn *conn, lsquic_stream_id_t stream_id, enum http_error_code error_code) @@ -2855,7 +2815,7 @@ process_stream_ready_to_send (struct ietf_full_conn *conn, if (stream->sm_qflags & SMQF_SEND_MAX_STREAM_DATA) r &= generate_max_stream_data_frame(conn, stream); if (stream->sm_qflags & SMQF_SEND_BLOCKED) - r &= generate_stream_blocked_frame(conn, stream); + r &= lsquic_sendctl_gen_stream_blocked_frame(&conn->ifc_send_ctl, stream); if (stream->sm_qflags & SMQF_SEND_RST) r &= generate_rst_stream_frame(conn, stream); if (stream->sm_qflags & SMQF_SEND_STOP_SENDING) diff --git a/src/liblsquic/lsquic_send_ctl.c b/src/liblsquic/lsquic_send_ctl.c index 224c001c..160f3766 100644 --- a/src/liblsquic/lsquic_send_ctl.c +++ b/src/liblsquic/lsquic_send_ctl.c @@ -2897,6 +2897,42 @@ lsquic_send_ctl_get_packet_for_stream (lsquic_send_ctl_t *ctl, } +/* Return true if generated, false otherwise */ +int +lsquic_sendctl_gen_stream_blocked_frame (struct lsquic_send_ctl *ctl, + struct lsquic_stream *stream) +{ + struct lsquic_packet_out *packet_out; + const struct parse_funcs *const pf = stream->conn_pub->lconn->cn_pf; + unsigned need; + uint64_t off; + int sz; + + off = lsquic_stream_combined_send_off(stream); + need = pf->pf_stream_blocked_frame_size(stream->id, off); + packet_out = lsquic_send_ctl_get_packet_for_stream(ctl, need, + stream->conn_pub->path, stream); + if (!packet_out) + return 0; + sz = pf->pf_gen_stream_blocked_frame( + packet_out->po_data + packet_out->po_data_sz, + lsquic_packet_out_avail(packet_out), stream->id, off); + if (sz < 0) + return 0; + LSQ_DEBUG("generated %d-byte STREAM_BLOCKED " + "frame; stream_id: %"PRIu64"; offset: %"PRIu64, sz, stream->id, off); + EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "generated %d-byte STREAM_BLOCKED " + "frame; stream_id: %"PRIu64"; offset: %"PRIu64, sz, stream->id, off); + if (0 != lsquic_packet_out_add_frame(packet_out, &ctl->sc_enpub->enp_mm, 0, + QUIC_FRAME_STREAM_BLOCKED, packet_out->po_data_sz, sz)) + return 0; + lsquic_send_ctl_incr_pack_sz(ctl, packet_out, sz); + packet_out->po_frame_types |= 1 << QUIC_FRAME_STREAM_BLOCKED; + lsquic_stream_blocked_frame_sent(stream); + return 1; +} + + #ifdef NDEBUG static #elif __GNUC__ diff --git a/src/liblsquic/lsquic_send_ctl.h b/src/liblsquic/lsquic_send_ctl.h index 01156371..22414d40 100644 --- a/src/liblsquic/lsquic_send_ctl.h +++ b/src/liblsquic/lsquic_send_ctl.h @@ -236,6 +236,10 @@ lsquic_send_ctl_get_packet_for_stream (lsquic_send_ctl_t *, unsigned need_at_least, const struct network_path *, const struct lsquic_stream *); +int +lsquic_sendctl_gen_stream_blocked_frame (struct lsquic_send_ctl *ctl, + struct lsquic_stream *stream); + struct lsquic_packet_out * lsquic_send_ctl_get_packet_for_crypto (struct lsquic_send_ctl *ctl, unsigned need_at_least, enum packnum_space, const struct network_path *); diff --git a/src/liblsquic/lsquic_stream.c b/src/liblsquic/lsquic_stream.c index 9788246c..2e826357 100644 --- a/src/liblsquic/lsquic_stream.c +++ b/src/liblsquic/lsquic_stream.c @@ -3695,10 +3695,15 @@ stream_write (lsquic_stream_t *stream, struct lsquic_reader *reader, } while (nwritten < len && stream->sm_n_buffered < stream->sm_n_allocated); - return nwritten; } else - return stream_write_to_packets(stream, reader, thresh, swo); + nwritten = stream_write_to_packets(stream, reader, thresh, swo); + if ((stream->sm_qflags & SMQF_SEND_BLOCKED) && + (stream->sm_bflags & SMBF_IETF)) + { + lsquic_sendctl_gen_stream_blocked_frame(stream->conn_pub->send_ctl, stream); + } + return nwritten; }