2
0

quic_rstream.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. /*
  2. * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <openssl/err.h>
  10. #include "internal/common.h"
  11. #include "internal/time.h"
  12. #include "internal/quic_stream.h"
  13. #include "internal/quic_sf_list.h"
  14. #include "internal/ring_buf.h"
  15. struct quic_rstream_st {
  16. SFRAME_LIST fl;
  17. QUIC_RXFC *rxfc;
  18. OSSL_STATM *statm;
  19. UINT_RANGE head_range;
  20. struct ring_buf rbuf;
  21. };
  22. QUIC_RSTREAM *ossl_quic_rstream_new(QUIC_RXFC *rxfc,
  23. OSSL_STATM *statm, size_t rbuf_size)
  24. {
  25. QUIC_RSTREAM *ret = OPENSSL_zalloc(sizeof(*ret));
  26. if (ret == NULL)
  27. return NULL;
  28. ring_buf_init(&ret->rbuf);
  29. if (!ring_buf_resize(&ret->rbuf, rbuf_size, 0)) {
  30. OPENSSL_free(ret);
  31. return NULL;
  32. }
  33. ossl_sframe_list_init(&ret->fl);
  34. ret->rxfc = rxfc;
  35. ret->statm = statm;
  36. return ret;
  37. }
  38. void ossl_quic_rstream_free(QUIC_RSTREAM *qrs)
  39. {
  40. int cleanse;
  41. if (qrs == NULL)
  42. return;
  43. cleanse = qrs->fl.cleanse;
  44. ossl_sframe_list_destroy(&qrs->fl);
  45. ring_buf_destroy(&qrs->rbuf, cleanse);
  46. OPENSSL_free(qrs);
  47. }
  48. int ossl_quic_rstream_queue_data(QUIC_RSTREAM *qrs, OSSL_QRX_PKT *pkt,
  49. uint64_t offset,
  50. const unsigned char *data, uint64_t data_len,
  51. int fin)
  52. {
  53. UINT_RANGE range;
  54. if ((data == NULL && data_len != 0) || (data_len == 0 && fin == 0)) {
  55. /* empty frame allowed only at the end of the stream */
  56. ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
  57. return 0;
  58. }
  59. range.start = offset;
  60. range.end = offset + data_len;
  61. return ossl_sframe_list_insert(&qrs->fl, &range, pkt, data, fin);
  62. }
  63. static int read_internal(QUIC_RSTREAM *qrs, unsigned char *buf, size_t size,
  64. size_t *readbytes, int *fin, int drop)
  65. {
  66. void *iter = NULL;
  67. UINT_RANGE range;
  68. const unsigned char *data;
  69. uint64_t offset = 0;
  70. size_t readbytes_ = 0;
  71. int fin_ = 0, ret = 1;
  72. while (ossl_sframe_list_peek(&qrs->fl, &iter, &range, &data, &fin_)) {
  73. size_t l = (size_t)(range.end - range.start);
  74. if (l > size) {
  75. l = size;
  76. fin_ = 0;
  77. }
  78. offset = range.start + l;
  79. if (l == 0)
  80. break;
  81. if (data == NULL) {
  82. size_t max_len;
  83. data = ring_buf_get_ptr(&qrs->rbuf, range.start, &max_len);
  84. if (!ossl_assert(data != NULL))
  85. return 0;
  86. if (max_len < l) {
  87. memcpy(buf, data, max_len);
  88. size -= max_len;
  89. buf += max_len;
  90. readbytes_ += max_len;
  91. l -= max_len;
  92. data = ring_buf_get_ptr(&qrs->rbuf, range.start + max_len,
  93. &max_len);
  94. if (!ossl_assert(data != NULL) || !ossl_assert(max_len > l))
  95. return 0;
  96. }
  97. }
  98. memcpy(buf, data, l);
  99. size -= l;
  100. buf += l;
  101. readbytes_ += l;
  102. if (size == 0)
  103. break;
  104. }
  105. if (drop && offset != 0) {
  106. ret = ossl_sframe_list_drop_frames(&qrs->fl, offset);
  107. ring_buf_cpop_range(&qrs->rbuf, 0, offset - 1, qrs->fl.cleanse);
  108. }
  109. if (ret) {
  110. *readbytes = readbytes_;
  111. *fin = fin_;
  112. }
  113. return ret;
  114. }
  115. static OSSL_TIME get_rtt(QUIC_RSTREAM *qrs)
  116. {
  117. OSSL_TIME rtt;
  118. if (qrs->statm != NULL) {
  119. OSSL_RTT_INFO rtt_info;
  120. ossl_statm_get_rtt_info(qrs->statm, &rtt_info);
  121. rtt = rtt_info.smoothed_rtt;
  122. } else {
  123. rtt = ossl_time_zero();
  124. }
  125. return rtt;
  126. }
  127. int ossl_quic_rstream_read(QUIC_RSTREAM *qrs, unsigned char *buf, size_t size,
  128. size_t *readbytes, int *fin)
  129. {
  130. OSSL_TIME rtt = get_rtt(qrs);
  131. if (!read_internal(qrs, buf, size, readbytes, fin, 1))
  132. return 0;
  133. if (qrs->rxfc != NULL
  134. && !ossl_quic_rxfc_on_retire(qrs->rxfc, *readbytes, rtt))
  135. return 0;
  136. return 1;
  137. }
  138. int ossl_quic_rstream_peek(QUIC_RSTREAM *qrs, unsigned char *buf, size_t size,
  139. size_t *readbytes, int *fin)
  140. {
  141. return read_internal(qrs, buf, size, readbytes, fin, 0);
  142. }
  143. int ossl_quic_rstream_available(QUIC_RSTREAM *qrs, size_t *avail, int *fin)
  144. {
  145. void *iter = NULL;
  146. UINT_RANGE range;
  147. const unsigned char *data;
  148. uint64_t avail_ = 0;
  149. while (ossl_sframe_list_peek(&qrs->fl, &iter, &range, &data, fin))
  150. avail_ += range.end - range.start;
  151. #if SIZE_MAX < UINT64_MAX
  152. *avail = avail_ > SIZE_MAX ? SIZE_MAX : (size_t)avail_;
  153. #else
  154. *avail = (size_t)avail_;
  155. #endif
  156. return 1;
  157. }
  158. int ossl_quic_rstream_get_record(QUIC_RSTREAM *qrs,
  159. const unsigned char **record, size_t *rec_len,
  160. int *fin)
  161. {
  162. const unsigned char *record_ = NULL;
  163. size_t rec_len_, max_len;
  164. if (!ossl_sframe_list_lock_head(&qrs->fl, &qrs->head_range, &record_, fin)) {
  165. /* No head frame to lock and return */
  166. *record = NULL;
  167. *rec_len = 0;
  168. return 1;
  169. }
  170. /* if final empty frame, we drop it immediately */
  171. if (qrs->head_range.end == qrs->head_range.start) {
  172. if (!ossl_assert(*fin))
  173. return 0;
  174. if (!ossl_sframe_list_drop_frames(&qrs->fl, qrs->head_range.end))
  175. return 0;
  176. }
  177. rec_len_ = (size_t)(qrs->head_range.end - qrs->head_range.start);
  178. if (record_ == NULL && rec_len_ != 0) {
  179. record_ = ring_buf_get_ptr(&qrs->rbuf, qrs->head_range.start,
  180. &max_len);
  181. if (!ossl_assert(record_ != NULL))
  182. return 0;
  183. if (max_len < rec_len_) {
  184. rec_len_ = max_len;
  185. qrs->head_range.end = qrs->head_range.start + max_len;
  186. }
  187. }
  188. *rec_len = rec_len_;
  189. *record = record_;
  190. return 1;
  191. }
  192. int ossl_quic_rstream_release_record(QUIC_RSTREAM *qrs, size_t read_len)
  193. {
  194. uint64_t offset;
  195. if (!ossl_sframe_list_is_head_locked(&qrs->fl))
  196. return 0;
  197. if (read_len > qrs->head_range.end - qrs->head_range.start) {
  198. if (read_len != SIZE_MAX)
  199. return 0;
  200. offset = qrs->head_range.end;
  201. } else {
  202. offset = qrs->head_range.start + read_len;
  203. }
  204. if (!ossl_sframe_list_drop_frames(&qrs->fl, offset))
  205. return 0;
  206. if (offset > 0)
  207. ring_buf_cpop_range(&qrs->rbuf, 0, offset - 1, qrs->fl.cleanse);
  208. if (qrs->rxfc != NULL) {
  209. OSSL_TIME rtt = get_rtt(qrs);
  210. if (!ossl_quic_rxfc_on_retire(qrs->rxfc, offset, rtt))
  211. return 0;
  212. }
  213. return 1;
  214. }
  215. static int write_at_ring_buf_cb(uint64_t logical_offset,
  216. const unsigned char *buf,
  217. size_t buf_len,
  218. void *cb_arg)
  219. {
  220. struct ring_buf *rbuf = cb_arg;
  221. return ring_buf_write_at(rbuf, logical_offset, buf, buf_len);
  222. }
  223. int ossl_quic_rstream_move_to_rbuf(QUIC_RSTREAM *qrs)
  224. {
  225. if (ring_buf_avail(&qrs->rbuf) == 0)
  226. return 0;
  227. return ossl_sframe_list_move_data(&qrs->fl,
  228. write_at_ring_buf_cb, &qrs->rbuf);
  229. }
  230. int ossl_quic_rstream_resize_rbuf(QUIC_RSTREAM *qrs, size_t rbuf_size)
  231. {
  232. if (ossl_sframe_list_is_head_locked(&qrs->fl))
  233. return 0;
  234. if (!ring_buf_resize(&qrs->rbuf, rbuf_size, qrs->fl.cleanse))
  235. return 0;
  236. return 1;
  237. }
  238. void ossl_quic_rstream_set_cleanse(QUIC_RSTREAM *qrs, int cleanse)
  239. {
  240. qrs->fl.cleanse = cleanse;
  241. }