From 1e75f9380e697775c4500cdbba6c8df200a78ca3 Mon Sep 17 00:00:00 2001 From: Dmitri Tikhonov Date: Tue, 16 Oct 2018 09:03:33 -0400 Subject: [PATCH] Release 1.17.0 - [API Change] Packet out Memory Interface (PMI) update: - Split PMI pool return into pmi_release and pmi_return - PMI callbacks take peer_ctx and is_ipv6 arguments - [BUGFIX] Fix use-after-free when certificate is updated - Silence gcc warning in optimized mode by performing useless initialization - cmake: use the standard variable CMAKE_BUILD_TYPE instead of DEVEL_MODE --- BUILD-WINDOWS.md | 4 +- CHANGELOG | 11 +++++ CMakeLists.txt | 16 +++---- include/lsquic.h | 25 ++++++++--- src/liblsquic/lsquic_engine.c | 72 +++++++++++++++++++++++++------ src/liblsquic/lsquic_handshake.c | 35 ++++++++++++--- src/liblsquic/lsquic_packet_out.c | 6 +-- src/liblsquic/lsquic_packet_out.h | 13 +++++- src/liblsquic/lsquic_send_ctl.c | 38 ++++++++++------ test/CMakeLists.txt | 2 +- test/prog.c | 1 + test/test_common.c | 7 +-- test/test_common.h | 4 +- test/unittests/test_elision.c | 6 +-- test/unittests/test_packet_out.c | 2 +- 15 files changed, 178 insertions(+), 64 deletions(-) diff --git a/BUILD-WINDOWS.md b/BUILD-WINDOWS.md index b8c92f4..6e116d5 100644 --- a/BUILD-WINDOWS.md +++ b/BUILD-WINDOWS.md @@ -78,7 +78,7 @@ cmake must be run to prepare to build the software in the top level cloned directory. The dot at the end is required. Begin with the debug version as it includes all of the programs. ``` - cmake -DCMAKE_GENERATOR_PLATFORM=x64 --config Debug -DBUILD_SHARED_LIBS=OFF -DDEVEL_MODE=1 . + cmake -DCMAKE_GENERATOR_PLATFORM=x64 --config Debug -DBUILD_SHARED_LIBS=OFF ``` Visual Studio can now be brought up, and there will be projects in the @@ -93,7 +93,7 @@ environment as they are compiled to different directories. To build the optimized version, repeat the process above with a slightly different cmake command: ``` - cmake -DCMAKE_GENERATOR_PLATFORM=x64 --config Release -DBUILD_SHARED_LIBS=OFF -DDEVEL_MODE=0 . + cmake -DCMAKE_GENERATOR_PLATFORM=x64 --config Release -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release . ``` After cmake has finished, you can open the project, set the solution diff --git a/CHANGELOG b/CHANGELOG index f3f0a5f..7810cba 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,14 @@ +2018-10-16 + - 1.17.0 + - [API Change] Packet out Memory Interface (PMI) update: + - Split PMI pool return into pmi_release and pmi_return + - PMI callbacks take peer_ctx and is_ipv6 arguments + - [BUGFIX] Fix use-after-free when certificate is updated + - Silence gcc warning in optimized mode by performing useless + initialization + - cmake: use the standard variable CMAKE_BUILD_TYPE instead of + DEVEL_MODE + 2018-10-03 - 1.16.0 - [API Change] Add lsquic_conn_n_avail_streams() diff --git a/CMakeLists.txt b/CMakeLists.txt index 4dc7484..4acaec8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,16 +25,12 @@ IF(NOT GLIBC_VERSION EQUAL "" AND GLIBC_VERSION VERSION_LESS 2.17) SET(LIBS ${LIBS} rt) ENDIF() -# By default, we compile in development mode. To compile production code, -# pass -DDEVEL_MODE=0 to cmake (before that, `make clean' and remove any -# cmake cache files). -# -IF(NOT DEFINED DEVEL_MODE) - SET(DEVEL_MODE 1) +IF("${CMAKE_BUILD_TYPE}" STREQUAL "") + SET(CMAKE_BUILD_TYPE Debug) ENDIF() -MESSAGE(STATUS "DEVEL_MODE: ${DEVEL_MODE}") +MESSAGE(STATUS "Build type: ${CMAKE_BUILD_TYPE}") IF (NOT MSVC) @@ -45,7 +41,7 @@ SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -fno-omit-frame-pointer") IF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9.3) SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -Wno-missing-field-initializers") ENDIF() -IF(DEVEL_MODE EQUAL 1) +IF(CMAKE_BUILD_TYPE STREQUAL "Debug") SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -O0 -g3") IF(CMAKE_C_COMPILER MATCHES "clang" AND NOT "$ENV{TRAVIS}" MATCHES "^true$") @@ -78,7 +74,7 @@ ENDIF() #MSVC ELSE() SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -W4 -WX -Zi -DWIN32_LEAN_AND_MEAN -DNOMINMAX -D_CRT_SECURE_NO_WARNINGS -I${CMAKE_CURRENT_SOURCE_DIR}/wincompat") -IF(DEVEL_MODE EQUAL 1) +IF(CMAKE_BUILD_TYPE STREQUAL "Debug") SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -Od") #SET (MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -DFIU_ENABLE=1") #SET(LIBS ${LIBS} fiu) @@ -161,7 +157,7 @@ add_subdirectory(src) add_subdirectory(test) -IF(DEVEL_MODE EQUAL 1) +IF(NOT (CMAKE_C_FLAGS MATCHES "-DNDEBUG")) # Our test framework relies on assertions, only compile if assertions are # enabled. # diff --git a/include/lsquic.h b/include/lsquic.h index fb49dc4..8fb4e73 100644 --- a/include/lsquic.h +++ b/include/lsquic.h @@ -24,7 +24,7 @@ extern "C" { #endif #define LSQUIC_MAJOR_VERSION 1 -#define LSQUIC_MINOR_VERSION 16 +#define LSQUIC_MINOR_VERSION 17 #define LSQUIC_PATCH_VERSION 0 /** @@ -485,16 +485,29 @@ typedef int (*lsquic_packets_out_f)( /** * The packet out memory interface is used by LSQUIC to get buffers to * which outgoing packets will be written before they are passed to - * ea_packets_out callback. pmi_release() is called at some point, - * usually after the packet is sent successfully, to return the buffer - * to the pool. + * ea_packets_out callback. * * If not specified, malloc() and free() are used. */ struct lsquic_packout_mem_if { - void * (*pmi_allocate) (void *pmi_ctx, size_t sz); - void (*pmi_release) (void *pmi_ctx, void *obj); + /** + * Allocate buffer for sending. + */ + void * (*pmi_allocate) (void *pmi_ctx, void *conn_ctx, unsigned short sz, + char is_ipv6); + /** + * This function is used to release the allocated buffer after it is + * sent via @ref ea_packets_out. + */ + void (*pmi_release) (void *pmi_ctx, void *conn_ctx, void *buf, + char is_ipv6); + /** + * If allocated buffer is not going to be sent, return it to the caller + * using this function. + */ + void (*pmi_return) (void *pmi_ctx, void *conn_ctx, void *buf, + char is_ipv6); }; struct stack_st_X509; diff --git a/src/liblsquic/lsquic_engine.c b/src/liblsquic/lsquic_engine.c index b05f32e..ca72a9d 100644 --- a/src/liblsquic/lsquic_engine.c +++ b/src/liblsquic/lsquic_engine.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -244,14 +245,14 @@ lsquic_engine_check_settings (const struct lsquic_engine_settings *settings, static void -free_packet (void *ctx, unsigned char *packet_data) +free_packet (void *ctx, void *conn_ctx, void *packet_data, char is_ipv6) { free(packet_data); } static void * -malloc_buf (void *ctx, size_t size) +malloc_buf (void *ctx, void *conn_ctx, unsigned short size, char is_ipv6) { return malloc(size); } @@ -259,7 +260,7 @@ malloc_buf (void *ctx, size_t size) static const struct lsquic_packout_mem_if stock_pmi = { - malloc_buf, (void(*)(void *, void *)) free_packet, + malloc_buf, free_packet, free_packet, }; @@ -821,6 +822,13 @@ really_encrypt_packet (const lsquic_conn_t *conn, } +static int +conn_peer_ipv6 (const struct lsquic_conn *conn) +{ + return AF_INET6 == ((struct sockaddr *) conn->cn_peer_addr)->sa_family; +} + + static enum { ENCPA_OK, ENCPA_NOMEM, ENCPA_BADCRYPT, } encrypt_packet (lsquic_engine_t *engine, const lsquic_conn_t *conn, lsquic_packet_out_t *packet_out) @@ -829,10 +837,15 @@ encrypt_packet (lsquic_engine_t *engine, const lsquic_conn_t *conn, size_t bufsz; unsigned sent_sz; unsigned char *buf; + int ipv6; bufsz = conn->cn_pf->pf_packout_header_size(conn, packet_out->po_flags) + packet_out->po_data_sz + QUIC_PACKET_HASH_SZ; - buf = engine->pub.enp_pmi->pmi_allocate(engine->pub.enp_pmi_ctx, bufsz); + if (bufsz > USHRT_MAX) + return ENCPA_BADCRYPT; /* To cause connection to close */ + ipv6 = conn_peer_ipv6(conn); + buf = engine->pub.enp_pmi->pmi_allocate(engine->pub.enp_pmi_ctx, + conn->cn_peer_ctx, bufsz, ipv6); if (!buf) { LSQ_DEBUG("could not allocate memory for outgoing packet of size %zd", @@ -847,19 +860,51 @@ encrypt_packet (lsquic_engine_t *engine, const lsquic_conn_t *conn, if (enc_sz < 0) { - engine->pub.enp_pmi->pmi_release(engine->pub.enp_pmi_ctx, buf); + engine->pub.enp_pmi->pmi_return(engine->pub.enp_pmi_ctx, + conn->cn_peer_ctx, buf, ipv6); return ENCPA_BADCRYPT; } packet_out->po_enc_data = buf; packet_out->po_enc_data_sz = enc_sz; packet_out->po_sent_sz = sent_sz; - packet_out->po_flags |= PO_ENCRYPTED|PO_SENT_SZ; + packet_out->po_flags &= ~PO_IPv6; + packet_out->po_flags |= PO_ENCRYPTED|PO_SENT_SZ|(ipv6 << POIPv6_SHIFT); return ENCPA_OK; } +static void +release_or_return_enc_data (struct lsquic_engine *engine, + void (*pmi_rel_or_ret) (void *, void *, void *, char), + struct lsquic_conn *conn, struct lsquic_packet_out *packet_out) +{ + pmi_rel_or_ret(engine->pub.enp_pmi_ctx, conn->cn_peer_ctx, + packet_out->po_enc_data, lsquic_packet_out_ipv6(packet_out)); + packet_out->po_flags &= ~PO_ENCRYPTED; + packet_out->po_enc_data = NULL; +} + + +static void +release_enc_data (struct lsquic_engine *engine, struct lsquic_conn *conn, + struct lsquic_packet_out *packet_out) +{ + release_or_return_enc_data(engine, engine->pub.enp_pmi->pmi_release, + conn, packet_out); +} + + +static void +return_enc_data (struct lsquic_engine *engine, struct lsquic_conn *conn, + struct lsquic_packet_out *packet_out) +{ + release_or_return_enc_data(engine, engine->pub.enp_pmi->pmi_return, + conn, packet_out); +} + + STAILQ_HEAD(conns_stailq, lsquic_conn); TAILQ_HEAD(conns_tailq, lsquic_conn); @@ -1006,12 +1051,7 @@ send_batch (lsquic_engine_t *engine, struct conns_out_iter *conns_iter, * or until it times out and regenerated. */ if (batch->packets[i]->po_flags & PO_ENCRYPTED) - { - batch->packets[i]->po_flags &= ~PO_ENCRYPTED; - engine->pub.enp_pmi->pmi_release(engine->pub.enp_pmi_ctx, - batch->packets[i]->po_enc_data); - batch->packets[i]->po_enc_data = NULL; /* JIC */ - } + release_enc_data(engine, batch->conns[i], batch->packets[i]); } if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) for ( ; i < (int) n_to_send; ++i) @@ -1074,6 +1114,14 @@ send_packets_out (struct lsquic_engine *engine, coi_deactivate(&conns_iter, conn); continue; } + if ((packet_out->po_flags & PO_ENCRYPTED) + && lsquic_packet_out_ipv6(packet_out) != conn_peer_ipv6(conn)) + { + /* Peer address changed since the packet was encrypted. Need to + * reallocate. + */ + return_enc_data(engine, conn, packet_out); + } if (!(packet_out->po_flags & (PO_ENCRYPTED|PO_NOENCRYPT))) { switch (encrypt_packet(engine, conn, packet_out)) diff --git a/src/liblsquic/lsquic_handshake.c b/src/liblsquic/lsquic_handshake.c index 3c0e1d9..31788ba 100644 --- a/src/liblsquic/lsquic_handshake.c +++ b/src/liblsquic/lsquic_handshake.c @@ -173,6 +173,7 @@ static void free_info (lsquic_session_cache_info_t *); /* client */ static cert_hash_item_t *make_cert_hash_item(struct lsquic_str *domain, struct lsquic_str **certs, int count); static int c_insert_certs(cert_hash_item_t *item); +static void c_erase_certs(struct lsquic_hash_elem *el); static void c_free_cert_hash_item (cert_hash_item_t *item); static int get_tag_val_u32 (unsigned char *v, int len, uint32_t *val); @@ -265,16 +266,23 @@ static int init_hs_hash_tables(int flags) /* client */ -cert_hash_item_t * -c_find_certs (const lsquic_str_t *domain) +struct lsquic_hash_elem * +c_get_certs_elem (const lsquic_str_t *domain) { - struct lsquic_hash_elem *el; - if (!s_cached_client_certs) return NULL; - el = lsquic_hash_find(s_cached_client_certs, lsquic_str_cstr(domain), + return lsquic_hash_find(s_cached_client_certs, lsquic_str_cstr(domain), lsquic_str_len(domain)); +} + + +/* client */ +cert_hash_item_t * +c_find_certs (const lsquic_str_t *domain) +{ + struct lsquic_hash_elem *el = c_get_certs_elem(domain); + if (el == NULL) return NULL; @@ -335,6 +343,15 @@ c_insert_certs (cert_hash_item_t *item) } +/* client */ +static void +c_erase_certs (struct lsquic_hash_elem *el) +{ + if (s_cached_client_certs && el) + lsquic_hash_erase(s_cached_client_certs, el); +} + + static int save_session_info_entry(lsquic_str_t *key, lsquic_session_cache_info_t *entry) { lsquic_str_setto(&entry->sni_key, lsquic_str_cstr(key), lsquic_str_len(key)); @@ -1364,7 +1381,11 @@ lsquic_enc_session_handle_chlo_reply (lsquic_enc_session_t *enc_session, int ret; lsquic_session_cache_info_t *info = enc_session->info; hs_ctx_t * hs_ctx = &enc_session->hs_ctx; - cert_hash_item_t *cached_certs_item = c_find_certs(&hs_ctx->sni); + cert_hash_item_t *cached_certs_item = NULL; + struct lsquic_hash_elem *el = c_get_certs_elem(&hs_ctx->sni); + + if (el) + cached_certs_item = lsquic_hashelem_getdata(el); /* FIXME get the number first */ lsquic_str_t **out_certs = NULL; @@ -1427,6 +1448,8 @@ lsquic_enc_session_handle_chlo_reply (lsquic_enc_session_t *enc_session, ; else { + if (el) + c_erase_certs(el); if (cached_certs_item) c_free_cert_hash_item(cached_certs_item); diff --git a/src/liblsquic/lsquic_packet_out.c b/src/liblsquic/lsquic_packet_out.c index a422756..053eb2f 100644 --- a/src/liblsquic/lsquic_packet_out.c +++ b/src/liblsquic/lsquic_packet_out.c @@ -279,7 +279,7 @@ lsquic_packet_out_new (struct lsquic_mm *mm, struct malo *malo, int use_cid, void lsquic_packet_out_destroy (lsquic_packet_out_t *packet_out, - struct lsquic_engine_public *enpub) + struct lsquic_engine_public *enpub, void *peer_ctx) { if (packet_out->po_flags & PO_SREC_ARR) { @@ -292,8 +292,8 @@ lsquic_packet_out_destroy (lsquic_packet_out_t *packet_out, } } if (packet_out->po_flags & PO_ENCRYPTED) - enpub->enp_pmi->pmi_release(enpub->enp_pmi_ctx, - packet_out->po_enc_data); + enpub->enp_pmi->pmi_release(enpub->enp_pmi_ctx, peer_ctx, + packet_out->po_enc_data, lsquic_packet_out_ipv6(packet_out)); if (packet_out->po_nonce) free(packet_out->po_nonce); lsquic_mm_put_packet_out(&enpub->enp_mm, packet_out); diff --git a/src/liblsquic/lsquic_packet_out.h b/src/liblsquic/lsquic_packet_out.h index a6e7503..0d5981f 100644 --- a/src/liblsquic/lsquic_packet_out.h +++ b/src/liblsquic/lsquic_packet_out.h @@ -90,6 +90,10 @@ typedef struct lsquic_packet_out #define POLEV_SHIFT 18 PO_BITS_2 = (1 <<18), /* PO_BITS_2 and PO_BITS_3 encode the */ PO_BITS_3 = (1 <<19), /* crypto level. Used for logging. */ +#define POIPv6_SHIFT 20 + PO_IPv6 = (1 <<20), /* Set if pmi_allocate was passed is_ipv6=1, + * otherwise unset. + */ } po_flags; enum quic_ft_bit po_frame_types:16; /* Bitmask of QUIC_FRAME_* */ unsigned short po_data_sz; /* Number of usable bytes in data */ @@ -142,6 +146,13 @@ typedef struct lsquic_packet_out (p)->po_flags |= ((b) & 0x3) << POBIT_SHIFT; \ } while (0) +#define lsquic_packet_out_ipv6(p) ((int)(((p)->po_flags >> POIPv6_SHIFT) & 1)) + +#define lsquic_packet_out_set_ipv6(p, b) do { \ + (p)->po_flags &= ~(1 << POIPv6_SHIFT); \ + (p)->po_flags |= ((b) & 1) << POIPv6_SHIFT; \ +} while (0) + #define lsquic_po_header_length(lconn, po_flags) ( \ lconn->cn_pf->pf_packout_header_size(lconn, po_flags)) @@ -198,7 +209,7 @@ lsquic_packet_out_new (struct lsquic_mm *, struct malo *, int use_cid, void lsquic_packet_out_destroy (lsquic_packet_out_t *, - struct lsquic_engine_public *); + struct lsquic_engine_public *, void *peer_ctx); int lsquic_packet_out_add_stream (lsquic_packet_out_t *packet_out, diff --git a/src/liblsquic/lsquic_send_ctl.c b/src/liblsquic/lsquic_send_ctl.c index 48093cb..d4585f5 100644 --- a/src/liblsquic/lsquic_send_ctl.c +++ b/src/liblsquic/lsquic_send_ctl.c @@ -528,12 +528,22 @@ send_ctl_release_enc_data (struct lsquic_send_ctl *ctl, struct lsquic_packet_out *packet_out) { ctl->sc_enpub->enp_pmi->pmi_release(ctl->sc_enpub->enp_pmi_ctx, - packet_out->po_enc_data); + ctl->sc_conn_pub->lconn->cn_peer_ctx, packet_out->po_enc_data, + lsquic_packet_out_ipv6(packet_out)); packet_out->po_flags &= ~PO_ENCRYPTED; packet_out->po_enc_data = NULL; } +static void +send_ctl_destroy_packet (struct lsquic_send_ctl *ctl, + struct lsquic_packet_out *packet_out) +{ + lsquic_packet_out_destroy(packet_out, ctl->sc_enpub, + ctl->sc_conn_pub->lconn->cn_peer_ctx); +} + + /* Returns true if packet was rescheduled, false otherwise. In the latter * case, you should not dereference packet_out after the function returns. */ @@ -564,7 +574,7 @@ send_ctl_handle_lost_packet (lsquic_send_ctl_t *ctl, { LSQ_DEBUG("lost unretransmittable packet %"PRIu64, packet_out->po_packno); - lsquic_packet_out_destroy(packet_out, ctl->sc_enpub); + send_ctl_destroy_packet(ctl, packet_out); return 0; } } @@ -754,7 +764,7 @@ lsquic_send_ctl_got_ack (lsquic_send_ctl_t *ctl, lsquic_cubic_ack(&ctl->sc_cubic, now, now - packet_out->po_sent, app_limited, packet_sz); lsquic_packet_out_ack_streams(packet_out); - lsquic_packet_out_destroy(packet_out, ctl->sc_enpub); + send_ctl_destroy_packet(ctl, packet_out); } packet_out = next; } @@ -853,7 +863,7 @@ lsquic_send_ctl_cleanup (lsquic_send_ctl_t *ctl) while ((packet_out = TAILQ_FIRST(&ctl->sc_scheduled_packets))) { send_ctl_sched_remove(ctl, packet_out); - lsquic_packet_out_destroy(packet_out, ctl->sc_enpub); + send_ctl_destroy_packet(ctl, packet_out); } assert(0 == ctl->sc_n_scheduled); assert(0 == ctl->sc_bytes_scheduled); @@ -861,7 +871,7 @@ lsquic_send_ctl_cleanup (lsquic_send_ctl_t *ctl) { TAILQ_REMOVE(&ctl->sc_unacked_packets, packet_out, po_next); ctl->sc_bytes_unacked_all -= packet_out_total_sz(packet_out); - lsquic_packet_out_destroy(packet_out, ctl->sc_enpub); + send_ctl_destroy_packet(ctl, packet_out); --ctl->sc_n_in_flight_all; } assert(0 == ctl->sc_n_in_flight_all); @@ -869,7 +879,7 @@ lsquic_send_ctl_cleanup (lsquic_send_ctl_t *ctl) while ((packet_out = TAILQ_FIRST(&ctl->sc_lost_packets))) { TAILQ_REMOVE(&ctl->sc_lost_packets, packet_out, po_next); - lsquic_packet_out_destroy(packet_out, ctl->sc_enpub); + send_ctl_destroy_packet(ctl, packet_out); } pacer_cleanup(&ctl->sc_pacer); #if LSQUIC_SEND_STATS @@ -1100,7 +1110,7 @@ lsquic_send_ctl_next_packet_to_send (lsquic_send_ctl_t *ctl) { LSQ_DEBUG("Dropping packet %"PRIu64" from scheduled queue", packet_out->po_packno); - lsquic_packet_out_destroy(packet_out, ctl->sc_enpub); + send_ctl_destroy_packet(ctl, packet_out); goto get_packet; } } @@ -1166,7 +1176,7 @@ send_ctl_allocate_packet (lsquic_send_ctl_t *ctl, enum lsquic_packno_bits bits, LSQ_ERROR("wanted to allocate packet with at least %u bytes of " "payload, but only got %u bytes (mtu: %u bytes)", need_at_least, lsquic_packet_out_avail(packet_out), ctl->sc_pack_size); - lsquic_packet_out_destroy(packet_out, ctl->sc_enpub); + send_ctl_destroy_packet(ctl, packet_out); return NULL; } @@ -1311,7 +1321,7 @@ lsquic_send_ctl_reschedule_packets (lsquic_send_ctl_t *ctl) { LSQ_DEBUG("Dropping packet %"PRIu64" from unacked queue", packet_out->po_packno); - lsquic_packet_out_destroy(packet_out, ctl->sc_enpub); + send_ctl_destroy_packet(ctl, packet_out); } } @@ -1373,7 +1383,7 @@ lsquic_send_ctl_elide_stream_frames (lsquic_send_ctl_t *ctl, uint32_t stream_id) LSQ_DEBUG("cancel packet %"PRIu64" after eliding frames for " "stream %"PRIu32, packet_out->po_packno, stream_id); send_ctl_sched_remove(ctl, packet_out); - lsquic_packet_out_destroy(packet_out, ctl->sc_enpub); + send_ctl_destroy_packet(ctl, packet_out); ++dropped; } } @@ -1398,7 +1408,7 @@ lsquic_send_ctl_elide_stream_frames (lsquic_send_ctl_t *ctl, uint32_t stream_id) TAILQ_REMOVE(&ctl->sc_buffered_packets[n].bpq_packets, packet_out, po_next); --ctl->sc_buffered_packets[n].bpq_count; - lsquic_packet_out_destroy(packet_out, ctl->sc_enpub); + send_ctl_destroy_packet(ctl, packet_out); LSQ_DEBUG("Elide packet from buffered queue #%u; count: %u", n, ctl->sc_buffered_packets[n].bpq_count); } @@ -1508,7 +1518,7 @@ lsquic_send_ctl_squeeze_sched (lsquic_send_ctl_t *ctl) send_ctl_sched_remove(ctl, packet_out); LSQ_DEBUG("Dropping packet %"PRIu64" from scheduled queue", packet_out->po_packno); - lsquic_packet_out_destroy(packet_out, ctl->sc_enpub); + send_ctl_destroy_packet(ctl, packet_out); ++dropped; } } @@ -1560,7 +1570,7 @@ lsquic_send_ctl_drop_scheduled (lsquic_send_ctl_t *ctl) while ((packet_out = TAILQ_FIRST(&ctl->sc_scheduled_packets))) { send_ctl_sched_remove(ctl, packet_out); - lsquic_packet_out_destroy(packet_out, ctl->sc_enpub); + send_ctl_destroy_packet(ctl, packet_out); } assert(0 == ctl->sc_n_scheduled); ctl->sc_cur_packno = lsquic_senhist_largest(&ctl->sc_senhist); @@ -1743,7 +1753,7 @@ split_buffered_packet (lsquic_send_ctl_t *ctl, } else { - lsquic_packet_out_destroy(packet_out, ctl->sc_enpub); + send_ctl_destroy_packet(ctl, packet_out); return -1; } } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 1451a88..73f4373 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -21,7 +21,7 @@ CHECK_INCLUDE_FILES(regex.h HAVE_REGEX) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/test_config.h.in ${CMAKE_CURRENT_SOURCE_DIR}/test_config.h) -IF(DEVEL_MODE EQUAL 1) +IF(NOT (CMAKE_C_FLAGS MATCHES "-DNDEBUG")) # Our test framework relies on assertions, only compile if assertions are # enabled. # diff --git a/test/prog.c b/test/prog.c index 3e628a7..f3b2c8c 100644 --- a/test/prog.c +++ b/test/prog.c @@ -32,6 +32,7 @@ static int prog_stopped; static const struct lsquic_packout_mem_if pmi = { .pmi_allocate = pba_allocate, .pmi_release = pba_release, + .pmi_return = pba_release, }; diff --git a/test/test_common.c b/test/test_common.c index f68a5db..c3a59c3 100644 --- a/test/test_common.c +++ b/test/test_common.c @@ -1133,14 +1133,15 @@ pba_init (struct packout_buf_allocator *pba, unsigned max) void * -pba_allocate (void *packout_buf_allocator, size_t size) +pba_allocate (void *packout_buf_allocator, void *peer_ctx, unsigned short size, + char is_ipv6) { struct packout_buf_allocator *const pba = packout_buf_allocator; struct packout_buf *pb; if (size > MAX_PACKOUT_BUF_SZ) { - fprintf(stderr, "packout buf size too large: %zd", size); + fprintf(stderr, "packout buf size too large: %hu", size); abort(); } @@ -1165,7 +1166,7 @@ pba_allocate (void *packout_buf_allocator, size_t size) void -pba_release (void *packout_buf_allocator, void *obj) +pba_release (void *packout_buf_allocator, void *peer_ctx, void *obj, char ipv6) { struct packout_buf_allocator *const pba = packout_buf_allocator; struct packout_buf *const pb = obj; diff --git a/test/test_common.h b/test/test_common.h index dc3fc99..18aa7df 100644 --- a/test/test_common.h +++ b/test/test_common.h @@ -87,10 +87,10 @@ void pba_init (struct packout_buf_allocator *, unsigned max); void * -pba_allocate (void *packout_buf_allocator, size_t); +pba_allocate (void *packout_buf_allocator, void*, unsigned short, char); void -pba_release (void *packout_buf_allocator, void *obj); +pba_release (void *packout_buf_allocator, void *, void *obj, char); void pba_cleanup (struct packout_buf_allocator *); diff --git a/test/unittests/test_elision.c b/test/unittests/test_elision.c index ffd4199..3b58a05 100644 --- a/test/unittests/test_elision.c +++ b/test/unittests/test_elision.c @@ -116,7 +116,7 @@ elide_single_stream_frame (void) assert(0 == packet_out->po_frame_types); assert(!posi_first(&posi, packet_out)); - lsquic_packet_out_destroy(packet_out, &enpub); + lsquic_packet_out_destroy(packet_out, &enpub, NULL); lsquic_mm_cleanup(&enpub.enp_mm); } @@ -309,8 +309,8 @@ elide_three_stream_frames (int chop_regen) srec = posi_next(&posi); assert(!srec); - lsquic_packet_out_destroy(packet_out, &enpub); - lsquic_packet_out_destroy(ref_out, &enpub); + lsquic_packet_out_destroy(packet_out, &enpub, NULL); + lsquic_packet_out_destroy(ref_out, &enpub, NULL); lsquic_mm_cleanup(&enpub.enp_mm); } diff --git a/test/unittests/test_packet_out.c b/test/unittests/test_packet_out.c index 3418e5e..4b4c85c 100644 --- a/test/unittests/test_packet_out.c +++ b/test/unittests/test_packet_out.c @@ -83,7 +83,7 @@ main (void) assert((void *) 0 == posi_next(&posi)); - lsquic_packet_out_destroy(packet_out, &enpub); + lsquic_packet_out_destroy(packet_out, &enpub, NULL); assert(!lsquic_malo_first(enpub.enp_mm.malo.stream_rec_arr)); lsquic_mm_cleanup(&enpub.enp_mm);