mirror of
				https://gitea.invidious.io/iv-org/litespeed-quic.git
				synced 2024-08-15 00:53:43 +00:00 
			
		
		
		
	Release 2.24.0
- [FEATURE] QUIC and HTTP/3 Internet Draft 31 support. Drop ID-30 and ID-31 support. - [BUGFIX] Divide-by-zero in newly enabled conn stats code when no packets were sent. - [BUGFIX] Memory leak in gQUIC client when server hello cannot be parsed. - [BUGFIX] Server Initial packet size calculation. - Log user-agent and CONN_CLOSE reason when peer reports error. - Example programs: Specify ALPN for echo and md5 clients and servers (issue #184). - Example programs: Don't add "QUIC_" prefix to lines in keylog file (issue #185). - http_server: Fix fd leak in preadv mode; fix preadv() usage when reading from disk.
This commit is contained in:
		
							parent
							
								
									078f53798c
								
							
						
					
					
						commit
						4429f8ea1e
					
				
					 33 changed files with 249 additions and 117 deletions
				
			
		
							
								
								
									
										17
									
								
								CHANGELOG
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								CHANGELOG
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,3 +1,20 @@
 | 
			
		|||
2020-10-28
 | 
			
		||||
    - 2.24.0
 | 
			
		||||
    - [FEATURE] QUIC and HTTP/3 Internet Draft 31 support.  Drop ID-30
 | 
			
		||||
      and ID-31 support.
 | 
			
		||||
    - [BUGFIX] Divide-by-zero in newly enabled conn stats code when no
 | 
			
		||||
      packets were sent.
 | 
			
		||||
    - [BUGFIX] Memory leak in gQUIC client when server hello cannot be
 | 
			
		||||
      parsed.
 | 
			
		||||
    - [BUGFIX] Server Initial packet size calculation.
 | 
			
		||||
    - Log user-agent and CONN_CLOSE reason when peer reports error.
 | 
			
		||||
    - Example programs: Specify ALPN for echo and md5 clients and servers
 | 
			
		||||
      (issue #184).
 | 
			
		||||
    - Example programs: Don't add "QUIC_" prefix to lines in keylog file
 | 
			
		||||
      (issue #185).
 | 
			
		||||
    - http_server: Fix fd leak in preadv mode; fix preadv() usage when
 | 
			
		||||
      reading from disk.
 | 
			
		||||
 | 
			
		||||
2020-10-22
 | 
			
		||||
    - 2.23.3
 | 
			
		||||
    - [BUGFIX] Update packetization threshold when writing to stream
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,8 +14,7 @@ distribution is used in our own products: LiteSpeed Web Server, LiteSpeed ADC,
 | 
			
		|||
and OpenLiteSpeed.
 | 
			
		||||
 | 
			
		||||
Currently supported QUIC versions are Q043, Q046, Q050, ID-27, ID-28, ID-29,
 | 
			
		||||
ID-30, and ID-31.  Support for newer versions is added soon after they
 | 
			
		||||
are released.
 | 
			
		||||
and ID-32.  Support for newer versions is added soon after they are released.
 | 
			
		||||
 | 
			
		||||
Documentation
 | 
			
		||||
-------------
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -213,6 +213,7 @@ main (int argc, char **argv)
 | 
			
		|||
 | 
			
		||||
    TAILQ_INIT(&sports);
 | 
			
		||||
    prog_init(&prog, 0, &sports, &client_echo_stream_if, &client_ctx);
 | 
			
		||||
    prog.prog_api.ea_alpn = "echo";
 | 
			
		||||
 | 
			
		||||
    while (-1 != (opt = getopt(argc, argv, PROG_OPTS "h")))
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,6 +20,8 @@
 | 
			
		|||
 | 
			
		||||
#include "lsquic.h"
 | 
			
		||||
#include "test_common.h"
 | 
			
		||||
#include "../src/liblsquic/lsquic_hash.h"
 | 
			
		||||
#include "test_cert.h"
 | 
			
		||||
#include "prog.h"
 | 
			
		||||
 | 
			
		||||
#include "../src/liblsquic/lsquic_logger.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -218,6 +220,7 @@ main (int argc, char **argv)
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    add_alpn("echo");
 | 
			
		||||
    if (0 != prog_prep(&prog))
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_ERROR("could not prep");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -582,13 +582,39 @@ my_preadv (void *user_data, const struct iovec *iov, int iovcnt)
 | 
			
		|||
{
 | 
			
		||||
#if HAVE_PREADV
 | 
			
		||||
    lsquic_stream_ctx_t *const st_h = user_data;
 | 
			
		||||
    return preadv(st_h->file_fd, iov, iovcnt, st_h->written);
 | 
			
		||||
    ssize_t nread = preadv(st_h->file_fd, iov, iovcnt, st_h->written);
 | 
			
		||||
    LSQ_DEBUG("%s: wrote %zd bytes", __func__, (size_t) nread);
 | 
			
		||||
    return nread;
 | 
			
		||||
#else
 | 
			
		||||
    return -1;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static size_t
 | 
			
		||||
pwritev_fallback_read (void *lsqr_ctx, void *buf, size_t count)
 | 
			
		||||
{
 | 
			
		||||
    lsquic_stream_ctx_t *const st_h = lsqr_ctx;
 | 
			
		||||
    struct iovec iov;
 | 
			
		||||
    size_t ntoread;
 | 
			
		||||
 | 
			
		||||
    ntoread = st_h->file_size - st_h->written;
 | 
			
		||||
    if (ntoread > count)
 | 
			
		||||
        count = ntoread;
 | 
			
		||||
    iov.iov_base = buf;
 | 
			
		||||
    iov.iov_len = count;
 | 
			
		||||
    return my_preadv(lsqr_ctx, &iov, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static size_t
 | 
			
		||||
pwritev_fallback_size (void *lsqr_ctx)
 | 
			
		||||
{
 | 
			
		||||
    lsquic_stream_ctx_t *const st_h = lsqr_ctx;
 | 
			
		||||
    return st_h->file_size - st_h->written;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
http_server_on_write (lsquic_stream_t *stream, lsquic_stream_ctx_t *st_h)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -624,11 +650,17 @@ http_server_on_write (lsquic_stream_t *stream, lsquic_stream_ctx_t *st_h)
 | 
			
		|||
                    to_write = s_pwritev;
 | 
			
		||||
                nw = lsquic_stream_pwritev(stream, my_preadv, st_h, to_write);
 | 
			
		||||
                if (nw == 0)
 | 
			
		||||
                    goto use_reader;
 | 
			
		||||
                {
 | 
			
		||||
                    struct lsquic_reader reader = {
 | 
			
		||||
                        .lsqr_read = pwritev_fallback_read,
 | 
			
		||||
                        .lsqr_size = pwritev_fallback_size,
 | 
			
		||||
                        .lsqr_ctx = st_h,
 | 
			
		||||
                    };
 | 
			
		||||
                    nw = lsquic_stream_writef(stream, &reader);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
  use_reader:
 | 
			
		||||
                nw = lsquic_stream_writef(stream, &st_h->reader);
 | 
			
		||||
            }
 | 
			
		||||
            if (nw < 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -1006,6 +1038,8 @@ http_server_on_close (lsquic_stream_t *stream, lsquic_stream_ctx_t *st_h)
 | 
			
		|||
    free(st_h->req_path);
 | 
			
		||||
    if (st_h->reader.lsqr_ctx)
 | 
			
		||||
        destroy_lsquic_reader_ctx(st_h->reader.lsqr_ctx);
 | 
			
		||||
    if (s_pwritev)
 | 
			
		||||
        close(st_h->file_fd);
 | 
			
		||||
    if (st_h->req)
 | 
			
		||||
        interop_server_hset_destroy(st_h->req);
 | 
			
		||||
    free(st_h);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -460,6 +460,7 @@ main (int argc, char **argv)
 | 
			
		|||
 | 
			
		||||
    TAILQ_INIT(&sports);
 | 
			
		||||
    prog_init(&prog, 0, &sports, &client_file_stream_if, &client_ctx);
 | 
			
		||||
    prog.prog_api.ea_alpn = "md5";
 | 
			
		||||
 | 
			
		||||
    while (-1 != (opt = getopt(argc, argv, PROG_OPTS "bhr:f:p:")))
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,6 +19,8 @@
 | 
			
		|||
 | 
			
		||||
#include "lsquic.h"
 | 
			
		||||
#include "test_common.h"
 | 
			
		||||
#include "../src/liblsquic/lsquic_hash.h"
 | 
			
		||||
#include "test_cert.h"
 | 
			
		||||
#include "prog.h"
 | 
			
		||||
 | 
			
		||||
#include "../src/liblsquic/lsquic_logger.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -325,6 +327,7 @@ main (int argc, char **argv)
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    add_alpn("md5");
 | 
			
		||||
    if (0 != prog_prep(&prog))
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_ERROR("could not prep");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -610,11 +610,6 @@ keylog_open (void *ctx, lsquic_conn_t *conn)
 | 
			
		|||
static void
 | 
			
		||||
keylog_log_line (void *handle, const char *line)
 | 
			
		||||
{
 | 
			
		||||
    size_t len;
 | 
			
		||||
 | 
			
		||||
    len = strlen(line);
 | 
			
		||||
    if (len < sizeof("QUIC_") - 1 || strncmp(line, "QUIC_", 5))
 | 
			
		||||
        fputs("QUIC_", handle);
 | 
			
		||||
    fputs(line, handle);
 | 
			
		||||
    fputs("\n", handle);
 | 
			
		||||
    fflush(handle);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,13 +58,9 @@ developed by the IETF.  Both types are included in a single enum:
 | 
			
		|||
 | 
			
		||||
        IETF QUIC version ID 29
 | 
			
		||||
 | 
			
		||||
    .. member:: LSQVER_ID30
 | 
			
		||||
    .. member:: LSQVER_ID32
 | 
			
		||||
 | 
			
		||||
        IETF QUIC version ID 30; this version is deprecated.
 | 
			
		||||
 | 
			
		||||
    .. member:: LSQVER_ID31
 | 
			
		||||
 | 
			
		||||
        IETF QUIC version ID 31
 | 
			
		||||
        IETF QUIC version ID 32
 | 
			
		||||
 | 
			
		||||
    .. member:: N_LSQVER
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,9 +24,9 @@ copyright = u'2020, LiteSpeed Technologies'
 | 
			
		|||
author = u'LiteSpeed Technologies'
 | 
			
		||||
 | 
			
		||||
# The short X.Y version
 | 
			
		||||
version = u'2.23'
 | 
			
		||||
version = u'2.24'
 | 
			
		||||
# The full version, including alpha/beta/rc tags
 | 
			
		||||
release = u'2.23.3'
 | 
			
		||||
release = u'2.24.0'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# -- General configuration ---------------------------------------------------
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,7 +17,7 @@ Most of the code in this distribution has been  used in our own products
 | 
			
		|||
since 2017.
 | 
			
		||||
 | 
			
		||||
Currently supported QUIC versions are Q043, Q046, Q050, ID-27, ID-28,
 | 
			
		||||
ID-29, ID-30, and ID-31.
 | 
			
		||||
ID-29, and ID-32.
 | 
			
		||||
Support for newer versions will be added soon after they are released.
 | 
			
		||||
 | 
			
		||||
LSQUIC is licensed under the `MIT License`_; see LICENSE in the source
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,8 +24,8 @@ extern "C" {
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
#define LSQUIC_MAJOR_VERSION 2
 | 
			
		||||
#define LSQUIC_MINOR_VERSION 23
 | 
			
		||||
#define LSQUIC_PATCH_VERSION 3
 | 
			
		||||
#define LSQUIC_MINOR_VERSION 24
 | 
			
		||||
#define LSQUIC_PATCH_VERSION 0
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Engine flags:
 | 
			
		||||
| 
						 | 
				
			
			@ -92,14 +92,9 @@ enum lsquic_version
 | 
			
		|||
    LSQVER_ID29,
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * IETF QUIC Draft-30
 | 
			
		||||
     * IETF QUIC Draft-32
 | 
			
		||||
     */
 | 
			
		||||
    LSQVER_ID30,
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * IETF QUIC Draft-31
 | 
			
		||||
     */
 | 
			
		||||
    LSQVER_ID31,
 | 
			
		||||
    LSQVER_ID32,
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Special version to trigger version negotiation.
 | 
			
		||||
| 
						 | 
				
			
			@ -112,7 +107,7 @@ enum lsquic_version
 | 
			
		|||
 | 
			
		||||
/**
 | 
			
		||||
 * We currently support versions 43, 46, 50, Draft-27, Draft-28, Draft-29,
 | 
			
		||||
 * Draft-30, and Draft-31.
 | 
			
		||||
 * and Draft-32.
 | 
			
		||||
 * @see lsquic_version
 | 
			
		||||
 */
 | 
			
		||||
#define LSQUIC_SUPPORTED_VERSIONS ((1 << N_LSQVER) - 1)
 | 
			
		||||
| 
						 | 
				
			
			@ -125,18 +120,17 @@ enum lsquic_version
 | 
			
		|||
#define LSQUIC_EXPERIMENTAL_VERSIONS ( \
 | 
			
		||||
                            (1 << LSQVER_VERNEG) | LSQUIC_EXPERIMENTAL_Q098)
 | 
			
		||||
 | 
			
		||||
#define LSQUIC_DEPRECATED_VERSIONS ((1 << LSQVER_ID27) | (1 << LSQVER_ID28) \
 | 
			
		||||
                                  | (1 << LSQVER_ID30))
 | 
			
		||||
#define LSQUIC_DEPRECATED_VERSIONS ((1 << LSQVER_ID27) | (1 << LSQVER_ID28))
 | 
			
		||||
 | 
			
		||||
#define LSQUIC_GQUIC_HEADER_VERSIONS (1 << LSQVER_043)
 | 
			
		||||
 | 
			
		||||
#define LSQUIC_IETF_VERSIONS ((1 << LSQVER_ID27) | (1 << LSQVER_ID28) \
 | 
			
		||||
                          | (1 << LSQVER_ID29) | (1 << LSQVER_ID30)   \
 | 
			
		||||
                          | (1 << LSQVER_ID31) | (1 << LSQVER_VERNEG))
 | 
			
		||||
                          | (1 << LSQVER_ID29) \
 | 
			
		||||
                          | (1 << LSQVER_ID32) | (1 << LSQVER_VERNEG))
 | 
			
		||||
 | 
			
		||||
#define LSQUIC_IETF_DRAFT_VERSIONS ((1 << LSQVER_ID27) | (1 << LSQVER_ID28) \
 | 
			
		||||
                                  | (1 << LSQVER_ID29) | (1 << LSQVER_ID30) \
 | 
			
		||||
                                  | (1 << LSQVER_ID31) | (1 << LSQVER_VERNEG))
 | 
			
		||||
                                  | (1 << LSQVER_ID29) \
 | 
			
		||||
                                  | (1 << LSQVER_ID32) | (1 << LSQVER_VERNEG))
 | 
			
		||||
 | 
			
		||||
enum lsquic_hsk_status
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -133,6 +133,7 @@ hsk_client_on_read (lsquic_stream_t *stream, struct lsquic_stream_ctx *sh)
 | 
			
		|||
        /* fallthru */
 | 
			
		||||
    case DATA_FORMAT_ERROR:
 | 
			
		||||
        LSQ_INFO("lsquic_enc_session_handle_chlo_reply returned an error");
 | 
			
		||||
        lsquic_mm_put_16k(c_hsk->mm, c_hsk->buf_in);
 | 
			
		||||
        c_hsk->buf_in = NULL;
 | 
			
		||||
        lsquic_stream_wantread(stream, 0);
 | 
			
		||||
        c_hsk->lconn->cn_if->ci_hsk_done(c_hsk->lconn, LSQ_HSK_FAIL);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -338,8 +338,7 @@ extern const struct enc_session_funcs_iquic lsquic_enc_session_iquic_ietf_v1;
 | 
			
		|||
    ver == LSQVER_ID27 ? &lsquic_enc_session_common_ietf_v1 : \
 | 
			
		||||
    ver == LSQVER_ID28 ? &lsquic_enc_session_common_ietf_v1 : \
 | 
			
		||||
    ver == LSQVER_ID29 ? &lsquic_enc_session_common_ietf_v1 : \
 | 
			
		||||
    ver == LSQVER_ID30 ? &lsquic_enc_session_common_ietf_v1 : \
 | 
			
		||||
    ver == LSQVER_ID31 ? &lsquic_enc_session_common_ietf_v1 : \
 | 
			
		||||
    ver == LSQVER_ID32 ? &lsquic_enc_session_common_ietf_v1 : \
 | 
			
		||||
    ver == LSQVER_VERNEG ? &lsquic_enc_session_common_ietf_v1 : \
 | 
			
		||||
    ver == LSQVER_050 ? &lsquic_enc_session_common_gquic_2 : \
 | 
			
		||||
    &lsquic_enc_session_common_gquic_1 )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -74,9 +74,8 @@ static const struct alpn_map {
 | 
			
		|||
    {   LSQVER_ID27, (unsigned char *) "\x05h3-27",     },
 | 
			
		||||
    {   LSQVER_ID28, (unsigned char *) "\x05h3-28",     },
 | 
			
		||||
    {   LSQVER_ID29, (unsigned char *) "\x05h3-29",     },
 | 
			
		||||
    {   LSQVER_ID30, (unsigned char *) "\x05h3-30",     },
 | 
			
		||||
    {   LSQVER_ID31, (unsigned char *) "\x05h3-31",     },
 | 
			
		||||
    {   LSQVER_VERNEG, (unsigned char *) "\x05h3-31",     },
 | 
			
		||||
    {   LSQVER_ID32, (unsigned char *) "\x05h3-32",     },
 | 
			
		||||
    {   LSQVER_VERNEG, (unsigned char *) "\x05h3-32",     },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct enc_sess_iquic;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1114,7 +1114,8 @@ full_conn_ci_destroy (lsquic_conn_t *lconn)
 | 
			
		|||
        conn->fc_stats.in.packets, conn->fc_stats.in.undec_packets,
 | 
			
		||||
        conn->fc_stats.in.dup_packets, conn->fc_stats.in.err_packets,
 | 
			
		||||
        conn->fc_stats.out.packets,
 | 
			
		||||
        conn->fc_stats.out.stream_data_sz / conn->fc_stats.out.packets);
 | 
			
		||||
        conn->fc_stats.out.stream_data_sz /
 | 
			
		||||
            (conn->fc_stats.out.packets ? conn->fc_stats.out.packets : 1));
 | 
			
		||||
    LSQ_NOTICE("ACKs: in: %lu; processed: %lu; merged: %lu",
 | 
			
		||||
        conn->fc_stats.in.n_acks, conn->fc_stats.in.n_acks_proc,
 | 
			
		||||
        conn->fc_stats.in.n_acks_merged);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3103,7 +3103,8 @@ ietf_full_conn_ci_destroy (struct lsquic_conn *lconn)
 | 
			
		|||
            conn->ifc_stats.in.packets, conn->ifc_stats.in.undec_packets,
 | 
			
		||||
            conn->ifc_stats.in.dup_packets, conn->ifc_stats.in.err_packets,
 | 
			
		||||
            conn->ifc_stats.out.packets,
 | 
			
		||||
            conn->ifc_stats.out.stream_data_sz / conn->ifc_stats.out.packets);
 | 
			
		||||
            conn->ifc_stats.out.stream_data_sz /
 | 
			
		||||
                (conn->ifc_stats.out.packets ? conn->ifc_stats.out.packets : 1));
 | 
			
		||||
        LSQ_NOTICE("ACKs: in: %lu; processed: %lu; merged: %lu",
 | 
			
		||||
            conn->ifc_stats.in.n_acks, conn->ifc_stats.in.n_acks_proc,
 | 
			
		||||
            conn->ifc_stats.in.n_acks_merged);
 | 
			
		||||
| 
						 | 
				
			
			@ -4471,6 +4472,24 @@ generate_ack_frequency_frame (struct ietf_full_conn *conn, lsquic_time_t unused)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
maybe_pad_packet (struct ietf_full_conn *conn,
 | 
			
		||||
                                        struct lsquic_packet_out *packet_out)
 | 
			
		||||
{
 | 
			
		||||
    unsigned short avail;
 | 
			
		||||
 | 
			
		||||
    avail = lsquic_packet_out_avail(packet_out);
 | 
			
		||||
    if (avail)
 | 
			
		||||
    {
 | 
			
		||||
        memset(packet_out->po_data + packet_out->po_data_sz, 0, avail);
 | 
			
		||||
        lsquic_send_ctl_incr_pack_sz(&conn->ifc_send_ctl, packet_out, avail);
 | 
			
		||||
        packet_out->po_frame_types |= QUIC_FTBIT_PADDING;
 | 
			
		||||
        LSQ_DEBUG("added %hu-byte PADDING frame to packet %"PRIu64, avail,
 | 
			
		||||
                                                        packet_out->po_packno);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
generate_path_chal_frame (struct ietf_full_conn *conn, lsquic_time_t now,
 | 
			
		||||
                                                            unsigned path_id)
 | 
			
		||||
| 
						 | 
				
			
			@ -4530,6 +4549,7 @@ generate_path_chal_frame (struct ietf_full_conn *conn, lsquic_time_t now,
 | 
			
		|||
    packet_out->po_frame_types |= QUIC_FTBIT_PATH_CHALLENGE;
 | 
			
		||||
    lsquic_send_ctl_incr_pack_sz(&conn->ifc_send_ctl, packet_out, w);
 | 
			
		||||
    packet_out->po_regen_sz += w;
 | 
			
		||||
    maybe_pad_packet(conn, packet_out);
 | 
			
		||||
    conn->ifc_send_flags &= ~(SF_SEND_PATH_CHAL << path_id);
 | 
			
		||||
    lsquic_alarmset_set(&conn->ifc_alset, AL_PATH_CHAL + path_id,
 | 
			
		||||
                    now + (INITIAL_CHAL_TIMEOUT << (copath->cop_n_chals - 1)));
 | 
			
		||||
| 
						 | 
				
			
			@ -4600,6 +4620,7 @@ generate_path_resp_frame (struct ietf_full_conn *conn, lsquic_time_t now,
 | 
			
		|||
    }
 | 
			
		||||
    packet_out->po_frame_types |= QUIC_FTBIT_PATH_RESPONSE;
 | 
			
		||||
    lsquic_send_ctl_incr_pack_sz(&conn->ifc_send_ctl, packet_out, w);
 | 
			
		||||
    maybe_pad_packet(conn, packet_out);
 | 
			
		||||
    packet_out->po_regen_sz += w;
 | 
			
		||||
    conn->ifc_send_flags &= ~(SF_SEND_PATH_RESP << path_id);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -5699,6 +5720,34 @@ process_ping_frame (struct ietf_full_conn *conn,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
is_benign_transport_error_code (uint64_t error_code)
 | 
			
		||||
{
 | 
			
		||||
    switch (error_code)
 | 
			
		||||
    {
 | 
			
		||||
    case TEC_NO_ERROR:
 | 
			
		||||
    case TEC_INTERNAL_ERROR:
 | 
			
		||||
        return 1;
 | 
			
		||||
    default:
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
is_benign_application_error_code (uint64_t error_code)
 | 
			
		||||
{
 | 
			
		||||
    switch (error_code)
 | 
			
		||||
    {
 | 
			
		||||
    case HEC_NO_ERROR:
 | 
			
		||||
    case HEC_INTERNAL_ERROR:
 | 
			
		||||
        return 1;
 | 
			
		||||
    default:
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static unsigned
 | 
			
		||||
process_connection_close_frame (struct ietf_full_conn *conn,
 | 
			
		||||
        struct lsquic_packet_in *packet_in, const unsigned char *p, size_t len)
 | 
			
		||||
| 
						 | 
				
			
			@ -5709,6 +5758,7 @@ process_connection_close_frame (struct ietf_full_conn *conn,
 | 
			
		|||
    uint16_t reason_len;
 | 
			
		||||
    uint8_t reason_off;
 | 
			
		||||
    int parsed_len, app_error;
 | 
			
		||||
    const char *ua;
 | 
			
		||||
 | 
			
		||||
    parsed_len = conn->ifc_conn.cn_pf->pf_parse_connect_close_frame(p, len,
 | 
			
		||||
                            &app_error, &error_code, &reason_len, &reason_off);
 | 
			
		||||
| 
						 | 
				
			
			@ -5716,7 +5766,25 @@ process_connection_close_frame (struct ietf_full_conn *conn,
 | 
			
		|||
        return 0;
 | 
			
		||||
    EV_LOG_CONNECTION_CLOSE_FRAME_IN(LSQUIC_LOG_CONN_ID, error_code,
 | 
			
		||||
                            (int) reason_len, (const char *) p + reason_off);
 | 
			
		||||
    LSQ_INFO("Received CONNECTION_CLOSE frame (%s-level code: %"PRIu64"; "
 | 
			
		||||
    if (LSQ_LOG_ENABLED(LSQ_LOG_NOTICE)
 | 
			
		||||
        && !(   (!app_error && is_benign_transport_error_code(error_code))
 | 
			
		||||
              ||( app_error && is_benign_application_error_code(error_code))))
 | 
			
		||||
    {
 | 
			
		||||
        if (conn->ifc_flags & IFC_HTTP)
 | 
			
		||||
        {
 | 
			
		||||
            ua = lsquic_qdh_get_ua(&conn->ifc_qdh);
 | 
			
		||||
            if (!ua)
 | 
			
		||||
                ua = "unknown peer";
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
            ua = "non-HTTP/3 peer";
 | 
			
		||||
        LSQ_NOTICE("Received CONNECTION_CLOSE from <%s> with %s-level error "
 | 
			
		||||
            "code %"PRIu64", reason: `%.*s'", ua,
 | 
			
		||||
            app_error ? "application" : "transport", error_code,
 | 
			
		||||
            (int) reason_len, (const char *) p + reason_off);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
        LSQ_INFO("Received CONNECTION_CLOSE frame (%s-level code: %"PRIu64"; "
 | 
			
		||||
            "reason: %.*s)", app_error ? "application" : "transport",
 | 
			
		||||
                error_code, (int) reason_len, (const char *) p + reason_off);
 | 
			
		||||
    conn->ifc_flags |= IFC_RECV_CLOSE;
 | 
			
		||||
| 
						 | 
				
			
			@ -9126,16 +9194,14 @@ hcsi_on_new (void *stream_if_ctx, struct lsquic_stream *stream)
 | 
			
		|||
            callbacks = &hcsi_callbacks_server_28;
 | 
			
		||||
            break;
 | 
			
		||||
        case (0 << 8) | LSQVER_ID29:
 | 
			
		||||
        case (0 << 8) | LSQVER_ID30:
 | 
			
		||||
        case (0 << 8) | LSQVER_ID31:
 | 
			
		||||
        case (0 << 8) | LSQVER_ID32:
 | 
			
		||||
            callbacks = &hcsi_callbacks_client_29;
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            assert(0);
 | 
			
		||||
            /* fallthru */
 | 
			
		||||
        case (1 << 8) | LSQVER_ID29:
 | 
			
		||||
        case (1 << 8) | LSQVER_ID30:
 | 
			
		||||
        case (1 << 8) | LSQVER_ID31:
 | 
			
		||||
        case (1 << 8) | LSQVER_ID32:
 | 
			
		||||
            callbacks = &hcsi_callbacks_server_29;
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -887,7 +887,8 @@ allocate_packet_out (struct mini_conn *mc, const unsigned char *nonce)
 | 
			
		|||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
    packet_out = lsquic_packet_out_new(&mc->mc_enpub->enp_mm, NULL, 1,
 | 
			
		||||
                &mc->mc_conn, GQUIC_PACKNO_LEN_1, NULL, nonce, &mc->mc_path);
 | 
			
		||||
                &mc->mc_conn, GQUIC_PACKNO_LEN_1, NULL, nonce, &mc->mc_path,
 | 
			
		||||
                HETY_NOT_SET);
 | 
			
		||||
    if (!packet_out)
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_WARN("could not allocate packet: %s", strerror(errno));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -121,7 +121,8 @@ imico_get_packet_out (struct ietf_mini_conn *conn,
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    packet_out = lsquic_packet_out_new(&conn->imc_enpub->enp_mm, NULL, 1,
 | 
			
		||||
            &conn->imc_conn, IQUIC_PACKNO_LEN_1, NULL, NULL, &conn->imc_path);
 | 
			
		||||
            &conn->imc_conn, IQUIC_PACKNO_LEN_1, NULL, NULL, &conn->imc_path,
 | 
			
		||||
            header_type);
 | 
			
		||||
    if (!packet_out)
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_WARN("could not allocate packet: %s", strerror(errno));
 | 
			
		||||
| 
						 | 
				
			
			@ -696,6 +697,18 @@ imico_can_send (const struct ietf_mini_conn *conn, size_t size)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
imico_zero_pad (struct lsquic_packet_out *packet_out)
 | 
			
		||||
{
 | 
			
		||||
    size_t pad_size;
 | 
			
		||||
 | 
			
		||||
    pad_size = lsquic_packet_out_avail(packet_out);
 | 
			
		||||
    memset(packet_out->po_data + packet_out->po_data_sz, 0, pad_size);
 | 
			
		||||
    packet_out->po_data_sz += pad_size;
 | 
			
		||||
    packet_out->po_frame_types |= QUIC_FTBIT_PADDING;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static struct lsquic_packet_out *
 | 
			
		||||
ietf_mini_conn_ci_next_packet_to_send (struct lsquic_conn *lconn,
 | 
			
		||||
                                            const struct to_coal *to_coal)
 | 
			
		||||
| 
						 | 
				
			
			@ -708,6 +721,16 @@ ietf_mini_conn_ci_next_packet_to_send (struct lsquic_conn *lconn,
 | 
			
		|||
    {
 | 
			
		||||
        if (packet_out->po_flags & PO_SENT)
 | 
			
		||||
            continue;
 | 
			
		||||
        /* [draft-ietf-quic-transport-32] Section 14.1:
 | 
			
		||||
         " a server MUST expand the payload of all UDP datagrams carrying
 | 
			
		||||
         " ack-eliciting Initial packets to at least the smallest allowed
 | 
			
		||||
         " maximum datagram size of 1200 bytes.
 | 
			
		||||
         */
 | 
			
		||||
        if (packet_out->po_header_type == HETY_INITIAL
 | 
			
		||||
                && !(packet_out->po_frame_types & (1 << QUIC_FRAME_PADDING))
 | 
			
		||||
                && (packet_out->po_frame_types & IQUIC_FRAME_ACKABLE_MASK)
 | 
			
		||||
                && lsquic_packet_out_avail(packet_out) > 0)
 | 
			
		||||
            imico_zero_pad(packet_out);
 | 
			
		||||
        packet_size = lsquic_packet_out_total_sz(lconn, packet_out);
 | 
			
		||||
        if (!(to_coal
 | 
			
		||||
            && (packet_size + to_coal->prev_sz_sum
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -204,7 +204,7 @@ lsquic_packet_out_t *
 | 
			
		|||
lsquic_packet_out_new (struct lsquic_mm *mm, struct malo *malo, int use_cid,
 | 
			
		||||
                const struct lsquic_conn *lconn, enum packno_bits bits,
 | 
			
		||||
                const lsquic_ver_tag_t *ver_tag, const unsigned char *nonce,
 | 
			
		||||
                const struct network_path *path)
 | 
			
		||||
                const struct network_path *path, enum header_type header_type)
 | 
			
		||||
{
 | 
			
		||||
    lsquic_packet_out_t *packet_out;
 | 
			
		||||
    enum packet_out_flags flags;
 | 
			
		||||
| 
						 | 
				
			
			@ -222,7 +222,7 @@ lsquic_packet_out_new (struct lsquic_mm *mm, struct malo *malo, int use_cid,
 | 
			
		|||
        flags |= PO_LONGHEAD;
 | 
			
		||||
 | 
			
		||||
    header_size = lconn->cn_pf->pf_packout_max_header_size(lconn, flags,
 | 
			
		||||
                                                        path->np_dcid.len);
 | 
			
		||||
                                            path->np_dcid.len, header_type);
 | 
			
		||||
    tag_len = lconn->cn_esf_c->esf_tag_len;
 | 
			
		||||
    max_size = path->np_pack_size;
 | 
			
		||||
    if (header_size + tag_len >= max_size)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -229,8 +229,9 @@ typedef struct lsquic_packet_out
 | 
			
		|||
    (p)->po_flags |= ((b) & 1) << POSPIN_SHIFT;                         \
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
#define lsquic_po_header_length(lconn, po_flags, dcid_len) ( \
 | 
			
		||||
    lconn->cn_pf->pf_packout_max_header_size(lconn, po_flags, dcid_len))
 | 
			
		||||
#define lsquic_po_header_length(lconn, po_flags, dcid_len, header_type) (   \
 | 
			
		||||
    lconn->cn_pf->pf_packout_max_header_size(lconn, po_flags, dcid_len,     \
 | 
			
		||||
                                             header_type))                  \
 | 
			
		||||
 | 
			
		||||
#define lsquic_packet_out_total_sz(lconn, p) (\
 | 
			
		||||
    (lconn)->cn_pf->pf_packout_size(lconn, p))
 | 
			
		||||
| 
						 | 
				
			
			@ -308,7 +309,7 @@ lsquic_packet_out_t *
 | 
			
		|||
lsquic_packet_out_new (struct lsquic_mm *, struct malo *, int use_cid,
 | 
			
		||||
                       const struct lsquic_conn *, enum packno_bits,
 | 
			
		||||
                       const lsquic_ver_tag_t *, const unsigned char *nonce,
 | 
			
		||||
                       const struct network_path *);
 | 
			
		||||
                       const struct network_path *, enum header_type);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
lsquic_packet_out_destroy (lsquic_packet_out_t *,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -222,7 +222,7 @@ struct parse_funcs
 | 
			
		|||
     */
 | 
			
		||||
    size_t
 | 
			
		||||
    (*pf_packout_max_header_size) (const struct lsquic_conn *,
 | 
			
		||||
                                    enum packet_out_flags, size_t dcid_len);
 | 
			
		||||
                    enum packet_out_flags, size_t dcid_len, enum header_type);
 | 
			
		||||
 | 
			
		||||
    enum packno_bits
 | 
			
		||||
    (*pf_calc_packno_bits) (lsquic_packno_t packno,
 | 
			
		||||
| 
						 | 
				
			
			@ -381,7 +381,7 @@ lsquic_gquic_packout_size (const struct lsquic_conn *,
 | 
			
		|||
 | 
			
		||||
size_t
 | 
			
		||||
lsquic_gquic_packout_header_size (const struct lsquic_conn *conn,
 | 
			
		||||
                                enum packet_out_flags flags, size_t unused);
 | 
			
		||||
                enum packet_out_flags flags, size_t unused, enum header_type);
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
lsquic_gquic_po_header_sz (enum packet_out_flags flags);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -215,7 +215,8 @@ gquic_Q046_packout_header_size_short (const struct lsquic_conn *lconn,
 | 
			
		|||
 | 
			
		||||
static size_t
 | 
			
		||||
gquic_Q046_packout_header_size (const struct lsquic_conn *lconn,
 | 
			
		||||
                            enum packet_out_flags flags, size_t dcid_len_unused)
 | 
			
		||||
                            enum packet_out_flags flags, size_t dcid_len_unused,
 | 
			
		||||
                            enum header_type unused)
 | 
			
		||||
{
 | 
			
		||||
    if (0 == (flags & PO_LONGHEAD))
 | 
			
		||||
        return gquic_Q046_packout_header_size_short(lconn, flags);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -459,7 +459,8 @@ gquic_Q050_packout_header_size_short (const struct lsquic_conn *lconn,
 | 
			
		|||
 | 
			
		||||
static size_t
 | 
			
		||||
gquic_Q050_packout_max_header_size (const struct lsquic_conn *lconn,
 | 
			
		||||
                        enum packet_out_flags flags, size_t dcid_len_unused)
 | 
			
		||||
                        enum packet_out_flags flags, size_t dcid_len_unused,
 | 
			
		||||
                        enum header_type unused)
 | 
			
		||||
{
 | 
			
		||||
    if (lconn->cn_flags & LSCONN_SERVER)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -220,37 +220,7 @@ lsquic_cid_from_packet (const unsigned char *buf, size_t bufsz,
 | 
			
		|||
/* See [draft-ietf-quic-transport-28], Section 12.4 (Table 3) */
 | 
			
		||||
const enum quic_ft_bit lsquic_legal_frames_by_level[N_LSQVER][N_ENC_LEVS] =
 | 
			
		||||
{
 | 
			
		||||
    [LSQVER_ID31] = {
 | 
			
		||||
    [ENC_LEV_CLEAR] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
 | 
			
		||||
                    | QUIC_FTBIT_ACK | QUIC_FTBIT_CONNECTION_CLOSE,
 | 
			
		||||
    [ENC_LEV_EARLY] = QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
 | 
			
		||||
                    | QUIC_FTBIT_STREAM | QUIC_FTBIT_RST_STREAM
 | 
			
		||||
                    | QUIC_FTBIT_BLOCKED | QUIC_FTBIT_CONNECTION_CLOSE
 | 
			
		||||
                    | QUIC_FTBIT_MAX_DATA | QUIC_FTBIT_MAX_STREAM_DATA
 | 
			
		||||
                    | QUIC_FTBIT_MAX_STREAMS | QUIC_FTBIT_STREAM_BLOCKED
 | 
			
		||||
                    | QUIC_FTBIT_STREAMS_BLOCKED
 | 
			
		||||
                    | QUIC_FTBIT_NEW_CONNECTION_ID | QUIC_FTBIT_STOP_SENDING
 | 
			
		||||
                    | QUIC_FTBIT_PATH_CHALLENGE | QUIC_FTBIT_PATH_RESPONSE
 | 
			
		||||
                    | QUIC_FTBIT_DATAGRAM
 | 
			
		||||
                    | QUIC_FTBIT_RETIRE_CONNECTION_ID,
 | 
			
		||||
    [ENC_LEV_INIT]  = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
 | 
			
		||||
                    | QUIC_FTBIT_ACK| QUIC_FTBIT_CONNECTION_CLOSE,
 | 
			
		||||
    [ENC_LEV_FORW]  = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
 | 
			
		||||
                    | QUIC_FTBIT_ACK | QUIC_FTBIT_CONNECTION_CLOSE
 | 
			
		||||
                    | QUIC_FTBIT_STREAM | QUIC_FTBIT_RST_STREAM
 | 
			
		||||
                    | QUIC_FTBIT_BLOCKED
 | 
			
		||||
                    | QUIC_FTBIT_MAX_DATA | QUIC_FTBIT_MAX_STREAM_DATA
 | 
			
		||||
                    | QUIC_FTBIT_MAX_STREAMS | QUIC_FTBIT_STREAM_BLOCKED
 | 
			
		||||
                    | QUIC_FTBIT_STREAMS_BLOCKED
 | 
			
		||||
                    | QUIC_FTBIT_NEW_CONNECTION_ID | QUIC_FTBIT_STOP_SENDING
 | 
			
		||||
                    | QUIC_FTBIT_PATH_CHALLENGE | QUIC_FTBIT_PATH_RESPONSE
 | 
			
		||||
                    | QUIC_FTBIT_HANDSHAKE_DONE | QUIC_FTBIT_ACK_FREQUENCY
 | 
			
		||||
                    | QUIC_FTBIT_RETIRE_CONNECTION_ID | QUIC_FTBIT_NEW_TOKEN
 | 
			
		||||
                    | QUIC_FTBIT_TIMESTAMP
 | 
			
		||||
                    | QUIC_FTBIT_DATAGRAM
 | 
			
		||||
                    ,
 | 
			
		||||
    },
 | 
			
		||||
    [LSQVER_ID30] = {
 | 
			
		||||
    [LSQVER_ID32] = {
 | 
			
		||||
    [ENC_LEV_CLEAR] = QUIC_FTBIT_CRYPTO | QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
 | 
			
		||||
                    | QUIC_FTBIT_ACK | QUIC_FTBIT_CONNECTION_CLOSE,
 | 
			
		||||
    [ENC_LEV_EARLY] = QUIC_FTBIT_PADDING | QUIC_FTBIT_PING
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -574,7 +574,8 @@ lsquic_gquic_packout_size (const struct lsquic_conn *conn,
 | 
			
		|||
 | 
			
		||||
size_t
 | 
			
		||||
lsquic_gquic_packout_header_size (const struct lsquic_conn *conn,
 | 
			
		||||
                                enum packet_out_flags flags, size_t dcid_len)
 | 
			
		||||
                                enum packet_out_flags flags, size_t dcid_len,
 | 
			
		||||
                                enum header_type unused)
 | 
			
		||||
{
 | 
			
		||||
    return lsquic_gquic_po_header_sz(flags);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -122,8 +122,7 @@ ietf_v1_packout_header_size_long_by_packet (const struct lsquic_conn *lconn,
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
static size_t
 | 
			
		||||
ietf_v1_packout_header_size_short (const struct lsquic_conn *lconn,
 | 
			
		||||
                                enum packet_out_flags flags, size_t dcid_len)
 | 
			
		||||
ietf_v1_packout_header_size_short (enum packet_out_flags flags, size_t dcid_len)
 | 
			
		||||
{
 | 
			
		||||
    enum packno_bits bits;
 | 
			
		||||
    size_t sz;
 | 
			
		||||
| 
						 | 
				
			
			@ -140,19 +139,13 @@ ietf_v1_packout_header_size_short (const struct lsquic_conn *lconn,
 | 
			
		|||
 | 
			
		||||
static size_t
 | 
			
		||||
ietf_v1_packout_max_header_size (const struct lsquic_conn *lconn,
 | 
			
		||||
                                enum packet_out_flags flags, size_t dcid_len)
 | 
			
		||||
    enum packet_out_flags flags, size_t dcid_len, enum header_type header_type)
 | 
			
		||||
{
 | 
			
		||||
    if (lconn->cn_flags & LSCONN_HANDSHAKE_DONE)
 | 
			
		||||
        return ietf_v1_packout_header_size_short(lconn, flags, dcid_len);
 | 
			
		||||
    else if (lconn->cn_flags & LSCONN_SERVER)
 | 
			
		||||
        /* Server does not set the token in its Initial packet header: set
 | 
			
		||||
         * the packet type to something else in order not to overestimate
 | 
			
		||||
         * header size.
 | 
			
		||||
         */
 | 
			
		||||
        return ietf_v1_packout_header_size_long_by_flags(lconn, HETY_HANDSHAKE,
 | 
			
		||||
                                                            flags, dcid_len);
 | 
			
		||||
    if ((lconn->cn_flags & LSCONN_HANDSHAKE_DONE)
 | 
			
		||||
                                                && header_type == HETY_NOT_SET)
 | 
			
		||||
        return ietf_v1_packout_header_size_short(flags, dcid_len);
 | 
			
		||||
    else
 | 
			
		||||
        return ietf_v1_packout_header_size_long_by_flags(lconn, HETY_INITIAL,
 | 
			
		||||
        return ietf_v1_packout_header_size_long_by_flags(lconn, header_type,
 | 
			
		||||
                                                            flags, dcid_len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -309,7 +302,7 @@ ietf_v1_packout_size (const struct lsquic_conn *lconn,
 | 
			
		|||
 | 
			
		||||
    if ((lconn->cn_flags & LSCONN_HANDSHAKE_DONE)
 | 
			
		||||
                                && packet_out->po_header_type == HETY_NOT_SET)
 | 
			
		||||
        sz = ietf_v1_packout_header_size_short(lconn, packet_out->po_flags,
 | 
			
		||||
        sz = ietf_v1_packout_header_size_short(packet_out->po_flags,
 | 
			
		||||
                                            packet_out->po_path->np_dcid.len);
 | 
			
		||||
    else
 | 
			
		||||
        sz = ietf_v1_packout_header_size_long_by_packet(lconn, packet_out);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -165,6 +165,8 @@ lsquic_qdh_init (struct qpack_dec_hdl *qdh, struct lsquic_conn *conn,
 | 
			
		|||
    if (enpub->enp_hsi_if->hsi_flags & LSQUIC_HSI_HASH_NAMEVAL)
 | 
			
		||||
        dec_opts |= LSQPACK_DEC_OPT_HASH_NAMEVAL;
 | 
			
		||||
 | 
			
		||||
    if (conn->cn_flags & LSCONN_SERVER)
 | 
			
		||||
        qdh->qdh_flags |= QDH_SERVER;
 | 
			
		||||
    if (enpub->enp_settings.es_qpack_experiment)
 | 
			
		||||
    {
 | 
			
		||||
        qdh->qdh_exp_rec = lsquic_qpack_exp_new();
 | 
			
		||||
| 
						 | 
				
			
			@ -176,6 +178,8 @@ lsquic_qdh_init (struct qpack_dec_hdl *qdh, struct lsquic_conn *conn,
 | 
			
		|||
            qdh->qdh_exp_rec->qer_used_max_blocked = max_risked_streams;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (!qdh->qdh_exp_rec && LSQ_LOG_ENABLED_EXT(LSQ_LOG_NOTICE, LSQLM_CONN))
 | 
			
		||||
        qdh->qdh_flags |= QDH_SAVE_UA;
 | 
			
		||||
 | 
			
		||||
    qdh->qdh_conn = conn;
 | 
			
		||||
    lsquic_frab_list_init(&qdh->qdh_fral, 0x400, NULL, NULL, NULL);
 | 
			
		||||
| 
						 | 
				
			
			@ -226,6 +230,11 @@ lsquic_qdh_cleanup (struct qpack_dec_hdl *qdh)
 | 
			
		|||
        LSQ_DEBUG("cleanup");
 | 
			
		||||
        if (qdh->qdh_exp_rec)
 | 
			
		||||
            qdh_log_and_clean_exp_rec(qdh);
 | 
			
		||||
        if (qdh->qdh_ua)
 | 
			
		||||
        {
 | 
			
		||||
            free(qdh->qdh_ua);
 | 
			
		||||
            qdh->qdh_ua = NULL;
 | 
			
		||||
        }
 | 
			
		||||
        lsqpack_dec_cleanup(&qdh->qdh_decoder);
 | 
			
		||||
        lsquic_frab_list_cleanup(&qdh->qdh_fral);
 | 
			
		||||
        qdh->qdh_flags &= ~QDH_INITIALIZED;
 | 
			
		||||
| 
						 | 
				
			
			@ -531,17 +540,16 @@ qdh_prepare_decode (void *stream_p, struct lsxpack_header *xhdr, size_t space)
 | 
			
		|||
 | 
			
		||||
static void
 | 
			
		||||
qdh_maybe_set_user_agent (struct qpack_dec_hdl *qdh,
 | 
			
		||||
                                        const struct lsxpack_header *xhdr)
 | 
			
		||||
                                const struct lsxpack_header *xhdr, char **ua)
 | 
			
		||||
{
 | 
			
		||||
    /* Flipped: we are the *decoder* */
 | 
			
		||||
    const char *const name = qdh->qdh_exp_rec->qer_flags & QER_SERVER ?
 | 
			
		||||
    const char *const name = qdh->qdh_flags & QDH_SERVER ?
 | 
			
		||||
                                    "user-agent" : "server";
 | 
			
		||||
    const size_t len = qdh->qdh_exp_rec->qer_flags & QER_SERVER ? 10 : 6;
 | 
			
		||||
    const size_t len = qdh->qdh_flags & QDH_SERVER ? 10 : 6;
 | 
			
		||||
 | 
			
		||||
    if (len == xhdr->name_len
 | 
			
		||||
                && 0 == memcmp(name, lsxpack_header_get_name(xhdr), len))
 | 
			
		||||
        qdh->qdh_exp_rec->qer_user_agent
 | 
			
		||||
                = strndup(lsxpack_header_get_value(xhdr), xhdr->val_len);
 | 
			
		||||
        *ua = strndup(lsxpack_header_get_value(xhdr), xhdr->val_len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -572,7 +580,9 @@ qdh_process_header (void *stream_p, struct lsxpack_header *xhdr)
 | 
			
		|||
                        sizeof(*stream->conn_pub->mm->acki));
 | 
			
		||||
    }
 | 
			
		||||
    else if (qdh->qdh_exp_rec && !qdh->qdh_exp_rec->qer_user_agent)
 | 
			
		||||
        qdh_maybe_set_user_agent(qdh, xhdr);
 | 
			
		||||
        qdh_maybe_set_user_agent(qdh, xhdr, &qdh->qdh_exp_rec->qer_user_agent);
 | 
			
		||||
    else if ((qdh->qdh_flags & QDH_SAVE_UA) && !qdh->qdh_ua)
 | 
			
		||||
        qdh_maybe_set_user_agent(qdh, xhdr, &qdh->qdh_ua);
 | 
			
		||||
 | 
			
		||||
    return qdh->qdh_enpub->enp_hsi_if->hsi_process_header(u->ctx.hset, xhdr);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -844,3 +854,15 @@ lsquic_qdh_arm_if_unsent (struct qpack_dec_hdl *qdh, void (*func)(void *),
 | 
			
		|||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const char *
 | 
			
		||||
lsquic_qdh_get_ua (const struct qpack_dec_hdl *qdh)
 | 
			
		||||
{
 | 
			
		||||
    if (qdh->qdh_ua)
 | 
			
		||||
        return qdh->qdh_ua;
 | 
			
		||||
    else if (qdh->qdh_exp_rec && qdh->qdh_exp_rec->qer_user_agent)
 | 
			
		||||
        return qdh->qdh_exp_rec->qer_user_agent;
 | 
			
		||||
    else
 | 
			
		||||
        return NULL;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,6 +23,8 @@ struct qpack_dec_hdl
 | 
			
		|||
    enum {
 | 
			
		||||
        QDH_INITIALIZED     = 1 << 0,
 | 
			
		||||
        QDH_PUSH_PROMISE    = 1 << 1,
 | 
			
		||||
        QDH_SAVE_UA         = 1 << 2,
 | 
			
		||||
        QDH_SERVER          = 1 << 3,
 | 
			
		||||
    }                        qdh_flags;
 | 
			
		||||
    struct lsqpack_dec       qdh_decoder;
 | 
			
		||||
    struct lsquic_stream    *qdh_enc_sm_in;
 | 
			
		||||
| 
						 | 
				
			
			@ -35,6 +37,7 @@ struct qpack_dec_hdl
 | 
			
		|||
    void                   (*qdh_on_dec_sent_func)(void *);
 | 
			
		||||
    void                    *qdh_on_dec_sent_ctx;
 | 
			
		||||
    struct qpack_exp_record *qdh_exp_rec;
 | 
			
		||||
    char                    *qdh_ua;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
| 
						 | 
				
			
			@ -74,6 +77,9 @@ lsquic_qdh_cancel_stream_id (struct qpack_dec_hdl *, lsquic_stream_id_t);
 | 
			
		|||
int
 | 
			
		||||
lsquic_qdh_arm_if_unsent (struct qpack_dec_hdl *, void (*)(void *), void *);
 | 
			
		||||
 | 
			
		||||
const char *
 | 
			
		||||
lsquic_qdh_get_ua (const struct qpack_dec_hdl *);
 | 
			
		||||
 | 
			
		||||
extern const struct lsquic_stream_if *const lsquic_qdh_enc_sm_in_if;
 | 
			
		||||
extern const struct lsquic_stream_if *const lsquic_qdh_dec_sm_out_if;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2043,12 +2043,18 @@ send_ctl_allocate_packet (struct lsquic_send_ctl *ctl, enum packno_bits bits,
 | 
			
		|||
                            unsigned need_at_least, enum packnum_space pns,
 | 
			
		||||
                            const struct network_path *path)
 | 
			
		||||
{
 | 
			
		||||
    static const enum header_type pns2hety[] =
 | 
			
		||||
    {
 | 
			
		||||
        [PNS_INIT]  = HETY_INITIAL,
 | 
			
		||||
        [PNS_HSK]   = HETY_HANDSHAKE,
 | 
			
		||||
        [PNS_APP]   = HETY_NOT_SET,
 | 
			
		||||
    };
 | 
			
		||||
    lsquic_packet_out_t *packet_out;
 | 
			
		||||
 | 
			
		||||
    packet_out = lsquic_packet_out_new(&ctl->sc_enpub->enp_mm,
 | 
			
		||||
                    ctl->sc_conn_pub->packet_out_malo,
 | 
			
		||||
                    !(ctl->sc_flags & SC_TCID0), ctl->sc_conn_pub->lconn, bits,
 | 
			
		||||
                    ctl->sc_ver_neg->vn_tag, NULL, path);
 | 
			
		||||
                    ctl->sc_ver_neg->vn_tag, NULL, path, pns2hety[pns]);
 | 
			
		||||
    if (!packet_out)
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2483,7 +2483,7 @@ lsquic_stream_flush_threshold (const struct lsquic_stream *stream,
 | 
			
		|||
        flags |= PO_LONGHEAD;
 | 
			
		||||
 | 
			
		||||
    packet_header_sz = lsquic_po_header_length(stream->conn_pub->lconn, flags,
 | 
			
		||||
                                        stream->conn_pub->path->np_dcid.len);
 | 
			
		||||
                            stream->conn_pub->path->np_dcid.len, HETY_NOT_SET);
 | 
			
		||||
    stream_header_sz = stream->sm_frame_header_sz(stream, data_sz);
 | 
			
		||||
    tag_len = stream->conn_pub->lconn->cn_esf_c->esf_tag_len;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,8 +21,7 @@ static const unsigned char version_tags[N_LSQVER][4] =
 | 
			
		|||
    [LSQVER_ID27] = { 0xFF, 0, 0, 27, },
 | 
			
		||||
    [LSQVER_ID28] = { 0xFF, 0, 0, 28, },
 | 
			
		||||
    [LSQVER_ID29] = { 0xFF, 0, 0, 29, },
 | 
			
		||||
    [LSQVER_ID30] = { 0xFF, 0, 0, 30, },
 | 
			
		||||
    [LSQVER_ID31] = { 0xFF, 0, 0, 31, },
 | 
			
		||||
    [LSQVER_ID32] = { 0xFF, 0, 0, 32, },
 | 
			
		||||
    [LSQVER_VERNEG] = { 0xFA, 0xFA, 0xFA, 0xFA, },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -62,8 +61,7 @@ const char *const lsquic_ver2str[N_LSQVER] = {
 | 
			
		|||
    [LSQVER_ID27] = "FF00001B",
 | 
			
		||||
    [LSQVER_ID28] = "FF00001C",
 | 
			
		||||
    [LSQVER_ID29] = "FF00001D",
 | 
			
		||||
    [LSQVER_ID30] = "FF00001E",
 | 
			
		||||
    [LSQVER_ID31] = "FF00001F",
 | 
			
		||||
    [LSQVER_ID32] = "FF000020",
 | 
			
		||||
    [LSQVER_VERNEG] = "FAFAFAFA",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -214,7 +214,7 @@ new_packet (struct test_ctx *ctx)
 | 
			
		|||
                                     */
 | 
			
		||||
 | 
			
		||||
    packet_out = lsquic_packet_out_new(&ctx->enpub.enp_mm, ctx->enpub.enp_mm.malo.packet_out, 1,
 | 
			
		||||
                         &ctx->lconn, PACKNO_BITS_0, 0, NULL, &ctx->path);
 | 
			
		||||
                         &ctx->lconn, PACKNO_BITS_0, 0, NULL, &ctx->path, HETY_NOT_SET);
 | 
			
		||||
    if (packet_out)
 | 
			
		||||
        packet_out->po_packno = packno++;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue