mirror of
				https://gitea.invidious.io/iv-org/litespeed-quic.git
				synced 2024-08-15 00:53:43 +00:00 
			
		
		
		
	Release 2.13.0
- [API] Use lsxpack_header structure to process incoming headers. - [BUGFIX] Fix assertion when zero-padding Initial packet. - [BUGFIX] Use idle timeout before we learn of peer's value. - Use ls-hpack 2.0.0 -- has lsxpack_header changes. - Use ls-qpack 0.14.0 -- new, common with ls-hpack, XXH seed (not used yet). - Code cleanup: prefix exported functions with "lsquic_".
This commit is contained in:
		
							parent
							
								
									5289ebd2fd
								
							
						
					
					
						commit
						a5fa05f958
					
				
					 77 changed files with 1168 additions and 73475 deletions
				
			
		
							
								
								
									
										3
									
								
								.gitmodules
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitmodules
									
										
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -2,3 +2,6 @@
 | 
			
		|||
	path = src/liblsquic/ls-qpack
 | 
			
		||||
	url = https://github.com/litespeedtech/ls-qpack
 | 
			
		||||
        branch = v0.9.13
 | 
			
		||||
[submodule "src/lshpack"]
 | 
			
		||||
	path = src/lshpack
 | 
			
		||||
	url = https://github.com/litespeedtech/ls-hpack
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										10
									
								
								CHANGELOG
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								CHANGELOG
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,3 +1,13 @@
 | 
			
		|||
2020-03-12
 | 
			
		||||
    - 2.13.0
 | 
			
		||||
    - [API] Use lsxpack_header structure to process incoming headers.
 | 
			
		||||
    - [BUGFIX] Fix assertion when zero-padding Initial packet.
 | 
			
		||||
    - [BUGFIX] Use idle timeout before we learn of peer's value.
 | 
			
		||||
    - Use ls-hpack 2.0.0 -- has lsxpack_header changes.
 | 
			
		||||
    - Use ls-qpack 0.14.0 -- new, common with ls-hpack, XXH seed (not
 | 
			
		||||
      used yet).
 | 
			
		||||
    - Code cleanup: prefix exported functions with "lsquic_".
 | 
			
		||||
 | 
			
		||||
2020-03-02
 | 
			
		||||
    - 2.12.0
 | 
			
		||||
    - [FEATURE] QUIC timestamps extension.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,11 +21,10 @@ Support for newer versions will be added soon after they are released.
 | 
			
		|||
Documentation
 | 
			
		||||
-------------
 | 
			
		||||
 | 
			
		||||
The documentation for this module is admittedly sparse but is now externally hosted at [Read the Docs](https://lsquic.readthedocs.io/en/latest/).  The API is
 | 
			
		||||
documented in include/lsquic.h.  If you have doxygen, you can run
 | 
			
		||||
`doxygen dox.cfg` or `make docs`.  The example program is
 | 
			
		||||
test/http_client.c: a bare-bones, but working, QUIC client.  Have a look
 | 
			
		||||
in EXAMPLES.txt to see how it can be used.
 | 
			
		||||
Documentation is available at https://lsquic.readthedocs.io/en/latest/.
 | 
			
		||||
 | 
			
		||||
In addition, see example programs for API usage and EXAMPLES.txt for
 | 
			
		||||
some compilation and run-time options.
 | 
			
		||||
 | 
			
		||||
Requirements
 | 
			
		||||
------------
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										104
									
								
								docs/apiref.rst
									
										
									
									
									
								
							
							
						
						
									
										104
									
								
								docs/apiref.rst
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1418,45 +1418,34 @@ fields yourself.  In that case, the header set must be "read" from the stream vi
 | 
			
		|||
        stream by calling :func:`lsquic_stream_get_hset()` before the stream can
 | 
			
		||||
        be read.
 | 
			
		||||
 | 
			
		||||
    .. member:: enum lsquic_header_status (*hsi_process_header)(void *hdr_set, unsigned name_idx, const char *name, unsigned name_len, const char *value, unsigned value_len)
 | 
			
		||||
    .. member:: struct lsxpack_header * (*hsi_prepare_decode)(void *hdr_set, struct lsxpack_header *hdr, size_t space)
 | 
			
		||||
 | 
			
		||||
        Return a header set prepared for decoding.  If ``hdr`` is NULL, this
 | 
			
		||||
        means return a new structure with at least `space' bytes available
 | 
			
		||||
        in the decoder buffer.  If `hdr' is not NULL, it means there was not
 | 
			
		||||
        enough decoder buffer and it must be increased by ``space`` bytes.
 | 
			
		||||
 | 
			
		||||
        If NULL is returned the header set is discarded.
 | 
			
		||||
 | 
			
		||||
    .. member:: int (*hsi_process_header)(void *hdr_set, struct lsxpack_header *hdr)
 | 
			
		||||
 | 
			
		||||
        Process new header.
 | 
			
		||||
 | 
			
		||||
        :param hdr_set:
 | 
			
		||||
 | 
			
		||||
            Header set to add the new header field to.  This is the object
 | 
			
		||||
            returned by ``hsi_create_header_set()``.
 | 
			
		||||
 | 
			
		||||
        :param name_idx:
 | 
			
		||||
        :param hdr:
 | 
			
		||||
 | 
			
		||||
            This value is set to the index in either the HPACK or QPACK static table
 | 
			
		||||
            whose entry's name element matches ``name``.  The values are as follows:
 | 
			
		||||
 | 
			
		||||
            - if there is no such match, this value is zero;
 | 
			
		||||
            - if HPACK is used, the value is between 1 and 61; and
 | 
			
		||||
            - if QPACK is used, the value is 62+ (subtract 62 to get the QPACK
 | 
			
		||||
              static table index).
 | 
			
		||||
 | 
			
		||||
        :param name:
 | 
			
		||||
 | 
			
		||||
            Header field name.  If NULL, this means that no more header are going to be
 | 
			
		||||
            added to the set.
 | 
			
		||||
 | 
			
		||||
        :param name_len:
 | 
			
		||||
 | 
			
		||||
            Header field name length.
 | 
			
		||||
 | 
			
		||||
        :param value:
 | 
			
		||||
 | 
			
		||||
            Header field value.
 | 
			
		||||
 | 
			
		||||
        :param value_len:
 | 
			
		||||
 | 
			
		||||
            Header field value length.
 | 
			
		||||
            The header returned by @ref ``hsi_prepare_decode()``.
 | 
			
		||||
 | 
			
		||||
        :return:
 | 
			
		||||
 | 
			
		||||
            0 on success, non-zero on failure.  The latter is treated as a stream
 | 
			
		||||
            error: the associated stream is reset.  See :type:`lsquic_header_status`
 | 
			
		||||
            for detailed error listing.
 | 
			
		||||
            Return 0 on success, a positive value if a header error occured,
 | 
			
		||||
            or a negative value on any other error.  A positive return value
 | 
			
		||||
            will result in cancellation of associated stream. A negative return
 | 
			
		||||
            value will result in connection being aborted.
 | 
			
		||||
 | 
			
		||||
    .. member:: void                (*hsi_discard_header_set)(void *hdr_set)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1763,63 +1752,6 @@ Miscellaneous Types
 | 
			
		|||
 | 
			
		||||
        Close handle.
 | 
			
		||||
 | 
			
		||||
.. type:: enum lsquic_header_status
 | 
			
		||||
 | 
			
		||||
    When headers are processed, various errors may occur.  They are listed
 | 
			
		||||
    in this enum.
 | 
			
		||||
 | 
			
		||||
    .. member:: LSQUIC_HDR_OK
 | 
			
		||||
 | 
			
		||||
        Header was processed OK.
 | 
			
		||||
 | 
			
		||||
    .. member:: LSQUIC_HDR_ERR_DUPLICATE_PSDO_HDR
 | 
			
		||||
 | 
			
		||||
        Duplicate pseudo-header
 | 
			
		||||
 | 
			
		||||
    .. member:: LSQUIC_HDR_ERR_INCOMPL_REQ_PSDO_HDR
 | 
			
		||||
 | 
			
		||||
        Not all request pseudo-headers are present
 | 
			
		||||
 | 
			
		||||
    .. member:: LSQUIC_HDR_ERR_UNNEC_REQ_PSDO_HDR
 | 
			
		||||
 | 
			
		||||
        Unnecessary request pseudo-header present in the response
 | 
			
		||||
 | 
			
		||||
    .. member:: LSQUIC_HDR_ERR_BAD_REQ_HEADER
 | 
			
		||||
 | 
			
		||||
        Prohibited header in request
 | 
			
		||||
 | 
			
		||||
    .. member:: LSQUIC_HDR_ERR_INCOMPL_RESP_PSDO_HDR
 | 
			
		||||
 | 
			
		||||
        Not all response pseudo-headers are present
 | 
			
		||||
 | 
			
		||||
    .. member:: LSQUIC_HDR_ERR_UNNEC_RESP_PSDO_HDR
 | 
			
		||||
 | 
			
		||||
        Unnecessary response pseudo-header present in the response.
 | 
			
		||||
 | 
			
		||||
    .. member:: LSQUIC_HDR_ERR_UNKNOWN_PSDO_HDR
 | 
			
		||||
 | 
			
		||||
        Unknown pseudo-header
 | 
			
		||||
 | 
			
		||||
    .. member:: LSQUIC_HDR_ERR_UPPERCASE_HEADER
 | 
			
		||||
 | 
			
		||||
        Uppercase letter in header
 | 
			
		||||
 | 
			
		||||
    .. member:: LSQUIC_HDR_ERR_MISPLACED_PSDO_HDR
 | 
			
		||||
 | 
			
		||||
        Misplaced pseudo-header
 | 
			
		||||
 | 
			
		||||
    .. member:: LSQUIC_HDR_ERR_MISSING_PSDO_HDR
 | 
			
		||||
 | 
			
		||||
        Missing pseudo-header
 | 
			
		||||
 | 
			
		||||
    .. member:: LSQUIC_HDR_ERR_HEADERS_TOO_LARGE
 | 
			
		||||
 | 
			
		||||
        Header or headers are too large
 | 
			
		||||
 | 
			
		||||
    .. member:: LSQUIC_HDR_ERR_NOMEM
 | 
			
		||||
 | 
			
		||||
        Cannot allocate any more memory.
 | 
			
		||||
 | 
			
		||||
.. type:: enum lsquic_logger_timestamp_style
 | 
			
		||||
 | 
			
		||||
    Enumerate timestamp styles supported by LSQUIC logger mechanism.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,9 +24,9 @@ copyright = u'2020, LiteSpeed Technologies'
 | 
			
		|||
author = u'LiteSpeed Technologies'
 | 
			
		||||
 | 
			
		||||
# The short X.Y version
 | 
			
		||||
version = u'2.12'
 | 
			
		||||
version = u'2.13'
 | 
			
		||||
# The full version, including alpha/beta/rc tags
 | 
			
		||||
release = u'2.12.0'
 | 
			
		||||
release = u'2.13.0'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# -- General configuration ---------------------------------------------------
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,6 +16,7 @@ LSQUIC library uses:
 | 
			
		|||
 | 
			
		||||
- zlib_;
 | 
			
		||||
- BoringSSL_; and
 | 
			
		||||
- `ls-hpack`_ (as a Git submodule).
 | 
			
		||||
- `ls-qpack`_ (as a Git submodule).
 | 
			
		||||
 | 
			
		||||
The accompanying demo command-line tools use libevent_.
 | 
			
		||||
| 
						 | 
				
			
			@ -66,6 +67,7 @@ the :doc:`apiref`.
 | 
			
		|||
 | 
			
		||||
.. _zlib: https://www.zlib.net/
 | 
			
		||||
.. _BoringSSL: https://boringssl.googlesource.com/boringssl/
 | 
			
		||||
.. _`ls-hpack`: https://github.com/litespeedtech/ls-hpack
 | 
			
		||||
.. _`ls-qpack`: https://github.com/litespeedtech/ls-qpack
 | 
			
		||||
.. _libevent: https://libevent.org/
 | 
			
		||||
.. _README: https://github.com/litespeedtech/lsquic/blob/master/README.md
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,7 +24,7 @@ extern "C" {
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
#define LSQUIC_MAJOR_VERSION 2
 | 
			
		||||
#define LSQUIC_MINOR_VERSION 12
 | 
			
		||||
#define LSQUIC_MINOR_VERSION 13
 | 
			
		||||
#define LSQUIC_PATCH_VERSION 0
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -862,39 +862,6 @@ typedef void (*lsquic_cids_update_f)(void *ctx, void **peer_ctx,
 | 
			
		|||
 | 
			
		||||
struct stack_st_X509;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * When headers are processed, various errors may occur.  They are listed
 | 
			
		||||
 * in this enum.
 | 
			
		||||
 */
 | 
			
		||||
enum lsquic_header_status
 | 
			
		||||
{
 | 
			
		||||
    LSQUIC_HDR_OK,
 | 
			
		||||
    /** Duplicate pseudo-header */
 | 
			
		||||
    LSQUIC_HDR_ERR_DUPLICATE_PSDO_HDR,
 | 
			
		||||
    /** Not all request pseudo-headers are present */
 | 
			
		||||
    LSQUIC_HDR_ERR_INCOMPL_REQ_PSDO_HDR,
 | 
			
		||||
    /** Unnecessary request pseudo-header present in the response */
 | 
			
		||||
    LSQUIC_HDR_ERR_UNNEC_REQ_PSDO_HDR,
 | 
			
		||||
    /** Prohibited header in request */
 | 
			
		||||
    LSQUIC_HDR_ERR_BAD_REQ_HEADER,
 | 
			
		||||
    /** Not all response pseudo-headers are present */
 | 
			
		||||
    LSQUIC_HDR_ERR_INCOMPL_RESP_PSDO_HDR,
 | 
			
		||||
    /** Unnecessary response pseudo-header present in the response. */
 | 
			
		||||
    LSQUIC_HDR_ERR_UNNEC_RESP_PSDO_HDR,
 | 
			
		||||
    /** Unknown pseudo-header */
 | 
			
		||||
    LSQUIC_HDR_ERR_UNKNOWN_PSDO_HDR,
 | 
			
		||||
    /** Uppercase letter in header */
 | 
			
		||||
    LSQUIC_HDR_ERR_UPPERCASE_HEADER,
 | 
			
		||||
    /** Misplaced pseudo-header */
 | 
			
		||||
    LSQUIC_HDR_ERR_MISPLACED_PSDO_HDR,
 | 
			
		||||
    /** Missing pseudo-header */
 | 
			
		||||
    LSQUIC_HDR_ERR_MISSING_PSDO_HDR,
 | 
			
		||||
    /** Header or headers are too large */
 | 
			
		||||
    LSQUIC_HDR_ERR_HEADERS_TOO_LARGE,
 | 
			
		||||
    /** Cannot allocate any more memory. */
 | 
			
		||||
    LSQUIC_HDR_ERR_NOMEM,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct lsquic_hset_if
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -905,27 +872,35 @@ struct lsquic_hset_if
 | 
			
		|||
    void *              (*hsi_create_header_set)(void *hsi_ctx,
 | 
			
		||||
                                                        int is_push_promise);
 | 
			
		||||
    /**
 | 
			
		||||
     * Process new header.  Return 0 on success, -1 if there is a problem with
 | 
			
		||||
     * the header.  -1 is treated as a stream error: the associated stream is
 | 
			
		||||
     * reset.
 | 
			
		||||
     * Return a header set prepared for decoding.  If `hdr' is NULL, this
 | 
			
		||||
     * means return a new structure with at least `space' bytes available
 | 
			
		||||
     * in the decoder buffer.  If `hdr' is not NULL, it means there was not
 | 
			
		||||
     * enough decoder buffer and it must be increased by `space' bytes.
 | 
			
		||||
     *
 | 
			
		||||
     * If NULL is returned the header set is discarded.
 | 
			
		||||
     */
 | 
			
		||||
    struct lsxpack_header *
 | 
			
		||||
                        (*hsi_prepare_decode)(void *hdr_set,
 | 
			
		||||
                                              struct lsxpack_header *hdr,
 | 
			
		||||
                                              size_t space);
 | 
			
		||||
    /**
 | 
			
		||||
     * Process new header.  Return 0 on success, a positive value if a header
 | 
			
		||||
     * error occured, or a negative value on any other error.
 | 
			
		||||
     *
 | 
			
		||||
     * A positive return value will result in cancellation of associated
 | 
			
		||||
     * stream.
 | 
			
		||||
     *
 | 
			
		||||
     * A negative return value will result in connection being aborted.
 | 
			
		||||
     *
 | 
			
		||||
     * `hdr_set' is the header set object returned by
 | 
			
		||||
     * @ref hsi_create_header_set().
 | 
			
		||||
     *
 | 
			
		||||
     * `name_idx' is set to the index in either the HPACK or QPACK static table
 | 
			
		||||
     * whose entry's name element matches `name'.  The values are as follows:
 | 
			
		||||
     *      - if there is no such match, `name_idx' is set to zero;
 | 
			
		||||
     *      - if HPACK is used, the value is between 1 and 61; and
 | 
			
		||||
     *      - if QPACK is used, the value is 62+ (subtract 62 to get the QPACK
 | 
			
		||||
     *        static table index).
 | 
			
		||||
     * `hdr' is the header returned by @ref `hsi_prepare_decode'.
 | 
			
		||||
     *
 | 
			
		||||
     * If `name' is NULL, this means that no more header are going to be
 | 
			
		||||
     * If `hdr' is NULL, this means that no more header are going to be
 | 
			
		||||
     * added to the set.
 | 
			
		||||
     */
 | 
			
		||||
    enum lsquic_header_status (*hsi_process_header)(void *hdr_set,
 | 
			
		||||
                                    unsigned name_idx,
 | 
			
		||||
                                    const char *name, unsigned name_len,
 | 
			
		||||
                                    const char *value, unsigned value_len);
 | 
			
		||||
    int (*hsi_process_header)(void *hdr_set, struct lsxpack_header *hdr);
 | 
			
		||||
    /**
 | 
			
		||||
     * Discard header set.  This is called for unclaimed header sets and
 | 
			
		||||
     * header sets that had an error.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										165
									
								
								include/lsxpack_header.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								include/lsxpack_header.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,165 @@
 | 
			
		|||
/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc.  See LICENSE. */
 | 
			
		||||
#ifndef LSXPACK_HEADER_H_v203
 | 
			
		||||
#define LSXPACK_HEADER_H_v203
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#ifndef LSXPACK_MAX_STRLEN
 | 
			
		||||
#define LSXPACK_MAX_STRLEN UINT16_MAX
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if LSXPACK_MAX_STRLEN == UINT16_MAX
 | 
			
		||||
typedef uint16_t lsxpack_strlen_t;
 | 
			
		||||
#elif LSXPACK_MAX_STRLEN == UINT32_MAX
 | 
			
		||||
typedef uint32_t lsxpack_strlen_t;
 | 
			
		||||
#else
 | 
			
		||||
#error unexpected LSXPACK_MAX_STRLEN
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
enum lsxpack_flag
 | 
			
		||||
{
 | 
			
		||||
    LSXPACK_HPACK_IDX = 1,
 | 
			
		||||
    LSXPACK_QPACK_IDX = 2,
 | 
			
		||||
    LSXPACK_APP_IDX   = 4,
 | 
			
		||||
    LSXPACK_NAME_HASH = 8,
 | 
			
		||||
    LSXPACK_NAMEVAL_HASH = 16,
 | 
			
		||||
    LSXPACK_VAL_MATCHED = 32,
 | 
			
		||||
    LSXPACK_NEVER_INDEX = 64,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * When header are decoded, it should be stored to @buf starting from @name_offset,
 | 
			
		||||
 *    <name>: <value>\r\n
 | 
			
		||||
 * So, it can be used directly as HTTP/1.1 header. there are 4 extra characters
 | 
			
		||||
 * added.
 | 
			
		||||
 *
 | 
			
		||||
 * limitation: we currently does not support total header size > 64KB.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
struct lsxpack_header
 | 
			
		||||
{
 | 
			
		||||
    char             *buf;          /* the buffer for headers */
 | 
			
		||||
    const char       *name_ptr;     /* the name pointer can be optionally set for encoding */
 | 
			
		||||
    uint32_t          name_hash;    /* hash value for name */
 | 
			
		||||
    uint32_t          nameval_hash; /* hash value for name + value */
 | 
			
		||||
    lsxpack_strlen_t  name_offset;  /* the offset for name in the buffer */
 | 
			
		||||
    lsxpack_strlen_t  name_len;     /* the length of name */
 | 
			
		||||
    lsxpack_strlen_t  val_offset;   /* the offset for value in the buffer */
 | 
			
		||||
    lsxpack_strlen_t  val_len;      /* the length of value */
 | 
			
		||||
    uint8_t           hpack_index;  /* HPACK static table index */
 | 
			
		||||
    uint8_t           qpack_index;  /* QPACK static table index */
 | 
			
		||||
    uint8_t           app_index;    /* APP header index */
 | 
			
		||||
    enum lsxpack_flag flags:8;      /* combination of lsxpack_flag */
 | 
			
		||||
    uint8_t           indexed_type; /* control to disable index or not */
 | 
			
		||||
    uint8_t           dec_overhead; /* num of extra bytes written to decoded buffer */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct lsxpack_header lsxpack_header_t;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static inline void
 | 
			
		||||
lsxpack_header_set_idx(lsxpack_header_t *hdr, int hpack_idx,
 | 
			
		||||
                       const char *val, size_t val_len)
 | 
			
		||||
{
 | 
			
		||||
    memset(hdr, 0, sizeof(*hdr));
 | 
			
		||||
    hdr->buf = (char *)val;
 | 
			
		||||
    hdr->hpack_index = hpack_idx;
 | 
			
		||||
    assert(hpack_idx != 0);
 | 
			
		||||
    hdr->flags = LSXPACK_HPACK_IDX;
 | 
			
		||||
    assert(val_len <= LSXPACK_MAX_STRLEN);
 | 
			
		||||
    hdr->val_len = val_len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static inline void
 | 
			
		||||
lsxpack_header_set_ptr(lsxpack_header_t *hdr,
 | 
			
		||||
                       const char *name, size_t name_len,
 | 
			
		||||
                       const char *val, size_t val_len)
 | 
			
		||||
{
 | 
			
		||||
    memset(hdr, 0, sizeof(*hdr));
 | 
			
		||||
    hdr->buf = (char *)val;
 | 
			
		||||
    assert(val_len <= LSXPACK_MAX_STRLEN);
 | 
			
		||||
    hdr->val_len = val_len;
 | 
			
		||||
    hdr->name_ptr = name;
 | 
			
		||||
    assert(name_len <= LSXPACK_MAX_STRLEN);
 | 
			
		||||
    hdr->name_len = name_len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static inline void
 | 
			
		||||
lsxpack_header_set_offset(lsxpack_header_t *hdr, const char *buf,
 | 
			
		||||
                          size_t name_offset, size_t name_len,
 | 
			
		||||
                          size_t val_len)
 | 
			
		||||
{
 | 
			
		||||
    memset(hdr, 0, sizeof(*hdr));
 | 
			
		||||
    hdr->buf = (char *)buf;
 | 
			
		||||
    hdr->name_offset = name_offset;
 | 
			
		||||
    assert(name_len <= LSXPACK_MAX_STRLEN);
 | 
			
		||||
    hdr->name_len = name_len;
 | 
			
		||||
    assert(name_offset + name_len + 2 <= LSXPACK_MAX_STRLEN);
 | 
			
		||||
    hdr->val_offset = name_offset + name_len + 2;
 | 
			
		||||
    assert(val_len <= LSXPACK_MAX_STRLEN);
 | 
			
		||||
    hdr->val_len = val_len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static inline void
 | 
			
		||||
lsxpack_header_set_offset2(lsxpack_header_t *hdr, const char *buf,
 | 
			
		||||
                           size_t name_offset, size_t name_len,
 | 
			
		||||
                           size_t val_offset, size_t val_len)
 | 
			
		||||
{
 | 
			
		||||
    memset(hdr, 0, sizeof(*hdr));
 | 
			
		||||
    hdr->buf = (char *)buf;
 | 
			
		||||
    hdr->name_offset = name_offset;
 | 
			
		||||
    assert(name_len <= LSXPACK_MAX_STRLEN);
 | 
			
		||||
    hdr->name_len = name_len;
 | 
			
		||||
    assert(val_offset <= LSXPACK_MAX_STRLEN);
 | 
			
		||||
    hdr->val_offset = val_offset;
 | 
			
		||||
    assert(val_len <= LSXPACK_MAX_STRLEN);
 | 
			
		||||
    hdr->val_len = val_len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static inline void
 | 
			
		||||
lsxpack_header_prepare_decode(lsxpack_header_t *hdr,
 | 
			
		||||
                              char *out, size_t offset, size_t len)
 | 
			
		||||
{
 | 
			
		||||
    memset(hdr, 0, sizeof(*hdr));
 | 
			
		||||
    hdr->buf = out;
 | 
			
		||||
    assert(offset <= LSXPACK_MAX_STRLEN);
 | 
			
		||||
    hdr->name_offset = offset;
 | 
			
		||||
    if (len > LSXPACK_MAX_STRLEN)
 | 
			
		||||
        hdr->val_len = LSXPACK_MAX_STRLEN;
 | 
			
		||||
    else
 | 
			
		||||
        hdr->val_len = len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static inline const char *
 | 
			
		||||
lsxpack_header_get_name(const lsxpack_header_t *hdr)
 | 
			
		||||
{
 | 
			
		||||
    return hdr->name_ptr ? hdr->name_ptr
 | 
			
		||||
                         : (hdr->name_len) ? hdr->buf + hdr->name_offset
 | 
			
		||||
                                           : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static inline const char *
 | 
			
		||||
lsxpack_header_get_value(const lsxpack_header_t *hdr)
 | 
			
		||||
{   return hdr->buf + hdr->val_offset;  }
 | 
			
		||||
 | 
			
		||||
static inline size_t
 | 
			
		||||
lsxpack_header_get_dec_size(const lsxpack_header_t *hdr)
 | 
			
		||||
{   return hdr->name_len + hdr->val_len + hdr->dec_overhead;    }
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif //LSXPACK_HEADER_H_v203
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +1 @@
 | 
			
		|||
Subproject commit c9aec0353776d98a371deff7c3f675a4bea190bd
 | 
			
		||||
Subproject commit d34c8c34dfb868417fbe14403f99290074341285
 | 
			
		||||
| 
						 | 
				
			
			@ -36,7 +36,7 @@ struct attq
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
struct attq *
 | 
			
		||||
attq_create (void)
 | 
			
		||||
lsquic_attq_create (void)
 | 
			
		||||
{
 | 
			
		||||
    struct attq *q;
 | 
			
		||||
    struct malo *malo;
 | 
			
		||||
| 
						 | 
				
			
			@ -58,7 +58,7 @@ attq_create (void)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
attq_destroy (struct attq *q)
 | 
			
		||||
lsquic_attq_destroy (struct attq *q)
 | 
			
		||||
{
 | 
			
		||||
    lsquic_malo_destroy(q->aq_elem_malo);
 | 
			
		||||
    free(q->aq_heap);
 | 
			
		||||
| 
						 | 
				
			
			@ -108,7 +108,7 @@ attq_swap (struct attq *q, unsigned a, unsigned b)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
attq_add (struct attq *q, struct lsquic_conn *conn,
 | 
			
		||||
lsquic_attq_add (struct attq *q, struct lsquic_conn *conn,
 | 
			
		||||
                                lsquic_time_t advisory_time, enum ae_why why)
 | 
			
		||||
{
 | 
			
		||||
    struct attq_elem *el, **heap;
 | 
			
		||||
| 
						 | 
				
			
			@ -155,7 +155,7 @@ attq_add (struct attq *q, struct lsquic_conn *conn,
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
struct lsquic_conn *
 | 
			
		||||
attq_pop (struct attq *q, lsquic_time_t cutoff)
 | 
			
		||||
lsquic_attq_pop (struct attq *q, lsquic_time_t cutoff)
 | 
			
		||||
{
 | 
			
		||||
    struct lsquic_conn *conn;
 | 
			
		||||
    struct attq_elem *el;
 | 
			
		||||
| 
						 | 
				
			
			@ -168,7 +168,7 @@ attq_pop (struct attq *q, lsquic_time_t cutoff)
 | 
			
		|||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    conn = el->ae_conn;
 | 
			
		||||
    attq_remove(q, conn);
 | 
			
		||||
    lsquic_attq_remove(q, conn);
 | 
			
		||||
    return conn;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -204,7 +204,7 @@ attq_heapify (struct attq *q, unsigned i)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
attq_remove (struct attq *q, struct lsquic_conn *conn)
 | 
			
		||||
lsquic_attq_remove (struct attq *q, struct lsquic_conn *conn)
 | 
			
		||||
{
 | 
			
		||||
    struct attq_elem *el;
 | 
			
		||||
    unsigned idx;
 | 
			
		||||
| 
						 | 
				
			
			@ -239,7 +239,7 @@ attq_remove (struct attq *q, struct lsquic_conn *conn)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
unsigned
 | 
			
		||||
attq_count_before (struct attq *q, lsquic_time_t cutoff)
 | 
			
		||||
lsquic_attq_count_before (struct attq *q, lsquic_time_t cutoff)
 | 
			
		||||
{
 | 
			
		||||
    unsigned level, total_count, level_count, i, level_max;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -260,7 +260,7 @@ attq_count_before (struct attq *q, lsquic_time_t cutoff)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
const struct attq_elem *
 | 
			
		||||
attq_next (struct attq *q)
 | 
			
		||||
lsquic_attq_next (struct attq *q)
 | 
			
		||||
{
 | 
			
		||||
    if (q->aq_nelem > 0)
 | 
			
		||||
        return q->aq_heap[0];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,27 +31,27 @@ struct attq_elem
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
struct attq *
 | 
			
		||||
attq_create (void);
 | 
			
		||||
lsquic_attq_create (void);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
attq_destroy (struct attq *);
 | 
			
		||||
lsquic_attq_destroy (struct attq *);
 | 
			
		||||
 | 
			
		||||
/* Return 0 on success, -1 on failure (malloc) */
 | 
			
		||||
int
 | 
			
		||||
attq_add (struct attq *, struct lsquic_conn *, lsquic_time_t advisory_time,
 | 
			
		||||
lsquic_attq_add (struct attq *, struct lsquic_conn *, lsquic_time_t advisory_time,
 | 
			
		||||
                enum ae_why);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
attq_remove (struct attq *, struct lsquic_conn *);
 | 
			
		||||
lsquic_attq_remove (struct attq *, struct lsquic_conn *);
 | 
			
		||||
 | 
			
		||||
struct lsquic_conn *
 | 
			
		||||
attq_pop (struct attq *, lsquic_time_t cutoff);
 | 
			
		||||
lsquic_attq_pop (struct attq *, lsquic_time_t cutoff);
 | 
			
		||||
 | 
			
		||||
unsigned
 | 
			
		||||
attq_count_before (struct attq *, lsquic_time_t cutoff);
 | 
			
		||||
lsquic_attq_count_before (struct attq *, lsquic_time_t cutoff);
 | 
			
		||||
 | 
			
		||||
const struct attq_elem *
 | 
			
		||||
attq_next (struct attq *);
 | 
			
		||||
lsquic_attq_next (struct attq *);
 | 
			
		||||
 | 
			
		||||
const char *
 | 
			
		||||
lsquic_attq_why2str (enum ae_why);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -162,7 +162,12 @@ const common_cert_t common_cert_set[common_certs_num] = {
 | 
			
		|||
 | 
			
		||||
static lsquic_str_t *s_ccsbuf;
 | 
			
		||||
 | 
			
		||||
lsquic_str_t * get_common_certs_hash()
 | 
			
		||||
static int
 | 
			
		||||
match_common_cert (lsquic_str_t * cert, lsquic_str_t * common_set_hashes,
 | 
			
		||||
        uint64_t* out_hash, uint32_t* out_index);
 | 
			
		||||
 | 
			
		||||
lsquic_str_t *
 | 
			
		||||
lsquic_get_common_certs_hash()
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    if (s_ccsbuf == NULL)
 | 
			
		||||
| 
						 | 
				
			
			@ -178,7 +183,8 @@ lsquic_str_t * get_common_certs_hash()
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
/* return 0 found, -1 not found */
 | 
			
		||||
int get_common_cert(uint64_t hash, uint32_t index, lsquic_str_t *buf)
 | 
			
		||||
int
 | 
			
		||||
lsquic_get_common_cert(uint64_t hash, uint32_t index, lsquic_str_t *buf)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    for (i = 0; i < common_certs_num; i++)
 | 
			
		||||
| 
						 | 
				
			
			@ -214,7 +220,8 @@ comp_ls_str (lsquic_str_t * a, const void * b, size_t b_len)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
/* 0, matched -1, error */
 | 
			
		||||
int match_common_cert(lsquic_str_t * cert, lsquic_str_t * common_set_hashes,
 | 
			
		||||
static int
 | 
			
		||||
match_common_cert (lsquic_str_t * cert, lsquic_str_t * common_set_hashes,
 | 
			
		||||
        uint64_t* out_hash, uint32_t* out_index)
 | 
			
		||||
{
 | 
			
		||||
    size_t i, j;
 | 
			
		||||
| 
						 | 
				
			
			@ -299,12 +306,13 @@ make_zlib_dict_for_entries(cert_entry_t *entries,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void get_certs_hash(lsquic_str_t *certs, size_t certs_count, uint64_t *hashs)
 | 
			
		||||
{
 | 
			
		||||
    size_t i;
 | 
			
		||||
    for(i = 0; i < certs_count; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        hashs[i] = fnv1a_64((const uint8_t *)lsquic_str_buf(&certs[i]), lsquic_str_len(&certs[i]));
 | 
			
		||||
        hashs[i] = lsquic_fnv1a_64((const uint8_t *)lsquic_str_buf(&certs[i]), lsquic_str_len(&certs[i]));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -331,7 +339,7 @@ static void get_certs_entries(lsquic_str_t **certs, size_t certs_count,
 | 
			
		|||
        if (cached_valid)
 | 
			
		||||
        {
 | 
			
		||||
            cached = false;
 | 
			
		||||
            hash = fnv1a_64((const uint8_t *)lsquic_str_buf(certs[i]), lsquic_str_len(certs[i]));
 | 
			
		||||
            hash = lsquic_fnv1a_64((const uint8_t *)lsquic_str_buf(certs[i]), lsquic_str_len(certs[i]));
 | 
			
		||||
 | 
			
		||||
            for (j = 0; j < (int)lsquic_str_len(client_cached_cert_hashes);
 | 
			
		||||
                 j += sizeof(uint64_t))
 | 
			
		||||
| 
						 | 
				
			
			@ -362,7 +370,8 @@ static void get_certs_entries(lsquic_str_t **certs, size_t certs_count,
 | 
			
		|||
   }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t get_entries_size(cert_entry_t *entries, size_t entries_count)
 | 
			
		||||
static size_t
 | 
			
		||||
get_entries_size(cert_entry_t *entries, size_t entries_count)
 | 
			
		||||
{
 | 
			
		||||
    size_t i;
 | 
			
		||||
    size_t entries_size = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -387,6 +396,7 @@ size_t get_entries_size(cert_entry_t *entries, size_t entries_count)
 | 
			
		|||
    return entries_size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void serialize_cert_entries(uint8_t* out, int *out_len, cert_entry_t *entries,
 | 
			
		||||
                            size_t entries_count)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -419,7 +429,8 @@ void serialize_cert_entries(uint8_t* out, int *out_len, cert_entry_t *entries,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int get_certs_count(lsquic_str_t *compressed_crt_buf)
 | 
			
		||||
int
 | 
			
		||||
lsquic_get_certs_count(lsquic_str_t *compressed_crt_buf)
 | 
			
		||||
{
 | 
			
		||||
    char *in = lsquic_str_buf(compressed_crt_buf);
 | 
			
		||||
    char *in_end = in + lsquic_str_len(compressed_crt_buf);
 | 
			
		||||
| 
						 | 
				
			
			@ -535,7 +546,7 @@ static int parse_entries(const unsigned char **in_out, const unsigned char *cons
 | 
			
		|||
            memcpy(&entry->index, in, sizeof(uint32_t));
 | 
			
		||||
            in += sizeof(uint32_t);
 | 
			
		||||
 | 
			
		||||
            if (0 == get_common_cert(entry->set_hash, entry->index, cert))
 | 
			
		||||
            if (0 == lsquic_get_common_cert(entry->set_hash, entry->index, cert))
 | 
			
		||||
                break;
 | 
			
		||||
            else
 | 
			
		||||
                goto err;
 | 
			
		||||
| 
						 | 
				
			
			@ -560,7 +571,8 @@ static int parse_entries(const unsigned char **in_out, const unsigned char *cons
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
/* return 0 for OK */
 | 
			
		||||
int compress_certs(lsquic_str_t **certs, size_t certs_count,
 | 
			
		||||
int
 | 
			
		||||
lsquic_compress_certs (lsquic_str_t **certs, size_t certs_count,
 | 
			
		||||
                   lsquic_str_t *client_common_set_hashes,
 | 
			
		||||
                   lsquic_str_t *client_cached_cert_hashes,
 | 
			
		||||
                   lsquic_str_t *result)
 | 
			
		||||
| 
						 | 
				
			
			@ -670,7 +682,8 @@ int compress_certs(lsquic_str_t **certs, size_t certs_count,
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
/* 0: ok */
 | 
			
		||||
int decompress_certs(const unsigned char *in, const unsigned char *in_end,
 | 
			
		||||
int
 | 
			
		||||
lsquic_decompress_certs (const unsigned char *in, const unsigned char *in_end,
 | 
			
		||||
                     lsquic_str_t *cached_certs, size_t cached_certs_count,
 | 
			
		||||
                     lsquic_str_t **out_certs, size_t *out_certs_count)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -684,7 +697,7 @@ int decompress_certs(const unsigned char *in, const unsigned char *in_end,
 | 
			
		|||
    z_stream z;
 | 
			
		||||
 | 
			
		||||
    assert(*out_certs_count > 0 && *out_certs_count < 10000
 | 
			
		||||
            && "Call get_certs_count() to get right certificates count first and make enough room for out_certs_count");
 | 
			
		||||
            && "Call lsquic_get_certs_count() to get right certificates count first and make enough room for out_certs_count");
 | 
			
		||||
    
 | 
			
		||||
    if (count == 0 || count > 10000)
 | 
			
		||||
        return -1;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,20 +34,18 @@ typedef struct common_cert_st
 | 
			
		|||
    uint64_t hash;
 | 
			
		||||
} common_cert_t;
 | 
			
		||||
 | 
			
		||||
struct lsquic_str * get_common_certs_hash();
 | 
			
		||||
struct lsquic_str * lsquic_get_common_certs_hash();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int get_common_cert(uint64_t hash, uint32_t index, struct lsquic_str *buf);
 | 
			
		||||
int match_common_cert(struct lsquic_str * cert, struct lsquic_str * common_set_hashes,
 | 
			
		||||
                      uint64_t* out_hash, uint32_t* out_index);
 | 
			
		||||
int lsquic_get_common_cert(uint64_t hash, uint32_t index, struct lsquic_str *buf);
 | 
			
		||||
 | 
			
		||||
int compress_certs(struct lsquic_str **certs, size_t certs_count,
 | 
			
		||||
int lsquic_compress_certs(struct lsquic_str **certs, size_t certs_count,
 | 
			
		||||
                   struct lsquic_str *client_common_set_hashes,
 | 
			
		||||
                   struct lsquic_str *client_cached_cert_hashes,
 | 
			
		||||
                   struct lsquic_str *result);
 | 
			
		||||
 | 
			
		||||
int get_certs_count(struct lsquic_str *compressed_crt_buf);
 | 
			
		||||
int decompress_certs(const unsigned char *in, const unsigned char *in_end,
 | 
			
		||||
int lsquic_get_certs_count(struct lsquic_str *compressed_crt_buf);
 | 
			
		||||
int lsquic_decompress_certs(const unsigned char *in, const unsigned char *in_end,
 | 
			
		||||
                     struct lsquic_str *cached_certs, size_t cached_certs_count,
 | 
			
		||||
                     struct lsquic_str **out_certs, 
 | 
			
		||||
                     size_t *out_certs_count);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,7 +30,7 @@ static const char s_hs_signature[] = "QUIC CHLO and server config signature";
 | 
			
		|||
static int crypto_inited = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint64_t fnv1a_64(const uint8_t * data, int len)
 | 
			
		||||
uint64_t lsquic_fnv1a_64(const uint8_t * data, int len)
 | 
			
		||||
{
 | 
			
		||||
    uint64_t hash = UINT64_C(14695981039346656037);
 | 
			
		||||
    const uint8_t *end = data + len;
 | 
			
		||||
| 
						 | 
				
			
			@ -44,9 +44,9 @@ uint64_t fnv1a_64(const uint8_t * data, int len)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void fnv1a_64_s(const uint8_t * data, int len, char *md)
 | 
			
		||||
void lsquic_fnv1a_64_s(const uint8_t * data, int len, char *md)
 | 
			
		||||
{
 | 
			
		||||
    uint64_t hash = fnv1a_64(data, len);
 | 
			
		||||
    uint64_t hash = lsquic_fnv1a_64(data, len);
 | 
			
		||||
    memcpy(md, (void *)&hash, 8);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -65,7 +65,7 @@ static inline void make_uint128(uint128 *v, uint64_t hi, uint64_t lo)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void fnv1a_inc(uint128 *hash, const uint8_t *data, int len)
 | 
			
		||||
void lsquic_fnv1a_inc(uint128 *hash, const uint8_t *data, int len)
 | 
			
		||||
{
 | 
			
		||||
    const uint8_t* end = data + len;
 | 
			
		||||
    while(data < end)
 | 
			
		||||
| 
						 | 
				
			
			@ -75,21 +75,21 @@ void fnv1a_inc(uint128 *hash, const uint8_t *data, int len)
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint128 fnv1a_128_3(const uint8_t *data1, int len1,
 | 
			
		||||
uint128 lsquic_fnv1a_128_3(const uint8_t *data1, int len1,
 | 
			
		||||
                      const uint8_t *data2, int len2,
 | 
			
		||||
                      const uint8_t *data3, int len3)
 | 
			
		||||
{
 | 
			
		||||
    uint128 hash;
 | 
			
		||||
    memcpy(&hash, &s_init_hash, 16);
 | 
			
		||||
 | 
			
		||||
    fnv1a_inc(&hash, data1, len1);
 | 
			
		||||
    fnv1a_inc(&hash, data2, len2);
 | 
			
		||||
    fnv1a_inc(&hash, data3, len3);
 | 
			
		||||
    lsquic_fnv1a_inc(&hash, data1, len1);
 | 
			
		||||
    lsquic_fnv1a_inc(&hash, data2, len2);
 | 
			
		||||
    lsquic_fnv1a_inc(&hash, data3, len3);
 | 
			
		||||
    return hash;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* HS_PKT_HASH_LENGTH bytes of md */
 | 
			
		||||
void serialize_fnv128_short(uint128 v, uint8_t *md)
 | 
			
		||||
void lsquic_serialize_fnv128_short(uint128 v, uint8_t *md)
 | 
			
		||||
{
 | 
			
		||||
    memcpy(md, (void *)&v, 12);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -131,7 +131,7 @@ uint128  *uint128_times(uint128 *v, const uint128 *factor)
 | 
			
		|||
    return v;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void fnv1a_inc(uint128 *hash, const uint8_t * data, int len)
 | 
			
		||||
void lsquic_fnv1a_inc(uint128 *hash, const uint8_t * data, int len)
 | 
			
		||||
{
 | 
			
		||||
    static const uint128 kPrime = {16777216, 315};
 | 
			
		||||
    const uint8_t* end = data + len;
 | 
			
		||||
| 
						 | 
				
			
			@ -144,20 +144,20 @@ void fnv1a_inc(uint128 *hash, const uint8_t * data, int len)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint128 fnv1a_128_3(const uint8_t * data1, int len1,
 | 
			
		||||
uint128 lsquic_fnv1a_128_3(const uint8_t * data1, int len1,
 | 
			
		||||
                      const uint8_t * data2, int len2,
 | 
			
		||||
                      const uint8_t * data3, int len3)
 | 
			
		||||
{
 | 
			
		||||
    uint128 hash = {UINT64_C(7809847782465536322), UINT64_C(7113472399480571277)};
 | 
			
		||||
    fnv1a_inc(&hash, data1, len1);
 | 
			
		||||
    fnv1a_inc(&hash, data2, len2);
 | 
			
		||||
    fnv1a_inc(&hash, data3, len3);
 | 
			
		||||
    lsquic_fnv1a_inc(&hash, data1, len1);
 | 
			
		||||
    lsquic_fnv1a_inc(&hash, data2, len2);
 | 
			
		||||
    lsquic_fnv1a_inc(&hash, data3, len3);
 | 
			
		||||
    return hash;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* HS_PKT_HASH_LENGTH bytes of md */
 | 
			
		||||
void serialize_fnv128_short(uint128 v, uint8_t *md)
 | 
			
		||||
void lsquic_serialize_fnv128_short(uint128 v, uint8_t *md)
 | 
			
		||||
{
 | 
			
		||||
    assert(HS_PKT_HASH_LENGTH == 8 + 4);
 | 
			
		||||
    memcpy(md, (void *)&v.lo_, 8);
 | 
			
		||||
| 
						 | 
				
			
			@ -266,7 +266,8 @@ int lshkdf_expand(const unsigned char *prk, const unsigned char *info, int info_
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int export_key_material_simple(unsigned char *ikm, uint32_t ikm_len,
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
int lsquic_export_key_material_simple(unsigned char *ikm, uint32_t ikm_len,
 | 
			
		||||
                        unsigned char *salt, int salt_len,
 | 
			
		||||
                        char *label, uint32_t label_len,
 | 
			
		||||
                        const uint8_t *context, uint32_t context_len,
 | 
			
		||||
| 
						 | 
				
			
			@ -292,6 +293,7 @@ int export_key_material_simple(unsigned char *ikm, uint32_t ikm_len,
 | 
			
		|||
    free(info);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
| 
						 | 
				
			
			@ -314,13 +316,13 @@ lsquic_export_key_material(const unsigned char *ikm, uint32_t ikm_len,
 | 
			
		|||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void c255_get_pub_key(unsigned char *priv_key, unsigned char pub_key[32])
 | 
			
		||||
void lsquic_c255_get_pub_key(unsigned char *priv_key, unsigned char pub_key[32])
 | 
			
		||||
{
 | 
			
		||||
    X25519_public_from_private(pub_key, priv_key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int c255_gen_share_key(unsigned char *priv_key, unsigned char *peer_pub_key, unsigned char *shared_key)
 | 
			
		||||
int lsquic_c255_gen_share_key(unsigned char *priv_key, unsigned char *peer_pub_key, unsigned char *shared_key)
 | 
			
		||||
{
 | 
			
		||||
    return X25519(shared_key, priv_key, peer_pub_key);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -329,7 +331,7 @@ int c255_gen_share_key(unsigned char *priv_key, unsigned char *peer_pub_key, uns
 | 
			
		|||
 | 
			
		||||
/* AEAD nonce is always zero */
 | 
			
		||||
/* return 0 for OK */
 | 
			
		||||
int aes_aead_enc(EVP_AEAD_CTX *key,
 | 
			
		||||
int lsquic_aes_aead_enc(EVP_AEAD_CTX *key,
 | 
			
		||||
              const uint8_t *ad, size_t ad_len,
 | 
			
		||||
              const uint8_t *nonce, size_t nonce_len, 
 | 
			
		||||
              const uint8_t *plain, size_t plain_len,
 | 
			
		||||
| 
						 | 
				
			
			@ -340,28 +342,28 @@ int aes_aead_enc(EVP_AEAD_CTX *key,
 | 
			
		|||
    max_out_len = *cypher_len;//plain_len + EVP_AEAD_max_overhead(aead_);
 | 
			
		||||
    assert(*cypher_len >= max_out_len);
 | 
			
		||||
 | 
			
		||||
    LSQ_DEBUG("***aes_aead_enc data %s", get_bin_str(plain, plain_len, 40));
 | 
			
		||||
    LSQ_DEBUG("***lsquic_aes_aead_enc data %s", lsquic_get_bin_str(plain, plain_len, 40));
 | 
			
		||||
    ret = EVP_AEAD_CTX_seal(key, cypher, cypher_len, max_out_len, 
 | 
			
		||||
                            nonce, nonce_len, plain, plain_len, ad, ad_len);
 | 
			
		||||
//     LSQ_DEBUG("***aes_aead_enc nonce: %s", get_bin_str(nonce, nonce_len));
 | 
			
		||||
//     LSQ_DEBUG("***aes_aead_enc AD: %s", get_bin_str(ad, ad_len));
 | 
			
		||||
//     LSQ_DEBUG("***aes_aead_enc return %d", (ret ? 0 : -1));
 | 
			
		||||
//     LSQ_DEBUG("***lsquic_aes_aead_enc nonce: %s", lsquic_get_bin_str(nonce, nonce_len));
 | 
			
		||||
//     LSQ_DEBUG("***lsquic_aes_aead_enc AD: %s", lsquic_get_bin_str(ad, ad_len));
 | 
			
		||||
//     LSQ_DEBUG("***lsquic_aes_aead_enc return %d", (ret ? 0 : -1));
 | 
			
		||||
    if (ret)
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_DEBUG("***aes_aead_enc succeed, cypher content %s",
 | 
			
		||||
                  get_bin_str(cypher, *cypher_len, 40));
 | 
			
		||||
        LSQ_DEBUG("***lsquic_aes_aead_enc succeed, cypher content %s",
 | 
			
		||||
                  lsquic_get_bin_str(cypher, *cypher_len, 40));
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_DEBUG("***aes_aead_enc failed.");
 | 
			
		||||
        LSQ_DEBUG("***lsquic_aes_aead_enc failed.");
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* return 0 for OK */
 | 
			
		||||
int aes_aead_dec(EVP_AEAD_CTX *key,
 | 
			
		||||
int lsquic_aes_aead_dec(EVP_AEAD_CTX *key,
 | 
			
		||||
              const uint8_t *ad, size_t ad_len,
 | 
			
		||||
              const uint8_t *nonce, size_t nonce_len, 
 | 
			
		||||
              const uint8_t *cypher, size_t cypher_len,
 | 
			
		||||
| 
						 | 
				
			
			@ -371,30 +373,30 @@ int aes_aead_dec(EVP_AEAD_CTX *key,
 | 
			
		|||
    size_t max_out_len = *plain_len;
 | 
			
		||||
    assert(max_out_len >= cypher_len);
 | 
			
		||||
 | 
			
		||||
    LSQ_DEBUG("***aes_aead_dec data %s", get_bin_str(cypher, cypher_len, 40));
 | 
			
		||||
    LSQ_DEBUG("***lsquic_aes_aead_dec data %s", lsquic_get_bin_str(cypher, cypher_len, 40));
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    ret = EVP_AEAD_CTX_open(key, plain, plain_len, max_out_len,
 | 
			
		||||
                            nonce, nonce_len, cypher, cypher_len, ad, ad_len);
 | 
			
		||||
    
 | 
			
		||||
//    LSQ_DEBUG("***aes_aead_dec nonce: %s", get_bin_str(nonce, nonce_len));
 | 
			
		||||
//    LSQ_DEBUG("***aes_aead_dec AD: %s", get_bin_str(ad, ad_len));
 | 
			
		||||
//    LSQ_DEBUG("***aes_aead_dec return %d", (ret ? 0 : -1));
 | 
			
		||||
//    LSQ_DEBUG("***lsquic_aes_aead_dec nonce: %s", lsquic_get_bin_str(nonce, nonce_len));
 | 
			
		||||
//    LSQ_DEBUG("***lsquic_aes_aead_dec AD: %s", lsquic_get_bin_str(ad, ad_len));
 | 
			
		||||
//    LSQ_DEBUG("***lsquic_aes_aead_dec return %d", (ret ? 0 : -1));
 | 
			
		||||
    if (ret)
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_DEBUG("***aes_aead_dec succeed, plain content %s",
 | 
			
		||||
              get_bin_str(plain, *plain_len, 20));
 | 
			
		||||
        LSQ_DEBUG("***lsquic_aes_aead_dec succeed, plain content %s",
 | 
			
		||||
              lsquic_get_bin_str(plain, *plain_len, 20));
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_DEBUG("***aes_aead_dec failed.");
 | 
			
		||||
        LSQ_DEBUG("***lsquic_aes_aead_dec failed.");
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 32 bytes client nonce with 4 bytes tm, 8 bytes orbit */
 | 
			
		||||
void gen_nonce_c(unsigned char *buf, uint64_t orbit)
 | 
			
		||||
void lsquic_gen_nonce_c(unsigned char *buf, uint64_t orbit)
 | 
			
		||||
{
 | 
			
		||||
    time_t tm = time(NULL);
 | 
			
		||||
    unsigned char *p = buf;
 | 
			
		||||
| 
						 | 
				
			
			@ -407,25 +409,9 @@ void gen_nonce_c(unsigned char *buf, uint64_t orbit)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
EVP_PKEY *PEM_to_key(const char *buf, int len)
 | 
			
		||||
{
 | 
			
		||||
    RSA *rsa = NULL;
 | 
			
		||||
    EVP_PKEY *key = EVP_PKEY_new();
 | 
			
		||||
    BIO *bio = BIO_new_mem_buf(buf, len);
 | 
			
		||||
    if (!bio || !key)
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    rsa = PEM_read_bio_RSAPrivateKey(bio, &rsa, NULL, NULL);
 | 
			
		||||
    if (!rsa)
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    EVP_PKEY_assign_RSA(key, rsa);
 | 
			
		||||
    return key;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* type 0 DER, 1: PEM */
 | 
			
		||||
X509 *bio_to_crt(const void *buf, int len, int type)
 | 
			
		||||
X509 *
 | 
			
		||||
lsquic_bio_to_crt (const void *buf, int len, int type)
 | 
			
		||||
{
 | 
			
		||||
    X509 *crt = NULL;
 | 
			
		||||
    BIO *bio = BIO_new_mem_buf(buf, len);
 | 
			
		||||
| 
						 | 
				
			
			@ -441,7 +427,8 @@ X509 *bio_to_crt(const void *buf, int len, int type)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int gen_prof(const uint8_t *chlo_data, size_t chlo_data_len,
 | 
			
		||||
int
 | 
			
		||||
lsquic_gen_prof (const uint8_t *chlo_data, size_t chlo_data_len,
 | 
			
		||||
             const uint8_t *scfg_data, uint32_t scfg_data_len,
 | 
			
		||||
             const EVP_PKEY *priv_key, uint8_t *buf, size_t *buf_len)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -481,19 +468,9 @@ int gen_prof(const uint8_t *chlo_data, size_t chlo_data_len,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int verify_prof(const uint8_t *chlo_data, size_t chlo_data_len, lsquic_str_t * scfg,
 | 
			
		||||
                const EVP_PKEY *pub_key, const uint8_t *buf, size_t len)
 | 
			
		||||
{
 | 
			
		||||
    return verify_prof0(chlo_data, chlo_data_len,
 | 
			
		||||
                        (const uint8_t *)lsquic_str_buf(scfg),
 | 
			
		||||
                        lsquic_str_len(scfg), pub_key, buf, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -3 internal error, -1: verify failed, 0: Success */
 | 
			
		||||
int verify_prof0(const uint8_t *chlo_data, size_t chlo_data_len,
 | 
			
		||||
static int
 | 
			
		||||
verify_prof0 (const uint8_t *chlo_data, size_t chlo_data_len,
 | 
			
		||||
                const uint8_t *scfg_data, uint32_t scfg_data_len,
 | 
			
		||||
                const EVP_PKEY *pub_key, const uint8_t *buf, size_t len)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -531,7 +508,18 @@ int verify_prof0(const uint8_t *chlo_data, size_t chlo_data_len,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void crypto_init(void)
 | 
			
		||||
int
 | 
			
		||||
lsquic_verify_prof (const uint8_t *chlo_data, size_t chlo_data_len,
 | 
			
		||||
    lsquic_str_t *scfg, const EVP_PKEY *pub_key, const uint8_t *buf, size_t len)
 | 
			
		||||
{
 | 
			
		||||
    return verify_prof0(chlo_data, chlo_data_len,
 | 
			
		||||
                        (const uint8_t *)lsquic_str_buf(scfg),
 | 
			
		||||
                        lsquic_str_len(scfg), pub_key, buf, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
lsquic_crypto_init (void)
 | 
			
		||||
{
 | 
			
		||||
    if (crypto_inited)
 | 
			
		||||
        return ;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,14 +28,16 @@ struct x509_st;
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void crypto_init(void);
 | 
			
		||||
void lsquic_crypto_init(void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int export_key_material_simple(unsigned char *ikm, uint32_t ikm_len,
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
int lsquic_export_key_material_simple(unsigned char *ikm, uint32_t ikm_len,
 | 
			
		||||
                        unsigned char *salt, int salt_len,
 | 
			
		||||
                        char *label, uint32_t label_len,
 | 
			
		||||
                        const uint8_t *context, uint32_t context_len,
 | 
			
		||||
                        uint8_t *key, uint16_t key_len);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int lsquic_export_key_material(const unsigned char *ikm, uint32_t ikm_len,
 | 
			
		||||
                        const unsigned char *salt, int salt_len,
 | 
			
		||||
| 
						 | 
				
			
			@ -47,39 +49,37 @@ int lsquic_export_key_material(const unsigned char *ikm, uint32_t ikm_len,
 | 
			
		|||
                        uint8_t *sub_key,
 | 
			
		||||
                        uint8_t *c_hp, uint8_t *s_hp);
 | 
			
		||||
 | 
			
		||||
void c255_get_pub_key(unsigned char *priv_key, unsigned char pub_key[32]);
 | 
			
		||||
int c255_gen_share_key(unsigned char *priv_key, unsigned char *peer_pub_key, unsigned char *shared_key);
 | 
			
		||||
void lsquic_c255_get_pub_key(unsigned char *priv_key, unsigned char pub_key[32]);
 | 
			
		||||
int lsquic_c255_gen_share_key(unsigned char *priv_key, unsigned char *peer_pub_key, unsigned char *shared_key);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint64_t fnv1a_64(const uint8_t * data, int len);
 | 
			
		||||
void fnv1a_64_s(const uint8_t * data, int len, char *md);
 | 
			
		||||
void fnv1a_128_s(const uint8_t * data , int len, uint8_t  *md);
 | 
			
		||||
uint128 fnv1a_128_3(const uint8_t * data1, int len1,
 | 
			
		||||
uint64_t lsquic_fnv1a_64(const uint8_t * data, int len);
 | 
			
		||||
void lsquic_fnv1a_64_s(const uint8_t * data, int len, char *md);
 | 
			
		||||
void lsquic_fnv1a_128_s(const uint8_t * data , int len, uint8_t  *md);
 | 
			
		||||
uint128 lsquic_fnv1a_128_3(const uint8_t * data1, int len1,
 | 
			
		||||
                      const uint8_t * data2, int len2,
 | 
			
		||||
                      const uint8_t * data3, int len3);
 | 
			
		||||
void serialize_fnv128_short(uint128 v, uint8_t *md);
 | 
			
		||||
void lsquic_serialize_fnv128_short(uint128 v, uint8_t *md);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Encrypt plaint text to cipher test */
 | 
			
		||||
int aes_aead_enc(struct evp_aead_ctx_st *key,
 | 
			
		||||
int lsquic_aes_aead_enc(struct evp_aead_ctx_st *key,
 | 
			
		||||
              const uint8_t *ad, size_t ad_len,
 | 
			
		||||
              const uint8_t *nonce, size_t nonce_len, 
 | 
			
		||||
              const uint8_t *plain, size_t plain_len,
 | 
			
		||||
              uint8_t *cypher, size_t *cypher_len);
 | 
			
		||||
 | 
			
		||||
int aes_aead_dec(struct evp_aead_ctx_st *key,
 | 
			
		||||
int lsquic_aes_aead_dec(struct evp_aead_ctx_st *key,
 | 
			
		||||
              const uint8_t *ad, size_t ad_len,
 | 
			
		||||
              const uint8_t *nonce, size_t nonce_len, 
 | 
			
		||||
              const uint8_t *cypher, size_t cypher_len,
 | 
			
		||||
              uint8_t *plain, size_t *plain_len);
 | 
			
		||||
 | 
			
		||||
/* 32 bytes client nonce with 4 bytes tm, 8 bytes orbit */
 | 
			
		||||
void gen_nonce_c(unsigned char *buf, uint64_t orbit);
 | 
			
		||||
void lsquic_gen_nonce_c(unsigned char *buf, uint64_t orbit);
 | 
			
		||||
 | 
			
		||||
struct evp_pkey_st *PEM_to_key(const char *buf, int len);
 | 
			
		||||
 | 
			
		||||
struct x509_st *bio_to_crt(const void *buf, int len, int type);
 | 
			
		||||
struct x509_st *lsquic_bio_to_crt(const void *buf, int len, int type);
 | 
			
		||||
 | 
			
		||||
int lshkdf_expand(const unsigned char *prk, const unsigned char *info, int info_len,
 | 
			
		||||
                uint16_t c_key_len, uint8_t *c_key,
 | 
			
		||||
| 
						 | 
				
			
			@ -91,14 +91,11 @@ int lshkdf_expand(const unsigned char *prk, const unsigned char *info, int info_
 | 
			
		|||
void lshkdf_extract(const unsigned char *ikm, int ikm_len, const unsigned char *salt,
 | 
			
		||||
                  int salt_len, unsigned char *prk);
 | 
			
		||||
 | 
			
		||||
int gen_prof(const uint8_t *chlo_data, size_t chlo_data_len,
 | 
			
		||||
int lsquic_gen_prof(const uint8_t *chlo_data, size_t chlo_data_len,
 | 
			
		||||
             const uint8_t *scfg_data, uint32_t scfg_data_len,
 | 
			
		||||
             const struct evp_pkey_st *priv_key, uint8_t *buf, size_t *len);
 | 
			
		||||
int verify_prof0(const uint8_t *chlo_data, size_t chlo_data_len,
 | 
			
		||||
                const uint8_t *scfg_data, uint32_t scfg_data_len,
 | 
			
		||||
                const struct evp_pkey_st *pub_key, const uint8_t *buf, size_t len);
 | 
			
		||||
 | 
			
		||||
int verify_prof(const uint8_t *chlo_data, size_t chlo_data_len, struct lsquic_str * scfg,
 | 
			
		||||
int lsquic_verify_prof(const uint8_t *chlo_data, size_t chlo_data_len, struct lsquic_str * scfg,
 | 
			
		||||
                const struct evp_pkey_st *pub_key, const uint8_t *buf, size_t len);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -92,20 +92,20 @@ struct data_in
 | 
			
		|||
 * INS_FRAME_OVERLAP.
 | 
			
		||||
 */
 | 
			
		||||
struct data_in *
 | 
			
		||||
data_in_nocopy_new (struct lsquic_conn_public *, lsquic_stream_id_t);
 | 
			
		||||
lsquic_data_in_nocopy_new (struct lsquic_conn_public *, lsquic_stream_id_t);
 | 
			
		||||
 | 
			
		||||
/* This implementation supports overlapping frames and will never return
 | 
			
		||||
 * INS_FRAME_OVERLAP.
 | 
			
		||||
 */
 | 
			
		||||
struct data_in *
 | 
			
		||||
data_in_hash_new (struct lsquic_conn_public *, lsquic_stream_id_t,
 | 
			
		||||
lsquic_data_in_hash_new (struct lsquic_conn_public *, lsquic_stream_id_t,
 | 
			
		||||
                  uint64_t byteage);
 | 
			
		||||
 | 
			
		||||
enum ins_frame
 | 
			
		||||
data_in_hash_insert_data_frame (struct data_in *data_in,
 | 
			
		||||
lsquic_data_in_hash_insert_data_frame (struct data_in *data_in,
 | 
			
		||||
                const struct data_frame *data_frame, uint64_t read_offset);
 | 
			
		||||
 | 
			
		||||
struct data_in *
 | 
			
		||||
data_in_error_new ();
 | 
			
		||||
lsquic_data_in_error_new ();
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,7 @@ static const struct data_in *error_data_in_ptr;
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
struct data_in *
 | 
			
		||||
data_in_error_new (struct lsquic_conn_public *conn_pub)
 | 
			
		||||
lsquic_data_in_error_new (struct lsquic_conn_public *conn_pub)
 | 
			
		||||
{
 | 
			
		||||
    return (struct data_in *) error_data_in_ptr;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -61,7 +61,7 @@ error_di_empty (struct data_in *data_in)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct data_in *
 | 
			
		||||
static struct data_in *
 | 
			
		||||
error_di_switch_impl (struct data_in *data_in, uint64_t read_offset)
 | 
			
		||||
{
 | 
			
		||||
    assert(0);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -114,7 +114,7 @@ my_log2 /* silly name to suppress compiler warning */ (unsigned sz)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
struct data_in *
 | 
			
		||||
data_in_hash_new (struct lsquic_conn_public *conn_pub,
 | 
			
		||||
lsquic_data_in_hash_new (struct lsquic_conn_public *conn_pub,
 | 
			
		||||
                        lsquic_stream_id_t stream_id, uint64_t byteage)
 | 
			
		||||
{
 | 
			
		||||
    struct hash_data_in *hdi;
 | 
			
		||||
| 
						 | 
				
			
			@ -350,7 +350,7 @@ has_bytes_after (const struct data_block *block, unsigned off)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
enum ins_frame
 | 
			
		||||
data_in_hash_insert_data_frame (struct data_in *data_in,
 | 
			
		||||
lsquic_data_in_hash_insert_data_frame (struct data_in *data_in,
 | 
			
		||||
                const struct data_frame *data_frame, uint64_t read_offset)
 | 
			
		||||
{
 | 
			
		||||
    struct hash_data_in *const hdi = HDI_PTR(data_in);
 | 
			
		||||
| 
						 | 
				
			
			@ -436,7 +436,8 @@ hash_di_insert_frame (struct data_in *data_in,
 | 
			
		|||
    const struct data_frame *const data_frame = &new_frame->data_frame;
 | 
			
		||||
    enum ins_frame ins;
 | 
			
		||||
 | 
			
		||||
    ins = data_in_hash_insert_data_frame(data_in, data_frame, read_offset);
 | 
			
		||||
    ins = lsquic_data_in_hash_insert_data_frame(data_in, data_frame,
 | 
			
		||||
                                                                read_offset);
 | 
			
		||||
    assert(ins != INS_FRAME_OVERLAP);
 | 
			
		||||
    lsquic_packet_in_put(hdi->hdi_conn_pub->mm, new_frame->packet_in);
 | 
			
		||||
    if (ins != INS_FRAME_OK)
 | 
			
		||||
| 
						 | 
				
			
			@ -605,7 +606,7 @@ hash_di_empty (struct data_in *data_in)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct data_in *
 | 
			
		||||
static struct data_in *
 | 
			
		||||
hash_di_switch_impl (struct data_in *data_in, uint64_t read_offset)
 | 
			
		||||
{
 | 
			
		||||
    struct hash_data_in *const hdi = HDI_PTR(data_in);
 | 
			
		||||
| 
						 | 
				
			
			@ -613,7 +614,8 @@ hash_di_switch_impl (struct data_in *data_in, uint64_t read_offset)
 | 
			
		|||
 | 
			
		||||
    assert(hdi->hdi_count == 0);
 | 
			
		||||
 | 
			
		||||
    new_data_in = data_in_nocopy_new(hdi->hdi_conn_pub, hdi->hdi_stream_id);
 | 
			
		||||
    new_data_in = lsquic_data_in_nocopy_new(hdi->hdi_conn_pub,
 | 
			
		||||
                                                    hdi->hdi_stream_id);
 | 
			
		||||
    data_in->di_if->di_destroy(data_in);
 | 
			
		||||
 | 
			
		||||
    return new_data_in;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -128,7 +128,7 @@ static const struct data_in_iface *di_if_nocopy_ptr;
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
struct data_in *
 | 
			
		||||
data_in_nocopy_new (struct lsquic_conn_public *conn_pub,
 | 
			
		||||
lsquic_data_in_nocopy_new (struct lsquic_conn_public *conn_pub,
 | 
			
		||||
                                                lsquic_stream_id_t stream_id)
 | 
			
		||||
{
 | 
			
		||||
    struct nocopy_data_in *ncdi;
 | 
			
		||||
| 
						 | 
				
			
			@ -459,7 +459,7 @@ nocopy_di_empty (struct data_in *data_in)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct data_in *
 | 
			
		||||
static struct data_in *
 | 
			
		||||
nocopy_di_switch_impl (struct data_in *data_in, uint64_t read_offset)
 | 
			
		||||
{
 | 
			
		||||
    struct nocopy_data_in *const ncdi = NCDI_PTR(data_in);
 | 
			
		||||
| 
						 | 
				
			
			@ -467,16 +467,16 @@ nocopy_di_switch_impl (struct data_in *data_in, uint64_t read_offset)
 | 
			
		|||
    stream_frame_t *frame;
 | 
			
		||||
    enum ins_frame ins;
 | 
			
		||||
 | 
			
		||||
    new_data_in = data_in_hash_new(ncdi->ncdi_conn_pub, ncdi->ncdi_stream_id,
 | 
			
		||||
                                                        ncdi->ncdi_byteage);
 | 
			
		||||
    new_data_in = lsquic_data_in_hash_new(ncdi->ncdi_conn_pub,
 | 
			
		||||
                                ncdi->ncdi_stream_id, ncdi->ncdi_byteage);
 | 
			
		||||
    if (!new_data_in)
 | 
			
		||||
        goto end;
 | 
			
		||||
 | 
			
		||||
    while ((frame = TAILQ_FIRST(&ncdi->ncdi_frames_in)))
 | 
			
		||||
    {
 | 
			
		||||
        TAILQ_REMOVE(&ncdi->ncdi_frames_in, frame, next_frame);
 | 
			
		||||
        ins = data_in_hash_insert_data_frame(new_data_in, &frame->data_frame,
 | 
			
		||||
                                                                  read_offset);
 | 
			
		||||
        ins = lsquic_data_in_hash_insert_data_frame(new_data_in,
 | 
			
		||||
                                            &frame->data_frame, read_offset);
 | 
			
		||||
        lsquic_packet_in_put(ncdi->ncdi_conn_pub->mm, frame->packet_in);
 | 
			
		||||
        lsquic_malo_put(frame);
 | 
			
		||||
        if (INS_FRAME_ERR == ins)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1664,7 +1664,7 @@ iquic_esfi_get_peer_transport_params (enc_session_t *enc_session_p)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
static void
 | 
			
		||||
iquic_esfi_destroy (enc_session_t *enc_session_p)
 | 
			
		||||
{
 | 
			
		||||
    struct enc_sess_iquic *const enc_sess = enc_session_p;
 | 
			
		||||
| 
						 | 
				
			
			@ -2288,7 +2288,7 @@ iquic_esfi_in_init (enc_session_t *sess)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
static int
 | 
			
		||||
iquic_esfi_data_in (enc_session_t *sess, enum enc_level enc_level,
 | 
			
		||||
                                    const unsigned char *buf, size_t len)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,7 +43,7 @@ log_hist_slice (const struct hist_slice *slice, time_t t)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eng_hist_log (const struct eng_hist *hist)
 | 
			
		||||
lsquic_eng_hist_log (const struct eng_hist *hist)
 | 
			
		||||
{
 | 
			
		||||
    unsigned i, idx;
 | 
			
		||||
    time_t t0 = time(NULL) - ENG_HIST_NELEMS + 1;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -59,7 +59,7 @@ struct eng_hist
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eng_hist_log (const struct eng_hist *);
 | 
			
		||||
lsquic_eng_hist_log (const struct eng_hist *);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Switch to next slice if necessary */
 | 
			
		||||
| 
						 | 
				
			
			@ -70,7 +70,7 @@ eng_hist_log (const struct eng_hist *);
 | 
			
		|||
        (eh)->eh_cur_idx = ((now) / 1000000) & (ENG_HIST_NELEMS - 1);       \
 | 
			
		||||
    if ((eh)->eh_cur_idx != (eh)->eh_prev_idx)                              \
 | 
			
		||||
    {                                                                       \
 | 
			
		||||
        eng_hist_log(eh);                                                   \
 | 
			
		||||
        lsquic_eng_hist_log(eh);                                            \
 | 
			
		||||
        eng_hist_clear_cur(eh);                                             \
 | 
			
		||||
        (eh)->eh_prev_idx = (eh)->eh_cur_idx;                               \
 | 
			
		||||
    }                                                                       \
 | 
			
		||||
| 
						 | 
				
			
			@ -89,7 +89,7 @@ eng_hist_log (const struct eng_hist *);
 | 
			
		|||
#define eng_hist_clear_cur(eh)
 | 
			
		||||
#define eng_hist_tick(eh, now)
 | 
			
		||||
#define eng_hist_inc(eh, now, what)
 | 
			
		||||
#define eng_hist_log(eh)
 | 
			
		||||
#define lsquic_eng_hist_log(eh)
 | 
			
		||||
 | 
			
		||||
#endif  /* ENG_HIST_ENABLED */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -548,7 +548,7 @@ lsquic_engine_new (unsigned flags,
 | 
			
		|||
    else
 | 
			
		||||
    {
 | 
			
		||||
        engine->pub.enp_shi      = &stock_shi;
 | 
			
		||||
        engine->pub.enp_shi_ctx  = stock_shared_hash_new();
 | 
			
		||||
        engine->pub.enp_shi_ctx  = lsquic_stock_shared_hash_new();
 | 
			
		||||
        if (!engine->pub.enp_shi_ctx)
 | 
			
		||||
        {
 | 
			
		||||
            free(engine);
 | 
			
		||||
| 
						 | 
				
			
			@ -589,7 +589,7 @@ lsquic_engine_new (unsigned flags,
 | 
			
		|||
    engine->pub.enp_crand = &engine->crand;
 | 
			
		||||
    if (flags & ENG_SERVER)
 | 
			
		||||
    {
 | 
			
		||||
        engine->pr_queue = prq_create(
 | 
			
		||||
        engine->pr_queue = lsquic_prq_create(
 | 
			
		||||
            10000 /* TODO: make configurable */, MAX_OUT_BATCH_SIZE,
 | 
			
		||||
            &engine->pub);
 | 
			
		||||
        if (!engine->pr_queue)
 | 
			
		||||
| 
						 | 
				
			
			@ -602,11 +602,11 @@ lsquic_engine_new (unsigned flags,
 | 
			
		|||
        if (!engine->purga)
 | 
			
		||||
        {
 | 
			
		||||
            lsquic_tg_destroy(engine->pub.enp_tokgen);
 | 
			
		||||
            prq_destroy(engine->pr_queue);
 | 
			
		||||
            lsquic_prq_destroy(engine->pr_queue);
 | 
			
		||||
            return NULL;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    engine->attq = attq_create();
 | 
			
		||||
    engine->attq = lsquic_attq_create();
 | 
			
		||||
    eng_hist_init(&engine->history);
 | 
			
		||||
    engine->batch_size = INITIAL_OUT_BATCH_SIZE;
 | 
			
		||||
    if (engine->pub.enp_settings.es_honor_prst)
 | 
			
		||||
| 
						 | 
				
			
			@ -1009,7 +1009,7 @@ schedule_req_packet (struct lsquic_engine *engine, enum packet_req_type type,
 | 
			
		|||
    const struct sockaddr *sa_peer, void *peer_ctx)
 | 
			
		||||
{
 | 
			
		||||
    assert(engine->pr_queue);
 | 
			
		||||
    if (0 == prq_new_req(engine->pr_queue, type, packet_in, peer_ctx,
 | 
			
		||||
    if (0 == lsquic_prq_new_req(engine->pr_queue, type, packet_in, peer_ctx,
 | 
			
		||||
                                                            sa_local, sa_peer))
 | 
			
		||||
        LSQ_DEBUGC("scheduled %s packet for cid %"CID_FMT,
 | 
			
		||||
                    lsquic_preqt2str[type], CID_BITS(&packet_in->pi_conn_id));
 | 
			
		||||
| 
						 | 
				
			
			@ -1199,7 +1199,7 @@ find_or_create_conn (lsquic_engine_t *engine, lsquic_packet_in_t *packet_in,
 | 
			
		|||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        conn = mini_conn_new(&engine->pub, packet_in, version);
 | 
			
		||||
        conn = lsquic_mini_conn_new(&engine->pub, packet_in, version);
 | 
			
		||||
    }
 | 
			
		||||
    if (!conn)
 | 
			
		||||
        return NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -1268,12 +1268,12 @@ lsquic_engine_add_conn_to_attq (struct lsquic_engine_public *enpub,
 | 
			
		|||
    {
 | 
			
		||||
        if (lsquic_conn_adv_time(conn) != tick_time)
 | 
			
		||||
        {
 | 
			
		||||
            attq_remove(engine->attq, conn);
 | 
			
		||||
            if (0 != attq_add(engine->attq, conn, tick_time, why))
 | 
			
		||||
            lsquic_attq_remove(engine->attq, conn);
 | 
			
		||||
            if (0 != lsquic_attq_add(engine->attq, conn, tick_time, why))
 | 
			
		||||
                engine_decref_conn(engine, conn, LSCONN_ATTQ);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else if (0 == attq_add(engine->attq, conn, tick_time, why))
 | 
			
		||||
    else if (0 == lsquic_attq_add(engine->attq, conn, tick_time, why))
 | 
			
		||||
        engine_incref_conn(conn, LSCONN_ATTQ);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1423,15 +1423,15 @@ lsquic_engine_destroy (lsquic_engine_t *engine)
 | 
			
		|||
    assert(0 == engine->n_conns);
 | 
			
		||||
    assert(0 == engine->mini_conns_count);
 | 
			
		||||
    if (engine->pr_queue)
 | 
			
		||||
        prq_destroy(engine->pr_queue);
 | 
			
		||||
        lsquic_prq_destroy(engine->pr_queue);
 | 
			
		||||
    if (engine->purga)
 | 
			
		||||
        lsquic_purga_destroy(engine->purga);
 | 
			
		||||
    attq_destroy(engine->attq);
 | 
			
		||||
    lsquic_attq_destroy(engine->attq);
 | 
			
		||||
 | 
			
		||||
    assert(0 == lsquic_mh_count(&engine->conns_out));
 | 
			
		||||
    assert(0 == lsquic_mh_count(&engine->conns_tickable));
 | 
			
		||||
    if (engine->pub.enp_shi == &stock_shi)
 | 
			
		||||
        stock_shared_hash_destroy(engine->pub.enp_shi_ctx);
 | 
			
		||||
        lsquic_stock_shared_hash_destroy(engine->pub.enp_shi_ctx);
 | 
			
		||||
    lsquic_mm_cleanup(&engine->pub.enp_mm);
 | 
			
		||||
    free(engine->conns_tickable.mh_elems);
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
| 
						 | 
				
			
			@ -1707,7 +1707,7 @@ force_close_conn (lsquic_engine_t *engine, lsquic_conn_t *conn)
 | 
			
		|||
    assert(!(flags & LSCONN_CLOSING));  /* It is in transient queue? */
 | 
			
		||||
    if (flags & LSCONN_ATTQ)
 | 
			
		||||
    {
 | 
			
		||||
        attq_remove(engine->attq, conn);
 | 
			
		||||
        lsquic_attq_remove(engine->attq, conn);
 | 
			
		||||
        (void) engine_decref_conn(engine, conn, LSCONN_ATTQ);
 | 
			
		||||
    }
 | 
			
		||||
    if (flags & LSCONN_HASHED)
 | 
			
		||||
| 
						 | 
				
			
			@ -1740,7 +1740,7 @@ conn_iter_next_tickable (struct lsquic_engine *engine)
 | 
			
		|||
        conn = engine_decref_conn(engine, conn, LSCONN_TICKABLE);
 | 
			
		||||
    if (conn && (conn->cn_flags & LSCONN_ATTQ))
 | 
			
		||||
    {
 | 
			
		||||
        attq_remove(engine->attq, conn);
 | 
			
		||||
        lsquic_attq_remove(engine->attq, conn);
 | 
			
		||||
        conn = engine_decref_conn(engine, conn, LSCONN_ATTQ);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1830,7 +1830,7 @@ lsquic_engine_process_conns (lsquic_engine_t *engine)
 | 
			
		|||
    ENGINE_IN(engine);
 | 
			
		||||
 | 
			
		||||
    now = lsquic_time_now();
 | 
			
		||||
    while ((conn = attq_pop(engine->attq, now)))
 | 
			
		||||
    while ((conn = lsquic_attq_pop(engine->attq, now)))
 | 
			
		||||
    {
 | 
			
		||||
        conn = engine_decref_conn(engine, conn, LSCONN_ATTQ);
 | 
			
		||||
        if (conn && !(conn->cn_flags & LSCONN_TICKABLE))
 | 
			
		||||
| 
						 | 
				
			
			@ -1965,7 +1965,7 @@ coi_next (struct conns_out_iter *iter)
 | 
			
		|||
#endif
 | 
			
		||||
        return conn;
 | 
			
		||||
    }
 | 
			
		||||
    else if (iter->coi_prq && (conn = prq_next_conn(iter->coi_prq)))
 | 
			
		||||
    else if (iter->coi_prq && (conn = lsquic_prq_next_conn(iter->coi_prq)))
 | 
			
		||||
    {
 | 
			
		||||
        return conn;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -2432,7 +2432,7 @@ int
 | 
			
		|||
lsquic_engine_has_unsent_packets (lsquic_engine_t *engine)
 | 
			
		||||
{
 | 
			
		||||
    return lsquic_mh_count(&engine->conns_out) > 0
 | 
			
		||||
             || (engine->pr_queue && prq_have_pending(engine->pr_queue))
 | 
			
		||||
             || (engine->pr_queue && lsquic_prq_have_pending(engine->pr_queue))
 | 
			
		||||
    ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2595,7 +2595,8 @@ process_connections (lsquic_engine_t *engine, conn_iter_f next_conn,
 | 
			
		|||
            next_tick_time = conn->cn_if->ci_next_tick_time(conn, &why);
 | 
			
		||||
            if (next_tick_time)
 | 
			
		||||
            {
 | 
			
		||||
                if (0 == attq_add(engine->attq, conn, next_tick_time, why))
 | 
			
		||||
                if (0 == lsquic_attq_add(engine->attq, conn, next_tick_time,
 | 
			
		||||
                                                                        why))
 | 
			
		||||
                    engine_incref_conn(conn, LSCONN_ATTQ);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
| 
						 | 
				
			
			@ -2759,7 +2760,7 @@ lsquic_engine_earliest_adv_tick (lsquic_engine_t *engine, int *diff)
 | 
			
		|||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (engine->pr_queue && prq_have_pending(engine->pr_queue))
 | 
			
		||||
    if (engine->pr_queue && lsquic_prq_have_pending(engine->pr_queue))
 | 
			
		||||
    {
 | 
			
		||||
#if LSQUIC_DEBUG_NEXT_ADV_TICK
 | 
			
		||||
        engine->last_logged_conn = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -2784,7 +2785,7 @@ lsquic_engine_earliest_adv_tick (lsquic_engine_t *engine, int *diff)
 | 
			
		|||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    next_attq = attq_next(engine->attq);
 | 
			
		||||
    next_attq = lsquic_attq_next(engine->attq);
 | 
			
		||||
    if (engine->pub.enp_flags & ENPUB_CAN_SEND)
 | 
			
		||||
    {
 | 
			
		||||
        if (next_attq)
 | 
			
		||||
| 
						 | 
				
			
			@ -2847,7 +2848,7 @@ lsquic_engine_count_attq (lsquic_engine_t *engine, int from_now)
 | 
			
		|||
        now -= from_now;
 | 
			
		||||
    else
 | 
			
		||||
        now += from_now;
 | 
			
		||||
    return attq_count_before(engine->attq, now);
 | 
			
		||||
    return lsquic_attq_count_before(engine->attq, now);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -380,7 +380,7 @@ prepare_for_payload (struct lsquic_frame_reader *fr)
 | 
			
		|||
            LSQ_WARN("cannot allocate %u bytes for header block",
 | 
			
		||||
                                                    fr->fr_header_block_sz);
 | 
			
		||||
            fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, stream_id,
 | 
			
		||||
                                                                FR_ERR_NOMEM);
 | 
			
		||||
                                                        FR_ERR_OTHER_ERROR);
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
        fr->fr_header_block = header_block;
 | 
			
		||||
| 
						 | 
				
			
			@ -430,7 +430,7 @@ prepare_for_payload (struct lsquic_frame_reader *fr)
 | 
			
		|||
        LSQ_INFO("headers are too large (%u bytes), skipping",
 | 
			
		||||
            fr->fr_state.payload_length);
 | 
			
		||||
        fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, stream_id,
 | 
			
		||||
                                                FR_ERR_HEADERS_TOO_LARGE);
 | 
			
		||||
                                                FR_ERR_BAD_HEADER);
 | 
			
		||||
        /* fallthru */
 | 
			
		||||
    continue_skipping:
 | 
			
		||||
    default:
 | 
			
		||||
| 
						 | 
				
			
			@ -513,29 +513,20 @@ static int
 | 
			
		|||
decode_and_pass_payload (struct lsquic_frame_reader *fr)
 | 
			
		||||
{
 | 
			
		||||
    struct headers_state *hs = &fr->fr_state.by_type.headers_state;
 | 
			
		||||
    const uint32_t hpack_static_table_size = 61;
 | 
			
		||||
    const unsigned char *comp, *end;
 | 
			
		||||
    enum frame_reader_error err;
 | 
			
		||||
    int s;
 | 
			
		||||
    uint32_t name_idx;
 | 
			
		||||
    lshpack_strlen_t name_len, val_len;
 | 
			
		||||
    char *buf;
 | 
			
		||||
    uint32_t stream_id32;
 | 
			
		||||
    struct uncompressed_headers *uh = NULL;
 | 
			
		||||
    void *hset = NULL;
 | 
			
		||||
 | 
			
		||||
    buf = lsquic_mm_get_16k(fr->fr_mm);
 | 
			
		||||
    if (!buf)
 | 
			
		||||
    {
 | 
			
		||||
        err = FR_ERR_NOMEM;
 | 
			
		||||
        goto stream_error;
 | 
			
		||||
    }
 | 
			
		||||
    struct lsxpack_header *hdr = NULL;
 | 
			
		||||
    size_t extra = 0;
 | 
			
		||||
 | 
			
		||||
    hset = fr->fr_hsi_if->hsi_create_header_set(fr->fr_hsi_ctx,
 | 
			
		||||
                            READER_PUSH_PROMISE == fr->fr_state.reader_type);
 | 
			
		||||
    if (!hset)
 | 
			
		||||
    {
 | 
			
		||||
        err = FR_ERR_NOMEM;
 | 
			
		||||
        err = FR_ERR_OTHER_ERROR;
 | 
			
		||||
        goto stream_error;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -544,40 +535,54 @@ decode_and_pass_payload (struct lsquic_frame_reader *fr)
 | 
			
		|||
 | 
			
		||||
    while (comp < end)
 | 
			
		||||
    {
 | 
			
		||||
        s = lshpack_dec_decode(fr->fr_hdec, &comp, end,
 | 
			
		||||
                    buf, buf + 16 * 1024, &name_len, &val_len, &name_idx);
 | 
			
		||||
  prepare:
 | 
			
		||||
        hdr = fr->fr_hsi_if->hsi_prepare_decode(hset, hdr, extra);
 | 
			
		||||
        if (!hdr)
 | 
			
		||||
        {
 | 
			
		||||
            err = FR_ERR_OTHER_ERROR;
 | 
			
		||||
            goto stream_error;
 | 
			
		||||
        }
 | 
			
		||||
        s = lshpack_dec_decode(fr->fr_hdec, &comp, end, hdr);
 | 
			
		||||
        if (s == 0)
 | 
			
		||||
        {
 | 
			
		||||
            if (name_idx > hpack_static_table_size)
 | 
			
		||||
                name_idx = 0;   /* Work around bug in ls-hpack */
 | 
			
		||||
            err = (enum frame_reader_error)
 | 
			
		||||
                fr->fr_hsi_if->hsi_process_header(hset, name_idx, buf,
 | 
			
		||||
                                        name_len, buf + name_len, val_len);
 | 
			
		||||
            if (err == 0)
 | 
			
		||||
            s = fr->fr_hsi_if->hsi_process_header(hset, hdr);
 | 
			
		||||
            if (s == 0)
 | 
			
		||||
            {
 | 
			
		||||
#if LSQUIC_CONN_STATS
 | 
			
		||||
                fr->fr_conn_stats->in.headers_uncomp += name_len + val_len;
 | 
			
		||||
                fr->fr_conn_stats->in.headers_uncomp += hdr->name_len +
 | 
			
		||||
                                                        hdr->val_len;
 | 
			
		||||
#endif
 | 
			
		||||
                extra = 0;
 | 
			
		||||
                hdr = NULL;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            else if (s > 0)
 | 
			
		||||
                err = FR_ERR_BAD_HEADER;
 | 
			
		||||
            else
 | 
			
		||||
                err = FR_ERR_OTHER_ERROR;
 | 
			
		||||
        }
 | 
			
		||||
        else if (s == LSHPACK_ERR_MORE_BUF)
 | 
			
		||||
        {
 | 
			
		||||
            extra = hdr->val_len;
 | 
			
		||||
            goto prepare;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
            err = FR_ERR_DECOMPRESS;
 | 
			
		||||
        goto stream_error;
 | 
			
		||||
    }
 | 
			
		||||
    assert(comp == end);
 | 
			
		||||
    lsquic_mm_put_16k(fr->fr_mm, buf);
 | 
			
		||||
    buf = NULL;
 | 
			
		||||
 | 
			
		||||
    err = (enum frame_reader_error)
 | 
			
		||||
        fr->fr_hsi_if->hsi_process_header(hset, 0, 0, 0, 0, 0);
 | 
			
		||||
    if (err)
 | 
			
		||||
    s = fr->fr_hsi_if->hsi_process_header(hset, NULL);
 | 
			
		||||
    if (s != 0)
 | 
			
		||||
    {
 | 
			
		||||
        err = s < 0 ? FR_ERR_OTHER_ERROR : FR_ERR_BAD_HEADER;
 | 
			
		||||
        goto stream_error;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uh = calloc(1, sizeof(*uh));
 | 
			
		||||
    if (!uh)
 | 
			
		||||
    {
 | 
			
		||||
        err = FR_ERR_NOMEM;
 | 
			
		||||
        err = FR_ERR_OTHER_ERROR;
 | 
			
		||||
        goto stream_error;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -620,8 +625,6 @@ decode_and_pass_payload (struct lsquic_frame_reader *fr)
 | 
			
		|||
    LSQ_INFO("%s: stream error %u", __func__, err);
 | 
			
		||||
    if (hset)
 | 
			
		||||
        fr->fr_hsi_if->hsi_discard_header_set(hset);
 | 
			
		||||
    if (buf)
 | 
			
		||||
        lsquic_mm_put_16k(fr->fr_mm, buf);
 | 
			
		||||
    fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, fr_get_stream_id(fr), err);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,18 +36,8 @@ enum frame_reader_flags
 | 
			
		|||
 */
 | 
			
		||||
enum frame_reader_error
 | 
			
		||||
{
 | 
			
		||||
    FR_ERR_DUPLICATE_PSEH     =  LSQUIC_HDR_ERR_DUPLICATE_PSDO_HDR,
 | 
			
		||||
    FR_ERR_INCOMPL_REQ_PSEH   =  LSQUIC_HDR_ERR_INCOMPL_REQ_PSDO_HDR,
 | 
			
		||||
    FR_ERR_UNNEC_REQ_PSEH     =  LSQUIC_HDR_ERR_UNNEC_REQ_PSDO_HDR,
 | 
			
		||||
    FR_ERR_BAD_REQ_HEADER     =  LSQUIC_HDR_ERR_BAD_REQ_HEADER,
 | 
			
		||||
    FR_ERR_INCOMPL_RESP_PSEH  =  LSQUIC_HDR_ERR_INCOMPL_RESP_PSDO_HDR,
 | 
			
		||||
    FR_ERR_UNNEC_RESP_PSEH    =  LSQUIC_HDR_ERR_UNNEC_RESP_PSDO_HDR,
 | 
			
		||||
    FR_ERR_UNKNOWN_PSEH       =  LSQUIC_HDR_ERR_UNKNOWN_PSDO_HDR,
 | 
			
		||||
    FR_ERR_UPPERCASE_HEADER   =  LSQUIC_HDR_ERR_UPPERCASE_HEADER,
 | 
			
		||||
    FR_ERR_MISPLACED_PSEH     =  LSQUIC_HDR_ERR_MISPLACED_PSDO_HDR,
 | 
			
		||||
    FR_ERR_MISSING_PSEH       =  LSQUIC_HDR_ERR_MISSING_PSDO_HDR,
 | 
			
		||||
    FR_ERR_HEADERS_TOO_LARGE  =  LSQUIC_HDR_ERR_HEADERS_TOO_LARGE,
 | 
			
		||||
    FR_ERR_NOMEM              =  LSQUIC_HDR_ERR_NOMEM,
 | 
			
		||||
    FR_ERR_BAD_HEADER,
 | 
			
		||||
    FR_ERR_OTHER_ERROR,
 | 
			
		||||
 | 
			
		||||
    FR_ERR_DECOMPRESS,
 | 
			
		||||
    FR_ERR_INVALID_FRAME_SIZE,  /* E.g. a SETTINGS frame length is not a multiple
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -389,13 +389,13 @@ write_headers (struct lsquic_frame_writer *fw,
 | 
			
		|||
{
 | 
			
		||||
    unsigned char *end;
 | 
			
		||||
    int i, s;
 | 
			
		||||
 | 
			
		||||
    struct lsxpack_header hdr;
 | 
			
		||||
    for (i = 0; i < headers->count; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        end = lshpack_enc_encode(fw->fw_henc, buf, buf + buf_sz,
 | 
			
		||||
                                 LSHPACK_HDR_UNKNOWN,
 | 
			
		||||
                                 (const lshpack_header_t *)&headers->headers[i],
 | 
			
		||||
                                 0);
 | 
			
		||||
        lsquic_http_header_t *h = &headers->headers[i];
 | 
			
		||||
        lsxpack_header_set_ptr(&hdr, h->name.iov_base, h->name.iov_len,
 | 
			
		||||
                               h->value.iov_base, h->value.iov_len);
 | 
			
		||||
        end = lshpack_enc_encode(fw->fw_henc, buf, buf + buf_sz, &hdr);
 | 
			
		||||
        if (end > buf)
 | 
			
		||||
        {
 | 
			
		||||
            s = hfc_write(hfc, buf, end - buf);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2211,8 +2211,8 @@ process_ver_neg_packet (struct full_conn *conn, lsquic_packet_in_t *packet_in)
 | 
			
		|||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (s = packet_in_ver_first(packet_in, &vi, &ver_tag); s;
 | 
			
		||||
                     s = packet_in_ver_next(&vi, &ver_tag))
 | 
			
		||||
    for (s = lsquic_packet_in_ver_first(packet_in, &vi, &ver_tag); s;
 | 
			
		||||
                     s = lsquic_packet_in_ver_next(&vi, &ver_tag))
 | 
			
		||||
    {
 | 
			
		||||
        version = lsquic_tag2ver(ver_tag);
 | 
			
		||||
        if (version < N_LSQVER)
 | 
			
		||||
| 
						 | 
				
			
			@ -2256,7 +2256,8 @@ reconstruct_packet_number (struct full_conn *conn, lsquic_packet_in_t *packet_in
 | 
			
		|||
    max_packno = lsquic_rechist_largest_packno(&conn->fc_rechist);
 | 
			
		||||
    bits = lsquic_packet_in_packno_bits(packet_in);
 | 
			
		||||
    packet_len = conn->fc_conn.cn_pf->pf_packno_bits2len(bits);
 | 
			
		||||
    packet_in->pi_packno = restore_packno(cur_packno, packet_len, max_packno);
 | 
			
		||||
    packet_in->pi_packno = lsquic_restore_packno(cur_packno, packet_len,
 | 
			
		||||
                                                                max_packno);
 | 
			
		||||
    LSQ_DEBUG("reconstructed (bits: %u, packno: %"PRIu64", max: %"PRIu64") "
 | 
			
		||||
        "to %"PRIu64"", bits, cur_packno, max_packno, packet_in->pi_packno);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -3913,9 +3914,11 @@ synthesize_push_request (struct full_conn *conn, void *hset,
 | 
			
		|||
    void *hsi_ctx;
 | 
			
		||||
    unsigned idx, i, n_headers;
 | 
			
		||||
    const lsquic_http_header_t *header;
 | 
			
		||||
    enum lsquic_header_status st;
 | 
			
		||||
    int st;
 | 
			
		||||
    lsquic_http_header_t pseudo_headers[4];
 | 
			
		||||
    lsquic_http_headers_t all_headers[2];
 | 
			
		||||
    struct lsxpack_header *xhdr;
 | 
			
		||||
    size_t extra;
 | 
			
		||||
 | 
			
		||||
    if (!hset)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -3970,18 +3973,34 @@ synthesize_push_request (struct full_conn *conn, void *hset,
 | 
			
		|||
                    header < all_headers[i].headers + all_headers[i].count;
 | 
			
		||||
                        ++header)
 | 
			
		||||
            {
 | 
			
		||||
                idx = lshpack_enc_get_stx_tab_id(header->name.iov_base,
 | 
			
		||||
                                header->name.iov_len, header->value.iov_base,
 | 
			
		||||
                                header->value.iov_len);
 | 
			
		||||
                st = conn->fc_enpub->enp_hsi_if->hsi_process_header(hset, idx,
 | 
			
		||||
                                header->name.iov_base, header->name.iov_len,
 | 
			
		||||
                                header->value.iov_base, header->value.iov_len);
 | 
			
		||||
                extra = header->name.iov_len + header->value.iov_len + 4;
 | 
			
		||||
                xhdr = conn->fc_enpub->enp_hsi_if->hsi_prepare_decode(hset,
 | 
			
		||||
                                                                NULL, extra);
 | 
			
		||||
                if (!xhdr)
 | 
			
		||||
                    goto err;
 | 
			
		||||
                memcpy(xhdr->buf + xhdr->name_offset, header->name.iov_base,
 | 
			
		||||
                                                        header->name.iov_len);
 | 
			
		||||
                xhdr->name_len = header->name.iov_len;
 | 
			
		||||
                memcpy(xhdr->buf + xhdr->name_offset + xhdr->name_len, ": ", 2);
 | 
			
		||||
                xhdr->val_offset = xhdr->name_offset + xhdr->name_len + 2;
 | 
			
		||||
                memcpy(xhdr->buf + xhdr->val_offset, header->value.iov_base,
 | 
			
		||||
                                                        header->value.iov_len);
 | 
			
		||||
                xhdr->val_len = header->value.iov_len;
 | 
			
		||||
                memcpy(xhdr->buf + xhdr->name_offset + xhdr->name_len + 2
 | 
			
		||||
                            + xhdr->val_len, "\r\n", 2);
 | 
			
		||||
                xhdr->dec_overhead = 4;
 | 
			
		||||
                idx = lshpack_enc_get_stx_tab_id(xhdr);
 | 
			
		||||
                if (idx)
 | 
			
		||||
                {
 | 
			
		||||
                    xhdr->flags |= LSXPACK_HPACK_IDX;
 | 
			
		||||
                    xhdr->hpack_index = idx;
 | 
			
		||||
                }
 | 
			
		||||
                st = conn->fc_enpub->enp_hsi_if->hsi_process_header(hset, xhdr);
 | 
			
		||||
                if (st)
 | 
			
		||||
                    goto err;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        st = conn->fc_enpub->enp_hsi_if->hsi_process_header(hset, 0, 0, 0,
 | 
			
		||||
                                                            0, 0);
 | 
			
		||||
        st = conn->fc_enpub->enp_hsi_if->hsi_process_header(hset, NULL);
 | 
			
		||||
        if (st)
 | 
			
		||||
            goto err;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -3989,7 +4008,7 @@ synthesize_push_request (struct full_conn *conn, void *hset,
 | 
			
		|||
    uh = malloc(sizeof(*uh));
 | 
			
		||||
    if (!uh)
 | 
			
		||||
    {
 | 
			
		||||
        st = LSQUIC_HDR_ERR_NOMEM;
 | 
			
		||||
        st = -__LINE__;
 | 
			
		||||
        goto err;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -4005,7 +4024,7 @@ synthesize_push_request (struct full_conn *conn, void *hset,
 | 
			
		|||
    return uh;
 | 
			
		||||
 | 
			
		||||
  err:
 | 
			
		||||
    LSQ_INFO("%s: error %u", __func__, st);
 | 
			
		||||
    LSQ_INFO("%s: error %d", __func__, st);
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,6 +18,7 @@
 | 
			
		|||
#include "fiu-local.h"
 | 
			
		||||
 | 
			
		||||
#include "lsquic.h"
 | 
			
		||||
#include "lsxpack_header.h"
 | 
			
		||||
#include "lsquic_types.h"
 | 
			
		||||
#include "lsquic_int_types.h"
 | 
			
		||||
#include "lsquic_attq.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -1177,6 +1178,7 @@ lsquic_ietf_full_conn_client_new (struct lsquic_engine_public *enpub,
 | 
			
		|||
    if (conn->ifc_settings->es_handshake_to)
 | 
			
		||||
        lsquic_alarmset_set(&conn->ifc_alset, AL_HANDSHAKE,
 | 
			
		||||
                    lsquic_time_now() + conn->ifc_settings->es_handshake_to);
 | 
			
		||||
    conn->ifc_idle_to = conn->ifc_settings->es_idle_timeout * 1000000;
 | 
			
		||||
    if (conn->ifc_idle_to)
 | 
			
		||||
        lsquic_alarmset_set(&conn->ifc_alset, AL_IDLE, now + conn->ifc_idle_to);
 | 
			
		||||
    if (enpub->enp_settings.es_support_push && CLIENT_PUSH_SUPPORT)
 | 
			
		||||
| 
						 | 
				
			
			@ -1435,6 +1437,7 @@ lsquic_ietf_full_conn_server_new (struct lsquic_engine_public *enpub,
 | 
			
		|||
        goto err3;
 | 
			
		||||
 | 
			
		||||
    conn->ifc_created = imc->imc_created;
 | 
			
		||||
    conn->ifc_idle_to = conn->ifc_settings->es_idle_timeout * 1000000;
 | 
			
		||||
    if (conn->ifc_idle_to)
 | 
			
		||||
        lsquic_alarmset_set(&conn->ifc_alset, AL_IDLE,
 | 
			
		||||
                                        imc->imc_created + conn->ifc_idle_to);
 | 
			
		||||
| 
						 | 
				
			
			@ -3274,11 +3277,12 @@ ietf_full_conn_ci_push_stream (struct lsquic_conn *lconn, void *hset,
 | 
			
		|||
    void *hsi_ctx;
 | 
			
		||||
    struct uncompressed_headers *uh;
 | 
			
		||||
    enum lsqpack_enc_status enc_st;
 | 
			
		||||
    enum lsquic_header_status header_st;
 | 
			
		||||
    unsigned i, name_idx, n_header_sets;
 | 
			
		||||
    int header_st;
 | 
			
		||||
    unsigned i, n_header_sets;
 | 
			
		||||
    int own_hset, stx_tab_id;
 | 
			
		||||
    const unsigned hpack_static_table_size = 61;
 | 
			
		||||
    unsigned char discard[2];
 | 
			
		||||
    struct lsxpack_header *xhdr;
 | 
			
		||||
    size_t extra;
 | 
			
		||||
 | 
			
		||||
    if (!ietf_full_conn_ci_is_push_enabled(lconn)
 | 
			
		||||
                                || !lsquic_stream_can_push(dep_stream))
 | 
			
		||||
| 
						 | 
				
			
			@ -3390,32 +3394,47 @@ ietf_full_conn_ci_push_stream (struct lsquic_conn *lconn, void *hset,
 | 
			
		|||
                    header < all_headers[i].headers + all_headers[i].count;
 | 
			
		||||
                        ++header)
 | 
			
		||||
            {
 | 
			
		||||
                extra = header->name.iov_len + header->value.iov_len + 4;
 | 
			
		||||
                xhdr = conn->ifc_enpub->enp_hsi_if->hsi_prepare_decode(hset,
 | 
			
		||||
                                                                NULL, extra);
 | 
			
		||||
                if (!xhdr)
 | 
			
		||||
                    goto header_err;
 | 
			
		||||
                memcpy(xhdr->buf + xhdr->name_offset, header->name.iov_base,
 | 
			
		||||
                                                        header->name.iov_len);
 | 
			
		||||
                xhdr->name_len = header->name.iov_len;
 | 
			
		||||
                memcpy(xhdr->buf + xhdr->name_offset + xhdr->name_len, ": ", 2);
 | 
			
		||||
                xhdr->val_offset = xhdr->name_offset + xhdr->name_len + 2;
 | 
			
		||||
                memcpy(xhdr->buf + xhdr->val_offset, header->value.iov_base,
 | 
			
		||||
                                                        header->value.iov_len);
 | 
			
		||||
                xhdr->val_len = header->value.iov_len;
 | 
			
		||||
                memcpy(xhdr->buf + xhdr->name_offset + xhdr->name_len + 2
 | 
			
		||||
                            + xhdr->val_len, "\r\n", 2);
 | 
			
		||||
                xhdr->dec_overhead = 4;
 | 
			
		||||
                stx_tab_id = lsqpack_get_stx_tab_id(header->name.iov_base,
 | 
			
		||||
                                header->name.iov_len, header->value.iov_base,
 | 
			
		||||
                                header->value.iov_len);
 | 
			
		||||
                if (stx_tab_id >= 0)
 | 
			
		||||
                    name_idx = hpack_static_table_size + 1 + stx_tab_id;
 | 
			
		||||
                else
 | 
			
		||||
                    name_idx = 0;
 | 
			
		||||
                header_st = conn->ifc_enpub->enp_hsi_if->hsi_process_header(hset,
 | 
			
		||||
                                name_idx,
 | 
			
		||||
                                header->name.iov_base, header->name.iov_len,
 | 
			
		||||
                                header->value.iov_base, header->value.iov_len);
 | 
			
		||||
                if (header_st != LSQUIC_HDR_OK)
 | 
			
		||||
                {
 | 
			
		||||
                    xhdr->qpack_index = stx_tab_id;
 | 
			
		||||
                    xhdr->flags |= LSXPACK_QPACK_IDX;
 | 
			
		||||
                }
 | 
			
		||||
                header_st = conn->ifc_enpub->enp_hsi_if
 | 
			
		||||
                                            ->hsi_process_header(hset, xhdr);
 | 
			
		||||
                if (header_st != 0)
 | 
			
		||||
                {
 | 
			
		||||
  header_err:
 | 
			
		||||
                    lsquic_mm_put_4k(conn->ifc_pub.mm, header_block_buf);
 | 
			
		||||
                    conn->ifc_enpub->enp_hsi_if->hsi_discard_header_set(hset);
 | 
			
		||||
                    LSQ_DEBUG("header process error: %u", header_st);
 | 
			
		||||
                    LSQ_DEBUG("header process error: %d", header_st);
 | 
			
		||||
                    return -1;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        header_st = conn->ifc_enpub->enp_hsi_if->hsi_process_header(hset, 0, 0,
 | 
			
		||||
                                                            0, 0, 0);
 | 
			
		||||
        if (header_st != LSQUIC_HDR_OK)
 | 
			
		||||
        header_st = conn->ifc_enpub->enp_hsi_if->hsi_process_header(hset, NULL);
 | 
			
		||||
        if (header_st != 0)
 | 
			
		||||
        {
 | 
			
		||||
            lsquic_mm_put_4k(conn->ifc_pub.mm, header_block_buf);
 | 
			
		||||
            conn->ifc_enpub->enp_hsi_if->hsi_discard_header_set(hset);
 | 
			
		||||
            LSQ_DEBUG("header process error: %u", header_st);
 | 
			
		||||
            LSQ_DEBUG("header process error: %d", header_st);
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -6406,8 +6425,8 @@ process_incoming_packet_verneg (struct ietf_full_conn *conn,
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        versions = 0;
 | 
			
		||||
        for (s = packet_in_ver_first(packet_in, &vi, &ver_tag); s;
 | 
			
		||||
                         s = packet_in_ver_next(&vi, &ver_tag))
 | 
			
		||||
        for (s = lsquic_packet_in_ver_first(packet_in, &vi, &ver_tag); s;
 | 
			
		||||
                         s = lsquic_packet_in_ver_next(&vi, &ver_tag))
 | 
			
		||||
        {
 | 
			
		||||
            version = lsquic_tag2ver(ver_tag);
 | 
			
		||||
            if (version < N_LSQVER)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -338,12 +338,11 @@ static compress_cert_hash_item_t *make_compress_cert_hash_item(struct lsquic_str
 | 
			
		|||
#ifdef NDEBUG
 | 
			
		||||
static
 | 
			
		||||
enum hsk_failure_reason
 | 
			
		||||
verify_stk (enc_session_t *,
 | 
			
		||||
lsquic_verify_stk (enc_session_t *,
 | 
			
		||||
               const struct sockaddr *ip_addr, uint64_t tm, lsquic_str_t *stk);
 | 
			
		||||
static
 | 
			
		||||
void gen_stk(lsquic_server_config_t *, const struct sockaddr *, uint64_t tm,
 | 
			
		||||
             unsigned char stk_out[STK_LENGTH]);
 | 
			
		||||
#endif
 | 
			
		||||
void lsquic_gen_stk(lsquic_server_config_t *, const struct sockaddr *, uint64_t tm,
 | 
			
		||||
             unsigned char stk_out[STK_LENGTH]);
 | 
			
		||||
 | 
			
		||||
/* client */
 | 
			
		||||
static c_cert_item_t *make_c_cert_item(struct lsquic_str **certs, int count);
 | 
			
		||||
| 
						 | 
				
			
			@ -375,7 +374,7 @@ eshist_append (struct lsquic_enc_session *enc_session,
 | 
			
		|||
static int
 | 
			
		||||
lsquic_handshake_init(int flags)
 | 
			
		||||
{
 | 
			
		||||
    crypto_init();
 | 
			
		||||
    lsquic_crypto_init();
 | 
			
		||||
    return init_hs_hash_tables(flags);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -467,7 +466,7 @@ make_c_cert_item (lsquic_str_t **certs, int count)
 | 
			
		|||
    for (i = 0; i < count; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        lsquic_str_copy(&item->crts[i], certs[i]);
 | 
			
		||||
        hash = fnv1a_64((const uint8_t *)lsquic_str_cstr(certs[i]),
 | 
			
		||||
        hash = lsquic_fnv1a_64((const uint8_t *)lsquic_str_cstr(certs[i]),
 | 
			
		||||
                        lsquic_str_len(certs[i]));
 | 
			
		||||
        lsquic_str_append(item->hashs, (char *)&hash, 8);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -694,7 +693,7 @@ lsquic_enc_session_deserialize_zero_rtt(
 | 
			
		|||
        lsquic_str_prealloc(&cert_item->crts[i], len);
 | 
			
		||||
        lsquic_str_setlen(&cert_item->crts[i], len);
 | 
			
		||||
        memcpy(lsquic_str_buf(&cert_item->crts[i]), cert_data, len);
 | 
			
		||||
        hash = fnv1a_64((const uint8_t *)cert_data, len);
 | 
			
		||||
        hash = lsquic_fnv1a_64((const uint8_t *)cert_data, len);
 | 
			
		||||
        lsquic_str_append(cert_item->hashs, (char *)&hash, 8);
 | 
			
		||||
        cert_len = (uint32_t *)(cert_data + len);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -1493,7 +1492,7 @@ lsquic_enc_session_gen_chlo (enc_session_t *enc_session_p,
 | 
			
		|||
{
 | 
			
		||||
    struct lsquic_enc_session *const enc_session = enc_session_p;
 | 
			
		||||
    int include_pad;
 | 
			
		||||
    const lsquic_str_t *const ccs = get_common_certs_hash();
 | 
			
		||||
    const lsquic_str_t *const ccs = lsquic_get_common_certs_hash();
 | 
			
		||||
    const struct lsquic_engine_settings *const settings =
 | 
			
		||||
                                        &enc_session->enpub->enp_settings;
 | 
			
		||||
    c_cert_item_t *const cert_item = enc_session->cert_item;
 | 
			
		||||
| 
						 | 
				
			
			@ -1572,8 +1571,8 @@ lsquic_enc_session_gen_chlo (enc_session_t *enc_session_p,
 | 
			
		|||
            MSG_LEN_ADD(msg_len, sizeof(enc_session->hs_ctx.nonc));
 | 
			
		||||
                                            ++n_tags;           /* NONC */
 | 
			
		||||
            RAND_bytes(enc_session->priv_key, 32);
 | 
			
		||||
            c255_get_pub_key(enc_session->priv_key, pub_key);
 | 
			
		||||
            gen_nonce_c(enc_session->hs_ctx.nonc, enc_session->info->orbt);
 | 
			
		||||
            lsquic_c255_get_pub_key(enc_session->priv_key, pub_key);
 | 
			
		||||
            lsquic_gen_nonce_c(enc_session->hs_ctx.nonc, enc_session->info->orbt);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    include_pad = MSG_LEN_VAL(msg_len) < MIN_CHLO_SIZE;
 | 
			
		||||
| 
						 | 
				
			
			@ -1671,7 +1670,7 @@ determine_rtts (struct lsquic_enc_session *enc_session,
 | 
			
		|||
        goto fail_1rtt;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    hfr = verify_stk(enc_session, ip_addr, t, &hs_ctx->stk);
 | 
			
		||||
    hfr = lsquic_verify_stk(enc_session, ip_addr, t, &hs_ctx->stk);
 | 
			
		||||
    if (hfr != HFR_HANDSHAKE_OK)
 | 
			
		||||
    {
 | 
			
		||||
        hs_ctx->rrej = hfr;
 | 
			
		||||
| 
						 | 
				
			
			@ -1835,7 +1834,7 @@ get_valid_scfg (const struct lsquic_enc_session *enc_session,
 | 
			
		|||
    RAND_bytes(temp_scfg->skt_key, sizeof(temp_scfg->skt_key));
 | 
			
		||||
    RAND_bytes(temp_scfg->sscid, sizeof(temp_scfg->sscid));
 | 
			
		||||
    RAND_bytes(temp_scfg->priv_key, sizeof(temp_scfg->priv_key));
 | 
			
		||||
    c255_get_pub_key(temp_scfg->priv_key, spubs + 3);
 | 
			
		||||
    lsquic_c255_get_pub_key(temp_scfg->priv_key, spubs + 3);
 | 
			
		||||
    temp_scfg->aead = settings->es_aead;
 | 
			
		||||
    temp_scfg->kexs = settings->es_kexs;
 | 
			
		||||
    temp_scfg->pdmd = settings->es_pdmd;
 | 
			
		||||
| 
						 | 
				
			
			@ -1926,7 +1925,7 @@ generate_crt (struct lsquic_enc_session *enc_session, int common_case)
 | 
			
		|||
        OPENSSL_free(out);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (0 != compress_certs(crts, crt_num, &hs_ctx->ccs, &hs_ctx->ccrt,
 | 
			
		||||
    if (0 != lsquic_compress_certs(crts, crt_num, &hs_ctx->ccs, &hs_ctx->ccrt,
 | 
			
		||||
                                                            &hs_ctx->crt))
 | 
			
		||||
        goto cleanup;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1980,7 +1979,7 @@ gen_rej1_data (struct lsquic_enc_session *enc_session, uint8_t *data,
 | 
			
		|||
     * This is the most common case
 | 
			
		||||
     */
 | 
			
		||||
    common_case = lsquic_str_len(&hs_ctx->ccrt) == 0
 | 
			
		||||
               && lsquic_str_bcmp(&hs_ctx->ccs, get_common_certs_hash()) == 0;
 | 
			
		||||
               && lsquic_str_bcmp(&hs_ctx->ccs, lsquic_get_common_certs_hash()) == 0;
 | 
			
		||||
    if (common_case)
 | 
			
		||||
        compress_certs_item = find_compress_certs(&hs_ctx->sni);
 | 
			
		||||
    else
 | 
			
		||||
| 
						 | 
				
			
			@ -1996,7 +1995,7 @@ gen_rej1_data (struct lsquic_enc_session *enc_session, uint8_t *data,
 | 
			
		|||
 | 
			
		||||
    LSQ_DEBUG("gQUIC rej1 data");
 | 
			
		||||
    LSQ_DEBUG("gQUIC NOT enabled");
 | 
			
		||||
    gen_prof((const uint8_t *)lsquic_str_cstr(&enc_session->chlo),
 | 
			
		||||
    lsquic_gen_prof((const uint8_t *)lsquic_str_cstr(&enc_session->chlo),
 | 
			
		||||
         (size_t)lsquic_str_len(&enc_session->chlo),
 | 
			
		||||
         scfg_data, scfg_len,
 | 
			
		||||
         rsa_priv_key, (uint8_t *)prof_buf, &prof_len);
 | 
			
		||||
| 
						 | 
				
			
			@ -2029,7 +2028,7 @@ gen_rej1_data (struct lsquic_enc_session *enc_session, uint8_t *data,
 | 
			
		|||
        lsquic_str_prealloc(&enc_session->sstk, STK_LENGTH);
 | 
			
		||||
        lsquic_str_setlen(&enc_session->sstk, STK_LENGTH);
 | 
			
		||||
    }
 | 
			
		||||
    gen_stk(enc_session->server_config, ip, t,
 | 
			
		||||
    lsquic_gen_stk(enc_session->server_config, ip, t,
 | 
			
		||||
                        (unsigned char *) lsquic_str_buf(&enc_session->sstk));
 | 
			
		||||
 | 
			
		||||
    if (lsquic_str_len(&enc_session->ssno) != SNO_LENGTH)
 | 
			
		||||
| 
						 | 
				
			
			@ -2090,14 +2089,14 @@ gen_shlo_data (uint8_t *buf, size_t buf_len, struct lsquic_enc_session *enc_sess
 | 
			
		|||
 | 
			
		||||
    RAND_bytes(nonce, 32);
 | 
			
		||||
    RAND_bytes(enc_session->priv_key, 32);
 | 
			
		||||
    c255_get_pub_key(enc_session->priv_key, (unsigned char *)pub_key);
 | 
			
		||||
    lsquic_c255_get_pub_key(enc_session->priv_key, (unsigned char *)pub_key);
 | 
			
		||||
    if (lsquic_str_len(&enc_session->sstk) != STK_LENGTH)
 | 
			
		||||
    {
 | 
			
		||||
        lsquic_str_d(&enc_session->sstk);
 | 
			
		||||
        lsquic_str_prealloc(&enc_session->sstk, STK_LENGTH);
 | 
			
		||||
        lsquic_str_setlen(&enc_session->sstk, STK_LENGTH);
 | 
			
		||||
    }
 | 
			
		||||
    gen_stk(enc_session->server_config, ip, t,
 | 
			
		||||
    lsquic_gen_stk(enc_session->server_config, ip, t,
 | 
			
		||||
                        (unsigned char *) lsquic_str_buf(&enc_session->sstk));
 | 
			
		||||
    if (lsquic_str_len(&enc_session->ssno) != SNO_LENGTH)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -2333,15 +2332,15 @@ static int handle_chlo_reply_verify_prof(struct lsquic_enc_session *enc_session,
 | 
			
		|||
    size_t i;
 | 
			
		||||
    X509 *cert, *server_cert;
 | 
			
		||||
    STACK_OF(X509) *chain = NULL;
 | 
			
		||||
    ret = decompress_certs(in, in_end,cached_certs, cached_certs_count,
 | 
			
		||||
    ret = lsquic_decompress_certs(in, in_end,cached_certs, cached_certs_count,
 | 
			
		||||
                           out_certs, out_certs_count);
 | 
			
		||||
    if (ret)
 | 
			
		||||
        return ret;
 | 
			
		||||
 | 
			
		||||
    server_cert = bio_to_crt((const char *)lsquic_str_cstr(out_certs[0]),
 | 
			
		||||
    server_cert = lsquic_bio_to_crt((const char *)lsquic_str_cstr(out_certs[0]),
 | 
			
		||||
                      lsquic_str_len(out_certs[0]), 0);
 | 
			
		||||
    pub_key = X509_get_pubkey(server_cert);
 | 
			
		||||
    ret = verify_prof((const uint8_t *)lsquic_str_cstr(&enc_session->chlo),
 | 
			
		||||
    ret = lsquic_verify_prof((const uint8_t *)lsquic_str_cstr(&enc_session->chlo),
 | 
			
		||||
                      (size_t)lsquic_str_len(&enc_session->chlo),
 | 
			
		||||
                      &enc_session->info->scfg,
 | 
			
		||||
                      pub_key,
 | 
			
		||||
| 
						 | 
				
			
			@ -2349,7 +2348,10 @@ static int handle_chlo_reply_verify_prof(struct lsquic_enc_session *enc_session,
 | 
			
		|||
                      lsquic_str_len(&enc_session->hs_ctx.prof));
 | 
			
		||||
    EVP_PKEY_free(pub_key);
 | 
			
		||||
    if (ret != 0)
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_DEBUG("cannot verify server proof");
 | 
			
		||||
        goto cleanup;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (enc_session->enpub->enp_verify_cert)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -2357,7 +2359,7 @@ static int handle_chlo_reply_verify_prof(struct lsquic_enc_session *enc_session,
 | 
			
		|||
        sk_X509_push(chain, server_cert);
 | 
			
		||||
        for (i = 1; i < *out_certs_count; ++i)
 | 
			
		||||
        {
 | 
			
		||||
            cert = bio_to_crt((const char *)lsquic_str_cstr(out_certs[i]),
 | 
			
		||||
            cert = lsquic_bio_to_crt((const char *)lsquic_str_cstr(out_certs[i]),
 | 
			
		||||
                                    lsquic_str_len(out_certs[i]), 0);
 | 
			
		||||
            if (cert)
 | 
			
		||||
                sk_X509_push(chain, cert);
 | 
			
		||||
| 
						 | 
				
			
			@ -2505,7 +2507,7 @@ determine_keys (struct lsquic_enc_session *enc_session)
 | 
			
		|||
        key_flag = 'F';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    c255_gen_share_key(enc_session->priv_key,
 | 
			
		||||
    lsquic_c255_gen_share_key(enc_session->priv_key,
 | 
			
		||||
                       enc_session->hs_ctx.pubs,
 | 
			
		||||
                       (unsigned char *)shared_key_c);
 | 
			
		||||
    if (is_client)
 | 
			
		||||
| 
						 | 
				
			
			@ -2563,8 +2565,8 @@ determine_keys (struct lsquic_enc_session *enc_session)
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LSQ_DEBUG("export_key_material c255_gen_share_key %s",
 | 
			
		||||
              get_bin_str(shared_key_c, 32, 512));
 | 
			
		||||
    LSQ_DEBUG("export_key_material lsquic_c255_gen_share_key %s",
 | 
			
		||||
              lsquic_get_bin_str(shared_key_c, 32, 512));
 | 
			
		||||
 | 
			
		||||
    memcpy(hkdf_input_p, enc_session->cid.idbuf, enc_session->cid.len);
 | 
			
		||||
    hkdf_input_p += enc_session->cid.len;
 | 
			
		||||
| 
						 | 
				
			
			@ -2756,7 +2758,7 @@ lsquic_enc_session_handle_chlo_reply (enc_session_t *enc_session_p,
 | 
			
		|||
 | 
			
		||||
        if (lsquic_str_len(&enc_session->hs_ctx.crt) > 0)
 | 
			
		||||
        {
 | 
			
		||||
            out_certs_count = get_certs_count(&enc_session->hs_ctx.crt);
 | 
			
		||||
            out_certs_count = lsquic_get_certs_count(&enc_session->hs_ctx.crt);
 | 
			
		||||
            if (out_certs_count > 0)
 | 
			
		||||
            {
 | 
			
		||||
                out_certs = malloc(out_certs_count * sizeof(lsquic_str_t *));
 | 
			
		||||
| 
						 | 
				
			
			@ -2821,7 +2823,7 @@ lsquic_enc_session_handle_chlo_reply (enc_session_t *enc_session_p,
 | 
			
		|||
static
 | 
			
		||||
#endif
 | 
			
		||||
void
 | 
			
		||||
gen_stk (lsquic_server_config_t *server_config, const struct sockaddr *ip_addr,
 | 
			
		||||
lsquic_gen_stk (lsquic_server_config_t *server_config, const struct sockaddr *ip_addr,
 | 
			
		||||
         uint64_t tm, unsigned char stk_out[STK_LENGTH])
 | 
			
		||||
{
 | 
			
		||||
    unsigned char stk[STK_LENGTH + 16];
 | 
			
		||||
| 
						 | 
				
			
			@ -2835,7 +2837,7 @@ gen_stk (lsquic_server_config_t *server_config, const struct sockaddr *ip_addr,
 | 
			
		|||
    memcpy(stk + 16, &tm, 8);
 | 
			
		||||
    RAND_bytes(stk + 24, STK_LENGTH - 24 - 12);
 | 
			
		||||
    RAND_bytes(stk_out + STK_LENGTH - 12, 12);
 | 
			
		||||
    aes_aead_enc(&server_config->lsc_stk_ctx, NULL, 0, stk_out + STK_LENGTH - 12, 12, stk,
 | 
			
		||||
    lsquic_aes_aead_enc(&server_config->lsc_stk_ctx, NULL, 0, stk_out + STK_LENGTH - 12, 12, stk,
 | 
			
		||||
                 STK_LENGTH - 12 - 12, stk_out, &out_len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2845,7 +2847,7 @@ gen_stk (lsquic_server_config_t *server_config, const struct sockaddr *ip_addr,
 | 
			
		|||
static
 | 
			
		||||
#endif
 | 
			
		||||
enum hsk_failure_reason
 | 
			
		||||
verify_stk0 (const struct lsquic_enc_session *enc_session,
 | 
			
		||||
lsquic_verify_stk0 (const struct lsquic_enc_session *enc_session,
 | 
			
		||||
             lsquic_server_config_t *server_config,
 | 
			
		||||
             const struct sockaddr *ip_addr, uint64_t tm, lsquic_str_t *stk,
 | 
			
		||||
             unsigned secs_since_stk_generated)
 | 
			
		||||
| 
						 | 
				
			
			@ -2858,12 +2860,12 @@ verify_stk0 (const struct lsquic_enc_session *enc_session,
 | 
			
		|||
    if (lsquic_str_len(stk) < STK_LENGTH)
 | 
			
		||||
        return HFR_SRC_ADDR_TOKEN_INVALID;
 | 
			
		||||
 | 
			
		||||
    int ret = aes_aead_dec(&server_config->lsc_stk_ctx, NULL, 0,
 | 
			
		||||
    int ret = lsquic_aes_aead_dec(&server_config->lsc_stk_ctx, NULL, 0,
 | 
			
		||||
                           stks + STK_LENGTH - 12, 12, stks,
 | 
			
		||||
                           STK_LENGTH - 12, stk_out, &out_len);
 | 
			
		||||
    if (ret != 0)
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_DEBUG("***verify_stk decrypted failed.");
 | 
			
		||||
        LSQ_DEBUG("***lsquic_verify_stk decrypted failed.");
 | 
			
		||||
        return HFR_SRC_ADDR_TOKEN_DECRYPTION;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2871,7 +2873,7 @@ verify_stk0 (const struct lsquic_enc_session *enc_session,
 | 
			
		|||
    {
 | 
			
		||||
        if (memcmp(stk_out, &((struct sockaddr_in *)ip_addr)->sin_addr.s_addr, 4) != 0)
 | 
			
		||||
        {
 | 
			
		||||
            LSQ_DEBUG("***verify_stk for ipv4 failed.");
 | 
			
		||||
            LSQ_DEBUG("***lsquic_verify_stk for ipv4 failed.");
 | 
			
		||||
            return HFR_SRC_ADDR_TOKEN_DIFFERENT_IP_ADDRESS;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -2879,7 +2881,7 @@ verify_stk0 (const struct lsquic_enc_session *enc_session,
 | 
			
		|||
    {
 | 
			
		||||
        if (memcmp(stk_out, &((struct sockaddr_in6 *)ip_addr)->sin6_addr, 16) != 0)
 | 
			
		||||
        {
 | 
			
		||||
            LSQ_DEBUG("***verify_stk for ipv6 failed.");
 | 
			
		||||
            LSQ_DEBUG("***lsquic_verify_stk for ipv6 failed.");
 | 
			
		||||
            return HFR_SRC_ADDR_TOKEN_DIFFERENT_IP_ADDRESS;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -2887,7 +2889,7 @@ verify_stk0 (const struct lsquic_enc_session *enc_session,
 | 
			
		|||
    memcpy((void *)&tm0, stk_out + 16, 8);
 | 
			
		||||
    if (tm < tm0)
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_DEBUG("***verify_stk timestamp is in the future.");
 | 
			
		||||
        LSQ_DEBUG("***lsquic_verify_stk timestamp is in the future.");
 | 
			
		||||
        return HFR_SRC_ADDR_TOKEN_CLOCK_SKEW;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2899,11 +2901,11 @@ verify_stk0 (const struct lsquic_enc_session *enc_session,
 | 
			
		|||
    if (tm > server_config->lsc_scfg->info.expy /* XXX this check does not seem needed */ ||
 | 
			
		||||
                                                        tm0 > exp)
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_DEBUG("***verify_stk stk expired");
 | 
			
		||||
        LSQ_DEBUG("***lsquic_verify_stk stk expired");
 | 
			
		||||
        return HFR_SRC_ADDR_TOKEN_EXPIRED;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LSQ_DEBUG("***verify_stk pass.");
 | 
			
		||||
    LSQ_DEBUG("***lsquic_verify_stk pass.");
 | 
			
		||||
    return HFR_HANDSHAKE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2913,7 +2915,7 @@ verify_stk0 (const struct lsquic_enc_session *enc_session,
 | 
			
		|||
static
 | 
			
		||||
#endif
 | 
			
		||||
enum hsk_failure_reason
 | 
			
		||||
verify_stk (enc_session_t *enc_session_p,
 | 
			
		||||
lsquic_verify_stk (enc_session_t *enc_session_p,
 | 
			
		||||
               const struct sockaddr *ip_addr, uint64_t tm, lsquic_str_t *stk)
 | 
			
		||||
{
 | 
			
		||||
    struct lsquic_enc_session *const enc_session = enc_session_p;
 | 
			
		||||
| 
						 | 
				
			
			@ -2926,8 +2928,8 @@ verify_stk (enc_session_t *enc_session_p,
 | 
			
		|||
            return HFR_SRC_ADDR_TOKEN_INVALID;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
        return verify_stk0(enc_session, enc_session->server_config, ip_addr,
 | 
			
		||||
                                                                    tm, stk, 0);
 | 
			
		||||
        return lsquic_verify_stk0(enc_session, enc_session->server_config,
 | 
			
		||||
                                                        ip_addr, tm, stk, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2954,17 +2956,17 @@ verify_packet_hash (const struct lsquic_enc_session *enc_session,
 | 
			
		|||
        return -1;
 | 
			
		||||
 | 
			
		||||
    if (!enc_session || (IS_SERVER(enc_session)))
 | 
			
		||||
        hash = fnv1a_128_3(buf, *header_len,
 | 
			
		||||
        hash = lsquic_fnv1a_128_3(buf, *header_len,
 | 
			
		||||
                    buf + *header_len + HS_PKT_HASH_LENGTH,
 | 
			
		||||
                    data_len - HS_PKT_HASH_LENGTH,
 | 
			
		||||
                    (unsigned char *) "Client", 6);
 | 
			
		||||
    else
 | 
			
		||||
        hash = fnv1a_128_3(buf, *header_len,
 | 
			
		||||
        hash = lsquic_fnv1a_128_3(buf, *header_len,
 | 
			
		||||
                    buf + *header_len + HS_PKT_HASH_LENGTH,
 | 
			
		||||
                    data_len - HS_PKT_HASH_LENGTH,
 | 
			
		||||
                    (unsigned char *) "Server", 6);
 | 
			
		||||
 | 
			
		||||
    serialize_fnv128_short(hash, md);
 | 
			
		||||
    lsquic_serialize_fnv128_short(hash, md);
 | 
			
		||||
    ret = memcmp(md, buf + *header_len, HS_PKT_HASH_LENGTH);
 | 
			
		||||
    if(ret == 0)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -3017,7 +3019,7 @@ decrypt_packet (struct lsquic_enc_session *enc_session, uint8_t path_id,
 | 
			
		|||
               sizeof(path_id_packet_number));
 | 
			
		||||
 | 
			
		||||
        *out_len = data_len;
 | 
			
		||||
        ret = aes_aead_dec(key,
 | 
			
		||||
        ret = lsquic_aes_aead_dec(key,
 | 
			
		||||
                           buf, *header_len,
 | 
			
		||||
                           nonce, 12,
 | 
			
		||||
                           buf + *header_len, data_len,
 | 
			
		||||
| 
						 | 
				
			
			@ -3166,13 +3168,13 @@ gquic_encrypt_buf (struct lsquic_enc_session *enc_session,
 | 
			
		|||
            return -1;
 | 
			
		||||
 | 
			
		||||
        if (!enc_session || (IS_SERVER(enc_session)))
 | 
			
		||||
            hash = fnv1a_128_3(header, header_len, data, data_len,
 | 
			
		||||
            hash = lsquic_fnv1a_128_3(header, header_len, data, data_len,
 | 
			
		||||
                                        (unsigned char *) "Server", 6);
 | 
			
		||||
        else
 | 
			
		||||
            hash = fnv1a_128_3(header, header_len, data, data_len,
 | 
			
		||||
            hash = lsquic_fnv1a_128_3(header, header_len, data, data_len,
 | 
			
		||||
                                        (unsigned char *) "Client", 6);
 | 
			
		||||
 | 
			
		||||
        serialize_fnv128_short(hash, md);
 | 
			
		||||
        lsquic_serialize_fnv128_short(hash, md);
 | 
			
		||||
        memcpy(buf_out, header, header_len);
 | 
			
		||||
        memcpy(buf_out + header_len, md, HS_PKT_HASH_LENGTH);
 | 
			
		||||
        memcpy(buf_out + header_len + HS_PKT_HASH_LENGTH, data, data_len);
 | 
			
		||||
| 
						 | 
				
			
			@ -3207,7 +3209,7 @@ gquic_encrypt_buf (struct lsquic_enc_session *enc_session,
 | 
			
		|||
        memcpy(buf_out, header, header_len);
 | 
			
		||||
        *out_len = max_out_len - header_len;
 | 
			
		||||
 | 
			
		||||
        ret = aes_aead_enc(key, header, header_len, nonce, 12, data,
 | 
			
		||||
        ret = lsquic_aes_aead_enc(key, header, header_len, nonce, 12, data,
 | 
			
		||||
                           data_len, buf_out + header_len, out_len);
 | 
			
		||||
        if (ret == 0)
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			@ -3670,7 +3672,7 @@ lsquic_enc_session_get_server_cert_chain (enc_session_t *enc_session_p)
 | 
			
		|||
    chain = sk_X509_new_null();
 | 
			
		||||
    for (i = 0; i < item->count; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        cert = bio_to_crt(lsquic_str_cstr(&item->crts[i]),
 | 
			
		||||
        cert = lsquic_bio_to_crt(lsquic_str_cstr(&item->crts[i]),
 | 
			
		||||
                                lsquic_str_len(&item->crts[i]), 0);
 | 
			
		||||
        if (cert)
 | 
			
		||||
            sk_X509_push(chain, cert);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,15 +26,13 @@ typedef struct cert_hash_item_st
 | 
			
		|||
} cert_hash_item_t;
 | 
			
		||||
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
void gen_stk(struct lsquic_server_config *, const struct sockaddr *ip_addr, uint64_t tm,
 | 
			
		||||
             unsigned char stk_out[STK_LENGTH]);
 | 
			
		||||
enum hsk_failure_reason
 | 
			
		||||
verify_stk0(const struct lsquic_enc_session *,
 | 
			
		||||
lsquic_verify_stk0(const struct lsquic_enc_session *,
 | 
			
		||||
            struct lsquic_server_config *, const struct sockaddr *ip_addr, uint64_t tm,
 | 
			
		||||
               struct lsquic_str *stk,
 | 
			
		||||
               unsigned secs_since_stk_generated);
 | 
			
		||||
enum hsk_failure_reason
 | 
			
		||||
verify_stk(void *, const struct sockaddr *ip_addr,
 | 
			
		||||
lsquic_verify_stk(void *, const struct sockaddr *ip_addr,
 | 
			
		||||
                                        uint64_t tm, struct lsquic_str *stk);
 | 
			
		||||
struct cert_hash_item_st* c_find_certs(const struct lsquic_str *domain);
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -218,7 +218,7 @@ hqft2str (enum hq_frame_type type)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
static int
 | 
			
		||||
hcso_write_number_frame (struct hcso_writer *writer,
 | 
			
		||||
                                    enum hq_frame_type type, uint64_t value)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -81,7 +81,7 @@ static lsquic_stream_ctx_t *
 | 
			
		|||
headers_on_new_stream (void *stream_if_ctx, lsquic_stream_t *stream)
 | 
			
		||||
{
 | 
			
		||||
    struct headers_stream *hs = stream_if_ctx;
 | 
			
		||||
    lshpack_dec_init(&hs->hs_hdec);
 | 
			
		||||
    lshpack_dec_init(&hs->hs_hdec, LSHPACK_DEC_HTTP1X);
 | 
			
		||||
    if (0 != lshpack_enc_init(&hs->hs_henc))
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_WARN("could not initialize HPACK encoder: %s", strerror(errno));
 | 
			
		||||
| 
						 | 
				
			
			@ -292,18 +292,8 @@ headers_on_error (void *ctx, lsquic_stream_id_t stream_id,
 | 
			
		|||
    struct headers_stream *hs = ctx;
 | 
			
		||||
    switch (err)
 | 
			
		||||
    {
 | 
			
		||||
    case FR_ERR_DUPLICATE_PSEH:
 | 
			
		||||
    case FR_ERR_INCOMPL_REQ_PSEH:
 | 
			
		||||
    case FR_ERR_UNNEC_REQ_PSEH:
 | 
			
		||||
    case FR_ERR_BAD_REQ_HEADER:
 | 
			
		||||
    case FR_ERR_INCOMPL_RESP_PSEH:
 | 
			
		||||
    case FR_ERR_UNNEC_RESP_PSEH:
 | 
			
		||||
    case FR_ERR_UNKNOWN_PSEH:
 | 
			
		||||
    case FR_ERR_UPPERCASE_HEADER:
 | 
			
		||||
    case FR_ERR_MISPLACED_PSEH:
 | 
			
		||||
    case FR_ERR_MISSING_PSEH:
 | 
			
		||||
    case FR_ERR_BAD_HEADER:
 | 
			
		||||
    case FR_ERR_DECOMPRESS:
 | 
			
		||||
    case FR_ERR_HEADERS_TOO_LARGE:
 | 
			
		||||
    case FR_ERR_SELF_DEP_STREAM:
 | 
			
		||||
        LSQ_INFO("error %u is a stream error (stream %"PRIu64")", err,
 | 
			
		||||
                                                                    stream_id);
 | 
			
		||||
| 
						 | 
				
			
			@ -313,8 +303,8 @@ headers_on_error (void *ctx, lsquic_stream_id_t stream_id,
 | 
			
		|||
    case FR_ERR_NONZERO_STREAM_ID:
 | 
			
		||||
    case FR_ERR_UNEXPECTED_PUSH:
 | 
			
		||||
    case FR_ERR_ZERO_STREAM_ID:
 | 
			
		||||
    case FR_ERR_NOMEM:
 | 
			
		||||
    case FR_ERR_EXPECTED_CONTIN:
 | 
			
		||||
    case FR_ERR_OTHER_ERROR:
 | 
			
		||||
        LSQ_INFO("error %u is a connection error (stream %"PRIu64")", err,
 | 
			
		||||
                                                                    stream_id);
 | 
			
		||||
        hs->hs_callbacks->hsc_on_conn_error(hs->hs_cb_ctx);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,6 +52,9 @@ struct header_writer_ctx
 | 
			
		|||
    enum pseudo_header           pseh_mask;
 | 
			
		||||
    char                        *pseh_bufs[N_PSEH];
 | 
			
		||||
    struct http1x_headers        hwc_h1h;
 | 
			
		||||
    char                        *hwc_header_buf;
 | 
			
		||||
    size_t                       hwc_header_buf_nalloc;
 | 
			
		||||
    struct lsxpack_header        hwc_xhdr;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -102,7 +105,7 @@ hwc_uh_write (struct header_writer_ctx *hwc, const void *buf, size_t sz)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static enum lsquic_header_status
 | 
			
		||||
static int
 | 
			
		||||
save_pseudo_header (struct header_writer_ctx *hwc, enum pseudo_header ph,
 | 
			
		||||
                    const char *val, unsigned val_len)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -111,30 +114,37 @@ save_pseudo_header (struct header_writer_ctx *hwc, enum pseudo_header ph,
 | 
			
		|||
        assert(!hwc->pseh_bufs[ph]);
 | 
			
		||||
        hwc->pseh_bufs[ph] = malloc(val_len + 1);
 | 
			
		||||
        if (!hwc->pseh_bufs[ph])
 | 
			
		||||
            return LSQUIC_HDR_ERR_NOMEM;
 | 
			
		||||
            return -1;
 | 
			
		||||
        hwc->pseh_mask |= BIT(ph);
 | 
			
		||||
        memcpy(hwc->pseh_bufs[ph], val, val_len);
 | 
			
		||||
        hwc->pseh_bufs[ph][val_len] = '\0';
 | 
			
		||||
        return LSQUIC_HDR_OK;
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_INFO("header %u is already present", ph);
 | 
			
		||||
        return LSQUIC_HDR_ERR_DUPLICATE_PSDO_HDR;
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static enum lsquic_header_status
 | 
			
		||||
add_pseudo_header (struct header_writer_ctx *hwc, const char *name,
 | 
			
		||||
                         unsigned name_len, const char *val, unsigned val_len)
 | 
			
		||||
static int
 | 
			
		||||
add_pseudo_header (struct header_writer_ctx *hwc, struct lsxpack_header *xhdr)
 | 
			
		||||
{
 | 
			
		||||
    const char *name, *val;
 | 
			
		||||
    unsigned name_len, val_len;
 | 
			
		||||
 | 
			
		||||
    if (!(hwc->hwc_flags & HWC_EXPECT_COLON))
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_INFO("unexpected colon");
 | 
			
		||||
        return LSQUIC_HDR_ERR_MISPLACED_PSDO_HDR;
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    name = lsxpack_header_get_name(xhdr);
 | 
			
		||||
    val = lsxpack_header_get_value(xhdr);
 | 
			
		||||
    name_len = xhdr->name_len;
 | 
			
		||||
    val_len = xhdr->val_len;
 | 
			
		||||
 | 
			
		||||
    switch (name_len)
 | 
			
		||||
    {
 | 
			
		||||
    case 5:
 | 
			
		||||
| 
						 | 
				
			
			@ -165,7 +175,7 @@ add_pseudo_header (struct header_writer_ctx *hwc, const char *name,
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    LSQ_INFO("unknown pseudo-header `%.*s'", name_len, name);
 | 
			
		||||
    return LSQUIC_HDR_ERR_UNKNOWN_PSDO_HDR;
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -236,18 +246,18 @@ code_str_to_reason (const char code_str[HTTP_CODE_LEN])
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static enum lsquic_header_status
 | 
			
		||||
static int
 | 
			
		||||
convert_response_pseudo_headers (struct header_writer_ctx *hwc)
 | 
			
		||||
{
 | 
			
		||||
    if ((hwc->pseh_mask & REQUIRED_SERVER_PSEH) != REQUIRED_SERVER_PSEH)
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_INFO("not all response pseudo-headers are specified");
 | 
			
		||||
        return LSQUIC_HDR_ERR_INCOMPL_RESP_PSDO_HDR;
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    if (hwc->pseh_mask & ALL_REQUEST_PSEH)
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_INFO("response pseudo-headers contain request-only headers");
 | 
			
		||||
        return LSQUIC_HDR_ERR_UNNEC_REQ_PSDO_HDR;
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const char *code_str, *reason;
 | 
			
		||||
| 
						 | 
				
			
			@ -258,7 +268,7 @@ convert_response_pseudo_headers (struct header_writer_ctx *hwc)
 | 
			
		|||
 | 
			
		||||
#define HWC_UH_WRITE(h, buf, sz) do {                                   \
 | 
			
		||||
    if (0 != hwc_uh_write(h, buf, sz))                                  \
 | 
			
		||||
        return LSQUIC_HDR_ERR_NOMEM;                                    \
 | 
			
		||||
        return -1;                                                      \
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
    HWC_UH_WRITE(hwc, "HTTP/1.1 ", 9);
 | 
			
		||||
| 
						 | 
				
			
			@ -274,31 +284,31 @@ convert_response_pseudo_headers (struct header_writer_ctx *hwc)
 | 
			
		|||
    if (hwc->max_headers_sz && hwc->w_off > hwc->max_headers_sz)
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_INFO("headers too large");
 | 
			
		||||
        return LSQUIC_HDR_ERR_HEADERS_TOO_LARGE;
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    return LSQUIC_HDR_OK;
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
#undef HWC_UH_WRITE
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static enum lsquic_header_status
 | 
			
		||||
static int
 | 
			
		||||
convert_request_pseudo_headers (struct header_writer_ctx *hwc)
 | 
			
		||||
{
 | 
			
		||||
    if ((hwc->pseh_mask & REQUIRED_REQUEST_PSEH) != REQUIRED_REQUEST_PSEH)
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_INFO("not all request pseudo-headers are specified");
 | 
			
		||||
        return LSQUIC_HDR_ERR_INCOMPL_REQ_PSDO_HDR;
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    if (hwc->pseh_mask & ALL_SERVER_PSEH)
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_INFO("request pseudo-headers contain response-only headers");
 | 
			
		||||
        return LSQUIC_HDR_ERR_UNNEC_RESP_PSDO_HDR;
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#define HWC_UH_WRITE(h, buf, sz) do {                                   \
 | 
			
		||||
    if (0 != hwc_uh_write(h, buf, sz))                                  \
 | 
			
		||||
        return LSQUIC_HDR_ERR_NOMEM;                                    \
 | 
			
		||||
        return -1;                                                      \
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
    HWC_UH_WRITE(hwc, HWC_PSEH_VAL(hwc, PSEH_METHOD), HWC_PSEH_LEN(hwc, PSEH_METHOD));
 | 
			
		||||
| 
						 | 
				
			
			@ -309,7 +319,7 @@ convert_request_pseudo_headers (struct header_writer_ctx *hwc)
 | 
			
		|||
    if (hwc->max_headers_sz && hwc->w_off > hwc->max_headers_sz)
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_INFO("headers too large");
 | 
			
		||||
        return LSQUIC_HDR_ERR_HEADERS_TOO_LARGE;
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -318,7 +328,7 @@ convert_request_pseudo_headers (struct header_writer_ctx *hwc)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static enum lsquic_header_status
 | 
			
		||||
static int
 | 
			
		||||
convert_pseudo_headers (struct header_writer_ctx *hwc)
 | 
			
		||||
{
 | 
			
		||||
    /* We are *reading* the message.  Thus, a server expects a request, and a
 | 
			
		||||
| 
						 | 
				
			
			@ -332,7 +342,7 @@ convert_pseudo_headers (struct header_writer_ctx *hwc)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static enum lsquic_header_status
 | 
			
		||||
static int
 | 
			
		||||
save_cookie (struct header_writer_ctx *hwc, const char *val, unsigned val_len)
 | 
			
		||||
{
 | 
			
		||||
    char *cookie_val;
 | 
			
		||||
| 
						 | 
				
			
			@ -342,7 +352,7 @@ save_cookie (struct header_writer_ctx *hwc, const char *val, unsigned val_len)
 | 
			
		|||
        hwc->cookie_nalloc = hwc->cookie_sz = val_len;
 | 
			
		||||
        cookie_val = malloc(hwc->cookie_nalloc);
 | 
			
		||||
        if (!cookie_val)
 | 
			
		||||
            return LSQUIC_HDR_ERR_NOMEM;
 | 
			
		||||
            return -1;
 | 
			
		||||
        hwc->cookie_val = cookie_val;
 | 
			
		||||
        memcpy(hwc->cookie_val, val, val_len);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -354,7 +364,7 @@ save_cookie (struct header_writer_ctx *hwc, const char *val, unsigned val_len)
 | 
			
		|||
            hwc->cookie_nalloc = hwc->cookie_nalloc * 2 + val_len + 2;
 | 
			
		||||
            cookie_val = realloc(hwc->cookie_val, hwc->cookie_nalloc);
 | 
			
		||||
            if (!cookie_val)
 | 
			
		||||
                return LSQUIC_HDR_ERR_NOMEM;
 | 
			
		||||
                return -1;
 | 
			
		||||
            hwc->cookie_val = cookie_val;
 | 
			
		||||
        }
 | 
			
		||||
        memcpy(hwc->cookie_val + hwc->cookie_sz - val_len - 2, "; ", 2);
 | 
			
		||||
| 
						 | 
				
			
			@ -365,13 +375,14 @@ save_cookie (struct header_writer_ctx *hwc, const char *val, unsigned val_len)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static enum lsquic_header_status
 | 
			
		||||
add_real_header (struct header_writer_ctx *hwc, const char *name,
 | 
			
		||||
                 unsigned name_len, const char *val, unsigned val_len)
 | 
			
		||||
static int
 | 
			
		||||
add_real_header (struct header_writer_ctx *hwc, struct lsxpack_header *xhdr)
 | 
			
		||||
{
 | 
			
		||||
    enum lsquic_header_status err;
 | 
			
		||||
    int err;
 | 
			
		||||
    unsigned i;
 | 
			
		||||
    int n_upper;
 | 
			
		||||
    const char *name, *val;
 | 
			
		||||
    unsigned name_len, val_len;
 | 
			
		||||
 | 
			
		||||
    if (hwc->hwc_flags & HWC_EXPECT_COLON)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -380,6 +391,11 @@ add_real_header (struct header_writer_ctx *hwc, const char *name,
 | 
			
		|||
        hwc->hwc_flags &= ~HWC_EXPECT_COLON;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    name = lsxpack_header_get_name(xhdr);
 | 
			
		||||
    val = lsxpack_header_get_value(xhdr);
 | 
			
		||||
    name_len = xhdr->name_len;
 | 
			
		||||
    val_len = xhdr->val_len;
 | 
			
		||||
 | 
			
		||||
    if (4 == name_len && 0 == memcmp(name, "host", 4))
 | 
			
		||||
        hwc->hwc_flags |= HWC_SEEN_HOST;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -390,7 +406,7 @@ add_real_header (struct header_writer_ctx *hwc, const char *name,
 | 
			
		|||
    {
 | 
			
		||||
        LSQ_INFO("Header name `%.*s' contains uppercase letters",
 | 
			
		||||
            name_len, name);
 | 
			
		||||
        return LSQUIC_HDR_ERR_UPPERCASE_HEADER;
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (6 == name_len && memcmp(name, "cookie", 6) == 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -400,7 +416,7 @@ add_real_header (struct header_writer_ctx *hwc, const char *name,
 | 
			
		|||
 | 
			
		||||
#define HWC_UH_WRITE(h, buf, sz) do {                                   \
 | 
			
		||||
    if (0 != hwc_uh_write(h, buf, sz))                                  \
 | 
			
		||||
        return LSQUIC_HDR_ERR_NOMEM;                                    \
 | 
			
		||||
        return -1;                                                      \
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
    HWC_UH_WRITE(hwc, name, name_len);
 | 
			
		||||
| 
						 | 
				
			
			@ -411,7 +427,7 @@ add_real_header (struct header_writer_ctx *hwc, const char *name,
 | 
			
		|||
    if (hwc->max_headers_sz && hwc->w_off > hwc->max_headers_sz)
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_INFO("headers too large");
 | 
			
		||||
        return LSQUIC_HDR_ERR_HEADERS_TOO_LARGE;
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -420,22 +436,25 @@ add_real_header (struct header_writer_ctx *hwc, const char *name,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static enum lsquic_header_status
 | 
			
		||||
add_header_to_uh (struct header_writer_ctx *hwc, const char *name,
 | 
			
		||||
                  unsigned name_len, const char *val, unsigned val_len)
 | 
			
		||||
static int
 | 
			
		||||
add_header_to_uh (struct header_writer_ctx *hwc, struct lsxpack_header *xhdr)
 | 
			
		||||
{
 | 
			
		||||
    LSQ_DEBUG("Got header '%.*s': '%.*s'", name_len, name, val_len, val);
 | 
			
		||||
    const char *name;
 | 
			
		||||
 | 
			
		||||
    name = lsxpack_header_get_name(xhdr);
 | 
			
		||||
    LSQ_DEBUG("Got header '%.*s': '%.*s'", (int) xhdr->name_len, name,
 | 
			
		||||
                        (int) xhdr->val_len, lsxpack_header_get_value(xhdr));
 | 
			
		||||
    if (':' == name[0])
 | 
			
		||||
        return add_pseudo_header(hwc, name, name_len, val, val_len);
 | 
			
		||||
        return add_pseudo_header(hwc, xhdr);
 | 
			
		||||
    else
 | 
			
		||||
        return add_real_header(hwc, name, name_len, val, val_len);
 | 
			
		||||
        return add_real_header(hwc, xhdr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static enum lsquic_header_status
 | 
			
		||||
static int
 | 
			
		||||
h1h_finish_hset (struct header_writer_ctx *hwc)
 | 
			
		||||
{
 | 
			
		||||
    enum lsquic_header_status st;
 | 
			
		||||
    int st;
 | 
			
		||||
 | 
			
		||||
    if (hwc->hwc_flags & HWC_EXPECT_COLON)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -477,23 +496,65 @@ h1h_finish_hset (struct header_writer_ctx *hwc)
 | 
			
		|||
    if (hwc->max_headers_sz && hwc->w_off > hwc->max_headers_sz)
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_INFO("headers too large");
 | 
			
		||||
        return LSQUIC_HDR_ERR_HEADERS_TOO_LARGE;
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return LSQUIC_HDR_OK;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define HWC_PTR(data_in) (struct header_writer_ctx *) \
 | 
			
		||||
    ((unsigned char *) (hset) - offsetof(struct header_writer_ctx, hwc_h1h))
 | 
			
		||||
 | 
			
		||||
static enum lsquic_header_status
 | 
			
		||||
h1h_process_header (void *hset, unsigned name_idx,
 | 
			
		||||
                    const char *name, unsigned name_len,
 | 
			
		||||
                    const char *value, unsigned value_len)
 | 
			
		||||
 | 
			
		||||
static struct lsxpack_header *
 | 
			
		||||
h1h_prepare_decode (void *hset, struct lsxpack_header *xhdr, size_t extra_space)
 | 
			
		||||
{
 | 
			
		||||
    struct header_writer_ctx *const hwc = HWC_PTR(hset);
 | 
			
		||||
    if (name)
 | 
			
		||||
        return add_header_to_uh(hwc, name, name_len, value, value_len);
 | 
			
		||||
    size_t min_space;
 | 
			
		||||
 | 
			
		||||
    if (0 == extra_space)
 | 
			
		||||
        min_space = 0x100;
 | 
			
		||||
    else
 | 
			
		||||
        min_space = extra_space;
 | 
			
		||||
 | 
			
		||||
    if (xhdr)
 | 
			
		||||
    {
 | 
			
		||||
        assert(xhdr == &hwc->hwc_xhdr);
 | 
			
		||||
        min_space += xhdr->val_len;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (min_space > MAX_HTTP1X_HEADERS_SIZE || min_space > LSXPACK_MAX_STRLEN)
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_DEBUG("requested space for header is too large: %zd bytes",
 | 
			
		||||
                                                                    min_space);
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (min_space > hwc->hwc_header_buf_nalloc)
 | 
			
		||||
    {
 | 
			
		||||
        free(hwc->hwc_header_buf);
 | 
			
		||||
        hwc->hwc_header_buf_nalloc = 0;
 | 
			
		||||
        hwc->hwc_header_buf = malloc(min_space);
 | 
			
		||||
        if (!hwc->hwc_header_buf)
 | 
			
		||||
        {
 | 
			
		||||
            LSQ_DEBUG("cannot allocate %zd bytes", min_space);
 | 
			
		||||
            return NULL;
 | 
			
		||||
        }
 | 
			
		||||
        hwc->hwc_header_buf_nalloc = min_space;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    lsxpack_header_prepare_decode(&hwc->hwc_xhdr, hwc->hwc_header_buf,
 | 
			
		||||
                                            0, hwc->hwc_header_buf_nalloc);
 | 
			
		||||
    return &hwc->hwc_xhdr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
h1h_process_header (void *hset, struct lsxpack_header *xhdr)
 | 
			
		||||
{
 | 
			
		||||
    struct header_writer_ctx *const hwc = HWC_PTR(hset);
 | 
			
		||||
    if (xhdr)
 | 
			
		||||
        return add_header_to_uh(hwc, xhdr);
 | 
			
		||||
    else
 | 
			
		||||
        return h1h_finish_hset(hwc);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -511,6 +572,7 @@ h1h_discard_header_set (void *hset)
 | 
			
		|||
    if (hwc->cookie_val)
 | 
			
		||||
        free(hwc->cookie_val);
 | 
			
		||||
    free(hwc->hwc_h1h.h1h_buf);
 | 
			
		||||
    free(hwc->hwc_header_buf);
 | 
			
		||||
    free(hwc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -518,6 +580,7 @@ h1h_discard_header_set (void *hset)
 | 
			
		|||
static const struct lsquic_hset_if http1x_if =
 | 
			
		||||
{
 | 
			
		||||
    .hsi_create_header_set  = h1h_create_header_set,
 | 
			
		||||
    .hsi_prepare_decode     = h1h_prepare_decode,
 | 
			
		||||
    .hsi_process_header     = h1h_process_header,
 | 
			
		||||
    .hsi_discard_header_set = h1h_discard_header_set,
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -185,7 +185,7 @@ packet_in_is_ok (enum lsquic_version version,
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
lsquic_conn_t *
 | 
			
		||||
mini_conn_new (struct lsquic_engine_public *enp,
 | 
			
		||||
lsquic_mini_conn_new (struct lsquic_engine_public *enp,
 | 
			
		||||
               const struct lsquic_packet_in *packet_in,
 | 
			
		||||
               enum lsquic_version version)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -1852,6 +1852,7 @@ mini_conn_ci_Q050_packet_in (struct lsquic_conn *lconn,
 | 
			
		|||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    if (!mc->mc_conn.cn_enc_session)
 | 
			
		||||
    {
 | 
			
		||||
        mc->mc_conn.cn_enc_session =
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -149,8 +149,8 @@ struct mini_conn {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
lsquic_conn_t *
 | 
			
		||||
mini_conn_new (struct lsquic_engine_public *, const struct lsquic_packet_in *,
 | 
			
		||||
               enum lsquic_version version);
 | 
			
		||||
lsquic_mini_conn_new (struct lsquic_engine_public *,
 | 
			
		||||
            const struct lsquic_packet_in *, enum lsquic_version version);
 | 
			
		||||
 | 
			
		||||
/* Packet numbers start with 1.  By subtracting 1, we can utilize the full
 | 
			
		||||
 * length of the bitmask.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,7 +25,7 @@
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
pacer_init (struct pacer *pacer, const struct lsquic_conn *conn,
 | 
			
		||||
lsquic_pacer_init (struct pacer *pacer, const struct lsquic_conn *conn,
 | 
			
		||||
                                                unsigned clock_granularity)
 | 
			
		||||
{
 | 
			
		||||
    memset(pacer, 0, sizeof(*pacer));
 | 
			
		||||
| 
						 | 
				
			
			@ -36,7 +36,7 @@ pacer_init (struct pacer *pacer, const struct lsquic_conn *conn,
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
pacer_cleanup (struct pacer *pacer)
 | 
			
		||||
lsquic_pacer_cleanup (struct pacer *pacer)
 | 
			
		||||
{
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
    LSQ_DEBUG("scheduled calls: %u", pacer->pa_stats.n_scheduled);
 | 
			
		||||
| 
						 | 
				
			
			@ -45,7 +45,7 @@ pacer_cleanup (struct pacer *pacer)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
pacer_packet_scheduled (struct pacer *pacer, unsigned n_in_flight,
 | 
			
		||||
lsquic_pacer_packet_scheduled (struct pacer *pacer, unsigned n_in_flight,
 | 
			
		||||
                            int in_recovery, tx_time_f tx_time, void *tx_ctx)
 | 
			
		||||
{
 | 
			
		||||
    lsquic_time_t delay, sched_time;
 | 
			
		||||
| 
						 | 
				
			
			@ -98,7 +98,7 @@ pacer_packet_scheduled (struct pacer *pacer, unsigned n_in_flight,
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
pacer_loss_event (struct pacer *pacer)
 | 
			
		||||
lsquic_pacer_loss_event (struct pacer *pacer)
 | 
			
		||||
{
 | 
			
		||||
    pacer->pa_burst_tokens = 0;
 | 
			
		||||
    LSQ_DEBUG("%s: tokens: %u", __func__, pacer->pa_burst_tokens);
 | 
			
		||||
| 
						 | 
				
			
			@ -106,7 +106,7 @@ pacer_loss_event (struct pacer *pacer)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
pacer_can_schedule (struct pacer *pacer, unsigned n_in_flight)
 | 
			
		||||
lsquic_pacer_can_schedule (struct pacer *pacer, unsigned n_in_flight)
 | 
			
		||||
{
 | 
			
		||||
    int can;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -126,7 +126,7 @@ pacer_can_schedule (struct pacer *pacer, unsigned n_in_flight)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
pacer_tick_in (struct pacer *pacer, lsquic_time_t now)
 | 
			
		||||
lsquic_pacer_tick_in (struct pacer *pacer, lsquic_time_t now)
 | 
			
		||||
{
 | 
			
		||||
    assert(now >= pacer->pa_now);
 | 
			
		||||
    pacer->pa_now = now;
 | 
			
		||||
| 
						 | 
				
			
			@ -137,7 +137,7 @@ pacer_tick_in (struct pacer *pacer, lsquic_time_t now)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
pacer_tick_out (struct pacer *pacer)
 | 
			
		||||
lsquic_pacer_tick_out (struct pacer *pacer)
 | 
			
		||||
{
 | 
			
		||||
    if ((pacer->pa_flags & PA_DELAYED_ON_TICK_IN)
 | 
			
		||||
            && pacer->pa_n_scheduled == 0
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,30 +33,30 @@ struct pacer
 | 
			
		|||
typedef lsquic_time_t (*tx_time_f)(void *ctx);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
pacer_init (struct pacer *, const struct lsquic_conn *,
 | 
			
		||||
lsquic_pacer_init (struct pacer *, const struct lsquic_conn *,
 | 
			
		||||
                                            unsigned clock_granularity);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
pacer_cleanup (struct pacer *);
 | 
			
		||||
lsquic_pacer_cleanup (struct pacer *);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
pacer_tick_in (struct pacer *, lsquic_time_t);
 | 
			
		||||
lsquic_pacer_tick_in (struct pacer *, lsquic_time_t);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
pacer_tick_out (struct pacer *);
 | 
			
		||||
lsquic_pacer_tick_out (struct pacer *);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
pacer_can_schedule (struct pacer *, unsigned n_in_flight);
 | 
			
		||||
lsquic_pacer_can_schedule (struct pacer *, unsigned n_in_flight);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
pacer_packet_scheduled (struct pacer *pacer, unsigned n_in_flight,
 | 
			
		||||
lsquic_pacer_packet_scheduled (struct pacer *pacer, unsigned n_in_flight,
 | 
			
		||||
                        int in_recovery, tx_time_f tx_time, void *tx_ctx);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
pacer_loss_event (struct pacer *);
 | 
			
		||||
lsquic_pacer_loss_event (struct pacer *);
 | 
			
		||||
 | 
			
		||||
#define pacer_delayed(pacer) ((pacer)->pa_flags & PA_LAST_SCHED_DELAYED)
 | 
			
		||||
#define lsquic_pacer_delayed(pacer) ((pacer)->pa_flags & PA_LAST_SCHED_DELAYED)
 | 
			
		||||
 | 
			
		||||
#define pacer_next_sched(pacer) (+(pacer)->pa_next_sched)
 | 
			
		||||
#define lsquic_pacer_next_sched(pacer) (+(pacer)->pa_next_sched)
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,7 @@
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
lsquic_packno_t
 | 
			
		||||
restore_packno (lsquic_packno_t cur_packno,
 | 
			
		||||
lsquic_restore_packno (lsquic_packno_t cur_packno,
 | 
			
		||||
                unsigned len,
 | 
			
		||||
                lsquic_packno_t max_packno)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -92,7 +92,7 @@ enum PACKET_PUBLIC_FLAGS
 | 
			
		|||
#define gquic_packno_bits2len(b) (((b) << 1) + !(b))
 | 
			
		||||
 | 
			
		||||
lsquic_packno_t
 | 
			
		||||
restore_packno (lsquic_packno_t cur_packno,
 | 
			
		||||
lsquic_restore_packno (lsquic_packno_t cur_packno,
 | 
			
		||||
                unsigned packet_len,
 | 
			
		||||
                lsquic_packno_t max_packno);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,17 +14,17 @@
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
packet_in_ver_first (const lsquic_packet_in_t *packet_in, struct ver_iter *vi,
 | 
			
		||||
                     lsquic_ver_tag_t *ver_tag)
 | 
			
		||||
lsquic_packet_in_ver_first (const lsquic_packet_in_t *packet_in,
 | 
			
		||||
                            struct ver_iter *vi, lsquic_ver_tag_t *ver_tag)
 | 
			
		||||
{
 | 
			
		||||
    vi->packet_in = packet_in;
 | 
			
		||||
    vi->off       = packet_in->pi_quic_ver;
 | 
			
		||||
    return packet_in_ver_next(vi, ver_tag);
 | 
			
		||||
    return lsquic_packet_in_ver_next(vi, ver_tag);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
packet_in_ver_next (struct ver_iter *vi, lsquic_ver_tag_t *ver_tag)
 | 
			
		||||
lsquic_packet_in_ver_next (struct ver_iter *vi, lsquic_ver_tag_t *ver_tag)
 | 
			
		||||
{
 | 
			
		||||
    if (vi->off + 4 <= vi->packet_in->pi_header_sz)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -159,11 +159,11 @@ struct ver_iter
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
packet_in_ver_first (const lsquic_packet_in_t *packet_in, struct ver_iter *,
 | 
			
		||||
                     lsquic_ver_tag_t *ver_tag);
 | 
			
		||||
lsquic_packet_in_ver_first (const lsquic_packet_in_t *packet_in,
 | 
			
		||||
                            struct ver_iter *, lsquic_ver_tag_t *ver_tag);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
packet_in_ver_next (struct ver_iter *, lsquic_ver_tag_t *ver_tag);
 | 
			
		||||
lsquic_packet_in_ver_next (struct ver_iter *, lsquic_ver_tag_t *ver_tag);
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
lsquic_packet_in_mem_used (const struct lsquic_packet_in *);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,14 +43,14 @@ srec_one_posi_first (struct packet_out_srec_iter *posi,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct stream_rec *
 | 
			
		||||
static struct stream_rec *
 | 
			
		||||
srec_one_posi_next (struct packet_out_srec_iter *posi)
 | 
			
		||||
{
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct stream_rec *
 | 
			
		||||
static struct stream_rec *
 | 
			
		||||
srec_arr_posi_next (struct packet_out_srec_iter *posi)
 | 
			
		||||
{
 | 
			
		||||
    while (posi->cur_srec_arr)
 | 
			
		||||
| 
						 | 
				
			
			@ -96,7 +96,7 @@ static struct stream_rec * (* const posi_nexts[])
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
struct stream_rec *
 | 
			
		||||
posi_first (struct packet_out_srec_iter *posi,
 | 
			
		||||
lsquic_posi_first (struct packet_out_srec_iter *posi,
 | 
			
		||||
            lsquic_packet_out_t *packet_out)
 | 
			
		||||
{
 | 
			
		||||
    posi->impl_idx = !!(packet_out->po_flags & PO_SREC_ARR);
 | 
			
		||||
| 
						 | 
				
			
			@ -105,7 +105,7 @@ posi_first (struct packet_out_srec_iter *posi,
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
struct stream_rec *
 | 
			
		||||
posi_next (struct packet_out_srec_iter *posi)
 | 
			
		||||
lsquic_posi_next (struct packet_out_srec_iter *posi)
 | 
			
		||||
{
 | 
			
		||||
    return posi_nexts[posi->impl_idx](posi);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -296,7 +296,8 @@ lsquic_packet_out_elide_reset_stream_frames (lsquic_packet_out_t *packet_out,
 | 
			
		|||
    int n_stream_frames = 0, n_elided = 0;
 | 
			
		||||
    int victim;
 | 
			
		||||
 | 
			
		||||
    for (srec = posi_first(&posi, packet_out); srec; srec = posi_next(&posi))
 | 
			
		||||
    for (srec = lsquic_posi_first(&posi, packet_out); srec;
 | 
			
		||||
                                            srec = lsquic_posi_next(&posi))
 | 
			
		||||
    {
 | 
			
		||||
        if (srec->sr_frame_type == QUIC_FRAME_STREAM)
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			@ -357,7 +358,8 @@ lsquic_packet_out_chop_regen (lsquic_packet_out_t *packet_out)
 | 
			
		|||
                                                    packet_out->po_data_sz);
 | 
			
		||||
    packet_out->po_regen_sz = 0;
 | 
			
		||||
 | 
			
		||||
    for (srec = posi_first(&posi, packet_out); srec; srec = posi_next(&posi))
 | 
			
		||||
    for (srec = lsquic_posi_first(&posi, packet_out); srec;
 | 
			
		||||
                                                srec = lsquic_posi_next(&posi))
 | 
			
		||||
        if (srec->sr_frame_type == QUIC_FRAME_STREAM)
 | 
			
		||||
            srec->sr_off -= delta;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -368,7 +370,8 @@ lsquic_packet_out_ack_streams (lsquic_packet_out_t *packet_out)
 | 
			
		|||
{
 | 
			
		||||
    struct packet_out_srec_iter posi;
 | 
			
		||||
    struct stream_rec *srec;
 | 
			
		||||
    for (srec = posi_first(&posi, packet_out); srec; srec = posi_next(&posi))
 | 
			
		||||
    for (srec = lsquic_posi_first(&posi, packet_out); srec;
 | 
			
		||||
                                                srec = lsquic_posi_next(&posi))
 | 
			
		||||
        lsquic_stream_acked(srec->sr_stream, srec->sr_frame_type);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -588,11 +591,11 @@ verify_srecs (lsquic_packet_out_t *packet_out, enum quic_frame_type frame_type)
 | 
			
		|||
    const struct stream_rec *srec;
 | 
			
		||||
    unsigned off;
 | 
			
		||||
 | 
			
		||||
    srec = posi_first(&posi, packet_out);
 | 
			
		||||
    srec = lsquic_posi_first(&posi, packet_out);
 | 
			
		||||
    assert(srec);
 | 
			
		||||
 | 
			
		||||
    off = 0;
 | 
			
		||||
    for ( ; srec; srec = posi_next(&posi))
 | 
			
		||||
    for ( ; srec; srec = lsquic_posi_next(&posi))
 | 
			
		||||
    {
 | 
			
		||||
        assert(srec->sr_off == off);
 | 
			
		||||
        assert(srec->sr_frame_type == frame_type);
 | 
			
		||||
| 
						 | 
				
			
			@ -635,7 +638,8 @@ lsquic_packet_out_split_in_two (struct lsquic_mm *mm,
 | 
			
		|||
#ifdef WIN32
 | 
			
		||||
    max_idx = 0;
 | 
			
		||||
#endif
 | 
			
		||||
    for (srec = posi_first(&posi, packet_out); srec; srec = posi_next(&posi))
 | 
			
		||||
    for (srec = lsquic_posi_first(&posi, packet_out); srec;
 | 
			
		||||
                                                srec = lsquic_posi_next(&posi))
 | 
			
		||||
    {
 | 
			
		||||
        assert(srec->sr_frame_type == QUIC_FRAME_STREAM
 | 
			
		||||
            || srec->sr_frame_type == QUIC_FRAME_CRYPTO);
 | 
			
		||||
| 
						 | 
				
			
			@ -772,7 +776,8 @@ lsquic_packet_out_turn_on_fin (struct lsquic_packet_out *packet_out,
 | 
			
		|||
    uint64_t last_offset;
 | 
			
		||||
    int len;
 | 
			
		||||
 | 
			
		||||
    for (srec = posi_first(&posi, packet_out); srec; srec = posi_next(&posi))
 | 
			
		||||
    for (srec = lsquic_posi_first(&posi, packet_out); srec;
 | 
			
		||||
                                                srec = lsquic_posi_next(&posi))
 | 
			
		||||
        if (srec->sr_frame_type == QUIC_FRAME_STREAM
 | 
			
		||||
            && srec->sr_stream == stream)
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -279,10 +279,10 @@ struct packet_out_srec_iter {
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
struct stream_rec *
 | 
			
		||||
posi_first (struct packet_out_srec_iter *posi, lsquic_packet_out_t *);
 | 
			
		||||
lsquic_posi_first (struct packet_out_srec_iter *posi, lsquic_packet_out_t *);
 | 
			
		||||
 | 
			
		||||
struct stream_rec *
 | 
			
		||||
posi_next (struct packet_out_srec_iter *posi);
 | 
			
		||||
lsquic_posi_next (struct packet_out_srec_iter *posi);
 | 
			
		||||
 | 
			
		||||
lsquic_packet_out_t *
 | 
			
		||||
lsquic_packet_out_new (struct lsquic_mm *, struct malo *, int use_cid,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -354,7 +354,7 @@ lsquic_parse_frame_type_gquic_Q035_thru_Q046 (const unsigned char *, size_t);
 | 
			
		|||
extern const enum quic_frame_type lsquic_iquic_byte2type[0x40];
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
calc_stream_frame_header_sz_gquic (lsquic_stream_id_t stream_id,
 | 
			
		||||
lsquic_calc_stream_frame_header_sz_gquic (lsquic_stream_id_t stream_id,
 | 
			
		||||
                                                    uint64_t offset, unsigned);
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -242,7 +242,7 @@ gquic_Q046_packout_size (const struct lsquic_conn *lconn,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
static void
 | 
			
		||||
gquic_Q046_parse_packet_in_finish (struct lsquic_packet_in *packet_in,
 | 
			
		||||
                                            struct packin_parse_state *state)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -323,29 +323,29 @@ const struct parse_funcs lsquic_parse_funcs_gquic_Q046 =
 | 
			
		|||
{
 | 
			
		||||
    .pf_gen_reg_pkt_header            =  gquic_Q046_gen_reg_pkt_header,
 | 
			
		||||
    .pf_parse_packet_in_finish        =  gquic_Q046_parse_packet_in_finish,
 | 
			
		||||
    .pf_gen_stream_frame              =  gquic_be_gen_stream_frame,
 | 
			
		||||
    .pf_calc_stream_frame_header_sz   =  calc_stream_frame_header_sz_gquic,
 | 
			
		||||
    .pf_parse_stream_frame            =  gquic_be_parse_stream_frame,
 | 
			
		||||
    .pf_parse_ack_frame               =  gquic_be_parse_ack_frame,
 | 
			
		||||
    .pf_gen_ack_frame                 =  gquic_be_gen_ack_frame,
 | 
			
		||||
    .pf_gen_stop_waiting_frame        =  gquic_be_gen_stop_waiting_frame,
 | 
			
		||||
    .pf_parse_stop_waiting_frame      =  gquic_be_parse_stop_waiting_frame,
 | 
			
		||||
    .pf_skip_stop_waiting_frame       =  gquic_be_skip_stop_waiting_frame,
 | 
			
		||||
    .pf_gen_window_update_frame       =  gquic_be_gen_window_update_frame,
 | 
			
		||||
    .pf_parse_window_update_frame     =  gquic_be_parse_window_update_frame,
 | 
			
		||||
    .pf_gen_blocked_frame             =  gquic_be_gen_blocked_frame,
 | 
			
		||||
    .pf_parse_blocked_frame           =  gquic_be_parse_blocked_frame,
 | 
			
		||||
    .pf_gen_rst_frame                 =  gquic_be_gen_rst_frame,
 | 
			
		||||
    .pf_parse_rst_frame               =  gquic_be_parse_rst_frame,
 | 
			
		||||
    .pf_connect_close_frame_size      =  gquic_be_connect_close_frame_size,
 | 
			
		||||
    .pf_gen_connect_close_frame       =  gquic_be_gen_connect_close_frame,
 | 
			
		||||
    .pf_parse_connect_close_frame     =  gquic_be_parse_connect_close_frame,
 | 
			
		||||
    .pf_gen_goaway_frame              =  gquic_be_gen_goaway_frame,
 | 
			
		||||
    .pf_parse_goaway_frame            =  gquic_be_parse_goaway_frame,
 | 
			
		||||
    .pf_gen_ping_frame                =  gquic_be_gen_ping_frame,
 | 
			
		||||
    .pf_gen_stream_frame              =  lsquic_gquic_be_gen_stream_frame,
 | 
			
		||||
    .pf_calc_stream_frame_header_sz   =  lsquic_calc_stream_frame_header_sz_gquic,
 | 
			
		||||
    .pf_parse_stream_frame            =  lsquic_gquic_be_parse_stream_frame,
 | 
			
		||||
    .pf_parse_ack_frame               =  lsquic_gquic_be_parse_ack_frame,
 | 
			
		||||
    .pf_gen_ack_frame                 =  lsquic_gquic_be_gen_ack_frame,
 | 
			
		||||
    .pf_gen_stop_waiting_frame        =  lsquic_gquic_be_gen_stop_waiting_frame,
 | 
			
		||||
    .pf_parse_stop_waiting_frame      =  lsquic_gquic_be_parse_stop_waiting_frame,
 | 
			
		||||
    .pf_skip_stop_waiting_frame       =  lsquic_gquic_be_skip_stop_waiting_frame,
 | 
			
		||||
    .pf_gen_window_update_frame       =  lsquic_gquic_be_gen_window_update_frame,
 | 
			
		||||
    .pf_parse_window_update_frame     =  lsquic_gquic_be_parse_window_update_frame,
 | 
			
		||||
    .pf_gen_blocked_frame             =  lsquic_gquic_be_gen_blocked_frame,
 | 
			
		||||
    .pf_parse_blocked_frame           =  lsquic_gquic_be_parse_blocked_frame,
 | 
			
		||||
    .pf_gen_rst_frame                 =  lsquic_gquic_be_gen_rst_frame,
 | 
			
		||||
    .pf_parse_rst_frame               =  lsquic_gquic_be_parse_rst_frame,
 | 
			
		||||
    .pf_connect_close_frame_size      =  lsquic_gquic_be_connect_close_frame_size,
 | 
			
		||||
    .pf_gen_connect_close_frame       =  lsquic_gquic_be_gen_connect_close_frame,
 | 
			
		||||
    .pf_parse_connect_close_frame     =  lsquic_gquic_be_parse_connect_close_frame,
 | 
			
		||||
    .pf_gen_goaway_frame              =  lsquic_gquic_be_gen_goaway_frame,
 | 
			
		||||
    .pf_parse_goaway_frame            =  lsquic_gquic_be_parse_goaway_frame,
 | 
			
		||||
    .pf_gen_ping_frame                =  lsquic_gquic_be_gen_ping_frame,
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
    .pf_write_float_time16            =  gquic_be_write_float_time16,
 | 
			
		||||
    .pf_read_float_time16             =  gquic_be_read_float_time16,
 | 
			
		||||
    .pf_write_float_time16            =  lsquic_gquic_be_write_float_time16,
 | 
			
		||||
    .pf_read_float_time16             =  lsquic_gquic_be_read_float_time16,
 | 
			
		||||
#endif
 | 
			
		||||
    .pf_generate_simple_prst          =  gquic_Q046_generate_simple_prst,
 | 
			
		||||
    .pf_parse_frame_type              =  lsquic_parse_frame_type_gquic_Q035_thru_Q046,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -515,7 +515,7 @@ gquic_Q050_packout_size (const struct lsquic_conn *lconn,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
static void
 | 
			
		||||
gquic_Q050_parse_packet_in_finish (struct lsquic_packet_in *packet_in,
 | 
			
		||||
                                            struct packin_parse_state *state)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -862,29 +862,29 @@ const struct parse_funcs lsquic_parse_funcs_gquic_Q050 =
 | 
			
		|||
{
 | 
			
		||||
    .pf_gen_reg_pkt_header            =  gquic_Q050_gen_reg_pkt_header,
 | 
			
		||||
    .pf_parse_packet_in_finish        =  gquic_Q050_parse_packet_in_finish,
 | 
			
		||||
    .pf_gen_stream_frame              =  gquic_be_gen_stream_frame,
 | 
			
		||||
    .pf_calc_stream_frame_header_sz   =  calc_stream_frame_header_sz_gquic,
 | 
			
		||||
    .pf_parse_stream_frame            =  gquic_be_parse_stream_frame,
 | 
			
		||||
    .pf_parse_ack_frame               =  gquic_be_parse_ack_frame,
 | 
			
		||||
    .pf_gen_ack_frame                 =  gquic_be_gen_ack_frame,
 | 
			
		||||
    .pf_gen_stop_waiting_frame        =  gquic_be_gen_stop_waiting_frame,
 | 
			
		||||
    .pf_parse_stop_waiting_frame      =  gquic_be_parse_stop_waiting_frame,
 | 
			
		||||
    .pf_skip_stop_waiting_frame       =  gquic_be_skip_stop_waiting_frame,
 | 
			
		||||
    .pf_gen_window_update_frame       =  gquic_be_gen_window_update_frame,
 | 
			
		||||
    .pf_parse_window_update_frame     =  gquic_be_parse_window_update_frame,
 | 
			
		||||
    .pf_gen_blocked_frame             =  gquic_be_gen_blocked_frame,
 | 
			
		||||
    .pf_parse_blocked_frame           =  gquic_be_parse_blocked_frame,
 | 
			
		||||
    .pf_gen_rst_frame                 =  gquic_be_gen_rst_frame,
 | 
			
		||||
    .pf_parse_rst_frame               =  gquic_be_parse_rst_frame,
 | 
			
		||||
    .pf_connect_close_frame_size      =  gquic_be_connect_close_frame_size,
 | 
			
		||||
    .pf_gen_connect_close_frame       =  gquic_be_gen_connect_close_frame,
 | 
			
		||||
    .pf_parse_connect_close_frame     =  gquic_be_parse_connect_close_frame,
 | 
			
		||||
    .pf_gen_goaway_frame              =  gquic_be_gen_goaway_frame,
 | 
			
		||||
    .pf_parse_goaway_frame            =  gquic_be_parse_goaway_frame,
 | 
			
		||||
    .pf_gen_ping_frame                =  gquic_be_gen_ping_frame,
 | 
			
		||||
    .pf_gen_stream_frame              =  lsquic_gquic_be_gen_stream_frame,
 | 
			
		||||
    .pf_calc_stream_frame_header_sz   =  lsquic_calc_stream_frame_header_sz_gquic,
 | 
			
		||||
    .pf_parse_stream_frame            =  lsquic_gquic_be_parse_stream_frame,
 | 
			
		||||
    .pf_parse_ack_frame               =  lsquic_gquic_be_parse_ack_frame,
 | 
			
		||||
    .pf_gen_ack_frame                 =  lsquic_gquic_be_gen_ack_frame,
 | 
			
		||||
    .pf_gen_stop_waiting_frame        =  lsquic_gquic_be_gen_stop_waiting_frame,
 | 
			
		||||
    .pf_parse_stop_waiting_frame      =  lsquic_gquic_be_parse_stop_waiting_frame,
 | 
			
		||||
    .pf_skip_stop_waiting_frame       =  lsquic_gquic_be_skip_stop_waiting_frame,
 | 
			
		||||
    .pf_gen_window_update_frame       =  lsquic_gquic_be_gen_window_update_frame,
 | 
			
		||||
    .pf_parse_window_update_frame     =  lsquic_gquic_be_parse_window_update_frame,
 | 
			
		||||
    .pf_gen_blocked_frame             =  lsquic_gquic_be_gen_blocked_frame,
 | 
			
		||||
    .pf_parse_blocked_frame           =  lsquic_gquic_be_parse_blocked_frame,
 | 
			
		||||
    .pf_gen_rst_frame                 =  lsquic_gquic_be_gen_rst_frame,
 | 
			
		||||
    .pf_parse_rst_frame               =  lsquic_gquic_be_parse_rst_frame,
 | 
			
		||||
    .pf_connect_close_frame_size      =  lsquic_gquic_be_connect_close_frame_size,
 | 
			
		||||
    .pf_gen_connect_close_frame       =  lsquic_gquic_be_gen_connect_close_frame,
 | 
			
		||||
    .pf_parse_connect_close_frame     =  lsquic_gquic_be_parse_connect_close_frame,
 | 
			
		||||
    .pf_gen_goaway_frame              =  lsquic_gquic_be_gen_goaway_frame,
 | 
			
		||||
    .pf_parse_goaway_frame            =  lsquic_gquic_be_parse_goaway_frame,
 | 
			
		||||
    .pf_gen_ping_frame                =  lsquic_gquic_be_gen_ping_frame,
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
    .pf_write_float_time16            =  gquic_be_write_float_time16,
 | 
			
		||||
    .pf_read_float_time16             =  gquic_be_read_float_time16,
 | 
			
		||||
    .pf_write_float_time16            =  lsquic_gquic_be_write_float_time16,
 | 
			
		||||
    .pf_read_float_time16             =  lsquic_gquic_be_read_float_time16,
 | 
			
		||||
#endif
 | 
			
		||||
    .pf_generate_simple_prst          =  gquic_Q050_generate_simple_prst,
 | 
			
		||||
    .pf_parse_frame_type              =  gquic_Q050_parse_frame_type,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,7 +43,7 @@
 | 
			
		|||
 | 
			
		||||
/* read 16 bits(2 bytes) time, unit: us */
 | 
			
		||||
uint64_t
 | 
			
		||||
gquic_be_read_float_time16 (const void *mem)
 | 
			
		||||
lsquic_gquic_be_read_float_time16 (const void *mem)
 | 
			
		||||
{
 | 
			
		||||
    uint16_t val;
 | 
			
		||||
    READ_UINT(val, 16, mem, 2);
 | 
			
		||||
| 
						 | 
				
			
			@ -62,7 +62,7 @@ gquic_be_read_float_time16 (const void *mem)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gquic_be_write_float_time16 (lsquic_time_t time_us, void *mem)
 | 
			
		||||
lsquic_gquic_be_write_float_time16 (lsquic_time_t time_us, void *mem)
 | 
			
		||||
{
 | 
			
		||||
    uint16_t ret = 0;
 | 
			
		||||
    uint16_t high, i;
 | 
			
		||||
| 
						 | 
				
			
			@ -93,7 +93,7 @@ gquic_be_write_float_time16 (lsquic_time_t time_us, void *mem)
 | 
			
		|||
 | 
			
		||||
/* Parse out packet number */
 | 
			
		||||
void
 | 
			
		||||
gquic_be_parse_packet_in_finish (lsquic_packet_in_t *packet_in,
 | 
			
		||||
lsquic_gquic_be_parse_packet_in_finish (lsquic_packet_in_t *packet_in,
 | 
			
		||||
                                            struct packin_parse_state *state)
 | 
			
		||||
{
 | 
			
		||||
    lsquic_packno_t packno;
 | 
			
		||||
| 
						 | 
				
			
			@ -106,7 +106,7 @@ gquic_be_parse_packet_in_finish (lsquic_packet_in_t *packet_in,
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
gquic_be_gen_reg_pkt_header (const struct lsquic_conn *lconn,
 | 
			
		||||
lsquic_gquic_be_gen_reg_pkt_header (const struct lsquic_conn *lconn,
 | 
			
		||||
            const struct lsquic_packet_out *packet_out, unsigned char *buf,
 | 
			
		||||
                                                                size_t bufsz)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -190,7 +190,7 @@ gquic_be_gen_reg_pkt_header (const struct lsquic_conn *lconn,
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_gen_stream_frame (unsigned char *buf, size_t buf_len,
 | 
			
		||||
lsquic_gquic_be_gen_stream_frame (unsigned char *buf, size_t buf_len,
 | 
			
		||||
        lsquic_stream_id_t stream_id64, uint64_t offset, int fin, size_t size,
 | 
			
		||||
        gsf_read_f gsf_read, void *stream)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -296,7 +296,7 @@ gquic_be_gen_stream_frame (unsigned char *buf, size_t buf_len,
 | 
			
		|||
 | 
			
		||||
/* return parsed (used) buffer length */
 | 
			
		||||
int
 | 
			
		||||
gquic_be_parse_stream_frame (const unsigned char *buf, size_t rem_packet_sz,
 | 
			
		||||
lsquic_gquic_be_parse_stream_frame (const unsigned char *buf, size_t rem_packet_sz,
 | 
			
		||||
                       stream_frame_t *stream_frame)
 | 
			
		||||
{
 | 
			
		||||
    /* 1fdoooss */
 | 
			
		||||
| 
						 | 
				
			
			@ -385,7 +385,7 @@ parse_ack_frame_without_blocks (const unsigned char *buf, size_t buf_len,
 | 
			
		|||
    READ_UINT(ack->ranges[0].high, 64, p, largest_obs_len);
 | 
			
		||||
    p += largest_obs_len;
 | 
			
		||||
 | 
			
		||||
    ack->lack_delta = gquic_be_read_float_time16(p);
 | 
			
		||||
    ack->lack_delta = lsquic_gquic_be_read_float_time16(p);
 | 
			
		||||
    p += 2;
 | 
			
		||||
 | 
			
		||||
    READ_UINT(tmp_packno, 64, p, ack_block_len);
 | 
			
		||||
| 
						 | 
				
			
			@ -432,7 +432,7 @@ parse_ack_frame_with_blocks (const unsigned char *buf, size_t buf_len,
 | 
			
		|||
    READ_UINT(ack->ranges[0].high, 64, p, largest_obs_len);
 | 
			
		||||
    p += largest_obs_len;
 | 
			
		||||
 | 
			
		||||
    ack->lack_delta = gquic_be_read_float_time16(p);
 | 
			
		||||
    ack->lack_delta = lsquic_gquic_be_read_float_time16(p);
 | 
			
		||||
    p += 2;
 | 
			
		||||
 | 
			
		||||
    unsigned n_blocks;
 | 
			
		||||
| 
						 | 
				
			
			@ -484,7 +484,7 @@ parse_ack_frame_with_blocks (const unsigned char *buf, size_t buf_len,
 | 
			
		|||
 * If parsing failed, negative value is returned.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
gquic_be_parse_ack_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
lsquic_gquic_be_parse_ack_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
                                    struct ack_info *ack, uint8_t UNUSED_exp)
 | 
			
		||||
{
 | 
			
		||||
    if (!(buf[0] & 0x20))
 | 
			
		||||
| 
						 | 
				
			
			@ -495,7 +495,7 @@ gquic_be_parse_ack_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_gen_stop_waiting_frame(unsigned char *buf, size_t buf_len,
 | 
			
		||||
lsquic_gquic_be_gen_stop_waiting_frame(unsigned char *buf, size_t buf_len,
 | 
			
		||||
                lsquic_packno_t cur_packno, enum packno_bits bits,
 | 
			
		||||
                lsquic_packno_t least_unacked_packno)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -519,7 +519,7 @@ gquic_be_gen_stop_waiting_frame(unsigned char *buf, size_t buf_len,
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_parse_stop_waiting_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
lsquic_gquic_be_parse_stop_waiting_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
                 lsquic_packno_t cur_packno, enum packno_bits bits,
 | 
			
		||||
                 lsquic_packno_t *least_unacked)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -538,7 +538,7 @@ gquic_be_parse_stop_waiting_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_skip_stop_waiting_frame (size_t buf_len, enum packno_bits bits)
 | 
			
		||||
lsquic_gquic_be_skip_stop_waiting_frame (size_t buf_len, enum packno_bits bits)
 | 
			
		||||
{
 | 
			
		||||
    unsigned packnum_len = gquic_packno_bits2len(bits);
 | 
			
		||||
    if (buf_len >= 1 + packnum_len)
 | 
			
		||||
| 
						 | 
				
			
			@ -549,7 +549,7 @@ gquic_be_skip_stop_waiting_frame (size_t buf_len, enum packno_bits bits)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_gen_window_update_frame (unsigned char *buf, int buf_len,
 | 
			
		||||
lsquic_gquic_be_gen_window_update_frame (unsigned char *buf, int buf_len,
 | 
			
		||||
                            lsquic_stream_id_t stream_id64, uint64_t offset)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t stream_id = stream_id64;
 | 
			
		||||
| 
						 | 
				
			
			@ -571,7 +571,7 @@ gquic_be_gen_window_update_frame (unsigned char *buf, int buf_len,
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_parse_window_update_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
lsquic_gquic_be_parse_window_update_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
                      lsquic_stream_id_t *stream_id_p, uint64_t *offset)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t stream_id;
 | 
			
		||||
| 
						 | 
				
			
			@ -587,7 +587,7 @@ gquic_be_parse_window_update_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_gen_blocked_frame (unsigned char *buf, size_t buf_len,
 | 
			
		||||
lsquic_gquic_be_gen_blocked_frame (unsigned char *buf, size_t buf_len,
 | 
			
		||||
                            lsquic_stream_id_t stream_id64)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t stream_id = stream_id64;
 | 
			
		||||
| 
						 | 
				
			
			@ -605,7 +605,7 @@ gquic_be_gen_blocked_frame (unsigned char *buf, size_t buf_len,
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_parse_blocked_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
lsquic_gquic_be_parse_blocked_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
                                            lsquic_stream_id_t *stream_id_p)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t stream_id;
 | 
			
		||||
| 
						 | 
				
			
			@ -619,7 +619,7 @@ gquic_be_parse_blocked_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
static unsigned
 | 
			
		||||
gquic_be_rst_frame_size (lsquic_stream_id_t stream_id, uint64_t error_code,
 | 
			
		||||
lsquic_gquic_be_rst_frame_size (lsquic_stream_id_t stream_id, uint64_t error_code,
 | 
			
		||||
                                                        uint64_t final_size)
 | 
			
		||||
{
 | 
			
		||||
    assert(0);  /* This function is not called */
 | 
			
		||||
| 
						 | 
				
			
			@ -628,7 +628,7 @@ gquic_be_rst_frame_size (lsquic_stream_id_t stream_id, uint64_t error_code,
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_gen_rst_frame (unsigned char *buf, size_t buf_len,
 | 
			
		||||
lsquic_gquic_be_gen_rst_frame (unsigned char *buf, size_t buf_len,
 | 
			
		||||
        lsquic_stream_id_t stream_id64, uint64_t offset, uint64_t error_code64)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t stream_id = stream_id64, error_code = error_code64;
 | 
			
		||||
| 
						 | 
				
			
			@ -658,7 +658,7 @@ gquic_be_gen_rst_frame (unsigned char *buf, size_t buf_len,
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_parse_rst_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
lsquic_gquic_be_parse_rst_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
    lsquic_stream_id_t *stream_id_p, uint64_t *offset, uint64_t *error_code_p)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t stream_id, error_code;
 | 
			
		||||
| 
						 | 
				
			
			@ -676,7 +676,7 @@ gquic_be_parse_rst_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_gen_ping_frame (unsigned char *buf, int buf_len)
 | 
			
		||||
lsquic_gquic_be_gen_ping_frame (unsigned char *buf, int buf_len)
 | 
			
		||||
{
 | 
			
		||||
    if (buf_len > 0)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -689,7 +689,7 @@ gquic_be_gen_ping_frame (unsigned char *buf, int buf_len)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
gquic_be_connect_close_frame_size (int app_error, unsigned error_code,
 | 
			
		||||
lsquic_gquic_be_connect_close_frame_size (int app_error, unsigned error_code,
 | 
			
		||||
                                unsigned frame_type, size_t reason_len)
 | 
			
		||||
{
 | 
			
		||||
    return 1 + 4 + 2 + reason_len;
 | 
			
		||||
| 
						 | 
				
			
			@ -697,7 +697,7 @@ gquic_be_connect_close_frame_size (int app_error, unsigned error_code,
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_gen_connect_close_frame (unsigned char *buf, size_t buf_len,
 | 
			
		||||
lsquic_gquic_be_gen_connect_close_frame (unsigned char *buf, size_t buf_len,
 | 
			
		||||
    int app_error_UNUSED, unsigned ecode, const char *reason, int reason_len)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t error_code;
 | 
			
		||||
| 
						 | 
				
			
			@ -728,7 +728,7 @@ gquic_be_gen_connect_close_frame (unsigned char *buf, size_t buf_len,
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_parse_connect_close_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
lsquic_gquic_be_parse_connect_close_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
        int *app_error, uint64_t *error_code_p,
 | 
			
		||||
        uint16_t *reason_len, uint8_t *reason_offset)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -752,7 +752,7 @@ gquic_be_parse_connect_close_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_gen_goaway_frame (unsigned char *buf, size_t buf_len,
 | 
			
		||||
lsquic_gquic_be_gen_goaway_frame (unsigned char *buf, size_t buf_len,
 | 
			
		||||
        uint32_t error_code, lsquic_stream_id_t last_good_stream_id64,
 | 
			
		||||
        const char *reason, size_t reason_len)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -792,7 +792,7 @@ gquic_be_gen_goaway_frame (unsigned char *buf, size_t buf_len,
 | 
			
		|||
 | 
			
		||||
/* the reason is buf + *reason_offset, length is *reason_length */
 | 
			
		||||
int
 | 
			
		||||
gquic_be_parse_goaway_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
lsquic_gquic_be_parse_goaway_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
               uint32_t *error_code, lsquic_stream_id_t *last_good_stream_id,
 | 
			
		||||
               uint16_t *reason_length, const char **reason)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -820,7 +820,7 @@ gquic_be_parse_goaway_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		|||
/* Returns number of bytes written or -1 on failure */
 | 
			
		||||
/* This function makes an assumption that there is at least one range */
 | 
			
		||||
int
 | 
			
		||||
gquic_be_gen_ack_frame (unsigned char *outbuf, size_t outbuf_sz,
 | 
			
		||||
lsquic_gquic_be_gen_ack_frame (unsigned char *outbuf, size_t outbuf_sz,
 | 
			
		||||
        gaf_rechist_first_f rechist_first, gaf_rechist_next_f rechist_next,
 | 
			
		||||
        gaf_rechist_largest_recv_f rechist_largest_recv,
 | 
			
		||||
        void *rechist, lsquic_time_t now, int *has_missing,
 | 
			
		||||
| 
						 | 
				
			
			@ -898,7 +898,7 @@ gquic_be_gen_ack_frame (unsigned char *outbuf, size_t outbuf_sz,
 | 
			
		|||
 | 
			
		||||
    CHECKOUT(2);
 | 
			
		||||
    time_diff = now - rechist_largest_recv(rechist);
 | 
			
		||||
    gquic_be_write_float_time16(time_diff, p);
 | 
			
		||||
    lsquic_gquic_be_write_float_time16(time_diff, p);
 | 
			
		||||
    LSQ_DEBUG("%s: diff: %"PRIu64"; encoded: 0x%04X", __func__, time_diff,
 | 
			
		||||
        *(uint16_t*)p);
 | 
			
		||||
    p += 2;
 | 
			
		||||
| 
						 | 
				
			
			@ -985,7 +985,7 @@ gquic_be_gen_ack_frame (unsigned char *outbuf, size_t outbuf_sz,
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
gquic_be_gen_crypto_frame (unsigned char *buf, size_t buf_len,
 | 
			
		||||
lsquic_gquic_be_gen_crypto_frame (unsigned char *buf, size_t buf_len,
 | 
			
		||||
        uint64_t offset, size_t size, gcf_read_f gcf_read, void *stream)
 | 
			
		||||
{
 | 
			
		||||
    assert(0);
 | 
			
		||||
| 
						 | 
				
			
			@ -994,7 +994,7 @@ gquic_be_gen_crypto_frame (unsigned char *buf, size_t buf_len,
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
gquic_be_parse_crypto_frame (const unsigned char *buf, size_t rem_packet_sz,
 | 
			
		||||
lsquic_gquic_be_parse_crypto_frame (const unsigned char *buf, size_t rem_packet_sz,
 | 
			
		||||
                                            struct stream_frame *stream_frame)
 | 
			
		||||
{
 | 
			
		||||
    assert(0);
 | 
			
		||||
| 
						 | 
				
			
			@ -1003,7 +1003,7 @@ gquic_be_parse_crypto_frame (const unsigned char *buf, size_t rem_packet_sz,
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
gquic_be_packno_info (const struct lsquic_conn *lconn,
 | 
			
		||||
lsquic_gquic_be_packno_info (const struct lsquic_conn *lconn,
 | 
			
		||||
        const struct lsquic_packet_out *packet_out, unsigned *packno_off,
 | 
			
		||||
        unsigned *packno_len)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -1034,32 +1034,32 @@ gquic_Q043_parse_handshake_done_frame (const unsigned char *buf, size_t buf_len)
 | 
			
		|||
 | 
			
		||||
const struct parse_funcs lsquic_parse_funcs_gquic_Q043 =
 | 
			
		||||
{
 | 
			
		||||
    .pf_gen_reg_pkt_header            =  gquic_be_gen_reg_pkt_header,
 | 
			
		||||
    .pf_parse_packet_in_finish        =  gquic_be_parse_packet_in_finish,
 | 
			
		||||
    .pf_gen_stream_frame              =  gquic_be_gen_stream_frame,
 | 
			
		||||
    .pf_calc_stream_frame_header_sz   =  calc_stream_frame_header_sz_gquic,
 | 
			
		||||
    .pf_parse_stream_frame            =  gquic_be_parse_stream_frame,
 | 
			
		||||
    .pf_parse_ack_frame               =  gquic_be_parse_ack_frame,
 | 
			
		||||
    .pf_gen_ack_frame                 =  gquic_be_gen_ack_frame,
 | 
			
		||||
    .pf_gen_stop_waiting_frame        =  gquic_be_gen_stop_waiting_frame,
 | 
			
		||||
    .pf_parse_stop_waiting_frame      =  gquic_be_parse_stop_waiting_frame,
 | 
			
		||||
    .pf_skip_stop_waiting_frame       =  gquic_be_skip_stop_waiting_frame,
 | 
			
		||||
    .pf_gen_window_update_frame       =  gquic_be_gen_window_update_frame,
 | 
			
		||||
    .pf_parse_window_update_frame     =  gquic_be_parse_window_update_frame,
 | 
			
		||||
    .pf_gen_blocked_frame             =  gquic_be_gen_blocked_frame,
 | 
			
		||||
    .pf_parse_blocked_frame           =  gquic_be_parse_blocked_frame,
 | 
			
		||||
    .pf_rst_frame_size                =  gquic_be_rst_frame_size,
 | 
			
		||||
    .pf_gen_rst_frame                 =  gquic_be_gen_rst_frame,
 | 
			
		||||
    .pf_parse_rst_frame               =  gquic_be_parse_rst_frame,
 | 
			
		||||
    .pf_connect_close_frame_size      =  gquic_be_connect_close_frame_size,
 | 
			
		||||
    .pf_gen_connect_close_frame       =  gquic_be_gen_connect_close_frame,
 | 
			
		||||
    .pf_parse_connect_close_frame     =  gquic_be_parse_connect_close_frame,
 | 
			
		||||
    .pf_gen_goaway_frame              =  gquic_be_gen_goaway_frame,
 | 
			
		||||
    .pf_parse_goaway_frame            =  gquic_be_parse_goaway_frame,
 | 
			
		||||
    .pf_gen_ping_frame                =  gquic_be_gen_ping_frame,
 | 
			
		||||
    .pf_gen_reg_pkt_header            =  lsquic_gquic_be_gen_reg_pkt_header,
 | 
			
		||||
    .pf_parse_packet_in_finish        =  lsquic_gquic_be_parse_packet_in_finish,
 | 
			
		||||
    .pf_gen_stream_frame              =  lsquic_gquic_be_gen_stream_frame,
 | 
			
		||||
    .pf_calc_stream_frame_header_sz   =  lsquic_calc_stream_frame_header_sz_gquic,
 | 
			
		||||
    .pf_parse_stream_frame            =  lsquic_gquic_be_parse_stream_frame,
 | 
			
		||||
    .pf_parse_ack_frame               =  lsquic_gquic_be_parse_ack_frame,
 | 
			
		||||
    .pf_gen_ack_frame                 =  lsquic_gquic_be_gen_ack_frame,
 | 
			
		||||
    .pf_gen_stop_waiting_frame        =  lsquic_gquic_be_gen_stop_waiting_frame,
 | 
			
		||||
    .pf_parse_stop_waiting_frame      =  lsquic_gquic_be_parse_stop_waiting_frame,
 | 
			
		||||
    .pf_skip_stop_waiting_frame       =  lsquic_gquic_be_skip_stop_waiting_frame,
 | 
			
		||||
    .pf_gen_window_update_frame       =  lsquic_gquic_be_gen_window_update_frame,
 | 
			
		||||
    .pf_parse_window_update_frame     =  lsquic_gquic_be_parse_window_update_frame,
 | 
			
		||||
    .pf_gen_blocked_frame             =  lsquic_gquic_be_gen_blocked_frame,
 | 
			
		||||
    .pf_parse_blocked_frame           =  lsquic_gquic_be_parse_blocked_frame,
 | 
			
		||||
    .pf_rst_frame_size                =  lsquic_gquic_be_rst_frame_size,
 | 
			
		||||
    .pf_gen_rst_frame                 =  lsquic_gquic_be_gen_rst_frame,
 | 
			
		||||
    .pf_parse_rst_frame               =  lsquic_gquic_be_parse_rst_frame,
 | 
			
		||||
    .pf_connect_close_frame_size      =  lsquic_gquic_be_connect_close_frame_size,
 | 
			
		||||
    .pf_gen_connect_close_frame       =  lsquic_gquic_be_gen_connect_close_frame,
 | 
			
		||||
    .pf_parse_connect_close_frame     =  lsquic_gquic_be_parse_connect_close_frame,
 | 
			
		||||
    .pf_gen_goaway_frame              =  lsquic_gquic_be_gen_goaway_frame,
 | 
			
		||||
    .pf_parse_goaway_frame            =  lsquic_gquic_be_parse_goaway_frame,
 | 
			
		||||
    .pf_gen_ping_frame                =  lsquic_gquic_be_gen_ping_frame,
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
    .pf_write_float_time16            =  gquic_be_write_float_time16,
 | 
			
		||||
    .pf_read_float_time16             =  gquic_be_read_float_time16,
 | 
			
		||||
    .pf_write_float_time16            =  lsquic_gquic_be_write_float_time16,
 | 
			
		||||
    .pf_read_float_time16             =  lsquic_gquic_be_read_float_time16,
 | 
			
		||||
#endif
 | 
			
		||||
    .pf_generate_simple_prst          =  lsquic_generate_gquic_reset,
 | 
			
		||||
    .pf_parse_frame_type              =  lsquic_parse_frame_type_gquic_Q035_thru_Q046,
 | 
			
		||||
| 
						 | 
				
			
			@ -1068,9 +1068,9 @@ const struct parse_funcs lsquic_parse_funcs_gquic_Q043 =
 | 
			
		|||
    .pf_packout_max_header_size       =  lsquic_gquic_packout_header_size,
 | 
			
		||||
    .pf_calc_packno_bits              =  lsquic_gquic_calc_packno_bits,
 | 
			
		||||
    .pf_packno_bits2len               =  lsquic_gquic_packno_bits2len,
 | 
			
		||||
    .pf_gen_crypto_frame              =  gquic_be_gen_crypto_frame,
 | 
			
		||||
    .pf_parse_crypto_frame            =  gquic_be_parse_crypto_frame,
 | 
			
		||||
    .pf_packno_info                   =  gquic_be_packno_info,
 | 
			
		||||
    .pf_gen_crypto_frame              =  lsquic_gquic_be_gen_crypto_frame,
 | 
			
		||||
    .pf_parse_crypto_frame            =  lsquic_gquic_be_parse_crypto_frame,
 | 
			
		||||
    .pf_packno_info                   =  lsquic_gquic_be_packno_info,
 | 
			
		||||
    .pf_gen_handshake_done_frame      =  gquic_Q043_gen_handshake_done_frame,
 | 
			
		||||
    .pf_parse_handshake_done_frame    =  gquic_Q043_parse_handshake_done_frame,
 | 
			
		||||
    .pf_handshake_done_frame_size     =  gquic_Q043_handshake_done_frame_size,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,100 +12,100 @@
 | 
			
		|||
    do { if ((intptr_t) (need) > ((pend) - (pstart))) { return -1; } } while (0)
 | 
			
		||||
 | 
			
		||||
uint64_t
 | 
			
		||||
gquic_be_read_float_time16 (const void *mem);
 | 
			
		||||
lsquic_gquic_be_read_float_time16 (const void *mem);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gquic_be_write_float_time16 (lsquic_time_t time_us, void *mem);
 | 
			
		||||
lsquic_gquic_be_write_float_time16 (lsquic_time_t time_us, void *mem);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gquic_be_parse_packet_in_finish (lsquic_packet_in_t *packet_in,
 | 
			
		||||
lsquic_gquic_be_parse_packet_in_finish (lsquic_packet_in_t *packet_in,
 | 
			
		||||
                                            struct packin_parse_state *state);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_gen_ver_nego_pkt (unsigned char *buf, size_t bufsz,
 | 
			
		||||
lsquic_gquic_be_gen_ver_nego_pkt (unsigned char *buf, size_t bufsz,
 | 
			
		||||
                    const lsquic_cid_t *, unsigned version_bitmask);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_gen_stream_frame (unsigned char *buf, size_t buf_len,
 | 
			
		||||
lsquic_gquic_be_gen_stream_frame (unsigned char *buf, size_t buf_len,
 | 
			
		||||
    lsquic_stream_id_t stream_id, uint64_t offset, int fin, size_t size,
 | 
			
		||||
    gsf_read_f gsf_read, void *stream);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_parse_stream_frame (const unsigned char *buf, size_t rem_packet_sz,
 | 
			
		||||
lsquic_gquic_be_parse_stream_frame (const unsigned char *buf, size_t rem_packet_sz,
 | 
			
		||||
                       stream_frame_t *stream_frame);
 | 
			
		||||
 | 
			
		||||
lsquic_packno_t
 | 
			
		||||
gquic_be_parse_ack_high (const unsigned char *buf, size_t buf_len);
 | 
			
		||||
lsquic_gquic_be_parse_ack_high (const unsigned char *buf, size_t buf_len);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_parse_ack_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
lsquic_gquic_be_parse_ack_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
                                                struct ack_info *, uint8_t);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_gen_stop_waiting_frame(unsigned char *buf, size_t buf_len,
 | 
			
		||||
lsquic_gquic_be_gen_stop_waiting_frame(unsigned char *buf, size_t buf_len,
 | 
			
		||||
                lsquic_packno_t cur_packno, enum packno_bits bits,
 | 
			
		||||
                lsquic_packno_t least_unacked_packno);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_parse_stop_waiting_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
lsquic_gquic_be_parse_stop_waiting_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
                 lsquic_packno_t cur_packno, enum packno_bits bits,
 | 
			
		||||
                 lsquic_packno_t *least_unacked);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_skip_stop_waiting_frame (size_t buf_len, enum packno_bits bits);
 | 
			
		||||
lsquic_gquic_be_skip_stop_waiting_frame (size_t buf_len, enum packno_bits bits);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_gen_window_update_frame (unsigned char *buf, int buf_len,
 | 
			
		||||
lsquic_gquic_be_gen_window_update_frame (unsigned char *buf, int buf_len,
 | 
			
		||||
                            lsquic_stream_id_t stream_id, uint64_t offset);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_parse_window_update_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
lsquic_gquic_be_parse_window_update_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
                              lsquic_stream_id_t *stream_id, uint64_t *offset);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_gen_blocked_frame (unsigned char *buf, size_t buf_len,
 | 
			
		||||
lsquic_gquic_be_gen_blocked_frame (unsigned char *buf, size_t buf_len,
 | 
			
		||||
                            lsquic_stream_id_t stream_id);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_parse_blocked_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
lsquic_gquic_be_parse_blocked_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
                                                lsquic_stream_id_t *stream_id);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_gen_rst_frame (unsigned char *buf, size_t buf_len,
 | 
			
		||||
lsquic_gquic_be_gen_rst_frame (unsigned char *buf, size_t buf_len,
 | 
			
		||||
        lsquic_stream_id_t stream_id, uint64_t offset, uint64_t error_code);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_parse_rst_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
lsquic_gquic_be_parse_rst_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
    lsquic_stream_id_t *stream_id, uint64_t *offset, uint64_t *error_code);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_gen_ping_frame (unsigned char *buf, int buf_len);
 | 
			
		||||
lsquic_gquic_be_gen_ping_frame (unsigned char *buf, int buf_len);
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
gquic_be_connect_close_frame_size (int app_error, unsigned error_code,
 | 
			
		||||
lsquic_gquic_be_connect_close_frame_size (int app_error, unsigned error_code,
 | 
			
		||||
                                unsigned frame_type, size_t reason_len);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_gen_connect_close_frame (unsigned char *buf, size_t buf_len,
 | 
			
		||||
lsquic_gquic_be_gen_connect_close_frame (unsigned char *buf, size_t buf_len,
 | 
			
		||||
    int app_error, unsigned error_code, const char *reason, int reason_len);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_parse_connect_close_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
lsquic_gquic_be_parse_connect_close_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
        int *app_error, uint64_t *error_code,
 | 
			
		||||
        uint16_t *reason_len, uint8_t *reason_offset);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_gen_goaway_frame(unsigned char *buf, size_t buf_len, uint32_t error_code,
 | 
			
		||||
lsquic_gquic_be_gen_goaway_frame(unsigned char *buf, size_t buf_len, uint32_t error_code,
 | 
			
		||||
                     lsquic_stream_id_t last_good_stream_id, const char *reason,
 | 
			
		||||
                     size_t reason_len);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_parse_goaway_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
lsquic_gquic_be_parse_goaway_frame (const unsigned char *buf, size_t buf_len,
 | 
			
		||||
               uint32_t *error_code, lsquic_stream_id_t *last_good_stream_id,
 | 
			
		||||
                       uint16_t *reason_length, const char **reason);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
gquic_be_gen_ack_frame (unsigned char *outbuf, size_t outbuf_sz,
 | 
			
		||||
lsquic_gquic_be_gen_ack_frame (unsigned char *outbuf, size_t outbuf_sz,
 | 
			
		||||
        gaf_rechist_first_f rechist_first, gaf_rechist_next_f rechist_next,
 | 
			
		||||
        gaf_rechist_largest_recv_f rechist_largest_recv,
 | 
			
		||||
        void *rechist, lsquic_time_t now, int *has_missing, lsquic_packno_t *,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -477,7 +477,7 @@ lsquic_turn_on_fin_Q035_thru_Q046 (unsigned char *stream_header)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
calc_stream_frame_header_sz_gquic (lsquic_stream_id_t stream_id,
 | 
			
		||||
lsquic_calc_stream_frame_header_sz_gquic (lsquic_stream_id_t stream_id,
 | 
			
		||||
                                    uint64_t offset, unsigned data_sz_IGNORED)
 | 
			
		||||
{
 | 
			
		||||
    return
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1185,7 +1185,7 @@ ietf_v1_parse_path_resp_frame (const unsigned char *buf, size_t len,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
static void
 | 
			
		||||
ietf_v1_turn_on_fin (unsigned char *stream_frame_header)
 | 
			
		||||
{
 | 
			
		||||
    *stream_frame_header |= 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -1609,7 +1609,7 @@ ietf_v1_new_token_frame_size (size_t token_sz)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
static int
 | 
			
		||||
ietf_v1_gen_new_token_frame (unsigned char *buf, size_t buf_sz,
 | 
			
		||||
                                const unsigned char *token, size_t token_sz)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -1649,7 +1649,7 @@ ietf_v1_new_connection_id_frame_size (unsigned seqno, unsigned scid_len)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
static int
 | 
			
		||||
ietf_v1_gen_new_connection_id_frame (unsigned char *buf, size_t buf_sz,
 | 
			
		||||
            unsigned seqno, const struct lsquic_cid *cid,
 | 
			
		||||
            const unsigned char *token, size_t token_sz)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -135,7 +135,7 @@ hash_req (const void *p, size_t len, unsigned seed)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
struct pr_queue *
 | 
			
		||||
prq_create (unsigned max_elems, unsigned max_conns,
 | 
			
		||||
lsquic_prq_create (unsigned max_elems, unsigned max_conns,
 | 
			
		||||
                        const struct lsquic_engine_public *enpub)
 | 
			
		||||
{
 | 
			
		||||
    const struct parse_funcs *pf;
 | 
			
		||||
| 
						 | 
				
			
			@ -217,7 +217,7 @@ prq_create (unsigned max_elems, unsigned max_conns,
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
prq_destroy (struct pr_queue *prq)
 | 
			
		||||
lsquic_prq_destroy (struct pr_queue *prq)
 | 
			
		||||
{
 | 
			
		||||
    struct lsquic_conn *conn;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -259,8 +259,8 @@ put_req (struct pr_queue *prq, struct packet_req *req)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
lsquic_prq_new_req (struct pr_queue *prq, enum packet_req_type type,
 | 
			
		||||
static int
 | 
			
		||||
lsquic_prq_new_req_ext (struct pr_queue *prq, enum packet_req_type type,
 | 
			
		||||
    unsigned flags, enum lsquic_version version, unsigned short data_sz,
 | 
			
		||||
    const lsquic_cid_t *dcid, const lsquic_cid_t *scid, void *peer_ctx,
 | 
			
		||||
    const struct sockaddr *local_addr, const struct sockaddr *peer_addr)
 | 
			
		||||
| 
						 | 
				
			
			@ -334,7 +334,7 @@ lsquic_prq_new_req (struct pr_queue *prq, enum packet_req_type type,
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
prq_new_req (struct pr_queue *prq, enum packet_req_type type,
 | 
			
		||||
lsquic_prq_new_req (struct pr_queue *prq, enum packet_req_type type,
 | 
			
		||||
         const struct lsquic_packet_in *packet_in, void *peer_ctx,
 | 
			
		||||
         const struct sockaddr *local_addr, const struct sockaddr *peer_addr)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -358,8 +358,9 @@ prq_new_req (struct pr_queue *prq, enum packet_req_type type,
 | 
			
		|||
        version = LSQVER_ID25;
 | 
			
		||||
 | 
			
		||||
    lsquic_scid_from_packet_in(packet_in, &scid);
 | 
			
		||||
    return lsquic_prq_new_req(prq, type, flags, version, packet_in->pi_data_sz,
 | 
			
		||||
                &packet_in->pi_dcid, &scid, peer_ctx, local_addr, peer_addr);
 | 
			
		||||
    return lsquic_prq_new_req_ext(prq, type, flags, version,
 | 
			
		||||
                packet_in->pi_data_sz, &packet_in->pi_dcid, &scid,
 | 
			
		||||
                peer_ctx, local_addr, peer_addr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -421,7 +422,7 @@ get_evconn (struct pr_queue *prq)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
struct lsquic_conn *
 | 
			
		||||
prq_next_conn (struct pr_queue *prq)
 | 
			
		||||
lsquic_prq_next_conn (struct pr_queue *prq)
 | 
			
		||||
{
 | 
			
		||||
    struct evanescent_conn *evconn;
 | 
			
		||||
    struct lsquic_conn *lconn;
 | 
			
		||||
| 
						 | 
				
			
			@ -504,7 +505,7 @@ prq_next_conn (struct pr_queue *prq)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
prq_have_pending (const struct pr_queue *prq)
 | 
			
		||||
lsquic_prq_have_pending (const struct pr_queue *prq)
 | 
			
		||||
{
 | 
			
		||||
    return lsquic_hash_count(prq->prq_reqs_hash) > 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,23 +57,23 @@ enum packet_req_type {
 | 
			
		|||
extern const char *const lsquic_preqt2str[N_PREQ_TYPES];
 | 
			
		||||
 | 
			
		||||
struct pr_queue *
 | 
			
		||||
prq_create (unsigned max_elems, unsigned max_conns,
 | 
			
		||||
lsquic_prq_create (unsigned max_elems, unsigned max_conns,
 | 
			
		||||
                const struct lsquic_engine_public *);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
prq_destroy (struct pr_queue *);
 | 
			
		||||
lsquic_prq_destroy (struct pr_queue *);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
prq_new_req (struct pr_queue *, enum packet_req_type,
 | 
			
		||||
lsquic_prq_new_req (struct pr_queue *, enum packet_req_type,
 | 
			
		||||
             const struct lsquic_packet_in *, void *conn_ctx,
 | 
			
		||||
             const struct sockaddr *local_addr,
 | 
			
		||||
             const struct sockaddr *peer_addr);
 | 
			
		||||
 | 
			
		||||
struct lsquic_conn *
 | 
			
		||||
prq_next_conn (struct pr_queue *);
 | 
			
		||||
lsquic_prq_next_conn (struct pr_queue *);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
prq_have_pending (const struct pr_queue *);
 | 
			
		||||
lsquic_prq_have_pending (const struct pr_queue *);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
lsquic_prq_drop (struct lsquic_conn *);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,6 +12,7 @@
 | 
			
		|||
 | 
			
		||||
#include "lsquic.h"
 | 
			
		||||
#include "lsquic_types.h"
 | 
			
		||||
#include "lsxpack_header.h"
 | 
			
		||||
#include "lsquic_int_types.h"
 | 
			
		||||
#include "lsquic_sfcw.h"
 | 
			
		||||
#include "lsquic_varint.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -446,14 +447,15 @@ qdh_supply_hset_to_stream (struct qpack_dec_hdl *qdh,
 | 
			
		|||
            struct lsquic_stream *stream, struct lsqpack_header_list *qlist)
 | 
			
		||||
{
 | 
			
		||||
    const struct lsquic_hset_if *const hset_if = qdh->qdh_enpub->enp_hsi_if;
 | 
			
		||||
    const unsigned hpack_static_table_size = 61;
 | 
			
		||||
    struct uncompressed_headers *uh = NULL;
 | 
			
		||||
    const struct lsqpack_header *header;
 | 
			
		||||
    enum lsquic_header_status st;
 | 
			
		||||
    int st;
 | 
			
		||||
    int push_promise;
 | 
			
		||||
    unsigned i;
 | 
			
		||||
    void *hset;
 | 
			
		||||
    struct cont_len cl;
 | 
			
		||||
    struct lsxpack_header *xhdr;
 | 
			
		||||
    size_t extra;
 | 
			
		||||
 | 
			
		||||
    push_promise = lsquic_stream_header_is_pp(stream);
 | 
			
		||||
    hset = hset_if->hsi_create_header_set(qdh->qdh_hsi_ctx, push_promise);
 | 
			
		||||
| 
						 | 
				
			
			@ -471,14 +473,33 @@ qdh_supply_hset_to_stream (struct qpack_dec_hdl *qdh,
 | 
			
		|||
        header = qlist->qhl_headers[i];
 | 
			
		||||
        LSQ_DEBUG("%.*s: %.*s", header->qh_name_len, header->qh_name,
 | 
			
		||||
                                        header->qh_value_len, header->qh_value);
 | 
			
		||||
        st = hset_if->hsi_process_header(hset,
 | 
			
		||||
                    header->qh_flags & QH_ID_SET ?
 | 
			
		||||
                        hpack_static_table_size + 1 + header->qh_static_id : 0,
 | 
			
		||||
                    header->qh_name, header->qh_name_len,
 | 
			
		||||
                    header->qh_value, header->qh_value_len);
 | 
			
		||||
        if (st != LSQUIC_HDR_OK)
 | 
			
		||||
        extra = header->qh_name_len + header->qh_value_len + 4;
 | 
			
		||||
        xhdr = hset_if->hsi_prepare_decode(hset, NULL, extra);
 | 
			
		||||
        if (!xhdr)
 | 
			
		||||
        {
 | 
			
		||||
            LSQ_INFO("header process returned non-OK code %u", (unsigned) st);
 | 
			
		||||
            LSQ_DEBUG("prepare_decode(%zd) failed", extra);
 | 
			
		||||
            goto err;
 | 
			
		||||
        }
 | 
			
		||||
        memcpy(xhdr->buf + xhdr->name_offset, header->qh_name,
 | 
			
		||||
                                                    header->qh_name_len);
 | 
			
		||||
        xhdr->name_len = header->qh_name_len;
 | 
			
		||||
        memcpy(xhdr->buf + xhdr->name_offset + xhdr->name_len, ": ", 2);
 | 
			
		||||
        xhdr->val_offset = xhdr->name_offset + xhdr->name_len + 2;
 | 
			
		||||
        memcpy(xhdr->buf + xhdr->val_offset,
 | 
			
		||||
                                    header->qh_value, header->qh_value_len);
 | 
			
		||||
        xhdr->val_len = header->qh_value_len;
 | 
			
		||||
        memcpy(xhdr->buf + xhdr->name_offset + xhdr->name_len + 2
 | 
			
		||||
                    + xhdr->val_len, "\r\n", 2);
 | 
			
		||||
        xhdr->dec_overhead = 4;
 | 
			
		||||
        if (header->qh_flags & QH_ID_SET)
 | 
			
		||||
        {
 | 
			
		||||
            xhdr->flags |= LSXPACK_QPACK_IDX;
 | 
			
		||||
            xhdr->qpack_index = header->qh_static_id;
 | 
			
		||||
        }
 | 
			
		||||
        st = hset_if->hsi_process_header(hset, xhdr);
 | 
			
		||||
        if (st != 0)
 | 
			
		||||
        {
 | 
			
		||||
            LSQ_INFO("header process returned non-OK code %d", st);
 | 
			
		||||
            goto err;
 | 
			
		||||
        }
 | 
			
		||||
        if (is_content_length(header))
 | 
			
		||||
| 
						 | 
				
			
			@ -488,8 +509,8 @@ qdh_supply_hset_to_stream (struct qpack_dec_hdl *qdh,
 | 
			
		|||
 | 
			
		||||
    lsqpack_dec_destroy_header_list(qlist);
 | 
			
		||||
    qlist = NULL;
 | 
			
		||||
    st = hset_if->hsi_process_header(hset, 0, 0, 0, 0, 0);
 | 
			
		||||
    if (st != LSQUIC_HDR_OK)
 | 
			
		||||
    st = hset_if->hsi_process_header(hset, NULL);
 | 
			
		||||
    if (st != 0)
 | 
			
		||||
        goto err;
 | 
			
		||||
 | 
			
		||||
    uh = calloc(1, sizeof(*uh));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -347,7 +347,7 @@ lsquic_send_ctl_init (lsquic_send_ctl_t *ctl, struct lsquic_alarmset *alset,
 | 
			
		|||
        ctl->sc_ci = &lsquic_cong_cubic_if;
 | 
			
		||||
    ctl->sc_ci->cci_init(CGP(ctl), conn_pub, ctl->sc_retx_frames);
 | 
			
		||||
    if (ctl->sc_flags & SC_PACE)
 | 
			
		||||
        pacer_init(&ctl->sc_pacer, conn_pub->lconn,
 | 
			
		||||
        lsquic_pacer_init(&ctl->sc_pacer, conn_pub->lconn,
 | 
			
		||||
        /* TODO: conn_pub has a pointer to enpub: drop third argument */
 | 
			
		||||
                                    enpub->enp_settings.es_clock_granularity);
 | 
			
		||||
    for (i = 0; i < sizeof(ctl->sc_buffered_packets) /
 | 
			
		||||
| 
						 | 
				
			
			@ -967,7 +967,7 @@ send_ctl_detect_losses (struct lsquic_send_ctl *ctl, enum packnum_space pns,
 | 
			
		|||
            "%"PRIu64, largest_lost_packno, ctl->sc_largest_sent_at_cutback);
 | 
			
		||||
        ctl->sc_ci->cci_loss(CGP(ctl));
 | 
			
		||||
        if (ctl->sc_flags & SC_PACE)
 | 
			
		||||
            pacer_loss_event(&ctl->sc_pacer);
 | 
			
		||||
            lsquic_pacer_loss_event(&ctl->sc_pacer);
 | 
			
		||||
        ctl->sc_largest_sent_at_cutback =
 | 
			
		||||
                                lsquic_senhist_largest(&ctl->sc_senhist);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -1329,7 +1329,7 @@ lsquic_send_ctl_cleanup (lsquic_send_ctl_t *ctl)
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (ctl->sc_flags & SC_PACE)
 | 
			
		||||
        pacer_cleanup(&ctl->sc_pacer);
 | 
			
		||||
        lsquic_pacer_cleanup(&ctl->sc_pacer);
 | 
			
		||||
    ctl->sc_ci->cci_cleanup(CGP(ctl));
 | 
			
		||||
#if LSQUIC_SEND_STATS
 | 
			
		||||
    LSQ_NOTICE("stats: n_total_sent: %u; n_resent: %u; n_delayed: %u",
 | 
			
		||||
| 
						 | 
				
			
			@ -1362,7 +1362,7 @@ int
 | 
			
		|||
lsquic_send_ctl_pacer_blocked (struct lsquic_send_ctl *ctl)
 | 
			
		||||
{
 | 
			
		||||
    return (ctl->sc_flags & SC_PACE)
 | 
			
		||||
        && !pacer_can_schedule(&ctl->sc_pacer,
 | 
			
		||||
        && !lsquic_pacer_can_schedule(&ctl->sc_pacer,
 | 
			
		||||
                               ctl->sc_n_scheduled + ctl->sc_n_in_flight_all);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1383,14 +1383,14 @@ lsquic_send_ctl_can_send (lsquic_send_ctl_t *ctl)
 | 
			
		|||
    {
 | 
			
		||||
        if (n_out >= ctl->sc_ci->cci_get_cwnd(CGP(ctl)))
 | 
			
		||||
            return 0;
 | 
			
		||||
        if (pacer_can_schedule(&ctl->sc_pacer,
 | 
			
		||||
        if (lsquic_pacer_can_schedule(&ctl->sc_pacer,
 | 
			
		||||
                               ctl->sc_n_scheduled + ctl->sc_n_in_flight_all))
 | 
			
		||||
            return 1;
 | 
			
		||||
        if (ctl->sc_flags & SC_SCHED_TICK)
 | 
			
		||||
        {
 | 
			
		||||
            ctl->sc_flags &= ~SC_SCHED_TICK;
 | 
			
		||||
            lsquic_engine_add_conn_to_attq(ctl->sc_enpub,
 | 
			
		||||
                    ctl->sc_conn_pub->lconn, pacer_next_sched(&ctl->sc_pacer),
 | 
			
		||||
                    ctl->sc_conn_pub->lconn, lsquic_pacer_next_sched(&ctl->sc_pacer),
 | 
			
		||||
                    AEW_PACER);
 | 
			
		||||
        }
 | 
			
		||||
        return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -1407,7 +1407,7 @@ send_ctl_could_send (const struct lsquic_send_ctl *ctl)
 | 
			
		|||
    uint64_t cwnd;
 | 
			
		||||
    unsigned n_out;
 | 
			
		||||
 | 
			
		||||
    if ((ctl->sc_flags & SC_PACE) && pacer_delayed(&ctl->sc_pacer))
 | 
			
		||||
    if ((ctl->sc_flags & SC_PACE) && lsquic_pacer_delayed(&ctl->sc_pacer))
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    cwnd = ctl->sc_ci->cci_get_cwnd(CGP(ctl));
 | 
			
		||||
| 
						 | 
				
			
			@ -1557,7 +1557,7 @@ lsquic_send_ctl_scheduled_one (lsquic_send_ctl_t *ctl,
 | 
			
		|||
    if (ctl->sc_flags & SC_PACE)
 | 
			
		||||
    {
 | 
			
		||||
        unsigned n_out = ctl->sc_n_in_flight_retx + ctl->sc_n_scheduled;
 | 
			
		||||
        pacer_packet_scheduled(&ctl->sc_pacer, n_out,
 | 
			
		||||
        lsquic_pacer_packet_scheduled(&ctl->sc_pacer, n_out,
 | 
			
		||||
            send_ctl_in_recovery(ctl), send_ctl_transfer_time, ctl);
 | 
			
		||||
    }
 | 
			
		||||
    send_ctl_sched_append(ctl, packet_out);
 | 
			
		||||
| 
						 | 
				
			
			@ -1624,13 +1624,16 @@ send_ctl_maybe_zero_pad (struct lsquic_send_ctl *ctl,
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    LSQ_DEBUG("cum_size: %zu; limit: %zu", cum_size, limit);
 | 
			
		||||
    assert(cum_size < limit);
 | 
			
		||||
    assert(cum_size <= limit);
 | 
			
		||||
    size = limit - cum_size;
 | 
			
		||||
    if (size > lsquic_packet_out_avail(initial_packet))
 | 
			
		||||
        size = lsquic_packet_out_avail(initial_packet);
 | 
			
		||||
    memset(initial_packet->po_data + initial_packet->po_data_sz, 0, size);
 | 
			
		||||
    initial_packet->po_data_sz += size;
 | 
			
		||||
    initial_packet->po_frame_types |= QUIC_FTBIT_PADDING;
 | 
			
		||||
    if (size)
 | 
			
		||||
    {
 | 
			
		||||
        memset(initial_packet->po_data + initial_packet->po_data_sz, 0, size);
 | 
			
		||||
        initial_packet->po_data_sz += size;
 | 
			
		||||
        initial_packet->po_frame_types |= QUIC_FTBIT_PADDING;
 | 
			
		||||
    }
 | 
			
		||||
    LSQ_DEBUG("Added %zu bytes of PADDING to packet %"PRIu64, size,
 | 
			
		||||
                                                initial_packet->po_packno);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2697,7 +2700,8 @@ strip_trailing_padding (struct lsquic_packet_out *packet_out)
 | 
			
		|||
    unsigned off;
 | 
			
		||||
 | 
			
		||||
    off = 0;
 | 
			
		||||
    for (srec = posi_first(&posi, packet_out); srec; srec = posi_next(&posi))
 | 
			
		||||
    for (srec = lsquic_posi_first(&posi, packet_out); srec;
 | 
			
		||||
                                                srec = lsquic_posi_next(&posi))
 | 
			
		||||
        off = srec->sr_off + srec->sr_len;
 | 
			
		||||
 | 
			
		||||
    assert(off);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -268,20 +268,20 @@ lsquic_send_ctl_drop_scheduled (lsquic_send_ctl_t *);
 | 
			
		|||
    if ((ctl)->sc_flags & SC_PACE)                          \
 | 
			
		||||
    {                                                       \
 | 
			
		||||
        (ctl)->sc_flags |= SC_SCHED_TICK;                   \
 | 
			
		||||
        pacer_tick_in(&(ctl)->sc_pacer, now);               \
 | 
			
		||||
        lsquic_pacer_tick_in(&(ctl)->sc_pacer, now);        \
 | 
			
		||||
    }                                                       \
 | 
			
		||||
    (ctl)->sc_flags &= ~SC_APP_LIMITED;                     \
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
#define lsquic_send_ctl_tick_out(ctl) do {                  \
 | 
			
		||||
    if ((ctl)->sc_flags & SC_PACE)                          \
 | 
			
		||||
        pacer_tick_out(&(ctl)->sc_pacer);                   \
 | 
			
		||||
        lsquic_pacer_tick_out(&(ctl)->sc_pacer);            \
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
#define lsquic_send_ctl_next_pacer_time(ctl) (              \
 | 
			
		||||
    ((ctl)->sc_flags & SC_PACE)                             \
 | 
			
		||||
        && pacer_delayed(&(ctl)->sc_pacer)                  \
 | 
			
		||||
        ? pacer_next_sched(&(ctl)->sc_pacer)                \
 | 
			
		||||
        && lsquic_pacer_delayed(&(ctl)->sc_pacer)           \
 | 
			
		||||
        ? lsquic_pacer_next_sched(&(ctl)->sc_pacer)         \
 | 
			
		||||
        : 0 )
 | 
			
		||||
 | 
			
		||||
enum packno_bits
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -155,7 +155,7 @@ stock_shi_delete (void *hash_ctx, const void *key, unsigned key_sz)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
struct stock_shared_hash *
 | 
			
		||||
stock_shared_hash_new (void)
 | 
			
		||||
lsquic_stock_shared_hash_new (void)
 | 
			
		||||
{
 | 
			
		||||
    struct malo *malo;
 | 
			
		||||
    struct stock_shared_hash *hash;
 | 
			
		||||
| 
						 | 
				
			
			@ -179,7 +179,7 @@ stock_shared_hash_new (void)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
stock_shared_hash_destroy (struct stock_shared_hash *hash)
 | 
			
		||||
lsquic_stock_shared_hash_destroy (struct stock_shared_hash *hash)
 | 
			
		||||
{
 | 
			
		||||
    struct hash_elem *he;
 | 
			
		||||
    struct lsquic_hash_elem *el;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,10 +15,10 @@ extern "C" {
 | 
			
		|||
struct stock_shared_hash;
 | 
			
		||||
 | 
			
		||||
struct stock_shared_hash *
 | 
			
		||||
stock_shared_hash_new (void);
 | 
			
		||||
lsquic_stock_shared_hash_new (void);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
stock_shared_hash_destroy (struct stock_shared_hash *);
 | 
			
		||||
lsquic_stock_shared_hash_destroy (struct stock_shared_hash *);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -348,9 +348,9 @@ stream_new_common (lsquic_stream_id_t id, struct lsquic_conn_public *conn_pub,
 | 
			
		|||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    if (ctor_flags & SCF_USE_DI_HASH)
 | 
			
		||||
        stream->data_in = data_in_hash_new(conn_pub, id, 0);
 | 
			
		||||
        stream->data_in = lsquic_data_in_hash_new(conn_pub, id, 0);
 | 
			
		||||
    else
 | 
			
		||||
        stream->data_in = data_in_nocopy_new(conn_pub, id);
 | 
			
		||||
        stream->data_in = lsquic_data_in_nocopy_new(conn_pub, id);
 | 
			
		||||
    if (!stream->data_in)
 | 
			
		||||
    {
 | 
			
		||||
        free(stream);
 | 
			
		||||
| 
						 | 
				
			
			@ -947,7 +947,7 @@ lsquic_stream_frame_in (lsquic_stream_t *stream, stream_frame_t *frame)
 | 
			
		|||
                                        stream->data_in, stream->read_offset);
 | 
			
		||||
            if (!stream->data_in)
 | 
			
		||||
            {
 | 
			
		||||
                stream->data_in = data_in_error_new();
 | 
			
		||||
                stream->data_in = lsquic_data_in_error_new();
 | 
			
		||||
                goto end_ok;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -972,7 +972,7 @@ lsquic_stream_frame_in (lsquic_stream_t *stream, stream_frame_t *frame)
 | 
			
		|||
                                    stream->data_in, stream->read_offset);
 | 
			
		||||
        if (stream->data_in)
 | 
			
		||||
            goto insert_frame;
 | 
			
		||||
        stream->data_in = data_in_error_new();
 | 
			
		||||
        stream->data_in = lsquic_data_in_error_new();
 | 
			
		||||
        lsquic_packet_in_put(stream->conn_pub->mm, frame->packet_in);
 | 
			
		||||
        lsquic_malo_put(frame);
 | 
			
		||||
        return -1;
 | 
			
		||||
| 
						 | 
				
			
			@ -995,7 +995,7 @@ drop_frames_in (lsquic_stream_t *stream)
 | 
			
		|||
         * data-in stream.  It does the right thing after incoming data is
 | 
			
		||||
         * dropped.
 | 
			
		||||
         */
 | 
			
		||||
        stream->data_in = data_in_error_new();
 | 
			
		||||
        stream->data_in = lsquic_data_in_error_new();
 | 
			
		||||
        stream->stream_flags &= ~STREAM_CACHED_FRAME;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1334,7 +1334,7 @@ read_data_frames (struct lsquic_stream *stream, int do_filtering,
 | 
			
		|||
                                                stream->data_in, stream->read_offset);
 | 
			
		||||
                    if (!stream->data_in)
 | 
			
		||||
                    {
 | 
			
		||||
                        stream->data_in = data_in_error_new();
 | 
			
		||||
                        stream->data_in = lsquic_data_in_error_new();
 | 
			
		||||
                        return (struct read_frames_status) { .error = 1, };
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -2468,7 +2468,7 @@ incr_conn_cap (struct lsquic_stream *stream, size_t incr)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
static void
 | 
			
		||||
incr_sm_payload (struct lsquic_stream *stream, size_t incr)
 | 
			
		||||
{
 | 
			
		||||
    stream->sm_payload += incr;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -125,7 +125,8 @@ lsquic_is_zero (const void *pbuf, size_t bufsz)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
/* XXX this function uses static buffer.  Replace it with lsquic_hexdump() if possible */
 | 
			
		||||
char *get_bin_str(const void *s, size_t len, size_t max_display_len)
 | 
			
		||||
char *
 | 
			
		||||
lsquic_get_bin_str (const void *s, size_t len, size_t max_display_len)
 | 
			
		||||
{
 | 
			
		||||
    const unsigned char *p, *pEnd;
 | 
			
		||||
    char *pOutput; 
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,7 +25,8 @@ lsquic_is_zero (const void *buf, size_t bufsz);
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
char * get_bin_str(const void *s, size_t len, size_t max_display_len);
 | 
			
		||||
char *
 | 
			
		||||
lsquic_get_bin_str (const void *s, size_t len, size_t max_display_len);
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
lsquic_hex_encode (const void *src, size_t src_sz, void *dst, size_t dst_sz);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								src/lshpack
									
										
									
									
									
										Submodule
									
								
							
							
						
						
									
										1
									
								
								src/lshpack
									
										
									
									
									
										Submodule
									
								
							| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
Subproject commit 226eedeb9077c1f8b4c6eeb580c7989d458d1268
 | 
			
		||||
							
								
								
									
										72303
									
								
								src/lshpack/lshpack.c
									
										
									
									
									
								
							
							
						
						
									
										72303
									
								
								src/lshpack/lshpack.c
									
										
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -1,290 +0,0 @@
 | 
			
		|||
/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc.  See LICENSE. */
 | 
			
		||||
/*
 | 
			
		||||
MIT License
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2018 LiteSpeed Technologies Inc
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
in the Software without restriction, including without limitation the rights
 | 
			
		||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
furnished to do so, subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
SOFTWARE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef LITESPEED_HPACK_H
 | 
			
		||||
#define LITESPEED_HPACK_H 1
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
#include <sys/uio.h>
 | 
			
		||||
#else
 | 
			
		||||
#include "vc_compat.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/** Maximum length is defined for convenience */
 | 
			
		||||
#define LSHPACK_MAX_STRLEN UINT_MAX
 | 
			
		||||
 | 
			
		||||
struct lshpack_enc;
 | 
			
		||||
struct lshpack_dec;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @typedef lshpack_http_header_t
 | 
			
		||||
 * @brief HTTP header structure. Contains header name and value.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
typedef struct lshpack_header
 | 
			
		||||
{
 | 
			
		||||
   struct iovec name;
 | 
			
		||||
   struct iovec value;
 | 
			
		||||
} lshpack_header_t;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
enum lshpack_static_hdr_idx
 | 
			
		||||
{
 | 
			
		||||
    LSHPACK_HDR_UNKNOWN,
 | 
			
		||||
    LSHPACK_HDR_AUTHORITY,
 | 
			
		||||
    LSHPACK_HDR_METHOD_GET,
 | 
			
		||||
    LSHPACK_HDR_METHOD_POST,
 | 
			
		||||
    LSHPACK_HDR_PATH,
 | 
			
		||||
    LSHPACK_HDR_PATH_INDEX_HTML,
 | 
			
		||||
    LSHPACK_HDR_SCHEME_HTTP,
 | 
			
		||||
    LSHPACK_HDR_SCHEME_HTTPS,
 | 
			
		||||
    LSHPACK_HDR_STATUS_200,
 | 
			
		||||
    LSHPACK_HDR_STATUS_204,
 | 
			
		||||
    LSHPACK_HDR_STATUS_206,
 | 
			
		||||
    LSHPACK_HDR_STATUS_304,
 | 
			
		||||
    LSHPACK_HDR_STATUS_400,
 | 
			
		||||
    LSHPACK_HDR_STATUS_404,
 | 
			
		||||
    LSHPACK_HDR_STATUS_500,
 | 
			
		||||
    LSHPACK_HDR_ACCEPT_CHARSET,
 | 
			
		||||
    LSHPACK_HDR_ACCEPT_ENCODING,
 | 
			
		||||
    LSHPACK_HDR_ACCEPT_LANGUAGE,
 | 
			
		||||
    LSHPACK_HDR_ACCEPT_RANGES,
 | 
			
		||||
    LSHPACK_HDR_ACCEPT,
 | 
			
		||||
    LSHPACK_HDR_ACCESS_CONTROL_ALLOW_ORIGIN,
 | 
			
		||||
    LSHPACK_HDR_AGE,
 | 
			
		||||
    LSHPACK_HDR_ALLOW,
 | 
			
		||||
    LSHPACK_HDR_AUTHORIZATION,
 | 
			
		||||
    LSHPACK_HDR_CACHE_CONTROL,
 | 
			
		||||
    LSHPACK_HDR_CONTENT_DISPOSITION,
 | 
			
		||||
    LSHPACK_HDR_CONTENT_ENCODING,
 | 
			
		||||
    LSHPACK_HDR_CONTENT_LANGUAGE,
 | 
			
		||||
    LSHPACK_HDR_CONTENT_LENGTH,
 | 
			
		||||
    LSHPACK_HDR_CONTENT_LOCATION,
 | 
			
		||||
    LSHPACK_HDR_CONTENT_RANGE,
 | 
			
		||||
    LSHPACK_HDR_CONTENT_TYPE,
 | 
			
		||||
    LSHPACK_HDR_COOKIE,
 | 
			
		||||
    LSHPACK_HDR_DATE,
 | 
			
		||||
    LSHPACK_HDR_ETAG,
 | 
			
		||||
    LSHPACK_HDR_EXPECT,
 | 
			
		||||
    LSHPACK_HDR_EXPIRES,
 | 
			
		||||
    LSHPACK_HDR_FROM,
 | 
			
		||||
    LSHPACK_HDR_HOST,
 | 
			
		||||
    LSHPACK_HDR_IF_MATCH,
 | 
			
		||||
    LSHPACK_HDR_IF_MODIFIED_SINCE,
 | 
			
		||||
    LSHPACK_HDR_IF_NONE_MATCH,
 | 
			
		||||
    LSHPACK_HDR_IF_RANGE,
 | 
			
		||||
    LSHPACK_HDR_IF_UNMODIFIED_SINCE,
 | 
			
		||||
    LSHPACK_HDR_LAST_MODIFIED,
 | 
			
		||||
    LSHPACK_HDR_LINK,
 | 
			
		||||
    LSHPACK_HDR_LOCATION,
 | 
			
		||||
    LSHPACK_HDR_MAX_FORWARDS,
 | 
			
		||||
    LSHPACK_HDR_PROXY_AUTHENTICATE,
 | 
			
		||||
    LSHPACK_HDR_PROXY_AUTHORIZATION,
 | 
			
		||||
    LSHPACK_HDR_RANGE,
 | 
			
		||||
    LSHPACK_HDR_REFERER,
 | 
			
		||||
    LSHPACK_HDR_REFRESH,
 | 
			
		||||
    LSHPACK_HDR_RETRY_AFTER,
 | 
			
		||||
    LSHPACK_HDR_SERVER,
 | 
			
		||||
    LSHPACK_HDR_SET_COOKIE,
 | 
			
		||||
    LSHPACK_HDR_STRICT_TRANSPORT_SECURITY,
 | 
			
		||||
    LSHPACK_HDR_TRANSFER_ENCODING,
 | 
			
		||||
    LSHPACK_HDR_USER_AGENT,
 | 
			
		||||
    LSHPACK_HDR_VARY,
 | 
			
		||||
    LSHPACK_HDR_VIA,
 | 
			
		||||
    LSHPACK_HDR_WWW_AUTHENTICATE
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Initialization routine allocates memory.  -1 is returned if memory
 | 
			
		||||
 * could not be allocated.  0 is returned on success.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
lshpack_enc_init (struct lshpack_enc *);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Clean up HPACK encoder, freeing all allocated memory.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
lshpack_enc_cleanup (struct lshpack_enc *);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Encode one name/value pair
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in,out] henc - A pointer to a valid HPACK API struct
 | 
			
		||||
 * @param[out] dst - A pointer to destination buffer
 | 
			
		||||
 * @param[out] dst_end - A pointer to end of destination buffer
 | 
			
		||||
 * @param[in] name - A pointer to the item name
 | 
			
		||||
 * @param[in] name_len - The item name's length
 | 
			
		||||
 * @param[in] value - A pointer to the item value
 | 
			
		||||
 * @param[in] value_len - The item value's length
 | 
			
		||||
 * @param[in] indexed_type - 0, Add, 1,: without, 2: never
 | 
			
		||||
 *
 | 
			
		||||
 * @return The (possibly advanced) dst pointer.  If the destination
 | 
			
		||||
 * pointer was not advanced, an error must have occurred.
 | 
			
		||||
 */
 | 
			
		||||
unsigned char *
 | 
			
		||||
lshpack_enc_encode2 (struct lshpack_enc *henc, unsigned char *dst,
 | 
			
		||||
    unsigned char *dst_end, const char *name, unsigned name_len,
 | 
			
		||||
    const char *value, unsigned value_len, int indexed_type);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Encode one name/value pair
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in,out] henc - A pointer to a valid HPACK API struct
 | 
			
		||||
 * @param[out] dst - A pointer to destination buffer
 | 
			
		||||
 * @param[out] dst_end - A pointer to end of destination buffer
 | 
			
		||||
 * @param[in] hpack_idx - The position of header name in static table,
 | 
			
		||||
 *              0 = unknown, < 0 not in static table, 1 - 63 the position
 | 
			
		||||
 * @param[in] hdr - the header name and value
 | 
			
		||||
 * @param[in] indexed_type - 0, Add, 1,: without, 2: never
 | 
			
		||||
 *
 | 
			
		||||
 * @return The (possibly advanced) dst pointer.  If the destination
 | 
			
		||||
 * pointer was not advanced, an error must have occurred.
 | 
			
		||||
 */
 | 
			
		||||
unsigned char *
 | 
			
		||||
lshpack_enc_encode (struct lshpack_enc *henc, unsigned char *dst,
 | 
			
		||||
                     unsigned char *dst_end, int hpack_idx,
 | 
			
		||||
                     const lshpack_header_t *hdr, int indexed_type);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
lshpack_enc_set_max_capacity (struct lshpack_enc *, unsigned);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Turn history on or off.  Turning history on may fail (malloc), in
 | 
			
		||||
 * which case -1 is returned.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
lshpack_enc_use_hist (struct lshpack_enc *, int on);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Return true if history is used, false otherwise.  By default,
 | 
			
		||||
 * history is off.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
lshpack_enc_hist_used (const struct lshpack_enc *);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Initialize HPACK decoder structure.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
lshpack_dec_init (struct lshpack_dec *);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Clean up HPACK decoder structure, freeing all allocated memory.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
lshpack_dec_cleanup (struct lshpack_dec *);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Returns 0 on success, a negative value on failure.
 | 
			
		||||
 *
 | 
			
		||||
 * If 0 is returned, `src' is advanced.  Calling with a zero-length input
 | 
			
		||||
 * buffer results in an error.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
lshpack_dec_decode (struct lshpack_dec *dec,
 | 
			
		||||
    const unsigned char **src, const unsigned char *src_end,
 | 
			
		||||
    char *dst, char *const dst_end, unsigned *name_len,
 | 
			
		||||
    unsigned *val_len, uint32_t *name_idx);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
lshpack_dec_set_max_capacity (struct lshpack_dec *, unsigned);
 | 
			
		||||
 | 
			
		||||
/* Some internals follow.  Struct definitions are exposed to save a malloc.
 | 
			
		||||
 * These structures are not very complicated.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/queue.h>
 | 
			
		||||
 | 
			
		||||
struct lshpack_enc_table_entry;
 | 
			
		||||
 | 
			
		||||
STAILQ_HEAD(lshpack_enc_head, lshpack_enc_table_entry);
 | 
			
		||||
struct lshpack_double_enc_head;
 | 
			
		||||
 | 
			
		||||
struct lshpack_enc
 | 
			
		||||
{
 | 
			
		||||
    unsigned            hpe_cur_capacity;
 | 
			
		||||
    unsigned            hpe_max_capacity;
 | 
			
		||||
 | 
			
		||||
    /* Each new dynamic table entry gets the next number.  It is used to
 | 
			
		||||
     * calculate the entry's position in the decoder table without having
 | 
			
		||||
     * to maintain an actual array.
 | 
			
		||||
     */
 | 
			
		||||
    unsigned            hpe_next_id;
 | 
			
		||||
 | 
			
		||||
    /* Dynamic table entries (struct enc_table_entry) live in two hash
 | 
			
		||||
     * tables: name/value hash table and name hash table.  These tables
 | 
			
		||||
     * are the same size.
 | 
			
		||||
     */
 | 
			
		||||
    unsigned            hpe_nelem;
 | 
			
		||||
    unsigned            hpe_nbits;
 | 
			
		||||
    struct lshpack_enc_head
 | 
			
		||||
                        hpe_all_entries;
 | 
			
		||||
    struct lshpack_double_enc_head
 | 
			
		||||
                       *hpe_buckets;
 | 
			
		||||
 | 
			
		||||
    uint32_t           *hpe_hist_buf;
 | 
			
		||||
    unsigned            hpe_hist_size, hpe_hist_idx;
 | 
			
		||||
    int                 hpe_hist_wrapped;
 | 
			
		||||
    enum {
 | 
			
		||||
        LSHPACK_ENC_USE_HIST    = 1 << 0,
 | 
			
		||||
    }                   hpe_flags;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct lshpack_arr
 | 
			
		||||
{
 | 
			
		||||
    unsigned        nalloc,
 | 
			
		||||
                    nelem,
 | 
			
		||||
                    off;
 | 
			
		||||
    uintptr_t      *els;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct lshpack_dec
 | 
			
		||||
{
 | 
			
		||||
    unsigned           hpd_max_capacity;       /* Maximum set by caller */
 | 
			
		||||
    unsigned           hpd_cur_max_capacity;   /* Adjusted at runtime */
 | 
			
		||||
    unsigned           hpd_cur_capacity;
 | 
			
		||||
    struct lshpack_arr hpd_dyn_table;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
unsigned
 | 
			
		||||
lshpack_enc_get_stx_tab_id (const char *name, unsigned name_len,
 | 
			
		||||
                                const char *val, unsigned val_len);
 | 
			
		||||
 | 
			
		||||
typedef unsigned lshpack_strlen_t;  /* Compatibility */
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -53,6 +53,7 @@
 | 
			
		|||
#include "../src/liblsquic/lsquic_stream.h"
 | 
			
		||||
/* include directly for retire_cid testing */
 | 
			
		||||
#include "../src/liblsquic/lsquic_conn.h"
 | 
			
		||||
#include "lsxpack_header.h"
 | 
			
		||||
 | 
			
		||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -218,9 +219,9 @@ struct lsquic_conn_ctx {
 | 
			
		|||
struct hset_elem
 | 
			
		||||
{
 | 
			
		||||
    STAILQ_ENTRY(hset_elem)     next;
 | 
			
		||||
    unsigned                    name_idx;
 | 
			
		||||
    char                       *name;
 | 
			
		||||
    char                       *value;
 | 
			
		||||
    struct lsxpack_header       xhdr;
 | 
			
		||||
    size_t                      nalloc;
 | 
			
		||||
    char                       *buf;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -997,42 +998,77 @@ hset_create (void *hsi_ctx, int is_push_promise)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static enum lsquic_header_status
 | 
			
		||||
hset_add_header (void *hset_p, unsigned name_idx,
 | 
			
		||||
                 const char *name, unsigned name_len,
 | 
			
		||||
                 const char *value, unsigned value_len)
 | 
			
		||||
static struct lsxpack_header *
 | 
			
		||||
hset_prepare_decode (void *hset_p, struct lsxpack_header *xhdr,
 | 
			
		||||
                                                        size_t extra_space)
 | 
			
		||||
{
 | 
			
		||||
    struct hset *hset = hset_p;
 | 
			
		||||
    struct hset *const hset = hset_p;
 | 
			
		||||
    struct hset_elem *el;
 | 
			
		||||
    size_t min_space;
 | 
			
		||||
 | 
			
		||||
    if (name)
 | 
			
		||||
    if (0 == extra_space)
 | 
			
		||||
        min_space = 0x100;
 | 
			
		||||
    else
 | 
			
		||||
        min_space = extra_space;
 | 
			
		||||
 | 
			
		||||
    if (xhdr)
 | 
			
		||||
        min_space += xhdr->val_len;
 | 
			
		||||
 | 
			
		||||
    if (min_space > LSXPACK_MAX_STRLEN)
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_WARN("requested space for header is too large: %zd bytes",
 | 
			
		||||
                                                                    min_space);
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!xhdr)
 | 
			
		||||
    {
 | 
			
		||||
        el = malloc(sizeof(*el));
 | 
			
		||||
        if (!el)
 | 
			
		||||
        {
 | 
			
		||||
            LSQ_WARN("cannot allocate hset_elem");
 | 
			
		||||
            return NULL;
 | 
			
		||||
        }
 | 
			
		||||
        STAILQ_INSERT_TAIL(hset, el, next);
 | 
			
		||||
        el->buf = NULL;
 | 
			
		||||
        el->nalloc = 0;
 | 
			
		||||
        xhdr = &el->xhdr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (min_space > el->nalloc)
 | 
			
		||||
    {
 | 
			
		||||
        free(el->buf);
 | 
			
		||||
        el->nalloc = 0;
 | 
			
		||||
        el->buf = malloc(min_space);
 | 
			
		||||
        if (!el->buf)
 | 
			
		||||
        {
 | 
			
		||||
            LSQ_DEBUG("cannot allocate %zd bytes", min_space);
 | 
			
		||||
            return NULL;
 | 
			
		||||
        }
 | 
			
		||||
        el->nalloc = min_space;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    lsxpack_header_prepare_decode(&el->xhdr, el->buf, 0, el->nalloc);
 | 
			
		||||
    return &el->xhdr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
hset_add_header (void *hset_p, struct lsxpack_header *xhdr)
 | 
			
		||||
{
 | 
			
		||||
    unsigned name_len, value_len;
 | 
			
		||||
    /* Not much to do: the header value are in xhdr */
 | 
			
		||||
 | 
			
		||||
    if (xhdr)
 | 
			
		||||
    {
 | 
			
		||||
        name_len = xhdr->name_len;
 | 
			
		||||
        value_len = xhdr->val_len;
 | 
			
		||||
        s_stat_downloaded_bytes += name_len + value_len + 4;    /* ": \r\n" */
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
        s_stat_downloaded_bytes += 2;   /* \r\n "*/
 | 
			
		||||
 | 
			
		||||
    if (s_discard_response)
 | 
			
		||||
        return LSQUIC_HDR_OK;
 | 
			
		||||
 | 
			
		||||
    if (!name)  /* This signals end of headers.  We do no post-processing. */
 | 
			
		||||
        return LSQUIC_HDR_OK;
 | 
			
		||||
 | 
			
		||||
    el = malloc(sizeof(*el));
 | 
			
		||||
    if (!el)
 | 
			
		||||
        return LSQUIC_HDR_ERR_NOMEM;
 | 
			
		||||
 | 
			
		||||
    el->name = strndup(name, name_len);
 | 
			
		||||
    el->value = strndup(value, value_len);
 | 
			
		||||
    if (!(el->name && el->value))
 | 
			
		||||
    {
 | 
			
		||||
        free(el->name);
 | 
			
		||||
        free(el->value);
 | 
			
		||||
        free(el);
 | 
			
		||||
        return LSQUIC_HDR_ERR_NOMEM;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    el->name_idx = name_idx;
 | 
			
		||||
    STAILQ_INSERT_TAIL(hset, el, next);
 | 
			
		||||
    return LSQUIC_HDR_OK;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1047,8 +1083,7 @@ hset_destroy (void *hset_p)
 | 
			
		|||
        for (el = STAILQ_FIRST(hset); el; el = next)
 | 
			
		||||
        {
 | 
			
		||||
            next = STAILQ_NEXT(el, next);
 | 
			
		||||
            free(el->name);
 | 
			
		||||
            free(el->value);
 | 
			
		||||
            free(el->buf);
 | 
			
		||||
            free(el);
 | 
			
		||||
        }
 | 
			
		||||
        free(hset);
 | 
			
		||||
| 
						 | 
				
			
			@ -1062,11 +1097,17 @@ hset_dump (const struct hset *hset, FILE *out)
 | 
			
		|||
    const struct hset_elem *el;
 | 
			
		||||
 | 
			
		||||
    STAILQ_FOREACH(el, hset, next)
 | 
			
		||||
        if (el->name_idx)
 | 
			
		||||
            fprintf(out, "%s (static table idx %u): %s\n", el->name,
 | 
			
		||||
                                                    el->name_idx, el->value);
 | 
			
		||||
        if (el->xhdr.flags & (LSXPACK_HPACK_IDX|LSXPACK_QPACK_IDX))
 | 
			
		||||
            fprintf(out, "%.*s (%s static table idx %u): %.*s\n",
 | 
			
		||||
                (int) el->xhdr.name_len, lsxpack_header_get_name(&el->xhdr),
 | 
			
		||||
                el->xhdr.flags & LSXPACK_HPACK_IDX ? "hpack" : "qpack",
 | 
			
		||||
                el->xhdr.flags & LSXPACK_HPACK_IDX ? el->xhdr.hpack_index
 | 
			
		||||
                                                    : el->xhdr.qpack_index,
 | 
			
		||||
                (int) el->xhdr.val_len, lsxpack_header_get_value(&el->xhdr));
 | 
			
		||||
        else
 | 
			
		||||
            fprintf(out, "%s: %s\n", el->name, el->value);
 | 
			
		||||
            fprintf(out, "%.*s: %.*s\n",
 | 
			
		||||
                (int) el->xhdr.name_len, lsxpack_header_get_name(&el->xhdr),
 | 
			
		||||
                (int) el->xhdr.val_len, lsxpack_header_get_value(&el->xhdr));
 | 
			
		||||
 | 
			
		||||
    fprintf(out, "\n");
 | 
			
		||||
    fflush(out);
 | 
			
		||||
| 
						 | 
				
			
			@ -1080,6 +1121,7 @@ hset_dump (const struct hset *hset, FILE *out)
 | 
			
		|||
static const struct lsquic_hset_if header_bypass_api =
 | 
			
		||||
{
 | 
			
		||||
    .hsi_create_header_set  = hset_create,
 | 
			
		||||
    .hsi_prepare_decode     = hset_prepare_decode,
 | 
			
		||||
    .hsi_process_header     = hset_add_header,
 | 
			
		||||
    .hsi_discard_header_set = hset_destroy,
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,6 +24,7 @@
 | 
			
		|||
#include <openssl/md5.h>
 | 
			
		||||
 | 
			
		||||
#include "lsquic.h"
 | 
			
		||||
#include "lsxpack_header.h"
 | 
			
		||||
#include "test_config.h"
 | 
			
		||||
#include "test_common.h"
 | 
			
		||||
#include "prog.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -162,11 +163,18 @@ struct req
 | 
			
		|||
    enum method {
 | 
			
		||||
        UNSET, GET, POST, UNSUPPORTED,
 | 
			
		||||
    }            method;
 | 
			
		||||
    enum {
 | 
			
		||||
        HAVE_XHDR   = 1 << 0,
 | 
			
		||||
    }            flags;
 | 
			
		||||
    char        *path;
 | 
			
		||||
    char        *method_str;
 | 
			
		||||
    char        *authority_str;
 | 
			
		||||
    char        *qif_str;
 | 
			
		||||
    size_t       qif_sz;
 | 
			
		||||
    struct lsxpack_header
 | 
			
		||||
                 xhdr;
 | 
			
		||||
    size_t       decode_off;
 | 
			
		||||
    char         decode_buf[MIN(LSXPACK_MAX_STRLEN + 1, 64 * 1024)];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1167,70 +1175,101 @@ usage (const char *prog)
 | 
			
		|||
static void *
 | 
			
		||||
interop_server_hset_create (void *hsi_ctx, int is_push_promise)
 | 
			
		||||
{
 | 
			
		||||
    return calloc(1, sizeof(struct req));
 | 
			
		||||
    struct req *req;
 | 
			
		||||
 | 
			
		||||
    req = malloc(sizeof(struct req));
 | 
			
		||||
    memset(req, 0, offsetof(struct req, decode_buf));
 | 
			
		||||
 | 
			
		||||
    return req;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static enum lsquic_header_status
 | 
			
		||||
interop_server_hset_add_header (void *hset_p, unsigned name_idx,
 | 
			
		||||
                 const char *name, unsigned name_len,
 | 
			
		||||
                 const char *value, unsigned value_len)
 | 
			
		||||
static struct lsxpack_header *
 | 
			
		||||
interop_server_hset_prepare_decode (void *hset_p, struct lsxpack_header *xhdr,
 | 
			
		||||
                                                            size_t extra_space)
 | 
			
		||||
{
 | 
			
		||||
    struct req *req = hset_p;
 | 
			
		||||
 | 
			
		||||
    if (name)
 | 
			
		||||
    if (xhdr)
 | 
			
		||||
    {
 | 
			
		||||
        req->qif_str = realloc(req->qif_str,
 | 
			
		||||
                            req->qif_sz + name_len + value_len + 2);
 | 
			
		||||
        if (!req->qif_str)
 | 
			
		||||
        {
 | 
			
		||||
            LSQ_ERROR("malloc failed");
 | 
			
		||||
            return LSQUIC_HDR_ERR_NOMEM;
 | 
			
		||||
        }
 | 
			
		||||
        memcpy(req->qif_str + req->qif_sz, name, name_len);
 | 
			
		||||
        req->qif_str[req->qif_sz + name_len] = '\t';
 | 
			
		||||
        memcpy(req->qif_str + req->qif_sz + name_len + 1, value, value_len);
 | 
			
		||||
        req->qif_str[req->qif_sz + name_len + 1 + value_len] = '\n';
 | 
			
		||||
        req->qif_sz += name_len + value_len + 2;
 | 
			
		||||
        LSQ_WARN("we don't reallocate headers: can't give more");
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (req->flags & HAVE_XHDR)
 | 
			
		||||
        req->decode_off += lsxpack_header_get_dec_size(&req->xhdr);
 | 
			
		||||
    else
 | 
			
		||||
        return LSQUIC_HDR_OK;
 | 
			
		||||
        req->flags |= HAVE_XHDR;
 | 
			
		||||
 | 
			
		||||
    lsxpack_header_prepare_decode(&req->xhdr, req->decode_buf,
 | 
			
		||||
                                        req->decode_off, sizeof(req->decode_buf));
 | 
			
		||||
    return &req->xhdr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
interop_server_hset_add_header (void *hset_p, struct lsxpack_header *xhdr)
 | 
			
		||||
{
 | 
			
		||||
    struct req *req = hset_p;
 | 
			
		||||
    const char *name, *value;
 | 
			
		||||
    unsigned name_len, value_len;
 | 
			
		||||
 | 
			
		||||
    if (!xhdr)
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    name = lsxpack_header_get_name(xhdr);
 | 
			
		||||
    value = lsxpack_header_get_value(xhdr);
 | 
			
		||||
    name_len = xhdr->name_len;
 | 
			
		||||
    value_len = xhdr->val_len;
 | 
			
		||||
 | 
			
		||||
    req->qif_str = realloc(req->qif_str,
 | 
			
		||||
                        req->qif_sz + name_len + value_len + 2);
 | 
			
		||||
    if (!req->qif_str)
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_ERROR("malloc failed");
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
    memcpy(req->qif_str + req->qif_sz, name, name_len);
 | 
			
		||||
    req->qif_str[req->qif_sz + name_len] = '\t';
 | 
			
		||||
    memcpy(req->qif_str + req->qif_sz + name_len + 1, value, value_len);
 | 
			
		||||
    req->qif_str[req->qif_sz + name_len + 1 + value_len] = '\n';
 | 
			
		||||
    req->qif_sz += name_len + value_len + 2;
 | 
			
		||||
 | 
			
		||||
    if (5 == name_len && 0 == strncmp(name, ":path", 5))
 | 
			
		||||
    {
 | 
			
		||||
        if (req->path)
 | 
			
		||||
            return LSQUIC_HDR_ERR_DUPLICATE_PSDO_HDR;
 | 
			
		||||
            return 1;
 | 
			
		||||
        req->path = strndup(value, value_len);
 | 
			
		||||
        if (!req->path)
 | 
			
		||||
            return LSQUIC_HDR_ERR_NOMEM;
 | 
			
		||||
        return LSQUIC_HDR_OK;
 | 
			
		||||
            return -1;
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (7 == name_len && 0 == strncmp(name, ":method", 7))
 | 
			
		||||
    {
 | 
			
		||||
        if (req->method != UNSET)
 | 
			
		||||
            return LSQUIC_HDR_ERR_DUPLICATE_PSDO_HDR;
 | 
			
		||||
            return 1;
 | 
			
		||||
        req->method_str = strndup(value, value_len);
 | 
			
		||||
        if (!req->method_str)
 | 
			
		||||
            return LSQUIC_HDR_ERR_NOMEM;
 | 
			
		||||
            return -1;
 | 
			
		||||
        if (0 == strcmp(req->method_str, "GET"))
 | 
			
		||||
            req->method = GET;
 | 
			
		||||
        else if (0 == strcmp(req->method_str, "POST"))
 | 
			
		||||
            req->method = POST;
 | 
			
		||||
        else
 | 
			
		||||
            req->method = UNSUPPORTED;
 | 
			
		||||
        return LSQUIC_HDR_OK;
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (10 == name_len && 0 == strncmp(name, ":authority", 10))
 | 
			
		||||
    {
 | 
			
		||||
        req->authority_str = strndup(value, value_len);
 | 
			
		||||
        if (!req->authority_str)
 | 
			
		||||
            return LSQUIC_HDR_ERR_NOMEM;
 | 
			
		||||
        return LSQUIC_HDR_OK;
 | 
			
		||||
            return -1;
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return LSQUIC_HDR_OK;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1249,6 +1288,7 @@ interop_server_hset_destroy (void *hset_p)
 | 
			
		|||
static const struct lsquic_hset_if header_bypass_api =
 | 
			
		||||
{
 | 
			
		||||
    .hsi_create_header_set  = interop_server_hset_create,
 | 
			
		||||
    .hsi_prepare_decode     = interop_server_hset_prepare_decode,
 | 
			
		||||
    .hsi_process_header     = interop_server_hset_add_header,
 | 
			
		||||
    .hsi_discard_header_set = interop_server_hset_destroy,
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -104,7 +104,7 @@ main (int argc, char **argv)
 | 
			
		|||
    packet_in.pi_data = buf;
 | 
			
		||||
    packet_in.pi_refcnt = 1;
 | 
			
		||||
 | 
			
		||||
    lconn = mini_conn_new(&enpub, &packet_in, ver);
 | 
			
		||||
    lconn = lsquic_mini_conn_new(&enpub, &packet_in, ver);
 | 
			
		||||
    lconn->cn_if->ci_packet_in(lconn, &packet_in);
 | 
			
		||||
 | 
			
		||||
    exit(EXIT_SUCCESS);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -78,18 +78,18 @@ test_attq_ordering (enum sort_action sa)
 | 
			
		|||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    q = attq_create();
 | 
			
		||||
    q = lsquic_attq_create();
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < sizeof(curiosity); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        unsigned count_before = attq_count_before(q, curiosity[i]);
 | 
			
		||||
        unsigned count_before = lsquic_attq_count_before(q, curiosity[i]);
 | 
			
		||||
        assert(count_before == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    conns = calloc(sizeof(curiosity), sizeof(conns[0]));
 | 
			
		||||
    for (i = 0; i < sizeof(curiosity); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        s = attq_add(q, &conns[i], (lsquic_time_t) curiosity[i], 0);
 | 
			
		||||
        s = lsquic_attq_add(q, &conns[i], (lsquic_time_t) curiosity[i], 0);
 | 
			
		||||
        assert(s == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -110,30 +110,30 @@ test_attq_ordering (enum sort_action sa)
 | 
			
		|||
        }
 | 
			
		||||
        for (i = 1; i < sizeof(curiosity); ++i)
 | 
			
		||||
        {
 | 
			
		||||
            count_before = attq_count_before(q, curiosity[i]);
 | 
			
		||||
            count_before = lsquic_attq_count_before(q, curiosity[i]);
 | 
			
		||||
            assert(count_before == counts[i]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < sizeof(curiosity); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        next_attq = attq_next(q);
 | 
			
		||||
        next_attq = lsquic_attq_next(q);
 | 
			
		||||
        assert(next_attq);
 | 
			
		||||
        t = next_attq->ae_adv_time;
 | 
			
		||||
        if (i > 0)
 | 
			
		||||
            assert(t >= prev);
 | 
			
		||||
        prev = t;
 | 
			
		||||
        conn = attq_pop(q, ~0ULL);
 | 
			
		||||
        conn = lsquic_attq_pop(q, ~0ULL);
 | 
			
		||||
        assert(conn);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    next_attq = attq_next(q);
 | 
			
		||||
    next_attq = lsquic_attq_next(q);
 | 
			
		||||
    assert(!next_attq);
 | 
			
		||||
    conn = attq_pop(q, ~0ULL);
 | 
			
		||||
    conn = lsquic_attq_pop(q, ~0ULL);
 | 
			
		||||
    assert(!conn);
 | 
			
		||||
 | 
			
		||||
    free(conns);
 | 
			
		||||
    attq_destroy(q);
 | 
			
		||||
    lsquic_attq_destroy(q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -144,20 +144,20 @@ test_attq_removal_1 (void)
 | 
			
		|||
    struct attq *q;
 | 
			
		||||
    struct lsquic_conn *conns;
 | 
			
		||||
 | 
			
		||||
    q = attq_create();
 | 
			
		||||
    q = lsquic_attq_create();
 | 
			
		||||
    conns = calloc(6, sizeof(conns[0]));
 | 
			
		||||
 | 
			
		||||
    attq_add(q, &conns[0], 1, 0);
 | 
			
		||||
    attq_add(q, &conns[1], 4, 0);
 | 
			
		||||
    attq_add(q, &conns[2], 2, 0);
 | 
			
		||||
    attq_add(q, &conns[3], 5, 0);
 | 
			
		||||
    attq_add(q, &conns[4], 6, 0);
 | 
			
		||||
    attq_add(q, &conns[5], 3, 0);
 | 
			
		||||
    lsquic_attq_add(q, &conns[0], 1, 0);
 | 
			
		||||
    lsquic_attq_add(q, &conns[1], 4, 0);
 | 
			
		||||
    lsquic_attq_add(q, &conns[2], 2, 0);
 | 
			
		||||
    lsquic_attq_add(q, &conns[3], 5, 0);
 | 
			
		||||
    lsquic_attq_add(q, &conns[4], 6, 0);
 | 
			
		||||
    lsquic_attq_add(q, &conns[5], 3, 0);
 | 
			
		||||
 | 
			
		||||
    attq_remove(q, &conns[3]);
 | 
			
		||||
    lsquic_attq_remove(q, &conns[3]);
 | 
			
		||||
 | 
			
		||||
    free(conns);
 | 
			
		||||
    attq_destroy(q);
 | 
			
		||||
    lsquic_attq_destroy(q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -168,23 +168,23 @@ test_attq_removal_2 (void)
 | 
			
		|||
    struct attq *q;
 | 
			
		||||
    struct lsquic_conn *conns;
 | 
			
		||||
 | 
			
		||||
    q = attq_create();
 | 
			
		||||
    q = lsquic_attq_create();
 | 
			
		||||
    conns = calloc(9, sizeof(conns[0]));
 | 
			
		||||
 | 
			
		||||
    attq_add(q, &conns[0], 1, 0);
 | 
			
		||||
    attq_add(q, &conns[1], 5, 0);
 | 
			
		||||
    attq_add(q, &conns[2], 6, 0);
 | 
			
		||||
    attq_add(q, &conns[3], 9, 0);
 | 
			
		||||
    attq_add(q, &conns[4], 11, 0);
 | 
			
		||||
    attq_add(q, &conns[5], 8, 0);
 | 
			
		||||
    attq_add(q, &conns[6], 15, 0);
 | 
			
		||||
    attq_add(q, &conns[7], 17, 0);
 | 
			
		||||
    attq_add(q, &conns[8], 21, 0);
 | 
			
		||||
    lsquic_attq_add(q, &conns[0], 1, 0);
 | 
			
		||||
    lsquic_attq_add(q, &conns[1], 5, 0);
 | 
			
		||||
    lsquic_attq_add(q, &conns[2], 6, 0);
 | 
			
		||||
    lsquic_attq_add(q, &conns[3], 9, 0);
 | 
			
		||||
    lsquic_attq_add(q, &conns[4], 11, 0);
 | 
			
		||||
    lsquic_attq_add(q, &conns[5], 8, 0);
 | 
			
		||||
    lsquic_attq_add(q, &conns[6], 15, 0);
 | 
			
		||||
    lsquic_attq_add(q, &conns[7], 17, 0);
 | 
			
		||||
    lsquic_attq_add(q, &conns[8], 21, 0);
 | 
			
		||||
 | 
			
		||||
    attq_remove(q, &conns[1]);
 | 
			
		||||
    lsquic_attq_remove(q, &conns[1]);
 | 
			
		||||
 | 
			
		||||
    free(conns);
 | 
			
		||||
    attq_destroy(q);
 | 
			
		||||
    lsquic_attq_destroy(q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -195,23 +195,23 @@ test_attq_removal_3 (void)
 | 
			
		|||
    struct attq *q;
 | 
			
		||||
    struct lsquic_conn *conns;
 | 
			
		||||
 | 
			
		||||
    q = attq_create();
 | 
			
		||||
    q = lsquic_attq_create();
 | 
			
		||||
    conns = calloc(9, sizeof(conns[0]));
 | 
			
		||||
 | 
			
		||||
    attq_add(q, &conns[0], 1, 0);
 | 
			
		||||
    attq_add(q, &conns[1], 9, 0);
 | 
			
		||||
    attq_add(q, &conns[2], 22, 0);
 | 
			
		||||
    attq_add(q, &conns[3], 17, 0);
 | 
			
		||||
    attq_add(q, &conns[4], 11, 0);
 | 
			
		||||
    attq_add(q, &conns[5], 33, 0);
 | 
			
		||||
    attq_add(q, &conns[6], 27, 0);
 | 
			
		||||
    attq_add(q, &conns[7], 21, 0);
 | 
			
		||||
    attq_add(q, &conns[8], 19, 0);
 | 
			
		||||
    lsquic_attq_add(q, &conns[0], 1, 0);
 | 
			
		||||
    lsquic_attq_add(q, &conns[1], 9, 0);
 | 
			
		||||
    lsquic_attq_add(q, &conns[2], 22, 0);
 | 
			
		||||
    lsquic_attq_add(q, &conns[3], 17, 0);
 | 
			
		||||
    lsquic_attq_add(q, &conns[4], 11, 0);
 | 
			
		||||
    lsquic_attq_add(q, &conns[5], 33, 0);
 | 
			
		||||
    lsquic_attq_add(q, &conns[6], 27, 0);
 | 
			
		||||
    lsquic_attq_add(q, &conns[7], 21, 0);
 | 
			
		||||
    lsquic_attq_add(q, &conns[8], 19, 0);
 | 
			
		||||
 | 
			
		||||
    attq_remove(q, &conns[1]);
 | 
			
		||||
    lsquic_attq_remove(q, &conns[1]);
 | 
			
		||||
 | 
			
		||||
    free(conns);
 | 
			
		||||
    attq_destroy(q);
 | 
			
		||||
    lsquic_attq_destroy(q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -287,7 +287,7 @@ run_di_nocopy_test (const struct nocopy_test *test)
 | 
			
		|||
    conn_pub.lconn = &conn;
 | 
			
		||||
    conn_pub.mm = &mm;
 | 
			
		||||
 | 
			
		||||
    di = data_in_nocopy_new(&conn_pub, 3);
 | 
			
		||||
    di = lsquic_data_in_nocopy_new(&conn_pub, 3);
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < test->n_init_frames; ++i)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -120,14 +120,14 @@ elide_single_stream_frame (void)
 | 
			
		|||
    lsquic_packet_out_add_stream(packet_out, &enpub.enp_mm, &streams[0],
 | 
			
		||||
                                                QUIC_FRAME_STREAM, off, len);
 | 
			
		||||
    assert(1 == streams[0].n_unacked);
 | 
			
		||||
    assert(posi_first(&posi, packet_out));
 | 
			
		||||
    assert(lsquic_posi_first(&posi, packet_out));
 | 
			
		||||
 | 
			
		||||
    streams[0].stream_flags |= STREAM_RST_SENT;
 | 
			
		||||
 | 
			
		||||
    lsquic_packet_out_elide_reset_stream_frames(packet_out, 0);
 | 
			
		||||
    assert(0 == streams[0].n_unacked);
 | 
			
		||||
    assert(0 == packet_out->po_frame_types);
 | 
			
		||||
    assert(!posi_first(&posi, packet_out));
 | 
			
		||||
    assert(!lsquic_posi_first(&posi, packet_out));
 | 
			
		||||
 | 
			
		||||
    lsquic_packet_out_destroy(packet_out, &enpub, NULL);
 | 
			
		||||
    lsquic_mm_cleanup(&enpub.enp_mm);
 | 
			
		||||
| 
						 | 
				
			
			@ -189,7 +189,7 @@ shrink_packet_post_elision (void)
 | 
			
		|||
 | 
			
		||||
    assert(1 == streams[0].n_unacked);
 | 
			
		||||
    assert(1 == streams[1].n_unacked);
 | 
			
		||||
    assert(posi_first(&posi, packet_out));
 | 
			
		||||
    assert(lsquic_posi_first(&posi, packet_out));
 | 
			
		||||
 | 
			
		||||
    streams[0].stream_flags |= STREAM_RST_SENT;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -197,7 +197,7 @@ shrink_packet_post_elision (void)
 | 
			
		|||
    assert(0 == streams[0].n_unacked);
 | 
			
		||||
 | 
			
		||||
    assert(QUIC_FTBIT_STREAM == packet_out->po_frame_types);
 | 
			
		||||
    srec = posi_first(&posi, packet_out);
 | 
			
		||||
    srec = lsquic_posi_first(&posi, packet_out);
 | 
			
		||||
    assert(srec->sr_stream == &streams[1]);
 | 
			
		||||
    assert(packet_out->po_data_sz == exp);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -377,21 +377,21 @@ elide_three_stream_frames (int chop_regen)
 | 
			
		|||
 | 
			
		||||
    assert(packet_out->po_frame_types == ((1 << QUIC_FRAME_STREAM) | (1 << QUIC_FRAME_RST_STREAM)));
 | 
			
		||||
 | 
			
		||||
    srec = posi_first(&posi, packet_out);
 | 
			
		||||
    srec = lsquic_posi_first(&posi, packet_out);
 | 
			
		||||
    assert(srec->sr_stream == &streams[1]);
 | 
			
		||||
    assert(srec->sr_frame_type == QUIC_FRAME_STREAM);
 | 
			
		||||
    assert(srec->sr_off == b_off - (chop_regen ? 5 : 0));
 | 
			
		||||
 | 
			
		||||
    srec = posi_next(&posi);
 | 
			
		||||
    srec = lsquic_posi_next(&posi);
 | 
			
		||||
    assert(srec->sr_stream == &streams[0]);
 | 
			
		||||
    assert(srec->sr_frame_type == QUIC_FRAME_RST_STREAM);
 | 
			
		||||
 | 
			
		||||
    srec = posi_next(&posi);
 | 
			
		||||
    srec = lsquic_posi_next(&posi);
 | 
			
		||||
    assert(srec->sr_stream == &streams[3]);
 | 
			
		||||
    assert(srec->sr_frame_type == QUIC_FRAME_STREAM);
 | 
			
		||||
    assert(srec->sr_off == d_off - (chop_regen ? 5 : 0));
 | 
			
		||||
 | 
			
		||||
    srec = posi_next(&posi);
 | 
			
		||||
    srec = lsquic_posi_next(&posi);
 | 
			
		||||
    assert(!srec);
 | 
			
		||||
 | 
			
		||||
    lsquic_packet_out_destroy(packet_out, &enpub, NULL);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -736,14 +736,14 @@ static const struct frame_reader_test tests[] = {
 | 
			
		|||
                .type = CV_ERROR,
 | 
			
		||||
                .u.error = {
 | 
			
		||||
                    .stream_id  = 12345,
 | 
			
		||||
                    .code       = FR_ERR_INCOMPL_REQ_PSEH,
 | 
			
		||||
                    .code       = FR_ERR_BAD_HEADER,
 | 
			
		||||
                },
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                .type = CV_ERROR,
 | 
			
		||||
                .u.error = {
 | 
			
		||||
                    .stream_id  = 12345,
 | 
			
		||||
                    .code       = FR_ERR_UPPERCASE_HEADER,
 | 
			
		||||
                    .code       = FR_ERR_BAD_HEADER,
 | 
			
		||||
                },
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -943,7 +943,7 @@ static const struct frame_reader_test tests[] = {
 | 
			
		|||
            {
 | 
			
		||||
                .type = CV_ERROR,
 | 
			
		||||
                .stream_off = 9 + 5 + 4,
 | 
			
		||||
                .u.error.code = FR_ERR_HEADERS_TOO_LARGE,
 | 
			
		||||
                .u.error.code = FR_ERR_BAD_HEADER,
 | 
			
		||||
                .u.error.stream_id = 12345,
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -982,7 +982,7 @@ static const struct frame_reader_test tests[] = {
 | 
			
		|||
            {
 | 
			
		||||
                .type = CV_ERROR,
 | 
			
		||||
                .stream_off = 9,
 | 
			
		||||
                .u.error.code = FR_ERR_HEADERS_TOO_LARGE,
 | 
			
		||||
                .u.error.code = FR_ERR_BAD_HEADER,
 | 
			
		||||
                .u.error.stream_id = 12345,
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -1034,7 +1034,7 @@ static const struct frame_reader_test tests[] = {
 | 
			
		|||
            {
 | 
			
		||||
                .type = CV_ERROR,
 | 
			
		||||
                .stream_off = 9 + 0 + 0x10 + 9,
 | 
			
		||||
                .u.error.code = FR_ERR_HEADERS_TOO_LARGE,
 | 
			
		||||
                .u.error.code = FR_ERR_BAD_HEADER,
 | 
			
		||||
                .u.error.stream_id = 12345,
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -1124,7 +1124,7 @@ test_one_frt (const struct frame_reader_test *frt)
 | 
			
		|||
    conn_pub.lconn = &lconn;
 | 
			
		||||
 | 
			
		||||
    lsquic_mm_init(&mm);
 | 
			
		||||
    lshpack_dec_init(&hdec);
 | 
			
		||||
    lshpack_dec_init(&hdec, LSHPACK_DEC_HTTP1X);
 | 
			
		||||
    memset(&input, 0, sizeof(input));
 | 
			
		||||
    memcpy(input.in_buf, frt->frt_buf, frt->frt_bufsz);
 | 
			
		||||
    input.in_sz  = frt->frt_bufsz;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -218,7 +218,7 @@ test_rw (unsigned max_frame_sz)
 | 
			
		|||
 | 
			
		||||
    lsquic_mm_init(&mm);
 | 
			
		||||
    lshpack_enc_init(&henc);
 | 
			
		||||
    lshpack_dec_init(&hdec);
 | 
			
		||||
    lshpack_dec_init(&hdec, LSHPACK_DEC_HTTP1X);
 | 
			
		||||
    stream = stream_new();
 | 
			
		||||
    stream->sm_max_sz = 1;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -191,8 +191,8 @@ read_from_scheduled_packets (lsquic_send_ctl_t *send_ctl, lsquic_stream_id_t str
 | 
			
		|||
    expected_type = QUIC_FRAME_STREAM;
 | 
			
		||||
 | 
			
		||||
    TAILQ_FOREACH(packet_out, &send_ctl->sc_scheduled_packets, po_next)
 | 
			
		||||
        for (srec = posi_first(&posi, packet_out); srec;
 | 
			
		||||
                                                    srec = posi_next(&posi))
 | 
			
		||||
        for (srec = lsquic_posi_first(&posi, packet_out); srec;
 | 
			
		||||
                                                    srec = lsquic_posi_next(&posi))
 | 
			
		||||
        {
 | 
			
		||||
            if (fullcheck)
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -202,7 +202,7 @@ read_from_scheduled_packets (lsquic_send_ctl_t *send_ctl, lsquic_stream_id_t str
 | 
			
		|||
                    /* First packet may contain two stream frames, do not
 | 
			
		||||
                     * check it.
 | 
			
		||||
                     */
 | 
			
		||||
                    assert(!posi_next(&posi));
 | 
			
		||||
                    assert(!lsquic_posi_next(&posi));
 | 
			
		||||
                    if (TAILQ_NEXT(packet_out, po_next))
 | 
			
		||||
                    {
 | 
			
		||||
                        assert(packet_out->po_data_sz == packet_out->po_n_alloc);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,42 +55,42 @@ main (void)
 | 
			
		|||
    lsquic_packet_out_add_stream(packet_out, &enpub.enp_mm, &streams[4], QUIC_FRAME_STREAM,  12, 1);
 | 
			
		||||
    lsquic_packet_out_add_stream(packet_out, &enpub.enp_mm, &streams[5], QUIC_FRAME_STREAM,  13, 1);
 | 
			
		||||
 | 
			
		||||
    srec = posi_first(&posi, packet_out);
 | 
			
		||||
    srec = lsquic_posi_first(&posi, packet_out);
 | 
			
		||||
    assert(srec->sr_stream == &streams[0]);
 | 
			
		||||
    assert(srec->sr_off == 7);
 | 
			
		||||
    assert(srec->sr_frame_type == QUIC_FRAME_STREAM);
 | 
			
		||||
 | 
			
		||||
    srec = posi_next(&posi);
 | 
			
		||||
    srec = lsquic_posi_next(&posi);
 | 
			
		||||
    assert(srec->sr_stream == &streams[1]);
 | 
			
		||||
    assert(srec->sr_off == 8);
 | 
			
		||||
    assert(srec->sr_frame_type == QUIC_FRAME_STREAM);
 | 
			
		||||
 | 
			
		||||
    srec = posi_next(&posi);
 | 
			
		||||
    srec = lsquic_posi_next(&posi);
 | 
			
		||||
    assert(srec->sr_stream == &streams[2]);
 | 
			
		||||
    assert(srec->sr_off == 9);
 | 
			
		||||
    assert(srec->sr_frame_type == QUIC_FRAME_STREAM);
 | 
			
		||||
 | 
			
		||||
    srec = posi_next(&posi);
 | 
			
		||||
    srec = lsquic_posi_next(&posi);
 | 
			
		||||
    assert(srec->sr_stream == &streams[1]);
 | 
			
		||||
    assert(srec->sr_off == 10);
 | 
			
		||||
    assert(srec->sr_frame_type == QUIC_FRAME_RST_STREAM);
 | 
			
		||||
 | 
			
		||||
    srec = posi_next(&posi);
 | 
			
		||||
    srec = lsquic_posi_next(&posi);
 | 
			
		||||
    assert(srec->sr_stream == &streams[3]);
 | 
			
		||||
    assert(srec->sr_off == 11);
 | 
			
		||||
    assert(srec->sr_frame_type == QUIC_FRAME_STREAM);
 | 
			
		||||
 | 
			
		||||
    srec = posi_next(&posi);
 | 
			
		||||
    srec = lsquic_posi_next(&posi);
 | 
			
		||||
    assert(srec->sr_stream == &streams[4]);
 | 
			
		||||
    assert(srec->sr_off == 12);
 | 
			
		||||
    assert(srec->sr_frame_type == QUIC_FRAME_STREAM);
 | 
			
		||||
 | 
			
		||||
    srec = posi_next(&posi);
 | 
			
		||||
    srec = lsquic_posi_next(&posi);
 | 
			
		||||
    assert(srec->sr_stream == &streams[5]);
 | 
			
		||||
    assert(srec->sr_off == 13);
 | 
			
		||||
    assert(srec->sr_frame_type == QUIC_FRAME_STREAM);
 | 
			
		||||
 | 
			
		||||
    assert((void *) 0 == posi_next(&posi));
 | 
			
		||||
    assert((void *) 0 == lsquic_posi_next(&posi));
 | 
			
		||||
 | 
			
		||||
    lsquic_packet_out_destroy(packet_out, &enpub, NULL);
 | 
			
		||||
    assert(!lsquic_malo_first(enpub.enp_mm.malo.stream_rec_arr));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -214,13 +214,13 @@ run_pbt (int i)
 | 
			
		|||
    /* Now see if we can restore it back: */
 | 
			
		||||
    lsquic_packno_t cur_packno = pbt->pbt_packno &
 | 
			
		||||
                        ((1ULL << (packet_len << 3)) - 1);
 | 
			
		||||
    lsquic_packno_t orig_packno = restore_packno(cur_packno, packet_len,
 | 
			
		||||
    lsquic_packno_t orig_packno = lsquic_restore_packno(cur_packno, packet_len,
 | 
			
		||||
                                                    pbt->pbt_least_unacked);
 | 
			
		||||
    assert(orig_packno == pbt->pbt_packno);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct restore_packno_test {
 | 
			
		||||
struct lsquic_restore_packno_test {
 | 
			
		||||
    int                         rpt_lineno;
 | 
			
		||||
    /* Input */
 | 
			
		||||
    enum packno_bits     rpt_packno_bits;
 | 
			
		||||
| 
						 | 
				
			
			@ -230,7 +230,7 @@ struct restore_packno_test {
 | 
			
		|||
    lsquic_packno_t             rpt_orig_packno;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const struct restore_packno_test rp_tests[] =
 | 
			
		||||
static const struct lsquic_restore_packno_test rp_tests[] =
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    {   .rpt_lineno         = __LINE__,
 | 
			
		||||
| 
						 | 
				
			
			@ -246,9 +246,9 @@ static const struct restore_packno_test rp_tests[] =
 | 
			
		|||
static void
 | 
			
		||||
run_rpt (int i)
 | 
			
		||||
{
 | 
			
		||||
    const struct restore_packno_test *const rpt = &rp_tests[i];
 | 
			
		||||
    const struct lsquic_restore_packno_test *const rpt = &rp_tests[i];
 | 
			
		||||
    unsigned packet_len = pf->pf_packno_bits2len(rpt->rpt_packno_bits);
 | 
			
		||||
    lsquic_packno_t orig_packno = restore_packno(rpt->rpt_cur_packno,
 | 
			
		||||
    lsquic_packno_t orig_packno = lsquic_restore_packno(rpt->rpt_cur_packno,
 | 
			
		||||
                            packet_len, rpt->rpt_max_packno);
 | 
			
		||||
    assert(orig_packno == rpt->rpt_orig_packno);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -281,7 +281,7 @@ test_restore (enum packno_bits bits)
 | 
			
		|||
            else
 | 
			
		||||
                assert(0);
 | 
			
		||||
            cur_packno = orig_packno & (epoch_delta - 1);
 | 
			
		||||
            restored_packno = restore_packno(cur_packno, len, epoch);
 | 
			
		||||
            restored_packno = lsquic_restore_packno(cur_packno, len, epoch);
 | 
			
		||||
            assert(orig_packno == restored_packno);
 | 
			
		||||
            /* Test in the middle of the epoch */
 | 
			
		||||
            if (op == OP_MINUS)
 | 
			
		||||
| 
						 | 
				
			
			@ -289,7 +289,7 @@ test_restore (enum packno_bits bits)
 | 
			
		|||
            else
 | 
			
		||||
                orig_packno = epoch + n;
 | 
			
		||||
            cur_packno = orig_packno & (epoch_delta - 1);
 | 
			
		||||
            restored_packno = restore_packno(cur_packno, len, epoch);
 | 
			
		||||
            restored_packno = lsquic_restore_packno(cur_packno, len, epoch);
 | 
			
		||||
            assert(orig_packno == restored_packno);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -299,12 +299,12 @@ test_restore (enum packno_bits bits)
 | 
			
		|||
        /* Test at the end of the epoch */
 | 
			
		||||
        orig_packno = epoch + epoch_delta / 2 - n - 1;
 | 
			
		||||
        cur_packno = orig_packno & (epoch_delta - 1);
 | 
			
		||||
        restored_packno = restore_packno(cur_packno, len, epoch - epoch_delta * 3 / 4);
 | 
			
		||||
        restored_packno = lsquic_restore_packno(cur_packno, len, epoch - epoch_delta * 3 / 4);
 | 
			
		||||
        assert(orig_packno == restored_packno + epoch_delta);
 | 
			
		||||
        /* Test in the middle of the epoch */
 | 
			
		||||
        orig_packno = epoch + 2 - n;
 | 
			
		||||
        cur_packno = orig_packno & (epoch_delta - 1);
 | 
			
		||||
        restored_packno = restore_packno(cur_packno, len, epoch - epoch_delta * 3 / 4);
 | 
			
		||||
        restored_packno = lsquic_restore_packno(cur_packno, len, epoch - epoch_delta * 3 / 4);
 | 
			
		||||
        assert(orig_packno == restored_packno + epoch_delta);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -314,12 +314,12 @@ test_restore (enum packno_bits bits)
 | 
			
		|||
        /* Test at the end of the epoch */
 | 
			
		||||
        orig_packno = epoch - epoch_delta / 2 + n;
 | 
			
		||||
        cur_packno = orig_packno & (epoch_delta - 1);
 | 
			
		||||
        restored_packno = restore_packno(cur_packno, len, epoch + epoch_delta * 3 / 4);
 | 
			
		||||
        restored_packno = lsquic_restore_packno(cur_packno, len, epoch + epoch_delta * 3 / 4);
 | 
			
		||||
        assert(orig_packno == restored_packno - epoch_delta);
 | 
			
		||||
        /* Test in the middle of the epoch */
 | 
			
		||||
        orig_packno = epoch + 2 - n;
 | 
			
		||||
        cur_packno = orig_packno & (epoch_delta - 1);
 | 
			
		||||
        restored_packno = restore_packno(cur_packno, len, epoch + epoch_delta * 3 / 4);
 | 
			
		||||
        restored_packno = lsquic_restore_packno(cur_packno, len, epoch + epoch_delta * 3 / 4);
 | 
			
		||||
        assert(orig_packno == restored_packno - epoch_delta);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -70,7 +70,7 @@ test_shi (const struct order *order)
 | 
			
		|||
    void *datap;
 | 
			
		||||
    struct data *data;
 | 
			
		||||
 | 
			
		||||
    hash = stock_shared_hash_new();
 | 
			
		||||
    hash = lsquic_stock_shared_hash_new();
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < N_PAIRS; ++i)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -124,7 +124,7 @@ test_shi (const struct order *order)
 | 
			
		|||
        assert(0 == s);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    stock_shared_hash_destroy(hash);
 | 
			
		||||
    lsquic_stock_shared_hash_destroy(hash);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -218,8 +218,8 @@ read_from_scheduled_packets (lsquic_send_ctl_t *send_ctl, lsquic_stream_id_t str
 | 
			
		|||
        expected_type = QUIC_FRAME_STREAM;
 | 
			
		||||
 | 
			
		||||
    TAILQ_FOREACH(packet_out, &send_ctl->sc_scheduled_packets, po_next)
 | 
			
		||||
        for (srec = posi_first(&posi, packet_out); srec;
 | 
			
		||||
                                                    srec = posi_next(&posi))
 | 
			
		||||
        for (srec = lsquic_posi_first(&posi, packet_out); srec;
 | 
			
		||||
                                                srec = lsquic_posi_next(&posi))
 | 
			
		||||
        {
 | 
			
		||||
            if (fullcheck)
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -229,7 +229,7 @@ read_from_scheduled_packets (lsquic_send_ctl_t *send_ctl, lsquic_stream_id_t str
 | 
			
		|||
                    /* First packet may contain two stream frames, do not
 | 
			
		||||
                     * check it.
 | 
			
		||||
                     */
 | 
			
		||||
                    assert(!posi_next(&posi));
 | 
			
		||||
                    assert(!lsquic_posi_next(&posi));
 | 
			
		||||
                    if (TAILQ_NEXT(packet_out, po_next))
 | 
			
		||||
                    {
 | 
			
		||||
                        assert(packet_out->po_data_sz == packet_out->po_n_alloc);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -92,8 +92,8 @@ test_parsing_ver_nego (const struct gen_ver_nego_test *gvnt)
 | 
			
		|||
    s = lsquic_parse_packet_in_begin(packet_in, gvnt->gvnt_len, 0, GQUIC_CID_LEN, &ppstate);
 | 
			
		||||
    assert(s == 0);
 | 
			
		||||
 | 
			
		||||
    for (s = packet_in_ver_first(packet_in, &vi, &ver_tag); s;
 | 
			
		||||
                     s = packet_in_ver_next(&vi, &ver_tag))
 | 
			
		||||
    for (s = lsquic_packet_in_ver_first(packet_in, &vi, &ver_tag); s;
 | 
			
		||||
                     s = lsquic_packet_in_ver_next(&vi, &ver_tag))
 | 
			
		||||
    {
 | 
			
		||||
        version = lsquic_tag2ver(ver_tag);
 | 
			
		||||
        assert(version < N_LSQVER);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue