lsquic_push_promise.h revision bc520ef7
1/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc. See LICENSE. */ 2#ifndef LSQUIC_PUSH_PROMISE_H 3#define LSQUIC_PUSH_PROMISE_H 1 4 5struct lsquic_hash_elem; 6struct lsquic_stream; 7 8 9struct push_promise 10{ 11 /* A push promise is associated with a single stream, while a stream can 12 * have several push promises it depends on. These push promises are 13 * stored on a list. A push promise is destroyed when the dependent 14 * stream is destroyed. This bounds the amount of time when DUPLICATE_PUSH 15 * frames can be sent out. 16 */ 17 SLIST_ENTRY(push_promise) pp_next; 18 /* Push promises are stored a hash and can be searched by ID */ 19 struct lsquic_hash_elem pp_hash_id; 20 uint64_t pp_id; 21 struct lsquic_stream *pp_pushed_stream; 22 size_t pp_content_len; 23 /* Number of streams holding a reference to this push promise. When this 24 * value becomes zero, the push promise is destroyed. See lsquic_pp_put(). 25 * 26 * The stream on which PUSH_PROMISE frame is sent has a reference in its 27 * sm_promises list. The push streams themselves have a reference in 28 * sm_promise. 29 */ 30 unsigned pp_refcnt; 31 /* State for the promise reader. If the state is not PPWS_NONE, we are 32 * in the process of writing the first push promise on sm_promises list 33 * (that's the last promise received). 34 */ 35 enum { 36 PPWS_ID0, /* Write first byte of Push ID */ 37 PPWS_ID1, /* Write second byte of Push ID */ 38 PPWS_ID2, /* Write third byte of Push ID */ 39 PPWS_ID3, /* Write fourth byte of Push ID */ 40 PPWS_ID4, /* Write fifth byte of Push ID */ 41 PPWS_ID5, /* Write sixth byte of Push ID */ 42 PPWS_ID6, /* Write seventh byte of Push ID */ 43 PPWS_ID7, /* Write eighth byte of Push ID */ 44 PPWS_PFX0, /* Write first NUL byte of the Header Block Prefix */ 45 PPWS_PFX1, /* Write second NUL byte of the Header Block Prefix */ 46 PPWS_HBLOCK, /* Write header block -- use sm_push_hblock_off */ 47 PPWS_DONE, 48 } pp_write_state; 49 unsigned pp_write_off; 50 unsigned char pp_encoded_push_id[8]; 51 /* The content buffer is the header block: it does not include Header 52 * Block Prefix. 53 */ 54 unsigned char pp_content_buf[0]; 55}; 56 57 58#define lsquic_pp_put(promise_, all_promises_) do { \ 59 if ((promise_)->pp_refcnt > 0) { \ 60 --(promise_)->pp_refcnt; \ 61 if (0 == (promise_)->pp_refcnt) { \ 62 LSQ_DEBUG("destroy push promise %"PRIu64, (promise_)->pp_id); \ 63 if ((promise_)->pp_hash_id.qhe_flags & QHE_HASHED) \ 64 lsquic_hash_erase(all_promises_, &(promise_)->pp_hash_id); \ 65 free(promise); \ 66 } \ 67 } \ 68 else \ 69 assert(0); \ 70} while (0) 71 72#endif 73