quic_demux.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  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_DEMUX_H
  10. # define OSSL_QUIC_DEMUX_H
  11. # include <openssl/ssl.h>
  12. # include "internal/quic_types.h"
  13. # include "internal/bio_addr.h"
  14. # include "internal/time.h"
  15. # include "internal/list.h"
  16. # ifndef OPENSSL_NO_QUIC
  17. /*
  18. * QUIC Demuxer
  19. * ============
  20. *
  21. * The QUIC connection demuxer is the entity responsible for receiving datagrams
  22. * from the network via a datagram BIO. It parses packet headers to determine
  23. * each packet's destination connection ID (DCID) and hands off processing of
  24. * the packet to the correct QUIC Record Layer (QRL)'s RX side (known as the
  25. * QRX).
  26. *
  27. * A QRX is instantiated per QUIC connection and contains the cryptographic
  28. * resources needed to decrypt QUIC packets for that connection. Received
  29. * datagrams are passed from the demuxer to the QRX via a callback registered
  30. * for a specific DCID by the QRX; thus the demuxer has no specific knowledge of
  31. * the QRX and is not coupled to it.
  32. *
  33. * A connection may have multiple connection IDs associated with it; a QRX
  34. * handles this simply by registering multiple connection IDs with the demuxer
  35. * via multiple register calls.
  36. *
  37. * URX Queue
  38. * ---------
  39. *
  40. * Since the demuxer must handle the initial reception of datagrams from the OS,
  41. * RX queue management for new, unprocessed datagrams is also handled by the
  42. * demuxer.
  43. *
  44. * The demuxer maintains a queue of Unprocessed RX Entries (URXEs), which store
  45. * unprocessed (i.e., encrypted, unvalidated) data received from the network.
  46. * The URXE queue is designed to allow multiple datagrams to be received in a
  47. * single call to BIO_recvmmsg, where supported.
  48. *
  49. * One URXE is used per received datagram. Each datagram may contain multiple
  50. * packets, however, this is not the demuxer's concern. QUIC prohibits different
  51. * packets in the same datagram from containing different DCIDs; the demuxer
  52. * only considers the DCID of the first packet in a datagram when deciding how
  53. * to route a received datagram, and it is the responsibility of the QRX to
  54. * enforce this rule. Packets other than the first packet in a datagram are not
  55. * examined by the demuxer, and the demuxer does not perform validation of
  56. * packet headers other than to the minimum extent necessary to extract the
  57. * DCID; further parsing and validation of packet headers is the responsibility
  58. * of the QRX.
  59. *
  60. * Rather than defining an opaque interface, the URXE structure internals
  61. * are exposed. Since the demuxer is only exposed to other parts of the QUIC
  62. * implementation internals, this poses no problem, and has a number of
  63. * advantages:
  64. *
  65. * - Fields in the URXE can be allocated to support requirements in other
  66. * components, like the QRX, which would otherwise have to allocate extra
  67. * memory corresponding to each URXE.
  68. *
  69. * - Other components, like the QRX, can keep the URXE in queues of its own
  70. * when it is not being managed by the demuxer.
  71. *
  72. * URX Queue Structure
  73. * -------------------
  74. *
  75. * The URXE queue is maintained as a simple doubly-linked list. URXE entries are
  76. * moved between different lists in their lifecycle (for example, from a free
  77. * list to a pending list and vice versa). The buffer into which datagrams are
  78. * received immediately follows this URXE header structure and is part of the
  79. * same allocation.
  80. */
  81. typedef struct quic_urxe_st QUIC_URXE;
  82. /* Maximum number of packets we allow to exist in one datagram. */
  83. #define QUIC_MAX_PKT_PER_URXE (sizeof(uint64_t) * 8)
  84. struct quic_urxe_st {
  85. OSSL_LIST_MEMBER(urxe, QUIC_URXE);
  86. /*
  87. * The URXE data starts after this structure so we don't need a pointer.
  88. * data_len stores the current length (i.e., the length of the received
  89. * datagram) and alloc_len stores the allocation length. The URXE will be
  90. * reallocated if we need a larger allocation than is available, though this
  91. * should not be common as we will have a good idea of worst-case MTUs up
  92. * front.
  93. */
  94. size_t data_len, alloc_len;
  95. /*
  96. * Bitfields per packet. processed indicates the packet has been processed
  97. * and must not be processed again, hpr_removed indicates header protection
  98. * has already been removed. Used by QRX only; not used by the demuxer.
  99. */
  100. uint64_t processed, hpr_removed;
  101. /*
  102. * Address of peer we received the datagram from, and the local interface
  103. * address we received it on. If local address support is not enabled, local
  104. * is zeroed.
  105. */
  106. BIO_ADDR peer, local;
  107. /*
  108. * Time at which datagram was received (or ossl_time_zero()) if a now
  109. * function was not provided).
  110. */
  111. OSSL_TIME time;
  112. /*
  113. * Used by the QRX to mark whether a datagram has been deferred. Used by the
  114. * QRX only; not used by the demuxer.
  115. */
  116. char deferred;
  117. /*
  118. * Used by the DEMUX to track if a URXE has been handed out. Used primarily
  119. * for debugging purposes.
  120. */
  121. char demux_state;
  122. };
  123. /* Accessors for URXE buffer. */
  124. static ossl_unused ossl_inline unsigned char *
  125. ossl_quic_urxe_data(const QUIC_URXE *e)
  126. {
  127. return (unsigned char *)&e[1];
  128. }
  129. static ossl_unused ossl_inline unsigned char *
  130. ossl_quic_urxe_data_end(const QUIC_URXE *e)
  131. {
  132. return ossl_quic_urxe_data(e) + e->data_len;
  133. }
  134. /* List structure tracking a queue of URXEs. */
  135. DEFINE_LIST_OF(urxe, QUIC_URXE);
  136. typedef OSSL_LIST(urxe) QUIC_URXE_LIST;
  137. /*
  138. * List management helpers. These are used by the demuxer but can also be used
  139. * by users of the demuxer to manage URXEs.
  140. */
  141. void ossl_quic_urxe_remove(QUIC_URXE_LIST *l, QUIC_URXE *e);
  142. void ossl_quic_urxe_insert_head(QUIC_URXE_LIST *l, QUIC_URXE *e);
  143. void ossl_quic_urxe_insert_tail(QUIC_URXE_LIST *l, QUIC_URXE *e);
  144. /* Opaque type representing a demuxer. */
  145. typedef struct quic_demux_st QUIC_DEMUX;
  146. /*
  147. * Called when a datagram is received for a given connection ID.
  148. *
  149. * e is a URXE containing the datagram payload. It is permissible for the callee
  150. * to mutate this buffer; once the demuxer calls this callback, it will never
  151. * read the buffer again.
  152. *
  153. * The callee must arrange for ossl_quic_demux_release_urxe or
  154. * ossl_quic_demux_reinject_urxe to be called on the URXE at some point in the
  155. * future (this need not be before the callback returns).
  156. *
  157. * At the time the callback is made, the URXE will not be in any queue,
  158. * therefore the callee can use the prev and next fields as it wishes.
  159. */
  160. typedef void (ossl_quic_demux_cb_fn)(QUIC_URXE *e, void *arg);
  161. /*
  162. * Called when a datagram is received.
  163. * Returns 1 if the datagram ends with a stateless reset token and
  164. * 0 if not.
  165. */
  166. typedef int (ossl_quic_stateless_reset_cb_fn)(const unsigned char *data,
  167. size_t data_len, void *arg);
  168. /*
  169. * Creates a new demuxer. The given BIO is used to receive datagrams from the
  170. * network using BIO_recvmmsg. short_conn_id_len is the length of destination
  171. * connection IDs used in RX'd packets; it must have the same value for all
  172. * connections used on a socket. default_urxe_alloc_len is the buffer size to
  173. * receive datagrams into; it should be a value large enough to contain any
  174. * received datagram according to local MTUs, etc.
  175. *
  176. * now is an optional function used to determine the time a datagram was
  177. * received. now_arg is an opaque argument passed to the function. If now is
  178. * NULL, ossl_time_zero() is used as the datagram reception time.
  179. */
  180. QUIC_DEMUX *ossl_quic_demux_new(BIO *net_bio,
  181. size_t short_conn_id_len,
  182. OSSL_TIME (*now)(void *arg),
  183. void *now_arg);
  184. /*
  185. * Destroy a demuxer. All URXEs must have been released back to the demuxer
  186. * before calling this. No-op if demux is NULL.
  187. */
  188. void ossl_quic_demux_free(QUIC_DEMUX *demux);
  189. /*
  190. * Changes the BIO which the demuxer reads from. This also sets the MTU if the
  191. * BIO supports querying the MTU.
  192. */
  193. void ossl_quic_demux_set_bio(QUIC_DEMUX *demux, BIO *net_bio);
  194. /*
  195. * Changes the MTU in bytes we use to receive datagrams.
  196. */
  197. int ossl_quic_demux_set_mtu(QUIC_DEMUX *demux, unsigned int mtu);
  198. /*
  199. * Register a datagram handler callback for a connection ID.
  200. *
  201. * ossl_quic_demux_pump will call the specified function if it receives a datagram
  202. * the first packet of which has the specified destination connection ID.
  203. *
  204. * It is assumed all packets in a datagram have the same destination connection
  205. * ID (as QUIC mandates this), but it is the user's responsibility to check for
  206. * this and reject subsequent packets in a datagram that violate this rule.
  207. *
  208. * dst_conn_id is a destination connection ID; it is copied and need not remain
  209. * valid after this function returns.
  210. *
  211. * cb_arg is passed to cb when it is called. For information on the callback,
  212. * see its typedef above.
  213. *
  214. * Only one handler can be set for a given connection ID. If a handler is
  215. * already set for the given connection ID, returns 0.
  216. *
  217. * Returns 1 on success or 0 on failure.
  218. */
  219. int ossl_quic_demux_register(QUIC_DEMUX *demux,
  220. const QUIC_CONN_ID *dst_conn_id,
  221. ossl_quic_demux_cb_fn *cb,
  222. void *cb_arg);
  223. /*
  224. * Unregisters any datagram handler callback set for the given connection ID.
  225. * Fails if no handler is registered for the given connection ID.
  226. *
  227. * Returns 1 on success or 0 on failure.
  228. */
  229. int ossl_quic_demux_unregister(QUIC_DEMUX *demux,
  230. const QUIC_CONN_ID *dst_conn_id);
  231. /*
  232. * Unregisters any datagram handler callback from all connection IDs it is used
  233. * for. cb and cb_arg must both match the values passed to
  234. * ossl_quic_demux_register.
  235. */
  236. void ossl_quic_demux_unregister_by_cb(QUIC_DEMUX *demux,
  237. ossl_quic_demux_cb_fn *cb,
  238. void *cb_arg);
  239. /*
  240. * Set the default packet handler. This is used for incoming packets which don't
  241. * match a registered DCID. This is only needed for servers. If a default packet
  242. * handler is not set, a packet which doesn't match a registered DCID is
  243. * silently dropped. A default packet handler may be unset by passing NULL.
  244. *
  245. * The handler is responsible for ensuring that ossl_quic_demux_reinject_urxe or
  246. * ossl_quic_demux_release_urxe is called on the passed packet at some point in
  247. * the future, which may or may not be before the handler returns.
  248. */
  249. void ossl_quic_demux_set_default_handler(QUIC_DEMUX *demux,
  250. ossl_quic_demux_cb_fn *cb,
  251. void *cb_arg);
  252. /*
  253. * Sets a callback for stateless reset processing.
  254. *
  255. * If set, this callback is called for datagrams for which we cannot identify
  256. * a CID. This function should return 1 if there is a stateless reset token
  257. * present and 0 if not. If there is a token present, the connection should
  258. * also be reset.
  259. */
  260. void ossl_quic_demux_set_stateless_reset_handler(
  261. QUIC_DEMUX *demux,
  262. ossl_quic_stateless_reset_cb_fn *cb, void *cb_arg);
  263. /*
  264. * Releases a URXE back to the demuxer. No reference must be made to the URXE or
  265. * its buffer after calling this function. The URXE must not be in any queue;
  266. * that is, its prev and next pointers must be NULL.
  267. */
  268. void ossl_quic_demux_release_urxe(QUIC_DEMUX *demux,
  269. QUIC_URXE *e);
  270. /*
  271. * Reinjects a URXE which was issued to a registered DCID callback or the
  272. * default packet handler callback back into the pending queue. This is useful
  273. * when a packet has been handled by the default packet handler callback such
  274. * that a DCID has now been registered and can be dispatched normally by DCID.
  275. * Once this has been called, the caller must not touch the URXE anymore and
  276. * must not also call ossl_quic_demux_release_urxe().
  277. *
  278. * The URXE is reinjected at the head of the queue, so it will be reprocessed
  279. * immediately.
  280. */
  281. void ossl_quic_demux_reinject_urxe(QUIC_DEMUX *demux,
  282. QUIC_URXE *e);
  283. /*
  284. * Process any unprocessed RX'd datagrams, by calling registered callbacks by
  285. * connection ID, reading more datagrams from the BIO if necessary.
  286. *
  287. * Returns one of the following values:
  288. *
  289. * QUIC_DEMUX_PUMP_RES_OK
  290. * At least one incoming datagram was processed.
  291. *
  292. * QUIC_DEMUX_PUMP_RES_TRANSIENT_FAIL
  293. * No more incoming datagrams are currently available.
  294. * Call again later.
  295. *
  296. * QUIC_DEMUX_PUMP_RES_PERMANENT_FAIL
  297. * Either the network read BIO has failed in a non-transient fashion, or
  298. * the QUIC implementation has encountered an internal state, assertion
  299. * or allocation error. The caller should tear down the connection
  300. * similarly to in the case of a protocol violation.
  301. *
  302. */
  303. #define QUIC_DEMUX_PUMP_RES_OK 1
  304. #define QUIC_DEMUX_PUMP_RES_TRANSIENT_FAIL (-1)
  305. #define QUIC_DEMUX_PUMP_RES_PERMANENT_FAIL (-2)
  306. #define QUIC_DEMUX_PUMP_RES_STATELESS_RESET (-3)
  307. int ossl_quic_demux_pump(QUIC_DEMUX *demux);
  308. /*
  309. * Artificially inject a packet into the demuxer for testing purposes. The
  310. * buffer must not exceed the URXE size being used by the demuxer.
  311. *
  312. * If peer or local are NULL, their respective fields are zeroed in the injected
  313. * URXE.
  314. *
  315. * Returns 1 on success or 0 on failure.
  316. */
  317. int ossl_quic_demux_inject(QUIC_DEMUX *demux,
  318. const unsigned char *buf,
  319. size_t buf_len,
  320. const BIO_ADDR *peer,
  321. const BIO_ADDR *local);
  322. /*
  323. * Returns 1 if there are any pending URXEs.
  324. */
  325. int ossl_quic_demux_has_pending(const QUIC_DEMUX *demux);
  326. # endif
  327. #endif