Release 2.8.8

- [BUGFIX] Invalid read when parsing IETF transport parameters
  (this was benign).
- [OPTIMIZATION] Frame bundling when using buffered packets in
  IETF QUIC: a) flush QPACK decoder stream and b) include ACKs
  in opportunistic fashion.
- Fix HTTP/3 framing unit test.
- Code cleanup.
This commit is contained in:
Dmitri Tikhonov 2020-01-14 14:26:11 -05:00
parent 7d09751dbb
commit a4f5dac3cf
13 changed files with 151 additions and 26 deletions

View file

@ -35,6 +35,11 @@
lsquic_stream_conn(fw->fw_stream))
#include "lsquic_logger.h"
/* Size of the buffer passed to lshpack_enc_encode() -- this limits the size
* of a single compressed header field.
*/
#define MAX_COMP_HEADER_FIELD_SIZE (64 * 1024)
struct lsquic_frame_writer
{
@ -457,10 +462,10 @@ lsquic_frame_writer_write_headers (struct lsquic_frame_writer *fw,
return s;
}
buf = malloc(MAX_HEADERS_SIZE);
buf = malloc(MAX_COMP_HEADER_FIELD_SIZE);
if (!buf)
return -1;
s = write_headers(fw, headers, &hfc, buf, MAX_HEADERS_SIZE);
s = write_headers(fw, headers, &hfc, buf, MAX_COMP_HEADER_FIELD_SIZE);
free(buf);
if (0 == s)
{
@ -529,11 +534,11 @@ lsquic_frame_writer_write_promise (struct lsquic_frame_writer *fw,
if (s < 0)
return s;
buf = malloc(MAX_HEADERS_SIZE);
buf = malloc(MAX_COMP_HEADER_FIELD_SIZE);
if (!buf)
return -1;
s = write_headers(fw, &mpas, &hfc, buf, MAX_HEADERS_SIZE);
s = write_headers(fw, &mpas, &hfc, buf, MAX_COMP_HEADER_FIELD_SIZE);
if (s != 0)
{
free(buf);
@ -541,7 +546,7 @@ lsquic_frame_writer_write_promise (struct lsquic_frame_writer *fw,
}
if (extra_headers)
s = write_headers(fw, extra_headers, &hfc, buf, MAX_HEADERS_SIZE);
s = write_headers(fw, extra_headers, &hfc, buf, MAX_COMP_HEADER_FIELD_SIZE);
free(buf);

View file

@ -9,9 +9,6 @@
#include <stddef.h>
#include <stdint.h>
/* Same as H2_TMP_HDR_BUFF_SIZE */
#define MAX_HEADERS_SIZE (64 * 1024)
struct iovec;
struct lshpack_enc;
struct lsquic_mm;

View file

@ -1338,7 +1338,13 @@ static int
ietf_full_conn_ci_can_write_ack (struct lsquic_conn *lconn)
{
struct ietf_full_conn *conn = (struct ietf_full_conn *) lconn;
return should_generate_ack(conn, IFC_ACK_QUED_APP);
/* Follow opportunistic ACK logic. Because this method is only used by
* buffered packets code path, no need to check whether anything is
* writing: we know it is.
*/
return conn->ifc_n_slack_akbl[PNS_APP] > 0
&& lsquic_send_ctl_can_send(&conn->ifc_send_ctl);
}

View file

@ -23,4 +23,9 @@
/* [draft-ietf-quic-transport-24] Section 8.1 */
#define IQUIC_MIN_INIT_PACKET_SZ 1200
/* Our stream code makes an assumption that packet size is smaller than the
* maximum HTTP/3 DATA frame size we can generate.
*/
#define IQUIC_MAX_OUT_PACKET_SZ ((1u << 14) - 1)
#endif

View file

@ -139,7 +139,7 @@ lsquic_qdh_init (struct qpack_dec_hdl *qdh, struct lsquic_conn *conn,
{
qdh->qdh_h1x_ctor_ctx = (struct http1x_ctor_ctx) {
.conn = conn,
.max_headers_sz = 0x10000, /* XXX */
.max_headers_sz = MAX_HTTP1X_HEADERS_SIZE,
.is_server = is_server,
};
qdh->qdh_hsi_ctx = &qdh->qdh_h1x_ctor_ctx;

View file

@ -45,6 +45,10 @@
#include "lsquic_hash.h"
#include "lsquic_malo.h"
#include "lsquic_attq.h"
#include "lsquic_http1x_if.h"
#include "lsqpack.h"
#include "lsquic_frab_list.h"
#include "lsquic_qdec_hdl.h"
#define LSQUIC_LOGGER_MODULE LSQLM_SENDCTL
#define LSQUIC_LOG_CONN_ID lsquic_conn_log_cid(ctl->sc_conn_pub->lconn)
@ -2435,6 +2439,25 @@ send_ctl_get_buffered_packet (lsquic_send_ctl_t *ctl,
}
static void
send_ctl_maybe_flush_decoder (struct lsquic_send_ctl *ctl,
const struct lsquic_stream *caller)
{
struct lsquic_stream *decoder;
if ((ctl->sc_flags & SC_IETF) && ctl->sc_conn_pub->u.ietf.qdh)
{
decoder = ctl->sc_conn_pub->u.ietf.qdh->qdh_dec_sm_out;
if (decoder && decoder != caller
&& lsquic_stream_has_data_to_flush(decoder))
{
LSQ_DEBUG("flushing decoder stream");
lsquic_stream_flush(decoder);
}
}
}
lsquic_packet_out_t *
lsquic_send_ctl_get_packet_for_stream (lsquic_send_ctl_t *ctl,
unsigned need_at_least, const struct network_path *path,
@ -2447,6 +2470,8 @@ lsquic_send_ctl_get_packet_for_stream (lsquic_send_ctl_t *ctl,
need_at_least, path, 0, NULL);
else
{
if (!lsquic_send_ctl_has_buffered(ctl))
send_ctl_maybe_flush_decoder(ctl, stream);
packet_type = send_ctl_lookup_bpt(ctl, stream);
return send_ctl_get_buffered_packet(ctl, packet_type, need_at_least,
path, stream);

View file

@ -3418,7 +3418,7 @@ stream_write_buf (struct lsquic_stream *stream, const void *buf, size_t sz)
}
/* XXX Move this define elsewhere? */
/* This limits the cumulative size of the compressed header fields */
#define MAX_HEADERS_SIZE (64 * 1024)
static int

View file

@ -329,7 +329,7 @@ lsquic_tp_decode (const unsigned char *const buf, size_t bufsz,
} while (0)
set_of_ids = 0;
while (p < end)
while (p + 4 <= end)
{
READ_UINT(param_id, 16, p, 2);
p += 2;