A received H3 DATA frame may wrap in the buffer. Function
h3_data_to_htx() will parse it in two pass in this case, calling
htx_add_data() twice.
A double bug was present in case of such parsing as second call of
htx_add_data() return value was immediately added in <htx_sent>. This
could cause first check to activate QC_SF_DEM_FULL to be ignored. This
is a minor issue, as MUX would immediately reinvoke h3_rcv_buf(), with
the flag set this time.
The second bug is more important : comparison for HTX EOM reporting was
invalid in case of a two pass parsing. Most of the time, this result in
EOM not reported, causing the stream layer to report a stream
interruption with state CL--.
Fix this by using an intermediary return value for the second
htx_add_data() invokation. This value is only added to <htx_sent> once
necessary checks are performed. It is important to keep h3_data_to_htx()
to still return the total value of HTX added data to avoid parser desync
issue.
This must be backported up to 2.6, after a period of observation.
{
struct buffer *appbuf = NULL;
struct htx *htx = NULL;
- size_t htx_sent = 0;
+ size_t htx_sent = 0, ret;
int htx_space;
char *head;
goto retry;
}
- htx_sent += htx_add_data(htx, ist2(head, len));
- if (htx_sent < len) {
+ ret = htx_add_data(htx, ist2(head, len));
+ if (ret < len) {
qcs->flags |= QC_SF_DEM_FULL;
goto out;
}
- if (fin && len == htx_sent)
+ if (fin && len == ret)
htx_set_eom(htx);
+ htx_sent += ret;
out:
if (appbuf)