#include "internal/bio_addr.h"
#include "internal/common.h"
#include "quic_record_shared.h"
+#include "internal/list.h"
#include "../ssl_local.h"
/*
typedef struct txe_st TXE;
struct txe_st {
- TXE *prev, *next;
+ OSSL_LIST_MEMBER(txe, TXE);
size_t data_len, alloc_len;
/*
*/
};
+DEFINE_LIST_OF(txe, TXE);
+typedef OSSL_LIST(txe) TXE_LIST;
+
static ossl_inline unsigned char *txe_data(const TXE *e)
{
return (unsigned char *)(e + 1);
}
-typedef struct txe_list_st {
- TXE *head, *tail;
-} TXE_LIST;
-
-static void txe_remove(TXE_LIST *l, TXE *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 txe_insert_tail(TXE_LIST *l, TXE *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;
-}
-
/*
* QTX
* ===
static void qtx_cleanup_txl(TXE_LIST *l)
{
TXE *e, *enext;
- for (e = l->head; e != NULL; e = enext) {
- enext = e->next;
+
+ for (e = ossl_list_txe_head(l); e != NULL; e = enext) {
+ enext = ossl_list_txe_next(e);
OPENSSL_free(e);
}
- l->head = l->tail = NULL;
}
/* Frees the QTX. */
if (txe == NULL)
return NULL;
- txe->prev = txe->next = NULL;
+ ossl_list_txe_init_elem(txe);
txe->alloc_len = alloc_len;
- txe->data_len = 0;
+ txe->data_len = 0;
return txe;
}
{
TXE *txe;
- if (qtx->free.head != NULL)
- return qtx->free.head;
+ txe = ossl_list_txe_head(&qtx->free);
+ if (txe != NULL)
+ return txe;
txe = qtx_alloc_txe(alloc_len);
if (txe == NULL)
return NULL;
- txe_insert_tail(&qtx->free, txe);
+ ossl_list_txe_insert_tail(&qtx->free, txe);
return txe;
}
*/
static TXE *qtx_resize_txe(OSSL_QTX *qtx, TXE_LIST *txl, TXE *txe, size_t n)
{
- TXE *txe2;
+ TXE *txe2, *p;
/* Should never happen. */
if (txe == NULL)
if (n >= SIZE_MAX - sizeof(TXE))
return NULL;
+ /* Remove the item from the list to avoid accessing freed memory */
+ p = ossl_list_txe_prev(txe);
+ ossl_list_txe_remove(txl, txe);
+
/*
* NOTE: We do not clear old memory, although it does contain decrypted
* data.
*/
txe2 = OPENSSL_realloc(txe, sizeof(TXE) + n);
- if (txe2 == NULL)
- /* original TXE is still in tact unchanged */
- return NULL;
-
- if (txl != NULL && txe != txe2) {
- if (txl->head == txe)
- txl->head = txe2;
- if (txl->tail == txe)
- txl->tail = txe2;
- if (txe->prev != NULL)
- txe->prev->next = txe2;
- if (txe->next != NULL)
- txe->next->prev = txe2;
+ if (txe2 == NULL || txe == txe2) {
+ if (p == NULL)
+ ossl_list_txe_insert_head(txl, txe);
+ else
+ ossl_list_txe_insert_after(txl, p, txe);
+ return txe2;
}
+ if (p == NULL)
+ ossl_list_txe_insert_head(txl, txe2);
+ else
+ ossl_list_txe_insert_after(txl, p, txe2);
+
if (qtx->cons == txe)
qtx->cons = txe2;
/* Move a TXE from pending to free. */
static void qtx_pending_to_free(OSSL_QTX *qtx)
{
- TXE *txe = qtx->pending.head;
+ TXE *txe = ossl_list_txe_head(&qtx->pending);
assert(txe != NULL);
- txe_remove(&qtx->pending, txe);
+ ossl_list_txe_remove(&qtx->pending, txe);
--qtx->pending_count;
qtx->pending_bytes -= txe->data_len;
- txe_insert_tail(&qtx->free, txe);
+ ossl_list_txe_insert_tail(&qtx->free, txe);
}
/* Add a TXE not currently in any list to the pending list. */
static void qtx_add_to_pending(OSSL_QTX *qtx, TXE *txe)
{
- txe_insert_tail(&qtx->pending, txe);
+ ossl_list_txe_insert_tail(&qtx->pending, txe);
++qtx->pending_count;
qtx->pending_bytes += txe->data_len;
}
if (txe == NULL)
return NULL;
- txe_remove(&qtx->free, txe);
+ ossl_list_txe_remove(&qtx->free, txe);
qtx->cons = txe;
qtx->cons_count = 0;
txe->data_len = 0;
* If we did not put anything in the datagram, just move it back to the
* free list.
*/
- txe_insert_tail(&qtx->free, txe);
+ ossl_list_txe_insert_tail(&qtx->free, txe);
else
qtx_add_to_pending(qtx, txe);
return;
for (;;) {
- for (txe = qtx->pending.head, i = 0;
+ for (txe = ossl_list_txe_head(&qtx->pending), i = 0;
txe != NULL && i < OSSL_NELEM(msg);
- txe = txe->next, ++i)
+ txe = ossl_list_txe_next(txe), ++i)
txe_to_msg(txe, &msg[i]);
if (!i)
int ossl_qtx_pop_net(OSSL_QTX *qtx, BIO_MSG *msg)
{
- TXE *txe = qtx->pending.head;
+ TXE *txe = ossl_list_txe_head(&qtx->pending);
if (txe == NULL)
return 0;