123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- /*
- * ngtcp2
- *
- * Copyright (c) 2023 ngtcp2 contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
- #include "ngtcp2_frame_chain.h"
- #include <string.h>
- #include <assert.h>
- ngtcp2_objalloc_def(frame_chain, ngtcp2_frame_chain, oplent)
- int ngtcp2_frame_chain_new(ngtcp2_frame_chain **pfrc, const ngtcp2_mem *mem) {
- *pfrc = ngtcp2_mem_malloc(mem, sizeof(ngtcp2_frame_chain));
- if (*pfrc == NULL) {
- return NGTCP2_ERR_NOMEM;
- }
- ngtcp2_frame_chain_init(*pfrc);
- return 0;
- }
- int ngtcp2_frame_chain_objalloc_new(ngtcp2_frame_chain **pfrc,
- ngtcp2_objalloc *objalloc) {
- *pfrc = ngtcp2_objalloc_frame_chain_get(objalloc);
- if (*pfrc == NULL) {
- return NGTCP2_ERR_NOMEM;
- }
- ngtcp2_frame_chain_init(*pfrc);
- return 0;
- }
- int ngtcp2_frame_chain_extralen_new(ngtcp2_frame_chain **pfrc, size_t extralen,
- const ngtcp2_mem *mem) {
- *pfrc = ngtcp2_mem_malloc(mem, sizeof(ngtcp2_frame_chain) + extralen);
- if (*pfrc == NULL) {
- return NGTCP2_ERR_NOMEM;
- }
- ngtcp2_frame_chain_init(*pfrc);
- return 0;
- }
- int ngtcp2_frame_chain_stream_datacnt_objalloc_new(ngtcp2_frame_chain **pfrc,
- size_t datacnt,
- ngtcp2_objalloc *objalloc,
- const ngtcp2_mem *mem) {
- if (datacnt > NGTCP2_FRAME_CHAIN_STREAM_DATACNT_THRES) {
- return ngtcp2_frame_chain_extralen_new(pfrc,
- sizeof(ngtcp2_vec) * (datacnt - 1) -
- NGTCP2_FRAME_CHAIN_STREAM_AVAIL,
- mem);
- }
- return ngtcp2_frame_chain_objalloc_new(pfrc, objalloc);
- }
- int ngtcp2_frame_chain_new_token_objalloc_new(ngtcp2_frame_chain **pfrc,
- const uint8_t *token,
- size_t tokenlen,
- ngtcp2_objalloc *objalloc,
- const ngtcp2_mem *mem) {
- size_t avail = sizeof(ngtcp2_frame) - sizeof(ngtcp2_new_token);
- int rv;
- uint8_t *p;
- ngtcp2_frame *fr;
- if (tokenlen > avail) {
- rv = ngtcp2_frame_chain_extralen_new(pfrc, tokenlen - avail, mem);
- } else {
- rv = ngtcp2_frame_chain_objalloc_new(pfrc, objalloc);
- }
- if (rv != 0) {
- return rv;
- }
- fr = &(*pfrc)->fr;
- fr->type = NGTCP2_FRAME_NEW_TOKEN;
- p = (uint8_t *)fr + sizeof(ngtcp2_new_token);
- memcpy(p, token, tokenlen);
- fr->new_token.token = p;
- fr->new_token.tokenlen = tokenlen;
- return 0;
- }
- void ngtcp2_frame_chain_del(ngtcp2_frame_chain *frc, const ngtcp2_mem *mem) {
- ngtcp2_frame_chain_binder *binder;
- if (frc == NULL) {
- return;
- }
- binder = frc->binder;
- if (binder && --binder->refcount == 0) {
- ngtcp2_mem_free(mem, binder);
- }
- ngtcp2_mem_free(mem, frc);
- }
- void ngtcp2_frame_chain_objalloc_del(ngtcp2_frame_chain *frc,
- ngtcp2_objalloc *objalloc,
- const ngtcp2_mem *mem) {
- ngtcp2_frame_chain_binder *binder;
- if (frc == NULL) {
- return;
- }
- switch (frc->fr.type) {
- case NGTCP2_FRAME_CRYPTO:
- case NGTCP2_FRAME_STREAM:
- if (frc->fr.stream.datacnt > NGTCP2_FRAME_CHAIN_STREAM_DATACNT_THRES) {
- ngtcp2_frame_chain_del(frc, mem);
- return;
- }
- break;
- case NGTCP2_FRAME_NEW_TOKEN:
- if (frc->fr.new_token.tokenlen >
- sizeof(ngtcp2_frame) - sizeof(ngtcp2_new_token)) {
- ngtcp2_frame_chain_del(frc, mem);
- return;
- }
- break;
- }
- binder = frc->binder;
- if (binder && --binder->refcount == 0) {
- ngtcp2_mem_free(mem, binder);
- }
- frc->binder = NULL;
- ngtcp2_objalloc_frame_chain_release(objalloc, frc);
- }
- void ngtcp2_frame_chain_init(ngtcp2_frame_chain *frc) {
- frc->next = NULL;
- frc->binder = NULL;
- }
- void ngtcp2_frame_chain_list_objalloc_del(ngtcp2_frame_chain *frc,
- ngtcp2_objalloc *objalloc,
- const ngtcp2_mem *mem) {
- ngtcp2_frame_chain *next;
- for (; frc; frc = next) {
- next = frc->next;
- ngtcp2_frame_chain_objalloc_del(frc, objalloc, mem);
- }
- }
- int ngtcp2_frame_chain_binder_new(ngtcp2_frame_chain_binder **pbinder,
- const ngtcp2_mem *mem) {
- *pbinder = ngtcp2_mem_calloc(mem, 1, sizeof(ngtcp2_frame_chain_binder));
- if (*pbinder == NULL) {
- return NGTCP2_ERR_NOMEM;
- }
- return 0;
- }
- int ngtcp2_bind_frame_chains(ngtcp2_frame_chain *a, ngtcp2_frame_chain *b,
- const ngtcp2_mem *mem) {
- ngtcp2_frame_chain_binder *binder;
- int rv;
- assert(b->binder == NULL);
- if (a->binder == NULL) {
- rv = ngtcp2_frame_chain_binder_new(&binder, mem);
- if (rv != 0) {
- return rv;
- }
- a->binder = binder;
- ++a->binder->refcount;
- }
- b->binder = a->binder;
- ++b->binder->refcount;
- return 0;
- }
|