#include "internal/quic_record_rx.h"
#include "quic_record_shared.h"
#include "internal/common.h"
+#include "internal/list.h"
#include "../ssl_local.h"
/*
typedef struct rxe_st RXE;
struct rxe_st {
- RXE *prev, *next;
+ OSSL_LIST_MEMBER(rxe, RXE);
size_t data_len, alloc_len;
/* Extra fields for per-packet information. */
*/
};
-typedef struct ossl_qrx_rxe_list_st {
- RXE *head, *tail;
-} RXE_LIST;
+DEFINE_LIST_OF(rxe, RXE);
+typedef OSSL_LIST(rxe) RXE_LIST;
static ossl_inline unsigned char *rxe_data(const RXE *e)
{
return (unsigned char *)(e + 1);
}
-static void rxe_remove(RXE_LIST *l, RXE *e)
-{
- if (e->prev != NULL)
- e->prev->next = e->next;
- if (e->next != NULL)
- e->next->prev = e->prev;
-
- if (e == l->head)
- l->head = e->next;
- if (e == l->tail)
- l->tail = e->prev;
-
- e->next = e->prev = NULL;
-}
-
-static void rxe_insert_tail(RXE_LIST *l, RXE *e)
-{
- if (l->tail == NULL) {
- l->head = l->tail = e;
- e->next = e->prev = NULL;
- return;
- }
-
- l->tail->next = e;
- e->prev = l->tail;
- e->next = NULL;
- l->tail = e;
-}
-
/*
* QRL
* ===
{
RXE *e, *enext;
- for (e = l->head; e != NULL; e = enext) {
- enext = e->next;
+ for (e = ossl_list_rxe_head(l); e != NULL; e = enext) {
+ enext = ossl_list_rxe_next(e);
+ ossl_list_rxe_remove(l, e);
OPENSSL_free(e);
}
-
- l->head = l->tail = NULL;
}
static void qrx_cleanup_urxl(OSSL_QRX *qrx, QUIC_URXE_LIST *l)
{
QUIC_URXE *e, *enext;
- for (e = l->head; e != NULL; e = enext) {
- enext = e->next;
+ for (e = ossl_list_urxe_head(l); e != NULL; e = enext) {
+ enext = ossl_list_urxe_next(e);
ossl_quic_demux_release_urxe(qrx->demux, e);
}
-
- l->head = l->tail = NULL;
}
void ossl_qrx_free(OSSL_QRX *qrx)
urxe->processed = 0;
urxe->hpr_removed = 0;
urxe->deferred = 0;
- ossl_quic_urxe_insert_tail(&qrx->urx_pending, urxe);
+ ossl_list_urxe_insert_tail(&qrx->urx_pending, urxe);
}
int ossl_qrx_add_dst_conn_id(OSSL_QRX *qrx,
{
QUIC_URXE *e;
- while ((e = qrx->urx_deferred.head) != NULL) {
- ossl_quic_urxe_remove(&qrx->urx_deferred, e);
- ossl_quic_urxe_insert_head(&qrx->urx_pending, e);
+ while ((e = ossl_list_urxe_head(&qrx->urx_deferred)) != NULL) {
+ ossl_list_urxe_remove(&qrx->urx_deferred, e);
+ ossl_list_urxe_insert_head(&qrx->urx_pending, e);
}
}
/* Returns 1 if there are one or more pending RXEs. */
int ossl_qrx_processed_read_pending(OSSL_QRX *qrx)
{
- return qrx->rx_pending.head != NULL;
+ return !ossl_list_rxe_is_empty(&qrx->rx_pending);
}
/* Returns 1 if there are yet-unprocessed packets. */
int ossl_qrx_unprocessed_read_pending(OSSL_QRX *qrx)
{
- return qrx->urx_pending.head != NULL || qrx->urx_deferred.head != NULL;
+ return !ossl_list_urxe_is_empty(&qrx->urx_pending)
+ || !ossl_list_urxe_is_empty(&qrx->urx_deferred);
}
/* Pop the next pending RXE. Returns NULL if no RXE is pending. */
static RXE *qrx_pop_pending_rxe(OSSL_QRX *qrx)
{
- RXE *rxe = qrx->rx_pending.head;
+ RXE *rxe = ossl_list_rxe_head(&qrx->rx_pending);
if (rxe == NULL)
return NULL;
- rxe_remove(&qrx->rx_pending, rxe);
+ ossl_list_rxe_remove(&qrx->rx_pending, rxe);
return rxe;
}
if (rxe == NULL)
return NULL;
- rxe->prev = rxe->next = NULL;
+ ossl_list_rxe_init_elem(rxe);
rxe->alloc_len = alloc_len;
rxe->data_len = 0;
return rxe;
{
RXE *rxe;
- if (qrx->rx_free.head != NULL)
- return qrx->rx_free.head;
+ if (ossl_list_rxe_head(&qrx->rx_free) != NULL)
+ return ossl_list_rxe_head(&qrx->rx_free);
rxe = qrx_alloc_rxe(alloc_len);
if (rxe == NULL)
return NULL;
- rxe_insert_tail(&qrx->rx_free, rxe);
+ ossl_list_rxe_insert_tail(&qrx->rx_free, rxe);
return rxe;
}
*/
static RXE *qrx_resize_rxe(RXE_LIST *rxl, RXE *rxe, size_t n)
{
- RXE *rxe2;
+ RXE *rxe2, *p;
/* Should never happen. */
if (rxe == NULL)
if (n >= SIZE_MAX - sizeof(RXE))
return NULL;
+ /* Remove the item from the list to avoid accessing freed memory */
+ p = ossl_list_rxe_prev(rxe);
+ ossl_list_rxe_remove(rxl, rxe);
+
/*
* NOTE: We do not clear old memory, although it does contain decrypted
* data.
*/
rxe2 = OPENSSL_realloc(rxe, sizeof(RXE) + n);
- if (rxe2 == NULL)
- /* original RXE is still intact unchanged */
- return NULL;
-
- if (rxe != rxe2) {
- if (rxl->head == rxe)
- rxl->head = rxe2;
- if (rxl->tail == rxe)
- rxl->tail = rxe2;
- if (rxe->prev != NULL)
- rxe->prev->next = rxe2;
- if (rxe->next != NULL)
- rxe->next->prev = rxe2;
+ if (rxe2 == NULL || rxe == rxe2) {
+ if (p == NULL)
+ ossl_list_rxe_insert_head(rxl, rxe);
+ else
+ ossl_list_rxe_insert_after(rxl, p, rxe);
+ return rxe2;
}
+ if (p == NULL)
+ ossl_list_rxe_insert_head(rxl, rxe2);
+ else
+ ossl_list_rxe_insert_after(rxl, p, rxe2);
+
rxe2->alloc_len = n;
return rxe2;
}
static void qrx_recycle_rxe(OSSL_QRX *qrx, RXE *rxe)
{
/* RXE should not be in any list */
- assert(rxe->prev == NULL && rxe->next == NULL);
- rxe_insert_tail(&qrx->rx_free, rxe);
+ assert(ossl_list_rxe_prev(rxe) == NULL && ossl_list_rxe_next(rxe) == NULL);
+ ossl_list_rxe_insert_tail(&qrx->rx_free, rxe);
}
/*
rxe->pn = QUIC_PN_INVALID;
/* Move RXE to pending. */
- rxe_remove(&qrx->rx_free, rxe);
- rxe_insert_tail(&qrx->rx_pending, rxe);
+ ossl_list_rxe_remove(&qrx->rx_free, rxe);
+ ossl_list_rxe_insert_tail(&qrx->rx_pending, rxe);
return 0; /* success, did not defer */
}
rxe->time = urxe->time;
/* Move RXE to pending. */
- rxe_remove(&qrx->rx_free, rxe);
- rxe_insert_tail(&qrx->rx_pending, rxe);
+ ossl_list_rxe_remove(&qrx->rx_free, rxe);
+ ossl_list_rxe_insert_tail(&qrx->rx_pending, rxe);
return 0; /* success, did not defer; not distinguished from failure */
cannot_decrypt:
int was_deferred;
/* The next URXE we process should be at the head of the pending list. */
- if (!ossl_assert(e == qrx->urx_pending.head))
+ if (!ossl_assert(e == ossl_list_urxe_head(&qrx->urx_pending)))
return 0;
/*
* Remove the URXE from the pending list and return it to
* either the free or deferred list.
*/
- ossl_quic_urxe_remove(&qrx->urx_pending, e);
+ ossl_list_urxe_remove(&qrx->urx_pending, e);
if (was_deferred > 0 &&
(e->deferred || qrx->num_deferred < qrx->max_deferred)) {
- ossl_quic_urxe_insert_tail(&qrx->urx_deferred, e);
+ ossl_list_urxe_insert_tail(&qrx->urx_deferred, e);
if (!e->deferred) {
e->deferred = 1;
++qrx->num_deferred;
{
QUIC_URXE *e;
- while ((e = qrx->urx_pending.head) != NULL)
+ while ((e = ossl_list_urxe_head(&qrx->urx_pending)) != NULL)
if (!qrx_process_one_urxe(qrx, e))
return 0;