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:
Dmitri Tikhonov 2020-03-12 08:41:53 -04:00
parent 5289ebd2fd
commit a5fa05f958
77 changed files with 1168 additions and 73475 deletions

3
.gitmodules vendored
View file

@ -2,3 +2,6 @@
path = src/liblsquic/ls-qpack path = src/liblsquic/ls-qpack
url = https://github.com/litespeedtech/ls-qpack url = https://github.com/litespeedtech/ls-qpack
branch = v0.9.13 branch = v0.9.13
[submodule "src/lshpack"]
path = src/lshpack
url = https://github.com/litespeedtech/ls-hpack

View file

@ -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 2020-03-02
- 2.12.0 - 2.12.0
- [FEATURE] QUIC timestamps extension. - [FEATURE] QUIC timestamps extension.

View file

@ -21,11 +21,10 @@ Support for newer versions will be added soon after they are released.
Documentation 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 Documentation is available at https://lsquic.readthedocs.io/en/latest/.
documented in include/lsquic.h. If you have doxygen, you can run
`doxygen dox.cfg` or `make docs`. The example program is In addition, see example programs for API usage and EXAMPLES.txt for
test/http_client.c: a bare-bones, but working, QUIC client. Have a look some compilation and run-time options.
in EXAMPLES.txt to see how it can be used.
Requirements Requirements
------------ ------------

View file

@ -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 stream by calling :func:`lsquic_stream_get_hset()` before the stream can
be read. 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: :param hdr_set:
Header set to add the new header field to. This is the object Header set to add the new header field to. This is the object
returned by ``hsi_create_header_set()``. 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 The header returned by @ref ``hsi_prepare_decode()``.
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.
:return: :return:
0 on success, non-zero on failure. The latter is treated as a stream Return 0 on success, a positive value if a header error occured,
error: the associated stream is reset. See :type:`lsquic_header_status` or a negative value on any other error. A positive return value
for detailed error listing. 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) .. member:: void (*hsi_discard_header_set)(void *hdr_set)
@ -1763,63 +1752,6 @@ Miscellaneous Types
Close handle. 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 .. type:: enum lsquic_logger_timestamp_style
Enumerate timestamp styles supported by LSQUIC logger mechanism. Enumerate timestamp styles supported by LSQUIC logger mechanism.

View file

@ -24,9 +24,9 @@ copyright = u'2020, LiteSpeed Technologies'
author = u'LiteSpeed Technologies' author = u'LiteSpeed Technologies'
# The short X.Y version # The short X.Y version
version = u'2.12' version = u'2.13'
# The full version, including alpha/beta/rc tags # The full version, including alpha/beta/rc tags
release = u'2.12.0' release = u'2.13.0'
# -- General configuration --------------------------------------------------- # -- General configuration ---------------------------------------------------

View file

@ -16,6 +16,7 @@ LSQUIC library uses:
- zlib_; - zlib_;
- BoringSSL_; and - BoringSSL_; and
- `ls-hpack`_ (as a Git submodule).
- `ls-qpack`_ (as a Git submodule). - `ls-qpack`_ (as a Git submodule).
The accompanying demo command-line tools use libevent_. The accompanying demo command-line tools use libevent_.
@ -66,6 +67,7 @@ the :doc:`apiref`.
.. _zlib: https://www.zlib.net/ .. _zlib: https://www.zlib.net/
.. _BoringSSL: https://boringssl.googlesource.com/boringssl/ .. _BoringSSL: https://boringssl.googlesource.com/boringssl/
.. _`ls-hpack`: https://github.com/litespeedtech/ls-hpack
.. _`ls-qpack`: https://github.com/litespeedtech/ls-qpack .. _`ls-qpack`: https://github.com/litespeedtech/ls-qpack
.. _libevent: https://libevent.org/ .. _libevent: https://libevent.org/
.. _README: https://github.com/litespeedtech/lsquic/blob/master/README.md .. _README: https://github.com/litespeedtech/lsquic/blob/master/README.md

View file

@ -24,7 +24,7 @@ extern "C" {
#endif #endif
#define LSQUIC_MAJOR_VERSION 2 #define LSQUIC_MAJOR_VERSION 2
#define LSQUIC_MINOR_VERSION 12 #define LSQUIC_MINOR_VERSION 13
#define LSQUIC_PATCH_VERSION 0 #define LSQUIC_PATCH_VERSION 0
/** /**
@ -862,39 +862,6 @@ typedef void (*lsquic_cids_update_f)(void *ctx, void **peer_ctx,
struct stack_st_X509; 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 struct lsquic_hset_if
{ {
/** /**
@ -905,27 +872,35 @@ struct lsquic_hset_if
void * (*hsi_create_header_set)(void *hsi_ctx, void * (*hsi_create_header_set)(void *hsi_ctx,
int is_push_promise); int is_push_promise);
/** /**
* Process new header. Return 0 on success, -1 if there is a problem with * Return a header set prepared for decoding. If `hdr' is NULL, this
* the header. -1 is treated as a stream error: the associated stream is * means return a new structure with at least `space' bytes available
* reset. * 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 * `hdr_set' is the header set object returned by
* @ref hsi_create_header_set(). * @ref hsi_create_header_set().
* *
* `name_idx' is set to the index in either the HPACK or QPACK static table * `hdr' is the header returned by @ref `hsi_prepare_decode'.
* 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).
* *
* 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. * added to the set.
*/ */
enum lsquic_header_status (*hsi_process_header)(void *hdr_set, int (*hsi_process_header)(void *hdr_set, struct lsxpack_header *hdr);
unsigned name_idx,
const char *name, unsigned name_len,
const char *value, unsigned value_len);
/** /**
* Discard header set. This is called for unclaimed header sets and * Discard header set. This is called for unclaimed header sets and
* header sets that had an error. * header sets that had an error.

165
include/lsxpack_header.h Normal file
View 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

View file

@ -36,7 +36,7 @@ struct attq
struct attq * struct attq *
attq_create (void) lsquic_attq_create (void)
{ {
struct attq *q; struct attq *q;
struct malo *malo; struct malo *malo;
@ -58,7 +58,7 @@ attq_create (void)
void void
attq_destroy (struct attq *q) lsquic_attq_destroy (struct attq *q)
{ {
lsquic_malo_destroy(q->aq_elem_malo); lsquic_malo_destroy(q->aq_elem_malo);
free(q->aq_heap); free(q->aq_heap);
@ -108,7 +108,7 @@ attq_swap (struct attq *q, unsigned a, unsigned b)
int 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) lsquic_time_t advisory_time, enum ae_why why)
{ {
struct attq_elem *el, **heap; struct attq_elem *el, **heap;
@ -155,7 +155,7 @@ attq_add (struct attq *q, struct lsquic_conn *conn,
struct lsquic_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 lsquic_conn *conn;
struct attq_elem *el; struct attq_elem *el;
@ -168,7 +168,7 @@ attq_pop (struct attq *q, lsquic_time_t cutoff)
return NULL; return NULL;
conn = el->ae_conn; conn = el->ae_conn;
attq_remove(q, conn); lsquic_attq_remove(q, conn);
return conn; return conn;
} }
@ -204,7 +204,7 @@ attq_heapify (struct attq *q, unsigned i)
void void
attq_remove (struct attq *q, struct lsquic_conn *conn) lsquic_attq_remove (struct attq *q, struct lsquic_conn *conn)
{ {
struct attq_elem *el; struct attq_elem *el;
unsigned idx; unsigned idx;
@ -239,7 +239,7 @@ attq_remove (struct attq *q, struct lsquic_conn *conn)
unsigned 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; 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 * const struct attq_elem *
attq_next (struct attq *q) lsquic_attq_next (struct attq *q)
{ {
if (q->aq_nelem > 0) if (q->aq_nelem > 0)
return q->aq_heap[0]; return q->aq_heap[0];

View file

@ -31,27 +31,27 @@ struct attq_elem
struct attq * struct attq *
attq_create (void); lsquic_attq_create (void);
void void
attq_destroy (struct attq *); lsquic_attq_destroy (struct attq *);
/* Return 0 on success, -1 on failure (malloc) */ /* Return 0 on success, -1 on failure (malloc) */
int 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); enum ae_why);
void void
attq_remove (struct attq *, struct lsquic_conn *); lsquic_attq_remove (struct attq *, struct lsquic_conn *);
struct lsquic_conn * struct lsquic_conn *
attq_pop (struct attq *, lsquic_time_t cutoff); lsquic_attq_pop (struct attq *, lsquic_time_t cutoff);
unsigned unsigned
attq_count_before (struct attq *, lsquic_time_t cutoff); lsquic_attq_count_before (struct attq *, lsquic_time_t cutoff);
const struct attq_elem * const struct attq_elem *
attq_next (struct attq *); lsquic_attq_next (struct attq *);
const char * const char *
lsquic_attq_why2str (enum ae_why); lsquic_attq_why2str (enum ae_why);

View file

@ -162,7 +162,12 @@ const common_cert_t common_cert_set[common_certs_num] = {
static lsquic_str_t *s_ccsbuf; 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; int i;
if (s_ccsbuf == NULL) if (s_ccsbuf == NULL)
@ -178,7 +183,8 @@ lsquic_str_t * get_common_certs_hash()
/* return 0 found, -1 not found */ /* 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; int i;
for (i = 0; i < common_certs_num; 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 */ /* 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) uint64_t* out_hash, uint32_t* out_index)
{ {
size_t i, j; 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) void get_certs_hash(lsquic_str_t *certs, size_t certs_count, uint64_t *hashs)
{ {
size_t i; size_t i;
for(i = 0; i < certs_count; ++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) if (cached_valid)
{ {
cached = false; 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); for (j = 0; j < (int)lsquic_str_len(client_cached_cert_hashes);
j += sizeof(uint64_t)) 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 i;
size_t entries_size = 0; 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; return entries_size;
} }
static
void serialize_cert_entries(uint8_t* out, int *out_len, cert_entry_t *entries, void serialize_cert_entries(uint8_t* out, int *out_len, cert_entry_t *entries,
size_t entries_count) 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 = lsquic_str_buf(compressed_crt_buf);
char *in_end = in + lsquic_str_len(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)); memcpy(&entry->index, in, sizeof(uint32_t));
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; break;
else else
goto err; goto err;
@ -560,7 +571,8 @@ static int parse_entries(const unsigned char **in_out, const unsigned char *cons
/* return 0 for OK */ /* 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_common_set_hashes,
lsquic_str_t *client_cached_cert_hashes, lsquic_str_t *client_cached_cert_hashes,
lsquic_str_t *result) lsquic_str_t *result)
@ -670,7 +682,8 @@ int compress_certs(lsquic_str_t **certs, size_t certs_count,
/* 0: ok */ /* 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 *cached_certs, size_t cached_certs_count,
lsquic_str_t **out_certs, size_t *out_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; z_stream z;
assert(*out_certs_count > 0 && *out_certs_count < 10000 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) if (count == 0 || count > 10000)
return -1; return -1;

View file

@ -34,20 +34,18 @@ typedef struct common_cert_st
uint64_t hash; uint64_t hash;
} common_cert_t; } 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 lsquic_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 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_common_set_hashes,
struct lsquic_str *client_cached_cert_hashes, struct lsquic_str *client_cached_cert_hashes,
struct lsquic_str *result); struct lsquic_str *result);
int get_certs_count(struct lsquic_str *compressed_crt_buf); int lsquic_get_certs_count(struct lsquic_str *compressed_crt_buf);
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,
struct lsquic_str *cached_certs, size_t cached_certs_count, struct lsquic_str *cached_certs, size_t cached_certs_count,
struct lsquic_str **out_certs, struct lsquic_str **out_certs,
size_t *out_certs_count); size_t *out_certs_count);

View file

@ -30,7 +30,7 @@ static const char s_hs_signature[] = "QUIC CHLO and server config signature";
static int crypto_inited = 0; 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); uint64_t hash = UINT64_C(14695981039346656037);
const uint8_t *end = data + len; 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); 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; const uint8_t* end = data + len;
while(data < end) 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 *data2, int len2,
const uint8_t *data3, int len3) const uint8_t *data3, int len3)
{ {
uint128 hash; uint128 hash;
memcpy(&hash, &s_init_hash, 16); memcpy(&hash, &s_init_hash, 16);
fnv1a_inc(&hash, data1, len1); lsquic_fnv1a_inc(&hash, data1, len1);
fnv1a_inc(&hash, data2, len2); lsquic_fnv1a_inc(&hash, data2, len2);
fnv1a_inc(&hash, data3, len3); lsquic_fnv1a_inc(&hash, data3, len3);
return hash; return hash;
} }
/* HS_PKT_HASH_LENGTH bytes of md */ /* 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); memcpy(md, (void *)&v, 12);
} }
@ -131,7 +131,7 @@ uint128 *uint128_times(uint128 *v, const uint128 *factor)
return v; 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}; static const uint128 kPrime = {16777216, 315};
const uint8_t* end = data + len; 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 * data2, int len2,
const uint8_t * data3, int len3) const uint8_t * data3, int len3)
{ {
uint128 hash = {UINT64_C(7809847782465536322), UINT64_C(7113472399480571277)}; uint128 hash = {UINT64_C(7809847782465536322), UINT64_C(7113472399480571277)};
fnv1a_inc(&hash, data1, len1); lsquic_fnv1a_inc(&hash, data1, len1);
fnv1a_inc(&hash, data2, len2); lsquic_fnv1a_inc(&hash, data2, len2);
fnv1a_inc(&hash, data3, len3); lsquic_fnv1a_inc(&hash, data3, len3);
return hash; return hash;
} }
/* HS_PKT_HASH_LENGTH bytes of md */ /* 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); assert(HS_PKT_HASH_LENGTH == 8 + 4);
memcpy(md, (void *)&v.lo_, 8); 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, unsigned char *salt, int salt_len,
char *label, uint32_t label_len, char *label, uint32_t label_len,
const uint8_t *context, uint32_t context_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); free(info);
return 0; return 0;
} }
#endif
int int
@ -314,13 +316,13 @@ lsquic_export_key_material(const unsigned char *ikm, uint32_t ikm_len,
return 0; 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); 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); 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 */ /* AEAD nonce is always zero */
/* return 0 for OK */ /* 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 *ad, size_t ad_len,
const uint8_t *nonce, size_t nonce_len, const uint8_t *nonce, size_t nonce_len,
const uint8_t *plain, size_t plain_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_); max_out_len = *cypher_len;//plain_len + EVP_AEAD_max_overhead(aead_);
assert(*cypher_len >= max_out_len); 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, ret = EVP_AEAD_CTX_seal(key, cypher, cypher_len, max_out_len,
nonce, nonce_len, plain, plain_len, ad, ad_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("***lsquic_aes_aead_enc nonce: %s", lsquic_get_bin_str(nonce, nonce_len));
// LSQ_DEBUG("***aes_aead_enc AD: %s", get_bin_str(ad, ad_len)); // LSQ_DEBUG("***lsquic_aes_aead_enc AD: %s", lsquic_get_bin_str(ad, ad_len));
// LSQ_DEBUG("***aes_aead_enc return %d", (ret ? 0 : -1)); // LSQ_DEBUG("***lsquic_aes_aead_enc return %d", (ret ? 0 : -1));
if (ret) if (ret)
{ {
LSQ_DEBUG("***aes_aead_enc succeed, cypher content %s", LSQ_DEBUG("***lsquic_aes_aead_enc succeed, cypher content %s",
get_bin_str(cypher, *cypher_len, 40)); lsquic_get_bin_str(cypher, *cypher_len, 40));
return 0; return 0;
} }
else else
{ {
LSQ_DEBUG("***aes_aead_enc failed."); LSQ_DEBUG("***lsquic_aes_aead_enc failed.");
return -1; return -1;
} }
} }
/* return 0 for OK */ /* 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 *ad, size_t ad_len,
const uint8_t *nonce, size_t nonce_len, const uint8_t *nonce, size_t nonce_len,
const uint8_t *cypher, size_t cypher_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; size_t max_out_len = *plain_len;
assert(max_out_len >= cypher_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, ret = EVP_AEAD_CTX_open(key, plain, plain_len, max_out_len,
nonce, nonce_len, cypher, cypher_len, ad, ad_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("***lsquic_aes_aead_dec nonce: %s", lsquic_get_bin_str(nonce, nonce_len));
// LSQ_DEBUG("***aes_aead_dec AD: %s", get_bin_str(ad, ad_len)); // LSQ_DEBUG("***lsquic_aes_aead_dec AD: %s", lsquic_get_bin_str(ad, ad_len));
// LSQ_DEBUG("***aes_aead_dec return %d", (ret ? 0 : -1)); // LSQ_DEBUG("***lsquic_aes_aead_dec return %d", (ret ? 0 : -1));
if (ret) if (ret)
{ {
LSQ_DEBUG("***aes_aead_dec succeed, plain content %s", LSQ_DEBUG("***lsquic_aes_aead_dec succeed, plain content %s",
get_bin_str(plain, *plain_len, 20)); lsquic_get_bin_str(plain, *plain_len, 20));
return 0; return 0;
} }
else else
{ {
LSQ_DEBUG("***aes_aead_dec failed."); LSQ_DEBUG("***lsquic_aes_aead_dec failed.");
return -1; return -1;
} }
} }
/* 32 bytes client nonce with 4 bytes tm, 8 bytes orbit */ /* 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); time_t tm = time(NULL);
unsigned char *p = buf; 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 */ /* 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; X509 *crt = NULL;
BIO *bio = BIO_new_mem_buf(buf, len); 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 uint8_t *scfg_data, uint32_t scfg_data_len,
const EVP_PKEY *priv_key, uint8_t *buf, size_t *buf_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 */ /* -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 uint8_t *scfg_data, uint32_t scfg_data_len,
const EVP_PKEY *pub_key, const uint8_t *buf, size_t 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) if (crypto_inited)
return ; return ;

View file

@ -28,14 +28,16 @@ struct x509_st;
#endif #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, unsigned char *salt, int salt_len,
char *label, uint32_t label_len, char *label, uint32_t label_len,
const uint8_t *context, uint32_t context_len, const uint8_t *context, uint32_t context_len,
uint8_t *key, uint16_t key_len); uint8_t *key, uint16_t key_len);
#endif
int lsquic_export_key_material(const unsigned char *ikm, uint32_t ikm_len, int lsquic_export_key_material(const unsigned char *ikm, uint32_t ikm_len,
const unsigned char *salt, int salt_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 *sub_key,
uint8_t *c_hp, uint8_t *s_hp); uint8_t *c_hp, uint8_t *s_hp);
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]);
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);
uint64_t fnv1a_64(const uint8_t * data, int len); uint64_t lsquic_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);
void fnv1a_128_s(const uint8_t * data , int len, uint8_t *md); void lsquic_fnv1a_128_s(const uint8_t * data , int len, uint8_t *md);
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 * data2, int len2,
const uint8_t * data3, int len3); 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 */ /* 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 *ad, size_t ad_len,
const uint8_t *nonce, size_t nonce_len, const uint8_t *nonce, size_t nonce_len,
const uint8_t *plain, size_t plain_len, const uint8_t *plain, size_t plain_len,
uint8_t *cypher, size_t *cypher_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 *ad, size_t ad_len,
const uint8_t *nonce, size_t nonce_len, const uint8_t *nonce, size_t nonce_len,
const uint8_t *cypher, size_t cypher_len, const uint8_t *cypher, size_t cypher_len,
uint8_t *plain, size_t *plain_len); uint8_t *plain, size_t *plain_len);
/* 32 bytes client nonce with 4 bytes tm, 8 bytes orbit */ /* 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 *lsquic_bio_to_crt(const void *buf, int len, int type);
struct x509_st *bio_to_crt(const void *buf, int len, int type);
int lshkdf_expand(const unsigned char *prk, const unsigned char *info, int info_len, int lshkdf_expand(const unsigned char *prk, const unsigned char *info, int info_len,
uint16_t c_key_len, uint8_t *c_key, 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, void lshkdf_extract(const unsigned char *ikm, int ikm_len, const unsigned char *salt,
int salt_len, unsigned char *prk); 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 uint8_t *scfg_data, uint32_t scfg_data_len,
const struct evp_pkey_st *priv_key, uint8_t *buf, size_t *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); const struct evp_pkey_st *pub_key, const uint8_t *buf, size_t len);

View file

@ -92,20 +92,20 @@ struct data_in
* INS_FRAME_OVERLAP. * INS_FRAME_OVERLAP.
*/ */
struct data_in * 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 /* This implementation supports overlapping frames and will never return
* INS_FRAME_OVERLAP. * INS_FRAME_OVERLAP.
*/ */
struct data_in * 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); uint64_t byteage);
enum ins_frame 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); const struct data_frame *data_frame, uint64_t read_offset);
struct data_in * struct data_in *
data_in_error_new (); lsquic_data_in_error_new ();
#endif #endif

View file

@ -21,7 +21,7 @@ static const struct data_in *error_data_in_ptr;
struct data_in * 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; 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) error_di_switch_impl (struct data_in *data_in, uint64_t read_offset)
{ {
assert(0); assert(0);

View file

@ -114,7 +114,7 @@ my_log2 /* silly name to suppress compiler warning */ (unsigned sz)
struct data_in * 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) lsquic_stream_id_t stream_id, uint64_t byteage)
{ {
struct hash_data_in *hdi; struct hash_data_in *hdi;
@ -350,7 +350,7 @@ has_bytes_after (const struct data_block *block, unsigned off)
enum ins_frame 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) const struct data_frame *data_frame, uint64_t read_offset)
{ {
struct hash_data_in *const hdi = HDI_PTR(data_in); 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; const struct data_frame *const data_frame = &new_frame->data_frame;
enum ins_frame ins; 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); assert(ins != INS_FRAME_OVERLAP);
lsquic_packet_in_put(hdi->hdi_conn_pub->mm, new_frame->packet_in); lsquic_packet_in_put(hdi->hdi_conn_pub->mm, new_frame->packet_in);
if (ins != INS_FRAME_OK) 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) hash_di_switch_impl (struct data_in *data_in, uint64_t read_offset)
{ {
struct hash_data_in *const hdi = HDI_PTR(data_in); 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); 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); data_in->di_if->di_destroy(data_in);
return new_data_in; return new_data_in;

View file

@ -128,7 +128,7 @@ static const struct data_in_iface *di_if_nocopy_ptr;
struct data_in * 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) lsquic_stream_id_t stream_id)
{ {
struct nocopy_data_in *ncdi; 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) nocopy_di_switch_impl (struct data_in *data_in, uint64_t read_offset)
{ {
struct nocopy_data_in *const ncdi = NCDI_PTR(data_in); 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; stream_frame_t *frame;
enum ins_frame ins; enum ins_frame ins;
new_data_in = data_in_hash_new(ncdi->ncdi_conn_pub, ncdi->ncdi_stream_id, new_data_in = lsquic_data_in_hash_new(ncdi->ncdi_conn_pub,
ncdi->ncdi_byteage); ncdi->ncdi_stream_id, ncdi->ncdi_byteage);
if (!new_data_in) if (!new_data_in)
goto end; goto end;
while ((frame = TAILQ_FIRST(&ncdi->ncdi_frames_in))) while ((frame = TAILQ_FIRST(&ncdi->ncdi_frames_in)))
{ {
TAILQ_REMOVE(&ncdi->ncdi_frames_in, frame, next_frame); TAILQ_REMOVE(&ncdi->ncdi_frames_in, frame, next_frame);
ins = data_in_hash_insert_data_frame(new_data_in, &frame->data_frame, ins = lsquic_data_in_hash_insert_data_frame(new_data_in,
read_offset); &frame->data_frame, read_offset);
lsquic_packet_in_put(ncdi->ncdi_conn_pub->mm, frame->packet_in); lsquic_packet_in_put(ncdi->ncdi_conn_pub->mm, frame->packet_in);
lsquic_malo_put(frame); lsquic_malo_put(frame);
if (INS_FRAME_ERR == ins) if (INS_FRAME_ERR == ins)

View file

@ -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) iquic_esfi_destroy (enc_session_t *enc_session_p)
{ {
struct enc_sess_iquic *const enc_sess = 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, iquic_esfi_data_in (enc_session_t *sess, enum enc_level enc_level,
const unsigned char *buf, size_t len) const unsigned char *buf, size_t len)
{ {

View file

@ -43,7 +43,7 @@ log_hist_slice (const struct hist_slice *slice, time_t t)
void void
eng_hist_log (const struct eng_hist *hist) lsquic_eng_hist_log (const struct eng_hist *hist)
{ {
unsigned i, idx; unsigned i, idx;
time_t t0 = time(NULL) - ENG_HIST_NELEMS + 1; time_t t0 = time(NULL) - ENG_HIST_NELEMS + 1;

View file

@ -59,7 +59,7 @@ struct eng_hist
void void
eng_hist_log (const struct eng_hist *); lsquic_eng_hist_log (const struct eng_hist *);
/* Switch to next slice if necessary */ /* 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); \ (eh)->eh_cur_idx = ((now) / 1000000) & (ENG_HIST_NELEMS - 1); \
if ((eh)->eh_cur_idx != (eh)->eh_prev_idx) \ if ((eh)->eh_cur_idx != (eh)->eh_prev_idx) \
{ \ { \
eng_hist_log(eh); \ lsquic_eng_hist_log(eh); \
eng_hist_clear_cur(eh); \ eng_hist_clear_cur(eh); \
(eh)->eh_prev_idx = (eh)->eh_cur_idx; \ (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_clear_cur(eh)
#define eng_hist_tick(eh, now) #define eng_hist_tick(eh, now)
#define eng_hist_inc(eh, now, what) #define eng_hist_inc(eh, now, what)
#define eng_hist_log(eh) #define lsquic_eng_hist_log(eh)
#endif /* ENG_HIST_ENABLED */ #endif /* ENG_HIST_ENABLED */

View file

@ -548,7 +548,7 @@ lsquic_engine_new (unsigned flags,
else else
{ {
engine->pub.enp_shi = &stock_shi; 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) if (!engine->pub.enp_shi_ctx)
{ {
free(engine); free(engine);
@ -589,7 +589,7 @@ lsquic_engine_new (unsigned flags,
engine->pub.enp_crand = &engine->crand; engine->pub.enp_crand = &engine->crand;
if (flags & ENG_SERVER) if (flags & ENG_SERVER)
{ {
engine->pr_queue = prq_create( engine->pr_queue = lsquic_prq_create(
10000 /* TODO: make configurable */, MAX_OUT_BATCH_SIZE, 10000 /* TODO: make configurable */, MAX_OUT_BATCH_SIZE,
&engine->pub); &engine->pub);
if (!engine->pr_queue) if (!engine->pr_queue)
@ -602,11 +602,11 @@ lsquic_engine_new (unsigned flags,
if (!engine->purga) if (!engine->purga)
{ {
lsquic_tg_destroy(engine->pub.enp_tokgen); lsquic_tg_destroy(engine->pub.enp_tokgen);
prq_destroy(engine->pr_queue); lsquic_prq_destroy(engine->pr_queue);
return NULL; return NULL;
} }
} }
engine->attq = attq_create(); engine->attq = lsquic_attq_create();
eng_hist_init(&engine->history); eng_hist_init(&engine->history);
engine->batch_size = INITIAL_OUT_BATCH_SIZE; engine->batch_size = INITIAL_OUT_BATCH_SIZE;
if (engine->pub.enp_settings.es_honor_prst) 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) const struct sockaddr *sa_peer, void *peer_ctx)
{ {
assert(engine->pr_queue); 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)) sa_local, sa_peer))
LSQ_DEBUGC("scheduled %s packet for cid %"CID_FMT, LSQ_DEBUGC("scheduled %s packet for cid %"CID_FMT,
lsquic_preqt2str[type], CID_BITS(&packet_in->pi_conn_id)); 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 else
{ {
conn = mini_conn_new(&engine->pub, packet_in, version); conn = lsquic_mini_conn_new(&engine->pub, packet_in, version);
} }
if (!conn) if (!conn)
return NULL; 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) if (lsquic_conn_adv_time(conn) != tick_time)
{ {
attq_remove(engine->attq, conn); lsquic_attq_remove(engine->attq, conn);
if (0 != attq_add(engine->attq, conn, tick_time, why)) if (0 != lsquic_attq_add(engine->attq, conn, tick_time, why))
engine_decref_conn(engine, conn, LSCONN_ATTQ); 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); 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->n_conns);
assert(0 == engine->mini_conns_count); assert(0 == engine->mini_conns_count);
if (engine->pr_queue) if (engine->pr_queue)
prq_destroy(engine->pr_queue); lsquic_prq_destroy(engine->pr_queue);
if (engine->purga) if (engine->purga)
lsquic_purga_destroy(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_out));
assert(0 == lsquic_mh_count(&engine->conns_tickable)); assert(0 == lsquic_mh_count(&engine->conns_tickable));
if (engine->pub.enp_shi == &stock_shi) 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); lsquic_mm_cleanup(&engine->pub.enp_mm);
free(engine->conns_tickable.mh_elems); free(engine->conns_tickable.mh_elems);
#ifndef NDEBUG #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? */ assert(!(flags & LSCONN_CLOSING)); /* It is in transient queue? */
if (flags & LSCONN_ATTQ) if (flags & LSCONN_ATTQ)
{ {
attq_remove(engine->attq, conn); lsquic_attq_remove(engine->attq, conn);
(void) engine_decref_conn(engine, conn, LSCONN_ATTQ); (void) engine_decref_conn(engine, conn, LSCONN_ATTQ);
} }
if (flags & LSCONN_HASHED) if (flags & LSCONN_HASHED)
@ -1740,7 +1740,7 @@ conn_iter_next_tickable (struct lsquic_engine *engine)
conn = engine_decref_conn(engine, conn, LSCONN_TICKABLE); conn = engine_decref_conn(engine, conn, LSCONN_TICKABLE);
if (conn && (conn->cn_flags & LSCONN_ATTQ)) 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); conn = engine_decref_conn(engine, conn, LSCONN_ATTQ);
} }
@ -1830,7 +1830,7 @@ lsquic_engine_process_conns (lsquic_engine_t *engine)
ENGINE_IN(engine); ENGINE_IN(engine);
now = lsquic_time_now(); 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); conn = engine_decref_conn(engine, conn, LSCONN_ATTQ);
if (conn && !(conn->cn_flags & LSCONN_TICKABLE)) if (conn && !(conn->cn_flags & LSCONN_TICKABLE))
@ -1965,7 +1965,7 @@ coi_next (struct conns_out_iter *iter)
#endif #endif
return conn; 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; return conn;
} }
@ -2432,7 +2432,7 @@ int
lsquic_engine_has_unsent_packets (lsquic_engine_t *engine) lsquic_engine_has_unsent_packets (lsquic_engine_t *engine)
{ {
return lsquic_mh_count(&engine->conns_out) > 0 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); next_tick_time = conn->cn_if->ci_next_tick_time(conn, &why);
if (next_tick_time) 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); engine_incref_conn(conn, LSCONN_ATTQ);
} }
else else
@ -2759,7 +2760,7 @@ lsquic_engine_earliest_adv_tick (lsquic_engine_t *engine, int *diff)
return 1; 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 #if LSQUIC_DEBUG_NEXT_ADV_TICK
engine->last_logged_conn = 0; engine->last_logged_conn = 0;
@ -2784,7 +2785,7 @@ lsquic_engine_earliest_adv_tick (lsquic_engine_t *engine, int *diff)
return 1; return 1;
} }
next_attq = attq_next(engine->attq); next_attq = lsquic_attq_next(engine->attq);
if (engine->pub.enp_flags & ENPUB_CAN_SEND) if (engine->pub.enp_flags & ENPUB_CAN_SEND)
{ {
if (next_attq) if (next_attq)
@ -2847,7 +2848,7 @@ lsquic_engine_count_attq (lsquic_engine_t *engine, int from_now)
now -= from_now; now -= from_now;
else else
now += from_now; now += from_now;
return attq_count_before(engine->attq, now); return lsquic_attq_count_before(engine->attq, now);
} }

View file

@ -380,7 +380,7 @@ prepare_for_payload (struct lsquic_frame_reader *fr)
LSQ_WARN("cannot allocate %u bytes for header block", LSQ_WARN("cannot allocate %u bytes for header block",
fr->fr_header_block_sz); fr->fr_header_block_sz);
fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, stream_id, fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, stream_id,
FR_ERR_NOMEM); FR_ERR_OTHER_ERROR);
return -1; return -1;
} }
fr->fr_header_block = header_block; 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", LSQ_INFO("headers are too large (%u bytes), skipping",
fr->fr_state.payload_length); fr->fr_state.payload_length);
fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, stream_id, fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, stream_id,
FR_ERR_HEADERS_TOO_LARGE); FR_ERR_BAD_HEADER);
/* fallthru */ /* fallthru */
continue_skipping: continue_skipping:
default: default:
@ -513,29 +513,20 @@ static int
decode_and_pass_payload (struct lsquic_frame_reader *fr) decode_and_pass_payload (struct lsquic_frame_reader *fr)
{ {
struct headers_state *hs = &fr->fr_state.by_type.headers_state; struct headers_state *hs = &fr->fr_state.by_type.headers_state;
const uint32_t hpack_static_table_size = 61;
const unsigned char *comp, *end; const unsigned char *comp, *end;
enum frame_reader_error err; enum frame_reader_error err;
int s; int s;
uint32_t name_idx;
lshpack_strlen_t name_len, val_len;
char *buf;
uint32_t stream_id32; uint32_t stream_id32;
struct uncompressed_headers *uh = NULL; struct uncompressed_headers *uh = NULL;
void *hset = NULL; void *hset = NULL;
struct lsxpack_header *hdr = NULL;
buf = lsquic_mm_get_16k(fr->fr_mm); size_t extra = 0;
if (!buf)
{
err = FR_ERR_NOMEM;
goto stream_error;
}
hset = fr->fr_hsi_if->hsi_create_header_set(fr->fr_hsi_ctx, hset = fr->fr_hsi_if->hsi_create_header_set(fr->fr_hsi_ctx,
READER_PUSH_PROMISE == fr->fr_state.reader_type); READER_PUSH_PROMISE == fr->fr_state.reader_type);
if (!hset) if (!hset)
{ {
err = FR_ERR_NOMEM; err = FR_ERR_OTHER_ERROR;
goto stream_error; goto stream_error;
} }
@ -544,40 +535,54 @@ decode_and_pass_payload (struct lsquic_frame_reader *fr)
while (comp < end) while (comp < end)
{ {
s = lshpack_dec_decode(fr->fr_hdec, &comp, end, prepare:
buf, buf + 16 * 1024, &name_len, &val_len, &name_idx); 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 (s == 0)
{ {
if (name_idx > hpack_static_table_size) s = fr->fr_hsi_if->hsi_process_header(hset, hdr);
name_idx = 0; /* Work around bug in ls-hpack */ if (s == 0)
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)
{ {
#if LSQUIC_CONN_STATS #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 #endif
extra = 0;
hdr = NULL;
continue; 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 else
err = FR_ERR_DECOMPRESS; err = FR_ERR_DECOMPRESS;
goto stream_error; goto stream_error;
} }
assert(comp == end); assert(comp == end);
lsquic_mm_put_16k(fr->fr_mm, buf);
buf = NULL;
err = (enum frame_reader_error) s = fr->fr_hsi_if->hsi_process_header(hset, NULL);
fr->fr_hsi_if->hsi_process_header(hset, 0, 0, 0, 0, 0); if (s != 0)
if (err) {
err = s < 0 ? FR_ERR_OTHER_ERROR : FR_ERR_BAD_HEADER;
goto stream_error; goto stream_error;
}
uh = calloc(1, sizeof(*uh)); uh = calloc(1, sizeof(*uh));
if (!uh) if (!uh)
{ {
err = FR_ERR_NOMEM; err = FR_ERR_OTHER_ERROR;
goto stream_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); LSQ_INFO("%s: stream error %u", __func__, err);
if (hset) if (hset)
fr->fr_hsi_if->hsi_discard_header_set(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); fr->fr_callbacks->frc_on_error(fr->fr_cb_ctx, fr_get_stream_id(fr), err);
return 0; return 0;
} }

View file

@ -36,18 +36,8 @@ enum frame_reader_flags
*/ */
enum frame_reader_error enum frame_reader_error
{ {
FR_ERR_DUPLICATE_PSEH = LSQUIC_HDR_ERR_DUPLICATE_PSDO_HDR, FR_ERR_BAD_HEADER,
FR_ERR_INCOMPL_REQ_PSEH = LSQUIC_HDR_ERR_INCOMPL_REQ_PSDO_HDR, FR_ERR_OTHER_ERROR,
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_DECOMPRESS, FR_ERR_DECOMPRESS,
FR_ERR_INVALID_FRAME_SIZE, /* E.g. a SETTINGS frame length is not a multiple FR_ERR_INVALID_FRAME_SIZE, /* E.g. a SETTINGS frame length is not a multiple

View file

@ -389,13 +389,13 @@ write_headers (struct lsquic_frame_writer *fw,
{ {
unsigned char *end; unsigned char *end;
int i, s; int i, s;
struct lsxpack_header hdr;
for (i = 0; i < headers->count; ++i) for (i = 0; i < headers->count; ++i)
{ {
end = lshpack_enc_encode(fw->fw_henc, buf, buf + buf_sz, lsquic_http_header_t *h = &headers->headers[i];
LSHPACK_HDR_UNKNOWN, lsxpack_header_set_ptr(&hdr, h->name.iov_base, h->name.iov_len,
(const lshpack_header_t *)&headers->headers[i], h->value.iov_base, h->value.iov_len);
0); end = lshpack_enc_encode(fw->fw_henc, buf, buf + buf_sz, &hdr);
if (end > buf) if (end > buf)
{ {
s = hfc_write(hfc, buf, end - buf); s = hfc_write(hfc, buf, end - buf);

View file

@ -2211,8 +2211,8 @@ process_ver_neg_packet (struct full_conn *conn, lsquic_packet_in_t *packet_in)
return; return;
} }
for (s = packet_in_ver_first(packet_in, &vi, &ver_tag); s; for (s = lsquic_packet_in_ver_first(packet_in, &vi, &ver_tag); s;
s = packet_in_ver_next(&vi, &ver_tag)) s = lsquic_packet_in_ver_next(&vi, &ver_tag))
{ {
version = lsquic_tag2ver(ver_tag); version = lsquic_tag2ver(ver_tag);
if (version < N_LSQVER) 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); max_packno = lsquic_rechist_largest_packno(&conn->fc_rechist);
bits = lsquic_packet_in_packno_bits(packet_in); bits = lsquic_packet_in_packno_bits(packet_in);
packet_len = conn->fc_conn.cn_pf->pf_packno_bits2len(bits); 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") " LSQ_DEBUG("reconstructed (bits: %u, packno: %"PRIu64", max: %"PRIu64") "
"to %"PRIu64"", bits, cur_packno, max_packno, packet_in->pi_packno); "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; void *hsi_ctx;
unsigned idx, i, n_headers; unsigned idx, i, n_headers;
const lsquic_http_header_t *header; const lsquic_http_header_t *header;
enum lsquic_header_status st; int st;
lsquic_http_header_t pseudo_headers[4]; lsquic_http_header_t pseudo_headers[4];
lsquic_http_headers_t all_headers[2]; lsquic_http_headers_t all_headers[2];
struct lsxpack_header *xhdr;
size_t extra;
if (!hset) 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 < all_headers[i].headers + all_headers[i].count;
++header) ++header)
{ {
idx = lshpack_enc_get_stx_tab_id(header->name.iov_base, extra = header->name.iov_len + header->value.iov_len + 4;
header->name.iov_len, header->value.iov_base, xhdr = conn->fc_enpub->enp_hsi_if->hsi_prepare_decode(hset,
header->value.iov_len); NULL, extra);
st = conn->fc_enpub->enp_hsi_if->hsi_process_header(hset, idx, if (!xhdr)
header->name.iov_base, header->name.iov_len, goto err;
header->value.iov_base, header->value.iov_len); 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) if (st)
goto err; goto err;
} }
st = conn->fc_enpub->enp_hsi_if->hsi_process_header(hset, 0, 0, 0, st = conn->fc_enpub->enp_hsi_if->hsi_process_header(hset, NULL);
0, 0);
if (st) if (st)
goto err; goto err;
} }
@ -3989,7 +4008,7 @@ synthesize_push_request (struct full_conn *conn, void *hset,
uh = malloc(sizeof(*uh)); uh = malloc(sizeof(*uh));
if (!uh) if (!uh)
{ {
st = LSQUIC_HDR_ERR_NOMEM; st = -__LINE__;
goto err; goto err;
} }
@ -4005,7 +4024,7 @@ synthesize_push_request (struct full_conn *conn, void *hset,
return uh; return uh;
err: err:
LSQ_INFO("%s: error %u", __func__, st); LSQ_INFO("%s: error %d", __func__, st);
return NULL; return NULL;
} }

View file

@ -18,6 +18,7 @@
#include "fiu-local.h" #include "fiu-local.h"
#include "lsquic.h" #include "lsquic.h"
#include "lsxpack_header.h"
#include "lsquic_types.h" #include "lsquic_types.h"
#include "lsquic_int_types.h" #include "lsquic_int_types.h"
#include "lsquic_attq.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) if (conn->ifc_settings->es_handshake_to)
lsquic_alarmset_set(&conn->ifc_alset, AL_HANDSHAKE, lsquic_alarmset_set(&conn->ifc_alset, AL_HANDSHAKE,
lsquic_time_now() + conn->ifc_settings->es_handshake_to); 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) if (conn->ifc_idle_to)
lsquic_alarmset_set(&conn->ifc_alset, AL_IDLE, now + 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) 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; goto err3;
conn->ifc_created = imc->imc_created; conn->ifc_created = imc->imc_created;
conn->ifc_idle_to = conn->ifc_settings->es_idle_timeout * 1000000;
if (conn->ifc_idle_to) if (conn->ifc_idle_to)
lsquic_alarmset_set(&conn->ifc_alset, AL_IDLE, lsquic_alarmset_set(&conn->ifc_alset, AL_IDLE,
imc->imc_created + conn->ifc_idle_to); 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; void *hsi_ctx;
struct uncompressed_headers *uh; struct uncompressed_headers *uh;
enum lsqpack_enc_status enc_st; enum lsqpack_enc_status enc_st;
enum lsquic_header_status header_st; int header_st;
unsigned i, name_idx, n_header_sets; unsigned i, n_header_sets;
int own_hset, stx_tab_id; int own_hset, stx_tab_id;
const unsigned hpack_static_table_size = 61;
unsigned char discard[2]; unsigned char discard[2];
struct lsxpack_header *xhdr;
size_t extra;
if (!ietf_full_conn_ci_is_push_enabled(lconn) if (!ietf_full_conn_ci_is_push_enabled(lconn)
|| !lsquic_stream_can_push(dep_stream)) || !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 < all_headers[i].headers + all_headers[i].count;
++header) ++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, stx_tab_id = lsqpack_get_stx_tab_id(header->name.iov_base,
header->name.iov_len, header->value.iov_base, header->name.iov_len, header->value.iov_base,
header->value.iov_len); header->value.iov_len);
if (stx_tab_id >= 0) 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); lsquic_mm_put_4k(conn->ifc_pub.mm, header_block_buf);
conn->ifc_enpub->enp_hsi_if->hsi_discard_header_set(hset); 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; return -1;
} }
} }
header_st = conn->ifc_enpub->enp_hsi_if->hsi_process_header(hset, 0, 0, header_st = conn->ifc_enpub->enp_hsi_if->hsi_process_header(hset, NULL);
0, 0, 0); if (header_st != 0)
if (header_st != LSQUIC_HDR_OK)
{ {
lsquic_mm_put_4k(conn->ifc_pub.mm, header_block_buf); lsquic_mm_put_4k(conn->ifc_pub.mm, header_block_buf);
conn->ifc_enpub->enp_hsi_if->hsi_discard_header_set(hset); 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; return -1;
} }
} }
@ -6406,8 +6425,8 @@ process_incoming_packet_verneg (struct ietf_full_conn *conn,
} }
versions = 0; versions = 0;
for (s = packet_in_ver_first(packet_in, &vi, &ver_tag); s; for (s = lsquic_packet_in_ver_first(packet_in, &vi, &ver_tag); s;
s = packet_in_ver_next(&vi, &ver_tag)) s = lsquic_packet_in_ver_next(&vi, &ver_tag))
{ {
version = lsquic_tag2ver(ver_tag); version = lsquic_tag2ver(ver_tag);
if (version < N_LSQVER) if (version < N_LSQVER)

View file

@ -338,12 +338,11 @@ static compress_cert_hash_item_t *make_compress_cert_hash_item(struct lsquic_str
#ifdef NDEBUG #ifdef NDEBUG
static static
enum hsk_failure_reason 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); 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 #endif
void lsquic_gen_stk(lsquic_server_config_t *, const struct sockaddr *, uint64_t tm,
unsigned char stk_out[STK_LENGTH]);
/* client */ /* client */
static c_cert_item_t *make_c_cert_item(struct lsquic_str **certs, int count); 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 static int
lsquic_handshake_init(int flags) lsquic_handshake_init(int flags)
{ {
crypto_init(); lsquic_crypto_init();
return init_hs_hash_tables(flags); 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) for (i = 0; i < count; ++i)
{ {
lsquic_str_copy(&item->crts[i], certs[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_len(certs[i]));
lsquic_str_append(item->hashs, (char *)&hash, 8); 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_prealloc(&cert_item->crts[i], len);
lsquic_str_setlen(&cert_item->crts[i], len); lsquic_str_setlen(&cert_item->crts[i], len);
memcpy(lsquic_str_buf(&cert_item->crts[i]), cert_data, 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); lsquic_str_append(cert_item->hashs, (char *)&hash, 8);
cert_len = (uint32_t *)(cert_data + len); 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; struct lsquic_enc_session *const enc_session = enc_session_p;
int include_pad; 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 = const struct lsquic_engine_settings *const settings =
&enc_session->enpub->enp_settings; &enc_session->enpub->enp_settings;
c_cert_item_t *const cert_item = enc_session->cert_item; 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)); MSG_LEN_ADD(msg_len, sizeof(enc_session->hs_ctx.nonc));
++n_tags; /* NONC */ ++n_tags; /* NONC */
RAND_bytes(enc_session->priv_key, 32); RAND_bytes(enc_session->priv_key, 32);
c255_get_pub_key(enc_session->priv_key, pub_key); lsquic_c255_get_pub_key(enc_session->priv_key, pub_key);
gen_nonce_c(enc_session->hs_ctx.nonc, enc_session->info->orbt); lsquic_gen_nonce_c(enc_session->hs_ctx.nonc, enc_session->info->orbt);
} }
} }
include_pad = MSG_LEN_VAL(msg_len) < MIN_CHLO_SIZE; 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; 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) if (hfr != HFR_HANDSHAKE_OK)
{ {
hs_ctx->rrej = hfr; 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->skt_key, sizeof(temp_scfg->skt_key));
RAND_bytes(temp_scfg->sscid, sizeof(temp_scfg->sscid)); RAND_bytes(temp_scfg->sscid, sizeof(temp_scfg->sscid));
RAND_bytes(temp_scfg->priv_key, sizeof(temp_scfg->priv_key)); 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->aead = settings->es_aead;
temp_scfg->kexs = settings->es_kexs; temp_scfg->kexs = settings->es_kexs;
temp_scfg->pdmd = settings->es_pdmd; temp_scfg->pdmd = settings->es_pdmd;
@ -1926,7 +1925,7 @@ generate_crt (struct lsquic_enc_session *enc_session, int common_case)
OPENSSL_free(out); 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)) &hs_ctx->crt))
goto cleanup; goto cleanup;
@ -1980,7 +1979,7 @@ gen_rej1_data (struct lsquic_enc_session *enc_session, uint8_t *data,
* This is the most common case * This is the most common case
*/ */
common_case = lsquic_str_len(&hs_ctx->ccrt) == 0 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) if (common_case)
compress_certs_item = find_compress_certs(&hs_ctx->sni); compress_certs_item = find_compress_certs(&hs_ctx->sni);
else 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 rej1 data");
LSQ_DEBUG("gQUIC NOT enabled"); 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), (size_t)lsquic_str_len(&enc_session->chlo),
scfg_data, scfg_len, scfg_data, scfg_len,
rsa_priv_key, (uint8_t *)prof_buf, &prof_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_prealloc(&enc_session->sstk, STK_LENGTH);
lsquic_str_setlen(&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)); (unsigned char *) lsquic_str_buf(&enc_session->sstk));
if (lsquic_str_len(&enc_session->ssno) != SNO_LENGTH) 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(nonce, 32);
RAND_bytes(enc_session->priv_key, 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) if (lsquic_str_len(&enc_session->sstk) != STK_LENGTH)
{ {
lsquic_str_d(&enc_session->sstk); lsquic_str_d(&enc_session->sstk);
lsquic_str_prealloc(&enc_session->sstk, STK_LENGTH); lsquic_str_prealloc(&enc_session->sstk, STK_LENGTH);
lsquic_str_setlen(&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)); (unsigned char *) lsquic_str_buf(&enc_session->sstk));
if (lsquic_str_len(&enc_session->ssno) != SNO_LENGTH) 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; size_t i;
X509 *cert, *server_cert; X509 *cert, *server_cert;
STACK_OF(X509) *chain = NULL; 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); out_certs, out_certs_count);
if (ret) if (ret)
return 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); lsquic_str_len(out_certs[0]), 0);
pub_key = X509_get_pubkey(server_cert); 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), (size_t)lsquic_str_len(&enc_session->chlo),
&enc_session->info->scfg, &enc_session->info->scfg,
pub_key, 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)); lsquic_str_len(&enc_session->hs_ctx.prof));
EVP_PKEY_free(pub_key); EVP_PKEY_free(pub_key);
if (ret != 0) if (ret != 0)
{
LSQ_DEBUG("cannot verify server proof");
goto cleanup; goto cleanup;
}
if (enc_session->enpub->enp_verify_cert) 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); sk_X509_push(chain, server_cert);
for (i = 1; i < *out_certs_count; ++i) 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); lsquic_str_len(out_certs[i]), 0);
if (cert) if (cert)
sk_X509_push(chain, cert); sk_X509_push(chain, cert);
@ -2505,7 +2507,7 @@ determine_keys (struct lsquic_enc_session *enc_session)
key_flag = 'F'; 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, enc_session->hs_ctx.pubs,
(unsigned char *)shared_key_c); (unsigned char *)shared_key_c);
if (is_client) 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", LSQ_DEBUG("export_key_material lsquic_c255_gen_share_key %s",
get_bin_str(shared_key_c, 32, 512)); lsquic_get_bin_str(shared_key_c, 32, 512));
memcpy(hkdf_input_p, enc_session->cid.idbuf, enc_session->cid.len); memcpy(hkdf_input_p, enc_session->cid.idbuf, enc_session->cid.len);
hkdf_input_p += 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) 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) if (out_certs_count > 0)
{ {
out_certs = malloc(out_certs_count * sizeof(lsquic_str_t *)); 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 static
#endif #endif
void 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]) uint64_t tm, unsigned char stk_out[STK_LENGTH])
{ {
unsigned char stk[STK_LENGTH + 16]; 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); memcpy(stk + 16, &tm, 8);
RAND_bytes(stk + 24, STK_LENGTH - 24 - 12); RAND_bytes(stk + 24, STK_LENGTH - 24 - 12);
RAND_bytes(stk_out + STK_LENGTH - 12, 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); 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 static
#endif #endif
enum hsk_failure_reason 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, lsquic_server_config_t *server_config,
const struct sockaddr *ip_addr, uint64_t tm, lsquic_str_t *stk, const struct sockaddr *ip_addr, uint64_t tm, lsquic_str_t *stk,
unsigned secs_since_stk_generated) 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) if (lsquic_str_len(stk) < STK_LENGTH)
return HFR_SRC_ADDR_TOKEN_INVALID; 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, stks + STK_LENGTH - 12, 12, stks,
STK_LENGTH - 12, stk_out, &out_len); STK_LENGTH - 12, stk_out, &out_len);
if (ret != 0) if (ret != 0)
{ {
LSQ_DEBUG("***verify_stk decrypted failed."); LSQ_DEBUG("***lsquic_verify_stk decrypted failed.");
return HFR_SRC_ADDR_TOKEN_DECRYPTION; 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) 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; 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) 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; 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); memcpy((void *)&tm0, stk_out + 16, 8);
if (tm < tm0) 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; 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 */ || if (tm > server_config->lsc_scfg->info.expy /* XXX this check does not seem needed */ ||
tm0 > exp) tm0 > exp)
{ {
LSQ_DEBUG("***verify_stk stk expired"); LSQ_DEBUG("***lsquic_verify_stk stk expired");
return HFR_SRC_ADDR_TOKEN_EXPIRED; return HFR_SRC_ADDR_TOKEN_EXPIRED;
} }
LSQ_DEBUG("***verify_stk pass."); LSQ_DEBUG("***lsquic_verify_stk pass.");
return HFR_HANDSHAKE_OK; return HFR_HANDSHAKE_OK;
} }
@ -2913,7 +2915,7 @@ verify_stk0 (const struct lsquic_enc_session *enc_session,
static static
#endif #endif
enum hsk_failure_reason 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) const struct sockaddr *ip_addr, uint64_t tm, lsquic_str_t *stk)
{ {
struct lsquic_enc_session *const enc_session = enc_session_p; 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; return HFR_SRC_ADDR_TOKEN_INVALID;
} }
else else
return verify_stk0(enc_session, enc_session->server_config, ip_addr, return lsquic_verify_stk0(enc_session, enc_session->server_config,
tm, stk, 0); ip_addr, tm, stk, 0);
} }
@ -2954,17 +2956,17 @@ verify_packet_hash (const struct lsquic_enc_session *enc_session,
return -1; return -1;
if (!enc_session || (IS_SERVER(enc_session))) 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, buf + *header_len + HS_PKT_HASH_LENGTH,
data_len - HS_PKT_HASH_LENGTH, data_len - HS_PKT_HASH_LENGTH,
(unsigned char *) "Client", 6); (unsigned char *) "Client", 6);
else else
hash = fnv1a_128_3(buf, *header_len, hash = lsquic_fnv1a_128_3(buf, *header_len,
buf + *header_len + HS_PKT_HASH_LENGTH, buf + *header_len + HS_PKT_HASH_LENGTH,
data_len - HS_PKT_HASH_LENGTH, data_len - HS_PKT_HASH_LENGTH,
(unsigned char *) "Server", 6); (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); ret = memcmp(md, buf + *header_len, HS_PKT_HASH_LENGTH);
if(ret == 0) if(ret == 0)
{ {
@ -3017,7 +3019,7 @@ decrypt_packet (struct lsquic_enc_session *enc_session, uint8_t path_id,
sizeof(path_id_packet_number)); sizeof(path_id_packet_number));
*out_len = data_len; *out_len = data_len;
ret = aes_aead_dec(key, ret = lsquic_aes_aead_dec(key,
buf, *header_len, buf, *header_len,
nonce, 12, nonce, 12,
buf + *header_len, data_len, buf + *header_len, data_len,
@ -3166,13 +3168,13 @@ gquic_encrypt_buf (struct lsquic_enc_session *enc_session,
return -1; return -1;
if (!enc_session || (IS_SERVER(enc_session))) 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); (unsigned char *) "Server", 6);
else 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); (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, header_len);
memcpy(buf_out + header_len, md, HS_PKT_HASH_LENGTH); memcpy(buf_out + header_len, md, HS_PKT_HASH_LENGTH);
memcpy(buf_out + header_len + HS_PKT_HASH_LENGTH, data, data_len); 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); memcpy(buf_out, header, header_len);
*out_len = max_out_len - 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); data_len, buf_out + header_len, out_len);
if (ret == 0) 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(); chain = sk_X509_new_null();
for (i = 0; i < item->count; ++i) 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); lsquic_str_len(&item->crts[i]), 0);
if (cert) if (cert)
sk_X509_push(chain, cert); sk_X509_push(chain, cert);

View file

@ -26,15 +26,13 @@ typedef struct cert_hash_item_st
} cert_hash_item_t; } cert_hash_item_t;
#ifndef NDEBUG #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 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_server_config *, const struct sockaddr *ip_addr, uint64_t tm,
struct lsquic_str *stk, struct lsquic_str *stk,
unsigned secs_since_stk_generated); unsigned secs_since_stk_generated);
enum hsk_failure_reason 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); uint64_t tm, struct lsquic_str *stk);
struct cert_hash_item_st* c_find_certs(const struct lsquic_str *domain); struct cert_hash_item_st* c_find_certs(const struct lsquic_str *domain);
#endif #endif

View file

@ -218,7 +218,7 @@ hqft2str (enum hq_frame_type type)
} }
int static int
hcso_write_number_frame (struct hcso_writer *writer, hcso_write_number_frame (struct hcso_writer *writer,
enum hq_frame_type type, uint64_t value) enum hq_frame_type type, uint64_t value)
{ {

View file

@ -81,7 +81,7 @@ static lsquic_stream_ctx_t *
headers_on_new_stream (void *stream_if_ctx, lsquic_stream_t *stream) headers_on_new_stream (void *stream_if_ctx, lsquic_stream_t *stream)
{ {
struct headers_stream *hs = stream_if_ctx; 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)) if (0 != lshpack_enc_init(&hs->hs_henc))
{ {
LSQ_WARN("could not initialize HPACK encoder: %s", strerror(errno)); 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; struct headers_stream *hs = ctx;
switch (err) switch (err)
{ {
case FR_ERR_DUPLICATE_PSEH: case FR_ERR_BAD_HEADER:
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_DECOMPRESS: case FR_ERR_DECOMPRESS:
case FR_ERR_HEADERS_TOO_LARGE:
case FR_ERR_SELF_DEP_STREAM: case FR_ERR_SELF_DEP_STREAM:
LSQ_INFO("error %u is a stream error (stream %"PRIu64")", err, LSQ_INFO("error %u is a stream error (stream %"PRIu64")", err,
stream_id); 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_NONZERO_STREAM_ID:
case FR_ERR_UNEXPECTED_PUSH: case FR_ERR_UNEXPECTED_PUSH:
case FR_ERR_ZERO_STREAM_ID: case FR_ERR_ZERO_STREAM_ID:
case FR_ERR_NOMEM:
case FR_ERR_EXPECTED_CONTIN: case FR_ERR_EXPECTED_CONTIN:
case FR_ERR_OTHER_ERROR:
LSQ_INFO("error %u is a connection error (stream %"PRIu64")", err, LSQ_INFO("error %u is a connection error (stream %"PRIu64")", err,
stream_id); stream_id);
hs->hs_callbacks->hsc_on_conn_error(hs->hs_cb_ctx); hs->hs_callbacks->hsc_on_conn_error(hs->hs_cb_ctx);

View file

@ -52,6 +52,9 @@ struct header_writer_ctx
enum pseudo_header pseh_mask; enum pseudo_header pseh_mask;
char *pseh_bufs[N_PSEH]; char *pseh_bufs[N_PSEH];
struct http1x_headers hwc_h1h; 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, save_pseudo_header (struct header_writer_ctx *hwc, enum pseudo_header ph,
const char *val, unsigned val_len) 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]); assert(!hwc->pseh_bufs[ph]);
hwc->pseh_bufs[ph] = malloc(val_len + 1); hwc->pseh_bufs[ph] = malloc(val_len + 1);
if (!hwc->pseh_bufs[ph]) if (!hwc->pseh_bufs[ph])
return LSQUIC_HDR_ERR_NOMEM; return -1;
hwc->pseh_mask |= BIT(ph); hwc->pseh_mask |= BIT(ph);
memcpy(hwc->pseh_bufs[ph], val, val_len); memcpy(hwc->pseh_bufs[ph], val, val_len);
hwc->pseh_bufs[ph][val_len] = '\0'; hwc->pseh_bufs[ph][val_len] = '\0';
return LSQUIC_HDR_OK; return 0;
} }
else else
{ {
LSQ_INFO("header %u is already present", ph); LSQ_INFO("header %u is already present", ph);
return LSQUIC_HDR_ERR_DUPLICATE_PSDO_HDR; return 1;
} }
} }
static enum lsquic_header_status static int
add_pseudo_header (struct header_writer_ctx *hwc, const char *name, add_pseudo_header (struct header_writer_ctx *hwc, struct lsxpack_header *xhdr)
unsigned name_len, const char *val, unsigned val_len)
{ {
const char *name, *val;
unsigned name_len, val_len;
if (!(hwc->hwc_flags & HWC_EXPECT_COLON)) if (!(hwc->hwc_flags & HWC_EXPECT_COLON))
{ {
LSQ_INFO("unexpected 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) switch (name_len)
{ {
case 5: 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); 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) convert_response_pseudo_headers (struct header_writer_ctx *hwc)
{ {
if ((hwc->pseh_mask & REQUIRED_SERVER_PSEH) != REQUIRED_SERVER_PSEH) if ((hwc->pseh_mask & REQUIRED_SERVER_PSEH) != REQUIRED_SERVER_PSEH)
{ {
LSQ_INFO("not all response pseudo-headers are specified"); 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) if (hwc->pseh_mask & ALL_REQUEST_PSEH)
{ {
LSQ_INFO("response pseudo-headers contain request-only headers"); LSQ_INFO("response pseudo-headers contain request-only headers");
return LSQUIC_HDR_ERR_UNNEC_REQ_PSDO_HDR; return 1;
} }
const char *code_str, *reason; 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 { \ #define HWC_UH_WRITE(h, buf, sz) do { \
if (0 != hwc_uh_write(h, buf, sz)) \ if (0 != hwc_uh_write(h, buf, sz)) \
return LSQUIC_HDR_ERR_NOMEM; \ return -1; \
} while (0) } while (0)
HWC_UH_WRITE(hwc, "HTTP/1.1 ", 9); 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) if (hwc->max_headers_sz && hwc->w_off > hwc->max_headers_sz)
{ {
LSQ_INFO("headers too large"); LSQ_INFO("headers too large");
return LSQUIC_HDR_ERR_HEADERS_TOO_LARGE; return 1;
} }
return LSQUIC_HDR_OK; return 0;
#undef HWC_UH_WRITE #undef HWC_UH_WRITE
} }
static enum lsquic_header_status static int
convert_request_pseudo_headers (struct header_writer_ctx *hwc) convert_request_pseudo_headers (struct header_writer_ctx *hwc)
{ {
if ((hwc->pseh_mask & REQUIRED_REQUEST_PSEH) != REQUIRED_REQUEST_PSEH) if ((hwc->pseh_mask & REQUIRED_REQUEST_PSEH) != REQUIRED_REQUEST_PSEH)
{ {
LSQ_INFO("not all request pseudo-headers are specified"); 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) if (hwc->pseh_mask & ALL_SERVER_PSEH)
{ {
LSQ_INFO("request pseudo-headers contain response-only headers"); 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 { \ #define HWC_UH_WRITE(h, buf, sz) do { \
if (0 != hwc_uh_write(h, buf, sz)) \ if (0 != hwc_uh_write(h, buf, sz)) \
return LSQUIC_HDR_ERR_NOMEM; \ return -1; \
} while (0) } while (0)
HWC_UH_WRITE(hwc, HWC_PSEH_VAL(hwc, PSEH_METHOD), HWC_PSEH_LEN(hwc, PSEH_METHOD)); 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) if (hwc->max_headers_sz && hwc->w_off > hwc->max_headers_sz)
{ {
LSQ_INFO("headers too large"); LSQ_INFO("headers too large");
return LSQUIC_HDR_ERR_HEADERS_TOO_LARGE; return 1;
} }
return 0; 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) convert_pseudo_headers (struct header_writer_ctx *hwc)
{ {
/* We are *reading* the message. Thus, a server expects a request, and a /* 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) save_cookie (struct header_writer_ctx *hwc, const char *val, unsigned val_len)
{ {
char *cookie_val; 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; hwc->cookie_nalloc = hwc->cookie_sz = val_len;
cookie_val = malloc(hwc->cookie_nalloc); cookie_val = malloc(hwc->cookie_nalloc);
if (!cookie_val) if (!cookie_val)
return LSQUIC_HDR_ERR_NOMEM; return -1;
hwc->cookie_val = cookie_val; hwc->cookie_val = cookie_val;
memcpy(hwc->cookie_val, val, val_len); 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; hwc->cookie_nalloc = hwc->cookie_nalloc * 2 + val_len + 2;
cookie_val = realloc(hwc->cookie_val, hwc->cookie_nalloc); cookie_val = realloc(hwc->cookie_val, hwc->cookie_nalloc);
if (!cookie_val) if (!cookie_val)
return LSQUIC_HDR_ERR_NOMEM; return -1;
hwc->cookie_val = cookie_val; hwc->cookie_val = cookie_val;
} }
memcpy(hwc->cookie_val + hwc->cookie_sz - val_len - 2, "; ", 2); 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 static int
add_real_header (struct header_writer_ctx *hwc, const char *name, add_real_header (struct header_writer_ctx *hwc, struct lsxpack_header *xhdr)
unsigned name_len, const char *val, unsigned val_len)
{ {
enum lsquic_header_status err; int err;
unsigned i; unsigned i;
int n_upper; int n_upper;
const char *name, *val;
unsigned name_len, val_len;
if (hwc->hwc_flags & HWC_EXPECT_COLON) 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; 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)) if (4 == name_len && 0 == memcmp(name, "host", 4))
hwc->hwc_flags |= HWC_SEEN_HOST; 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", LSQ_INFO("Header name `%.*s' contains uppercase letters",
name_len, name); name_len, name);
return LSQUIC_HDR_ERR_UPPERCASE_HEADER; return 1;
} }
if (6 == name_len && memcmp(name, "cookie", 6) == 0) 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 { \ #define HWC_UH_WRITE(h, buf, sz) do { \
if (0 != hwc_uh_write(h, buf, sz)) \ if (0 != hwc_uh_write(h, buf, sz)) \
return LSQUIC_HDR_ERR_NOMEM; \ return -1; \
} while (0) } while (0)
HWC_UH_WRITE(hwc, name, name_len); 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) if (hwc->max_headers_sz && hwc->w_off > hwc->max_headers_sz)
{ {
LSQ_INFO("headers too large"); LSQ_INFO("headers too large");
return LSQUIC_HDR_ERR_HEADERS_TOO_LARGE; return 1;
} }
return 0; return 0;
@ -420,22 +436,25 @@ add_real_header (struct header_writer_ctx *hwc, const char *name,
} }
static enum lsquic_header_status static int
add_header_to_uh (struct header_writer_ctx *hwc, const char *name, add_header_to_uh (struct header_writer_ctx *hwc, struct lsxpack_header *xhdr)
unsigned name_len, const char *val, unsigned val_len)
{ {
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]) if (':' == name[0])
return add_pseudo_header(hwc, name, name_len, val, val_len); return add_pseudo_header(hwc, xhdr);
else 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) h1h_finish_hset (struct header_writer_ctx *hwc)
{ {
enum lsquic_header_status st; int st;
if (hwc->hwc_flags & HWC_EXPECT_COLON) 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) if (hwc->max_headers_sz && hwc->w_off > hwc->max_headers_sz)
{ {
LSQ_INFO("headers too large"); 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 *) \ #define HWC_PTR(data_in) (struct header_writer_ctx *) \
((unsigned char *) (hset) - offsetof(struct header_writer_ctx, hwc_h1h)) ((unsigned char *) (hset) - offsetof(struct header_writer_ctx, hwc_h1h))
static enum lsquic_header_status
h1h_process_header (void *hset, unsigned name_idx, static struct lsxpack_header *
const char *name, unsigned name_len, h1h_prepare_decode (void *hset, struct lsxpack_header *xhdr, size_t extra_space)
const char *value, unsigned value_len)
{ {
struct header_writer_ctx *const hwc = HWC_PTR(hset); struct header_writer_ctx *const hwc = HWC_PTR(hset);
if (name) size_t min_space;
return add_header_to_uh(hwc, name, name_len, value, value_len);
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 else
return h1h_finish_hset(hwc); return h1h_finish_hset(hwc);
} }
@ -511,6 +572,7 @@ h1h_discard_header_set (void *hset)
if (hwc->cookie_val) if (hwc->cookie_val)
free(hwc->cookie_val); free(hwc->cookie_val);
free(hwc->hwc_h1h.h1h_buf); free(hwc->hwc_h1h.h1h_buf);
free(hwc->hwc_header_buf);
free(hwc); free(hwc);
} }
@ -518,6 +580,7 @@ h1h_discard_header_set (void *hset)
static const struct lsquic_hset_if http1x_if = static const struct lsquic_hset_if http1x_if =
{ {
.hsi_create_header_set = h1h_create_header_set, .hsi_create_header_set = h1h_create_header_set,
.hsi_prepare_decode = h1h_prepare_decode,
.hsi_process_header = h1h_process_header, .hsi_process_header = h1h_process_header,
.hsi_discard_header_set = h1h_discard_header_set, .hsi_discard_header_set = h1h_discard_header_set,
}; };

View file

@ -185,7 +185,7 @@ packet_in_is_ok (enum lsquic_version version,
lsquic_conn_t * 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, const struct lsquic_packet_in *packet_in,
enum lsquic_version version) enum lsquic_version version)
{ {
@ -1852,6 +1852,7 @@ mini_conn_ci_Q050_packet_in (struct lsquic_conn *lconn,
return; return;
} }
if (!mc->mc_conn.cn_enc_session) if (!mc->mc_conn.cn_enc_session)
{ {
mc->mc_conn.cn_enc_session = mc->mc_conn.cn_enc_session =

View file

@ -149,8 +149,8 @@ struct mini_conn {
}; };
lsquic_conn_t * lsquic_conn_t *
mini_conn_new (struct lsquic_engine_public *, const struct lsquic_packet_in *, lsquic_mini_conn_new (struct lsquic_engine_public *,
enum lsquic_version version); const struct lsquic_packet_in *, enum lsquic_version version);
/* Packet numbers start with 1. By subtracting 1, we can utilize the full /* Packet numbers start with 1. By subtracting 1, we can utilize the full
* length of the bitmask. * length of the bitmask.

View file

@ -25,7 +25,7 @@
void 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) unsigned clock_granularity)
{ {
memset(pacer, 0, sizeof(*pacer)); memset(pacer, 0, sizeof(*pacer));
@ -36,7 +36,7 @@ pacer_init (struct pacer *pacer, const struct lsquic_conn *conn,
void void
pacer_cleanup (struct pacer *pacer) lsquic_pacer_cleanup (struct pacer *pacer)
{ {
#ifndef NDEBUG #ifndef NDEBUG
LSQ_DEBUG("scheduled calls: %u", pacer->pa_stats.n_scheduled); LSQ_DEBUG("scheduled calls: %u", pacer->pa_stats.n_scheduled);
@ -45,7 +45,7 @@ pacer_cleanup (struct pacer *pacer)
void 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) int in_recovery, tx_time_f tx_time, void *tx_ctx)
{ {
lsquic_time_t delay, sched_time; lsquic_time_t delay, sched_time;
@ -98,7 +98,7 @@ pacer_packet_scheduled (struct pacer *pacer, unsigned n_in_flight,
void void
pacer_loss_event (struct pacer *pacer) lsquic_pacer_loss_event (struct pacer *pacer)
{ {
pacer->pa_burst_tokens = 0; pacer->pa_burst_tokens = 0;
LSQ_DEBUG("%s: tokens: %u", __func__, pacer->pa_burst_tokens); LSQ_DEBUG("%s: tokens: %u", __func__, pacer->pa_burst_tokens);
@ -106,7 +106,7 @@ pacer_loss_event (struct pacer *pacer)
int int
pacer_can_schedule (struct pacer *pacer, unsigned n_in_flight) lsquic_pacer_can_schedule (struct pacer *pacer, unsigned n_in_flight)
{ {
int can; int can;
@ -126,7 +126,7 @@ pacer_can_schedule (struct pacer *pacer, unsigned n_in_flight)
void 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); assert(now >= pacer->pa_now);
pacer->pa_now = now; pacer->pa_now = now;
@ -137,7 +137,7 @@ pacer_tick_in (struct pacer *pacer, lsquic_time_t now)
void void
pacer_tick_out (struct pacer *pacer) lsquic_pacer_tick_out (struct pacer *pacer)
{ {
if ((pacer->pa_flags & PA_DELAYED_ON_TICK_IN) if ((pacer->pa_flags & PA_DELAYED_ON_TICK_IN)
&& pacer->pa_n_scheduled == 0 && pacer->pa_n_scheduled == 0

View file

@ -33,30 +33,30 @@ struct pacer
typedef lsquic_time_t (*tx_time_f)(void *ctx); typedef lsquic_time_t (*tx_time_f)(void *ctx);
void void
pacer_init (struct pacer *, const struct lsquic_conn *, lsquic_pacer_init (struct pacer *, const struct lsquic_conn *,
unsigned clock_granularity); unsigned clock_granularity);
void void
pacer_cleanup (struct pacer *); lsquic_pacer_cleanup (struct pacer *);
void void
pacer_tick_in (struct pacer *, lsquic_time_t); lsquic_pacer_tick_in (struct pacer *, lsquic_time_t);
void void
pacer_tick_out (struct pacer *); lsquic_pacer_tick_out (struct pacer *);
int int
pacer_can_schedule (struct pacer *, unsigned n_in_flight); lsquic_pacer_can_schedule (struct pacer *, unsigned n_in_flight);
void 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); int in_recovery, tx_time_f tx_time, void *tx_ctx);
void 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 #endif

View file

@ -8,7 +8,7 @@
lsquic_packno_t lsquic_packno_t
restore_packno (lsquic_packno_t cur_packno, lsquic_restore_packno (lsquic_packno_t cur_packno,
unsigned len, unsigned len,
lsquic_packno_t max_packno) lsquic_packno_t max_packno)
{ {

View file

@ -92,7 +92,7 @@ enum PACKET_PUBLIC_FLAGS
#define gquic_packno_bits2len(b) (((b) << 1) + !(b)) #define gquic_packno_bits2len(b) (((b) << 1) + !(b))
lsquic_packno_t lsquic_packno_t
restore_packno (lsquic_packno_t cur_packno, lsquic_restore_packno (lsquic_packno_t cur_packno,
unsigned packet_len, unsigned packet_len,
lsquic_packno_t max_packno); lsquic_packno_t max_packno);

View file

@ -14,17 +14,17 @@
int int
packet_in_ver_first (const lsquic_packet_in_t *packet_in, struct ver_iter *vi, lsquic_packet_in_ver_first (const lsquic_packet_in_t *packet_in,
lsquic_ver_tag_t *ver_tag) struct ver_iter *vi, lsquic_ver_tag_t *ver_tag)
{ {
vi->packet_in = packet_in; vi->packet_in = packet_in;
vi->off = packet_in->pi_quic_ver; 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 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) if (vi->off + 4 <= vi->packet_in->pi_header_sz)
{ {

View file

@ -159,11 +159,11 @@ struct ver_iter
}; };
int int
packet_in_ver_first (const lsquic_packet_in_t *packet_in, struct ver_iter *, lsquic_packet_in_ver_first (const lsquic_packet_in_t *packet_in,
lsquic_ver_tag_t *ver_tag); struct ver_iter *, lsquic_ver_tag_t *ver_tag);
int 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 size_t
lsquic_packet_in_mem_used (const struct lsquic_packet_in *); lsquic_packet_in_mem_used (const struct lsquic_packet_in *);

View file

@ -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) srec_one_posi_next (struct packet_out_srec_iter *posi)
{ {
return NULL; return NULL;
} }
struct stream_rec * static struct stream_rec *
srec_arr_posi_next (struct packet_out_srec_iter *posi) srec_arr_posi_next (struct packet_out_srec_iter *posi)
{ {
while (posi->cur_srec_arr) while (posi->cur_srec_arr)
@ -96,7 +96,7 @@ static struct stream_rec * (* const posi_nexts[])
struct stream_rec * 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) lsquic_packet_out_t *packet_out)
{ {
posi->impl_idx = !!(packet_out->po_flags & PO_SREC_ARR); 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 * 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); 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 n_stream_frames = 0, n_elided = 0;
int victim; 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) 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_data_sz);
packet_out->po_regen_sz = 0; 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) if (srec->sr_frame_type == QUIC_FRAME_STREAM)
srec->sr_off -= delta; 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 packet_out_srec_iter posi;
struct stream_rec *srec; 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); 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; const struct stream_rec *srec;
unsigned off; unsigned off;
srec = posi_first(&posi, packet_out); srec = lsquic_posi_first(&posi, packet_out);
assert(srec); assert(srec);
off = 0; off = 0;
for ( ; srec; srec = posi_next(&posi)) for ( ; srec; srec = lsquic_posi_next(&posi))
{ {
assert(srec->sr_off == off); assert(srec->sr_off == off);
assert(srec->sr_frame_type == frame_type); assert(srec->sr_frame_type == frame_type);
@ -635,7 +638,8 @@ lsquic_packet_out_split_in_two (struct lsquic_mm *mm,
#ifdef WIN32 #ifdef WIN32
max_idx = 0; max_idx = 0;
#endif #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 assert(srec->sr_frame_type == QUIC_FRAME_STREAM
|| srec->sr_frame_type == QUIC_FRAME_CRYPTO); || 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; uint64_t last_offset;
int len; 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 if (srec->sr_frame_type == QUIC_FRAME_STREAM
&& srec->sr_stream == stream) && srec->sr_stream == stream)
{ {

View file

@ -279,10 +279,10 @@ struct packet_out_srec_iter {
struct stream_rec * 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 * 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_t *
lsquic_packet_out_new (struct lsquic_mm *, struct malo *, int use_cid, lsquic_packet_out_new (struct lsquic_mm *, struct malo *, int use_cid,

View file

@ -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]; extern const enum quic_frame_type lsquic_iquic_byte2type[0x40];
size_t 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); uint64_t offset, unsigned);
size_t size_t

View file

@ -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, gquic_Q046_parse_packet_in_finish (struct lsquic_packet_in *packet_in,
struct packin_parse_state *state) 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_gen_reg_pkt_header = gquic_Q046_gen_reg_pkt_header,
.pf_parse_packet_in_finish = gquic_Q046_parse_packet_in_finish, .pf_parse_packet_in_finish = gquic_Q046_parse_packet_in_finish,
.pf_gen_stream_frame = gquic_be_gen_stream_frame, .pf_gen_stream_frame = lsquic_gquic_be_gen_stream_frame,
.pf_calc_stream_frame_header_sz = calc_stream_frame_header_sz_gquic, .pf_calc_stream_frame_header_sz = lsquic_calc_stream_frame_header_sz_gquic,
.pf_parse_stream_frame = gquic_be_parse_stream_frame, .pf_parse_stream_frame = lsquic_gquic_be_parse_stream_frame,
.pf_parse_ack_frame = gquic_be_parse_ack_frame, .pf_parse_ack_frame = lsquic_gquic_be_parse_ack_frame,
.pf_gen_ack_frame = gquic_be_gen_ack_frame, .pf_gen_ack_frame = lsquic_gquic_be_gen_ack_frame,
.pf_gen_stop_waiting_frame = gquic_be_gen_stop_waiting_frame, .pf_gen_stop_waiting_frame = lsquic_gquic_be_gen_stop_waiting_frame,
.pf_parse_stop_waiting_frame = gquic_be_parse_stop_waiting_frame, .pf_parse_stop_waiting_frame = lsquic_gquic_be_parse_stop_waiting_frame,
.pf_skip_stop_waiting_frame = gquic_be_skip_stop_waiting_frame, .pf_skip_stop_waiting_frame = lsquic_gquic_be_skip_stop_waiting_frame,
.pf_gen_window_update_frame = gquic_be_gen_window_update_frame, .pf_gen_window_update_frame = lsquic_gquic_be_gen_window_update_frame,
.pf_parse_window_update_frame = gquic_be_parse_window_update_frame, .pf_parse_window_update_frame = lsquic_gquic_be_parse_window_update_frame,
.pf_gen_blocked_frame = gquic_be_gen_blocked_frame, .pf_gen_blocked_frame = lsquic_gquic_be_gen_blocked_frame,
.pf_parse_blocked_frame = gquic_be_parse_blocked_frame, .pf_parse_blocked_frame = lsquic_gquic_be_parse_blocked_frame,
.pf_gen_rst_frame = gquic_be_gen_rst_frame, .pf_gen_rst_frame = lsquic_gquic_be_gen_rst_frame,
.pf_parse_rst_frame = gquic_be_parse_rst_frame, .pf_parse_rst_frame = lsquic_gquic_be_parse_rst_frame,
.pf_connect_close_frame_size = gquic_be_connect_close_frame_size, .pf_connect_close_frame_size = lsquic_gquic_be_connect_close_frame_size,
.pf_gen_connect_close_frame = gquic_be_gen_connect_close_frame, .pf_gen_connect_close_frame = lsquic_gquic_be_gen_connect_close_frame,
.pf_parse_connect_close_frame = gquic_be_parse_connect_close_frame, .pf_parse_connect_close_frame = lsquic_gquic_be_parse_connect_close_frame,
.pf_gen_goaway_frame = gquic_be_gen_goaway_frame, .pf_gen_goaway_frame = lsquic_gquic_be_gen_goaway_frame,
.pf_parse_goaway_frame = gquic_be_parse_goaway_frame, .pf_parse_goaway_frame = lsquic_gquic_be_parse_goaway_frame,
.pf_gen_ping_frame = gquic_be_gen_ping_frame, .pf_gen_ping_frame = lsquic_gquic_be_gen_ping_frame,
#ifndef NDEBUG #ifndef NDEBUG
.pf_write_float_time16 = gquic_be_write_float_time16, .pf_write_float_time16 = lsquic_gquic_be_write_float_time16,
.pf_read_float_time16 = gquic_be_read_float_time16, .pf_read_float_time16 = lsquic_gquic_be_read_float_time16,
#endif #endif
.pf_generate_simple_prst = gquic_Q046_generate_simple_prst, .pf_generate_simple_prst = gquic_Q046_generate_simple_prst,
.pf_parse_frame_type = lsquic_parse_frame_type_gquic_Q035_thru_Q046, .pf_parse_frame_type = lsquic_parse_frame_type_gquic_Q035_thru_Q046,

View file

@ -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, gquic_Q050_parse_packet_in_finish (struct lsquic_packet_in *packet_in,
struct packin_parse_state *state) 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_gen_reg_pkt_header = gquic_Q050_gen_reg_pkt_header,
.pf_parse_packet_in_finish = gquic_Q050_parse_packet_in_finish, .pf_parse_packet_in_finish = gquic_Q050_parse_packet_in_finish,
.pf_gen_stream_frame = gquic_be_gen_stream_frame, .pf_gen_stream_frame = lsquic_gquic_be_gen_stream_frame,
.pf_calc_stream_frame_header_sz = calc_stream_frame_header_sz_gquic, .pf_calc_stream_frame_header_sz = lsquic_calc_stream_frame_header_sz_gquic,
.pf_parse_stream_frame = gquic_be_parse_stream_frame, .pf_parse_stream_frame = lsquic_gquic_be_parse_stream_frame,
.pf_parse_ack_frame = gquic_be_parse_ack_frame, .pf_parse_ack_frame = lsquic_gquic_be_parse_ack_frame,
.pf_gen_ack_frame = gquic_be_gen_ack_frame, .pf_gen_ack_frame = lsquic_gquic_be_gen_ack_frame,
.pf_gen_stop_waiting_frame = gquic_be_gen_stop_waiting_frame, .pf_gen_stop_waiting_frame = lsquic_gquic_be_gen_stop_waiting_frame,
.pf_parse_stop_waiting_frame = gquic_be_parse_stop_waiting_frame, .pf_parse_stop_waiting_frame = lsquic_gquic_be_parse_stop_waiting_frame,
.pf_skip_stop_waiting_frame = gquic_be_skip_stop_waiting_frame, .pf_skip_stop_waiting_frame = lsquic_gquic_be_skip_stop_waiting_frame,
.pf_gen_window_update_frame = gquic_be_gen_window_update_frame, .pf_gen_window_update_frame = lsquic_gquic_be_gen_window_update_frame,
.pf_parse_window_update_frame = gquic_be_parse_window_update_frame, .pf_parse_window_update_frame = lsquic_gquic_be_parse_window_update_frame,
.pf_gen_blocked_frame = gquic_be_gen_blocked_frame, .pf_gen_blocked_frame = lsquic_gquic_be_gen_blocked_frame,
.pf_parse_blocked_frame = gquic_be_parse_blocked_frame, .pf_parse_blocked_frame = lsquic_gquic_be_parse_blocked_frame,
.pf_gen_rst_frame = gquic_be_gen_rst_frame, .pf_gen_rst_frame = lsquic_gquic_be_gen_rst_frame,
.pf_parse_rst_frame = gquic_be_parse_rst_frame, .pf_parse_rst_frame = lsquic_gquic_be_parse_rst_frame,
.pf_connect_close_frame_size = gquic_be_connect_close_frame_size, .pf_connect_close_frame_size = lsquic_gquic_be_connect_close_frame_size,
.pf_gen_connect_close_frame = gquic_be_gen_connect_close_frame, .pf_gen_connect_close_frame = lsquic_gquic_be_gen_connect_close_frame,
.pf_parse_connect_close_frame = gquic_be_parse_connect_close_frame, .pf_parse_connect_close_frame = lsquic_gquic_be_parse_connect_close_frame,
.pf_gen_goaway_frame = gquic_be_gen_goaway_frame, .pf_gen_goaway_frame = lsquic_gquic_be_gen_goaway_frame,
.pf_parse_goaway_frame = gquic_be_parse_goaway_frame, .pf_parse_goaway_frame = lsquic_gquic_be_parse_goaway_frame,
.pf_gen_ping_frame = gquic_be_gen_ping_frame, .pf_gen_ping_frame = lsquic_gquic_be_gen_ping_frame,
#ifndef NDEBUG #ifndef NDEBUG
.pf_write_float_time16 = gquic_be_write_float_time16, .pf_write_float_time16 = lsquic_gquic_be_write_float_time16,
.pf_read_float_time16 = gquic_be_read_float_time16, .pf_read_float_time16 = lsquic_gquic_be_read_float_time16,
#endif #endif
.pf_generate_simple_prst = gquic_Q050_generate_simple_prst, .pf_generate_simple_prst = gquic_Q050_generate_simple_prst,
.pf_parse_frame_type = gquic_Q050_parse_frame_type, .pf_parse_frame_type = gquic_Q050_parse_frame_type,

View file

@ -43,7 +43,7 @@
/* read 16 bits(2 bytes) time, unit: us */ /* read 16 bits(2 bytes) time, unit: us */
uint64_t uint64_t
gquic_be_read_float_time16 (const void *mem) lsquic_gquic_be_read_float_time16 (const void *mem)
{ {
uint16_t val; uint16_t val;
READ_UINT(val, 16, mem, 2); READ_UINT(val, 16, mem, 2);
@ -62,7 +62,7 @@ gquic_be_read_float_time16 (const void *mem)
void 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 ret = 0;
uint16_t high, i; uint16_t high, i;
@ -93,7 +93,7 @@ gquic_be_write_float_time16 (lsquic_time_t time_us, void *mem)
/* Parse out packet number */ /* Parse out packet number */
void 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) struct packin_parse_state *state)
{ {
lsquic_packno_t packno; lsquic_packno_t packno;
@ -106,7 +106,7 @@ gquic_be_parse_packet_in_finish (lsquic_packet_in_t *packet_in,
static int 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, const struct lsquic_packet_out *packet_out, unsigned char *buf,
size_t bufsz) size_t bufsz)
{ {
@ -190,7 +190,7 @@ gquic_be_gen_reg_pkt_header (const struct lsquic_conn *lconn,
int 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, lsquic_stream_id_t stream_id64, uint64_t offset, int fin, size_t size,
gsf_read_f gsf_read, void *stream) 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 */ /* return parsed (used) buffer length */
int 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) stream_frame_t *stream_frame)
{ {
/* 1fdoooss */ /* 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); READ_UINT(ack->ranges[0].high, 64, p, largest_obs_len);
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; p += 2;
READ_UINT(tmp_packno, 64, p, ack_block_len); 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); READ_UINT(ack->ranges[0].high, 64, p, largest_obs_len);
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; p += 2;
unsigned n_blocks; 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. * If parsing failed, negative value is returned.
*/ */
int 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) struct ack_info *ack, uint8_t UNUSED_exp)
{ {
if (!(buf[0] & 0x20)) if (!(buf[0] & 0x20))
@ -495,7 +495,7 @@ gquic_be_parse_ack_frame (const unsigned char *buf, size_t buf_len,
int 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 cur_packno, enum packno_bits bits,
lsquic_packno_t least_unacked_packno) lsquic_packno_t least_unacked_packno)
{ {
@ -519,7 +519,7 @@ gquic_be_gen_stop_waiting_frame(unsigned char *buf, size_t buf_len,
int 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 cur_packno, enum packno_bits bits,
lsquic_packno_t *least_unacked) lsquic_packno_t *least_unacked)
{ {
@ -538,7 +538,7 @@ gquic_be_parse_stop_waiting_frame (const unsigned char *buf, size_t buf_len,
int 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); unsigned packnum_len = gquic_packno_bits2len(bits);
if (buf_len >= 1 + packnum_len) 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 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) lsquic_stream_id_t stream_id64, uint64_t offset)
{ {
uint32_t stream_id = stream_id64; uint32_t stream_id = stream_id64;
@ -571,7 +571,7 @@ gquic_be_gen_window_update_frame (unsigned char *buf, int buf_len,
int 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) lsquic_stream_id_t *stream_id_p, uint64_t *offset)
{ {
uint32_t stream_id; uint32_t stream_id;
@ -587,7 +587,7 @@ gquic_be_parse_window_update_frame (const unsigned char *buf, size_t buf_len,
int 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) lsquic_stream_id_t stream_id64)
{ {
uint32_t stream_id = 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 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) lsquic_stream_id_t *stream_id_p)
{ {
uint32_t stream_id; uint32_t stream_id;
@ -619,7 +619,7 @@ gquic_be_parse_blocked_frame (const unsigned char *buf, size_t buf_len,
static unsigned 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) uint64_t final_size)
{ {
assert(0); /* This function is not called */ 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 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) lsquic_stream_id_t stream_id64, uint64_t offset, uint64_t error_code64)
{ {
uint32_t stream_id = stream_id64, error_code = 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 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) lsquic_stream_id_t *stream_id_p, uint64_t *offset, uint64_t *error_code_p)
{ {
uint32_t stream_id, error_code; uint32_t stream_id, error_code;
@ -676,7 +676,7 @@ gquic_be_parse_rst_frame (const unsigned char *buf, size_t buf_len,
int 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) if (buf_len > 0)
{ {
@ -689,7 +689,7 @@ gquic_be_gen_ping_frame (unsigned char *buf, int buf_len)
size_t 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) unsigned frame_type, size_t reason_len)
{ {
return 1 + 4 + 2 + 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 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) int app_error_UNUSED, unsigned ecode, const char *reason, int reason_len)
{ {
uint32_t error_code; uint32_t error_code;
@ -728,7 +728,7 @@ gquic_be_gen_connect_close_frame (unsigned char *buf, size_t buf_len,
int 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, int *app_error, uint64_t *error_code_p,
uint16_t *reason_len, uint8_t *reason_offset) 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 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, uint32_t error_code, lsquic_stream_id_t last_good_stream_id64,
const char *reason, size_t reason_len) 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 */ /* the reason is buf + *reason_offset, length is *reason_length */
int 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, uint32_t *error_code, lsquic_stream_id_t *last_good_stream_id,
uint16_t *reason_length, const char **reason) 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 */ /* Returns number of bytes written or -1 on failure */
/* This function makes an assumption that there is at least one range */ /* This function makes an assumption that there is at least one range */
int 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_first_f rechist_first, gaf_rechist_next_f rechist_next,
gaf_rechist_largest_recv_f rechist_largest_recv, gaf_rechist_largest_recv_f rechist_largest_recv,
void *rechist, lsquic_time_t now, int *has_missing, 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); CHECKOUT(2);
time_diff = now - rechist_largest_recv(rechist); 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, LSQ_DEBUG("%s: diff: %"PRIu64"; encoded: 0x%04X", __func__, time_diff,
*(uint16_t*)p); *(uint16_t*)p);
p += 2; p += 2;
@ -985,7 +985,7 @@ gquic_be_gen_ack_frame (unsigned char *outbuf, size_t outbuf_sz,
static int 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) uint64_t offset, size_t size, gcf_read_f gcf_read, void *stream)
{ {
assert(0); assert(0);
@ -994,7 +994,7 @@ gquic_be_gen_crypto_frame (unsigned char *buf, size_t buf_len,
static int 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) struct stream_frame *stream_frame)
{ {
assert(0); assert(0);
@ -1003,7 +1003,7 @@ gquic_be_parse_crypto_frame (const unsigned char *buf, size_t rem_packet_sz,
static void 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, const struct lsquic_packet_out *packet_out, unsigned *packno_off,
unsigned *packno_len) 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 = const struct parse_funcs lsquic_parse_funcs_gquic_Q043 =
{ {
.pf_gen_reg_pkt_header = gquic_be_gen_reg_pkt_header, .pf_gen_reg_pkt_header = lsquic_gquic_be_gen_reg_pkt_header,
.pf_parse_packet_in_finish = gquic_be_parse_packet_in_finish, .pf_parse_packet_in_finish = lsquic_gquic_be_parse_packet_in_finish,
.pf_gen_stream_frame = gquic_be_gen_stream_frame, .pf_gen_stream_frame = lsquic_gquic_be_gen_stream_frame,
.pf_calc_stream_frame_header_sz = calc_stream_frame_header_sz_gquic, .pf_calc_stream_frame_header_sz = lsquic_calc_stream_frame_header_sz_gquic,
.pf_parse_stream_frame = gquic_be_parse_stream_frame, .pf_parse_stream_frame = lsquic_gquic_be_parse_stream_frame,
.pf_parse_ack_frame = gquic_be_parse_ack_frame, .pf_parse_ack_frame = lsquic_gquic_be_parse_ack_frame,
.pf_gen_ack_frame = gquic_be_gen_ack_frame, .pf_gen_ack_frame = lsquic_gquic_be_gen_ack_frame,
.pf_gen_stop_waiting_frame = gquic_be_gen_stop_waiting_frame, .pf_gen_stop_waiting_frame = lsquic_gquic_be_gen_stop_waiting_frame,
.pf_parse_stop_waiting_frame = gquic_be_parse_stop_waiting_frame, .pf_parse_stop_waiting_frame = lsquic_gquic_be_parse_stop_waiting_frame,
.pf_skip_stop_waiting_frame = gquic_be_skip_stop_waiting_frame, .pf_skip_stop_waiting_frame = lsquic_gquic_be_skip_stop_waiting_frame,
.pf_gen_window_update_frame = gquic_be_gen_window_update_frame, .pf_gen_window_update_frame = lsquic_gquic_be_gen_window_update_frame,
.pf_parse_window_update_frame = gquic_be_parse_window_update_frame, .pf_parse_window_update_frame = lsquic_gquic_be_parse_window_update_frame,
.pf_gen_blocked_frame = gquic_be_gen_blocked_frame, .pf_gen_blocked_frame = lsquic_gquic_be_gen_blocked_frame,
.pf_parse_blocked_frame = gquic_be_parse_blocked_frame, .pf_parse_blocked_frame = lsquic_gquic_be_parse_blocked_frame,
.pf_rst_frame_size = gquic_be_rst_frame_size, .pf_rst_frame_size = lsquic_gquic_be_rst_frame_size,
.pf_gen_rst_frame = gquic_be_gen_rst_frame, .pf_gen_rst_frame = lsquic_gquic_be_gen_rst_frame,
.pf_parse_rst_frame = gquic_be_parse_rst_frame, .pf_parse_rst_frame = lsquic_gquic_be_parse_rst_frame,
.pf_connect_close_frame_size = gquic_be_connect_close_frame_size, .pf_connect_close_frame_size = lsquic_gquic_be_connect_close_frame_size,
.pf_gen_connect_close_frame = gquic_be_gen_connect_close_frame, .pf_gen_connect_close_frame = lsquic_gquic_be_gen_connect_close_frame,
.pf_parse_connect_close_frame = gquic_be_parse_connect_close_frame, .pf_parse_connect_close_frame = lsquic_gquic_be_parse_connect_close_frame,
.pf_gen_goaway_frame = gquic_be_gen_goaway_frame, .pf_gen_goaway_frame = lsquic_gquic_be_gen_goaway_frame,
.pf_parse_goaway_frame = gquic_be_parse_goaway_frame, .pf_parse_goaway_frame = lsquic_gquic_be_parse_goaway_frame,
.pf_gen_ping_frame = gquic_be_gen_ping_frame, .pf_gen_ping_frame = lsquic_gquic_be_gen_ping_frame,
#ifndef NDEBUG #ifndef NDEBUG
.pf_write_float_time16 = gquic_be_write_float_time16, .pf_write_float_time16 = lsquic_gquic_be_write_float_time16,
.pf_read_float_time16 = gquic_be_read_float_time16, .pf_read_float_time16 = lsquic_gquic_be_read_float_time16,
#endif #endif
.pf_generate_simple_prst = lsquic_generate_gquic_reset, .pf_generate_simple_prst = lsquic_generate_gquic_reset,
.pf_parse_frame_type = lsquic_parse_frame_type_gquic_Q035_thru_Q046, .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_packout_max_header_size = lsquic_gquic_packout_header_size,
.pf_calc_packno_bits = lsquic_gquic_calc_packno_bits, .pf_calc_packno_bits = lsquic_gquic_calc_packno_bits,
.pf_packno_bits2len = lsquic_gquic_packno_bits2len, .pf_packno_bits2len = lsquic_gquic_packno_bits2len,
.pf_gen_crypto_frame = gquic_be_gen_crypto_frame, .pf_gen_crypto_frame = lsquic_gquic_be_gen_crypto_frame,
.pf_parse_crypto_frame = gquic_be_parse_crypto_frame, .pf_parse_crypto_frame = lsquic_gquic_be_parse_crypto_frame,
.pf_packno_info = gquic_be_packno_info, .pf_packno_info = lsquic_gquic_be_packno_info,
.pf_gen_handshake_done_frame = gquic_Q043_gen_handshake_done_frame, .pf_gen_handshake_done_frame = gquic_Q043_gen_handshake_done_frame,
.pf_parse_handshake_done_frame = gquic_Q043_parse_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, .pf_handshake_done_frame_size = gquic_Q043_handshake_done_frame_size,

View file

@ -12,100 +12,100 @@
do { if ((intptr_t) (need) > ((pend) - (pstart))) { return -1; } } while (0) do { if ((intptr_t) (need) > ((pend) - (pstart))) { return -1; } } while (0)
uint64_t uint64_t
gquic_be_read_float_time16 (const void *mem); lsquic_gquic_be_read_float_time16 (const void *mem);
void 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 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); struct packin_parse_state *state);
int 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); const lsquic_cid_t *, unsigned version_bitmask);
int 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, lsquic_stream_id_t stream_id, uint64_t offset, int fin, size_t size,
gsf_read_f gsf_read, void *stream); gsf_read_f gsf_read, void *stream);
int 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); stream_frame_t *stream_frame);
lsquic_packno_t 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 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); struct ack_info *, uint8_t);
int 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 cur_packno, enum packno_bits bits,
lsquic_packno_t least_unacked_packno); lsquic_packno_t least_unacked_packno);
int 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 cur_packno, enum packno_bits bits,
lsquic_packno_t *least_unacked); lsquic_packno_t *least_unacked);
int 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 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); lsquic_stream_id_t stream_id, uint64_t offset);
int 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); lsquic_stream_id_t *stream_id, uint64_t *offset);
int 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); lsquic_stream_id_t stream_id);
int 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); lsquic_stream_id_t *stream_id);
int 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); lsquic_stream_id_t stream_id, uint64_t offset, uint64_t error_code);
int 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); lsquic_stream_id_t *stream_id, uint64_t *offset, uint64_t *error_code);
int 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 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); unsigned frame_type, size_t reason_len);
int 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 app_error, unsigned error_code, const char *reason, int reason_len);
int 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, int *app_error, uint64_t *error_code,
uint16_t *reason_len, uint8_t *reason_offset); uint16_t *reason_len, uint8_t *reason_offset);
int 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, lsquic_stream_id_t last_good_stream_id, const char *reason,
size_t reason_len); size_t reason_len);
int 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, uint32_t *error_code, lsquic_stream_id_t *last_good_stream_id,
uint16_t *reason_length, const char **reason); uint16_t *reason_length, const char **reason);
int 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_first_f rechist_first, gaf_rechist_next_f rechist_next,
gaf_rechist_largest_recv_f rechist_largest_recv, gaf_rechist_largest_recv_f rechist_largest_recv,
void *rechist, lsquic_time_t now, int *has_missing, lsquic_packno_t *, void *rechist, lsquic_time_t now, int *has_missing, lsquic_packno_t *,

View file

@ -477,7 +477,7 @@ lsquic_turn_on_fin_Q035_thru_Q046 (unsigned char *stream_header)
size_t 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) uint64_t offset, unsigned data_sz_IGNORED)
{ {
return return

View file

@ -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) ietf_v1_turn_on_fin (unsigned char *stream_frame_header)
{ {
*stream_frame_header |= 1; *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, ietf_v1_gen_new_token_frame (unsigned char *buf, size_t buf_sz,
const unsigned char *token, size_t token_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, ietf_v1_gen_new_connection_id_frame (unsigned char *buf, size_t buf_sz,
unsigned seqno, const struct lsquic_cid *cid, unsigned seqno, const struct lsquic_cid *cid,
const unsigned char *token, size_t token_sz) const unsigned char *token, size_t token_sz)

View file

@ -135,7 +135,7 @@ hash_req (const void *p, size_t len, unsigned seed)
struct pr_queue * 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 lsquic_engine_public *enpub)
{ {
const struct parse_funcs *pf; const struct parse_funcs *pf;
@ -217,7 +217,7 @@ prq_create (unsigned max_elems, unsigned max_conns,
void void
prq_destroy (struct pr_queue *prq) lsquic_prq_destroy (struct pr_queue *prq)
{ {
struct lsquic_conn *conn; struct lsquic_conn *conn;
@ -259,8 +259,8 @@ put_req (struct pr_queue *prq, struct packet_req *req)
} }
int static int
lsquic_prq_new_req (struct pr_queue *prq, enum packet_req_type type, lsquic_prq_new_req_ext (struct pr_queue *prq, enum packet_req_type type,
unsigned flags, enum lsquic_version version, unsigned short data_sz, unsigned flags, enum lsquic_version version, unsigned short data_sz,
const lsquic_cid_t *dcid, const lsquic_cid_t *scid, void *peer_ctx, const lsquic_cid_t *dcid, const lsquic_cid_t *scid, void *peer_ctx,
const struct sockaddr *local_addr, const struct sockaddr *peer_addr) 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 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 lsquic_packet_in *packet_in, void *peer_ctx,
const struct sockaddr *local_addr, const struct sockaddr *peer_addr) 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; version = LSQVER_ID25;
lsquic_scid_from_packet_in(packet_in, &scid); lsquic_scid_from_packet_in(packet_in, &scid);
return lsquic_prq_new_req(prq, type, flags, version, packet_in->pi_data_sz, return lsquic_prq_new_req_ext(prq, type, flags, version,
&packet_in->pi_dcid, &scid, peer_ctx, local_addr, peer_addr); 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 * struct lsquic_conn *
prq_next_conn (struct pr_queue *prq) lsquic_prq_next_conn (struct pr_queue *prq)
{ {
struct evanescent_conn *evconn; struct evanescent_conn *evconn;
struct lsquic_conn *lconn; struct lsquic_conn *lconn;
@ -504,7 +505,7 @@ prq_next_conn (struct pr_queue *prq)
int 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; return lsquic_hash_count(prq->prq_reqs_hash) > 0;
} }

View file

@ -57,23 +57,23 @@ enum packet_req_type {
extern const char *const lsquic_preqt2str[N_PREQ_TYPES]; extern const char *const lsquic_preqt2str[N_PREQ_TYPES];
struct pr_queue * 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 *); const struct lsquic_engine_public *);
void void
prq_destroy (struct pr_queue *); lsquic_prq_destroy (struct pr_queue *);
int 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 lsquic_packet_in *, void *conn_ctx,
const struct sockaddr *local_addr, const struct sockaddr *local_addr,
const struct sockaddr *peer_addr); const struct sockaddr *peer_addr);
struct lsquic_conn * struct lsquic_conn *
prq_next_conn (struct pr_queue *); lsquic_prq_next_conn (struct pr_queue *);
int int
prq_have_pending (const struct pr_queue *); lsquic_prq_have_pending (const struct pr_queue *);
void void
lsquic_prq_drop (struct lsquic_conn *); lsquic_prq_drop (struct lsquic_conn *);

View file

@ -12,6 +12,7 @@
#include "lsquic.h" #include "lsquic.h"
#include "lsquic_types.h" #include "lsquic_types.h"
#include "lsxpack_header.h"
#include "lsquic_int_types.h" #include "lsquic_int_types.h"
#include "lsquic_sfcw.h" #include "lsquic_sfcw.h"
#include "lsquic_varint.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) struct lsquic_stream *stream, struct lsqpack_header_list *qlist)
{ {
const struct lsquic_hset_if *const hset_if = qdh->qdh_enpub->enp_hsi_if; 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; struct uncompressed_headers *uh = NULL;
const struct lsqpack_header *header; const struct lsqpack_header *header;
enum lsquic_header_status st; int st;
int push_promise; int push_promise;
unsigned i; unsigned i;
void *hset; void *hset;
struct cont_len cl; struct cont_len cl;
struct lsxpack_header *xhdr;
size_t extra;
push_promise = lsquic_stream_header_is_pp(stream); push_promise = lsquic_stream_header_is_pp(stream);
hset = hset_if->hsi_create_header_set(qdh->qdh_hsi_ctx, push_promise); 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]; header = qlist->qhl_headers[i];
LSQ_DEBUG("%.*s: %.*s", header->qh_name_len, header->qh_name, LSQ_DEBUG("%.*s: %.*s", header->qh_name_len, header->qh_name,
header->qh_value_len, header->qh_value); header->qh_value_len, header->qh_value);
st = hset_if->hsi_process_header(hset, extra = header->qh_name_len + header->qh_value_len + 4;
header->qh_flags & QH_ID_SET ? xhdr = hset_if->hsi_prepare_decode(hset, NULL, extra);
hpack_static_table_size + 1 + header->qh_static_id : 0, if (!xhdr)
header->qh_name, header->qh_name_len,
header->qh_value, header->qh_value_len);
if (st != LSQUIC_HDR_OK)
{ {
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; goto err;
} }
if (is_content_length(header)) 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); lsqpack_dec_destroy_header_list(qlist);
qlist = NULL; qlist = NULL;
st = hset_if->hsi_process_header(hset, 0, 0, 0, 0, 0); st = hset_if->hsi_process_header(hset, NULL);
if (st != LSQUIC_HDR_OK) if (st != 0)
goto err; goto err;
uh = calloc(1, sizeof(*uh)); uh = calloc(1, sizeof(*uh));

View file

@ -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 = &lsquic_cong_cubic_if;
ctl->sc_ci->cci_init(CGP(ctl), conn_pub, ctl->sc_retx_frames); ctl->sc_ci->cci_init(CGP(ctl), conn_pub, ctl->sc_retx_frames);
if (ctl->sc_flags & SC_PACE) 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 */ /* TODO: conn_pub has a pointer to enpub: drop third argument */
enpub->enp_settings.es_clock_granularity); enpub->enp_settings.es_clock_granularity);
for (i = 0; i < sizeof(ctl->sc_buffered_packets) / 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); "%"PRIu64, largest_lost_packno, ctl->sc_largest_sent_at_cutback);
ctl->sc_ci->cci_loss(CGP(ctl)); ctl->sc_ci->cci_loss(CGP(ctl));
if (ctl->sc_flags & SC_PACE) 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 = ctl->sc_largest_sent_at_cutback =
lsquic_senhist_largest(&ctl->sc_senhist); 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) if (ctl->sc_flags & SC_PACE)
pacer_cleanup(&ctl->sc_pacer); lsquic_pacer_cleanup(&ctl->sc_pacer);
ctl->sc_ci->cci_cleanup(CGP(ctl)); ctl->sc_ci->cci_cleanup(CGP(ctl));
#if LSQUIC_SEND_STATS #if LSQUIC_SEND_STATS
LSQ_NOTICE("stats: n_total_sent: %u; n_resent: %u; n_delayed: %u", 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) lsquic_send_ctl_pacer_blocked (struct lsquic_send_ctl *ctl)
{ {
return (ctl->sc_flags & SC_PACE) 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); 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))) if (n_out >= ctl->sc_ci->cci_get_cwnd(CGP(ctl)))
return 0; 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)) ctl->sc_n_scheduled + ctl->sc_n_in_flight_all))
return 1; return 1;
if (ctl->sc_flags & SC_SCHED_TICK) if (ctl->sc_flags & SC_SCHED_TICK)
{ {
ctl->sc_flags &= ~SC_SCHED_TICK; ctl->sc_flags &= ~SC_SCHED_TICK;
lsquic_engine_add_conn_to_attq(ctl->sc_enpub, 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); AEW_PACER);
} }
return 0; return 0;
@ -1407,7 +1407,7 @@ send_ctl_could_send (const struct lsquic_send_ctl *ctl)
uint64_t cwnd; uint64_t cwnd;
unsigned n_out; 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; return 0;
cwnd = ctl->sc_ci->cci_get_cwnd(CGP(ctl)); 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) if (ctl->sc_flags & SC_PACE)
{ {
unsigned n_out = ctl->sc_n_in_flight_retx + ctl->sc_n_scheduled; 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_in_recovery(ctl), send_ctl_transfer_time, ctl);
} }
send_ctl_sched_append(ctl, packet_out); 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); LSQ_DEBUG("cum_size: %zu; limit: %zu", cum_size, limit);
assert(cum_size < limit); assert(cum_size <= limit);
size = limit - cum_size; size = limit - cum_size;
if (size > lsquic_packet_out_avail(initial_packet)) if (size > lsquic_packet_out_avail(initial_packet))
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); if (size)
initial_packet->po_data_sz += size; {
initial_packet->po_frame_types |= QUIC_FTBIT_PADDING; 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, LSQ_DEBUG("Added %zu bytes of PADDING to packet %"PRIu64, size,
initial_packet->po_packno); initial_packet->po_packno);
} }
@ -2697,7 +2700,8 @@ strip_trailing_padding (struct lsquic_packet_out *packet_out)
unsigned off; unsigned off;
off = 0; 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; off = srec->sr_off + srec->sr_len;
assert(off); assert(off);

View file

@ -268,20 +268,20 @@ lsquic_send_ctl_drop_scheduled (lsquic_send_ctl_t *);
if ((ctl)->sc_flags & SC_PACE) \ if ((ctl)->sc_flags & SC_PACE) \
{ \ { \
(ctl)->sc_flags |= SC_SCHED_TICK; \ (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; \ (ctl)->sc_flags &= ~SC_APP_LIMITED; \
} while (0) } while (0)
#define lsquic_send_ctl_tick_out(ctl) do { \ #define lsquic_send_ctl_tick_out(ctl) do { \
if ((ctl)->sc_flags & SC_PACE) \ if ((ctl)->sc_flags & SC_PACE) \
pacer_tick_out(&(ctl)->sc_pacer); \ lsquic_pacer_tick_out(&(ctl)->sc_pacer); \
} while (0) } while (0)
#define lsquic_send_ctl_next_pacer_time(ctl) ( \ #define lsquic_send_ctl_next_pacer_time(ctl) ( \
((ctl)->sc_flags & SC_PACE) \ ((ctl)->sc_flags & SC_PACE) \
&& pacer_delayed(&(ctl)->sc_pacer) \ && lsquic_pacer_delayed(&(ctl)->sc_pacer) \
? pacer_next_sched(&(ctl)->sc_pacer) \ ? lsquic_pacer_next_sched(&(ctl)->sc_pacer) \
: 0 ) : 0 )
enum packno_bits enum packno_bits

View file

@ -155,7 +155,7 @@ stock_shi_delete (void *hash_ctx, const void *key, unsigned key_sz)
struct stock_shared_hash * struct stock_shared_hash *
stock_shared_hash_new (void) lsquic_stock_shared_hash_new (void)
{ {
struct malo *malo; struct malo *malo;
struct stock_shared_hash *hash; struct stock_shared_hash *hash;
@ -179,7 +179,7 @@ stock_shared_hash_new (void)
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 hash_elem *he;
struct lsquic_hash_elem *el; struct lsquic_hash_elem *el;

View file

@ -15,10 +15,10 @@ extern "C" {
struct stock_shared_hash; struct stock_shared_hash;
struct stock_shared_hash * struct stock_shared_hash *
stock_shared_hash_new (void); lsquic_stock_shared_hash_new (void);
void void
stock_shared_hash_destroy (struct stock_shared_hash *); lsquic_stock_shared_hash_destroy (struct stock_shared_hash *);
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -348,9 +348,9 @@ stream_new_common (lsquic_stream_id_t id, struct lsquic_conn_public *conn_pub,
return NULL; return NULL;
if (ctor_flags & SCF_USE_DI_HASH) 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 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) if (!stream->data_in)
{ {
free(stream); free(stream);
@ -947,7 +947,7 @@ lsquic_stream_frame_in (lsquic_stream_t *stream, stream_frame_t *frame)
stream->data_in, stream->read_offset); stream->data_in, stream->read_offset);
if (!stream->data_in) if (!stream->data_in)
{ {
stream->data_in = data_in_error_new(); stream->data_in = lsquic_data_in_error_new();
goto end_ok; 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); stream->data_in, stream->read_offset);
if (stream->data_in) if (stream->data_in)
goto insert_frame; 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_packet_in_put(stream->conn_pub->mm, frame->packet_in);
lsquic_malo_put(frame); lsquic_malo_put(frame);
return -1; 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 * data-in stream. It does the right thing after incoming data is
* dropped. * dropped.
*/ */
stream->data_in = data_in_error_new(); stream->data_in = lsquic_data_in_error_new();
stream->stream_flags &= ~STREAM_CACHED_FRAME; 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); stream->data_in, stream->read_offset);
if (!stream->data_in) 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, }; 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) incr_sm_payload (struct lsquic_stream *stream, size_t incr)
{ {
stream->sm_payload += incr; stream->sm_payload += incr;

View file

@ -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 */ /* 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; const unsigned char *p, *pEnd;
char *pOutput; char *pOutput;

View file

@ -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 size_t
lsquic_hex_encode (const void *src, size_t src_sz, void *dst, size_t dst_sz); lsquic_hex_encode (const void *src, size_t src_sz, void *dst, size_t dst_sz);

1
src/lshpack Submodule

@ -0,0 +1 @@
Subproject commit 226eedeb9077c1f8b4c6eeb580c7989d458d1268

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -53,6 +53,7 @@
#include "../src/liblsquic/lsquic_stream.h" #include "../src/liblsquic/lsquic_stream.h"
/* include directly for retire_cid testing */ /* include directly for retire_cid testing */
#include "../src/liblsquic/lsquic_conn.h" #include "../src/liblsquic/lsquic_conn.h"
#include "lsxpack_header.h"
#define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b))
@ -218,9 +219,9 @@ struct lsquic_conn_ctx {
struct hset_elem struct hset_elem
{ {
STAILQ_ENTRY(hset_elem) next; STAILQ_ENTRY(hset_elem) next;
unsigned name_idx; struct lsxpack_header xhdr;
char *name; size_t nalloc;
char *value; char *buf;
}; };
@ -997,42 +998,77 @@ hset_create (void *hsi_ctx, int is_push_promise)
} }
static enum lsquic_header_status static struct lsxpack_header *
hset_add_header (void *hset_p, unsigned name_idx, hset_prepare_decode (void *hset_p, struct lsxpack_header *xhdr,
const char *name, unsigned name_len, size_t extra_space)
const char *value, unsigned value_len)
{ {
struct hset *hset = hset_p; struct hset *const hset = hset_p;
struct hset_elem *el; 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" */ s_stat_downloaded_bytes += name_len + value_len + 4; /* ": \r\n" */
}
else else
s_stat_downloaded_bytes += 2; /* \r\n "*/ s_stat_downloaded_bytes += 2; /* \r\n "*/
if (s_discard_response) return 0;
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;
} }
@ -1047,8 +1083,7 @@ hset_destroy (void *hset_p)
for (el = STAILQ_FIRST(hset); el; el = next) for (el = STAILQ_FIRST(hset); el; el = next)
{ {
next = STAILQ_NEXT(el, next); next = STAILQ_NEXT(el, next);
free(el->name); free(el->buf);
free(el->value);
free(el); free(el);
} }
free(hset); free(hset);
@ -1062,11 +1097,17 @@ hset_dump (const struct hset *hset, FILE *out)
const struct hset_elem *el; const struct hset_elem *el;
STAILQ_FOREACH(el, hset, next) STAILQ_FOREACH(el, hset, next)
if (el->name_idx) if (el->xhdr.flags & (LSXPACK_HPACK_IDX|LSXPACK_QPACK_IDX))
fprintf(out, "%s (static table idx %u): %s\n", el->name, fprintf(out, "%.*s (%s static table idx %u): %.*s\n",
el->name_idx, el->value); (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 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"); fprintf(out, "\n");
fflush(out); fflush(out);
@ -1080,6 +1121,7 @@ hset_dump (const struct hset *hset, FILE *out)
static const struct lsquic_hset_if header_bypass_api = static const struct lsquic_hset_if header_bypass_api =
{ {
.hsi_create_header_set = hset_create, .hsi_create_header_set = hset_create,
.hsi_prepare_decode = hset_prepare_decode,
.hsi_process_header = hset_add_header, .hsi_process_header = hset_add_header,
.hsi_discard_header_set = hset_destroy, .hsi_discard_header_set = hset_destroy,
}; };

View file

@ -24,6 +24,7 @@
#include <openssl/md5.h> #include <openssl/md5.h>
#include "lsquic.h" #include "lsquic.h"
#include "lsxpack_header.h"
#include "test_config.h" #include "test_config.h"
#include "test_common.h" #include "test_common.h"
#include "prog.h" #include "prog.h"
@ -162,11 +163,18 @@ struct req
enum method { enum method {
UNSET, GET, POST, UNSUPPORTED, UNSET, GET, POST, UNSUPPORTED,
} method; } method;
enum {
HAVE_XHDR = 1 << 0,
} flags;
char *path; char *path;
char *method_str; char *method_str;
char *authority_str; char *authority_str;
char *qif_str; char *qif_str;
size_t qif_sz; 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 * static void *
interop_server_hset_create (void *hsi_ctx, int is_push_promise) 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 static struct lsxpack_header *
interop_server_hset_add_header (void *hset_p, unsigned name_idx, interop_server_hset_prepare_decode (void *hset_p, struct lsxpack_header *xhdr,
const char *name, unsigned name_len, size_t extra_space)
const char *value, unsigned value_len)
{ {
struct req *req = hset_p; struct req *req = hset_p;
if (name) if (xhdr)
{ {
req->qif_str = realloc(req->qif_str, LSQ_WARN("we don't reallocate headers: can't give more");
req->qif_sz + name_len + value_len + 2); return NULL;
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;
} }
if (req->flags & HAVE_XHDR)
req->decode_off += lsxpack_header_get_dec_size(&req->xhdr);
else 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 (5 == name_len && 0 == strncmp(name, ":path", 5))
{ {
if (req->path) if (req->path)
return LSQUIC_HDR_ERR_DUPLICATE_PSDO_HDR; return 1;
req->path = strndup(value, value_len); req->path = strndup(value, value_len);
if (!req->path) if (!req->path)
return LSQUIC_HDR_ERR_NOMEM; return -1;
return LSQUIC_HDR_OK; return 0;
} }
if (7 == name_len && 0 == strncmp(name, ":method", 7)) if (7 == name_len && 0 == strncmp(name, ":method", 7))
{ {
if (req->method != UNSET) if (req->method != UNSET)
return LSQUIC_HDR_ERR_DUPLICATE_PSDO_HDR; return 1;
req->method_str = strndup(value, value_len); req->method_str = strndup(value, value_len);
if (!req->method_str) if (!req->method_str)
return LSQUIC_HDR_ERR_NOMEM; return -1;
if (0 == strcmp(req->method_str, "GET")) if (0 == strcmp(req->method_str, "GET"))
req->method = GET; req->method = GET;
else if (0 == strcmp(req->method_str, "POST")) else if (0 == strcmp(req->method_str, "POST"))
req->method = POST; req->method = POST;
else else
req->method = UNSUPPORTED; req->method = UNSUPPORTED;
return LSQUIC_HDR_OK; return 0;
} }
if (10 == name_len && 0 == strncmp(name, ":authority", 10)) if (10 == name_len && 0 == strncmp(name, ":authority", 10))
{ {
req->authority_str = strndup(value, value_len); req->authority_str = strndup(value, value_len);
if (!req->authority_str) if (!req->authority_str)
return LSQUIC_HDR_ERR_NOMEM; return -1;
return LSQUIC_HDR_OK; 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 = static const struct lsquic_hset_if header_bypass_api =
{ {
.hsi_create_header_set = interop_server_hset_create, .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_process_header = interop_server_hset_add_header,
.hsi_discard_header_set = interop_server_hset_destroy, .hsi_discard_header_set = interop_server_hset_destroy,
}; };

View file

@ -104,7 +104,7 @@ main (int argc, char **argv)
packet_in.pi_data = buf; packet_in.pi_data = buf;
packet_in.pi_refcnt = 1; 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); lconn->cn_if->ci_packet_in(lconn, &packet_in);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);

View file

@ -78,18 +78,18 @@ test_attq_ordering (enum sort_action sa)
break; break;
} }
q = attq_create(); q = lsquic_attq_create();
for (i = 0; i < sizeof(curiosity); ++i) 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); assert(count_before == 0);
} }
conns = calloc(sizeof(curiosity), sizeof(conns[0])); conns = calloc(sizeof(curiosity), sizeof(conns[0]));
for (i = 0; i < sizeof(curiosity); ++i) 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); assert(s == 0);
} }
@ -110,30 +110,30 @@ test_attq_ordering (enum sort_action sa)
} }
for (i = 1; i < sizeof(curiosity); ++i) 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]); assert(count_before == counts[i]);
} }
} }
for (i = 0; i < sizeof(curiosity); ++i) for (i = 0; i < sizeof(curiosity); ++i)
{ {
next_attq = attq_next(q); next_attq = lsquic_attq_next(q);
assert(next_attq); assert(next_attq);
t = next_attq->ae_adv_time; t = next_attq->ae_adv_time;
if (i > 0) if (i > 0)
assert(t >= prev); assert(t >= prev);
prev = t; prev = t;
conn = attq_pop(q, ~0ULL); conn = lsquic_attq_pop(q, ~0ULL);
assert(conn); assert(conn);
} }
next_attq = attq_next(q); next_attq = lsquic_attq_next(q);
assert(!next_attq); assert(!next_attq);
conn = attq_pop(q, ~0ULL); conn = lsquic_attq_pop(q, ~0ULL);
assert(!conn); assert(!conn);
free(conns); free(conns);
attq_destroy(q); lsquic_attq_destroy(q);
} }
@ -144,20 +144,20 @@ test_attq_removal_1 (void)
struct attq *q; struct attq *q;
struct lsquic_conn *conns; struct lsquic_conn *conns;
q = attq_create(); q = lsquic_attq_create();
conns = calloc(6, sizeof(conns[0])); conns = calloc(6, sizeof(conns[0]));
attq_add(q, &conns[0], 1, 0); lsquic_attq_add(q, &conns[0], 1, 0);
attq_add(q, &conns[1], 4, 0); lsquic_attq_add(q, &conns[1], 4, 0);
attq_add(q, &conns[2], 2, 0); lsquic_attq_add(q, &conns[2], 2, 0);
attq_add(q, &conns[3], 5, 0); lsquic_attq_add(q, &conns[3], 5, 0);
attq_add(q, &conns[4], 6, 0); lsquic_attq_add(q, &conns[4], 6, 0);
attq_add(q, &conns[5], 3, 0); lsquic_attq_add(q, &conns[5], 3, 0);
attq_remove(q, &conns[3]); lsquic_attq_remove(q, &conns[3]);
free(conns); free(conns);
attq_destroy(q); lsquic_attq_destroy(q);
} }
@ -168,23 +168,23 @@ test_attq_removal_2 (void)
struct attq *q; struct attq *q;
struct lsquic_conn *conns; struct lsquic_conn *conns;
q = attq_create(); q = lsquic_attq_create();
conns = calloc(9, sizeof(conns[0])); conns = calloc(9, sizeof(conns[0]));
attq_add(q, &conns[0], 1, 0); lsquic_attq_add(q, &conns[0], 1, 0);
attq_add(q, &conns[1], 5, 0); lsquic_attq_add(q, &conns[1], 5, 0);
attq_add(q, &conns[2], 6, 0); lsquic_attq_add(q, &conns[2], 6, 0);
attq_add(q, &conns[3], 9, 0); lsquic_attq_add(q, &conns[3], 9, 0);
attq_add(q, &conns[4], 11, 0); lsquic_attq_add(q, &conns[4], 11, 0);
attq_add(q, &conns[5], 8, 0); lsquic_attq_add(q, &conns[5], 8, 0);
attq_add(q, &conns[6], 15, 0); lsquic_attq_add(q, &conns[6], 15, 0);
attq_add(q, &conns[7], 17, 0); lsquic_attq_add(q, &conns[7], 17, 0);
attq_add(q, &conns[8], 21, 0); lsquic_attq_add(q, &conns[8], 21, 0);
attq_remove(q, &conns[1]); lsquic_attq_remove(q, &conns[1]);
free(conns); free(conns);
attq_destroy(q); lsquic_attq_destroy(q);
} }
@ -195,23 +195,23 @@ test_attq_removal_3 (void)
struct attq *q; struct attq *q;
struct lsquic_conn *conns; struct lsquic_conn *conns;
q = attq_create(); q = lsquic_attq_create();
conns = calloc(9, sizeof(conns[0])); conns = calloc(9, sizeof(conns[0]));
attq_add(q, &conns[0], 1, 0); lsquic_attq_add(q, &conns[0], 1, 0);
attq_add(q, &conns[1], 9, 0); lsquic_attq_add(q, &conns[1], 9, 0);
attq_add(q, &conns[2], 22, 0); lsquic_attq_add(q, &conns[2], 22, 0);
attq_add(q, &conns[3], 17, 0); lsquic_attq_add(q, &conns[3], 17, 0);
attq_add(q, &conns[4], 11, 0); lsquic_attq_add(q, &conns[4], 11, 0);
attq_add(q, &conns[5], 33, 0); lsquic_attq_add(q, &conns[5], 33, 0);
attq_add(q, &conns[6], 27, 0); lsquic_attq_add(q, &conns[6], 27, 0);
attq_add(q, &conns[7], 21, 0); lsquic_attq_add(q, &conns[7], 21, 0);
attq_add(q, &conns[8], 19, 0); lsquic_attq_add(q, &conns[8], 19, 0);
attq_remove(q, &conns[1]); lsquic_attq_remove(q, &conns[1]);
free(conns); free(conns);
attq_destroy(q); lsquic_attq_destroy(q);
} }

View file

@ -287,7 +287,7 @@ run_di_nocopy_test (const struct nocopy_test *test)
conn_pub.lconn = &conn; conn_pub.lconn = &conn;
conn_pub.mm = &mm; 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) for (i = 0; i < test->n_init_frames; ++i)
{ {

View file

@ -120,14 +120,14 @@ elide_single_stream_frame (void)
lsquic_packet_out_add_stream(packet_out, &enpub.enp_mm, &streams[0], lsquic_packet_out_add_stream(packet_out, &enpub.enp_mm, &streams[0],
QUIC_FRAME_STREAM, off, len); QUIC_FRAME_STREAM, off, len);
assert(1 == streams[0].n_unacked); 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; streams[0].stream_flags |= STREAM_RST_SENT;
lsquic_packet_out_elide_reset_stream_frames(packet_out, 0); lsquic_packet_out_elide_reset_stream_frames(packet_out, 0);
assert(0 == streams[0].n_unacked); assert(0 == streams[0].n_unacked);
assert(0 == packet_out->po_frame_types); 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_packet_out_destroy(packet_out, &enpub, NULL);
lsquic_mm_cleanup(&enpub.enp_mm); lsquic_mm_cleanup(&enpub.enp_mm);
@ -189,7 +189,7 @@ shrink_packet_post_elision (void)
assert(1 == streams[0].n_unacked); assert(1 == streams[0].n_unacked);
assert(1 == streams[1].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; streams[0].stream_flags |= STREAM_RST_SENT;
@ -197,7 +197,7 @@ shrink_packet_post_elision (void)
assert(0 == streams[0].n_unacked); assert(0 == streams[0].n_unacked);
assert(QUIC_FTBIT_STREAM == packet_out->po_frame_types); 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(srec->sr_stream == &streams[1]);
assert(packet_out->po_data_sz == exp); 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))); 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_stream == &streams[1]);
assert(srec->sr_frame_type == QUIC_FRAME_STREAM); assert(srec->sr_frame_type == QUIC_FRAME_STREAM);
assert(srec->sr_off == b_off - (chop_regen ? 5 : 0)); 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_stream == &streams[0]);
assert(srec->sr_frame_type == QUIC_FRAME_RST_STREAM); 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_stream == &streams[3]);
assert(srec->sr_frame_type == QUIC_FRAME_STREAM); assert(srec->sr_frame_type == QUIC_FRAME_STREAM);
assert(srec->sr_off == d_off - (chop_regen ? 5 : 0)); assert(srec->sr_off == d_off - (chop_regen ? 5 : 0));
srec = posi_next(&posi); srec = lsquic_posi_next(&posi);
assert(!srec); assert(!srec);
lsquic_packet_out_destroy(packet_out, &enpub, NULL); lsquic_packet_out_destroy(packet_out, &enpub, NULL);

View file

@ -736,14 +736,14 @@ static const struct frame_reader_test tests[] = {
.type = CV_ERROR, .type = CV_ERROR,
.u.error = { .u.error = {
.stream_id = 12345, .stream_id = 12345,
.code = FR_ERR_INCOMPL_REQ_PSEH, .code = FR_ERR_BAD_HEADER,
}, },
}, },
{ {
.type = CV_ERROR, .type = CV_ERROR,
.u.error = { .u.error = {
.stream_id = 12345, .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, .type = CV_ERROR,
.stream_off = 9 + 5 + 4, .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, .u.error.stream_id = 12345,
}, },
{ {
@ -982,7 +982,7 @@ static const struct frame_reader_test tests[] = {
{ {
.type = CV_ERROR, .type = CV_ERROR,
.stream_off = 9, .stream_off = 9,
.u.error.code = FR_ERR_HEADERS_TOO_LARGE, .u.error.code = FR_ERR_BAD_HEADER,
.u.error.stream_id = 12345, .u.error.stream_id = 12345,
}, },
{ {
@ -1034,7 +1034,7 @@ static const struct frame_reader_test tests[] = {
{ {
.type = CV_ERROR, .type = CV_ERROR,
.stream_off = 9 + 0 + 0x10 + 9, .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, .u.error.stream_id = 12345,
}, },
{ {
@ -1124,7 +1124,7 @@ test_one_frt (const struct frame_reader_test *frt)
conn_pub.lconn = &lconn; conn_pub.lconn = &lconn;
lsquic_mm_init(&mm); lsquic_mm_init(&mm);
lshpack_dec_init(&hdec); lshpack_dec_init(&hdec, LSHPACK_DEC_HTTP1X);
memset(&input, 0, sizeof(input)); memset(&input, 0, sizeof(input));
memcpy(input.in_buf, frt->frt_buf, frt->frt_bufsz); memcpy(input.in_buf, frt->frt_buf, frt->frt_bufsz);
input.in_sz = frt->frt_bufsz; input.in_sz = frt->frt_bufsz;

View file

@ -218,7 +218,7 @@ test_rw (unsigned max_frame_sz)
lsquic_mm_init(&mm); lsquic_mm_init(&mm);
lshpack_enc_init(&henc); lshpack_enc_init(&henc);
lshpack_dec_init(&hdec); lshpack_dec_init(&hdec, LSHPACK_DEC_HTTP1X);
stream = stream_new(); stream = stream_new();
stream->sm_max_sz = 1; stream->sm_max_sz = 1;

View file

@ -191,8 +191,8 @@ read_from_scheduled_packets (lsquic_send_ctl_t *send_ctl, lsquic_stream_id_t str
expected_type = QUIC_FRAME_STREAM; expected_type = QUIC_FRAME_STREAM;
TAILQ_FOREACH(packet_out, &send_ctl->sc_scheduled_packets, po_next) TAILQ_FOREACH(packet_out, &send_ctl->sc_scheduled_packets, po_next)
for (srec = posi_first(&posi, packet_out); srec; for (srec = lsquic_posi_first(&posi, packet_out); srec;
srec = posi_next(&posi)) srec = lsquic_posi_next(&posi))
{ {
if (fullcheck) 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 /* First packet may contain two stream frames, do not
* check it. * check it.
*/ */
assert(!posi_next(&posi)); assert(!lsquic_posi_next(&posi));
if (TAILQ_NEXT(packet_out, po_next)) if (TAILQ_NEXT(packet_out, po_next))
{ {
assert(packet_out->po_data_sz == packet_out->po_n_alloc); assert(packet_out->po_data_sz == packet_out->po_n_alloc);

View file

@ -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[4], QUIC_FRAME_STREAM, 12, 1);
lsquic_packet_out_add_stream(packet_out, &enpub.enp_mm, &streams[5], QUIC_FRAME_STREAM, 13, 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_stream == &streams[0]);
assert(srec->sr_off == 7); assert(srec->sr_off == 7);
assert(srec->sr_frame_type == QUIC_FRAME_STREAM); 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_stream == &streams[1]);
assert(srec->sr_off == 8); assert(srec->sr_off == 8);
assert(srec->sr_frame_type == QUIC_FRAME_STREAM); 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_stream == &streams[2]);
assert(srec->sr_off == 9); assert(srec->sr_off == 9);
assert(srec->sr_frame_type == QUIC_FRAME_STREAM); 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_stream == &streams[1]);
assert(srec->sr_off == 10); assert(srec->sr_off == 10);
assert(srec->sr_frame_type == QUIC_FRAME_RST_STREAM); 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_stream == &streams[3]);
assert(srec->sr_off == 11); assert(srec->sr_off == 11);
assert(srec->sr_frame_type == QUIC_FRAME_STREAM); 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_stream == &streams[4]);
assert(srec->sr_off == 12); assert(srec->sr_off == 12);
assert(srec->sr_frame_type == QUIC_FRAME_STREAM); 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_stream == &streams[5]);
assert(srec->sr_off == 13); assert(srec->sr_off == 13);
assert(srec->sr_frame_type == QUIC_FRAME_STREAM); 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); lsquic_packet_out_destroy(packet_out, &enpub, NULL);
assert(!lsquic_malo_first(enpub.enp_mm.malo.stream_rec_arr)); assert(!lsquic_malo_first(enpub.enp_mm.malo.stream_rec_arr));

View file

@ -214,13 +214,13 @@ run_pbt (int i)
/* Now see if we can restore it back: */ /* Now see if we can restore it back: */
lsquic_packno_t cur_packno = pbt->pbt_packno & lsquic_packno_t cur_packno = pbt->pbt_packno &
((1ULL << (packet_len << 3)) - 1); ((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); pbt->pbt_least_unacked);
assert(orig_packno == pbt->pbt_packno); assert(orig_packno == pbt->pbt_packno);
} }
struct restore_packno_test { struct lsquic_restore_packno_test {
int rpt_lineno; int rpt_lineno;
/* Input */ /* Input */
enum packno_bits rpt_packno_bits; enum packno_bits rpt_packno_bits;
@ -230,7 +230,7 @@ struct restore_packno_test {
lsquic_packno_t rpt_orig_packno; 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__, { .rpt_lineno = __LINE__,
@ -246,9 +246,9 @@ static const struct restore_packno_test rp_tests[] =
static void static void
run_rpt (int i) 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); 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); packet_len, rpt->rpt_max_packno);
assert(orig_packno == rpt->rpt_orig_packno); assert(orig_packno == rpt->rpt_orig_packno);
} }
@ -281,7 +281,7 @@ test_restore (enum packno_bits bits)
else else
assert(0); assert(0);
cur_packno = orig_packno & (epoch_delta - 1); 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); assert(orig_packno == restored_packno);
/* Test in the middle of the epoch */ /* Test in the middle of the epoch */
if (op == OP_MINUS) if (op == OP_MINUS)
@ -289,7 +289,7 @@ test_restore (enum packno_bits bits)
else else
orig_packno = epoch + n; orig_packno = epoch + n;
cur_packno = orig_packno & (epoch_delta - 1); 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); assert(orig_packno == restored_packno);
} }
@ -299,12 +299,12 @@ test_restore (enum packno_bits bits)
/* Test at the end of the epoch */ /* Test at the end of the epoch */
orig_packno = epoch + epoch_delta / 2 - n - 1; orig_packno = epoch + epoch_delta / 2 - n - 1;
cur_packno = orig_packno & (epoch_delta - 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); assert(orig_packno == restored_packno + epoch_delta);
/* Test in the middle of the epoch */ /* Test in the middle of the epoch */
orig_packno = epoch + 2 - n; orig_packno = epoch + 2 - n;
cur_packno = orig_packno & (epoch_delta - 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); assert(orig_packno == restored_packno + epoch_delta);
} }
@ -314,12 +314,12 @@ test_restore (enum packno_bits bits)
/* Test at the end of the epoch */ /* Test at the end of the epoch */
orig_packno = epoch - epoch_delta / 2 + n; orig_packno = epoch - epoch_delta / 2 + n;
cur_packno = orig_packno & (epoch_delta - 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); assert(orig_packno == restored_packno - epoch_delta);
/* Test in the middle of the epoch */ /* Test in the middle of the epoch */
orig_packno = epoch + 2 - n; orig_packno = epoch + 2 - n;
cur_packno = orig_packno & (epoch_delta - 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); assert(orig_packno == restored_packno - epoch_delta);
} }

View file

@ -70,7 +70,7 @@ test_shi (const struct order *order)
void *datap; void *datap;
struct data *data; struct data *data;
hash = stock_shared_hash_new(); hash = lsquic_stock_shared_hash_new();
for (i = 0; i < N_PAIRS; ++i) for (i = 0; i < N_PAIRS; ++i)
{ {
@ -124,7 +124,7 @@ test_shi (const struct order *order)
assert(0 == s); assert(0 == s);
} }
stock_shared_hash_destroy(hash); lsquic_stock_shared_hash_destroy(hash);
} }

View file

@ -218,8 +218,8 @@ read_from_scheduled_packets (lsquic_send_ctl_t *send_ctl, lsquic_stream_id_t str
expected_type = QUIC_FRAME_STREAM; expected_type = QUIC_FRAME_STREAM;
TAILQ_FOREACH(packet_out, &send_ctl->sc_scheduled_packets, po_next) TAILQ_FOREACH(packet_out, &send_ctl->sc_scheduled_packets, po_next)
for (srec = posi_first(&posi, packet_out); srec; for (srec = lsquic_posi_first(&posi, packet_out); srec;
srec = posi_next(&posi)) srec = lsquic_posi_next(&posi))
{ {
if (fullcheck) 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 /* First packet may contain two stream frames, do not
* check it. * check it.
*/ */
assert(!posi_next(&posi)); assert(!lsquic_posi_next(&posi));
if (TAILQ_NEXT(packet_out, po_next)) if (TAILQ_NEXT(packet_out, po_next))
{ {
assert(packet_out->po_data_sz == packet_out->po_n_alloc); assert(packet_out->po_data_sz == packet_out->po_n_alloc);

View file

@ -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); s = lsquic_parse_packet_in_begin(packet_in, gvnt->gvnt_len, 0, GQUIC_CID_LEN, &ppstate);
assert(s == 0); assert(s == 0);
for (s = packet_in_ver_first(packet_in, &vi, &ver_tag); s; for (s = lsquic_packet_in_ver_first(packet_in, &vi, &ver_tag); s;
s = packet_in_ver_next(&vi, &ver_tag)) s = lsquic_packet_in_ver_next(&vi, &ver_tag))
{ {
version = lsquic_tag2ver(ver_tag); version = lsquic_tag2ver(ver_tag);
assert(version < N_LSQVER); assert(version < N_LSQVER);