mirror of
https://gitea.invidious.io/iv-org/litespeed-quic.git
synced 2024-08-15 00:53:43 +00:00
Release 1.14.0
- [API Change] Disable packet sending if full batch cannot be sent If lsquic_packets_out_f() cannot send the whole batch, disable packet sending until lsquic_engine_send_unsent_packets() is called. - [BUGFIX] Handle case when STREAM frame does not fit. - [BUGFIX] Always allow incoming STREAM frames to overlap. Peers may send overlapping STREAM frames even if using versions older than Q043. - Custom header set fixes: - set "FIN reached" flag when custom header with FIN flag is claimed; - do not return custom header set for a reset stream.
This commit is contained in:
parent
3b55e6ae0a
commit
14e3680d6b
19 changed files with 187 additions and 70 deletions
14
CHANGELOG
14
CHANGELOG
|
@ -1,3 +1,17 @@
|
||||||
|
2018-09-06
|
||||||
|
- 1.14.0
|
||||||
|
- [API Change] Disable packet sending if full batch cannot be sent
|
||||||
|
If lsquic_packets_out_f() cannot send the whole batch, disable
|
||||||
|
packet sending until lsquic_engine_send_unsent_packets() is called.
|
||||||
|
- [BUGFIX] Handle case when STREAM frame does not fit.
|
||||||
|
- [BUGFIX] Always allow incoming STREAM frames to overlap. Peers
|
||||||
|
may send overlapping STREAM frames even if using versions older
|
||||||
|
than Q043.
|
||||||
|
- Custom header set fixes:
|
||||||
|
- set "FIN reached" flag when custom header with FIN flag is
|
||||||
|
claimed;
|
||||||
|
- do not return custom header set for a reset stream.
|
||||||
|
|
||||||
2018-08-27
|
2018-08-27
|
||||||
|
|
||||||
- 1.13.0
|
- 1.13.0
|
||||||
|
|
|
@ -113,7 +113,7 @@ include_directories(${BORINGSSL_INCLUDE} ${VCPKG_INCLUDE} )
|
||||||
link_directories( ${BORINGSSL_LIB} )
|
link_directories( ${BORINGSSL_LIB} )
|
||||||
|
|
||||||
SET(CMAKE_INCLUDE_CURRENT_DIR ON)
|
SET(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
include_directories( include )
|
include_directories( include src/lshpack)
|
||||||
IF(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD" OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
IF(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD" OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||||
# Find libevent on FreeBSD:
|
# Find libevent on FreeBSD:
|
||||||
include_directories( /usr/local/include )
|
include_directories( /usr/local/include )
|
||||||
|
|
|
@ -24,7 +24,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LSQUIC_MAJOR_VERSION 1
|
#define LSQUIC_MAJOR_VERSION 1
|
||||||
#define LSQUIC_MINOR_VERSION 13
|
#define LSQUIC_MINOR_VERSION 14
|
||||||
#define LSQUIC_PATCH_VERSION 0
|
#define LSQUIC_PATCH_VERSION 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -471,9 +471,10 @@ struct lsquic_out_spec
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns number of packets successfully sent out or -1 on error. -1 should
|
* Returns number of packets successfully sent out or -1 on error. -1 should
|
||||||
* only be returned if no packets were sent out. If -1 is returned,
|
* only be returned if no packets were sent out. If -1 is returned or if the
|
||||||
* no packets will be attempted to be sent out until
|
* return value is smaller than `n_packets_out', this indicates that sending
|
||||||
* @ref lsquic_engine_send_unsent_packets() is called.
|
* of packets is not possible No packets will be attempted to be sent out
|
||||||
|
* until @ref lsquic_engine_send_unsent_packets() is called.
|
||||||
*/
|
*/
|
||||||
typedef int (*lsquic_packets_out_f)(
|
typedef int (*lsquic_packets_out_f)(
|
||||||
void *packets_out_ctx,
|
void *packets_out_ctx,
|
||||||
|
@ -625,7 +626,7 @@ lsquic_engine_connect (lsquic_engine_t *, const struct sockaddr *local_sa,
|
||||||
/**
|
/**
|
||||||
* Pass incoming packet to the QUIC engine. This function can be called
|
* Pass incoming packet to the QUIC engine. This function can be called
|
||||||
* more than once in a row. After you add one or more packets, call
|
* more than once in a row. After you add one or more packets, call
|
||||||
* lsquic_engine_process_conns_with_incoming() to schedule output, if any.
|
* lsquic_engine_process_conns() to schedule output, if any.
|
||||||
*
|
*
|
||||||
* @retval 0 Packet was processed by a real connection.
|
* @retval 0 Packet was processed by a real connection.
|
||||||
*
|
*
|
||||||
|
|
|
@ -51,7 +51,7 @@ SET(lsquic_STAT_SRCS
|
||||||
lsquic_xxhash.c
|
lsquic_xxhash.c
|
||||||
lsquic_buf.c
|
lsquic_buf.c
|
||||||
lsquic_min_heap.c
|
lsquic_min_heap.c
|
||||||
lshpack.c
|
../lshpack/lshpack.c
|
||||||
lsquic_parse_Q044.c
|
lsquic_parse_Q044.c
|
||||||
lsquic_http1x_if.c
|
lsquic_http1x_if.c
|
||||||
)
|
)
|
||||||
|
|
|
@ -977,13 +977,17 @@ send_batch (lsquic_engine_t *engine, struct conns_out_iter *conns_iter,
|
||||||
batch->packets[i]->po_sent = now;
|
batch->packets[i]->po_sent = now;
|
||||||
n_sent = engine->packets_out(engine->packets_out_ctx, batch->outs,
|
n_sent = engine->packets_out(engine->packets_out_ctx, batch->outs,
|
||||||
n_to_send);
|
n_to_send);
|
||||||
|
if (n_sent < (int) n_to_send)
|
||||||
|
{
|
||||||
|
engine->pub.enp_flags &= ~ENPUB_CAN_SEND;
|
||||||
|
LSQ_DEBUG("cannot send packets");
|
||||||
|
EV_LOG_GENERIC_EVENT("cannot send packets");
|
||||||
|
}
|
||||||
if (n_sent >= 0)
|
if (n_sent >= 0)
|
||||||
LSQ_DEBUG("packets out returned %d (out of %u)", n_sent, n_to_send);
|
LSQ_DEBUG("packets out returned %d (out of %u)", n_sent, n_to_send);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
engine->pub.enp_flags &= ~ENPUB_CAN_SEND;
|
|
||||||
LSQ_DEBUG("packets out returned an error: %s", strerror(errno));
|
LSQ_DEBUG("packets out returned an error: %s", strerror(errno));
|
||||||
EV_LOG_GENERIC_EVENT("cannot send packets");
|
|
||||||
n_sent = 0;
|
n_sent = 0;
|
||||||
}
|
}
|
||||||
if (n_sent > 0)
|
if (n_sent > 0)
|
||||||
|
|
|
@ -913,9 +913,6 @@ new_stream_ext (struct full_conn *conn, uint32_t stream_id, int if_idx,
|
||||||
{
|
{
|
||||||
struct lsquic_stream *stream;
|
struct lsquic_stream *stream;
|
||||||
|
|
||||||
if (conn->fc_conn.cn_version >= LSQVER_043)
|
|
||||||
stream_ctor_flags |= SCF_ALLOW_OVERLAP;
|
|
||||||
|
|
||||||
stream = lsquic_stream_new_ext(stream_id, &conn->fc_pub,
|
stream = lsquic_stream_new_ext(stream_id, &conn->fc_pub,
|
||||||
conn->fc_stream_ifs[if_idx].stream_if,
|
conn->fc_stream_ifs[if_idx].stream_if,
|
||||||
conn->fc_stream_ifs[if_idx].stream_if_ctx, conn->fc_settings->es_sfcw,
|
conn->fc_stream_ifs[if_idx].stream_if_ctx, conn->fc_settings->es_sfcw,
|
||||||
|
|
|
@ -73,7 +73,12 @@ struct parse_funcs
|
||||||
struct packin_parse_state *);
|
struct packin_parse_state *);
|
||||||
enum QUIC_FRAME_TYPE
|
enum QUIC_FRAME_TYPE
|
||||||
(*pf_parse_frame_type) (unsigned char);
|
(*pf_parse_frame_type) (unsigned char);
|
||||||
/* Return used buffer length */
|
/* Return used buffer length or a negative value if there was not enough
|
||||||
|
* room to write the stream frame. In the latter case, the negative of
|
||||||
|
* the negative return value is the number of bytes required. The
|
||||||
|
* exception is -1, which is a generic error code, as we always need
|
||||||
|
* more than 1 byte to write a STREAM frame.
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
(*pf_gen_stream_frame) (unsigned char *buf, size_t bufsz,
|
(*pf_gen_stream_frame) (unsigned char *buf, size_t bufsz,
|
||||||
uint32_t stream_id, uint64_t offset,
|
uint32_t stream_id, uint64_t offset,
|
||||||
|
|
|
@ -117,7 +117,7 @@ gen_long_pkt_header (const struct lsquic_conn *lconn,
|
||||||
p += 4;
|
p += 4;
|
||||||
|
|
||||||
|
|
||||||
assert(need = p - buf);
|
assert(need == (unsigned int)(p - buf));
|
||||||
return p - buf;
|
return p - buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,4 +21,13 @@ int
|
||||||
lsquic_iquic_parse_packet_in_begin (struct lsquic_packet_in *,
|
lsquic_iquic_parse_packet_in_begin (struct lsquic_packet_in *,
|
||||||
size_t length, int is_server, struct packin_parse_state *);
|
size_t length, int is_server, struct packin_parse_state *);
|
||||||
|
|
||||||
|
/* Instead of just -1 like CHECK_SPACE(), this macro returns the number
|
||||||
|
* of bytes needed.
|
||||||
|
*/
|
||||||
|
#define CHECK_STREAM_SPACE(need, pstart, pend) do { \
|
||||||
|
if ((intptr_t) (need) > ((pend) - (pstart))) { \
|
||||||
|
return -((int) (need)); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -222,7 +222,7 @@ gquic_be_gen_stream_frame (unsigned char *buf, size_t buf_len, uint32_t stream_i
|
||||||
dlen = (size < n_avail) << 1;
|
dlen = (size < n_avail) << 1;
|
||||||
n_avail -= dlen;
|
n_avail -= dlen;
|
||||||
|
|
||||||
CHECK_SPACE(1 + olen + slen + dlen +
|
CHECK_STREAM_SPACE(1 + olen + slen + dlen +
|
||||||
+ 1 /* We need to write at least 1 byte */, buf, buf + buf_len);
|
+ 1 /* We need to write at least 1 byte */, buf, buf + buf_len);
|
||||||
|
|
||||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||||
|
@ -255,7 +255,7 @@ gquic_be_gen_stream_frame (unsigned char *buf, size_t buf_len, uint32_t stream_i
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dlen = 2;
|
dlen = 2;
|
||||||
CHECK_SPACE(1 + slen + olen + 2, buf, buf + buf_len);
|
CHECK_STREAM_SPACE(1 + slen + olen + 2, buf, buf + buf_len);
|
||||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||||
stream_id = bswap_32(stream_id);
|
stream_id = bswap_32(stream_id);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -217,7 +217,7 @@ gquic_le_gen_stream_frame (unsigned char *buf, size_t buf_len, uint32_t stream_i
|
||||||
dlen = (size < n_avail) << 1;
|
dlen = (size < n_avail) << 1;
|
||||||
n_avail -= dlen;
|
n_avail -= dlen;
|
||||||
|
|
||||||
CHECK_SPACE(1 + olen + slen + dlen +
|
CHECK_STREAM_SPACE(1 + olen + slen + dlen +
|
||||||
+ 1 /* We need to write at least 1 byte */, buf, buf + buf_len);
|
+ 1 /* We need to write at least 1 byte */, buf, buf + buf_len);
|
||||||
|
|
||||||
memcpy(p, &stream_id, slen);
|
memcpy(p, &stream_id, slen);
|
||||||
|
@ -238,7 +238,7 @@ gquic_le_gen_stream_frame (unsigned char *buf, size_t buf_len, uint32_t stream_i
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dlen = 2;
|
dlen = 2;
|
||||||
CHECK_SPACE(1 + slen + olen + 2, buf, buf + buf_len);
|
CHECK_STREAM_SPACE(1 + slen + olen + 2, buf, buf + buf_len);
|
||||||
memcpy(p, &stream_id, slen);
|
memcpy(p, &stream_id, slen);
|
||||||
p += slen;
|
p += slen;
|
||||||
memcpy(p, &offset, olen);
|
memcpy(p, &offset, olen);
|
||||||
|
|
|
@ -273,8 +273,6 @@ lsquic_stream_new_ext (uint32_t id, struct lsquic_conn_public *conn_pub,
|
||||||
lsquic_stream_call_on_new(stream);
|
lsquic_stream_call_on_new(stream);
|
||||||
if (ctor_flags & SCF_DISP_RW_ONCE)
|
if (ctor_flags & SCF_DISP_RW_ONCE)
|
||||||
stream->stream_flags |= STREAM_RW_ONCE;
|
stream->stream_flags |= STREAM_RW_ONCE;
|
||||||
if (ctor_flags & SCF_ALLOW_OVERLAP)
|
|
||||||
stream->stream_flags |= STREAM_ALLOW_OVERLAP;
|
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -559,17 +557,12 @@ lsquic_stream_frame_in (lsquic_stream_t *stream, stream_frame_t *frame)
|
||||||
}
|
}
|
||||||
else if (INS_FRAME_OVERLAP == ins_frame)
|
else if (INS_FRAME_OVERLAP == ins_frame)
|
||||||
{
|
{
|
||||||
if (stream->stream_flags & STREAM_ALLOW_OVERLAP)
|
LSQ_DEBUG("overlap: switching DATA IN implementation");
|
||||||
{
|
stream->data_in = stream->data_in->di_if->di_switch_impl(
|
||||||
LSQ_DEBUG("overlap: switching DATA IN implementation");
|
stream->data_in, stream->read_offset);
|
||||||
stream->data_in = stream->data_in->di_if->di_switch_impl(
|
if (stream->data_in)
|
||||||
stream->data_in, stream->read_offset);
|
goto insert_frame;
|
||||||
if (stream->data_in)
|
stream->data_in = data_in_error_new();
|
||||||
goto insert_frame;
|
|
||||||
stream->data_in = data_in_error_new();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
LSQ_DEBUG("overlap not supported");
|
|
||||||
lsquic_packet_in_put(stream->conn_pub->mm, frame->packet_in);
|
lsquic_packet_in_put(stream->conn_pub->mm, frame->packet_in);
|
||||||
lsquic_malo_put(frame);
|
lsquic_malo_put(frame);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1573,6 +1566,7 @@ stream_write_to_packet (struct frame_gen_ctx *fg_ctx, const size_t size)
|
||||||
stream->tosend_off);
|
stream->tosend_off);
|
||||||
need_at_least = stream_header_sz + (size > 0);
|
need_at_least = stream_header_sz + (size > 0);
|
||||||
hsk = LSQUIC_STREAM_HANDSHAKE == stream->id;
|
hsk = LSQUIC_STREAM_HANDSHAKE == stream->id;
|
||||||
|
get_packet:
|
||||||
packet_out = get_packet[hsk](send_ctl, need_at_least, stream);
|
packet_out = get_packet[hsk](send_ctl, need_at_least, stream);
|
||||||
if (!packet_out)
|
if (!packet_out)
|
||||||
return SWTP_STOP;
|
return SWTP_STOP;
|
||||||
|
@ -1588,8 +1582,18 @@ stream_write_to_packet (struct frame_gen_ctx *fg_ctx, const size_t size)
|
||||||
frame_gen_fin(fg_ctx), size, frame_gen_read, fg_ctx);
|
frame_gen_fin(fg_ctx), size, frame_gen_read, fg_ctx);
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
{
|
{
|
||||||
LSQ_ERROR("could not generate stream frame");
|
if (-len > (int) need_at_least)
|
||||||
return SWTP_ERROR;
|
{
|
||||||
|
LSQ_DEBUG("need more room (%d bytes) than initially calculated "
|
||||||
|
"%u bytes, will try again", -len, need_at_least);
|
||||||
|
need_at_least = -len;
|
||||||
|
goto get_packet;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LSQ_ERROR("could not generate stream frame");
|
||||||
|
return SWTP_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EV_LOG_GENERATED_STREAM_FRAME(LSQUIC_LOG_CONN_ID, pf,
|
EV_LOG_GENERATED_STREAM_FRAME(LSQUIC_LOG_CONN_ID, pf,
|
||||||
|
@ -2181,6 +2185,13 @@ lsquic_stream_get_hset (struct lsquic_stream *stream)
|
||||||
{
|
{
|
||||||
void *hset;
|
void *hset;
|
||||||
|
|
||||||
|
if (stream->stream_flags & STREAM_RST_FLAGS)
|
||||||
|
{
|
||||||
|
LSQ_INFO("%s: stream is reset, no headers returned", __func__);
|
||||||
|
errno = ECONNRESET;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if ((stream->stream_flags & (STREAM_USE_HEADERS|STREAM_HAVE_UH))
|
if ((stream->stream_flags & (STREAM_USE_HEADERS|STREAM_HAVE_UH))
|
||||||
!= (STREAM_USE_HEADERS|STREAM_HAVE_UH))
|
!= (STREAM_USE_HEADERS|STREAM_HAVE_UH))
|
||||||
{
|
{
|
||||||
|
@ -2204,6 +2215,11 @@ lsquic_stream_get_hset (struct lsquic_stream *stream)
|
||||||
hset = stream->uh->uh_hset;
|
hset = stream->uh->uh_hset;
|
||||||
stream->uh->uh_hset = NULL;
|
stream->uh->uh_hset = NULL;
|
||||||
destroy_uh(stream);
|
destroy_uh(stream);
|
||||||
|
if (stream->stream_flags & STREAM_HEAD_IN_FIN)
|
||||||
|
{
|
||||||
|
stream->stream_flags |= STREAM_FIN_REACHED;
|
||||||
|
SM_HISTORY_APPEND(stream, SHE_REACH_FIN);
|
||||||
|
}
|
||||||
LSQ_DEBUG("return header set");
|
LSQ_DEBUG("return header set");
|
||||||
return hset;
|
return hset;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,6 @@ struct lsquic_stream
|
||||||
STREAM_ONNEW_DONE = (1 <<26), /* on_new_stream has been called */
|
STREAM_ONNEW_DONE = (1 <<26), /* on_new_stream has been called */
|
||||||
STREAM_AUTOSWITCH = (1 <<27),
|
STREAM_AUTOSWITCH = (1 <<27),
|
||||||
STREAM_RW_ONCE = (1 <<28), /* When set, read/write events are dispatched once per call */
|
STREAM_RW_ONCE = (1 <<28), /* When set, read/write events are dispatched once per call */
|
||||||
STREAM_ALLOW_OVERLAP= (1 <<29),
|
|
||||||
} stream_flags;
|
} stream_flags;
|
||||||
|
|
||||||
/* There are more than one reason that a stream may be put onto
|
/* There are more than one reason that a stream may be put onto
|
||||||
|
@ -140,7 +139,6 @@ enum stream_ctor_flags
|
||||||
* performance.
|
* performance.
|
||||||
*/
|
*/
|
||||||
SCF_DISP_RW_ONCE = (1 << 3),
|
SCF_DISP_RW_ONCE = (1 << 3),
|
||||||
SCF_ALLOW_OVERLAP = (1 << 4), /* Allow STREAM frames to overlap */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
lsquic_stream_t *
|
lsquic_stream_t *
|
||||||
|
|
|
@ -36,7 +36,7 @@ SOFTWARE.
|
||||||
#if LS_HPACK_EMIT_TEST_CODE
|
#if LS_HPACK_EMIT_TEST_CODE
|
||||||
#include "lshpack-test.h"
|
#include "lshpack-test.h"
|
||||||
#endif
|
#endif
|
||||||
#include XXH_HEADER_NAME
|
#include "lsquic_xxhash.h"
|
||||||
|
|
||||||
#define HPACK_STATIC_TABLE_SIZE 61
|
#define HPACK_STATIC_TABLE_SIZE 61
|
||||||
#define INITIAL_DYNAMIC_TABLE_SIZE 4096
|
#define INITIAL_DYNAMIC_TABLE_SIZE 4096
|
|
@ -430,6 +430,7 @@ send_unsent (evutil_socket_t fd, short what, void *arg)
|
||||||
event_del(prog->prog_send);
|
event_del(prog->prog_send);
|
||||||
event_free(prog->prog_send);
|
event_free(prog->prog_send);
|
||||||
prog->prog_send = NULL;
|
prog->prog_send = NULL;
|
||||||
|
LSQ_DEBUG("on_write event fires");
|
||||||
lsquic_engine_send_unsent_packets(prog->prog_engine);
|
lsquic_engine_send_unsent_packets(prog->prog_engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,6 +439,7 @@ void
|
||||||
prog_sport_cant_send (struct prog *prog, int fd)
|
prog_sport_cant_send (struct prog *prog, int fd)
|
||||||
{
|
{
|
||||||
assert(!prog->prog_send);
|
assert(!prog->prog_send);
|
||||||
|
LSQ_DEBUG("cannot send: register on_write event");
|
||||||
prog->prog_send = event_new(prog->prog_eb, fd, EV_WRITE, send_unsent, prog);
|
prog->prog_send = event_new(prog->prog_eb, fd, EV_WRITE, send_unsent, prog);
|
||||||
event_add(prog->prog_send, NULL);
|
event_add(prog->prog_send, NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -894,6 +894,7 @@ send_packets_one_by_one (const struct lsquic_out_spec *specs, unsigned count)
|
||||||
assert(count > 0);
|
assert(count > 0);
|
||||||
sport = specs[0].peer_ctx;
|
sport = specs[0].peer_ctx;
|
||||||
LSQ_NOTICE("sending \"randomly\" fails");
|
LSQ_NOTICE("sending \"randomly\" fails");
|
||||||
|
prog_sport_cant_send(sport->sp_prog, sport->fd);
|
||||||
goto random_send_failure;
|
goto random_send_failure;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -951,6 +952,9 @@ send_packets_one_by_one (const struct lsquic_out_spec *specs, unsigned count)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (n < count)
|
||||||
|
prog_sport_cant_send(sport->sp_prog, sport->fd);
|
||||||
|
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
return n;
|
return n;
|
||||||
else if (s < 0)
|
else if (s < 0)
|
||||||
|
@ -958,7 +962,6 @@ send_packets_one_by_one (const struct lsquic_out_spec *specs, unsigned count)
|
||||||
#if LSQUIC_RANDOM_SEND_FAILURE
|
#if LSQUIC_RANDOM_SEND_FAILURE
|
||||||
random_send_failure:
|
random_send_failure:
|
||||||
#endif
|
#endif
|
||||||
prog_sport_cant_send(sport->sp_prog, sport->fd);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
#include "lsquic_ver_neg.h"
|
#include "lsquic_ver_neg.h"
|
||||||
#include "lsquic_packet_out.h"
|
#include "lsquic_packet_out.h"
|
||||||
|
|
||||||
static const struct parse_funcs *const pf = select_pf_by_ver(LSQVER_035);
|
static const struct parse_funcs *const g_pf = select_pf_by_ver(LSQVER_035);
|
||||||
|
|
||||||
struct test_ctl_settings
|
struct test_ctl_settings
|
||||||
{
|
{
|
||||||
|
@ -266,10 +266,10 @@ struct test_objs {
|
||||||
|
|
||||||
static void
|
static void
|
||||||
init_test_objs (struct test_objs *tobjs, unsigned initial_conn_window,
|
init_test_objs (struct test_objs *tobjs, unsigned initial_conn_window,
|
||||||
unsigned initial_stream_window)
|
unsigned initial_stream_window, const struct parse_funcs *pf)
|
||||||
{
|
{
|
||||||
memset(tobjs, 0, sizeof(*tobjs));
|
memset(tobjs, 0, sizeof(*tobjs));
|
||||||
tobjs->lconn.cn_pf = pf;
|
tobjs->lconn.cn_pf = pf ? pf : g_pf;
|
||||||
tobjs->lconn.cn_pack_size = 1370;
|
tobjs->lconn.cn_pack_size = 1370;
|
||||||
lsquic_mm_init(&tobjs->eng_pub.enp_mm);
|
lsquic_mm_init(&tobjs->eng_pub.enp_mm);
|
||||||
TAILQ_INIT(&tobjs->conn_pub.sending_streams);
|
TAILQ_INIT(&tobjs->conn_pub.sending_streams);
|
||||||
|
@ -379,7 +379,7 @@ run_frame_ordering_test (uint64_t run_id /* This is used to make it easier to se
|
||||||
|
|
||||||
struct test_objs tobjs;
|
struct test_objs tobjs;
|
||||||
|
|
||||||
init_test_objs(&tobjs, 0x4000, 0x4000);
|
init_test_objs(&tobjs, 0x4000, 0x4000, NULL);
|
||||||
|
|
||||||
lsquic_stream_t *stream = new_stream(&tobjs, 123);
|
lsquic_stream_t *stream = new_stream(&tobjs, 123);
|
||||||
struct lsquic_mm *const mm = &tobjs.eng_pub.enp_mm;
|
struct lsquic_mm *const mm = &tobjs.eng_pub.enp_mm;
|
||||||
|
@ -1195,7 +1195,7 @@ test_termination (void)
|
||||||
{
|
{
|
||||||
init_test_ctl_settings(&g_ctl_settings);
|
init_test_ctl_settings(&g_ctl_settings);
|
||||||
g_ctl_settings.tcs_schedule_stream_packets_immediately = 1;
|
g_ctl_settings.tcs_schedule_stream_packets_immediately = 1;
|
||||||
init_test_objs(&tobjs, 0x4000, 0x4000);
|
init_test_objs(&tobjs, 0x4000, 0x4000, NULL);
|
||||||
test_funcs[i](&tobjs);
|
test_funcs[i](&tobjs);
|
||||||
deinit_test_objs(&tobjs);
|
deinit_test_objs(&tobjs);
|
||||||
}
|
}
|
||||||
|
@ -1217,7 +1217,7 @@ test_flushing (void)
|
||||||
|
|
||||||
for (i = 0; i < sizeof(test_funcs) / sizeof(test_funcs[0]); ++i)
|
for (i = 0; i < sizeof(test_funcs) / sizeof(test_funcs[0]); ++i)
|
||||||
{
|
{
|
||||||
init_test_objs(&tobjs, 0x4000, 0x4000);
|
init_test_objs(&tobjs, 0x4000, 0x4000, NULL);
|
||||||
test_funcs[i](&tobjs);
|
test_funcs[i](&tobjs);
|
||||||
deinit_test_objs(&tobjs);
|
deinit_test_objs(&tobjs);
|
||||||
}
|
}
|
||||||
|
@ -1293,7 +1293,7 @@ test_writev (void)
|
||||||
|
|
||||||
for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
|
for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
|
||||||
{
|
{
|
||||||
init_test_objs(&tobjs, UINT_MAX, UINT_MAX);
|
init_test_objs(&tobjs, UINT_MAX, UINT_MAX, NULL);
|
||||||
stream = new_stream(&tobjs, 12345);
|
stream = new_stream(&tobjs, 12345);
|
||||||
n = lsquic_stream_writev(stream, tests[i].iov, tests[i].count);
|
n = lsquic_stream_writev(stream, tests[i].iov, tests[i].count);
|
||||||
assert(0x4000 == n);
|
assert(0x4000 == n);
|
||||||
|
@ -1317,7 +1317,7 @@ test_prio_conversion (void)
|
||||||
unsigned prio;
|
unsigned prio;
|
||||||
int s;
|
int s;
|
||||||
|
|
||||||
init_test_objs(&tobjs, UINT_MAX, UINT_MAX);
|
init_test_objs(&tobjs, UINT_MAX, UINT_MAX, NULL);
|
||||||
stream = new_stream(&tobjs, 123);
|
stream = new_stream(&tobjs, 123);
|
||||||
|
|
||||||
s = lsquic_stream_set_priority(stream, -2);
|
s = lsquic_stream_set_priority(stream, -2);
|
||||||
|
@ -1349,7 +1349,7 @@ test_read_in_middle (void)
|
||||||
struct test_objs tobjs;
|
struct test_objs tobjs;
|
||||||
stream_frame_t *frame;
|
stream_frame_t *frame;
|
||||||
|
|
||||||
init_test_objs(&tobjs, 0x4000, 0x4000);
|
init_test_objs(&tobjs, 0x4000, 0x4000, NULL);
|
||||||
|
|
||||||
lsquic_stream_t *stream = new_stream(&tobjs, 123);
|
lsquic_stream_t *stream = new_stream(&tobjs, 123);
|
||||||
|
|
||||||
|
@ -1392,7 +1392,7 @@ test_conn_unlimited (void)
|
||||||
struct test_objs tobjs;
|
struct test_objs tobjs;
|
||||||
lsquic_stream_t *header_stream, *data_stream;
|
lsquic_stream_t *header_stream, *data_stream;
|
||||||
|
|
||||||
init_test_objs(&tobjs, 0x4000, 0x4000);
|
init_test_objs(&tobjs, 0x4000, 0x4000, NULL);
|
||||||
|
|
||||||
unsigned char *const data = calloc(1, 0x4000);
|
unsigned char *const data = calloc(1, 0x4000);
|
||||||
|
|
||||||
|
@ -1438,9 +1438,9 @@ test_reading_from_stream2 (void)
|
||||||
stream_frame_t *frame;
|
stream_frame_t *frame;
|
||||||
ssize_t nw;
|
ssize_t nw;
|
||||||
int s;
|
int s;
|
||||||
const char data[] = "1234567890";
|
const char data[10] = "1234567890";
|
||||||
|
|
||||||
init_test_objs(&tobjs, 0x4000, 0x4000);
|
init_test_objs(&tobjs, 0x4000, 0x4000, NULL);
|
||||||
stream = new_stream(&tobjs, 123);
|
stream = new_stream(&tobjs, 123);
|
||||||
|
|
||||||
frame = new_frame_in_ext(&tobjs, 0, 6, 0, &data[0]);
|
frame = new_frame_in_ext(&tobjs, 0, 6, 0, &data[0]);
|
||||||
|
@ -1461,18 +1461,18 @@ test_reading_from_stream2 (void)
|
||||||
{
|
{
|
||||||
int dup;
|
int dup;
|
||||||
unsigned offset, length;
|
unsigned offset, length;
|
||||||
for (offset = 0; offset < 9; ++offset)
|
for (offset = 0; offset < 7; ++offset)
|
||||||
{
|
{
|
||||||
for (length = 1; length < 10; ++length)
|
for (length = 1; length <= sizeof(data) - offset; ++length)
|
||||||
{
|
{
|
||||||
dup = (offset == 0 && length == 6)
|
dup = (offset == 0 && length == 6)
|
||||||
|| (offset == 6 && length == 4);
|
|| (offset == 6 && length == 4);
|
||||||
frame = new_frame_in(&tobjs, offset, length, 0);
|
frame = new_frame_in_ext(&tobjs, offset, length, 0, data + offset);
|
||||||
s = lsquic_stream_frame_in(stream, frame);
|
s = lsquic_stream_frame_in(stream, frame);
|
||||||
if (dup)
|
if (dup)
|
||||||
assert(("Dup OK", 0 == s));
|
assert(("Dup OK", 0 == s));
|
||||||
else
|
else
|
||||||
assert(("Invalid frame: overlap", -1 == s));
|
assert(("Overlap OK", 0 == s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1693,9 +1693,7 @@ test_overlaps (void)
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
init_test_objs(&tobjs, 0x4000, 0x4000);
|
init_test_objs(&tobjs, 0x4000, 0x4000, NULL);
|
||||||
assert(!(tobjs.ctor_flags & SCF_ALLOW_OVERLAP)); /* Self-check */
|
|
||||||
tobjs.ctor_flags |= SCF_ALLOW_OVERLAP;
|
|
||||||
|
|
||||||
const struct overlap_test *test;
|
const struct overlap_test *test;
|
||||||
for (test = tests; test < tests + sizeof(tests) / sizeof(tests[0]); ++test)
|
for (test = tests; test < tests + sizeof(tests) / sizeof(tests[0]); ++test)
|
||||||
|
@ -1761,7 +1759,6 @@ test_overlaps (void)
|
||||||
lsquic_stream_destroy(stream);
|
lsquic_stream_destroy(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
tobjs.ctor_flags &= ~SCF_ALLOW_OVERLAP;
|
|
||||||
deinit_test_objs(&tobjs);
|
deinit_test_objs(&tobjs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1777,7 +1774,7 @@ test_insert_edge_cases (void)
|
||||||
const char data[] = "1234567890";
|
const char data[] = "1234567890";
|
||||||
unsigned buf[0x1000];
|
unsigned buf[0x1000];
|
||||||
|
|
||||||
init_test_objs(&tobjs, 0x4000, 0x4000);
|
init_test_objs(&tobjs, 0x4000, 0x4000, NULL);
|
||||||
|
|
||||||
{
|
{
|
||||||
stream = new_stream(&tobjs, 123);
|
stream = new_stream(&tobjs, 123);
|
||||||
|
@ -1847,7 +1844,7 @@ test_writing_to_stream_schedule_stream_packets_immediately (void)
|
||||||
init_test_ctl_settings(&g_ctl_settings);
|
init_test_ctl_settings(&g_ctl_settings);
|
||||||
g_ctl_settings.tcs_schedule_stream_packets_immediately = 1;
|
g_ctl_settings.tcs_schedule_stream_packets_immediately = 1;
|
||||||
|
|
||||||
init_test_objs(&tobjs, 0x4000, 0x4000);
|
init_test_objs(&tobjs, 0x4000, 0x4000, NULL);
|
||||||
n_closed = 0;
|
n_closed = 0;
|
||||||
stream = new_stream(&tobjs, 123);
|
stream = new_stream(&tobjs, 123);
|
||||||
assert(("Stream initialized", stream));
|
assert(("Stream initialized", stream));
|
||||||
|
@ -1915,7 +1912,7 @@ test_writing_to_stream_outside_callback (void)
|
||||||
const struct buf_packet_q *const bpq =
|
const struct buf_packet_q *const bpq =
|
||||||
&tobjs.send_ctl.sc_buffered_packets[g_ctl_settings.tcs_bp_type];
|
&tobjs.send_ctl.sc_buffered_packets[g_ctl_settings.tcs_bp_type];
|
||||||
|
|
||||||
init_test_objs(&tobjs, 0x4000, 0x4000);
|
init_test_objs(&tobjs, 0x4000, 0x4000, NULL);
|
||||||
n_closed = 0;
|
n_closed = 0;
|
||||||
stream = new_stream(&tobjs, 123);
|
stream = new_stream(&tobjs, 123);
|
||||||
assert(("Stream initialized", stream));
|
assert(("Stream initialized", stream));
|
||||||
|
@ -1982,7 +1979,7 @@ test_window_update1 (void)
|
||||||
init_test_ctl_settings(&g_ctl_settings);
|
init_test_ctl_settings(&g_ctl_settings);
|
||||||
g_ctl_settings.tcs_schedule_stream_packets_immediately = 1;
|
g_ctl_settings.tcs_schedule_stream_packets_immediately = 1;
|
||||||
|
|
||||||
init_test_objs(&tobjs, 0x4000, 0x4000);
|
init_test_objs(&tobjs, 0x4000, 0x4000, NULL);
|
||||||
n_closed = 0;
|
n_closed = 0;
|
||||||
stream = new_stream_ext(&tobjs, 123, 3);
|
stream = new_stream_ext(&tobjs, 123, 3);
|
||||||
nw = lsquic_stream_write(stream, "1234567890", 10);
|
nw = lsquic_stream_write(stream, "1234567890", 10);
|
||||||
|
@ -2040,7 +2037,7 @@ test_bad_packbits_guess_2 (void)
|
||||||
g_ctl_settings.tcs_schedule_stream_packets_immediately = 0;
|
g_ctl_settings.tcs_schedule_stream_packets_immediately = 0;
|
||||||
g_ctl_settings.tcs_guess_packno_bits = PACKNO_LEN_1;
|
g_ctl_settings.tcs_guess_packno_bits = PACKNO_LEN_1;
|
||||||
|
|
||||||
init_test_objs(&tobjs, 0x1000, 0x1000);
|
init_test_objs(&tobjs, 0x1000, 0x1000, NULL);
|
||||||
streams[0] = new_stream(&tobjs, 5);
|
streams[0] = new_stream(&tobjs, 5);
|
||||||
streams[1] = new_stream(&tobjs, 7);
|
streams[1] = new_stream(&tobjs, 7);
|
||||||
streams[2] = new_stream(&tobjs, 9);
|
streams[2] = new_stream(&tobjs, 9);
|
||||||
|
@ -2143,7 +2140,7 @@ test_bad_packbits_guess_3 (void)
|
||||||
g_ctl_settings.tcs_schedule_stream_packets_immediately = 0;
|
g_ctl_settings.tcs_schedule_stream_packets_immediately = 0;
|
||||||
g_ctl_settings.tcs_guess_packno_bits = PACKNO_LEN_1;
|
g_ctl_settings.tcs_guess_packno_bits = PACKNO_LEN_1;
|
||||||
|
|
||||||
init_test_objs(&tobjs, 0x1000, 0x1000);
|
init_test_objs(&tobjs, 0x1000, 0x1000, NULL);
|
||||||
streams[0] = new_stream(&tobjs, 5);
|
streams[0] = new_stream(&tobjs, 5);
|
||||||
|
|
||||||
nw = lsquic_stream_write(streams[0], buf,
|
nw = lsquic_stream_write(streams[0], buf,
|
||||||
|
@ -2315,7 +2312,7 @@ test_packetization (int schedule_stream_packets_immediately, int dispatch_once,
|
||||||
|
|
||||||
init_test_objs(&tobjs,
|
init_test_objs(&tobjs,
|
||||||
/* Test limits a bit while we are at it: */
|
/* Test limits a bit while we are at it: */
|
||||||
sizeof(buf) - 1, sizeof(buf) - 1);
|
sizeof(buf) - 1, sizeof(buf) - 1, NULL);
|
||||||
tobjs.stream_if_ctx = &packet_stream_ctx;
|
tobjs.stream_if_ctx = &packet_stream_ctx;
|
||||||
|
|
||||||
if (schedule_stream_packets_immediately)
|
if (schedule_stream_packets_immediately)
|
||||||
|
@ -2369,6 +2366,73 @@ test_packetization (int schedule_stream_packets_immediately, int dispatch_once,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Test condition when the room necessary to write a STREAM frame to a packet
|
||||||
|
* is miscalculated and a brand-new packet has to be allocated.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
test_cant_fit_frame (const struct parse_funcs *pf)
|
||||||
|
{
|
||||||
|
struct test_objs tobjs;
|
||||||
|
struct lsquic_stream *streams[2];
|
||||||
|
struct lsquic_packet_out *packet_out;
|
||||||
|
size_t pad_len, rem, nr;
|
||||||
|
int fin, s;
|
||||||
|
const char dude[] = "Dude, where is my car?!";
|
||||||
|
unsigned char buf_out[100];
|
||||||
|
|
||||||
|
init_test_ctl_settings(&g_ctl_settings);
|
||||||
|
g_ctl_settings.tcs_schedule_stream_packets_immediately = 0;
|
||||||
|
|
||||||
|
init_test_objs(&tobjs, 0x8000, 0x8000, pf);
|
||||||
|
|
||||||
|
streams[0] = new_stream(&tobjs, 5);
|
||||||
|
streams[1] = new_stream(&tobjs, 7);
|
||||||
|
|
||||||
|
/* Allocate a packet and pad it so just a few bytes remain to trigger
|
||||||
|
* the condition we're after.
|
||||||
|
*/
|
||||||
|
lsquic_stream_write(streams[0], dude, sizeof(dude) - 1);
|
||||||
|
lsquic_stream_flush(streams[0]);
|
||||||
|
|
||||||
|
rem = pf->pf_calc_stream_frame_header_sz(streams[1]->id, 0)
|
||||||
|
+ 1 /* We'll write one byte */
|
||||||
|
+ 1 /* This triggers the refit condition */
|
||||||
|
;
|
||||||
|
|
||||||
|
packet_out = TAILQ_FIRST(&tobjs.send_ctl.sc_buffered_packets[0].bpq_packets);
|
||||||
|
assert(NULL == TAILQ_NEXT(packet_out, po_next));
|
||||||
|
pad_len = packet_out->po_n_alloc - packet_out->po_data_sz - rem;
|
||||||
|
memset(packet_out->po_data + packet_out->po_data_sz, 0, pad_len);
|
||||||
|
packet_out->po_data_sz += pad_len;
|
||||||
|
|
||||||
|
lsquic_stream_write(streams[1], "A", 1);
|
||||||
|
s = lsquic_stream_flush(streams[1]);
|
||||||
|
assert(0 == s);
|
||||||
|
/* Allocated another packet */
|
||||||
|
assert(TAILQ_NEXT(packet_out, po_next));
|
||||||
|
|
||||||
|
g_ctl_settings.tcs_schedule_stream_packets_immediately = 1;
|
||||||
|
lsquic_send_ctl_schedule_buffered(&tobjs.send_ctl, BPT_HIGHEST_PRIO);
|
||||||
|
g_ctl_settings.tcs_schedule_stream_packets_immediately = 0;
|
||||||
|
|
||||||
|
/* Verify written data: */
|
||||||
|
nr = read_from_scheduled_packets(&tobjs.send_ctl, streams[0]->id, buf_out,
|
||||||
|
sizeof(buf_out), 0, &fin, 1);
|
||||||
|
assert(nr == sizeof(dude) - 1);
|
||||||
|
assert(!fin);
|
||||||
|
assert(0 == memcmp(dude, buf_out, sizeof(dude) - 1));
|
||||||
|
nr = read_from_scheduled_packets(&tobjs.send_ctl, streams[1]->id, buf_out,
|
||||||
|
sizeof(buf_out), 0, &fin, 1);
|
||||||
|
assert(nr == 1);
|
||||||
|
assert(!fin);
|
||||||
|
assert(buf_out[0] == 'A');
|
||||||
|
|
||||||
|
lsquic_stream_destroy(streams[0]);
|
||||||
|
lsquic_stream_destroy(streams[1]);
|
||||||
|
deinit_test_objs(&tobjs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Test window update logic, not connection limited */
|
/* Test window update logic, not connection limited */
|
||||||
static void
|
static void
|
||||||
test_window_update2 (void)
|
test_window_update2 (void)
|
||||||
|
@ -2381,7 +2445,7 @@ test_window_update2 (void)
|
||||||
struct lsquic_conn_cap *const conn_cap = &tobjs.conn_pub.conn_cap;
|
struct lsquic_conn_cap *const conn_cap = &tobjs.conn_pub.conn_cap;
|
||||||
unsigned char buf[0x1000];
|
unsigned char buf[0x1000];
|
||||||
|
|
||||||
init_test_objs(&tobjs, 0x4000, 0x4000);
|
init_test_objs(&tobjs, 0x4000, 0x4000, NULL);
|
||||||
n_closed = 0;
|
n_closed = 0;
|
||||||
stream = new_stream_ext(&tobjs, LSQUIC_STREAM_HANDSHAKE, 3);
|
stream = new_stream_ext(&tobjs, LSQUIC_STREAM_HANDSHAKE, 3);
|
||||||
nw = lsquic_stream_write(stream, "1234567890", 10);
|
nw = lsquic_stream_write(stream, "1234567890", 10);
|
||||||
|
@ -2433,7 +2497,7 @@ test_blocked_flags (void)
|
||||||
init_test_ctl_settings(&g_ctl_settings);
|
init_test_ctl_settings(&g_ctl_settings);
|
||||||
g_ctl_settings.tcs_schedule_stream_packets_immediately = 1;
|
g_ctl_settings.tcs_schedule_stream_packets_immediately = 1;
|
||||||
|
|
||||||
init_test_objs(&tobjs, 3, 3);
|
init_test_objs(&tobjs, 3, 3, NULL);
|
||||||
stream = new_stream_ext(&tobjs, 123, 3);
|
stream = new_stream_ext(&tobjs, 123, 3);
|
||||||
nw = lsquic_stream_write(stream, "1234567890", 10);
|
nw = lsquic_stream_write(stream, "1234567890", 10);
|
||||||
assert(("lsquic_stream_write is limited by the send window", 3 == nw));
|
assert(("lsquic_stream_write is limited by the send window", 3 == nw));
|
||||||
|
@ -2465,7 +2529,7 @@ test_forced_flush_when_conn_blocked (void)
|
||||||
init_test_ctl_settings(&g_ctl_settings);
|
init_test_ctl_settings(&g_ctl_settings);
|
||||||
g_ctl_settings.tcs_schedule_stream_packets_immediately = 1;
|
g_ctl_settings.tcs_schedule_stream_packets_immediately = 1;
|
||||||
|
|
||||||
init_test_objs(&tobjs, 3, 0x1000);
|
init_test_objs(&tobjs, 3, 0x1000, NULL);
|
||||||
stream = new_stream(&tobjs, 123);
|
stream = new_stream(&tobjs, 123);
|
||||||
nw = lsquic_stream_write(stream, "1234567890", 10);
|
nw = lsquic_stream_write(stream, "1234567890", 10);
|
||||||
assert(("lsquic_stream_write is limited by the send window", 3 == nw));
|
assert(("lsquic_stream_write is limited by the send window", 3 == nw));
|
||||||
|
@ -2502,7 +2566,7 @@ test_conn_abort (void)
|
||||||
init_test_ctl_settings(&g_ctl_settings);
|
init_test_ctl_settings(&g_ctl_settings);
|
||||||
g_ctl_settings.tcs_schedule_stream_packets_immediately = 1;
|
g_ctl_settings.tcs_schedule_stream_packets_immediately = 1;
|
||||||
|
|
||||||
init_test_objs(&tobjs, 0x1000, 0x1000);
|
init_test_objs(&tobjs, 0x1000, 0x1000, NULL);
|
||||||
my_pf = *tobjs.lconn.cn_pf;
|
my_pf = *tobjs.lconn.cn_pf;
|
||||||
my_pf.pf_gen_stream_frame = my_gen_stream_frame_err;
|
my_pf.pf_gen_stream_frame = my_gen_stream_frame_err;
|
||||||
tobjs.lconn.cn_pf = &my_pf;
|
tobjs.lconn.cn_pf = &my_pf;
|
||||||
|
@ -2540,7 +2604,7 @@ test_bad_packbits_guess_1 (void)
|
||||||
g_ctl_settings.tcs_schedule_stream_packets_immediately = 0;
|
g_ctl_settings.tcs_schedule_stream_packets_immediately = 0;
|
||||||
g_ctl_settings.tcs_guess_packno_bits = PACKNO_LEN_1;
|
g_ctl_settings.tcs_guess_packno_bits = PACKNO_LEN_1;
|
||||||
|
|
||||||
init_test_objs(&tobjs, 0x1000, 0x1000);
|
init_test_objs(&tobjs, 0x1000, 0x1000, NULL);
|
||||||
streams[0] = new_stream(&tobjs, 5);
|
streams[0] = new_stream(&tobjs, 5);
|
||||||
streams[1] = new_stream(&tobjs, 7);
|
streams[1] = new_stream(&tobjs, 7);
|
||||||
streams[2] = new_stream(&tobjs, 9);
|
streams[2] = new_stream(&tobjs, 9);
|
||||||
|
@ -2705,6 +2769,10 @@ main (int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum lsquic_version ver;
|
||||||
|
for (ver = 0; ver < N_LSQVER; ++ver)
|
||||||
|
test_cant_fit_frame(select_pf_by_ver(ver));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -569,7 +569,7 @@ run_test (int i)
|
||||||
len = test->pf->pf_gen_stream_frame(out, min, test->stream_id,
|
len = test->pf->pf_gen_stream_frame(out, min, test->stream_id,
|
||||||
test_ctx.test->offset, stream_tosend_fin(&test_ctx),
|
test_ctx.test->offset, stream_tosend_fin(&test_ctx),
|
||||||
stream_tosend_size(&test_ctx), stream_tosend_read, &test_ctx);
|
stream_tosend_size(&test_ctx), stream_tosend_read, &test_ctx);
|
||||||
assert(-1 == len);
|
assert(len < 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test that it succeeds now: */
|
/* Test that it succeeds now: */
|
||||||
|
|
Loading…
Reference in a new issue