quic_sf_list.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  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. #ifndef OSSL_QUIC_SF_LIST_H
  10. # define OSSL_QUIC_SF_LIST_H
  11. #include "internal/common.h"
  12. #include "internal/uint_set.h"
  13. #include "internal/quic_record_rx.h"
  14. /*
  15. * Stream frame list
  16. * =================
  17. *
  18. * This data structure supports similar operations as uint64 set but
  19. * it has slightly different invariants and also carries data associated with
  20. * the ranges in the list.
  21. *
  22. * Operations:
  23. * Insert frame (optimized insertion at the beginning and at the end).
  24. * Iterated peek into the frame(s) from the beginning.
  25. * Dropping frames from the beginning up to an offset (exclusive).
  26. *
  27. * Invariant: The frames in the list are sorted by the start and end bounds.
  28. * Invariant: There are no fully overlapping frames or frames that would
  29. * be fully encompassed by another frame in the list.
  30. * Invariant: No frame has start > end.
  31. * Invariant: The range start is inclusive the end is exclusive to be
  32. * able to mark an empty frame.
  33. * Invariant: The offset never points further than into the first frame.
  34. */
  35. # ifndef OPENSSL_NO_QUIC
  36. typedef struct stream_frame_st STREAM_FRAME;
  37. typedef struct sframe_list_st {
  38. STREAM_FRAME *head, *tail;
  39. /* Is the tail frame final. */
  40. unsigned int fin;
  41. /* Number of stream frames in the list. */
  42. size_t num_frames;
  43. /* Offset of data not yet dropped */
  44. uint64_t offset;
  45. /* Is head locked ? */
  46. int head_locked;
  47. /* Cleanse data on release? */
  48. int cleanse;
  49. } SFRAME_LIST;
  50. /*
  51. * Initializes the stream frame list fl.
  52. */
  53. void ossl_sframe_list_init(SFRAME_LIST *fl);
  54. /*
  55. * Destroys the stream frame list fl releasing any data
  56. * still present inside it.
  57. */
  58. void ossl_sframe_list_destroy(SFRAME_LIST *fl);
  59. /*
  60. * Insert a stream frame data into the list.
  61. * The data covers an offset range (range.start is inclusive,
  62. * range.end is exclusive).
  63. * fin should be set if this is the final frame of the stream.
  64. * Returns an error if a frame cannot be inserted - due to
  65. * STREAM_FRAME allocation error, or in case of erroneous
  66. * fin flag (this is an ossl_assert() check so a caller must
  67. * check it on its own too).
  68. */
  69. int ossl_sframe_list_insert(SFRAME_LIST *fl, UINT_RANGE *range,
  70. OSSL_QRX_PKT *pkt,
  71. const unsigned char *data, int fin);
  72. /*
  73. * Iterator to peek at the contiguous frames at the beginning
  74. * of the frame list fl.
  75. * The *data covers an offset range (range.start is inclusive,
  76. * range.end is exclusive).
  77. * *fin is set if this is the final frame of the stream.
  78. * Opaque iterator *iter can be used to peek at the subsequent
  79. * frame if there is any without any gap before it.
  80. * Returns 1 on success.
  81. * Returns 0 if there is no further contiguous frame. In that
  82. * case *fin is set, if the end of the stream is reached.
  83. */
  84. int ossl_sframe_list_peek(const SFRAME_LIST *fl, void **iter,
  85. UINT_RANGE *range, const unsigned char **data,
  86. int *fin);
  87. /*
  88. * Drop all frames up to the offset limit.
  89. * Also unlocks the head frame if locked.
  90. * Returns 1 on success.
  91. * Returns 0 when trying to drop frames at offsets that were not
  92. * received yet. (ossl_assert() is used to check, so this is an invalid call.)
  93. */
  94. int ossl_sframe_list_drop_frames(SFRAME_LIST *fl, uint64_t limit);
  95. /*
  96. * Locks and returns the head frame of fl if it is readable - read offset is
  97. * at the beginning or middle of the frame.
  98. * range is set to encompass the not yet read part of the head frame,
  99. * data pointer is set to appropriate offset within the frame if the read
  100. * offset points in the middle of the frame,
  101. * fin is set to 1 if the head frame is also the tail frame.
  102. * Returns 1 on success, 0 if there is no readable data or the head
  103. * frame is already locked.
  104. */
  105. int ossl_sframe_list_lock_head(SFRAME_LIST *fl, UINT_RANGE *range,
  106. const unsigned char **data,
  107. int *fin);
  108. /*
  109. * Just returns whether the head frame is locked by previous
  110. * ossl_sframe_list_lock_head() call.
  111. */
  112. int ossl_sframe_list_is_head_locked(SFRAME_LIST *fl);
  113. /*
  114. * Callback function type to write stream frame data to some
  115. * side storage before the packet containing the frame data
  116. * is released.
  117. * It should return 1 on success or 0 if there is not enough
  118. * space available in the side storage.
  119. */
  120. typedef int (sframe_list_write_at_cb)(uint64_t logical_offset,
  121. const unsigned char *buf,
  122. size_t buf_len,
  123. void *cb_arg);
  124. /*
  125. * Move the frame data in all the stream frames in the list fl
  126. * from the packets to the side storage using the write_at_cb
  127. * callback.
  128. * Returns 1 if all the calls to the callback return 1.
  129. * If the callback returns 0, the function stops processing further
  130. * frames and returns 0.
  131. */
  132. int ossl_sframe_list_move_data(SFRAME_LIST *fl,
  133. sframe_list_write_at_cb *write_at_cb,
  134. void *cb_arg);
  135. # endif
  136. #endif