diff --git a/src/quic_rx.c b/src/quic_rx.c index e6289dc83..8b629ce6b 100644 --- a/src/quic_rx.c +++ b/src/quic_rx.c @@ -321,7 +321,7 @@ static void qc_handle_newly_acked_frm(struct quic_conn *qc, struct quic_frame *f int ack; ack = qc_stream_desc_ack(&stream, offset, len, fin); - if (ack) { + if (ack && stream) { struct eb64_node *f; struct qf_stream *s = NULL; diff --git a/src/quic_stream.c b/src/quic_stream.c index 5c7df7633..fe67516e4 100644 --- a/src/quic_stream.c +++ b/src/quic_stream.c @@ -40,6 +40,31 @@ static void qc_stream_buf_free(struct qc_stream_desc *stream, } else { free_size = b_data(buf); + if (free_size) { + struct eb64_node *frm_node; + frm_node = eb64_first(&stream->acked_frms); + while (frm_node) { + /* TODO + * If qc_stream_buf_free() called from qc_stream_desc_ack(), + * all data removed so no need to call qcc_notify_buf(). + * If called via qc_stream_desc_release(), it may be non null, + * so qcc_notify_buf() must be called, excluding already + * buffered ACK. + */ + ABORT_NOW(); + //strm_frm = eb64_entry(frm_node, struct qf_stream, offset); + //if (strm_frm->offset.key >= offset && + // strm_frm->offset.key < offset + b_size(buf)) { + // BUG_ON(strm_frm->offset.key + strm_frm->len > offset + b_size(buf)); + // diff += strm_frm->len; + // fprintf(stderr, "%lu:%lu %llu:%llu %lu\n", + // offset, offset + b_size(buf), + // strm_frm->offset.key, strm_frm->offset.key + strm_frm->len, + // diff); + //} + //frm_node = eb64_next(frm_node); + } + } } if ((*stream_buf)->sbuf) { @@ -55,22 +80,6 @@ static void qc_stream_buf_free(struct qc_stream_desc *stream, /* notify MUX about available buffers. */ if (stream->ctx_conn && free_size) { struct qcc *qcc = stream->ctx_conn; - struct eb64_node *frm_node; - frm_node = eb64_first(&stream->acked_frms); - while (frm_node) { - ABORT_NOW(); - //strm_frm = eb64_entry(frm_node, struct qf_stream, offset); - //if (strm_frm->offset.key >= offset && - // strm_frm->offset.key < offset + b_size(buf)) { - // BUG_ON(strm_frm->offset.key + strm_frm->len > offset + b_size(buf)); - // diff += strm_frm->len; - // fprintf(stderr, "%lu:%lu %llu:%llu %lu\n", - // offset, offset + b_size(buf), - // strm_frm->offset.key, strm_frm->offset.key + strm_frm->len, - // diff); - //} - //frm_node = eb64_next(frm_node); - } /* notify MUX about available buffers. */ qcc_notify_buf(qcc, free_size); } @@ -157,22 +166,17 @@ void qc_stream_desc_release(struct qc_stream_desc *stream, struct qf_stream *strm_frm; size_t diff = b_room(buf); - frm_node = eb64_lookup_ge(&stream->acked_frms, stream->buf_offset); + frm_node = eb64_last(&stream->acked_frms); while (frm_node) { - //ABORT_NOW(); strm_frm = eb64_entry(frm_node, struct qf_stream, offset); - //if (strm_frm->offset.key >= offset && - // strm_frm->offset.key < offset + b_size(buf)) { - // BUG_ON(strm_frm->offset.key + strm_frm->len > offset + b_size(buf)); - // diff += strm_frm->len; - // fprintf(stderr, "%lu:%lu %llu:%llu %lu\n", - // offset, offset + b_size(buf), - // strm_frm->offset.key, strm_frm->offset.key + strm_frm->len, - // diff); - //} - //frm_node = eb64_next(frm_node); + if (strm_frm->offset.key < stream->buf_offset) { + if (strm_frm->offset.key + strm_frm->len > stream->buf_offset) + diff += strm_frm->offset.key + strm_frm->len - stream->buf_offset; + break; + } + diff += strm_frm->len; - frm_node = eb64_next(frm_node); + frm_node = eb64_prev(frm_node); } /* notify MUX about available buffers. */ qcc_notify_buf(qcc, diff); @@ -411,56 +415,40 @@ struct buffer *qc_stream_buf_realloc(struct qc_stream_desc *stream) */ void qc_stream_buf_release(struct qc_stream_desc *stream) { - struct buffer *buf; struct eb64_node *frm_node; struct qf_stream *strm_frm; - uint64_t offset = stream->buf_offset; uint64_t diff; /* current buffer already released */ BUG_ON(!stream->buf); - buf = &stream->buf->buf; - stream->buf = NULL; - stream->buf_offset = 0; - if (stream->ctx_conn) { - diff = b_room(buf); + diff = b_room(&stream->buf->buf); //fprintf(stderr, "qc_release_buf %lu\n", diff); - frm_node = eb64_first(&stream->acked_frms); + frm_node = eb64_last(&stream->acked_frms); while (frm_node) { strm_frm = eb64_entry(frm_node, struct qf_stream, offset); - //if (strm_frm->offset.key >= offset && - // strm_frm->offset.key < offset + b_size(buf)) { - //BUG_ON(strm_frm->offset.key < offset && - // strm_frm->offset.key + strm_frm->len > offset); - if (strm_frm->offset.key < offset && - strm_frm->offset.key + strm_frm->len > offset) { - diff += strm_frm->offset.key + strm_frm->len - offset; - //fprintf(stderr, "%lu:%lu %llu:%llu %lu\n", - // offset, offset + b_size(buf), - // strm_frm->offset.key, strm_frm->offset.key + strm_frm->len, - // diff); - } - else if (strm_frm->offset.key >= offset) { - BUG_ON(strm_frm->offset.key + strm_frm->len > offset + b_size(buf)); - diff += strm_frm->len; - //fprintf(stderr, "%lu:%lu %llu:%llu %lu\n", - // offset, offset + b_size(buf), - // strm_frm->offset.key, strm_frm->offset.key + strm_frm->len, - // diff); + if (strm_frm->offset.key < stream->buf_offset) { + if (strm_frm->offset.key + strm_frm->len > stream->buf_offset) + diff += strm_frm->offset.key + strm_frm->len - stream->buf_offset; + break; } - frm_node = eb64_next(frm_node); + + diff += strm_frm->len; + frm_node = eb64_prev(frm_node); } - BUG_ON(diff > b_room(buf) + b_data(buf)); + BUG_ON(diff > b_room(&stream->buf->buf) + b_data(&stream->buf->buf)); if (diff) { struct qcc *qcc = stream->ctx_conn; /* notify MUX about available buffers. */ qcc_notify_buf(qcc, diff); } } + + stream->buf = NULL; + stream->buf_offset = 0; } static int create_sbuf_pool(void)