1/*
2 * lsqpack.h - QPACK library
3 */
4
5/*
6MIT License
7
8Copyright (c) 2018 - 2022 LiteSpeed Technologies Inc
9
10Permission is hereby granted, free of charge, to any person obtaining a copy
11of this software and associated documentation files (the "Software"), to deal
12in the Software without restriction, including without limitation the rights
13to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14copies of the Software, and to permit persons to whom the Software is
15furnished to do so, subject to the following conditions:
16
17The above copyright notice and this permission notice shall be included in all
18copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26SOFTWARE.
27*/
28
29#ifndef LSQPACK_H
30#define LSQPACK_H 1
31
32#ifdef __cplusplus
33extern "C" {
34#endif
35
36#include <limits.h>
37#include <stdint.h>
38#include <stdio.h>
39
40#if defined(_MSC_VER)
41#include <BaseTsd.h>
42typedef SSIZE_T ssize_t;
43#endif
44
45#define LSQPACK_MAJOR_VERSION 2
46#define LSQPACK_MINOR_VERSION 3
47#define LSQPACK_PATCH_VERSION 0
48
49/** Let's start with four billion for now */
50typedef unsigned lsqpack_abs_id_t;
51
52#define LSQPACK_MAX_ABS_ID (~((lsqpack_abs_id_t) 0))
53
54#define LSQPACK_DEF_DYN_TABLE_SIZE      0
55#define LSQPACK_DEF_MAX_RISKED_STREAMS  0
56
57struct lsqpack_enc;
58struct lsqpack_dec;
59struct lsxpack_header;
60
61enum lsqpack_enc_opts
62{
63    /**
64     * Client and server follow different heuristics.  The encoder is either
65     * in one or the other mode.
66     *
67     * At the moment this option is a no-op.  This is a potential future
68     * work item where some heuristics may be added to the library.
69     */
70    LSQPACK_ENC_OPT_SERVER  = 1 << 0,
71
72    /**
73     * The encoder was pre-initialized using @ref lsqpack_enc_preinit() and
74     * so some initialization steps can be skipped.
75     */
76    LSQPACK_ENC_OPT_STAGE_2 = 1 << 1,
77
78    /* The options below are advanced.  The author only uses them for debugging
79     * or testing.
80     */
81
82    /**
83     * Disable emitting dup instructions.
84     *
85     * Disabling dup instructions usually makes compression performance
86     * significanly worse.  Do not use unless you know what you are doing.
87     */
88    LSQPACK_ENC_OPT_NO_DUP  = 1 << 2,
89
90    /**
91     * Index aggressively: ignore history
92     *
93     * Ignoring history usually makes compression performance significanly
94     * worse.  Do not use unless you know what you are doing.
95     */
96    LSQPACK_ENC_OPT_IX_AGGR = 1 << 3,
97
98    /**
99     * Turn off memory guard: keep on allocating state tracking oustanding
100     * headers even if they never get acknowledged.
101     *
102     * This is useful for some forms of testing.
103     */
104    LSQPACK_ENC_OPT_NO_MEM_GUARD = 1 << 4,
105};
106
107
108/**
109 * Initialize the encoder so that it can be used without using the
110 * dynamic table.  Once peer's settings are known, call
111 * @ref lsqpack_enc_init().
112 *
113 * `logger_ctx' can be set to NULL if no special logging is set up.
114 */
115void
116lsqpack_enc_preinit (struct lsqpack_enc *, void *logger_ctx);
117
118/**
119 * Number of bytes required to encode the longest possible Set Dynamic Table
120 * Capacity instruction.  This is a theoretical limit based on the integral
121 * type (unsigned int) used by this library to store the capacity value.  If
122 * the encoder is initialized with a smaller maximum table capacity, it is
123 * safe to use fewer bytes.
124 *
125 * SDTC instructtion can be produced by @ref lsqpack_enc_init() and
126 * @ref lsqpack_enc_set_max_capacity().
127 */
128#if UINT_MAX == 65535
129#define LSQPACK_LONGEST_SDTC 4
130#elif UINT_MAX == 4294967295
131#define LSQPACK_LONGEST_SDTC 6
132#elif UINT_MAX == 18446744073709551615ULL
133#define LSQPACK_LONGEST_SDTC 11
134#else
135#error unexpected sizeof(unsigned)
136#endif
137
138int
139lsqpack_enc_init (struct lsqpack_enc *,
140    /** `logger_ctx' can be set to NULL if no special logging is set up. */
141    void *logger_ctx,
142    /**
143     * As specified by the decoder.  This value is used to calculate
144     * MaxEntries.
145     */
146    unsigned max_table_size,
147    /**
148     * Actual dynamic table size to use.
149     */
150    unsigned dyn_table_size,
151    unsigned max_risked_streams, enum lsqpack_enc_opts,
152    /**
153     * If `dyn_table_size' is not zero, Set Dynamic Table Capacity (SDTC)
154     * instruction is generated and placed into `sdtc_buf'.  `sdtc_buf_sz'
155     * parameter is used both for input and output.
156     *
157     * If `dyn_table_size' is zero, `sdtc_buf' and `sdtc_buf_sz' are optional
158     * and can be set to NULL.
159     */
160    unsigned char *sdtc_buf, size_t *sdtc_buf_sz);
161
162/**
163 * Set table size to `capacity'.  If necessary, Set Dynamic Table Capacity
164 * (SDTC) instruction is generated and placed into `tsu_buf'.  If `capacity'
165 * is larger than the maximum table size specified during initialization, an
166 * error is returned.
167 */
168int
169lsqpack_enc_set_max_capacity (struct lsqpack_enc *enc, unsigned capacity,
170                                    unsigned char *sdtc_buf, size_t *sdtc_buf_sz);
171
172/** Start a new header block.  Return 0 on success or -1 on error. */
173int
174lsqpack_enc_start_header (struct lsqpack_enc *, uint64_t stream_id,
175                            unsigned seqno);
176
177/** Status returned by @ref lsqpack_enc_encode() */
178enum lsqpack_enc_status
179{
180    /** Header field encoded successfully */
181    LQES_OK,
182    /** There was not enough room in the encoder stream buffer */
183    LQES_NOBUF_ENC,
184    /** There was not enough room in the header block buffer */
185    LQES_NOBUF_HEAD,
186};
187
188enum lsqpack_enc_flags
189{
190    /**
191     * Do not index this header field.  No output to the encoder stream
192     * will be produced.
193     */
194    LQEF_NO_INDEX    = 1 << 0,
195    /**
196     * Never index this field.  This will set the 'N' bit on Literal Header
197     * Field With Name Reference, Literal Header Field With Post-Base Name
198     * Reference, and Literal Header Field Without Name Reference instructions
199     * in the header block.  Implies LQEF_NO_INDEX.
200     */
201    LQEF_NEVER_INDEX = 1 << 1,
202    /**
203     * Do not update history.
204     */
205    LQEF_NO_HIST_UPD = 1 << 2,
206    /**
207     * Do not use the dynamic table.  This is stricter than LQEF_NO_INDEX:
208     * this means that the dynamic table will be neither referenced nor
209     * modified.
210     */
211    LQEF_NO_DYN      = 1 << 3,
212};
213
214/**
215 * Encode header field into current header block.
216 *
217 * See @ref lsqpack_enc_status for explanation of the return values.
218 *
219 * enc_sz and header_sz parameters are used for both input and output.  If
220 * the return value is LQES_OK, they contain number of bytes written to
221 * enc_buf and header_buf, respectively.  enc_buf contains the bytes that
222 * must be written to the encoder stream; header_buf contains bytes that
223 * must be written to the header block.
224 *
225 * Note that even though this function may allocate memory, it falls back to
226 * not using the dynamic table should memory allocation fail.  Thus, failures
227 * to encode due to not enough memory do not exist.
228 */
229enum lsqpack_enc_status
230lsqpack_enc_encode (struct lsqpack_enc *,
231    unsigned char *enc_buf, size_t *enc_sz,
232    unsigned char *header_buf, size_t *header_sz,
233    const struct lsxpack_header *,
234    enum lsqpack_enc_flags flags);
235
236/**
237 * Cancel current header block. Cancellation is only allowed if the dynamic
238 * table is not used. Returns 0 on success, -1 on failure.
239 */
240int
241lsqpack_enc_cancel_header (struct lsqpack_enc *);
242
243
244/**
245 * Properties of the current header block
246 */
247enum lsqpack_enc_header_flags
248{
249    /** Set if there are at-risk references in this header block */
250    LSQECH_REF_AT_RISK      = 1 << 0,
251    /** Set if the header block references newly inserted entries */
252    LSQECH_REF_NEW_ENTRIES  = 1 << 1,
253    /** Set if min-reffed value is cached */
254    LSQECH_MINREF_CACHED    = 1 << 2,
255};
256
257
258/**
259 * End current header block.  The Header Block Prefix is written to `buf'.
260 *
261 * `buf' must be at least two bytes.  11 bytes are necessary to encode
262 * UINT64_MAX using 7- or 8-bit prefix.  Therefore, 22 bytes is the
263 * theoretical maximum for this library.
264 *
265 * Use @ref lsqpack_enc_header_block_prefix_size() if you require better
266 * precision.
267 *
268 * Returns:
269 *  -   A positive value indicates success and is the number of bytes
270 *      written to `buf'.
271 *  -   Zero means that there is not enough room in `buf' to write out the
272 *      full prefix.
273 *  -   A negative value means an error.  This is returned if there is no
274 *      started header to end.
275 *
276 * If header was ended successfully and @ref flags is not NULL, it is
277 * assigned properties of the header block.
278 */
279ssize_t
280lsqpack_enc_end_header (struct lsqpack_enc *, unsigned char *buf, size_t,
281    enum lsqpack_enc_header_flags *flags /* Optional */);
282
283/**
284 * Process next chunk of bytes from the decoder stream.  Returns 0 on success,
285 * -1 on failure.  The failure should be treated as fatal.
286 */
287int
288lsqpack_enc_decoder_in (struct lsqpack_enc *, const unsigned char *, size_t);
289
290/**
291 * Return estimated compression ratio until this point.  Compression ratio
292 * is defined as size of the output divided by the size of the input, where
293 * output includes both header blocks and instructions sent on the encoder
294 * stream.
295 */
296float
297lsqpack_enc_ratio (const struct lsqpack_enc *);
298
299/**
300 * Return maximum size needed to encode Header Block Prefix
301 */
302size_t
303lsqpack_enc_header_block_prefix_size (const struct lsqpack_enc *);
304
305void
306lsqpack_enc_cleanup (struct lsqpack_enc *);
307
308/** Decoder header set interface */
309struct lsqpack_dec_hset_if
310{
311    void    (*dhi_unblocked)(void *hblock_ctx);
312    struct lsxpack_header *
313            (*dhi_prepare_decode)(void *hblock_ctx,
314                                  struct lsxpack_header *, size_t space);
315    int     (*dhi_process_header)(void *hblock_ctx, struct lsxpack_header *);
316};
317
318enum lsqpack_dec_opts
319{
320    /**
321     * In this mode, returned lsxpack_header will contain ": " between
322     * name and value strings and have "\r\n" after the value.
323     */
324    LSQPACK_DEC_OPT_HTTP1X          = 1 << 0,
325    /** Include name hash into lsxpack_header */
326    LSQPACK_DEC_OPT_HASH_NAME       = 1 << 1,
327    /** Include nameval hash into lsxpack_header */
328    LSQPACK_DEC_OPT_HASH_NAMEVAL    = 1 << 2,
329};
330
331void
332lsqpack_dec_init (struct lsqpack_dec *, void *logger_ctx,
333    unsigned dyn_table_size, unsigned max_risked_streams,
334    const struct lsqpack_dec_hset_if *, enum lsqpack_dec_opts);
335
336/**
337 * Values returned by @ref lsqpack_dec_header_in() and
338 * @ref lsqpack_dec_header_read()
339 */
340enum lsqpack_read_header_status
341{
342    /**
343     * The header list has been placed in `hlist' and `buf' has been advanced.
344     * This header should be released using
345     * @ref lsqpack_dec_destroy_header_list() after the caller is done with it.
346     *
347     * Note that the header list in `hlist' has an unlimited lifetime.  Even
348     * destroying it after @ref lsqpack_dec_cleanup() is called is OK and
349     * will not leak memory.
350     */
351    LQRHS_DONE,
352    /**
353     * The decoder cannot decode the header block until more dynamic table
354     * entries become available.  `buf' is advanced.  When the header block
355     * becomes unblocked, the decoder will call hblock_unblocked() callback
356     * specified in the constructor.  See @ref lsqpack_dec_init().
357     *
358     * Once a header block is unblocked, it cannot get blocked again.  In
359     * other words, this status can only be returned once per header block.
360     */
361    LQRHS_BLOCKED,
362    /**
363     * The decoder needs more bytes from the header block to proceed.  When
364     * they become available, call @ref lsqpack_dec_header_read().  `buf' is
365     * advanced.
366     */
367    LQRHS_NEED,
368    /**
369     * An error has occurred.  This can be any error: decoding error, memory
370     * allocation failure, or some internal error.
371     */
372    LQRHS_ERROR,
373};
374
375/**
376 * Number of bytes needed to encode the longest Header Acknowledgement
377 * instruction.
378 */
379#define LSQPACK_LONGEST_HEADER_ACK 10
380
381
382/**
383 * Call this function when the header blocks is first read.  The decoder
384 * will try to decode the header block.  The decoder can process header
385 * blocks in a streaming fashion, which means that there is no need to
386 * buffer the header block.  As soon as header block bytes become available,
387 * they can be fed to this function or @ref lsqpack_dec_header_read().
388 *
389 * See @ref lsqpack_read_header_status for explanation of the return codes.
390 *
391 * If the decoder returns LQRHS_NEED or LQRHS_BLOCKED, it keeps a reference to
392 * the user-provided header block context `hblock_ctx'.  It uses this value for
393 * two purposes:
394 *  1. to use as argument to hblock_unblocked(); and
395 *  2. to locate header block state when @ref lsqpack_dec_header_read() is
396 *     called.
397 *
398 * If the decoder returns LQRHS_DONE or LQRHS_ERROR, it means that it no
399 * longer has a reference to the header block.
400 */
401enum lsqpack_read_header_status
402lsqpack_dec_header_in (struct lsqpack_dec *, void *hblock_ctx,
403                       uint64_t stream_id, size_t header_block_size,
404                       const unsigned char **buf, size_t bufsz,
405                       unsigned char *dec_buf, size_t *dec_buf_sz);
406
407/**
408 * Call this function when more header block bytes are become available
409 * after this function or @ref lsqpack_dec_header_in() returned LQRHS_NEED
410 * or hblock_unblocked() callback has been called.  This function behaves
411 * similarly to @ref lsqpack_dec_header_in(): see its comments for more
412 * information.
413 */
414enum lsqpack_read_header_status
415lsqpack_dec_header_read (struct lsqpack_dec *dec, void *hblock_ctx,
416                         const unsigned char **buf, size_t bufsz,
417                         unsigned char *dec_buf, size_t *dec_buf_sz);
418
419/**
420 * Feed encoder stream data to the decoder.  Zero is returned on success,
421 * negative value on error.
422 */
423int
424lsqpack_dec_enc_in (struct lsqpack_dec *, const unsigned char *, size_t);
425
426/**
427 * Returns true if Insert Count Increment (ICI) instruction is pending.
428 */
429int
430lsqpack_dec_ici_pending (const struct lsqpack_dec *dec);
431
432/**
433 * Number of bytes required to encode the longest Insert Count Increment (ICI)
434 * instruction.
435 */
436#define LSQPACK_LONGEST_ICI 6
437
438ssize_t
439lsqpack_dec_write_ici (struct lsqpack_dec *, unsigned char *, size_t);
440
441/** Number of bytes required to encode the longest cancel instruction */
442#define LSQPACK_LONGEST_CANCEL 6
443
444/**
445 * Cancel stream associated with the header block context `hblock_ctx' and
446 * write cancellation instruction to `buf'.  `buf' must be at least
447 * @ref LSQPACK_LONGEST_CANCEL bytes long.
448 *
449 * Number of bytes written to `buf' is returned.  If stream `stream_id'
450 * could not be found, zero is returned.  If `buf' is too short, -1 is
451 * returned.
452 */
453ssize_t
454lsqpack_dec_cancel_stream (struct lsqpack_dec *, void *hblock_ctx,
455                                unsigned char *buf, size_t buf_sz);
456
457/**
458 * Generate Cancel Stream instruction for stream `stream_id'.  Call when
459 * abandoning stream (see [draft-ietf-quic-qpack-14] Section 2.2.2.2).
460 *
461 * Return values:
462 *  -1  error (`buf' is too short)
463 *   0  Emitting Cancel Stream instruction is unnecessary
464 *  >0  Size of Cancel Stream instruction written to `buf'.
465 */
466ssize_t
467lsqpack_dec_cancel_stream_id (struct lsqpack_dec *dec, uint64_t stream_id,
468                                        unsigned char *buf, size_t buf_sz);
469
470/**
471 * Delete reference to the header block context `hblock_ctx'.  Use this
472 * instead of @ref lsqpack_dec_cancel_stream() when producing a Cancel Stream
473 * instruction is not necessary.
474 */
475int
476lsqpack_dec_unref_stream (struct lsqpack_dec *, void *hblock_ctx);
477
478/**
479 * Return estimated compression ratio until this point.  Compression ratio
480 * is defined as size of the input divided by the size of the output, where
481 * input includes both header blocks and instructions received on the encoder
482 * stream.
483 */
484float
485lsqpack_dec_ratio (const struct lsqpack_dec *);
486
487/**
488 * Clean up the decoder.  If any there are any blocked header blocks,
489 * references to them will be discarded.
490 */
491void
492lsqpack_dec_cleanup (struct lsqpack_dec *);
493
494/**
495 * Print human-readable decoder table.
496 */
497void
498lsqpack_dec_print_table (const struct lsqpack_dec *, FILE *out);
499
500
501struct lsqpack_dec_err
502{
503    enum {
504        LSQPACK_DEC_ERR_LOC_HEADER_BLOCK,
505        LSQPACK_DEC_ERR_LOC_ENC_STREAM,
506    }           type;
507    int         line;       /* In the source file */
508    uint64_t    off;        /* Offset in header block or on encoder stream */
509    uint64_t    stream_id;  /* Only applicable to header block */
510};
511
512
513const struct lsqpack_dec_err *
514lsqpack_dec_get_err_info (const struct lsqpack_dec *);
515
516/**
517 * Enum for name/value entries in the static table.  Use it to speed up
518 * encoding by setting xhdr->qpack_index and LSXPACK_QPACK_IDX flag.  If
519 * it's a full match, set LSXPACK_VAL_MATCHED flag as well.
520 */
521enum lsqpack_tnv
522{
523    LSQPACK_TNV_AUTHORITY = 0, /* ":authority" "" */
524    LSQPACK_TNV_PATH = 1, /* ":path" "/" */
525    LSQPACK_TNV_AGE_0 = 2, /* "age" "0" */
526    LSQPACK_TNV_CONTENT_DISPOSITION = 3, /* "content-disposition" "" */
527    LSQPACK_TNV_CONTENT_LENGTH_0 = 4, /* "content-length" "0" */
528    LSQPACK_TNV_COOKIE = 5, /* "cookie" "" */
529    LSQPACK_TNV_DATE = 6, /* "date" "" */
530    LSQPACK_TNV_ETAG = 7, /* "etag" "" */
531    LSQPACK_TNV_IF_MODIFIED_SINCE = 8, /* "if-modified-since" "" */
532    LSQPACK_TNV_IF_NONE_MATCH = 9, /* "if-none-match" "" */
533    LSQPACK_TNV_LAST_MODIFIED = 10, /* "last-modified" "" */
534    LSQPACK_TNV_LINK = 11, /* "link" "" */
535    LSQPACK_TNV_LOCATION = 12, /* "location" "" */
536    LSQPACK_TNV_REFERER = 13, /* "referer" "" */
537    LSQPACK_TNV_SET_COOKIE = 14, /* "set-cookie" "" */
538    LSQPACK_TNV_METHOD_CONNECT = 15, /* ":method" "CONNECT" */
539    LSQPACK_TNV_METHOD_DELETE = 16, /* ":method" "DELETE" */
540    LSQPACK_TNV_METHOD_GET = 17, /* ":method" "GET" */
541    LSQPACK_TNV_METHOD_HEAD = 18, /* ":method" "HEAD" */
542    LSQPACK_TNV_METHOD_OPTIONS = 19, /* ":method" "OPTIONS" */
543    LSQPACK_TNV_METHOD_POST = 20, /* ":method" "POST" */
544    LSQPACK_TNV_METHOD_PUT = 21, /* ":method" "PUT" */
545    LSQPACK_TNV_SCHEME_HTTP = 22, /* ":scheme" "http" */
546    LSQPACK_TNV_SCHEME_HTTPS = 23, /* ":scheme" "https" */
547    LSQPACK_TNV_STATUS_103 = 24, /* ":status" "103" */
548    LSQPACK_TNV_STATUS_200 = 25, /* ":status" "200" */
549    LSQPACK_TNV_STATUS_304 = 26, /* ":status" "304" */
550    LSQPACK_TNV_STATUS_404 = 27, /* ":status" "404" */
551    LSQPACK_TNV_STATUS_503 = 28, /* ":status" "503" */
552    LSQPACK_TNV_ACCEPT = 29, /* "accept" star slash star */
553    LSQPACK_TNV_ACCEPT_APPLICATION_DNS_MESSAGE = 30, /* "accept" "application/dns-message" */
554    LSQPACK_TNV_ACCEPT_ENCODING_GZIP_DEFLATE_BR = 31, /* "accept-encoding" "gzip, deflate, br" */
555    LSQPACK_TNV_ACCEPT_RANGES_BYTES = 32, /* "accept-ranges" "bytes" */
556    LSQPACK_TNV_ACCESS_CONTROL_ALLOW_HEADERS_CACHE_CONTROL = 33, /* "access-control-allow-headers" "cache-control" */
557    LSQPACK_TNV_ACCESS_CONTROL_ALLOW_HEADERS_CONTENT_TYPE = 34, /* "access-control-allow-headers" "content-type" */
558    LSQPACK_TNV_ACCESS_CONTROL_ALLOW_ORIGIN = 35, /* "access-control-allow-origin" "*" */
559    LSQPACK_TNV_CACHE_CONTROL_MAX_AGE_0 = 36, /* "cache-control" "max-age=0" */
560    LSQPACK_TNV_CACHE_CONTROL_MAX_AGE_2592000 = 37, /* "cache-control" "max-age=2592000" */
561    LSQPACK_TNV_CACHE_CONTROL_MAX_AGE_604800 = 38, /* "cache-control" "max-age=604800" */
562    LSQPACK_TNV_CACHE_CONTROL_NO_CACHE = 39, /* "cache-control" "no-cache" */
563    LSQPACK_TNV_CACHE_CONTROL_NO_STORE = 40, /* "cache-control" "no-store" */
564    LSQPACK_TNV_CACHE_CONTROL_PUBLIC_MAX_AGE_31536000 = 41, /* "cache-control" "public, max-age=31536000" */
565    LSQPACK_TNV_CONTENT_ENCODING_BR = 42, /* "content-encoding" "br" */
566    LSQPACK_TNV_CONTENT_ENCODING_GZIP = 43, /* "content-encoding" "gzip" */
567    LSQPACK_TNV_CONTENT_TYPE_APPLICATION_DNS_MESSAGE = 44, /* "content-type" "application/dns-message" */
568    LSQPACK_TNV_CONTENT_TYPE_APPLICATION_JAVASCRIPT = 45, /* "content-type" "application/javascript" */
569    LSQPACK_TNV_CONTENT_TYPE_APPLICATION_JSON = 46, /* "content-type" "application/json" */
570    LSQPACK_TNV_CONTENT_TYPE_APPLICATION_X_WWW_FORM_URLENCODED = 47, /* "content-type" "application/x-www-form-urlencoded" */
571    LSQPACK_TNV_CONTENT_TYPE_IMAGE_GIF = 48, /* "content-type" "image/gif" */
572    LSQPACK_TNV_CONTENT_TYPE_IMAGE_JPEG = 49, /* "content-type" "image/jpeg" */
573    LSQPACK_TNV_CONTENT_TYPE_IMAGE_PNG = 50, /* "content-type" "image/png" */
574    LSQPACK_TNV_CONTENT_TYPE_TEXT_CSS = 51, /* "content-type" "text/css" */
575    LSQPACK_TNV_CONTENT_TYPE_TEXT_HTML_CHARSET_UTF_8 = 52, /* "content-type" "text/html; charset=utf-8" */
576    LSQPACK_TNV_CONTENT_TYPE_TEXT_PLAIN = 53, /* "content-type" "text/plain" */
577    LSQPACK_TNV_CONTENT_TYPE_TEXT_PLAIN_CHARSET_UTF_8 = 54, /* "content-type" "text/plain;charset=utf-8" */
578    LSQPACK_TNV_RANGE_BYTES_0 = 55, /* "range" "bytes=0-" */
579    LSQPACK_TNV_STRICT_TRANSPORT_SECURITY_MAX_AGE_31536000 = 56, /* "strict-transport-security" "max-age=31536000" */
580    LSQPACK_TNV_STRICT_TRANSPORT_SECURITY_MAX_AGE_31536000_INCLUDESUBDOMAINS = 57, /* "strict-transport-security" "max-age=31536000; includesubdomains" */
581    LSQPACK_TNV_STRICT_TRANSPORT_SECURITY_MAX_AGE_31536000_INCLUDESUBDOMAINS_PRELOAD = 58, /* "strict-transport-security" "max-age=31536000; includesubdomains; preload" */
582    LSQPACK_TNV_VARY_ACCEPT_ENCODING = 59, /* "vary" "accept-encoding" */
583    LSQPACK_TNV_VARY_ORIGIN = 60, /* "vary" "origin" */
584    LSQPACK_TNV_X_CONTENT_TYPE_OPTIONS_NOSNIFF = 61, /* "x-content-type-options" "nosniff" */
585    LSQPACK_TNV_X_XSS_PROTECTION_1_MODE_BLOCK = 62, /* "x-xss-protection" "1; mode=block" */
586    LSQPACK_TNV_STATUS_100 = 63, /* ":status" "100" */
587    LSQPACK_TNV_STATUS_204 = 64, /* ":status" "204" */
588    LSQPACK_TNV_STATUS_206 = 65, /* ":status" "206" */
589    LSQPACK_TNV_STATUS_302 = 66, /* ":status" "302" */
590    LSQPACK_TNV_STATUS_400 = 67, /* ":status" "400" */
591    LSQPACK_TNV_STATUS_403 = 68, /* ":status" "403" */
592    LSQPACK_TNV_STATUS_421 = 69, /* ":status" "421" */
593    LSQPACK_TNV_STATUS_425 = 70, /* ":status" "425" */
594    LSQPACK_TNV_STATUS_500 = 71, /* ":status" "500" */
595    LSQPACK_TNV_ACCEPT_LANGUAGE = 72, /* "accept-language" "" */
596    LSQPACK_TNV_ACCESS_CONTROL_ALLOW_CREDENTIALS_FALSE = 73, /* "access-control-allow-credentials" "FALSE" */
597    LSQPACK_TNV_ACCESS_CONTROL_ALLOW_CREDENTIALS_TRUE = 74, /* "access-control-allow-credentials" "TRUE" */
598    LSQPACK_TNV_ACCESS_CONTROL_ALLOW_HEADERS = 75, /* "access-control-allow-headers" "*" */
599    LSQPACK_TNV_ACCESS_CONTROL_ALLOW_METHODS_GET = 76, /* "access-control-allow-methods" "get" */
600    LSQPACK_TNV_ACCESS_CONTROL_ALLOW_METHODS_GET_POST_OPTIONS = 77, /* "access-control-allow-methods" "get, post, options" */
601    LSQPACK_TNV_ACCESS_CONTROL_ALLOW_METHODS_OPTIONS = 78, /* "access-control-allow-methods" "options" */
602    LSQPACK_TNV_ACCESS_CONTROL_EXPOSE_HEADERS_CONTENT_LENGTH = 79, /* "access-control-expose-headers" "content-length" */
603    LSQPACK_TNV_ACCESS_CONTROL_REQUEST_HEADERS_CONTENT_TYPE = 80, /* "access-control-request-headers" "content-type" */
604    LSQPACK_TNV_ACCESS_CONTROL_REQUEST_METHOD_GET = 81, /* "access-control-request-method" "get" */
605    LSQPACK_TNV_ACCESS_CONTROL_REQUEST_METHOD_POST = 82, /* "access-control-request-method" "post" */
606    LSQPACK_TNV_ALT_SVC_CLEAR = 83, /* "alt-svc" "clear" */
607    LSQPACK_TNV_AUTHORIZATION = 84, /* "authorization" "" */
608    LSQPACK_TNV_CONTENT_SECURITY_POLICY_SCRIPT_SRC_NONE_OBJECT_SRC_NONE_BASE_URI_NONE = 85, /* "content-security-policy" "script-src 'none'; object-src 'none'; base-uri 'none'" */
609    LSQPACK_TNV_EARLY_DATA_1 = 86, /* "early-data" "1" */
610    LSQPACK_TNV_EXPECT_CT = 87, /* "expect-ct" "" */
611    LSQPACK_TNV_FORWARDED = 88, /* "forwarded" "" */
612    LSQPACK_TNV_IF_RANGE = 89, /* "if-range" "" */
613    LSQPACK_TNV_ORIGIN = 90, /* "origin" "" */
614    LSQPACK_TNV_PURPOSE_PREFETCH = 91, /* "purpose" "prefetch" */
615    LSQPACK_TNV_SERVER = 92, /* "server" "" */
616    LSQPACK_TNV_TIMING_ALLOW_ORIGIN = 93, /* "timing-allow-origin" "*" */
617    LSQPACK_TNV_UPGRADE_INSECURE_REQUESTS_1 = 94, /* "upgrade-insecure-requests" "1" */
618    LSQPACK_TNV_USER_AGENT = 95, /* "user-agent" "" */
619    LSQPACK_TNV_X_FORWARDED_FOR = 96, /* "x-forwarded-for" "" */
620    LSQPACK_TNV_X_FRAME_OPTIONS_DENY = 97, /* "x-frame-options" "deny" */
621    LSQPACK_TNV_X_FRAME_OPTIONS_SAMEORIGIN = 98, /* "x-frame-options" "sameorigin" */
622};
623
624
625/*
626 * Internals follow.  The internals are subject to change without notice.
627 */
628
629#include <sys/queue.h>
630
631/* It takes 11 bytes to encode UINT64_MAX as HPACK integer */
632#define LSQPACK_UINT64_ENC_SZ 11u
633
634struct lsqpack_enc_table_entry;
635
636STAILQ_HEAD(lsqpack_enc_head, lsqpack_enc_table_entry);
637struct lsqpack_double_enc_head;
638
639struct lsqpack_header_info_arr;
640
641struct lsqpack_dec_int_state
642{
643    int         resume;
644    unsigned    M, nread;
645    uint64_t    val;
646};
647
648struct lsqpack_enc
649{
650    /* The number of all the entries in the dynamic table that have been
651     * created so far.  This is used to calculate the Absolute Index.
652     */
653    lsqpack_abs_id_t            qpe_ins_count;
654    lsqpack_abs_id_t            qpe_max_acked_id;
655    lsqpack_abs_id_t            qpe_last_ici;
656
657    enum {
658        LSQPACK_ENC_HEADER  = 1 << 0,
659        LSQPACK_ENC_USE_DUP = 1 << 1,
660        LSQPACK_ENC_NO_MEM_GUARD    = 1 << 2,
661    }                           qpe_flags;
662
663    unsigned                    qpe_cur_bytes_used;
664    unsigned                    qpe_cur_max_capacity;
665    unsigned                    qpe_real_max_capacity;
666    unsigned                    qpe_max_entries;
667    /* Sum of all dropped entries.  OK if it overflows. */
668    unsigned                    qpe_dropped;
669
670    /* The maximum risked streams is the SETTINGS_QPACK_BLOCKED_STREAMS
671     * setting.  Note that streams must be differentiated from headers.
672     */
673    unsigned                    qpe_max_risked_streams;
674    unsigned                    qpe_cur_streams_at_risk;
675
676    /* Number of used entries in qpe_hinfo_arrs */
677    unsigned                    qpe_hinfo_arrs_count;
678
679    /* Dynamic table entries (struct enc_table_entry) live in two hash
680     * tables: name/value hash table and name hash table.  These tables
681     * are the same size.
682     */
683    unsigned                    qpe_nelem;
684    unsigned                    qpe_nbits;
685    struct lsqpack_enc_head     qpe_all_entries;
686    struct lsqpack_double_enc_head
687                               *qpe_buckets;
688
689    STAILQ_HEAD(, lsqpack_header_info_arr)
690                                qpe_hinfo_arrs;
691    TAILQ_HEAD(, lsqpack_header_info)
692                                qpe_all_hinfos;
693    TAILQ_HEAD(, lsqpack_header_info)
694                                qpe_risked_hinfos;
695
696    /* Current header state */
697    struct {
698        struct lsqpack_header_info  *hinfo, *other_at_risk;
699
700        /* Number of headers in this header list added to the history */
701        unsigned            n_hdr_added_to_hist;
702        lsqpack_abs_id_t    min_reffed;
703        enum lsqpack_enc_header_flags
704                            flags;
705        lsqpack_abs_id_t    base_idx;
706    }                           qpe_cur_header;
707
708    struct {
709        struct lsqpack_dec_int_state dec_int_state;
710        int   (*handler)(struct lsqpack_enc *, uint64_t);
711    }                           qpe_dec_stream_state;
712
713    /* Used to calculate estimated compression ratio.  Note that the `out'
714     * part contains bytes sent on the decoder stream, as it also counts
715     * toward the overhead.
716     */
717    unsigned                    qpe_bytes_in;
718    unsigned                    qpe_bytes_out;
719    void                       *qpe_logger_ctx;
720
721    /* Exponential moving averages (EMAs) of the number of elements in the
722     * dynamic table and the number of header fields in a single header list.
723     * These values are used to adjust history size.
724     */
725    float                       qpe_table_nelem_ema;
726    float                       qpe_header_count_ema;
727
728    struct lsqpack_hist_el     *qpe_hist_els;
729    unsigned                    qpe_hist_idx;
730    unsigned                    qpe_hist_nels;
731    int                         qpe_hist_wrapped;
732};
733
734struct lsqpack_ringbuf
735{
736    unsigned        rb_nalloc, rb_head, rb_tail;
737    void          **rb_els;
738};
739
740TAILQ_HEAD(lsqpack_header_sets, lsqpack_header_set_elem);
741
742struct lsqpack_header_block;
743
744struct lsqpack_decode_status
745{
746    uint8_t state;
747    uint8_t eos;
748};
749
750struct lsqpack_huff_decode_state
751{
752    int                             resume;
753    struct lsqpack_decode_status    status;
754};
755
756struct lsqpack_dec_inst;
757
758struct lsqpack_dec
759{
760    enum lsqpack_dec_opts   qpd_opts;
761    /** This is the hard limit set at initialization */
762    unsigned                qpd_max_capacity;
763    /** The current maximum capacity can be adjusted at run-time */
764    unsigned                qpd_cur_max_capacity;
765    unsigned                qpd_cur_capacity;
766    unsigned                qpd_max_risked_streams;
767    unsigned                qpd_max_entries;
768    /* Used to calculate estimated compression ratio.  Note that the `in'
769     * part contains bytes sent on the decoder stream, as it also counts
770     * toward the overhead.
771     */
772    unsigned                qpd_bytes_in;
773    unsigned                qpd_bytes_out;
774    /** ID of the last dynamic table entry.  Has the range
775     * [0, qpd_max_entries * 2 - 1 ]
776     */
777    lsqpack_abs_id_t        qpd_last_id;
778    /** TODO: describe the mechanism */
779    lsqpack_abs_id_t        qpd_largest_known_id;
780    const struct lsqpack_dec_hset_if
781                           *qpd_dh_if;
782
783    void                   *qpd_logger_ctx;
784
785    /** This is the dynamic table */
786    struct lsqpack_ringbuf  qpd_dyn_table;
787
788    TAILQ_HEAD(, header_block_read_ctx)
789                            qpd_hbrcs;
790
791    /** Blocked headers are kept in a small hash */
792#define LSQPACK_DEC_BLOCKED_BITS 3
793    TAILQ_HEAD(, header_block_read_ctx)
794                            qpd_blocked_headers[1 << LSQPACK_DEC_BLOCKED_BITS];
795    /** Number of blocked streams (in qpd_blocked_headers) */
796    unsigned                qpd_n_blocked;
797
798    /** Average number of header fields in header list */
799    float                   qpd_hlist_size_ema;
800
801    /** Reading the encoder stream */
802    struct {
803        int                                                 resume;
804        union {
805            /* State for reading in the Insert With Named Reference
806             * instruction.
807             */
808            struct {
809                struct lsqpack_dec_int_state        dec_int_state;
810                struct lsqpack_huff_decode_state    dec_huff_state;
811                unsigned                            name_idx;
812                unsigned                            val_len;
813                struct lsqpack_dec_table_entry     *reffed_entry;
814                struct lsqpack_dec_table_entry     *entry;
815                const char                         *name;
816                unsigned                            alloced_val_len;
817                unsigned                            val_off;
818                unsigned                            nread;
819                unsigned                            name_len;
820                signed char                         is_huffman;
821                signed char                         is_static;
822            }                                               with_namref;
823
824            /* State for reading in the Insert Without Named Reference
825             * instruction.
826             */
827            struct {
828                struct lsqpack_dec_int_state        dec_int_state;
829                struct lsqpack_huff_decode_state    dec_huff_state;
830                unsigned                            str_len;
831                struct lsqpack_dec_table_entry     *entry;
832                unsigned                            alloced_len;
833                unsigned                            str_off;
834                unsigned                            nread;
835                signed char                         is_huffman;
836            }                                               wo_namref;
837
838            struct {
839                struct lsqpack_dec_int_state        dec_int_state;
840                unsigned                            index;
841            }                                               duplicate;
842
843            struct {
844                struct lsqpack_dec_int_state        dec_int_state;
845                uint64_t                            new_size;
846            }                                               sdtc;
847        }               ctx_u;
848    }                       qpd_enc_state;
849    struct lsqpack_dec_err  qpd_err;
850};
851
852#ifdef __cplusplus
853}
854#endif
855
856#endif
857