ngtcp2_frame_chain.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /*
  2. * ngtcp2
  3. *
  4. * Copyright (c) 2023 ngtcp2 contributors
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining
  7. * a copy of this software and associated documentation files (the
  8. * "Software"), to deal in the Software without restriction, including
  9. * without limitation the rights to use, copy, modify, merge, publish,
  10. * distribute, sublicense, and/or sell copies of the Software, and to
  11. * permit persons to whom the Software is furnished to do so, subject to
  12. * the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be
  15. * included in all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  20. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  21. * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  22. * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  23. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24. */
  25. #include "ngtcp2_frame_chain.h"
  26. #include <string.h>
  27. #include <assert.h>
  28. ngtcp2_objalloc_def(frame_chain, ngtcp2_frame_chain, oplent)
  29. int ngtcp2_frame_chain_new(ngtcp2_frame_chain **pfrc, const ngtcp2_mem *mem) {
  30. *pfrc = ngtcp2_mem_malloc(mem, sizeof(ngtcp2_frame_chain));
  31. if (*pfrc == NULL) {
  32. return NGTCP2_ERR_NOMEM;
  33. }
  34. ngtcp2_frame_chain_init(*pfrc);
  35. return 0;
  36. }
  37. int ngtcp2_frame_chain_objalloc_new(ngtcp2_frame_chain **pfrc,
  38. ngtcp2_objalloc *objalloc) {
  39. *pfrc = ngtcp2_objalloc_frame_chain_get(objalloc);
  40. if (*pfrc == NULL) {
  41. return NGTCP2_ERR_NOMEM;
  42. }
  43. ngtcp2_frame_chain_init(*pfrc);
  44. return 0;
  45. }
  46. int ngtcp2_frame_chain_extralen_new(ngtcp2_frame_chain **pfrc, size_t extralen,
  47. const ngtcp2_mem *mem) {
  48. *pfrc = ngtcp2_mem_malloc(mem, sizeof(ngtcp2_frame_chain) + extralen);
  49. if (*pfrc == NULL) {
  50. return NGTCP2_ERR_NOMEM;
  51. }
  52. ngtcp2_frame_chain_init(*pfrc);
  53. return 0;
  54. }
  55. int ngtcp2_frame_chain_stream_datacnt_objalloc_new(ngtcp2_frame_chain **pfrc,
  56. size_t datacnt,
  57. ngtcp2_objalloc *objalloc,
  58. const ngtcp2_mem *mem) {
  59. if (datacnt > NGTCP2_FRAME_CHAIN_STREAM_DATACNT_THRES) {
  60. return ngtcp2_frame_chain_extralen_new(pfrc,
  61. sizeof(ngtcp2_vec) * (datacnt - 1) -
  62. NGTCP2_FRAME_CHAIN_STREAM_AVAIL,
  63. mem);
  64. }
  65. return ngtcp2_frame_chain_objalloc_new(pfrc, objalloc);
  66. }
  67. int ngtcp2_frame_chain_new_token_objalloc_new(ngtcp2_frame_chain **pfrc,
  68. const uint8_t *token,
  69. size_t tokenlen,
  70. ngtcp2_objalloc *objalloc,
  71. const ngtcp2_mem *mem) {
  72. size_t avail = sizeof(ngtcp2_frame) - sizeof(ngtcp2_new_token);
  73. int rv;
  74. uint8_t *p;
  75. ngtcp2_frame *fr;
  76. if (tokenlen > avail) {
  77. rv = ngtcp2_frame_chain_extralen_new(pfrc, tokenlen - avail, mem);
  78. } else {
  79. rv = ngtcp2_frame_chain_objalloc_new(pfrc, objalloc);
  80. }
  81. if (rv != 0) {
  82. return rv;
  83. }
  84. fr = &(*pfrc)->fr;
  85. fr->type = NGTCP2_FRAME_NEW_TOKEN;
  86. p = (uint8_t *)fr + sizeof(ngtcp2_new_token);
  87. memcpy(p, token, tokenlen);
  88. fr->new_token.token = p;
  89. fr->new_token.tokenlen = tokenlen;
  90. return 0;
  91. }
  92. void ngtcp2_frame_chain_del(ngtcp2_frame_chain *frc, const ngtcp2_mem *mem) {
  93. ngtcp2_frame_chain_binder *binder;
  94. if (frc == NULL) {
  95. return;
  96. }
  97. binder = frc->binder;
  98. if (binder && --binder->refcount == 0) {
  99. ngtcp2_mem_free(mem, binder);
  100. }
  101. ngtcp2_mem_free(mem, frc);
  102. }
  103. void ngtcp2_frame_chain_objalloc_del(ngtcp2_frame_chain *frc,
  104. ngtcp2_objalloc *objalloc,
  105. const ngtcp2_mem *mem) {
  106. ngtcp2_frame_chain_binder *binder;
  107. if (frc == NULL) {
  108. return;
  109. }
  110. switch (frc->fr.type) {
  111. case NGTCP2_FRAME_CRYPTO:
  112. case NGTCP2_FRAME_STREAM:
  113. if (frc->fr.stream.datacnt > NGTCP2_FRAME_CHAIN_STREAM_DATACNT_THRES) {
  114. ngtcp2_frame_chain_del(frc, mem);
  115. return;
  116. }
  117. break;
  118. case NGTCP2_FRAME_NEW_TOKEN:
  119. if (frc->fr.new_token.tokenlen >
  120. sizeof(ngtcp2_frame) - sizeof(ngtcp2_new_token)) {
  121. ngtcp2_frame_chain_del(frc, mem);
  122. return;
  123. }
  124. break;
  125. }
  126. binder = frc->binder;
  127. if (binder && --binder->refcount == 0) {
  128. ngtcp2_mem_free(mem, binder);
  129. }
  130. frc->binder = NULL;
  131. ngtcp2_objalloc_frame_chain_release(objalloc, frc);
  132. }
  133. void ngtcp2_frame_chain_init(ngtcp2_frame_chain *frc) {
  134. frc->next = NULL;
  135. frc->binder = NULL;
  136. }
  137. void ngtcp2_frame_chain_list_objalloc_del(ngtcp2_frame_chain *frc,
  138. ngtcp2_objalloc *objalloc,
  139. const ngtcp2_mem *mem) {
  140. ngtcp2_frame_chain *next;
  141. for (; frc; frc = next) {
  142. next = frc->next;
  143. ngtcp2_frame_chain_objalloc_del(frc, objalloc, mem);
  144. }
  145. }
  146. int ngtcp2_frame_chain_binder_new(ngtcp2_frame_chain_binder **pbinder,
  147. const ngtcp2_mem *mem) {
  148. *pbinder = ngtcp2_mem_calloc(mem, 1, sizeof(ngtcp2_frame_chain_binder));
  149. if (*pbinder == NULL) {
  150. return NGTCP2_ERR_NOMEM;
  151. }
  152. return 0;
  153. }
  154. int ngtcp2_bind_frame_chains(ngtcp2_frame_chain *a, ngtcp2_frame_chain *b,
  155. const ngtcp2_mem *mem) {
  156. ngtcp2_frame_chain_binder *binder;
  157. int rv;
  158. assert(b->binder == NULL);
  159. if (a->binder == NULL) {
  160. rv = ngtcp2_frame_chain_binder_new(&binder, mem);
  161. if (rv != 0) {
  162. return rv;
  163. }
  164. a->binder = binder;
  165. ++a->binder->refcount;
  166. }
  167. b->binder = a->binder;
  168. ++b->binder->refcount;
  169. return 0;
  170. }