mirror of
https://github.com/openssl/openssl.git
synced 2024-12-15 04:53:52 +08:00
QUIC RX: Support refcounted packets and eliminate wrapper
Previously, the QRX filled in a OSSL_QRX_PKT structure provided by the caller. This necessitated the caller managing reference counting itself using a OSSL_QRX_PKT_WRAP structure. The need for this structure has been eliminated by adding refcounting support to the QRX itself. The QRX now outputs a pointer to an OSSL_QRX_PKT instead of filling in a structure provided by the caller. The OSSL_QRX_PKT_WRAP structure has been eliminated. Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/19703)
This commit is contained in:
parent
f71ae05a4d
commit
6d5d5fc9a9
@ -197,9 +197,6 @@ int ossl_qrx_discard_enc_level(OSSL_QRX *qrx, uint32_t enc_level);
|
||||
|
||||
/* Information about a received packet. */
|
||||
typedef struct ossl_qrx_pkt_st {
|
||||
/* Opaque handle to be passed to ossl_qrx_release_pkt. */
|
||||
void *handle;
|
||||
|
||||
/*
|
||||
* Points to a logical representation of the decoded QUIC packet header. The
|
||||
* data and len fields point to the decrypted QUIC payload (i.e., to a
|
||||
@ -236,26 +233,35 @@ typedef struct ossl_qrx_pkt_st {
|
||||
* using a now() function.
|
||||
*/
|
||||
OSSL_TIME time;
|
||||
|
||||
/* The QRX which was used to receive the packet. */
|
||||
OSSL_QRX *qrx;
|
||||
} OSSL_QRX_PKT;
|
||||
|
||||
/*
|
||||
* Tries to read a new decrypted packet from the QRX.
|
||||
*
|
||||
* On success, all fields of *pkt are filled and 1 is returned.
|
||||
* Else, returns 0.
|
||||
* On success, *pkt points to a OSSL_QRX_PKT structure. The structure should be
|
||||
* freed when no longer needed by calling ossl_qrx_pkt_release(). The structure
|
||||
* is refcounted; to gain extra references, call ossl_qrx_pkt_ref(). This will
|
||||
* cause a corresponding number of calls to ossl_qrx_pkt_release() to be
|
||||
* ignored.
|
||||
*
|
||||
* The resources referenced by pkt->hdr, pkt->hdr->data and pkt->peer will
|
||||
* remain allocated at least until the user frees them by calling
|
||||
* ossl_qrx_release_pkt, which must be called once you are done with the packet.
|
||||
* The resources referenced by (*pkt)->hdr, (*pkt)->hdr->data and (*pkt)->peer
|
||||
* have the same lifetime as *pkt.
|
||||
*
|
||||
* Returns 1 on success and 0 on failure.
|
||||
*/
|
||||
int ossl_qrx_read_pkt(OSSL_QRX *qrx, OSSL_QRX_PKT *pkt);
|
||||
int ossl_qrx_read_pkt(OSSL_QRX *qrx, OSSL_QRX_PKT **pkt);
|
||||
|
||||
/*
|
||||
* Release the resources pointed to by an OSSL_QRX_PKT returned by
|
||||
* ossl_qrx_read_pkt. Pass the opaque value pkt->handle returned in the
|
||||
* structure.
|
||||
* Decrement the reference count for the given packet and frees it if the
|
||||
* reference count drops to zero. No-op if pkt is NULL.
|
||||
*/
|
||||
void ossl_qrx_release_pkt(OSSL_QRX *qrx, void *handle);
|
||||
void ossl_qrx_pkt_release(OSSL_QRX_PKT *pkt);
|
||||
|
||||
/* Increments the reference count for the given packet. */
|
||||
void ossl_qrx_pkt_up_ref(OSSL_QRX_PKT *pkt);
|
||||
|
||||
/*
|
||||
* Returns 1 if there are any already processed (i.e. decrypted) packets waiting
|
||||
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#ifndef OSSL_QUIC_RECORD_RX_WRAP_H
|
||||
# define OSSL_QUIC_RECORD_RX_WRAP_H
|
||||
|
||||
# include <openssl/crypto.h>
|
||||
# include "internal/refcount.h"
|
||||
# include "internal/quic_record_rx.h"
|
||||
|
||||
/*
|
||||
* OSSL_QRX_PKT handle wrapper for counted references
|
||||
* ==================================================
|
||||
*
|
||||
* When OSSL_QRX_PKT handles need to be put "in the wild", there may be
|
||||
* multiple references, which must be accounted for so that the OSSL_QRX_PKT
|
||||
* data isn't prematurely destroyed.
|
||||
* The OSSL_QRX_PKT itself is less important for reference counting, since
|
||||
* its handle contains references to all important data.
|
||||
*
|
||||
* The wrapper is created by ossl_quic_depacketize().
|
||||
* Consumers must call ossl_qrx_pkt_wrap_up_ref() as they grab a reference,
|
||||
* and must call ossl_qrx_pkt_wrap_release() when letting go of a reference.
|
||||
*/
|
||||
|
||||
typedef struct ossl_qrx_pkt_wrap_st {
|
||||
void *handle; /* This is a copy of |pkt->handle| */
|
||||
OSSL_QRX_PKT *pkt;
|
||||
CRYPTO_REF_COUNT references;
|
||||
CRYPTO_RWLOCK *lock; /* For reference counting without atomic */
|
||||
} OSSL_QRX_PKT_WRAP;
|
||||
|
||||
OSSL_QRX_PKT_WRAP *ossl_qrx_pkt_wrap_new(OSSL_QRX_PKT *pkt);
|
||||
int ossl_qrx_pkt_wrap_up_ref(OSSL_QRX_PKT_WRAP *pkt_wrap);
|
||||
void ossl_qrx_pkt_wrap_free(OSSL_QRX *qrx, OSSL_QRX_PKT_WRAP *pkt_wrap);
|
||||
|
||||
#endif
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include "internal/common.h"
|
||||
#include "internal/uint_set.h"
|
||||
#include "internal/quic_record_rx.h"
|
||||
|
||||
/*
|
||||
* Stream frame list
|
||||
@ -38,7 +39,6 @@
|
||||
typedef struct stream_frame_st STREAM_FRAME;
|
||||
|
||||
typedef struct sframe_list_st {
|
||||
OSSL_QRX *qrx;
|
||||
STREAM_FRAME *head, *tail;
|
||||
/* Is the tail frame final. */
|
||||
unsigned int fin;
|
||||
@ -48,10 +48,10 @@ typedef struct sframe_list_st {
|
||||
uint64_t offset;
|
||||
} SFRAME_LIST;
|
||||
|
||||
void ossl_sframe_list_init(SFRAME_LIST *fl, OSSL_QRX *qrx);
|
||||
void ossl_sframe_list_init(SFRAME_LIST *fl);
|
||||
void ossl_sframe_list_destroy(SFRAME_LIST *fl);
|
||||
int ossl_sframe_list_insert(SFRAME_LIST *fl, UINT_RANGE *range,
|
||||
OSSL_QRX_PKT_WRAP *pkt,
|
||||
OSSL_QRX_PKT *pkt,
|
||||
const unsigned char *data, int fin);
|
||||
int ossl_sframe_list_peek(const SFRAME_LIST *fl, void **iter,
|
||||
UINT_RANGE *range, const unsigned char **data,
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "internal/quic_wire.h"
|
||||
#include "internal/quic_record_tx.h"
|
||||
#include "internal/quic_record_rx.h"
|
||||
#include "internal/quic_record_rx_wrap.h"
|
||||
#include "internal/quic_fc.h"
|
||||
#include "internal/quic_statm.h"
|
||||
|
||||
@ -296,7 +295,7 @@ typedef struct quic_rstream_st QUIC_RSTREAM;
|
||||
* If they are non-NULL, the `rxfc` is called when receive stream data
|
||||
* is read by application. `statm` is queried for current rtt.
|
||||
*/
|
||||
QUIC_RSTREAM *ossl_quic_rstream_new(OSSL_QRX *qrx, QUIC_RXFC *rxfc,
|
||||
QUIC_RSTREAM *ossl_quic_rstream_new(QUIC_RXFC *rxfc,
|
||||
OSSL_STATM *statm);
|
||||
|
||||
/*
|
||||
@ -314,7 +313,7 @@ void ossl_quic_rstream_free(QUIC_RSTREAM *qrs);
|
||||
* Or to indicate `fin` without any further data added to the stream.
|
||||
*/
|
||||
|
||||
int ossl_quic_rstream_queue_data(QUIC_RSTREAM *qrs, OSSL_QRX_PKT_WRAP *pkt_wrap,
|
||||
int ossl_quic_rstream_queue_data(QUIC_RSTREAM *qrs, OSSL_QRX_PKT *pkt,
|
||||
uint64_t offset,
|
||||
const unsigned char *data, uint64_t data_len,
|
||||
int fin);
|
||||
|
@ -3,10 +3,9 @@ $LIBSSL=../../libssl
|
||||
SOURCE[$LIBSSL]=quic_method.c quic_impl.c quic_wire.c quic_ackm.c quic_statm.c
|
||||
SOURCE[$LIBSSL]=cc_dummy.c quic_demux.c quic_record_rx.c
|
||||
SOURCE[$LIBSSL]=quic_record_tx.c quic_record_util.c quic_record_shared.c quic_wire_pkt.c
|
||||
SOURCE[$LIBSSL]=quic_record_rx_wrap.c quic_rx_depack.c
|
||||
SOURCE[$LIBSSL]=quic_fc.c uint_set.c quic_sf_list.c quic_rstream.c quic_sstream.c
|
||||
SOURCE[$LIBSSL]=quic_rx_depack.c
|
||||
SOURCE[$LIBSSL]=quic_fc.c uint_set.c
|
||||
SOURCE[$LIBSSL]=quic_cfq.c quic_txpim.c quic_fifd.c quic_txp.c
|
||||
SOURCE[$LIBSSL]=quic_stream_map.c
|
||||
SOURCE[$LIBSSL]=quic_sf_list.c quic_rstream.c quic_sstream.c
|
||||
SOURCE[$LIBSSL]=quic_sf_list.c quic_rstream.c quic_sstream.c
|
||||
SOURCE[$LIBSSL]=quic_dummy_handshake.c
|
||||
|
@ -42,7 +42,8 @@ typedef struct rxe_st RXE;
|
||||
|
||||
struct rxe_st {
|
||||
OSSL_LIST_MEMBER(rxe, RXE);
|
||||
size_t data_len, alloc_len;
|
||||
OSSL_QRX_PKT pkt;
|
||||
size_t data_len, alloc_len, refcount;
|
||||
|
||||
/* Extra fields for per-packet information. */
|
||||
QUIC_PKT_HDR hdr; /* data/len are decrypted payload */
|
||||
@ -329,6 +330,7 @@ static RXE *qrx_alloc_rxe(size_t alloc_len)
|
||||
ossl_list_rxe_init_elem(rxe);
|
||||
rxe->alloc_len = alloc_len;
|
||||
rxe->data_len = 0;
|
||||
rxe->refcount = 0;
|
||||
return rxe;
|
||||
}
|
||||
|
||||
@ -414,6 +416,9 @@ static void qrx_recycle_rxe(OSSL_QRX *qrx, RXE *rxe)
|
||||
{
|
||||
/* RXE should not be in any list */
|
||||
assert(ossl_list_rxe_prev(rxe) == NULL && ossl_list_rxe_next(rxe) == NULL);
|
||||
rxe->pkt.hdr = NULL;
|
||||
rxe->pkt.peer = NULL;
|
||||
rxe->pkt.local = NULL;
|
||||
ossl_list_rxe_insert_tail(&qrx->rx_free, rxe);
|
||||
}
|
||||
|
||||
@ -1054,7 +1059,7 @@ static int qrx_process_pending_urxl(OSSL_QRX *qrx)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ossl_qrx_read_pkt(OSSL_QRX *qrx, OSSL_QRX_PKT *pkt)
|
||||
int ossl_qrx_read_pkt(OSSL_QRX *qrx, OSSL_QRX_PKT **ppkt)
|
||||
{
|
||||
RXE *rxe;
|
||||
|
||||
@ -1070,25 +1075,41 @@ int ossl_qrx_read_pkt(OSSL_QRX *qrx, OSSL_QRX_PKT *pkt)
|
||||
if (!ossl_assert(rxe != NULL))
|
||||
return 0;
|
||||
|
||||
pkt->handle = rxe;
|
||||
pkt->hdr = &rxe->hdr;
|
||||
pkt->pn = rxe->pn;
|
||||
pkt->time = rxe->time;
|
||||
pkt->datagram_len = rxe->datagram_len;
|
||||
pkt->peer
|
||||
assert(rxe->refcount == 0);
|
||||
rxe->refcount = 1;
|
||||
|
||||
rxe->pkt.hdr = &rxe->hdr;
|
||||
rxe->pkt.pn = rxe->pn;
|
||||
rxe->pkt.time = rxe->time;
|
||||
rxe->pkt.datagram_len = rxe->datagram_len;
|
||||
rxe->pkt.peer
|
||||
= BIO_ADDR_family(&rxe->peer) != AF_UNSPEC ? &rxe->peer : NULL;
|
||||
pkt->local
|
||||
rxe->pkt.local
|
||||
= BIO_ADDR_family(&rxe->local) != AF_UNSPEC ? &rxe->local : NULL;
|
||||
rxe->pkt.qrx = qrx;
|
||||
*ppkt = &rxe->pkt;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ossl_qrx_release_pkt(OSSL_QRX *qrx, void *handle)
|
||||
void ossl_qrx_pkt_release(OSSL_QRX_PKT *pkt)
|
||||
{
|
||||
if (handle != NULL) {
|
||||
RXE *rxe = handle;
|
||||
RXE *rxe;
|
||||
|
||||
qrx_recycle_rxe(qrx, rxe);
|
||||
}
|
||||
if (pkt == NULL)
|
||||
return;
|
||||
|
||||
rxe = (RXE *)pkt;
|
||||
assert(rxe->refcount > 0);
|
||||
if (--rxe->refcount == 0)
|
||||
qrx_recycle_rxe(pkt->qrx, rxe);
|
||||
}
|
||||
|
||||
void ossl_qrx_pkt_up_ref(OSSL_QRX_PKT *pkt)
|
||||
{
|
||||
RXE *rxe = (RXE *)pkt;
|
||||
|
||||
assert(rxe->refcount > 0);
|
||||
++rxe->refcount;
|
||||
}
|
||||
|
||||
uint64_t ossl_qrx_get_bytes_received(OSSL_QRX *qrx, int clear)
|
||||
|
@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/refcount.h"
|
||||
#include "internal/quic_record_rx_wrap.h"
|
||||
|
||||
OSSL_QRX_PKT_WRAP *ossl_qrx_pkt_wrap_new(OSSL_QRX_PKT *pkt)
|
||||
{
|
||||
CRYPTO_RWLOCK *refcount_lock = NULL;
|
||||
OSSL_QRX_PKT_WRAP *res = NULL;
|
||||
|
||||
if (pkt == NULL)
|
||||
return NULL;
|
||||
|
||||
#ifdef HAVE_ATOMICS
|
||||
refcount_lock = CRYPTO_THREAD_lock_new();
|
||||
if (refcount_lock == NULL) {
|
||||
ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((res = OPENSSL_zalloc(sizeof(*res))) == NULL) {
|
||||
CRYPTO_THREAD_lock_free(refcount_lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
res->pkt = pkt;
|
||||
res->handle = pkt->handle;
|
||||
res->references = 1;
|
||||
res->lock = refcount_lock;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int ossl_qrx_pkt_wrap_up_ref(OSSL_QRX_PKT_WRAP *pkt_wrap)
|
||||
{
|
||||
int ref = 0;
|
||||
|
||||
if (pkt_wrap == NULL || pkt_wrap->pkt == NULL)
|
||||
return 0;
|
||||
CRYPTO_UP_REF(&pkt_wrap->references, &ref, pkt_wrap->lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ossl_qrx_pkt_wrap_free(OSSL_QRX *qrx, OSSL_QRX_PKT_WRAP *pkt_wrap)
|
||||
{
|
||||
int ref = 0;
|
||||
|
||||
if (pkt_wrap == NULL)
|
||||
return;
|
||||
CRYPTO_DOWN_REF(&pkt_wrap->references, &ref, pkt_wrap->lock);
|
||||
if (ref > 0)
|
||||
return;
|
||||
ossl_qrx_release_pkt(qrx, pkt_wrap->handle);
|
||||
CRYPTO_THREAD_lock_free(pkt_wrap->lock);
|
||||
OPENSSL_free(pkt_wrap);
|
||||
}
|
@ -17,7 +17,7 @@ struct quic_rstream_st {
|
||||
OSSL_STATM *statm;
|
||||
};
|
||||
|
||||
QUIC_RSTREAM *ossl_quic_rstream_new(OSSL_QRX *qrx, QUIC_RXFC *rxfc,
|
||||
QUIC_RSTREAM *ossl_quic_rstream_new(QUIC_RXFC *rxfc,
|
||||
OSSL_STATM *statm)
|
||||
{
|
||||
QUIC_RSTREAM *ret = OPENSSL_malloc(sizeof(*ret));
|
||||
@ -25,7 +25,7 @@ QUIC_RSTREAM *ossl_quic_rstream_new(OSSL_QRX *qrx, QUIC_RXFC *rxfc,
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
|
||||
ossl_sframe_list_init(&ret->fl, qrx);
|
||||
ossl_sframe_list_init(&ret->fl);
|
||||
ret->rxfc = rxfc;
|
||||
ret->statm = statm;
|
||||
return ret;
|
||||
@ -37,7 +37,7 @@ void ossl_quic_rstream_free(QUIC_RSTREAM *qrs)
|
||||
OPENSSL_free(qrs);
|
||||
}
|
||||
|
||||
int ossl_quic_rstream_queue_data(QUIC_RSTREAM *qrs, OSSL_QRX_PKT_WRAP *pkt_wrap,
|
||||
int ossl_quic_rstream_queue_data(QUIC_RSTREAM *qrs, OSSL_QRX_PKT *pkt,
|
||||
uint64_t offset,
|
||||
const unsigned char *data, uint64_t data_len,
|
||||
int fin)
|
||||
@ -47,7 +47,7 @@ int ossl_quic_rstream_queue_data(QUIC_RSTREAM *qrs, OSSL_QRX_PKT_WRAP *pkt_wrap,
|
||||
range.start = offset;
|
||||
range.end = offset + data_len;
|
||||
|
||||
return ossl_sframe_list_insert(&qrs->fl, &range, pkt_wrap, data, fin);
|
||||
return ossl_sframe_list_insert(&qrs->fl, &range, pkt, data, fin);
|
||||
}
|
||||
|
||||
static int read_internal(QUIC_RSTREAM *qrs, unsigned char *buf, size_t size,
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "internal/quic_record_rx.h"
|
||||
#include "internal/quic_ackm.h"
|
||||
#include "internal/quic_rx_depack.h"
|
||||
#include "internal/quic_record_rx_wrap.h"
|
||||
#include "internal/quic_error.h"
|
||||
#include "internal/quic_fc.h"
|
||||
#include "internal/sockets.h"
|
||||
@ -66,7 +65,7 @@ static int ssl_get_stream_type(QUIC_STREAM *stream)
|
||||
* reference count. When the data is consumed (i.e. as a result of, say,
|
||||
* SSL_read()), ossl_qrx_pkt_wrap_free() must be called.
|
||||
*/
|
||||
static int ssl_queue_data(QUIC_STREAM *stream, OSSL_QRX_PKT_WRAP *pkt_wrap,
|
||||
static int ssl_queue_data(QUIC_STREAM *stream, OSSL_QRX_PKT *pkt,
|
||||
const unsigned char *data, uint64_t data_len,
|
||||
uint64_t logical_offset, int is_fin)
|
||||
{
|
||||
@ -80,7 +79,7 @@ static int ssl_queue_data(QUIC_STREAM *stream, OSSL_QRX_PKT_WRAP *pkt_wrap,
|
||||
return 0;
|
||||
|
||||
return stream->rstream == NULL
|
||||
|| ossl_quic_rstream_queue_data(stream->rstream, pkt_wrap,
|
||||
|| ossl_quic_rstream_queue_data(stream->rstream, pkt,
|
||||
logical_offset, data, data_len,
|
||||
is_fin);
|
||||
}
|
||||
@ -295,7 +294,7 @@ static int depack_do_frame_new_token(PACKET *pkt, QUIC_CONNECTION *connection,
|
||||
}
|
||||
|
||||
static int depack_do_frame_stream(PACKET *pkt, QUIC_CONNECTION *connection,
|
||||
OSSL_QRX_PKT_WRAP *parent_pkt,
|
||||
OSSL_QRX_PKT *parent_pkt,
|
||||
OSSL_ACKM_RX_PKT *ackm_data)
|
||||
{
|
||||
OSSL_QUIC_FRAME_STREAM frame_data;
|
||||
@ -547,10 +546,10 @@ static int depack_do_frame_unknown_extension(PACKET *pkt,
|
||||
/* Main frame processor */
|
||||
|
||||
static int depack_process_frames(QUIC_CONNECTION *connection, PACKET *pkt,
|
||||
OSSL_QRX_PKT_WRAP *parent_pkt, int packet_space,
|
||||
OSSL_QRX_PKT *parent_pkt, int packet_space,
|
||||
OSSL_TIME received, OSSL_ACKM_RX_PKT *ackm_data)
|
||||
{
|
||||
uint32_t pkt_type = parent_pkt->pkt->hdr->type;
|
||||
uint32_t pkt_type = parent_pkt->hdr->type;
|
||||
|
||||
while (PACKET_remaining(pkt) > 0) {
|
||||
uint64_t frame_type;
|
||||
@ -748,7 +747,6 @@ int ossl_quic_handle_frames(QUIC_CONNECTION *connection, OSSL_QRX_PKT *qpacket)
|
||||
{
|
||||
PACKET pkt;
|
||||
OSSL_ACKM_RX_PKT ackm_data;
|
||||
OSSL_QRX_PKT_WRAP *qpkt_wrap = NULL;
|
||||
/*
|
||||
* ok has three states:
|
||||
* -1 error with ackm_data uninitialized
|
||||
@ -760,9 +758,6 @@ int ossl_quic_handle_frames(QUIC_CONNECTION *connection, OSSL_QRX_PKT *qpacket)
|
||||
if (connection == NULL)
|
||||
goto end;
|
||||
|
||||
if ((qpkt_wrap = ossl_qrx_pkt_wrap_new(qpacket)) == NULL)
|
||||
goto end;
|
||||
|
||||
/* Initialize |ackm_data| (and reinitialize |ok|)*/
|
||||
memset(&ackm_data, 0, sizeof(ackm_data));
|
||||
/*
|
||||
@ -796,7 +791,7 @@ int ossl_quic_handle_frames(QUIC_CONNECTION *connection, OSSL_QRX_PKT *qpacket)
|
||||
|
||||
/* Now that special cases are out of the way, parse frames */
|
||||
if (!PACKET_buf_init(&pkt, qpacket->hdr->data, qpacket->hdr->len)
|
||||
|| !depack_process_frames(connection, &pkt, qpkt_wrap,
|
||||
|| !depack_process_frames(connection, &pkt, qpacket,
|
||||
ackm_data.pkt_space, qpacket->time,
|
||||
&ackm_data))
|
||||
goto end;
|
||||
@ -814,19 +809,16 @@ int ossl_quic_handle_frames(QUIC_CONNECTION *connection, OSSL_QRX_PKT *qpacket)
|
||||
ossl_ackm_on_rx_packet(GET_CONN_ACKM(connection), &ackm_data);
|
||||
|
||||
/*
|
||||
* Let go of the packet pointer in |qpkt_wrap|. This means that the
|
||||
* reference counter can't be incremented any more.
|
||||
* Release the ref to the packet. This will free the packet unless something
|
||||
* in our processing above has added a reference to it.
|
||||
*/
|
||||
if (qpkt_wrap != NULL)
|
||||
qpkt_wrap->pkt = NULL;
|
||||
|
||||
ossl_qrx_pkt_wrap_free(GET_CONN_QRX(connection), qpkt_wrap);
|
||||
ossl_qrx_pkt_release(qpacket);
|
||||
return ok > 0;
|
||||
}
|
||||
|
||||
int ossl_quic_depacketize(QUIC_CONNECTION *connection)
|
||||
{
|
||||
OSSL_QRX_PKT qpacket;
|
||||
OSSL_QRX_PKT *qpacket = NULL;
|
||||
|
||||
if (connection == NULL)
|
||||
return 0;
|
||||
@ -836,5 +828,5 @@ int ossl_quic_depacketize(QUIC_CONNECTION *connection)
|
||||
if (ossl_qrx_read_pkt(GET_CONN_QRX(connection), &qpacket) <= 0)
|
||||
return 0;
|
||||
|
||||
return ossl_quic_handle_frames(connection, &qpacket);
|
||||
return ossl_quic_handle_frames(connection, qpacket);
|
||||
}
|
||||
|
@ -9,31 +9,28 @@
|
||||
|
||||
#include "internal/uint_set.h"
|
||||
#include "internal/common.h"
|
||||
#include "internal/quic_record_rx_wrap.h"
|
||||
#include "internal/quic_sf_list.h"
|
||||
|
||||
struct stream_frame_st {
|
||||
struct stream_frame_st *prev, *next;
|
||||
UINT_RANGE range;
|
||||
OSSL_QRX_PKT_WRAP *pkt;
|
||||
OSSL_QRX_PKT *pkt;
|
||||
const unsigned char *data;
|
||||
};
|
||||
|
||||
static void stream_frame_free(SFRAME_LIST *fl, STREAM_FRAME *sf)
|
||||
{
|
||||
ossl_qrx_pkt_wrap_free(fl->qrx, sf->pkt);
|
||||
ossl_qrx_pkt_release(sf->pkt);
|
||||
OPENSSL_free(sf);
|
||||
}
|
||||
|
||||
static STREAM_FRAME *stream_frame_new(UINT_RANGE *range, OSSL_QRX_PKT_WRAP *pkt,
|
||||
static STREAM_FRAME *stream_frame_new(UINT_RANGE *range, OSSL_QRX_PKT *pkt,
|
||||
const unsigned char *data)
|
||||
{
|
||||
STREAM_FRAME *sf = OPENSSL_zalloc(sizeof(*sf));
|
||||
|
||||
if (pkt != NULL && !ossl_qrx_pkt_wrap_up_ref(pkt)) {
|
||||
OPENSSL_free(sf);
|
||||
return NULL;
|
||||
}
|
||||
if (pkt != NULL)
|
||||
ossl_qrx_pkt_up_ref(pkt);
|
||||
|
||||
sf->range = *range;
|
||||
sf->pkt = pkt;
|
||||
@ -42,10 +39,9 @@ static STREAM_FRAME *stream_frame_new(UINT_RANGE *range, OSSL_QRX_PKT_WRAP *pkt,
|
||||
return sf;
|
||||
}
|
||||
|
||||
void ossl_sframe_list_init(SFRAME_LIST *fl, OSSL_QRX *qrx)
|
||||
void ossl_sframe_list_init(SFRAME_LIST *fl)
|
||||
{
|
||||
memset(fl, 0, sizeof(*fl));
|
||||
fl->qrx = qrx;
|
||||
}
|
||||
|
||||
void ossl_sframe_list_destroy(SFRAME_LIST *fl)
|
||||
@ -59,7 +55,7 @@ void ossl_sframe_list_destroy(SFRAME_LIST *fl)
|
||||
}
|
||||
|
||||
static int append_frame(SFRAME_LIST *fl, UINT_RANGE *range,
|
||||
OSSL_QRX_PKT_WRAP *pkt,
|
||||
OSSL_QRX_PKT *pkt,
|
||||
const unsigned char *data)
|
||||
{
|
||||
STREAM_FRAME *new_frame;
|
||||
@ -75,7 +71,7 @@ static int append_frame(SFRAME_LIST *fl, UINT_RANGE *range,
|
||||
}
|
||||
|
||||
int ossl_sframe_list_insert(SFRAME_LIST *fl, UINT_RANGE *range,
|
||||
OSSL_QRX_PKT_WRAP *pkt,
|
||||
OSSL_QRX_PKT *pkt,
|
||||
const unsigned char *data, int fin)
|
||||
{
|
||||
STREAM_FRAME *sf, *new_frame, *prev_frame, *next_frame;
|
||||
|
@ -1791,7 +1791,7 @@ static int rx_run_script(const struct rx_test_op *script)
|
||||
int testresult = 0, pkt_outstanding = 0;
|
||||
struct rx_state s = {0};
|
||||
size_t i;
|
||||
OSSL_QRX_PKT pkt = {0};
|
||||
OSSL_QRX_PKT *pkt = NULL;
|
||||
const struct rx_test_op *op = script;
|
||||
|
||||
for (; op->op != RX_TEST_OP_END; ++op)
|
||||
@ -1850,14 +1850,14 @@ static int rx_run_script(const struct rx_test_op *script)
|
||||
goto err;
|
||||
|
||||
pkt_outstanding = 1;
|
||||
if (!TEST_ptr(pkt.hdr))
|
||||
if (!TEST_ptr(pkt) || !TEST_ptr(pkt->hdr))
|
||||
goto err;
|
||||
|
||||
if (!TEST_mem_eq(pkt.hdr->data, pkt.hdr->len,
|
||||
if (!TEST_mem_eq(pkt->hdr->data, pkt->hdr->len,
|
||||
op->buf, op->buf_len))
|
||||
goto err;
|
||||
|
||||
if (!TEST_true(cmp_pkt_hdr(pkt.hdr, op->hdr,
|
||||
if (!TEST_true(cmp_pkt_hdr(pkt->hdr, op->hdr,
|
||||
op->buf, op->buf_len, 1)))
|
||||
goto err;
|
||||
|
||||
@ -1866,19 +1866,19 @@ static int rx_run_script(const struct rx_test_op *script)
|
||||
if (!TEST_true(rx_state_ensure_for_frames(&s)))
|
||||
goto err;
|
||||
pkt_outstanding = 0;
|
||||
if (!TEST_true(ossl_quic_handle_frames(s.quic_conn, &pkt)))
|
||||
if (!TEST_true(ossl_quic_handle_frames(s.quic_conn, pkt)))
|
||||
goto err;
|
||||
break;
|
||||
case RX_TEST_OP_CHECK_PKT_FRAMES_INVALID:
|
||||
if (!TEST_true(rx_state_ensure_for_frames(&s)))
|
||||
goto err;
|
||||
pkt_outstanding = 0;
|
||||
if (!TEST_false(ossl_quic_handle_frames(s.quic_conn, &pkt)))
|
||||
if (!TEST_false(ossl_quic_handle_frames(s.quic_conn, pkt)))
|
||||
goto err;
|
||||
break;
|
||||
default:
|
||||
pkt_outstanding = 0;
|
||||
ossl_qrx_release_pkt(s.qrx, pkt.handle);
|
||||
ossl_qrx_pkt_release(pkt);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -1920,7 +1920,7 @@ static int rx_run_script(const struct rx_test_op *script)
|
||||
testresult = 1;
|
||||
err:
|
||||
if (pkt_outstanding)
|
||||
ossl_qrx_release_pkt(s.qrx, pkt.handle);
|
||||
ossl_qrx_pkt_release(pkt);
|
||||
rx_state_teardown(&s);
|
||||
return testresult;
|
||||
}
|
||||
|
@ -330,7 +330,7 @@ static int test_rstream_simple(void)
|
||||
size_t readbytes = 0, avail = 0;
|
||||
int fin = 0;
|
||||
|
||||
if (!TEST_ptr(rstream = ossl_quic_rstream_new(NULL, NULL, NULL)))
|
||||
if (!TEST_ptr(rstream = ossl_quic_rstream_new(NULL, NULL)))
|
||||
goto err;
|
||||
|
||||
if (!TEST_true(ossl_quic_rstream_queue_data(rstream, NULL, 5,
|
||||
@ -405,7 +405,7 @@ static int test_rstream_random(int idx)
|
||||
|
||||
if (!TEST_ptr(bulk_data = OPENSSL_malloc(data_size))
|
||||
|| !TEST_ptr(read_buf = OPENSSL_malloc(data_size))
|
||||
|| !TEST_ptr(rstream = ossl_quic_rstream_new(NULL, NULL, NULL)))
|
||||
|| !TEST_ptr(rstream = ossl_quic_rstream_new(NULL, NULL)))
|
||||
goto err;
|
||||
|
||||
for (i = 0; i < data_size; ++i)
|
||||
|
@ -55,7 +55,7 @@ struct helper {
|
||||
QUIC_DEMUX *demux;
|
||||
OSSL_QRX *qrx;
|
||||
OSSL_QRX_ARGS qrx_args;
|
||||
OSSL_QRX_PKT qrx_pkt;
|
||||
OSSL_QRX_PKT *qrx_pkt;
|
||||
PACKET pkt;
|
||||
uint64_t frame_type;
|
||||
union {
|
||||
@ -80,8 +80,8 @@ static void helper_cleanup(struct helper *h)
|
||||
size_t i;
|
||||
uint32_t pn_space;
|
||||
|
||||
if (h->qrx_pkt.handle != NULL)
|
||||
ossl_qrx_release_pkt(h->qrx, h->qrx_pkt.handle);
|
||||
ossl_qrx_pkt_release(h->qrx_pkt);
|
||||
h->qrx_pkt = NULL;
|
||||
|
||||
for (pn_space = QUIC_PN_SPACE_INITIAL;
|
||||
pn_space < QUIC_PN_SPACE_NUM;
|
||||
@ -1134,13 +1134,13 @@ static int run_script(const struct script_op *script)
|
||||
break;
|
||||
case OPK_RX_PKT:
|
||||
ossl_quic_demux_pump(h.demux);
|
||||
if (h.qrx_pkt.handle != NULL)
|
||||
ossl_qrx_release_pkt(h.qrx, h.qrx_pkt.handle);
|
||||
ossl_qrx_pkt_release(h.qrx_pkt);
|
||||
h.qrx_pkt = NULL;
|
||||
if (!TEST_true(ossl_qrx_read_pkt(h.qrx, &h.qrx_pkt)))
|
||||
goto err;
|
||||
if (!TEST_true(PACKET_buf_init(&h.pkt,
|
||||
h.qrx_pkt.hdr->data,
|
||||
h.qrx_pkt.hdr->len)))
|
||||
h.qrx_pkt->hdr->data,
|
||||
h.qrx_pkt->hdr->len)))
|
||||
goto err;
|
||||
h.frame_type = UINT64_MAX;
|
||||
break;
|
||||
@ -1151,8 +1151,8 @@ static int run_script(const struct script_op *script)
|
||||
h.frame_type = UINT64_MAX;
|
||||
break;
|
||||
case OPK_EXPECT_DGRAM_LEN:
|
||||
if (!TEST_size_t_ge(h.qrx_pkt.datagram_len, (size_t)op->arg0)
|
||||
|| !TEST_size_t_le(h.qrx_pkt.datagram_len, (size_t)op->arg1))
|
||||
if (!TEST_size_t_ge(h.qrx_pkt->datagram_len, (size_t)op->arg0)
|
||||
|| !TEST_size_t_le(h.qrx_pkt->datagram_len, (size_t)op->arg1))
|
||||
goto err;
|
||||
break;
|
||||
case OPK_EXPECT_FRAME:
|
||||
@ -1160,12 +1160,12 @@ static int run_script(const struct script_op *script)
|
||||
goto err;
|
||||
break;
|
||||
case OPK_EXPECT_INITIAL_TOKEN:
|
||||
if (!TEST_mem_eq(h.qrx_pkt.hdr->token, h.qrx_pkt.hdr->token_len,
|
||||
if (!TEST_mem_eq(h.qrx_pkt->hdr->token, h.qrx_pkt->hdr->token_len,
|
||||
op->buf, (size_t)op->arg0))
|
||||
goto err;
|
||||
break;
|
||||
case OPK_EXPECT_HDR:
|
||||
if (!TEST_true(cmp_pkt_hdr(h.qrx_pkt.hdr, op->buf,
|
||||
if (!TEST_true(cmp_pkt_hdr(h.qrx_pkt->hdr, op->buf,
|
||||
NULL, 0, 0)))
|
||||
goto err;
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user