BUG/MEDIUM: quic: do not split STREAM frames if no space
When building STREAM frames in a packet buffer, if a frame is too large it will be splitted in two. A shorten version will be used and the original frame will be modified to represent the remaining space. To ensure there is enough space to store the frame data length encoded as a QUIC integer, we use the function max_available_room(). This function can return 0 if there not only a small space left which is insufficient for the frame header and the shorten data. Prior to this patch, this wasn't check and an empty unneeded STREAM frame was built and sent for nothing. Change this by checking the value return by max_available_room(). If 0, do not try to split this frame and continue to the next ones in the packet. On 2.6, this patch serves as an optimization which will prevent the building of unneeded empty STREAM frames. On 2.7, this behavior has the side-effect of triggering a BUG_ON() statement on quic_build_stream_frame(). This BUG_ON() ensures that we do not use quic_frame with OFF bit set if its offset is 0. This can happens if the condition defined above is reproduced for a STREAM frame at offset 0. An empty unneeded frame is built as descibed. The problem is that the original frame is modified with its OFF bit set even if the offset is still 0. This must be backported up to 2.6.
This commit is contained in:
parent
50440457e3
commit
f2f08f88ef
|
@ -6819,11 +6819,13 @@ static inline int qc_build_frms(struct list *outlist, struct list *inlist,
|
|||
|
||||
TRACE_DEVEL(" New STREAM frame build (room, len)",
|
||||
QUIC_EV_CONN_BCFRMS, qc, &room, len);
|
||||
|
||||
/* hlen contains STREAM id and offset. Ensure there is
|
||||
* enough room for length field.
|
||||
*/
|
||||
if (cf->type & QUIC_STREAM_FRAME_TYPE_LEN_BIT) {
|
||||
dlen = max_available_room(avail_room, &dlen_sz);
|
||||
if (dlen > cf->stream.len) {
|
||||
dlen = cf->stream.len;
|
||||
}
|
||||
dlen = QUIC_MIN((uint64_t)max_available_room(avail_room, &dlen_sz),
|
||||
cf->stream.len);
|
||||
dlen_sz = quic_int_getsize(dlen);
|
||||
flen = hlen + dlen_sz + dlen;
|
||||
}
|
||||
|
@ -6831,6 +6833,14 @@ static inline int qc_build_frms(struct list *outlist, struct list *inlist,
|
|||
dlen = QUIC_MIN((uint64_t)avail_room, cf->stream.len);
|
||||
flen = hlen + dlen;
|
||||
}
|
||||
|
||||
if (cf->stream.len && !dlen) {
|
||||
/* Only a small gap is left on buffer, not
|
||||
* enough to encode the STREAM data length.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
TRACE_DEVEL(" STREAM data length (hlen, stream.len, dlen)",
|
||||
QUIC_EV_CONN_BCFRMS, qc, &hlen, &cf->stream.len, &dlen);
|
||||
TRACE_DEVEL(" STREAM frame length (flen)",
|
||||
|
|
Loading…
Reference in New Issue