struct buffer *qcc_get_stream_rxbuf(struct qcs *qcs);
struct buffer *qcc_get_stream_txbuf(struct qcs *qcs, int *err);
+int qcc_realign_stream_txbuf(const struct qcs *qcs, struct buffer *out);
int qcc_release_stream_txbuf(struct qcs *qcs);
int qcc_stream_can_send(const struct qcs *qcs);
void qcc_reset_stream(struct qcs *qcs, int err);
if (fsize > count)
fsize = count;
- /* TODO buffer can be realign only if no data waiting for ACK. */
- outbuf = b_make(b_tail(res), b_contig_space(res), 0, 0);
+ while (1) {
+ b_reset(&outbuf);
+ outbuf = b_make(b_tail(res), b_contig_space(res), 0, 0);
+ if (b_size(&outbuf) > hsize || !b_space_wraps(res))
+ break;
+ if (qcc_realign_stream_txbuf(qcs, res))
+ break;
+ }
/* Not enough room for headers and at least one data byte, try to
* release the current buffer and allocate a new one. If not possible,
/* h3 DATA headers : 1-byte frame type + varint frame length */
hsize = 1 + QUIC_VARINT_MAX_SIZE;
- /* TODO buffer can be realign only if no data waiting for ACK. */
+ while (1) {
+ if (b_contig_space(res) >= hsize || !b_space_wraps(res))
+ break;
+ if (qcc_realign_stream_txbuf(qcs, res))
+ break;
+ }
/* Not enough room for headers and at least one data byte, block the
* stream. It is expected that the stream connector layer will subscribe
return b_data(out) - diff;
}
+/* Try to realign <out> buffer for <qcs> stream. This is done only if there is
+ * no data waiting for ACK.
+ *
+ * Returns 0 if realign was performed else non-zero.
+ */
+int qcc_realign_stream_txbuf(const struct qcs *qcs, struct buffer *out)
+{
+ if (qcs_prep_bytes(qcs) == b_data(out)) {
+ b_slow_realign(out, trash.area, b_data(out));
+ return 0;
+ }
+
+ return 1;
+}
+
/* Release the current <qcs> Tx buffer. This is useful if space left is not
* enough anymore. A new instance can then be allocated to continue sending.
*