quic_stream_map.h 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /*
  2. * Copyright 2022 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_INTERNAL_QUIC_STREAM_MAP_H
  10. # define OSSL_INTERNAL_QUIC_STREAM_MAP_H
  11. # pragma once
  12. #include "internal/e_os.h"
  13. #include "internal/time.h"
  14. #include "internal/quic_types.h"
  15. #include "internal/quic_stream.h"
  16. #include "internal/quic_fc.h"
  17. #include <openssl/lhash.h>
  18. /*
  19. * QUIC Stream
  20. * ===========
  21. *
  22. * Logical QUIC stream composing all relevant send and receive components.
  23. */
  24. typedef struct quic_stream_st QUIC_STREAM;
  25. typedef struct quic_stream_list_node_st QUIC_STREAM_LIST_NODE;
  26. struct quic_stream_list_node_st {
  27. QUIC_STREAM_LIST_NODE *prev, *next;
  28. };
  29. struct quic_stream_st {
  30. QUIC_STREAM_LIST_NODE active_node; /* for use by QUIC_STREAM_MAP */
  31. /* Temporary link used by TXP. */
  32. QUIC_STREAM *txp_next;
  33. /*
  34. * QUIC Stream ID. Do not assume that this encodes a type as this is a
  35. * version-specific property and may change between QUIC versions; instead,
  36. * use the type field.
  37. */
  38. uint64_t id;
  39. /*
  40. * Application Error Code (AEC) used for STOP_SENDING frame.
  41. * This is only valid if stop_sending is 1.
  42. */
  43. uint64_t stop_sending_aec;
  44. /*
  45. * Application Error Code (AEC) used for RESET_STREAM frame.
  46. * This is only valid if reset_stream is 1.
  47. */
  48. uint64_t reset_stream_aec;
  49. /* Temporary value used by TXP. */
  50. uint64_t txp_txfc_new_credit_consumed;
  51. QUIC_SSTREAM *sstream; /* NULL if RX-only */
  52. void *rstream; /* NULL if TX only (placeholder) */
  53. QUIC_TXFC txfc; /* NULL if RX-only */
  54. QUIC_RXFC rxfc; /* NULL if TX-only */
  55. unsigned int type : 8; /* QUIC_STREAM_INITIATOR_*, QUIC_STREAM_DIR_* */
  56. unsigned int active : 1;
  57. /*
  58. * Has STOP_SENDING been requested? Note that this is not the same as
  59. * want_stop_sending below, as a STOP_SENDING frame may already have been
  60. * sent and fully acknowledged.
  61. */
  62. unsigned int stop_sending : 1;
  63. /*
  64. * Has RESET_STREAM been requested? Works identically to STOP_SENDING for
  65. * transmission purposes.
  66. */
  67. unsigned int reset_stream : 1;
  68. /* Temporary flags used by TXP. */
  69. unsigned int txp_sent_fc : 1;
  70. unsigned int txp_sent_stop_sending : 1;
  71. unsigned int txp_sent_reset_stream : 1;
  72. unsigned int txp_drained : 1;
  73. unsigned int txp_blocked : 1;
  74. /* Frame regeneration flags. */
  75. unsigned int want_max_stream_data : 1; /* used for regen only */
  76. unsigned int want_stop_sending : 1; /* used for gen or regen */
  77. unsigned int want_reset_stream : 1; /* used for gen or regen */
  78. };
  79. /*
  80. * Marks a stream for STOP_SENDING. aec is the application error code (AEC).
  81. * This can only fail if it has already been called.
  82. */
  83. int ossl_quic_stream_stop_sending(QUIC_STREAM *s, uint64_t aec);
  84. /*
  85. * Marks a stream for reset. aec is the application error code (AEC).
  86. * This can only fail if it has already been called.
  87. */
  88. int ossl_quic_stream_reset(QUIC_STREAM *s, uint64_t aec);
  89. /*
  90. * QUIC Stream Map
  91. * ===============
  92. *
  93. * The QUIC stream map:
  94. *
  95. * - maps stream IDs to QUIC_STREAM objects;
  96. * - tracks which streams are 'active' (currently have data for transmission);
  97. * - allows iteration over the active streams only.
  98. *
  99. */
  100. typedef struct quic_stream_map_st {
  101. LHASH_OF(QUIC_STREAM) *map;
  102. QUIC_STREAM_LIST_NODE active_list;
  103. size_t rr_stepping, rr_counter;
  104. QUIC_STREAM *rr_cur;
  105. } QUIC_STREAM_MAP;
  106. int ossl_quic_stream_map_init(QUIC_STREAM_MAP *qsm);
  107. /*
  108. * Any streams still in the map will be released as though
  109. * ossl_quic_stream_map_release was called on them.
  110. */
  111. void ossl_quic_stream_map_cleanup(QUIC_STREAM_MAP *qsm);
  112. #define QUIC_STREAM_INITIATOR_CLIENT 0
  113. #define QUIC_STREAM_INITIATOR_SERVER 1
  114. #define QUIC_STREAM_INITIATOR_MASK 1
  115. #define QUIC_STREAM_DIR_BIDI 0
  116. #define QUIC_STREAM_DIR_UNI 2
  117. #define QUIC_STREAM_DIR_MASK 2
  118. /*
  119. * Allocate a new stream. type is a combination of one QUIC_STREAM_INITIATOR_*
  120. * value and one QUIC_STREAM_DIR_* value. Note that clients can e.g. allocate
  121. * server-initiated streams as they will need to allocate a QUIC_STREAM
  122. * structure to track any stream created by the server, etc.
  123. *
  124. * stream_id must be a valid value. Returns NULL if a stream already exists
  125. * with the given ID.
  126. */
  127. QUIC_STREAM *ossl_quic_stream_map_alloc(QUIC_STREAM_MAP *qsm,
  128. uint64_t stream_id,
  129. int type);
  130. /*
  131. * Releases a stream object. Note that this must only be done once the teardown
  132. * process is entirely complete and the object will never be referenced again.
  133. */
  134. void ossl_quic_stream_map_release(QUIC_STREAM_MAP *qsm, QUIC_STREAM *stream);
  135. /*
  136. * Calls visit_cb() for each stream in the map. visit_cb_arg is an opaque
  137. * argument which is passed through.
  138. */
  139. void ossl_quic_stream_map_visit(QUIC_STREAM_MAP *qsm,
  140. void (*visit_cb)(QUIC_STREAM *stream, void *arg),
  141. void *visit_cb_arg);
  142. /*
  143. * Retrieves a stream by stream ID. Returns NULL if it does not exist.
  144. */
  145. QUIC_STREAM *ossl_quic_stream_map_get_by_id(QUIC_STREAM_MAP *qsm,
  146. uint64_t stream_id);
  147. /*
  148. * Marks the given stream as active or inactive based on its state. Idempotent.
  149. *
  150. * When a stream is marked active, it becomes available in the iteration list,
  151. * and when a stream is marked inactive, it no longer appears in the iteration
  152. * list.
  153. *
  154. * Calling this function invalidates any iterator currently pointing at the
  155. * given stream object, but iterators not currently pointing at the given stream
  156. * object are not invalidated.
  157. */
  158. void ossl_quic_stream_map_update_state(QUIC_STREAM_MAP *qsm, QUIC_STREAM *s);
  159. /*
  160. * Sets the RR stepping value, n. The RR rotation will be advanced every n
  161. * packets. The default value is 1.
  162. */
  163. void ossl_quic_stream_map_set_rr_stepping(QUIC_STREAM_MAP *qsm, size_t stepping);
  164. /*
  165. * QUIC Stream Iterator
  166. * ====================
  167. *
  168. * Allows the current set of active streams to be walked using a RR-based
  169. * algorithm. Each time ossl_quic_stream_iter_init is called, the RR algorithm
  170. * is stepped. The RR algorithm rotates the iteration order such that the next
  171. * active stream is returned first after n calls to ossl_quic_stream_iter_init,
  172. * where n is the stepping value configured via
  173. * ossl_quic_stream_map_set_rr_stepping.
  174. *
  175. * Suppose there are three active streams and the configured stepping is n:
  176. *
  177. * Iteration 0n: [Stream 1] [Stream 2] [Stream 3]
  178. * Iteration 1n: [Stream 2] [Stream 3] [Stream 1]
  179. * Iteration 2n: [Stream 3] [Stream 1] [Stream 2]
  180. *
  181. */
  182. typedef struct quic_stream_iter_st {
  183. QUIC_STREAM_MAP *qsm;
  184. QUIC_STREAM *first_stream, *stream;
  185. } QUIC_STREAM_ITER;
  186. /*
  187. * Initialise an iterator, advancing the RR algorithm as necessary (if
  188. * advance_rr is 1). After calling this, it->stream will be the first stream in
  189. * the iteration sequence, or NULL if there are no active streams.
  190. */
  191. void ossl_quic_stream_iter_init(QUIC_STREAM_ITER *it, QUIC_STREAM_MAP *qsm,
  192. int advance_rr);
  193. /*
  194. * Advances to next stream in iteration sequence. You do not need to call this
  195. * immediately after calling ossl_quic_stream_iter_init(). If the end of the
  196. * list is reached, it->stream will be NULL after calling this.
  197. */
  198. void ossl_quic_stream_iter_next(QUIC_STREAM_ITER *it);
  199. #endif