mirror of
				https://gitea.invidious.io/iv-org/litespeed-quic.git
				synced 2024-08-15 00:53:43 +00:00 
			
		
		
		
	Fix Windows support
This commit is contained in:
		
							parent
							
								
									41d574f34c
								
							
						
					
					
						commit
						fb3e20e0bc
					
				
					 72 changed files with 912 additions and 475 deletions
				
			
		| 
						 | 
				
			
			@ -85,7 +85,22 @@ ENDIF()
 | 
			
		|||
 | 
			
		||||
#MSVC
 | 
			
		||||
ELSE()
 | 
			
		||||
SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4100")	# unreferenced formal parameter
 | 
			
		||||
SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4115")	# unnamed type definition in parentheses
 | 
			
		||||
SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4116")	# named type definition in parentheses
 | 
			
		||||
SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4146")	# unary minus operator applied to unsigned type, result still unsigned
 | 
			
		||||
SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4132")	# const initialization
 | 
			
		||||
SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4200")	# zero-sized array
 | 
			
		||||
SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4204")	# non-constant aggregate initializer
 | 
			
		||||
SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4244")	# integer conversion
 | 
			
		||||
SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4245")	# conversion from 'int' to 'unsigned int', signed/unsigned mismatch
 | 
			
		||||
SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4267")	# integer conversion
 | 
			
		||||
SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4214")	# nonstandard extension used: bit field types other than int
 | 
			
		||||
SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4295")	# array is too small to include a terminating null character
 | 
			
		||||
SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4334")	# result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)
 | 
			
		||||
SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4456")	# hide previous local declaration
 | 
			
		||||
SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4459")	# hide global declaration
 | 
			
		||||
SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4706")	# assignment within conditional expression
 | 
			
		||||
SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -W4 -WX -Zi -DWIN32_LEAN_AND_MEAN -DNOMINMAX -D_CRT_SECURE_NO_WARNINGS -I${CMAKE_CURRENT_SOURCE_DIR}/wincompat")
 | 
			
		||||
IF(CMAKE_BUILD_TYPE STREQUAL "Debug")
 | 
			
		||||
    SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -Od")
 | 
			
		||||
| 
						 | 
				
			
			@ -103,6 +118,11 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}  ${MY_CMAKE_FLAGS} $ENV{EXTRA_CFLAGS}")
 | 
			
		|||
 | 
			
		||||
MESSAGE(STATUS "Compiler flags: ${CMAKE_C_FLAGS}")
 | 
			
		||||
 | 
			
		||||
find_package(Perl)
 | 
			
		||||
IF(NOT PERL_FOUND)
 | 
			
		||||
    MESSAGE(FATAL_ERROR "Perl not found -- need it to generate source code")
 | 
			
		||||
ENDIF()
 | 
			
		||||
 | 
			
		||||
IF (NOT DEFINED BORINGSSL_INCLUDE AND DEFINED BORINGSSL_DIR)
 | 
			
		||||
    FIND_PATH(BORINGSSL_INCLUDE NAMES openssl/ssl.h
 | 
			
		||||
                PATHS ${BORINGSSL_DIR}/include
 | 
			
		||||
| 
						 | 
				
			
			@ -124,7 +144,7 @@ IF (NOT DEFINED BORINGSSL_LIB AND DEFINED BORINGSSL_DIR)
 | 
			
		|||
            FIND_LIBRARY(BORINGSSL_LIB_${LIB_NAME}
 | 
			
		||||
                NAMES ${LIB_NAME}
 | 
			
		||||
                PATHS ${BORINGSSL_DIR}/${LIB_NAME}
 | 
			
		||||
                PATH_SUFFIXES Debug Release MinSizeRel RelWithDebInfo
 | 
			
		||||
		PATH_SUFFIXES Debug Release MinSizeRel RelWithDebInfo
 | 
			
		||||
                NO_DEFAULT_PATH)
 | 
			
		||||
        ELSE()
 | 
			
		||||
            FIND_LIBRARY(BORINGSSL_LIB_${LIB_NAME}
 | 
			
		||||
| 
						 | 
				
			
			@ -195,7 +215,7 @@ ELSE()
 | 
			
		|||
    MESSAGE(STATUS "zlib not found")
 | 
			
		||||
ENDIF()
 | 
			
		||||
 | 
			
		||||
IF (LSQUIC_BIN)
 | 
			
		||||
IF (LSQUIC_BIN OR LSQUIC_TESTS)
 | 
			
		||||
FIND_PATH(EVENT_INCLUDE_DIR NAMES event2/event.h)
 | 
			
		||||
IF (EVENT_INCLUDE_DIR)
 | 
			
		||||
    INCLUDE_DIRECTORIES(${EVENT_INCLUDE_DIR})
 | 
			
		||||
| 
						 | 
				
			
			@ -215,15 +235,38 @@ IF(EVENT_LIB)
 | 
			
		|||
ELSE()
 | 
			
		||||
    MESSAGE(STATUS "libevent not found")
 | 
			
		||||
ENDIF()
 | 
			
		||||
 | 
			
		||||
add_executable(http_server bin/http_server.c bin/prog.c bin/test_common.c bin/test_cert.c)
 | 
			
		||||
add_executable(md5_server bin/md5_server.c bin/prog.c bin/test_common.c bin/test_cert.c)
 | 
			
		||||
add_executable(md5_client bin/md5_client.c bin/prog.c bin/test_common.c bin/test_cert.c)
 | 
			
		||||
add_executable(echo_server bin/echo_server.c bin/prog.c bin/test_common.c bin/test_cert.c)
 | 
			
		||||
add_executable(echo_client bin/echo_client.c bin/prog.c bin/test_common.c bin/test_cert.c)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
SET(LIBS lsquic ${EVENT_LIB} ${BORINGSSL_LIB_ssl} ${BORINGSSL_LIB_crypto} ${ZLIB_LIB} ${LIBS})
 | 
			
		||||
IF(MSVC)
 | 
			
		||||
FIND_LIBRARY(PCRE_LIB pcre)
 | 
			
		||||
IF(PCRE_LIB)
 | 
			
		||||
    MESSAGE(STATUS "Found pcre: ${PCRE_LIB}")
 | 
			
		||||
    LIST(APPEND LIBS ${PCRE_LIB})
 | 
			
		||||
ELSE()
 | 
			
		||||
    MESSAGE(STATUS "pcre not found: http_server won't work")
 | 
			
		||||
ENDIF()
 | 
			
		||||
FIND_LIBRARY(PCREPOSIX_LIB pcreposix)
 | 
			
		||||
IF(PCREPOSIX_LIB)
 | 
			
		||||
    MESSAGE(STATUS "Found pcreposix: ${PCREPOSIX_LIB}")
 | 
			
		||||
    LIST(APPEND LIBS ${PCREPOSIX_LIB})
 | 
			
		||||
ELSE()
 | 
			
		||||
    MESSAGE(STATUS "pcreposix not found: http_server won't work")
 | 
			
		||||
ENDIF()
 | 
			
		||||
LIST(APPEND LIBS ws2_32)
 | 
			
		||||
ENDIF()
 | 
			
		||||
ENDIF()	# LSQUIC_BIN OR LSQUIC_TESTS
 | 
			
		||||
 | 
			
		||||
IF(LSQUIC_BIN)
 | 
			
		||||
IF(MSVC)
 | 
			
		||||
    SET(GETOPT_C wincompat/getopt.c)
 | 
			
		||||
ENDIF()
 | 
			
		||||
add_executable(http_server bin/http_server.c bin/prog.c bin/test_common.c bin/test_cert.c ${GETOPT_C})
 | 
			
		||||
IF(NOT MSVC)   #   TODO: port MD5 server and client to Windows
 | 
			
		||||
add_executable(md5_server bin/md5_server.c bin/prog.c bin/test_common.c bin/test_cert.c ${GETOPT_C})
 | 
			
		||||
add_executable(md5_client bin/md5_client.c bin/prog.c bin/test_common.c bin/test_cert.c ${GETOPT_C})
 | 
			
		||||
ENDIF()
 | 
			
		||||
add_executable(echo_server bin/echo_server.c bin/prog.c bin/test_common.c bin/test_cert.c ${GETOPT_C})
 | 
			
		||||
add_executable(echo_client bin/echo_client.c bin/prog.c bin/test_common.c bin/test_cert.c ${GETOPT_C})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
IF (NOT MSVC)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -242,6 +285,7 @@ add_executable(http_client
 | 
			
		|||
    bin/http_client.c
 | 
			
		||||
    bin/prog.c
 | 
			
		||||
    bin/test_common.c
 | 
			
		||||
    bin/test_cert.c
 | 
			
		||||
    wincompat/getopt.c
 | 
			
		||||
    wincompat/getopt1.c
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -251,8 +295,10 @@ ENDIF()
 | 
			
		|||
 | 
			
		||||
TARGET_LINK_LIBRARIES(http_client ${LIBS})
 | 
			
		||||
TARGET_LINK_LIBRARIES(http_server ${LIBS})
 | 
			
		||||
IF(NOT MSVC)
 | 
			
		||||
TARGET_LINK_LIBRARIES(md5_server  ${LIBS})
 | 
			
		||||
TARGET_LINK_LIBRARIES(md5_client  ${LIBS})
 | 
			
		||||
ENDIF()
 | 
			
		||||
TARGET_LINK_LIBRARIES(echo_server ${LIBS})
 | 
			
		||||
TARGET_LINK_LIBRARIES(echo_client ${LIBS})
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -137,7 +137,7 @@ The library has been tested on the following platforms:
 | 
			
		|||
  - x86_64
 | 
			
		||||
- Android
 | 
			
		||||
  - ARM
 | 
			
		||||
- Windows (this needs updating for the server part, now broken)
 | 
			
		||||
- Windows
 | 
			
		||||
  - x86_64
 | 
			
		||||
 | 
			
		||||
Have fun,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										63
									
								
								appveyor.yml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								appveyor.yml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,63 @@
 | 
			
		|||
version: 1.{branch}.{build}
 | 
			
		||||
 | 
			
		||||
image: Visual Studio 2017
 | 
			
		||||
 | 
			
		||||
cache: c:\tools\vcpkg\installed
 | 
			
		||||
 | 
			
		||||
init:
 | 
			
		||||
 | 
			
		||||
- cmd: ''
 | 
			
		||||
 | 
			
		||||
install:
 | 
			
		||||
 | 
			
		||||
- cmd: >-
 | 
			
		||||
 | 
			
		||||
    vcpkg install zlib:x64-windows-static
 | 
			
		||||
 | 
			
		||||
    vcpkg install libevent:x64-windows-static
 | 
			
		||||
 | 
			
		||||
    vcpkg install pcre:x64-windows-static
 | 
			
		||||
 | 
			
		||||
    vcpkg integrate install
 | 
			
		||||
 | 
			
		||||
build_script:
 | 
			
		||||
 | 
			
		||||
- cmd: >-
 | 
			
		||||
 | 
			
		||||
    vcpkg list
 | 
			
		||||
 | 
			
		||||
    git clone https://boringssl.googlesource.com/boringssl
 | 
			
		||||
 | 
			
		||||
    cd boringssl
 | 
			
		||||
 | 
			
		||||
    git checkout bfe527fa35735e8e045cbfb42b012e13ca68f9cf
 | 
			
		||||
 | 
			
		||||
    cmake -DCMAKE_GENERATOR_PLATFORM=x64 --config Debug -DBUILD_SHARED_LIBS=OFF -DOPENSSL_NO_ASM=1 .
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    msbuild /m ALL_BUILD.vcxproj
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    cd ..
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    git submodule init
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    git submodule update
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    cmake -DCMAKE_GENERATOR_PLATFORM=x64 -DBUILD_SHARED_LIBS=OFF -DVCPKG_TARGET_TRIPLET=x64-windows-static -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake -DBORINGSSL_DIR=%cd%\boringssl .
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    msbuild /m ALL_BUILD.vcxproj
 | 
			
		||||
 | 
			
		||||
test_script:
 | 
			
		||||
 | 
			
		||||
- cmd: msbuild /m RUN_TESTS.vcxproj
 | 
			
		||||
| 
						 | 
				
			
			@ -21,6 +21,16 @@ CHECK_SYMBOL_EXISTS(
 | 
			
		|||
 | 
			
		||||
INCLUDE(CheckIncludeFiles)
 | 
			
		||||
 | 
			
		||||
IF (MSVC AND PCRE_LIB)
 | 
			
		||||
FIND_PATH(EVENT_INCLUDE_DIR NAMES pcreposix.h)
 | 
			
		||||
IF (EVENT_INCLUDE_DIR)
 | 
			
		||||
    MESSAGE(STATUS "found pcreposix.h")
 | 
			
		||||
    SET(HAVE_REGEX 1)
 | 
			
		||||
ELSE()
 | 
			
		||||
    MESSAGE(FATAL_ERROR "event2/event.h was not found")
 | 
			
		||||
ENDIF()
 | 
			
		||||
ELSE()
 | 
			
		||||
CHECK_INCLUDE_FILES(regex.h HAVE_REGEX)
 | 
			
		||||
ENDIF()
 | 
			
		||||
 | 
			
		||||
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/test_config.h.in ${CMAKE_CURRENT_SOURCE_DIR}/test_config.h)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,11 +9,21 @@
 | 
			
		|||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/queue.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#define Read read
 | 
			
		||||
#else
 | 
			
		||||
#include "vc_compat.h"
 | 
			
		||||
#include "getopt.h"
 | 
			
		||||
#include <io.h>
 | 
			
		||||
#define Read _read
 | 
			
		||||
#define STDIN_FILENO 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <event2/event.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -69,12 +79,12 @@ struct lsquic_stream_ctx {
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
read_stdin (int fd, short what, void *ctx)
 | 
			
		||||
read_stdin (evutil_socket_t fd, short what, void *ctx)
 | 
			
		||||
{
 | 
			
		||||
    ssize_t nr;
 | 
			
		||||
    lsquic_stream_ctx_t *st_h = ctx;
 | 
			
		||||
 | 
			
		||||
    nr = read(fd, st_h->buf + st_h->buf_off++, 1);
 | 
			
		||||
    nr = Read(fd, st_h->buf + st_h->buf_off++, 1);
 | 
			
		||||
    LSQ_DEBUG("read %zd bytes from stdin", nr);
 | 
			
		||||
    if (0 == nr)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -217,6 +227,7 @@ main (int argc, char **argv)
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
    int flags = fcntl(STDIN_FILENO, F_GETFL);
 | 
			
		||||
    flags |= O_NONBLOCK;
 | 
			
		||||
    if (0 != fcntl(STDIN_FILENO, F_SETFL, flags))
 | 
			
		||||
| 
						 | 
				
			
			@ -224,6 +235,12 @@ main (int argc, char **argv)
 | 
			
		|||
        perror("fcntl");
 | 
			
		||||
        exit(1);
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    {
 | 
			
		||||
        u_long on = 1;
 | 
			
		||||
        ioctlsocket(STDIN_FILENO, FIONBIO, &on);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (0 != prog_prep(&prog))
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,14 +4,19 @@
 | 
			
		|||
 */
 | 
			
		||||
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/queue.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#else
 | 
			
		||||
#include "vc_compat.h"
 | 
			
		||||
#include "getopt.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "lsquic.h"
 | 
			
		||||
#include "test_common.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -531,18 +531,20 @@ static void
 | 
			
		|||
send_headers (lsquic_stream_ctx_t *st_h)
 | 
			
		||||
{
 | 
			
		||||
    const char *hostname = st_h->client_ctx->hostname;
 | 
			
		||||
    struct header_buf hbuf;
 | 
			
		||||
    if (!hostname)
 | 
			
		||||
        hostname = st_h->client_ctx->prog->prog_hostname;
 | 
			
		||||
    hbuf.off = 0;
 | 
			
		||||
    struct lsxpack_header headers_arr[7];
 | 
			
		||||
#define V(v) (v), strlen(v)
 | 
			
		||||
    lsxpack_header_set_ptr(&headers_arr[0], V(":method"), V(st_h->client_ctx->method));
 | 
			
		||||
    lsxpack_header_set_ptr(&headers_arr[1], V(":scheme"), V("https"));
 | 
			
		||||
    lsxpack_header_set_ptr(&headers_arr[2], V(":path"), V(st_h->path));
 | 
			
		||||
    lsxpack_header_set_ptr(&headers_arr[3], V(":authority"), V(hostname));
 | 
			
		||||
    lsxpack_header_set_ptr(&headers_arr[4], V("user-agent"), V(st_h->client_ctx->prog->prog_settings.es_ua));
 | 
			
		||||
    header_set_ptr(&headers_arr[0], &hbuf, V(":method"), V(st_h->client_ctx->method));
 | 
			
		||||
    header_set_ptr(&headers_arr[1], &hbuf, V(":scheme"), V("https"));
 | 
			
		||||
    header_set_ptr(&headers_arr[2], &hbuf, V(":path"), V(st_h->path));
 | 
			
		||||
    header_set_ptr(&headers_arr[3], &hbuf, V(":authority"), V(hostname));
 | 
			
		||||
    header_set_ptr(&headers_arr[4], &hbuf, V("user-agent"), V(st_h->client_ctx->prog->prog_settings.es_ua));
 | 
			
		||||
    /* The following headers only gets sent if there is request payload: */
 | 
			
		||||
    lsxpack_header_set_ptr(&headers_arr[5], V("content-type"), V("application/octet-stream"));
 | 
			
		||||
    lsxpack_header_set_ptr(&headers_arr[6], V("content-length"), V( st_h->client_ctx->payload_size));
 | 
			
		||||
    header_set_ptr(&headers_arr[5], &hbuf, V("content-type"), V("application/octet-stream"));
 | 
			
		||||
    header_set_ptr(&headers_arr[6], &hbuf, V("content-length"), V( st_h->client_ctx->payload_size));
 | 
			
		||||
    lsquic_http_headers_t headers = {
 | 
			
		||||
        .count = sizeof(headers_arr) / sizeof(headers_arr[0]),
 | 
			
		||||
        .headers = headers_arr,
 | 
			
		||||
| 
						 | 
				
			
			@ -1072,11 +1074,11 @@ hset_dump (const struct hset *hset, FILE *out)
 | 
			
		|||
    const struct hset_elem *el;
 | 
			
		||||
 | 
			
		||||
    STAILQ_FOREACH(el, hset, next)
 | 
			
		||||
        if (el->xhdr.flags & (LSXPACK_HPACK_IDX|LSXPACK_QPACK_IDX))
 | 
			
		||||
        if (el->xhdr.flags & (LSXPACK_HPACK_VAL_MATCHED|LSXPACK_QPACK_IDX))
 | 
			
		||||
            fprintf(out, "%.*s (%s static table idx %u): %.*s\n",
 | 
			
		||||
                (int) el->xhdr.name_len, lsxpack_header_get_name(&el->xhdr),
 | 
			
		||||
                el->xhdr.flags & LSXPACK_HPACK_IDX ? "hpack" : "qpack",
 | 
			
		||||
                el->xhdr.flags & LSXPACK_HPACK_IDX ? el->xhdr.hpack_index
 | 
			
		||||
                el->xhdr.flags & LSXPACK_HPACK_VAL_MATCHED ? "hpack" : "qpack",
 | 
			
		||||
                el->xhdr.flags & LSXPACK_HPACK_VAL_MATCHED ? el->xhdr.hpack_index
 | 
			
		||||
                                                    : el->xhdr.qpack_index,
 | 
			
		||||
                (int) el->xhdr.val_len, lsxpack_header_get_value(&el->xhdr));
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -1157,7 +1159,6 @@ qif_client_on_new_stream (void *stream_if_ctx, lsquic_stream_t *stream)
 | 
			
		|||
    struct lsxpack_header *header;
 | 
			
		||||
    static int reqno;
 | 
			
		||||
    size_t nalloc;
 | 
			
		||||
    int i;
 | 
			
		||||
    char *end, *tab, *line;
 | 
			
		||||
    char line_buf[0x1000];
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1215,20 +1216,11 @@ qif_client_on_new_stream (void *stream_if_ctx, lsquic_stream_t *stream)
 | 
			
		|||
            exit(1);
 | 
			
		||||
        }
 | 
			
		||||
        header = &ctx->headers.headers[ctx->headers.count++];
 | 
			
		||||
        lsxpack_header_set_ptr(header, (void *) ctx->qif_sz, tab - line,
 | 
			
		||||
                    (void *) (ctx->qif_sz + (tab - line + 1)), end - tab - 1);
 | 
			
		||||
 | 
			
		||||
        lsxpack_header_set_offset2(header, ctx->qif_str + ctx->qif_sz, 0,
 | 
			
		||||
                                    tab - line, tab - line + 1, end - tab - 1);
 | 
			
		||||
        ctx->qif_sz += end + 1 - line;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < ctx->headers.count; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        ctx->headers.headers[i].buf = ctx->qif_str
 | 
			
		||||
                + (uintptr_t) ctx->headers.headers[i].buf;
 | 
			
		||||
        ctx->headers.headers[i].name_ptr = ctx->qif_str
 | 
			
		||||
                + (uintptr_t) ctx->headers.headers[i].name_ptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    lsquic_stream_wantwrite(stream, 1);
 | 
			
		||||
 | 
			
		||||
    if (!line)
 | 
			
		||||
| 
						 | 
				
			
			@ -1426,10 +1418,6 @@ main (int argc, char **argv)
 | 
			
		|||
    client_ctx.hcc_reset_after_nbytes = 0;
 | 
			
		||||
    client_ctx.hcc_retire_cid_after_nbytes = 0;
 | 
			
		||||
    client_ctx.prog = &prog;
 | 
			
		||||
#ifdef WIN32
 | 
			
		||||
    WSADATA wsd;
 | 
			
		||||
    WSAStartup(MAKEWORD(2, 2), &wsd);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    prog_init(&prog, LSENG_HTTP, &sports, &http_client_if, &client_ctx);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,15 +10,20 @@
 | 
			
		|||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/queue.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <regex.h>
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#else
 | 
			
		||||
#include "vc_compat.h"
 | 
			
		||||
#include "getopt.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <event2/event.h>
 | 
			
		||||
 | 
			
		||||
#include <openssl/md5.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -29,12 +34,243 @@
 | 
			
		|||
#include "test_common.h"
 | 
			
		||||
#include "prog.h"
 | 
			
		||||
 | 
			
		||||
#if HAVE_REGEX
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
#include <regex.h>
 | 
			
		||||
#else
 | 
			
		||||
#include <pcreposix.h>
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "../src/liblsquic/lsquic_logger.h"
 | 
			
		||||
#include "../src/liblsquic/lsquic_int_types.h"
 | 
			
		||||
#include "../src/liblsquic/lsquic_util.h"
 | 
			
		||||
 | 
			
		||||
static const char on_being_idle[];
 | 
			
		||||
static const size_t IDLE_SIZE;
 | 
			
		||||
#if HAVE_REGEX
 | 
			
		||||
static const char on_being_idle[] =
 | 
			
		||||
"ON BEING IDLE.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"Now, this is a subject on which I flatter myself I really am _au fait_.\n"
 | 
			
		||||
"The gentleman who, when I was young, bathed me at wisdom's font for nine\n"
 | 
			
		||||
"guineas a term--no extras--used to say he never knew a boy who could\n"
 | 
			
		||||
"do less work in more time; and I remember my poor grandmother once\n"
 | 
			
		||||
"incidentally observing, in the course of an instruction upon the use\n"
 | 
			
		||||
"of the Prayer-book, that it was highly improbable that I should ever do\n"
 | 
			
		||||
"much that I ought not to do, but that she felt convinced beyond a doubt\n"
 | 
			
		||||
"that I should leave undone pretty well everything that I ought to do.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"I am afraid I have somewhat belied half the dear old lady's prophecy.\n"
 | 
			
		||||
"Heaven help me! I have done a good many things that I ought not to have\n"
 | 
			
		||||
"done, in spite of my laziness. But I have fully confirmed the accuracy\n"
 | 
			
		||||
"of her judgment so far as neglecting much that I ought not to have\n"
 | 
			
		||||
"neglected is concerned. Idling always has been my strong point. I take\n"
 | 
			
		||||
"no credit to myself in the matter--it is a gift. Few possess it. There\n"
 | 
			
		||||
"are plenty of lazy people and plenty of slow-coaches, but a genuine\n"
 | 
			
		||||
"idler is a rarity. He is not a man who slouches about with his hands in\n"
 | 
			
		||||
"his pockets. On the contrary, his most startling characteristic is that\n"
 | 
			
		||||
"he is always intensely busy.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"It is impossible to enjoy idling thoroughly unless one has plenty of\n"
 | 
			
		||||
"work to do. There is no fun in doing nothing when you have nothing to\n"
 | 
			
		||||
"do. Wasting time is merely an occupation then, and a most exhausting\n"
 | 
			
		||||
"one. Idleness, like kisses, to be sweet must be stolen.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"Many years ago, when I was a young man, I was taken very ill--I never\n"
 | 
			
		||||
"could see myself that much was the matter with me, except that I had\n"
 | 
			
		||||
"a beastly cold. But I suppose it was something very serious, for the\n"
 | 
			
		||||
"doctor said that I ought to have come to him a month before, and that\n"
 | 
			
		||||
"if it (whatever it was) had gone on for another week he would not have\n"
 | 
			
		||||
"answered for the consequences. It is an extraordinary thing, but I\n"
 | 
			
		||||
"never knew a doctor called into any case yet but what it transpired\n"
 | 
			
		||||
"that another day's delay would have rendered cure hopeless. Our medical\n"
 | 
			
		||||
"guide, philosopher, and friend is like the hero in a melodrama--he\n"
 | 
			
		||||
"always comes upon the scene just, and only just, in the nick of time. It\n"
 | 
			
		||||
"is Providence, that is what it is.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"Well, as I was saying, I was very ill and was ordered to Buxton for a\n"
 | 
			
		||||
"month, with strict injunctions to do nothing whatever all the while\n"
 | 
			
		||||
"that I was there. \"Rest is what you require,\" said the doctor, \"perfect\n"
 | 
			
		||||
"rest.\"\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"It seemed a delightful prospect. \"This man evidently understands my\n"
 | 
			
		||||
"complaint,\" said I, and I pictured to myself a glorious time--a four\n"
 | 
			
		||||
"weeks' _dolce far niente_ with a dash of illness in it. Not too much\n"
 | 
			
		||||
"illness, but just illness enough--just sufficient to give it the flavor\n"
 | 
			
		||||
"of suffering and make it poetical. I should get up late, sip chocolate,\n"
 | 
			
		||||
"and have my breakfast in slippers and a dressing-gown. I should lie out\n"
 | 
			
		||||
"in the garden in a hammock and read sentimental novels with a melancholy\n"
 | 
			
		||||
"ending, until the books should fall from my listless hand, and I should\n"
 | 
			
		||||
"recline there, dreamily gazing into the deep blue of the firmament,\n"
 | 
			
		||||
"watching the fleecy clouds floating like white-sailed ships across\n"
 | 
			
		||||
"its depths, and listening to the joyous song of the birds and the low\n"
 | 
			
		||||
"rustling of the trees. Or, on becoming too weak to go out of doors,\n"
 | 
			
		||||
"I should sit propped up with pillows at the open window of the\n"
 | 
			
		||||
"ground-floor front, and look wasted and interesting, so that all the\n"
 | 
			
		||||
"pretty girls would sigh as they passed by.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"And twice a day I should go down in a Bath chair to the Colonnade to\n"
 | 
			
		||||
"drink the waters. Oh, those waters! I knew nothing about them then,\n"
 | 
			
		||||
"and was rather taken with the idea. \"Drinking the waters\" sounded\n"
 | 
			
		||||
"fashionable and Queen Anne-fied, and I thought I should like them. But,\n"
 | 
			
		||||
"ugh! after the first three or four mornings! Sam Weller's description of\n"
 | 
			
		||||
"them as \"having a taste of warm flat-irons\" conveys only a faint idea of\n"
 | 
			
		||||
"their hideous nauseousness. If anything could make a sick man get well\n"
 | 
			
		||||
"quickly, it would be the knowledge that he must drink a glassful of them\n"
 | 
			
		||||
"every day until he was recovered. I drank them neat for six consecutive\n"
 | 
			
		||||
"days, and they nearly killed me; but after then I adopted the plan of\n"
 | 
			
		||||
"taking a stiff glass of brandy-and-water immediately on the top of them,\n"
 | 
			
		||||
"and found much relief thereby. I have been informed since, by various\n"
 | 
			
		||||
"eminent medical gentlemen, that the alcohol must have entirely\n"
 | 
			
		||||
"counteracted the effects of the chalybeate properties contained in the\n"
 | 
			
		||||
"water. I am glad I was lucky enough to hit upon the right thing.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"But \"drinking the waters\" was only a small portion of the torture I\n"
 | 
			
		||||
"experienced during that memorable month--a month which was, without\n"
 | 
			
		||||
"exception, the most miserable I have ever spent. During the best part of\n"
 | 
			
		||||
"it I religiously followed the doctor's mandate and did nothing whatever,\n"
 | 
			
		||||
"except moon about the house and garden and go out for two hours a day in\n"
 | 
			
		||||
"a Bath chair. That did break the monotony to a certain extent. There is\n"
 | 
			
		||||
"more excitement about Bath-chairing--especially if you are not used to\n"
 | 
			
		||||
"the exhilarating exercise--than might appear to the casual observer. A\n"
 | 
			
		||||
"sense of danger, such as a mere outsider might not understand, is ever\n"
 | 
			
		||||
"present to the mind of the occupant. He feels convinced every minute\n"
 | 
			
		||||
"that the whole concern is going over, a conviction which becomes\n"
 | 
			
		||||
"especially lively whenever a ditch or a stretch of newly macadamized\n"
 | 
			
		||||
"road comes in sight. Every vehicle that passes he expects is going to\n"
 | 
			
		||||
"run into him; and he never finds himself ascending or descending a\n"
 | 
			
		||||
"hill without immediately beginning to speculate upon his chances,\n"
 | 
			
		||||
"supposing--as seems extremely probable--that the weak-kneed controller\n"
 | 
			
		||||
"of his destiny should let go.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"But even this diversion failed to enliven after awhile, and the _ennui_\n"
 | 
			
		||||
"became perfectly unbearable. I felt my mind giving way under it. It is\n"
 | 
			
		||||
"not a strong mind, and I thought it would be unwise to tax it too far.\n"
 | 
			
		||||
"So somewhere about the twentieth morning I got up early, had a good\n"
 | 
			
		||||
"breakfast, and walked straight off to Hayfield, at the foot of the\n"
 | 
			
		||||
"Kinder Scout--a pleasant, busy little town, reached through a lovely\n"
 | 
			
		||||
"valley, and with two sweetly pretty women in it. At least they were\n"
 | 
			
		||||
"sweetly pretty then; one passed me on the bridge and, I think, smiled;\n"
 | 
			
		||||
"and the other was standing at an open door, making an unremunerative\n"
 | 
			
		||||
"investment of kisses upon a red-faced baby. But it is years ago, and I\n"
 | 
			
		||||
"dare say they have both grown stout and snappish since that time.\n"
 | 
			
		||||
"Coming back, I saw an old man breaking stones, and it roused such strong\n"
 | 
			
		||||
"longing in me to use my arms that I offered him a drink to let me take\n"
 | 
			
		||||
"his place. He was a kindly old man and he humored me. I went for those\n"
 | 
			
		||||
"stones with the accumulated energy of three weeks, and did more work in\n"
 | 
			
		||||
"half an hour than he had done all day. But it did not make him jealous.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"Having taken the plunge, I went further and further into dissipation,\n"
 | 
			
		||||
"going out for a long walk every morning and listening to the band in\n"
 | 
			
		||||
"the pavilion every evening. But the days still passed slowly\n"
 | 
			
		||||
"notwithstanding, and I was heartily glad when the last one came and I\n"
 | 
			
		||||
"was being whirled away from gouty, consumptive Buxton to London with its\n"
 | 
			
		||||
"stern work and life. I looked out of the carriage as we rushed through\n"
 | 
			
		||||
"Hendon in the evening. The lurid glare overhanging the mighty city\n"
 | 
			
		||||
"seemed to warm my heart, and when, later on, my cab rattled out of St.\n"
 | 
			
		||||
"Pancras' station, the old familiar roar that came swelling up around me\n"
 | 
			
		||||
"sounded the sweetest music I had heard for many a long day.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"I certainly did not enjoy that month's idling. I like idling when I\n"
 | 
			
		||||
"ought not to be idling; not when it is the only thing I have to do. That\n"
 | 
			
		||||
"is my pig-headed nature. The time when I like best to stand with my\n"
 | 
			
		||||
"back to the fire, calculating how much I owe, is when my desk is heaped\n"
 | 
			
		||||
"highest with letters that must be answered by the next post. When I like\n"
 | 
			
		||||
"to dawdle longest over my dinner is when I have a heavy evening's work\n"
 | 
			
		||||
"before me. And if, for some urgent reason, I ought to be up particularly\n"
 | 
			
		||||
"early in the morning, it is then, more than at any other time, that I\n"
 | 
			
		||||
"love to lie an extra half-hour in bed.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"Ah! how delicious it is to turn over and go to sleep again: \"just for\n"
 | 
			
		||||
"five minutes.\" Is there any human being, I wonder, besides the hero of\n"
 | 
			
		||||
"a Sunday-school \"tale for boys,\" who ever gets up willingly? There\n"
 | 
			
		||||
"are some men to whom getting up at the proper time is an utter\n"
 | 
			
		||||
"impossibility. If eight o'clock happens to be the time that they should\n"
 | 
			
		||||
"turn out, then they lie till half-past. If circumstances change and\n"
 | 
			
		||||
"half-past eight becomes early enough for them, then it is nine before\n"
 | 
			
		||||
"they can rise. They are like the statesman of whom it was said that he\n"
 | 
			
		||||
"was always punctually half an hour late. They try all manner of schemes.\n"
 | 
			
		||||
"They buy alarm-clocks (artful contrivances that go off at the wrong time\n"
 | 
			
		||||
"and alarm the wrong people). They tell Sarah Jane to knock at the door\n"
 | 
			
		||||
"and call them, and Sarah Jane does knock at the door and does call them,\n"
 | 
			
		||||
"and they grunt back \"awri\" and then go comfortably to sleep again. I\n"
 | 
			
		||||
"knew one man who would actually get out and have a cold bath; and even\n"
 | 
			
		||||
"that was of no use, for afterward he would jump into bed again to warm\n"
 | 
			
		||||
"himself.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"I think myself that I could keep out of bed all right if I once got\n"
 | 
			
		||||
"out. It is the wrenching away of the head from the pillow that I find so\n"
 | 
			
		||||
"hard, and no amount of over-night determination makes it easier. I say\n"
 | 
			
		||||
"to myself, after having wasted the whole evening, \"Well, I won't do\n"
 | 
			
		||||
"any more work to-night; I'll get up early to-morrow morning;\" and I am\n"
 | 
			
		||||
"thoroughly resolved to do so--then. In the morning, however, I feel less\n"
 | 
			
		||||
"enthusiastic about the idea, and reflect that it would have been much\n"
 | 
			
		||||
"better if I had stopped up last night. And then there is the trouble of\n"
 | 
			
		||||
"dressing, and the more one thinks about that the more one wants to put\n"
 | 
			
		||||
"it off.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"It is a strange thing this bed, this mimic grave, where we stretch our\n"
 | 
			
		||||
"tired limbs and sink away so quietly into the silence and rest. \"O bed,\n"
 | 
			
		||||
"O bed, delicious bed, that heaven on earth to the weary head,\" as sang\n"
 | 
			
		||||
"poor Hood, you are a kind old nurse to us fretful boys and girls. Clever\n"
 | 
			
		||||
"and foolish, naughty and good, you take us all in your motherly lap and\n"
 | 
			
		||||
"hush our wayward crying. The strong man full of care--the sick man\n"
 | 
			
		||||
"full of pain--the little maiden sobbing for her faithless lover--like\n"
 | 
			
		||||
"children we lay our aching heads on your white bosom, and you gently\n"
 | 
			
		||||
"soothe us off to by-by.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"Our trouble is sore indeed when you turn away and will not comfort us.\n"
 | 
			
		||||
"How long the dawn seems coming when we cannot sleep! Oh! those hideous\n"
 | 
			
		||||
"nights when we toss and turn in fever and pain, when we lie, like living\n"
 | 
			
		||||
"men among the dead, staring out into the dark hours that drift so slowly\n"
 | 
			
		||||
"between us and the light. And oh! those still more hideous nights when\n"
 | 
			
		||||
"we sit by another in pain, when the low fire startles us every now and\n"
 | 
			
		||||
"then with a falling cinder, and the tick of the clock seems a hammer\n"
 | 
			
		||||
"beating out the life that we are watching.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"But enough of beds and bedrooms. I have kept to them too long, even for\n"
 | 
			
		||||
"an idle fellow. Let us come out and have a smoke. That wastes time just\n"
 | 
			
		||||
"as well and does not look so bad. Tobacco has been a blessing to us\n"
 | 
			
		||||
"idlers. What the civil-service clerk before Sir Walter's time found\n"
 | 
			
		||||
"to occupy their minds with it is hard to imagine. I attribute the\n"
 | 
			
		||||
"quarrelsome nature of the Middle Ages young men entirely to the want of\n"
 | 
			
		||||
"the soothing weed. They had no work to do and could not smoke, and\n"
 | 
			
		||||
"the consequence was they were forever fighting and rowing. If, by any\n"
 | 
			
		||||
"extraordinary chance, there was no war going, then they got up a deadly\n"
 | 
			
		||||
"family feud with the next-door neighbor, and if, in spite of this, they\n"
 | 
			
		||||
"still had a few spare moments on their hands, they occupied them with\n"
 | 
			
		||||
"discussions as to whose sweetheart was the best looking, the arguments\n"
 | 
			
		||||
"employed on both sides being battle-axes, clubs, etc. Questions of taste\n"
 | 
			
		||||
"were soon decided in those days. When a twelfth-century youth fell in\n"
 | 
			
		||||
"love he did not take three paces backward, gaze into her eyes, and tell\n"
 | 
			
		||||
"her she was too beautiful to live. He said he would step outside and see\n"
 | 
			
		||||
"about it. And if, when he got out, he met a man and broke his head--the\n"
 | 
			
		||||
"other man's head, I mean--then that proved that his--the first\n"
 | 
			
		||||
"fellow's--girl was a pretty girl. But if the other fellow broke _his_\n"
 | 
			
		||||
"head--not his own, you know, but the other fellow's--the other fellow\n"
 | 
			
		||||
"to the second fellow, that is, because of course the other fellow would\n"
 | 
			
		||||
"only be the other fellow to him, not the first fellow who--well, if he\n"
 | 
			
		||||
"broke his head, then _his_ girl--not the other fellow's, but the fellow\n"
 | 
			
		||||
"who _was_ the--Look here, if A broke B's head, then A's girl was a\n"
 | 
			
		||||
"pretty girl; but if B broke A's head, then A's girl wasn't a pretty\n"
 | 
			
		||||
"girl, but B's girl was. That was their method of conducting art\n"
 | 
			
		||||
"criticism.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"Nowadays we light a pipe and let the girls fight it out among\n"
 | 
			
		||||
"themselves.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"They do it very well. They are getting to do all our work. They are\n"
 | 
			
		||||
"doctors, and barristers, and artists. They manage theaters, and promote\n"
 | 
			
		||||
"swindles, and edit newspapers. I am looking forward to the time when we\n"
 | 
			
		||||
"men shall have nothing to do but lie in bed till twelve, read two novels\n"
 | 
			
		||||
"a day, have nice little five-o'clock teas all to ourselves, and tax\n"
 | 
			
		||||
"our brains with nothing more trying than discussions upon the latest\n"
 | 
			
		||||
"patterns in trousers and arguments as to what Mr. Jones' coat was\n"
 | 
			
		||||
"made of and whether it fitted him. It is a glorious prospect--for idle\n"
 | 
			
		||||
"fellows.\n"
 | 
			
		||||
"\n\n\n"
 | 
			
		||||
;
 | 
			
		||||
static const size_t IDLE_SIZE = sizeof(on_being_idle) - 1;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* This is the "LSWS" mode: first write is performed immediately, outside
 | 
			
		||||
 * of the on_write() callback.  This makes it possible to play with buffered
 | 
			
		||||
| 
						 | 
				
			
			@ -43,11 +279,13 @@ static const size_t IDLE_SIZE;
 | 
			
		|||
static int s_immediate_write;
 | 
			
		||||
 | 
			
		||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
 | 
			
		||||
#define V(v) (v), strlen(v)
 | 
			
		||||
 | 
			
		||||
struct lsquic_conn_ctx;
 | 
			
		||||
 | 
			
		||||
static void interop_server_hset_destroy (void *);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct server_ctx {
 | 
			
		||||
    struct lsquic_conn_ctx  *conn_h;
 | 
			
		||||
    lsquic_engine_t             *engine;
 | 
			
		||||
| 
						 | 
				
			
			@ -278,12 +516,14 @@ static int
 | 
			
		|||
send_headers (struct lsquic_stream *stream, lsquic_stream_ctx_t *st_h)
 | 
			
		||||
{
 | 
			
		||||
    const char *content_type;
 | 
			
		||||
    struct header_buf hbuf;
 | 
			
		||||
 | 
			
		||||
    content_type = select_content_type(st_h);
 | 
			
		||||
    struct lsxpack_header headers_arr[2];
 | 
			
		||||
 | 
			
		||||
    lsxpack_header_set_ptr(&headers_arr[0], ":status", 7, "200", 3);
 | 
			
		||||
    lsxpack_header_set_ptr(&headers_arr[1], "content-type", 12,
 | 
			
		||||
    hbuf.off = 0;
 | 
			
		||||
    header_set_ptr(&headers_arr[0], &hbuf, ":status", 7, "200", 3);
 | 
			
		||||
    header_set_ptr(&headers_arr[1], &hbuf, "content-type", 12,
 | 
			
		||||
                                        content_type, strlen(content_type));
 | 
			
		||||
    lsquic_http_headers_t headers = {
 | 
			
		||||
        .count = sizeof(headers_arr) / sizeof(headers_arr[0]),
 | 
			
		||||
| 
						 | 
				
			
			@ -301,7 +541,7 @@ send_headers (struct lsquic_stream *stream, lsquic_stream_ctx_t *st_h)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
resume_response (int fd, short what, void *arg)
 | 
			
		||||
resume_response (evutil_socket_t fd, short what, void *arg)
 | 
			
		||||
{
 | 
			
		||||
    struct lsquic_stream_ctx *const st_h = arg;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -551,6 +791,7 @@ push_promise (lsquic_stream_ctx_t *st_h, lsquic_stream_t *stream)
 | 
			
		|||
    regex_t re;
 | 
			
		||||
    regmatch_t matches[2];
 | 
			
		||||
    struct hset_fm *hfm;
 | 
			
		||||
    struct header_buf hbuf;
 | 
			
		||||
 | 
			
		||||
    s = regcomp(&re, "\r\nHost: *([[:alnum:].][[:alnum:].]*)\r\n",
 | 
			
		||||
                                                    REG_EXTENDED|REG_ICASE);
 | 
			
		||||
| 
						 | 
				
			
			@ -577,16 +818,17 @@ push_promise (lsquic_stream_ctx_t *st_h, lsquic_stream_t *stream)
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
#define V(v) (v), strlen(v)
 | 
			
		||||
    hbuf.off = 0;
 | 
			
		||||
    struct lsxpack_header headers_arr[6];
 | 
			
		||||
    lsxpack_header_set_ptr(&headers_arr[0], V(":method"), V("GET"));
 | 
			
		||||
    lsxpack_header_set_ptr(&headers_arr[1], V(":path"),
 | 
			
		||||
    header_set_ptr(&headers_arr[0], &hbuf, V(":method"), V("GET"));
 | 
			
		||||
    header_set_ptr(&headers_arr[1], &hbuf, V(":path"),
 | 
			
		||||
                                            V(st_h->server_ctx->push_path));
 | 
			
		||||
    lsxpack_header_set_ptr(&headers_arr[2], V(":authority"),
 | 
			
		||||
    header_set_ptr(&headers_arr[2], &hbuf, V(":authority"),
 | 
			
		||||
        st_h->req_buf + matches[1].rm_so, matches[1].rm_eo - matches[1].rm_so);
 | 
			
		||||
    lsxpack_header_set_ptr(&headers_arr[3], V(":scheme"), V("https"));
 | 
			
		||||
    lsxpack_header_set_ptr(&headers_arr[4], V("x-some-header"),
 | 
			
		||||
    header_set_ptr(&headers_arr[3], &hbuf, V(":scheme"), V("https"));
 | 
			
		||||
    header_set_ptr(&headers_arr[4], &hbuf, V("x-some-header"),
 | 
			
		||||
                                                        V("x-some-value"));
 | 
			
		||||
    lsxpack_header_set_ptr(&headers_arr[5], V("x-kenny-status"),
 | 
			
		||||
    header_set_ptr(&headers_arr[5], &hbuf, V("x-kenny-status"),
 | 
			
		||||
                        V("Oh my God!  They killed Kenny!!!  You bastards!"));
 | 
			
		||||
    lsquic_http_headers_t headers = {
 | 
			
		||||
        .count = sizeof(headers_arr) / sizeof(headers_arr[0]),
 | 
			
		||||
| 
						 | 
				
			
			@ -605,7 +847,6 @@ push_promise (lsquic_stream_ctx_t *st_h, lsquic_stream_t *stream)
 | 
			
		|||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
| 
						 | 
				
			
			@ -641,7 +882,6 @@ static void
 | 
			
		|||
http_server_on_read_regular (struct lsquic_stream *stream,
 | 
			
		||||
                                                    lsquic_stream_ctx_t *st_h)
 | 
			
		||||
{
 | 
			
		||||
#if HAVE_OPEN_MEMSTREAM
 | 
			
		||||
    unsigned char buf[0x400];
 | 
			
		||||
    ssize_t nread;
 | 
			
		||||
    int s;
 | 
			
		||||
| 
						 | 
				
			
			@ -674,20 +914,22 @@ http_server_on_read_regular (struct lsquic_stream *stream,
 | 
			
		|||
        LSQ_ERROR("error reading: %s", strerror(errno));
 | 
			
		||||
        lsquic_stream_close(stream);
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    LSQ_ERROR("%s: open_memstream not supported\n", __func__);
 | 
			
		||||
    exit(1);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
http_server_on_read (struct lsquic_stream *stream, lsquic_stream_ctx_t *st_h)
 | 
			
		||||
{
 | 
			
		||||
#if HAVE_OPEN_MEMSTREAM
 | 
			
		||||
    if (lsquic_stream_is_pushed(stream))
 | 
			
		||||
        http_server_on_read_pushed(stream, st_h);
 | 
			
		||||
    else
 | 
			
		||||
        http_server_on_read_regular(stream, st_h);
 | 
			
		||||
#else
 | 
			
		||||
    LSQ_ERROR("%s: open_memstream not supported\n", __func__);
 | 
			
		||||
    exit(1);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -716,6 +958,7 @@ const struct lsquic_stream_if http_server_if = {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if HAVE_REGEX
 | 
			
		||||
struct req_map
 | 
			
		||||
{
 | 
			
		||||
    enum method             method;
 | 
			
		||||
| 
						 | 
				
			
			@ -848,12 +1091,12 @@ read_md5 (void *ctx, const unsigned char *buf, size_t sz, int fin)
 | 
			
		|||
static void
 | 
			
		||||
http_server_interop_on_read (lsquic_stream_t *stream, lsquic_stream_ctx_t *st_h)
 | 
			
		||||
{
 | 
			
		||||
#define ERROR_RESP(code, args...) do {  \
 | 
			
		||||
    LSQ_WARN(args);                                     \
 | 
			
		||||
#define ERROR_RESP(code, ...) do {  \
 | 
			
		||||
    LSQ_WARN(__VA_ARGS__);                                     \
 | 
			
		||||
    st_h->interop_handler = IOH_ERROR; \
 | 
			
		||||
    st_h->resp_status = #code;  \
 | 
			
		||||
    st_h->interop_u.err.resp.sz = snprintf(st_h->interop_u.err.buf, \
 | 
			
		||||
                                    sizeof(st_h->interop_u.err.buf), args); \
 | 
			
		||||
                            sizeof(st_h->interop_u.err.buf), __VA_ARGS__);  \
 | 
			
		||||
    if (st_h->interop_u.err.resp.sz >= sizeof(st_h->interop_u.err.buf))     \
 | 
			
		||||
        st_h->interop_u.err.resp.sz = sizeof(st_h->interop_u.err.buf) - 1;  \
 | 
			
		||||
    st_h->interop_u.err.resp.buf = st_h->interop_u.err.buf;                 \
 | 
			
		||||
| 
						 | 
				
			
			@ -1047,14 +1290,16 @@ send_headers2 (struct lsquic_stream *stream, struct lsquic_stream_ctx *st_h,
 | 
			
		|||
                    size_t content_len)
 | 
			
		||||
{
 | 
			
		||||
    char clbuf[0x20];
 | 
			
		||||
    struct header_buf hbuf;
 | 
			
		||||
 | 
			
		||||
    snprintf(clbuf, sizeof(clbuf), "%zd", content_len);
 | 
			
		||||
 | 
			
		||||
    hbuf.off = 0;
 | 
			
		||||
    struct lsxpack_header  headers_arr[4];
 | 
			
		||||
    lsxpack_header_set_ptr(&headers_arr[0], V(":status"), V(st_h->resp_status));
 | 
			
		||||
    lsxpack_header_set_ptr(&headers_arr[1], V("server"), V(LITESPEED_ID));
 | 
			
		||||
    lsxpack_header_set_ptr(&headers_arr[2], V("content-type"), V("text/html"));
 | 
			
		||||
    lsxpack_header_set_ptr(&headers_arr[3], V("content-length"), V(clbuf));
 | 
			
		||||
    header_set_ptr(&headers_arr[0], &hbuf, V(":status"), V(st_h->resp_status));
 | 
			
		||||
    header_set_ptr(&headers_arr[1], &hbuf, V("server"), V(LITESPEED_ID));
 | 
			
		||||
    header_set_ptr(&headers_arr[2], &hbuf, V("content-type"), V("text/html"));
 | 
			
		||||
    header_set_ptr(&headers_arr[3], &hbuf, V("content-length"), V(clbuf));
 | 
			
		||||
    lsquic_http_headers_t headers = {
 | 
			
		||||
        .count = sizeof(headers_arr) / sizeof(headers_arr[0]),
 | 
			
		||||
        .headers = headers_arr,
 | 
			
		||||
| 
						 | 
				
			
			@ -1070,7 +1315,7 @@ idle_read (void *lsqr_ctx, void *buf, size_t count)
 | 
			
		|||
{
 | 
			
		||||
    struct gen_file_ctx *const gfc = lsqr_ctx;
 | 
			
		||||
    unsigned char *p = buf;
 | 
			
		||||
    unsigned char *const end = buf + count;
 | 
			
		||||
    unsigned char *const end = p + count;
 | 
			
		||||
    size_t towrite;
 | 
			
		||||
 | 
			
		||||
    while (p < end && gfc->remain > 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -1133,6 +1378,7 @@ idle_on_write (lsquic_stream_t *stream, lsquic_stream_ctx_t *st_h)
 | 
			
		|||
    struct lsquic_http_headers headers;
 | 
			
		||||
    struct req *req;
 | 
			
		||||
    ssize_t nw;
 | 
			
		||||
    struct header_buf hbuf;
 | 
			
		||||
 | 
			
		||||
    if (st_h->flags & SH_HEADERS_SENT)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -1158,10 +1404,11 @@ idle_on_write (lsquic_stream_t *stream, lsquic_stream_ctx_t *st_h)
 | 
			
		|||
            {
 | 
			
		||||
                STAILQ_REMOVE_HEAD(&gfc->push_paths, next);
 | 
			
		||||
                LSQ_DEBUG("pushing promise for %s", push_path->path);
 | 
			
		||||
                lsxpack_header_set_ptr(&header_arr[0], V(":method"), V("GET"));
 | 
			
		||||
                lsxpack_header_set_ptr(&header_arr[1], V(":path"), V(push_path->path));
 | 
			
		||||
                lsxpack_header_set_ptr(&header_arr[2], V(":authority"), V(st_h->req->authority_str));
 | 
			
		||||
                lsxpack_header_set_ptr(&header_arr[3], V(":scheme"), V("https"));
 | 
			
		||||
                hbuf.off = 0;
 | 
			
		||||
                header_set_ptr(&header_arr[0], &hbuf, V(":method"), V("GET"));
 | 
			
		||||
                header_set_ptr(&header_arr[1], &hbuf, V(":path"), V(push_path->path));
 | 
			
		||||
                header_set_ptr(&header_arr[2], &hbuf, V(":authority"), V(st_h->req->authority_str));
 | 
			
		||||
                header_set_ptr(&header_arr[3], &hbuf, V(":scheme"), V("https"));
 | 
			
		||||
                headers.headers = header_arr;
 | 
			
		||||
                headers.count = sizeof(header_arr) / sizeof(header_arr[0]);
 | 
			
		||||
                req = new_req(GET, push_path->path, st_h->req->authority_str);
 | 
			
		||||
| 
						 | 
				
			
			@ -1243,6 +1490,7 @@ const struct lsquic_stream_if interop_http_server_if = {
 | 
			
		|||
    .on_write               = http_server_interop_on_write,
 | 
			
		||||
    .on_close               = http_server_on_close,
 | 
			
		||||
};
 | 
			
		||||
#endif /* HAVE_REGEX */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
| 
						 | 
				
			
			@ -1308,6 +1556,23 @@ interop_server_hset_prepare_decode (void *hset_p, struct lsxpack_header *xhdr,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef WIN32
 | 
			
		||||
char *
 | 
			
		||||
strndup (const char *s, size_t n)
 | 
			
		||||
{
 | 
			
		||||
    char *copy;
 | 
			
		||||
 | 
			
		||||
    copy = malloc(n + 1);
 | 
			
		||||
    if (!copy)
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    memcpy(copy, s, n);
 | 
			
		||||
    copy[n] = '\0';
 | 
			
		||||
    return copy;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
interop_server_hset_add_header (void *hset_p, struct lsxpack_header *xhdr)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -1403,6 +1668,11 @@ main (int argc, char **argv)
 | 
			
		|||
    struct server_ctx server_ctx;
 | 
			
		||||
    struct prog prog;
 | 
			
		||||
 | 
			
		||||
#if !(HAVE_OPEN_MEMSTREAM || HAVE_REGEX)
 | 
			
		||||
    fprintf(stderr, "cannot run server without regex or open_memstream\n");
 | 
			
		||||
    return 1;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    memset(&server_ctx, 0, sizeof(server_ctx));
 | 
			
		||||
    TAILQ_INIT(&server_ctx.sports);
 | 
			
		||||
    server_ctx.prog = &prog;
 | 
			
		||||
| 
						 | 
				
			
			@ -1425,11 +1695,13 @@ main (int argc, char **argv)
 | 
			
		|||
                perror("stat");
 | 
			
		||||
                exit(2);
 | 
			
		||||
            }
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
            if (!S_ISDIR(st.st_mode))
 | 
			
		||||
            {
 | 
			
		||||
                fprintf(stderr, "`%s' is not a directory\n", optarg);
 | 
			
		||||
                exit(2);
 | 
			
		||||
            }
 | 
			
		||||
#endif
 | 
			
		||||
            server_ctx.document_root = optarg;
 | 
			
		||||
            break;
 | 
			
		||||
        case 'w':
 | 
			
		||||
| 
						 | 
				
			
			@ -1450,11 +1722,16 @@ main (int argc, char **argv)
 | 
			
		|||
 | 
			
		||||
    if (!server_ctx.document_root)
 | 
			
		||||
    {
 | 
			
		||||
#if HAVE_REGEX
 | 
			
		||||
        LSQ_NOTICE("Document root is not set: start in Interop Mode");
 | 
			
		||||
        init_map_regexes();
 | 
			
		||||
        prog.prog_api.ea_stream_if = &interop_http_server_if;
 | 
			
		||||
        prog.prog_api.ea_hsi_if = &header_bypass_api;
 | 
			
		||||
        prog.prog_api.ea_hsi_ctx = NULL;
 | 
			
		||||
#else
 | 
			
		||||
        LSQ_ERROR("Document root is not set: use -r option");
 | 
			
		||||
        exit(EXIT_FAILURE);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (0 != prog_prep(&prog))
 | 
			
		||||
| 
						 | 
				
			
			@ -1468,233 +1745,10 @@ main (int argc, char **argv)
 | 
			
		|||
    s = prog_run(&prog);
 | 
			
		||||
    prog_cleanup(&prog);
 | 
			
		||||
 | 
			
		||||
#if HAVE_REGEX
 | 
			
		||||
    if (!server_ctx.document_root)
 | 
			
		||||
        free_map_regexes();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    exit(0 == s ? EXIT_SUCCESS : EXIT_FAILURE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static const char on_being_idle[] =
 | 
			
		||||
"ON BEING IDLE.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"Now, this is a subject on which I flatter myself I really am _au fait_.\n"
 | 
			
		||||
"The gentleman who, when I was young, bathed me at wisdom's font for nine\n"
 | 
			
		||||
"guineas a term--no extras--used to say he never knew a boy who could\n"
 | 
			
		||||
"do less work in more time; and I remember my poor grandmother once\n"
 | 
			
		||||
"incidentally observing, in the course of an instruction upon the use\n"
 | 
			
		||||
"of the Prayer-book, that it was highly improbable that I should ever do\n"
 | 
			
		||||
"much that I ought not to do, but that she felt convinced beyond a doubt\n"
 | 
			
		||||
"that I should leave undone pretty well everything that I ought to do.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"I am afraid I have somewhat belied half the dear old lady's prophecy.\n"
 | 
			
		||||
"Heaven help me! I have done a good many things that I ought not to have\n"
 | 
			
		||||
"done, in spite of my laziness. But I have fully confirmed the accuracy\n"
 | 
			
		||||
"of her judgment so far as neglecting much that I ought not to have\n"
 | 
			
		||||
"neglected is concerned. Idling always has been my strong point. I take\n"
 | 
			
		||||
"no credit to myself in the matter--it is a gift. Few possess it. There\n"
 | 
			
		||||
"are plenty of lazy people and plenty of slow-coaches, but a genuine\n"
 | 
			
		||||
"idler is a rarity. He is not a man who slouches about with his hands in\n"
 | 
			
		||||
"his pockets. On the contrary, his most startling characteristic is that\n"
 | 
			
		||||
"he is always intensely busy.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"It is impossible to enjoy idling thoroughly unless one has plenty of\n"
 | 
			
		||||
"work to do. There is no fun in doing nothing when you have nothing to\n"
 | 
			
		||||
"do. Wasting time is merely an occupation then, and a most exhausting\n"
 | 
			
		||||
"one. Idleness, like kisses, to be sweet must be stolen.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"Many years ago, when I was a young man, I was taken very ill--I never\n"
 | 
			
		||||
"could see myself that much was the matter with me, except that I had\n"
 | 
			
		||||
"a beastly cold. But I suppose it was something very serious, for the\n"
 | 
			
		||||
"doctor said that I ought to have come to him a month before, and that\n"
 | 
			
		||||
"if it (whatever it was) had gone on for another week he would not have\n"
 | 
			
		||||
"answered for the consequences. It is an extraordinary thing, but I\n"
 | 
			
		||||
"never knew a doctor called into any case yet but what it transpired\n"
 | 
			
		||||
"that another day's delay would have rendered cure hopeless. Our medical\n"
 | 
			
		||||
"guide, philosopher, and friend is like the hero in a melodrama--he\n"
 | 
			
		||||
"always comes upon the scene just, and only just, in the nick of time. It\n"
 | 
			
		||||
"is Providence, that is what it is.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"Well, as I was saying, I was very ill and was ordered to Buxton for a\n"
 | 
			
		||||
"month, with strict injunctions to do nothing whatever all the while\n"
 | 
			
		||||
"that I was there. \"Rest is what you require,\" said the doctor, \"perfect\n"
 | 
			
		||||
"rest.\"\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"It seemed a delightful prospect. \"This man evidently understands my\n"
 | 
			
		||||
"complaint,\" said I, and I pictured to myself a glorious time--a four\n"
 | 
			
		||||
"weeks' _dolce far niente_ with a dash of illness in it. Not too much\n"
 | 
			
		||||
"illness, but just illness enough--just sufficient to give it the flavor\n"
 | 
			
		||||
"of suffering and make it poetical. I should get up late, sip chocolate,\n"
 | 
			
		||||
"and have my breakfast in slippers and a dressing-gown. I should lie out\n"
 | 
			
		||||
"in the garden in a hammock and read sentimental novels with a melancholy\n"
 | 
			
		||||
"ending, until the books should fall from my listless hand, and I should\n"
 | 
			
		||||
"recline there, dreamily gazing into the deep blue of the firmament,\n"
 | 
			
		||||
"watching the fleecy clouds floating like white-sailed ships across\n"
 | 
			
		||||
"its depths, and listening to the joyous song of the birds and the low\n"
 | 
			
		||||
"rustling of the trees. Or, on becoming too weak to go out of doors,\n"
 | 
			
		||||
"I should sit propped up with pillows at the open window of the\n"
 | 
			
		||||
"ground-floor front, and look wasted and interesting, so that all the\n"
 | 
			
		||||
"pretty girls would sigh as they passed by.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"And twice a day I should go down in a Bath chair to the Colonnade to\n"
 | 
			
		||||
"drink the waters. Oh, those waters! I knew nothing about them then,\n"
 | 
			
		||||
"and was rather taken with the idea. \"Drinking the waters\" sounded\n"
 | 
			
		||||
"fashionable and Queen Anne-fied, and I thought I should like them. But,\n"
 | 
			
		||||
"ugh! after the first three or four mornings! Sam Weller's description of\n"
 | 
			
		||||
"them as \"having a taste of warm flat-irons\" conveys only a faint idea of\n"
 | 
			
		||||
"their hideous nauseousness. If anything could make a sick man get well\n"
 | 
			
		||||
"quickly, it would be the knowledge that he must drink a glassful of them\n"
 | 
			
		||||
"every day until he was recovered. I drank them neat for six consecutive\n"
 | 
			
		||||
"days, and they nearly killed me; but after then I adopted the plan of\n"
 | 
			
		||||
"taking a stiff glass of brandy-and-water immediately on the top of them,\n"
 | 
			
		||||
"and found much relief thereby. I have been informed since, by various\n"
 | 
			
		||||
"eminent medical gentlemen, that the alcohol must have entirely\n"
 | 
			
		||||
"counteracted the effects of the chalybeate properties contained in the\n"
 | 
			
		||||
"water. I am glad I was lucky enough to hit upon the right thing.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"But \"drinking the waters\" was only a small portion of the torture I\n"
 | 
			
		||||
"experienced during that memorable month--a month which was, without\n"
 | 
			
		||||
"exception, the most miserable I have ever spent. During the best part of\n"
 | 
			
		||||
"it I religiously followed the doctor's mandate and did nothing whatever,\n"
 | 
			
		||||
"except moon about the house and garden and go out for two hours a day in\n"
 | 
			
		||||
"a Bath chair. That did break the monotony to a certain extent. There is\n"
 | 
			
		||||
"more excitement about Bath-chairing--especially if you are not used to\n"
 | 
			
		||||
"the exhilarating exercise--than might appear to the casual observer. A\n"
 | 
			
		||||
"sense of danger, such as a mere outsider might not understand, is ever\n"
 | 
			
		||||
"present to the mind of the occupant. He feels convinced every minute\n"
 | 
			
		||||
"that the whole concern is going over, a conviction which becomes\n"
 | 
			
		||||
"especially lively whenever a ditch or a stretch of newly macadamized\n"
 | 
			
		||||
"road comes in sight. Every vehicle that passes he expects is going to\n"
 | 
			
		||||
"run into him; and he never finds himself ascending or descending a\n"
 | 
			
		||||
"hill without immediately beginning to speculate upon his chances,\n"
 | 
			
		||||
"supposing--as seems extremely probable--that the weak-kneed controller\n"
 | 
			
		||||
"of his destiny should let go.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"But even this diversion failed to enliven after awhile, and the _ennui_\n"
 | 
			
		||||
"became perfectly unbearable. I felt my mind giving way under it. It is\n"
 | 
			
		||||
"not a strong mind, and I thought it would be unwise to tax it too far.\n"
 | 
			
		||||
"So somewhere about the twentieth morning I got up early, had a good\n"
 | 
			
		||||
"breakfast, and walked straight off to Hayfield, at the foot of the\n"
 | 
			
		||||
"Kinder Scout--a pleasant, busy little town, reached through a lovely\n"
 | 
			
		||||
"valley, and with two sweetly pretty women in it. At least they were\n"
 | 
			
		||||
"sweetly pretty then; one passed me on the bridge and, I think, smiled;\n"
 | 
			
		||||
"and the other was standing at an open door, making an unremunerative\n"
 | 
			
		||||
"investment of kisses upon a red-faced baby. But it is years ago, and I\n"
 | 
			
		||||
"dare say they have both grown stout and snappish since that time.\n"
 | 
			
		||||
"Coming back, I saw an old man breaking stones, and it roused such strong\n"
 | 
			
		||||
"longing in me to use my arms that I offered him a drink to let me take\n"
 | 
			
		||||
"his place. He was a kindly old man and he humored me. I went for those\n"
 | 
			
		||||
"stones with the accumulated energy of three weeks, and did more work in\n"
 | 
			
		||||
"half an hour than he had done all day. But it did not make him jealous.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"Having taken the plunge, I went further and further into dissipation,\n"
 | 
			
		||||
"going out for a long walk every morning and listening to the band in\n"
 | 
			
		||||
"the pavilion every evening. But the days still passed slowly\n"
 | 
			
		||||
"notwithstanding, and I was heartily glad when the last one came and I\n"
 | 
			
		||||
"was being whirled away from gouty, consumptive Buxton to London with its\n"
 | 
			
		||||
"stern work and life. I looked out of the carriage as we rushed through\n"
 | 
			
		||||
"Hendon in the evening. The lurid glare overhanging the mighty city\n"
 | 
			
		||||
"seemed to warm my heart, and when, later on, my cab rattled out of St.\n"
 | 
			
		||||
"Pancras' station, the old familiar roar that came swelling up around me\n"
 | 
			
		||||
"sounded the sweetest music I had heard for many a long day.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"I certainly did not enjoy that month's idling. I like idling when I\n"
 | 
			
		||||
"ought not to be idling; not when it is the only thing I have to do. That\n"
 | 
			
		||||
"is my pig-headed nature. The time when I like best to stand with my\n"
 | 
			
		||||
"back to the fire, calculating how much I owe, is when my desk is heaped\n"
 | 
			
		||||
"highest with letters that must be answered by the next post. When I like\n"
 | 
			
		||||
"to dawdle longest over my dinner is when I have a heavy evening's work\n"
 | 
			
		||||
"before me. And if, for some urgent reason, I ought to be up particularly\n"
 | 
			
		||||
"early in the morning, it is then, more than at any other time, that I\n"
 | 
			
		||||
"love to lie an extra half-hour in bed.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"Ah! how delicious it is to turn over and go to sleep again: \"just for\n"
 | 
			
		||||
"five minutes.\" Is there any human being, I wonder, besides the hero of\n"
 | 
			
		||||
"a Sunday-school \"tale for boys,\" who ever gets up willingly? There\n"
 | 
			
		||||
"are some men to whom getting up at the proper time is an utter\n"
 | 
			
		||||
"impossibility. If eight o'clock happens to be the time that they should\n"
 | 
			
		||||
"turn out, then they lie till half-past. If circumstances change and\n"
 | 
			
		||||
"half-past eight becomes early enough for them, then it is nine before\n"
 | 
			
		||||
"they can rise. They are like the statesman of whom it was said that he\n"
 | 
			
		||||
"was always punctually half an hour late. They try all manner of schemes.\n"
 | 
			
		||||
"They buy alarm-clocks (artful contrivances that go off at the wrong time\n"
 | 
			
		||||
"and alarm the wrong people). They tell Sarah Jane to knock at the door\n"
 | 
			
		||||
"and call them, and Sarah Jane does knock at the door and does call them,\n"
 | 
			
		||||
"and they grunt back \"awri\" and then go comfortably to sleep again. I\n"
 | 
			
		||||
"knew one man who would actually get out and have a cold bath; and even\n"
 | 
			
		||||
"that was of no use, for afterward he would jump into bed again to warm\n"
 | 
			
		||||
"himself.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"I think myself that I could keep out of bed all right if I once got\n"
 | 
			
		||||
"out. It is the wrenching away of the head from the pillow that I find so\n"
 | 
			
		||||
"hard, and no amount of over-night determination makes it easier. I say\n"
 | 
			
		||||
"to myself, after having wasted the whole evening, \"Well, I won't do\n"
 | 
			
		||||
"any more work to-night; I'll get up early to-morrow morning;\" and I am\n"
 | 
			
		||||
"thoroughly resolved to do so--then. In the morning, however, I feel less\n"
 | 
			
		||||
"enthusiastic about the idea, and reflect that it would have been much\n"
 | 
			
		||||
"better if I had stopped up last night. And then there is the trouble of\n"
 | 
			
		||||
"dressing, and the more one thinks about that the more one wants to put\n"
 | 
			
		||||
"it off.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"It is a strange thing this bed, this mimic grave, where we stretch our\n"
 | 
			
		||||
"tired limbs and sink away so quietly into the silence and rest. \"O bed,\n"
 | 
			
		||||
"O bed, delicious bed, that heaven on earth to the weary head,\" as sang\n"
 | 
			
		||||
"poor Hood, you are a kind old nurse to us fretful boys and girls. Clever\n"
 | 
			
		||||
"and foolish, naughty and good, you take us all in your motherly lap and\n"
 | 
			
		||||
"hush our wayward crying. The strong man full of care--the sick man\n"
 | 
			
		||||
"full of pain--the little maiden sobbing for her faithless lover--like\n"
 | 
			
		||||
"children we lay our aching heads on your white bosom, and you gently\n"
 | 
			
		||||
"soothe us off to by-by.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"Our trouble is sore indeed when you turn away and will not comfort us.\n"
 | 
			
		||||
"How long the dawn seems coming when we cannot sleep! Oh! those hideous\n"
 | 
			
		||||
"nights when we toss and turn in fever and pain, when we lie, like living\n"
 | 
			
		||||
"men among the dead, staring out into the dark hours that drift so slowly\n"
 | 
			
		||||
"between us and the light. And oh! those still more hideous nights when\n"
 | 
			
		||||
"we sit by another in pain, when the low fire startles us every now and\n"
 | 
			
		||||
"then with a falling cinder, and the tick of the clock seems a hammer\n"
 | 
			
		||||
"beating out the life that we are watching.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"But enough of beds and bedrooms. I have kept to them too long, even for\n"
 | 
			
		||||
"an idle fellow. Let us come out and have a smoke. That wastes time just\n"
 | 
			
		||||
"as well and does not look so bad. Tobacco has been a blessing to us\n"
 | 
			
		||||
"idlers. What the civil-service clerk before Sir Walter's time found\n"
 | 
			
		||||
"to occupy their minds with it is hard to imagine. I attribute the\n"
 | 
			
		||||
"quarrelsome nature of the Middle Ages young men entirely to the want of\n"
 | 
			
		||||
"the soothing weed. They had no work to do and could not smoke, and\n"
 | 
			
		||||
"the consequence was they were forever fighting and rowing. If, by any\n"
 | 
			
		||||
"extraordinary chance, there was no war going, then they got up a deadly\n"
 | 
			
		||||
"family feud with the next-door neighbor, and if, in spite of this, they\n"
 | 
			
		||||
"still had a few spare moments on their hands, they occupied them with\n"
 | 
			
		||||
"discussions as to whose sweetheart was the best looking, the arguments\n"
 | 
			
		||||
"employed on both sides being battle-axes, clubs, etc. Questions of taste\n"
 | 
			
		||||
"were soon decided in those days. When a twelfth-century youth fell in\n"
 | 
			
		||||
"love he did not take three paces backward, gaze into her eyes, and tell\n"
 | 
			
		||||
"her she was too beautiful to live. He said he would step outside and see\n"
 | 
			
		||||
"about it. And if, when he got out, he met a man and broke his head--the\n"
 | 
			
		||||
"other man's head, I mean--then that proved that his--the first\n"
 | 
			
		||||
"fellow's--girl was a pretty girl. But if the other fellow broke _his_\n"
 | 
			
		||||
"head--not his own, you know, but the other fellow's--the other fellow\n"
 | 
			
		||||
"to the second fellow, that is, because of course the other fellow would\n"
 | 
			
		||||
"only be the other fellow to him, not the first fellow who--well, if he\n"
 | 
			
		||||
"broke his head, then _his_ girl--not the other fellow's, but the fellow\n"
 | 
			
		||||
"who _was_ the--Look here, if A broke B's head, then A's girl was a\n"
 | 
			
		||||
"pretty girl; but if B broke A's head, then A's girl wasn't a pretty\n"
 | 
			
		||||
"girl, but B's girl was. That was their method of conducting art\n"
 | 
			
		||||
"criticism.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"Nowadays we light a pipe and let the girls fight it out among\n"
 | 
			
		||||
"themselves.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"They do it very well. They are getting to do all our work. They are\n"
 | 
			
		||||
"doctors, and barristers, and artists. They manage theaters, and promote\n"
 | 
			
		||||
"swindles, and edit newspapers. I am looking forward to the time when we\n"
 | 
			
		||||
"men shall have nothing to do but lie in bed till twelve, read two novels\n"
 | 
			
		||||
"a day, have nice little five-o'clock teas all to ourselves, and tax\n"
 | 
			
		||||
"our brains with nothing more trying than discussions upon the latest\n"
 | 
			
		||||
"patterns in trousers and arguments as to what Mr. Jones' coat was\n"
 | 
			
		||||
"made of and whether it fitted him. It is a glorious prospect--for idle\n"
 | 
			
		||||
"fellows.\n"
 | 
			
		||||
"\n\n\n"
 | 
			
		||||
;
 | 
			
		||||
static const size_t IDLE_SIZE = sizeof(on_being_idle) - 1;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,11 +10,17 @@
 | 
			
		|||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/queue.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#else
 | 
			
		||||
#include "vc_compat.h"
 | 
			
		||||
#include "getopt.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <event2/event.h>
 | 
			
		||||
#include <openssl/md5.h>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								bin/prog.c
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								bin/prog.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -16,7 +16,8 @@
 | 
			
		|||
#ifndef WIN32
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#else
 | 
			
		||||
#include <getopt.h>
 | 
			
		||||
#include "vc_compat.h"
 | 
			
		||||
#include "getopt.h"
 | 
			
		||||
#pragma warning(disable:4028)
 | 
			
		||||
#endif// WIN32
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -47,11 +48,20 @@ static const struct lsquic_packout_mem_if pmi = {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
int
 | 
			
		||||
prog_init (struct prog *prog, unsigned flags,
 | 
			
		||||
           struct sport_head *sports,
 | 
			
		||||
           const struct lsquic_stream_if *stream_if, void *stream_if_ctx)
 | 
			
		||||
{
 | 
			
		||||
#ifdef WIN32
 | 
			
		||||
    WSADATA wsd;
 | 
			
		||||
    int s = WSAStartup(MAKEWORD(2, 2), &wsd);
 | 
			
		||||
    if (s != 0)
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_ERROR("WSAStartup failed: %d", s);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    /* prog-specific initialization: */
 | 
			
		||||
    memset(prog, 0, sizeof(*prog));
 | 
			
		||||
    prog->prog_engine_flags = flags;
 | 
			
		||||
| 
						 | 
				
			
			@ -82,6 +92,7 @@ prog_init (struct prog *prog, unsigned flags,
 | 
			
		|||
                                                    LSQUIC_GLOBAL_CLIENT);
 | 
			
		||||
    lsquic_log_to_fstream(stderr, LLTS_HHMMSSMS);
 | 
			
		||||
    lsquic_logger_lopt("=notice");
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -215,8 +226,10 @@ prog_print_common_options (const struct prog *prog, FILE *out)
 | 
			
		|||
int
 | 
			
		||||
prog_set_opt (struct prog *prog, int opt, const char *arg)
 | 
			
		||||
{
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
    struct stat st;
 | 
			
		||||
    int s;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    switch (opt)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -54,7 +54,7 @@ struct prog
 | 
			
		|||
    }                               prog_flags;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
int
 | 
			
		||||
prog_init (struct prog *, unsigned lsquic_engine_flags, struct sport_head *,
 | 
			
		||||
                    const struct lsquic_stream_if *, void *stream_if_ctx);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,8 +30,13 @@
 | 
			
		|||
#include <fcntl.h>
 | 
			
		||||
 | 
			
		||||
#include "test_config.h"
 | 
			
		||||
 | 
			
		||||
#if HAVE_REGEX
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
#include <regex.h>
 | 
			
		||||
#else
 | 
			
		||||
#include <pcreposix.h>
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <event2/event.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -39,6 +44,7 @@
 | 
			
		|||
#include "test_common.h"
 | 
			
		||||
#include "lsquic.h"
 | 
			
		||||
#include "prog.h"
 | 
			
		||||
#include "lsxpack_header.h"
 | 
			
		||||
 | 
			
		||||
#include "../src/liblsquic/lsquic_logger.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -49,16 +55,6 @@
 | 
			
		|||
#define LSQUIC_USE_POOLS 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
#   define SOCKET_TYPE int
 | 
			
		||||
#   define CLOSE_SOCKET close
 | 
			
		||||
#   define CHAR_CAST
 | 
			
		||||
#else
 | 
			
		||||
#   define SOCKET_TYPE SOCKET
 | 
			
		||||
#   define CLOSE_SOCKET closesocket
 | 
			
		||||
#   define CHAR_CAST (char *)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if __linux__
 | 
			
		||||
#   define NDROPPED_SZ CMSG_SPACE(sizeof(uint32_t))  /* SO_RXQ_OVFL */
 | 
			
		||||
#else
 | 
			
		||||
| 
						 | 
				
			
			@ -177,9 +173,10 @@ allocate_packets_in (SOCKET_TYPE fd)
 | 
			
		|||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    n_alloc = (unsigned) recvsz / MAX_PACKET_SZ * 2;
 | 
			
		||||
    n_alloc = (unsigned) recvsz / 1370;
 | 
			
		||||
    LSQ_INFO("socket buffer size: %d bytes; max # packets is set to %u",
 | 
			
		||||
        recvsz, n_alloc);
 | 
			
		||||
    recvsz += MAX_PACKET_SZ;
 | 
			
		||||
 | 
			
		||||
    packs_in = malloc(sizeof(*packs_in));
 | 
			
		||||
    packs_in->data_sz = recvsz;
 | 
			
		||||
| 
						 | 
				
			
			@ -520,7 +517,9 @@ read_one_packet (struct read_iter *iter)
 | 
			
		|||
    packs_in->vecs[iter->ri_idx].len = MAX_PACKET_SZ;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
  top:
 | 
			
		||||
#endif
 | 
			
		||||
    ctl_buf = packs_in->ctlmsg_data + iter->ri_idx * CTL_SZ;
 | 
			
		||||
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
| 
						 | 
				
			
			@ -799,7 +798,11 @@ sport_init_server (struct service_port *sport, struct lsquic_engine *engine,
 | 
			
		|||
                   struct event_base *eb)
 | 
			
		||||
{
 | 
			
		||||
    const struct sockaddr *sa_local = (struct sockaddr *) &sport->sas;
 | 
			
		||||
    int sockfd, saved_errno, flags, s, on;
 | 
			
		||||
    int sockfd, saved_errno, s;
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
    int flags;
 | 
			
		||||
#endif
 | 
			
		||||
    SOCKOPT_VAL on;
 | 
			
		||||
    socklen_t socklen;
 | 
			
		||||
    char addr_str[0x20];
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -816,6 +819,9 @@ sport_init_server (struct service_port *sport, struct lsquic_engine *engine,
 | 
			
		|||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if WIN32
 | 
			
		||||
    getExtensionPtrs();
 | 
			
		||||
#endif
 | 
			
		||||
    sockfd = socket(sa_local->sa_family, SOCK_DGRAM, 0);
 | 
			
		||||
    if (-1 == sockfd)
 | 
			
		||||
        return -1;
 | 
			
		||||
| 
						 | 
				
			
			@ -829,6 +835,7 @@ sport_init_server (struct service_port *sport, struct lsquic_engine *engine,
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    /* Make socket non-blocking */
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
    flags = fcntl(sockfd, F_GETFL);
 | 
			
		||||
    if (-1 == flags) {
 | 
			
		||||
        saved_errno = errno;
 | 
			
		||||
| 
						 | 
				
			
			@ -843,20 +850,33 @@ sport_init_server (struct service_port *sport, struct lsquic_engine *engine,
 | 
			
		|||
        errno = saved_errno;
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    {
 | 
			
		||||
        u_long on = 1;
 | 
			
		||||
        ioctlsocket(sockfd, FIONBIO, &on);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    on = 1;
 | 
			
		||||
    if (AF_INET == sa_local->sa_family)
 | 
			
		||||
        s = setsockopt(sockfd, IPPROTO_IP,
 | 
			
		||||
#if __linux__ && defined(IP_RECVORIGDSTADDR)
 | 
			
		||||
                                           IP_RECVORIGDSTADDR,
 | 
			
		||||
#elif __linux__ || __APPLE__
 | 
			
		||||
#elif __linux__ || __APPLE__ || defined(WIN32)
 | 
			
		||||
                                           IP_PKTINFO,
 | 
			
		||||
#else
 | 
			
		||||
                                           IP_RECVDSTADDR,
 | 
			
		||||
#endif
 | 
			
		||||
                                                               &on, sizeof(on));
 | 
			
		||||
                                                               CHAR_CAST &on, sizeof(on));
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
        s = setsockopt(sockfd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on));
 | 
			
		||||
#else
 | 
			
		||||
        s = setsockopt(sockfd, IPPROTO_IPV6, IPV6_PKTINFO, CHAR_CAST &on, sizeof(on));
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (0 != s)
 | 
			
		||||
    {
 | 
			
		||||
        saved_errno = errno;
 | 
			
		||||
| 
						 | 
				
			
			@ -865,12 +885,12 @@ sport_init_server (struct service_port *sport, struct lsquic_engine *engine,
 | 
			
		|||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if (__linux__ && !defined(IP_RECVORIGDSTADDR)) || __APPLE__
 | 
			
		||||
#if (__linux__ && !defined(IP_RECVORIGDSTADDR)) || __APPLE__ || defined(WIN32)
 | 
			
		||||
    /* Need to set IP_PKTINFO for sending */
 | 
			
		||||
    if (AF_INET == sa_local->sa_family)
 | 
			
		||||
    {
 | 
			
		||||
        on = 1;
 | 
			
		||||
        s = setsockopt(sockfd, IPPROTO_IP, IP_PKTINFO, &on, sizeof(on));
 | 
			
		||||
        s = setsockopt(sockfd, IPPROTO_IP, IP_PKTINFO, CHAR_CAST &on, sizeof(on));
 | 
			
		||||
        if (0 != s)
 | 
			
		||||
        {
 | 
			
		||||
            saved_errno = errno;
 | 
			
		||||
| 
						 | 
				
			
			@ -932,7 +952,7 @@ sport_init_server (struct service_port *sport, struct lsquic_engine *engine,
 | 
			
		|||
                                                                sizeof(on));
 | 
			
		||||
#else
 | 
			
		||||
            on = 1;
 | 
			
		||||
            s = setsockopt(sockfd, IPPROTO_IP, IP_DONTFRAG, &on, sizeof(on));
 | 
			
		||||
            s = setsockopt(sockfd, IPPROTO_IP, IP_DONTFRAG, CHAR_CAST &on, sizeof(on));
 | 
			
		||||
#endif
 | 
			
		||||
            if (0 != s)
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -948,9 +968,9 @@ sport_init_server (struct service_port *sport, struct lsquic_engine *engine,
 | 
			
		|||
#if ECN_SUPPORTED
 | 
			
		||||
    on = 1;
 | 
			
		||||
    if (AF_INET == sa_local->sa_family)
 | 
			
		||||
        s = setsockopt(sockfd, IPPROTO_IP, IP_RECVTOS, &on, sizeof(on));
 | 
			
		||||
        s = setsockopt(sockfd, IPPROTO_IP, IP_RECVTOS, CHAR_CAST &on, sizeof(on));
 | 
			
		||||
    else
 | 
			
		||||
        s = setsockopt(sockfd, IPPROTO_IPV6, IPV6_RECVTCLASS, &on, sizeof(on));
 | 
			
		||||
        s = setsockopt(sockfd, IPPROTO_IPV6, IPV6_RECVTCLASS, CHAR_CAST &on, sizeof(on));
 | 
			
		||||
    if (0 != s)
 | 
			
		||||
    {
 | 
			
		||||
        saved_errno = errno;
 | 
			
		||||
| 
						 | 
				
			
			@ -962,7 +982,7 @@ sport_init_server (struct service_port *sport, struct lsquic_engine *engine,
 | 
			
		|||
 | 
			
		||||
    if (sport->sp_flags & SPORT_SET_SNDBUF)
 | 
			
		||||
    {
 | 
			
		||||
        s = setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sport->sp_sndbuf,
 | 
			
		||||
        s = setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, CHAR_CAST &sport->sp_sndbuf,
 | 
			
		||||
                                                    sizeof(sport->sp_sndbuf));
 | 
			
		||||
        if (0 != s)
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			@ -975,7 +995,7 @@ sport_init_server (struct service_port *sport, struct lsquic_engine *engine,
 | 
			
		|||
 | 
			
		||||
    if (sport->sp_flags & SPORT_SET_RCVBUF)
 | 
			
		||||
    {
 | 
			
		||||
        s = setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &sport->sp_rcvbuf,
 | 
			
		||||
        s = setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, CHAR_CAST &sport->sp_rcvbuf,
 | 
			
		||||
                                                    sizeof(sport->sp_rcvbuf));
 | 
			
		||||
        if (0 != s)
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			@ -1121,7 +1141,7 @@ sport_init_client (struct service_port *sport, struct lsquic_engine *engine,
 | 
			
		|||
                                                                sizeof(on));
 | 
			
		||||
#elif WIN32
 | 
			
		||||
            on = 1;
 | 
			
		||||
            s = setsockopt(sockfd, IPPROTO_IP, IP_DONTFRAGMENT, (char*)&on, sizeof(on));
 | 
			
		||||
            s = setsockopt(sockfd, IPPROTO_IP, IP_DONTFRAGMENT, CHAR_CAST &on, sizeof(on));
 | 
			
		||||
#else
 | 
			
		||||
            on = 1;
 | 
			
		||||
            s = setsockopt(sockfd, IPPROTO_IP, IP_DONTFRAG, &on, sizeof(on));
 | 
			
		||||
| 
						 | 
				
			
			@ -1141,10 +1161,11 @@ sport_init_client (struct service_port *sport, struct lsquic_engine *engine,
 | 
			
		|||
    {
 | 
			
		||||
        int on = 1;
 | 
			
		||||
        if (AF_INET == sa_local->sa_family)
 | 
			
		||||
            s = setsockopt(sockfd, IPPROTO_IP, IP_RECVTOS, &on, sizeof(on));
 | 
			
		||||
            s = setsockopt(sockfd, IPPROTO_IP, IP_RECVTOS,
 | 
			
		||||
                                            CHAR_CAST &on, sizeof(on));
 | 
			
		||||
        else
 | 
			
		||||
            s = setsockopt(sockfd, IPPROTO_IPV6, IPV6_RECVTCLASS, &on,
 | 
			
		||||
                                                                sizeof(on));
 | 
			
		||||
            s = setsockopt(sockfd, IPPROTO_IPV6, IPV6_RECVTCLASS,
 | 
			
		||||
                                            CHAR_CAST &on, sizeof(on));
 | 
			
		||||
        if (0 != s)
 | 
			
		||||
        {
 | 
			
		||||
            saved_errno = errno;
 | 
			
		||||
| 
						 | 
				
			
			@ -1527,6 +1548,7 @@ send_packets_one_by_one (const struct lsquic_out_spec *specs, unsigned count)
 | 
			
		|||
#else
 | 
			
		||||
    DWORD bytes;
 | 
			
		||||
    WSAMSG msg;
 | 
			
		||||
    WSABUF wsaBuf;
 | 
			
		||||
#endif
 | 
			
		||||
    union {
 | 
			
		||||
        /* cmsg(3) recommends union for proper alignment */
 | 
			
		||||
| 
						 | 
				
			
			@ -1589,12 +1611,14 @@ send_packets_one_by_one (const struct lsquic_out_spec *specs, unsigned count)
 | 
			
		|||
        msg.msg_iovlen     = specs[n].iovlen;
 | 
			
		||||
        msg.msg_flags      = 0;
 | 
			
		||||
#else
 | 
			
		||||
        wsaBuf.buf = specs[n].iov->iov_base;
 | 
			
		||||
        wsaBuf.len = specs[n].iov->iov_len;
 | 
			
		||||
        msg.name           = (void *) specs[n].dest_sa;
 | 
			
		||||
        msg.namelen        = (AF_INET == specs[n].dest_sa->sa_family ?
 | 
			
		||||
                                            sizeof(struct sockaddr_in) :
 | 
			
		||||
                                            sizeof(struct sockaddr_in6)),
 | 
			
		||||
        msg.lpBuffers      = specs[n].iov;
 | 
			
		||||
        msg.dwBufferCount  = specs[n].iovlen;
 | 
			
		||||
                                            sizeof(struct sockaddr_in6));
 | 
			
		||||
        msg.dwBufferCount  = 1;
 | 
			
		||||
        msg.lpBuffers      = &wsaBuf;
 | 
			
		||||
        msg.dwFlags        = 0;
 | 
			
		||||
#endif
 | 
			
		||||
        if ((sport->sp_flags & SPORT_SERVER) && specs[n].local_sa->sa_family)
 | 
			
		||||
| 
						 | 
				
			
			@ -1748,13 +1772,13 @@ set_engine_option (struct lsquic_engine_settings *settings,
 | 
			
		|||
                settings->es_versions = 0;
 | 
			
		||||
            }
 | 
			
		||||
            enum lsquic_version ver = lsquic_str2ver(val, strlen(val));
 | 
			
		||||
            if (ver < N_LSQVER)
 | 
			
		||||
            if ((unsigned) ver < N_LSQVER)
 | 
			
		||||
            {
 | 
			
		||||
                settings->es_versions |= 1 << ver;
 | 
			
		||||
                return 0;
 | 
			
		||||
            }
 | 
			
		||||
            ver = lsquic_alpn2ver(val, strlen(val));
 | 
			
		||||
            if (ver < N_LSQVER)
 | 
			
		||||
            if ((unsigned) ver < N_LSQVER)
 | 
			
		||||
            {
 | 
			
		||||
                settings->es_versions |= 1 << ver;
 | 
			
		||||
                return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -2207,3 +2231,22 @@ sport_set_token (struct service_port *sport, const char *token_str)
 | 
			
		|||
    sport->sp_token_sz = len / 2;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
header_set_ptr (struct lsxpack_header *hdr, struct header_buf *header_buf,
 | 
			
		||||
                const char *name, size_t name_len,
 | 
			
		||||
                const char *val, size_t val_len)
 | 
			
		||||
{
 | 
			
		||||
    if (header_buf->off + name_len + val_len <= sizeof(header_buf->buf))
 | 
			
		||||
    {
 | 
			
		||||
        memcpy(header_buf->buf + header_buf->off, name, name_len);
 | 
			
		||||
        memcpy(header_buf->buf + header_buf->off + name_len, val, val_len);
 | 
			
		||||
        lsxpack_header_set_offset2(hdr, header_buf->buf + header_buf->off,
 | 
			
		||||
                                            0, name_len, name_len, val_len);
 | 
			
		||||
        header_buf->off += name_len + val_len;
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
        return -1;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,6 +10,11 @@
 | 
			
		|||
#   include <net/if.h>  /* For IFNAMSIZ */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef WIN32
 | 
			
		||||
#include <winsock2.h>
 | 
			
		||||
#include <ws2tcpip.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
struct lsquic_engine;
 | 
			
		||||
struct lsquic_engine_settings;
 | 
			
		||||
struct lsquic_out_spec;
 | 
			
		||||
| 
						 | 
				
			
			@ -19,6 +24,19 @@ struct packets_in;
 | 
			
		|||
struct lsquic_conn;
 | 
			
		||||
struct prog;
 | 
			
		||||
struct reader_ctx;
 | 
			
		||||
struct lsxpack_header;
 | 
			
		||||
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
#   define SOCKOPT_VAL int
 | 
			
		||||
#   define SOCKET_TYPE int
 | 
			
		||||
#   define CLOSE_SOCKET close
 | 
			
		||||
#   define CHAR_CAST
 | 
			
		||||
#else
 | 
			
		||||
#   define SOCKOPT_VAL DWORD
 | 
			
		||||
#   define SOCKET_TYPE SOCKET
 | 
			
		||||
#   define CLOSE_SOCKET closesocket
 | 
			
		||||
#   define CHAR_CAST (char *)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
enum sport_flags
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -51,8 +69,8 @@ struct service_port {
 | 
			
		|||
    struct sockaddr_storage    sp_local_addr;
 | 
			
		||||
    struct packets_in         *packs_in;
 | 
			
		||||
    enum sport_flags           sp_flags;
 | 
			
		||||
    int                        sp_sndbuf;   /* If SPORT_SET_SNDBUF is set */
 | 
			
		||||
    int                        sp_rcvbuf;   /* If SPORT_SET_RCVBUF is set */
 | 
			
		||||
    SOCKOPT_VAL                sp_sndbuf;   /* If SPORT_SET_SNDBUF is set */
 | 
			
		||||
    SOCKOPT_VAL                sp_rcvbuf;   /* If SPORT_SET_RCVBUF is set */
 | 
			
		||||
    struct prog               *sp_prog;
 | 
			
		||||
    unsigned char             *sp_token_buf;
 | 
			
		||||
    size_t                     sp_token_sz;
 | 
			
		||||
| 
						 | 
				
			
			@ -125,4 +143,15 @@ destroy_lsquic_reader_ctx (struct reader_ctx *ctx);
 | 
			
		|||
#define LITESPEED_ID "lsquic" "/" TOSTRING(LSQUIC_MAJOR_VERSION) "." \
 | 
			
		||||
            TOSTRING(LSQUIC_MINOR_VERSION) "." TOSTRING(LSQUIC_PATCH_VERSION)
 | 
			
		||||
 | 
			
		||||
struct header_buf
 | 
			
		||||
{
 | 
			
		||||
    unsigned    off;
 | 
			
		||||
    char        buf[UINT16_MAX];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
header_set_ptr (struct lsxpack_header *hdr, struct header_buf *header_buf,
 | 
			
		||||
                const char *name, size_t name_len,
 | 
			
		||||
                const char *val, size_t val_len);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1527,7 +1527,9 @@ fields yourself.  In that case, the header set must be "read" from the stream vi
 | 
			
		|||
    .. member:: enum lsquic_hsi_flag hsi_flags
 | 
			
		||||
 | 
			
		||||
        These flags specify properties of decoded headers passed to
 | 
			
		||||
        ``hsi_process_header()``.
 | 
			
		||||
        ``hsi_process_header()``.  This is only applicable to QPACK headers;
 | 
			
		||||
        HPACK library header properties are based on compilation, not
 | 
			
		||||
        run-time, options.
 | 
			
		||||
 | 
			
		||||
.. function:: void * lsquic_stream_get_hset (lsquic_stream_t *stream)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,10 +4,8 @@ Getting Started
 | 
			
		|||
Supported Platforms
 | 
			
		||||
-------------------
 | 
			
		||||
 | 
			
		||||
LSQUIC compiles and runs on Linux, FreeBSD, Mac OS, and Android.  It has been
 | 
			
		||||
tested on i386, x86_64, and ARM (Raspberry Pi and Android).
 | 
			
		||||
 | 
			
		||||
Windows support is on the TODO list.
 | 
			
		||||
LSQUIC compiles and runs on Linux, Windows, FreeBSD, Mac OS, and Android.
 | 
			
		||||
It has been tested on i386, x86_64, and ARM (Raspberry Pi and Android).
 | 
			
		||||
 | 
			
		||||
Dependencies
 | 
			
		||||
------------
 | 
			
		||||
| 
						 | 
				
			
			@ -25,8 +23,8 @@ What's in the box
 | 
			
		|||
-----------------
 | 
			
		||||
 | 
			
		||||
- ``src/liblsquic`` -- the library
 | 
			
		||||
- ``test`` -- demo client and server programs
 | 
			
		||||
- ``test/unittests`` -- unit tests
 | 
			
		||||
- ``bin`` -- demo client and server programs
 | 
			
		||||
- ``tests`` -- unit tests
 | 
			
		||||
 | 
			
		||||
Building
 | 
			
		||||
--------
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -943,7 +943,9 @@ struct lsquic_hset_if
 | 
			
		|||
    void                (*hsi_discard_header_set)(void *hdr_set);
 | 
			
		||||
    /**
 | 
			
		||||
     * These flags specify properties of decoded headers passed to
 | 
			
		||||
     * hsi_process_header().
 | 
			
		||||
     * hsi_process_header().  This is only applicable to QPACK headers;
 | 
			
		||||
     * HPACK library header properties are based on compilation, not
 | 
			
		||||
     * run-time, options.
 | 
			
		||||
     */
 | 
			
		||||
    enum lsquic_hsi_flag hsi_flags;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc.  See LICENSE. */
 | 
			
		||||
#ifndef LSXPACK_HEADER_H_v205
 | 
			
		||||
#define LSXPACK_HEADER_H_v205
 | 
			
		||||
#ifndef LSXPACK_HEADER_H_v206
 | 
			
		||||
#define LSXPACK_HEADER_H_v206
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
| 
						 | 
				
			
			@ -26,7 +26,7 @@ typedef uint32_t lsxpack_strlen_t;
 | 
			
		|||
 | 
			
		||||
enum lsxpack_flag
 | 
			
		||||
{
 | 
			
		||||
    LSXPACK_HPACK_IDX = 1,
 | 
			
		||||
    LSXPACK_HPACK_VAL_MATCHED = 1,
 | 
			
		||||
    LSXPACK_QPACK_IDX = 2,
 | 
			
		||||
    LSXPACK_APP_IDX   = 4,
 | 
			
		||||
    LSXPACK_NAME_HASH = 8,
 | 
			
		||||
| 
						 | 
				
			
			@ -47,7 +47,6 @@ enum lsxpack_flag
 | 
			
		|||
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 */
 | 
			
		||||
| 
						 | 
				
			
			@ -74,7 +73,6 @@ lsxpack_header_set_idx(lsxpack_header_t *hdr, int hpack_idx,
 | 
			
		|||
    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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -94,21 +92,6 @@ lsxpack_header_set_qpack_idx(lsxpack_header_t *hdr, int qpack_idx,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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,
 | 
			
		||||
| 
						 | 
				
			
			@ -161,9 +144,7 @@ lsxpack_header_prepare_decode(lsxpack_header_t *hdr,
 | 
			
		|||
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;
 | 
			
		||||
    return (hdr->name_len)? hdr->buf + hdr->name_offset : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -179,10 +160,10 @@ static inline void
 | 
			
		|||
lsxpack_header_mark_val_changed(lsxpack_header_t *hdr)
 | 
			
		||||
{
 | 
			
		||||
    hdr->flags = (enum lsxpack_flag)(hdr->flags &
 | 
			
		||||
                ~(LSXPACK_VAL_MATCHED|LSXPACK_NAMEVAL_HASH));
 | 
			
		||||
       ~(LSXPACK_HPACK_VAL_MATCHED|LSXPACK_VAL_MATCHED|LSXPACK_NAMEVAL_HASH));
 | 
			
		||||
}
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif //LSXPACK_HEADER_H_v205
 | 
			
		||||
#endif //LSXPACK_HEADER_H_v206
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -79,7 +79,9 @@ SET(lsquic_STAT_SRCS
 | 
			
		|||
    lsquic_version.c
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
IF(NOT MSVC)
 | 
			
		||||
set_source_files_properties(ls-qpack/lsqpack.c PROPERTIES COMPILE_FLAGS -Wno-uninitialized)
 | 
			
		||||
ENDIF()
 | 
			
		||||
 | 
			
		||||
include_directories(ls-qpack)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -95,8 +97,8 @@ ENDIF()
 | 
			
		|||
 | 
			
		||||
ADD_CUSTOM_COMMAND(
 | 
			
		||||
    OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/lsquic_versions_to_string.c
 | 
			
		||||
    COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/gen-verstrs.pl
 | 
			
		||||
    ARGS ${CMAKE_CURRENT_SOURCE_DIR}/../../include/lsquic.h ${CMAKE_CURRENT_SOURCE_DIR}/lsquic_versions_to_string.c
 | 
			
		||||
    COMMAND ${PERL}
 | 
			
		||||
    ARGS ${CMAKE_CURRENT_SOURCE_DIR}/gen-verstrs.pl ${CMAKE_CURRENT_SOURCE_DIR}/../../include/lsquic.h ${CMAKE_CURRENT_SOURCE_DIR}/lsquic_versions_to_string.c
 | 
			
		||||
    DEPENDS ./gen-verstrs.pl ${CMAKE_CURRENT_SOURCE_DIR}/../../include/lsquic.h
 | 
			
		||||
)
 | 
			
		||||
SET(lsquic_STAT_SRCS ${lsquic_STAT_SRCS} lsquic_versions_to_string.c)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -180,7 +180,7 @@ init_bbr (struct lsquic_bbr *bbr)
 | 
			
		|||
    bbr->bbr_min_cwnd = kDefaultMinimumCongestionWindow;
 | 
			
		||||
    bbr->bbr_high_gain = kDefaultHighGain;
 | 
			
		||||
    bbr->bbr_high_cwnd_gain = kDefaultHighGain;
 | 
			
		||||
    bbr->bbr_drain_gain = 1.0 / kDefaultHighGain;
 | 
			
		||||
    bbr->bbr_drain_gain = 1.0f / kDefaultHighGain;
 | 
			
		||||
    bbr->bbr_pacing_rate = BW_ZERO();
 | 
			
		||||
    bbr->bbr_pacing_gain = 1.0;
 | 
			
		||||
    bbr->bbr_cwnd_gain = 1.0;
 | 
			
		||||
| 
						 | 
				
			
			@ -298,7 +298,7 @@ is_pipe_sufficiently_full (struct lsquic_bbr *bbr, uint64_t bytes_in_flight)
 | 
			
		|||
    else
 | 
			
		||||
        // If bytes_in_flight are above the target congestion window, it should
 | 
			
		||||
        // be possible to observe the same or more bandwidth if it's available.
 | 
			
		||||
        return bytes_in_flight >= get_target_cwnd(bbr, 1.1);
 | 
			
		||||
        return bytes_in_flight >= get_target_cwnd(bbr, 1.1f);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -79,11 +79,11 @@ bw_sampler_abort_conn (struct bw_sampler *sampler)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define BW_WARN_ONCE(msg...) do {                                           \
 | 
			
		||||
#define BW_WARN_ONCE(...) do {                                              \
 | 
			
		||||
    if (!(sampler->bws_flags & BWS_WARNED))                                 \
 | 
			
		||||
    {                                                                       \
 | 
			
		||||
        sampler->bws_flags |= BWS_WARNED;                                   \
 | 
			
		||||
        LSQ_WARN(msg);                                                      \
 | 
			
		||||
        LSQ_WARN(__VA_ARGS__);                                              \
 | 
			
		||||
    }                                                                       \
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1545,6 +1545,8 @@ get_peer_transport_params (struct enc_sess_iquic *enc_sess)
 | 
			
		|||
    }
 | 
			
		||||
    else if ((enc_sess->esi_flags & (ESI_RETRY|ESI_SERVER)) == ESI_RETRY)
 | 
			
		||||
        must_have = 1 << TPI_ORIGINAL_DEST_CID;
 | 
			
		||||
    else
 | 
			
		||||
        must_have = 0;
 | 
			
		||||
 | 
			
		||||
    enum transport_param_id tpi;
 | 
			
		||||
    for (tpi = FIRST_TP_CID; tpi <= LAST_TP_CID; ++tpi)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,6 +25,15 @@
 | 
			
		|||
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(WIN32) || defined(NDEBUG)
 | 
			
		||||
#define CAN_LOSE_PACKETS 0
 | 
			
		||||
#else
 | 
			
		||||
#define CAN_LOSE_PACKETS 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if CAN_LOSE_PACKETS
 | 
			
		||||
#include <regex.h>      /* For code that loses packets */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -208,7 +217,11 @@ struct lsquic_engine
 | 
			
		|||
                        = (1 <<  9),    /* Connections are hashed by address */
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
        ENG_COALESCE    = (1 << 24),    /* Packet coalescing is enabled */
 | 
			
		||||
#endif
 | 
			
		||||
#if CAN_LOSE_PACKETS
 | 
			
		||||
        ENG_LOSE_PACKETS= (1 << 25),    /* Lose *some* outgoing packets */
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
        ENG_DTOR        = (1 << 26),    /* Engine destructor */
 | 
			
		||||
#endif
 | 
			
		||||
    }                                  flags;
 | 
			
		||||
| 
						 | 
				
			
			@ -230,7 +243,7 @@ struct lsquic_engine
 | 
			
		|||
     * priority lower than that of existing connections.
 | 
			
		||||
     */
 | 
			
		||||
    lsquic_time_t                      last_sent;
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
#if CAN_LOSE_PACKETS
 | 
			
		||||
    regex_t                            lose_packets_re;
 | 
			
		||||
    const char                        *lose_packets_str;
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -639,6 +652,7 @@ lsquic_engine_new (unsigned flags,
 | 
			
		|||
    {
 | 
			
		||||
        const char *env;
 | 
			
		||||
        env = getenv("LSQUIC_LOSE_PACKETS_RE");
 | 
			
		||||
#if CAN_LOSE_PACKETS
 | 
			
		||||
        if (env)
 | 
			
		||||
        {
 | 
			
		||||
            if (0 != regcomp(&engine->lose_packets_re, env,
 | 
			
		||||
| 
						 | 
				
			
			@ -652,6 +666,7 @@ lsquic_engine_new (unsigned flags,
 | 
			
		|||
            LSQ_WARN("will lose packets that match the following regex: %s",
 | 
			
		||||
                                                                        env);
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
        env = getenv("LSQUIC_COALESCE");
 | 
			
		||||
        if (env)
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			@ -1439,7 +1454,7 @@ lsquic_engine_destroy (lsquic_engine_t *engine)
 | 
			
		|||
        lsquic_stock_shared_hash_destroy(engine->pub.enp_shi_ctx);
 | 
			
		||||
    lsquic_mm_cleanup(&engine->pub.enp_mm);
 | 
			
		||||
    free(engine->conns_tickable.mh_elems);
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
#if CAN_LOSE_PACKETS
 | 
			
		||||
    if (engine->flags & ENG_LOSE_PACKETS)
 | 
			
		||||
        regfree(&engine->lose_packets_re);
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -2037,7 +2052,7 @@ coi_reheap (struct conns_out_iter *iter, lsquic_engine_t *engine)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
#if CAN_LOSE_PACKETS
 | 
			
		||||
static void
 | 
			
		||||
lose_matching_packets (const lsquic_engine_t *engine, struct out_batch *batch,
 | 
			
		||||
                                                                    unsigned n)
 | 
			
		||||
| 
						 | 
				
			
			@ -2136,7 +2151,7 @@ send_batch (lsquic_engine_t *engine, const struct send_batch_ctx *sb_ctx,
 | 
			
		|||
    CONST_BATCH struct out_batch *const batch = sb_ctx->batch;
 | 
			
		||||
    struct lsquic_packet_out *CONST_BATCH *packet_out, *CONST_BATCH *end;
 | 
			
		||||
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
#if CAN_LOSE_PACKETS
 | 
			
		||||
    if (engine->flags & ENG_LOSE_PACKETS)
 | 
			
		||||
        lose_matching_packets(engine, batch, n_to_send);
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -2699,12 +2714,11 @@ lsquic_engine_packet_in (lsquic_engine_t *engine,
 | 
			
		|||
            parse_packet_in_begin = lsquic_Q050_parse_packet_in_begin;
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            assert(conn->cn_version == LSQVER_046
 | 
			
		||||
#if LSQUIC_USE_Q098
 | 
			
		||||
                   || conn->cn_version == LSQVER_098
 | 
			
		||||
            assert(conn->cn_version == LSQVER_046 || conn->cn_version == LSQVER_098);
 | 
			
		||||
#else
 | 
			
		||||
            assert(conn->cn_version == LSQVER_046);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
                                                    );
 | 
			
		||||
            parse_packet_in_begin = lsquic_Q046_parse_packet_in_begin;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -2714,6 +2728,11 @@ lsquic_engine_packet_in (lsquic_engine_t *engine,
 | 
			
		|||
    engine->curr_conn = NULL;
 | 
			
		||||
    n_zeroes = 0;
 | 
			
		||||
    is_ietf = 0;
 | 
			
		||||
#ifdef _MSC_VER
 | 
			
		||||
    s = 0;
 | 
			
		||||
    cid.len = 0;
 | 
			
		||||
    cid.idbuf[0] = 0;
 | 
			
		||||
#endif
 | 
			
		||||
    do
 | 
			
		||||
    {
 | 
			
		||||
        packet_in = lsquic_mm_get_packet_in(&engine->pub.enp_mm);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -528,15 +528,10 @@ lsquic_frame_writer_write_promise (struct lsquic_frame_writer *fw,
 | 
			
		|||
 | 
			
		||||
    free(buf);
 | 
			
		||||
 | 
			
		||||
    if (0 == s)
 | 
			
		||||
    {
 | 
			
		||||
        EV_LOG_GENERATED_HTTP_PUSH_PROMISE(LSQUIC_LOG_CONN_ID, stream_id,
 | 
			
		||||
                            htonl(promised_stream_id), headers);
 | 
			
		||||
        hfc_terminate_frame(&hfc, HFHF_END_HEADERS);
 | 
			
		||||
        return lsquic_frame_writer_flush(fw);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
        return -1;
 | 
			
		||||
    EV_LOG_GENERATED_HTTP_PUSH_PROMISE(LSQUIC_LOG_CONN_ID, stream_id,
 | 
			
		||||
                                        htonl(promised_stream_id), headers);
 | 
			
		||||
    hfc_terminate_frame(&hfc, HFHF_END_HEADERS);
 | 
			
		||||
    return lsquic_frame_writer_flush(fw);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7740,4 +7740,4 @@ static const struct lsquic_stream_if unicla_if =
 | 
			
		|||
 | 
			
		||||
static const struct lsquic_stream_if *unicla_if_ptr = &unicla_if;
 | 
			
		||||
 | 
			
		||||
typedef char dcid_elem_fits_in_128_bytes[(sizeof(struct dcid_elem) <= 128) - 1];
 | 
			
		||||
typedef char dcid_elem_fits_in_128_bytes[sizeof(struct dcid_elem) <= 128 ? 1 : - 1];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,9 +1,6 @@
 | 
			
		|||
/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc.  See LICENSE. */
 | 
			
		||||
#define _GNU_SOURCE         /* for memmem */
 | 
			
		||||
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <netdb.h>
 | 
			
		||||
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -11,6 +8,8 @@
 | 
			
		|||
#include <string.h>
 | 
			
		||||
#include <sys/queue.h>
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <netdb.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -126,12 +126,12 @@ lsquic_hcso_write_settings (struct hcso_writer *writer,
 | 
			
		|||
    unsigned bits;
 | 
			
		||||
    int was_empty;
 | 
			
		||||
#ifdef NDEBUG
 | 
			
		||||
    const unsigned frame_size_len = 1;
 | 
			
		||||
#   define frame_size_len 1
 | 
			
		||||
#else
 | 
			
		||||
    /* Need to use two bytes for frame length, as randomization may require
 | 
			
		||||
     * more than 63 bytes.
 | 
			
		||||
     */
 | 
			
		||||
    const unsigned frame_size_len = 2;
 | 
			
		||||
#   define frame_size_len 2
 | 
			
		||||
#endif
 | 
			
		||||
    unsigned char buf[1 /* Frame type */ + /* Frame size */ frame_size_len
 | 
			
		||||
        /* There are maximum three settings that need to be written out and
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -81,17 +81,8 @@ static lsquic_stream_ctx_t *
 | 
			
		|||
headers_on_new_stream (void *stream_if_ctx, lsquic_stream_t *stream)
 | 
			
		||||
{
 | 
			
		||||
    struct headers_stream *hs = stream_if_ctx;
 | 
			
		||||
    enum lshpack_dec_flags flags;
 | 
			
		||||
 | 
			
		||||
    flags = 0;
 | 
			
		||||
    if (hs->hs_enpub->enp_hsi_if->hsi_flags & LSQUIC_HSI_HTTP1X)
 | 
			
		||||
        flags |= LSHPACK_DEC_HTTP1X;
 | 
			
		||||
    if (hs->hs_enpub->enp_hsi_if->hsi_flags & LSQUIC_HSI_HASH_NAME)
 | 
			
		||||
        flags |= LSHPACK_DEC_HASH_NAME;
 | 
			
		||||
    if (hs->hs_enpub->enp_hsi_if->hsi_flags & LSQUIC_HSI_HASH_NAMEVAL)
 | 
			
		||||
        flags |= LSHPACK_DEC_HASH_NAMEVAL;
 | 
			
		||||
 | 
			
		||||
    lshpack_dec_init(&hs->hs_hdec, flags);
 | 
			
		||||
    lshpack_dec_init(&hs->hs_hdec);
 | 
			
		||||
    if (0 != lshpack_enc_init(&hs->hs_henc))
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_WARN("could not initialize HPACK encoder: %s", strerror(errno));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,7 +17,12 @@ lsquic_qhkdf_expand (const EVP_MD *md, const unsigned char *secret,
 | 
			
		|||
#ifndef NDEBUG
 | 
			
		||||
    int s;
 | 
			
		||||
#endif
 | 
			
		||||
    const size_t len = 2 + 1 + 6 + label_len + 1;
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
    unsigned char info[ 2 + 1 + 6 + label_len + 1];
 | 
			
		||||
#else
 | 
			
		||||
    unsigned char info[ 2 + 1 + 6 + UINT8_MAX + 1];
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    info[0] = out_len >> 8;
 | 
			
		||||
    info[1] = out_len;
 | 
			
		||||
| 
						 | 
				
			
			@ -35,6 +40,6 @@ lsquic_qhkdf_expand (const EVP_MD *md, const unsigned char *secret,
 | 
			
		|||
#else
 | 
			
		||||
    (void)
 | 
			
		||||
#endif
 | 
			
		||||
    HKDF_expand(out, out_len, md, secret, secret_len, info, sizeof(info));
 | 
			
		||||
    HKDF_expand(out, out_len, md, secret, secret_len, info, len);
 | 
			
		||||
    assert(s);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -527,17 +527,13 @@ h1h_prepare_decode (void *hset, struct lsxpack_header *xhdr, size_t req_space)
 | 
			
		|||
        if (0 == hwc->hwc_header_buf_nalloc
 | 
			
		||||
                                    || req_space > hwc->hwc_header_buf_nalloc)
 | 
			
		||||
        {
 | 
			
		||||
            if (req_space < 0x100)
 | 
			
		||||
                nalloc = 0x100;
 | 
			
		||||
            else
 | 
			
		||||
                nalloc = req_space;
 | 
			
		||||
            buf = malloc(nalloc);
 | 
			
		||||
            buf = malloc(req_space);
 | 
			
		||||
            if (!buf)
 | 
			
		||||
            {
 | 
			
		||||
                LSQ_DEBUG("cannot allocate %zd bytes", nalloc);
 | 
			
		||||
                LSQ_DEBUG("cannot allocate %zd bytes", req_space);
 | 
			
		||||
                return NULL;
 | 
			
		||||
            }
 | 
			
		||||
            hwc->hwc_header_buf_nalloc = nalloc;
 | 
			
		||||
            hwc->hwc_header_buf_nalloc = req_space;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
            buf = hwc->hwc_xhdr.buf;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,6 +24,7 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/queue.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
 | 
			
		||||
#include "lsquic.h"
 | 
			
		||||
#include "lsquic_int_types.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -95,7 +96,7 @@ process_deferred_packets (struct mini_conn *mc);
 | 
			
		|||
 | 
			
		||||
/* If this is not true, highest_bit_set() may be broken */
 | 
			
		||||
typedef char packno_set_is_unsigned_long[
 | 
			
		||||
        (sizeof(unsigned long long) == sizeof(mconn_packno_set_t)) - 1];
 | 
			
		||||
        sizeof(unsigned long long) == sizeof(mconn_packno_set_t) ? 1 : -1 ];
 | 
			
		||||
 | 
			
		||||
static unsigned
 | 
			
		||||
highest_bit_set (unsigned long long sz)
 | 
			
		||||
| 
						 | 
				
			
			@ -2030,7 +2031,10 @@ mini_conn_ci_destroy (struct lsquic_conn *lconn)
 | 
			
		|||
            (int) (sizeof(mc->mc_hist_buf) - hist_idx),
 | 
			
		||||
            mc->mc_hist_buf + hist_idx, (int) hist_idx, mc->mc_hist_buf);
 | 
			
		||||
#else
 | 
			
		||||
    LSQ_LOG(log_level, "destroyed.  Diagnostics: conn flags: 0x%X, "
 | 
			
		||||
    if (LSQ_LOG_ENABLED(log_level))
 | 
			
		||||
        lsquic_logger_log2(log_level, LSQUIC_LOGGER_MODULE,
 | 
			
		||||
                                   LSQUIC_LOG_CONN_ID,
 | 
			
		||||
        "destroyed.  Diagnostics: conn flags: 0x%X, "
 | 
			
		||||
        "mc flags: 0x%X, "
 | 
			
		||||
#if LSQUIC_RECORD_INORD_HIST
 | 
			
		||||
        "incoming-history (trunc: %d) %s, "
 | 
			
		||||
| 
						 | 
				
			
			@ -2235,8 +2239,8 @@ static const struct conn_iface mini_conn_iface_standard_Q050 = {
 | 
			
		|||
 | 
			
		||||
typedef char largest_recv_holds_at_least_16_seconds[
 | 
			
		||||
    ((1 << (sizeof(((struct mini_conn *) 0)->mc_largest_recv) * 8)) / 1000000
 | 
			
		||||
                                                                    >= 16) - 1];
 | 
			
		||||
                                                                    >= 16) ? 1 : -1];
 | 
			
		||||
 | 
			
		||||
typedef char max_lifespan_smaller_than_largest_recv[
 | 
			
		||||
    ((1 << (sizeof(((struct mini_conn *) 0)->mc_largest_recv) * 8)) >
 | 
			
		||||
                                           MAX_MINI_CONN_LIFESPAN_IN_USEC) - 1];
 | 
			
		||||
                                           MAX_MINI_CONN_LIFESPAN_IN_USEC) ? 1 : -1];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,10 @@
 | 
			
		|||
#ifndef LSQUIC_PARSE_COMMON_H
 | 
			
		||||
#define LSQUIC_PARSE_COMMON_H 1
 | 
			
		||||
 | 
			
		||||
#ifdef WIN32
 | 
			
		||||
#include "vc_compat.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
struct lsquic_packet_in;
 | 
			
		||||
struct packin_parse_state;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -160,7 +160,7 @@ static const unsigned char simple_prst_payload[] = {
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
typedef char correct_simple_prst_size[(GQUIC_RESET_SZ ==
 | 
			
		||||
                1 + GQUIC_CID_LEN + sizeof(simple_prst_payload)) - 1];
 | 
			
		||||
                1 + GQUIC_CID_LEN + sizeof(simple_prst_payload)) ? 1 : -1 ];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ssize_t
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -353,6 +353,10 @@ ietf_v1_gen_stream_frame (unsigned char *buf, size_t buf_len,
 | 
			
		|||
    unsigned slen, olen, dlen;
 | 
			
		||||
    unsigned char *p = buf + 1;
 | 
			
		||||
 | 
			
		||||
#if _MSC_VER
 | 
			
		||||
    obits = 0, dbits = 0;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    assert(!!fin ^ !!size);
 | 
			
		||||
 | 
			
		||||
    /* We do not check that stream_id, offset, and size are smaller
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,11 +6,14 @@
 | 
			
		|||
#include <assert.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/queue.h>
 | 
			
		||||
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <openssl/aead.h>
 | 
			
		||||
#include <openssl/rand.h>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,6 +10,10 @@
 | 
			
		|||
#include <string.h>
 | 
			
		||||
#include <sys/queue.h>
 | 
			
		||||
 | 
			
		||||
#ifdef WIN32
 | 
			
		||||
#include <malloc.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "lsquic.h"
 | 
			
		||||
#include "lsquic_types.h"
 | 
			
		||||
#include "lsquic_int_types.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -333,13 +337,22 @@ qeh_write_headers (struct qpack_enc_hdl *qeh, lsquic_stream_id_t stream_id,
 | 
			
		|||
    enum lsqpack_enc_status st;
 | 
			
		||||
    int i, s, write_to_stream;
 | 
			
		||||
    enum lsqpack_enc_flags enc_flags;
 | 
			
		||||
    enum qwh_status retval;
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
    unsigned char enc_buf[ qeh->qeh_encoder.qpe_cur_max_capacity * 2 ];
 | 
			
		||||
#else
 | 
			
		||||
    unsigned char *enc_buf;
 | 
			
		||||
    enc_buf = _malloca(qeh->qeh_encoder.qpe_cur_max_capacity * 2);
 | 
			
		||||
    if (!enc_buf)
 | 
			
		||||
        return QWH_ERR;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    s = lsqpack_enc_start_header(&qeh->qeh_encoder, stream_id, 0);
 | 
			
		||||
    if (s != 0)
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_WARN("cannot start header");
 | 
			
		||||
        return QWH_ERR;
 | 
			
		||||
        retval = QWH_ERR;
 | 
			
		||||
        goto end;
 | 
			
		||||
    }
 | 
			
		||||
    LSQ_DEBUG("begin encoding headers for stream %"PRIu64, stream_id);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -384,7 +397,8 @@ qeh_write_headers (struct qpack_enc_hdl *qeh, lsquic_stream_id_t stream_id,
 | 
			
		|||
                    {
 | 
			
		||||
                        LSQ_INFO("could not write to encoder stream: %s",
 | 
			
		||||
                                                                strerror(errno));
 | 
			
		||||
                        return QWH_ERR;
 | 
			
		||||
                        retval = QWH_ERR;
 | 
			
		||||
                        goto end;
 | 
			
		||||
                    }
 | 
			
		||||
                    write_to_stream = 0;
 | 
			
		||||
                    enc_p = enc_buf + (size_t) nw;
 | 
			
		||||
| 
						 | 
				
			
			@ -395,18 +409,22 @@ qeh_write_headers (struct qpack_enc_hdl *qeh, lsquic_stream_id_t stream_id,
 | 
			
		|||
                if (0 != lsquic_frab_list_write(&qeh->qeh_fral, enc_p, enc_sz))
 | 
			
		||||
                {
 | 
			
		||||
                    LSQ_INFO("could not write to frab list");
 | 
			
		||||
                    return QWH_ERR;
 | 
			
		||||
                    retval = QWH_ERR;
 | 
			
		||||
                    goto end;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case LQES_NOBUF_HEAD:
 | 
			
		||||
            return QWH_ENOBUF;
 | 
			
		||||
            retval = QWH_ENOBUF;
 | 
			
		||||
            goto end;
 | 
			
		||||
        default:
 | 
			
		||||
            assert(0);
 | 
			
		||||
            return QWH_ERR;
 | 
			
		||||
            retval = QWH_ERR;
 | 
			
		||||
            goto end;
 | 
			
		||||
        case LQES_NOBUF_ENC:
 | 
			
		||||
            LSQ_DEBUG("not enough room to write encoder stream data");
 | 
			
		||||
            return QWH_ERR;
 | 
			
		||||
            retval = QWH_ERR;
 | 
			
		||||
            goto end;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -415,7 +433,8 @@ qeh_write_headers (struct qpack_enc_hdl *qeh, lsquic_stream_id_t stream_id,
 | 
			
		|||
    if (nw <= 0)
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_WARN("could not end header: %zd", nw);
 | 
			
		||||
        return QWH_ERR;
 | 
			
		||||
        retval = QWH_ERR;
 | 
			
		||||
        goto end;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((size_t) nw < *prefix_sz)
 | 
			
		||||
| 
						 | 
				
			
			@ -429,7 +448,8 @@ qeh_write_headers (struct qpack_enc_hdl *qeh, lsquic_stream_id_t stream_id,
 | 
			
		|||
        LSQ_DEBUG("all %zd bytes of encoder stream written out; header block "
 | 
			
		||||
            "is %zd bytes; estimated compression ratio %.3f", total_enc_sz,
 | 
			
		||||
            *headers_sz, lsqpack_enc_ratio(&qeh->qeh_encoder));
 | 
			
		||||
        return QWH_FULL;
 | 
			
		||||
        retval = QWH_FULL;
 | 
			
		||||
        goto end;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -439,8 +459,15 @@ qeh_write_headers (struct qpack_enc_hdl *qeh, lsquic_stream_id_t stream_id,
 | 
			
		|||
            "buffered; header block is %zd bytes; estimated compression ratio "
 | 
			
		||||
            "%.3f", total_enc_sz, lsquic_frab_list_size(&qeh->qeh_fral),
 | 
			
		||||
            *headers_sz, lsqpack_enc_ratio(&qeh->qeh_encoder));
 | 
			
		||||
        return QWH_PARTIAL;
 | 
			
		||||
        retval = QWH_PARTIAL;
 | 
			
		||||
        goto end;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  end:
 | 
			
		||||
#ifdef WIN32
 | 
			
		||||
    _freea(enc_buf);
 | 
			
		||||
#endif
 | 
			
		||||
    return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1542,6 +1542,9 @@ lsquic_send_ctl_do_sanity_check (const struct lsquic_send_ctl *ctl)
 | 
			
		|||
    unsigned count, bytes;
 | 
			
		||||
    enum packnum_space pns;
 | 
			
		||||
 | 
			
		||||
#if _MSC_VER
 | 
			
		||||
    prev_packno = 0;
 | 
			
		||||
#endif
 | 
			
		||||
    count = 0, bytes = 0;
 | 
			
		||||
    for (pns = PNS_INIT; pns <= PNS_APP; ++pns)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,10 +12,13 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/queue.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <netdb.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
#include <netdb.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "lsquic_int_types.h"
 | 
			
		||||
#include "lsquic.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -205,4 +205,4 @@ const struct lsquic_shared_hash_if stock_shi =
 | 
			
		|||
 | 
			
		||||
/* Need this to save one malloc using malo: */
 | 
			
		||||
typedef char hash_not_larger_than_hash_elem [
 | 
			
		||||
            (sizeof(struct stock_shared_hash) <= sizeof(struct hash_elem)) - 1];
 | 
			
		||||
            (sizeof(struct stock_shared_hash) <= sizeof(struct hash_elem)) ? 1 : -1];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,6 +26,10 @@
 | 
			
		|||
#include <sys/queue.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
 | 
			
		||||
#ifdef WIN32
 | 
			
		||||
#include <malloc.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "fiu-local.h"
 | 
			
		||||
 | 
			
		||||
#include "lsquic.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -3173,6 +3177,10 @@ update_buffered_hq_frames (struct lsquic_stream *stream, size_t len,
 | 
			
		|||
    uint64_t cur_off, end;
 | 
			
		||||
    size_t frame_sz;
 | 
			
		||||
    unsigned extendable;
 | 
			
		||||
#if _MSC_VER
 | 
			
		||||
    end = 0;
 | 
			
		||||
    extendable = 0;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    cur_off = stream->sm_payload + stream->sm_n_buffered;
 | 
			
		||||
    STAILQ_FOREACH(shf, &stream->sm_hq_frames, shf_next)
 | 
			
		||||
| 
						 | 
				
			
			@ -3437,7 +3445,15 @@ send_headers_ietf (struct lsquic_stream *stream,
 | 
			
		|||
    ssize_t nw;
 | 
			
		||||
    unsigned char *header_block;
 | 
			
		||||
    enum lsqpack_enc_header_flags hflags;
 | 
			
		||||
    unsigned char buf[max_push_size + max_prefix_size + MAX_HEADERS_SIZE];
 | 
			
		||||
    int rv;
 | 
			
		||||
    const size_t buf_sz = max_push_size + max_prefix_size + MAX_HEADERS_SIZE;
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
    unsigned char buf[buf_sz];
 | 
			
		||||
#else
 | 
			
		||||
    unsigned char *buf = _malloca(buf_sz);
 | 
			
		||||
    if (!buf)
 | 
			
		||||
        return -1;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    stream->stream_flags &= ~STREAM_PUSHING;
 | 
			
		||||
    stream->stream_flags |= STREAM_NOPUSH;
 | 
			
		||||
| 
						 | 
				
			
			@ -3446,7 +3462,7 @@ send_headers_ietf (struct lsquic_stream *stream,
 | 
			
		|||
     * back to a larger buffer if that fails.
 | 
			
		||||
     */
 | 
			
		||||
    prefix_sz = max_prefix_size;
 | 
			
		||||
    headers_sz = sizeof(buf) - max_prefix_size - max_push_size;
 | 
			
		||||
    headers_sz = buf_sz - max_prefix_size - max_push_size;
 | 
			
		||||
    qwh = lsquic_qeh_write_headers(stream->conn_pub->u.ietf.qeh, stream->id, 0,
 | 
			
		||||
                headers, buf + max_push_size + max_prefix_size, &prefix_sz,
 | 
			
		||||
                &headers_sz, &stream->sm_hb_compl, &hflags);
 | 
			
		||||
| 
						 | 
				
			
			@ -3457,7 +3473,7 @@ send_headers_ietf (struct lsquic_stream *stream,
 | 
			
		|||
            LSQ_INFO("not enough room for header block");
 | 
			
		||||
        else
 | 
			
		||||
            LSQ_WARN("internal error encoding and sending HTTP headers");
 | 
			
		||||
        return -1;
 | 
			
		||||
        goto err;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (hflags & LSQECH_REF_NEW_ENTRIES)
 | 
			
		||||
| 
						 | 
				
			
			@ -3471,7 +3487,7 @@ send_headers_ietf (struct lsquic_stream *stream,
 | 
			
		|||
        if (!stream_activate_hq_frame(stream,
 | 
			
		||||
                stream->sm_payload + stream->sm_n_buffered, HQFT_PUSH_PREAMBLE,
 | 
			
		||||
                SHF_FIXED_SIZE|SHF_PHANTOM, push_sz))
 | 
			
		||||
            return -1;
 | 
			
		||||
            goto err;
 | 
			
		||||
        buf[max_push_size + max_prefix_size - prefix_sz - push_sz] = HQUST_PUSH;
 | 
			
		||||
        vint_write(buf + max_push_size + max_prefix_size - prefix_sz
 | 
			
		||||
                    - push_sz + 1,stream->sm_promise->pp_id, bits, 1 << bits);
 | 
			
		||||
| 
						 | 
				
			
			@ -3485,7 +3501,7 @@ send_headers_ietf (struct lsquic_stream *stream,
 | 
			
		|||
    if (!stream_activate_hq_frame(stream,
 | 
			
		||||
                stream->sm_payload + stream->sm_n_buffered + push_sz,
 | 
			
		||||
                HQFT_HEADERS, SHF_FIXED_SIZE, hblock_sz - push_sz))
 | 
			
		||||
        return -1;
 | 
			
		||||
        goto err;
 | 
			
		||||
 | 
			
		||||
    if (qwh == QWH_FULL)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -3496,14 +3512,14 @@ send_headers_ietf (struct lsquic_stream *stream,
 | 
			
		|||
            if (nw < 0)
 | 
			
		||||
            {
 | 
			
		||||
                LSQ_WARN("cannot write to stream: %s", strerror(errno));
 | 
			
		||||
                return -1;
 | 
			
		||||
                goto err;
 | 
			
		||||
            }
 | 
			
		||||
            if ((size_t) nw == hblock_sz)
 | 
			
		||||
            {
 | 
			
		||||
                stream->stream_flags |= STREAM_HEADERS_SENT;
 | 
			
		||||
                stream_hblock_sent(stream);
 | 
			
		||||
                LSQ_DEBUG("wrote all %zu bytes of header block", hblock_sz);
 | 
			
		||||
                return 0;
 | 
			
		||||
                goto end;
 | 
			
		||||
            }
 | 
			
		||||
            LSQ_DEBUG("wrote only %zd bytes of header block, stash", nw);
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -3528,14 +3544,25 @@ send_headers_ietf (struct lsquic_stream *stream,
 | 
			
		|||
    {
 | 
			
		||||
        LSQ_WARN("cannot allocate %zd bytes to stash %s header block",
 | 
			
		||||
            hblock_sz - (size_t) nw, qwh == QWH_FULL ? "full" : "partial");
 | 
			
		||||
        return -1;
 | 
			
		||||
        goto err;
 | 
			
		||||
    }
 | 
			
		||||
    memcpy(stream->sm_header_block, header_block + (size_t) nw,
 | 
			
		||||
                                                hblock_sz - (size_t) nw);
 | 
			
		||||
    stream->sm_hblock_sz = hblock_sz - (size_t) nw;
 | 
			
		||||
    stream->sm_hblock_off = 0;
 | 
			
		||||
    LSQ_DEBUG("stashed %u bytes of header block", stream->sm_hblock_sz);
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
  end:
 | 
			
		||||
    rv = 0;
 | 
			
		||||
  clean:
 | 
			
		||||
#ifdef WIN32
 | 
			
		||||
    _freea(buf);
 | 
			
		||||
#endif
 | 
			
		||||
    return rv;
 | 
			
		||||
 | 
			
		||||
  err:
 | 
			
		||||
    rv = -1;
 | 
			
		||||
    goto clean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -4560,7 +4587,7 @@ pp_reader_read (void *lsqr_ctx, void *buf, size_t count)
 | 
			
		|||
{
 | 
			
		||||
    struct push_promise *const promise = lsqr_ctx;
 | 
			
		||||
    unsigned char *dst = buf;
 | 
			
		||||
    unsigned char *const end = buf + count;
 | 
			
		||||
    unsigned char *const end = dst + count;
 | 
			
		||||
    size_t len;
 | 
			
		||||
 | 
			
		||||
    while (dst < end)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,13 +1,16 @@
 | 
			
		|||
/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc.  See LICENSE. */
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/queue.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <openssl/aead.h>
 | 
			
		||||
#include <openssl/hkdf.h>
 | 
			
		||||
#include <openssl/rand.h>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,8 +11,13 @@
 | 
			
		|||
#include <stdint.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
#include <arpa/inet.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#else
 | 
			
		||||
#include "vc_compat.h"
 | 
			
		||||
#include "Ws2tcpip.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "lsquic_byteswap.h"
 | 
			
		||||
#include "lsquic_int_types.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -141,10 +141,10 @@ struct transport_params
 | 
			
		|||
 | 
			
		||||
int
 | 
			
		||||
lsquic_tp_encode (const struct transport_params *, int is_server,
 | 
			
		||||
                  unsigned char *buf, size_t bufsz);
 | 
			
		||||
                  unsigned char *const buf, size_t bufsz);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
lsquic_tp_decode (const unsigned char *buf, size_t bufsz,
 | 
			
		||||
lsquic_tp_decode (const unsigned char *const buf, size_t bufsz,
 | 
			
		||||
    /* This argument specifies whose transport parameters we are parsing.  If
 | 
			
		||||
     * true, we are parsing parameters sent by the server; if false, we are
 | 
			
		||||
     * parsing parameteres sent by the client.
 | 
			
		||||
| 
						 | 
				
			
			@ -157,10 +157,10 @@ lsquic_tp_to_str (const struct transport_params *params, char *buf, size_t sz);
 | 
			
		|||
 | 
			
		||||
int
 | 
			
		||||
lsquic_tp_encode_27 (const struct transport_params *, int is_server,
 | 
			
		||||
                  unsigned char *buf, size_t bufsz);
 | 
			
		||||
                  unsigned char *const buf, size_t bufsz);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
lsquic_tp_decode_27 (const unsigned char *buf, size_t bufsz,
 | 
			
		||||
lsquic_tp_decode_27 (const unsigned char *const buf, size_t bufsz,
 | 
			
		||||
                  int is_server,
 | 
			
		||||
                  struct transport_params *);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,14 +9,15 @@
 | 
			
		|||
#include <string.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <arpa/inet.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#else
 | 
			
		||||
#include <vc_compat.h>
 | 
			
		||||
#include <ws2tcpip.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <arpa/inet.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
 | 
			
		||||
#if !(defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0) && defined(__APPLE__)
 | 
			
		||||
#include <mach/mach_time.h>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,10 @@
 | 
			
		|||
#include "lsquic_int_types.h"
 | 
			
		||||
#include "lsquic_version.h"
 | 
			
		||||
 | 
			
		||||
#if _MSC_VER
 | 
			
		||||
#include "vc_compat.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static const unsigned char version_tags[N_LSQVER][4] =
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,7 +45,6 @@ SET(TESTS
 | 
			
		|||
    frame_writer
 | 
			
		||||
    goaway_gquic_be
 | 
			
		||||
    h3_framing
 | 
			
		||||
    hcsi_reader
 | 
			
		||||
    hkdf
 | 
			
		||||
    lsquic_hash
 | 
			
		||||
    packet_out
 | 
			
		||||
| 
						 | 
				
			
			@ -82,6 +81,8 @@ ENDIF()
 | 
			
		|||
IF (NOT CMAKE_SYSTEM_NAME STREQUAL "Windows")
 | 
			
		||||
    # No regexes on Windows
 | 
			
		||||
    SET(TESTS ${TESTS} ack_merge)
 | 
			
		||||
    # No open_memstream() on Windows
 | 
			
		||||
    SET(TESTS ${TESTS} hcsi_reader)
 | 
			
		||||
ENDIF()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -98,21 +99,27 @@ ADD_TEST(stream_hash test_stream -h)
 | 
			
		|||
ADD_TEST(stream_A test_stream -A)
 | 
			
		||||
ADD_TEST(stream_hash_A test_stream -A -h)
 | 
			
		||||
 | 
			
		||||
IF(NOT MSVC)
 | 
			
		||||
ADD_EXECUTABLE(graph_cubic graph_cubic.c ${ADDL_SOURCES})
 | 
			
		||||
TARGET_LINK_LIBRARIES(graph_cubic ${LIBS})
 | 
			
		||||
 | 
			
		||||
ADD_EXECUTABLE(mini_parse mini_parse.c ${ADDL_SOURCES})
 | 
			
		||||
TARGET_LINK_LIBRARIES(mini_parse ${LIBS})
 | 
			
		||||
ENDIF()
 | 
			
		||||
 | 
			
		||||
ADD_EXECUTABLE(test_min_heap test_min_heap.c ../src/liblsquic/lsquic_min_heap.c)
 | 
			
		||||
ADD_TEST(min_heap test_min_heap)
 | 
			
		||||
 | 
			
		||||
ADD_EXECUTABLE(test_malo_pooled test_malo.c ../src/liblsquic/lsquic_malo.c)
 | 
			
		||||
SET(MALO_SRC test_malo.c ../src/liblsquic/lsquic_malo.c)
 | 
			
		||||
IF(MSVC)
 | 
			
		||||
    LIST(APPEND MALO_SRC ../wincompat/getopt.c)
 | 
			
		||||
ENDIF()
 | 
			
		||||
ADD_EXECUTABLE(test_malo_pooled ${MALO_SRC})
 | 
			
		||||
SET_TARGET_PROPERTIES(test_malo_pooled
 | 
			
		||||
    PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLSQUIC_USE_POOLS=1")
 | 
			
		||||
ADD_TEST(malo_pooled test_malo_pooled)
 | 
			
		||||
 | 
			
		||||
ADD_EXECUTABLE(test_malo_nopool test_malo.c ../src/liblsquic/lsquic_malo.c)
 | 
			
		||||
ADD_EXECUTABLE(test_malo_nopool ${MALO_SRC})
 | 
			
		||||
SET_TARGET_PROPERTIES(test_malo_nopool
 | 
			
		||||
    PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLSQUIC_USE_POOLS=0")
 | 
			
		||||
ADD_TEST(malo_nopool test_malo_nopool)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,12 +10,16 @@
 | 
			
		|||
#include <stdint.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#else
 | 
			
		||||
#include "getopt.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <sys/queue.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
 | 
			
		||||
#include "lsquic.h"
 | 
			
		||||
#include "lsquic_types.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,6 +9,10 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#ifdef WIN32
 | 
			
		||||
#include "vc_compat.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "lsquic_types.h"
 | 
			
		||||
#include "lsquic_int_types.h"
 | 
			
		||||
#include "lsquic_rechist.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,8 @@
 | 
			
		|||
#include <string.h>
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#else
 | 
			
		||||
#include "vc_compat.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "lsquic_types.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,8 @@
 | 
			
		|||
#include <string.h>
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#else
 | 
			
		||||
#include "vc_compat.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "lsquic_types.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -105,7 +105,8 @@ main (void)
 | 
			
		|||
        unsigned const count = popcount(i);
 | 
			
		||||
        unsigned const min_n = i % count;
 | 
			
		||||
        unsigned const min_t = t++;
 | 
			
		||||
        unsigned j, n, ids[2];
 | 
			
		||||
        unsigned j, n;
 | 
			
		||||
        enum alarm_id ids[2];
 | 
			
		||||
        for (j = 0, n = 0; j < MAX_LSQUIC_ALARMS; ++j)
 | 
			
		||||
        {
 | 
			
		||||
            if ((1u << j) & i)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -115,6 +115,9 @@ test_attq_ordering (enum sort_action sa)
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef _MSC_VER
 | 
			
		||||
    prev = 0;
 | 
			
		||||
#endif
 | 
			
		||||
    for (i = 0; i < sizeof(curiosity); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        next_attq = lsquic_attq_next(q);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,7 +38,7 @@ test_post_quiescence_explosion (void)
 | 
			
		|||
    struct lsquic_conn lconn = LSCONN_INITIALIZER_CIDLEN(lconn, 8);
 | 
			
		||||
    struct lsquic_conn_public conn_pub = { .lconn = &lconn, };
 | 
			
		||||
    int i;
 | 
			
		||||
    struct lsquic_packet_out packet_out = {};
 | 
			
		||||
    struct lsquic_packet_out packet_out; memset(&packet_out, 0, sizeof(packet_out));
 | 
			
		||||
 | 
			
		||||
    cci->cci_init(&cubic, &conn_pub, 0);
 | 
			
		||||
    cubic.cu_ssthresh = cubic.cu_cwnd = 32 * 1370;
 | 
			
		||||
| 
						 | 
				
			
			@ -72,7 +72,7 @@ test_post_quiescence_explosion2 (void)
 | 
			
		|||
    struct lsquic_conn lconn = LSCONN_INITIALIZER_CIDLEN(lconn, 8);
 | 
			
		||||
    struct lsquic_conn_public conn_pub = { .lconn = &lconn, };
 | 
			
		||||
    int i;
 | 
			
		||||
    struct lsquic_packet_out packet_out = {};
 | 
			
		||||
    struct lsquic_packet_out packet_out; memset(&packet_out, 0, sizeof(packet_out));
 | 
			
		||||
 | 
			
		||||
    cci->cci_init(&cubic, &conn_pub, 0);
 | 
			
		||||
    cubic.cu_ssthresh = cubic.cu_cwnd = 32 * 1370;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -442,6 +442,8 @@ run_ekt_test (const struct export_key_test *test)
 | 
			
		|||
 | 
			
		||||
    for (i = 0; i < 2; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        if (i && !(test->ekt_ikm_sz == 32 && test->ekt_client_key_sz == 16 && test->ekt_server_key_sz == 16))
 | 
			
		||||
            continue;
 | 
			
		||||
        s = lsquic_export_key_material(test->ekt_ikm,       (uint32_t)test->ekt_ikm_sz,
 | 
			
		||||
                                test->ekt_salt,             (int)test->ekt_salt_sz,
 | 
			
		||||
                                test->ekt_context,          (uint32_t)test->ekt_context_sz,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -94,7 +94,7 @@ stream_write (struct lsquic_stream *stream, struct lsquic_reader *reader)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define XHDR(name_, value_) .buf = value_, .name_ptr = name_, .val_len = sizeof(value_) - 1, .name_len = sizeof(name_) - 1
 | 
			
		||||
#define XHDR(name_, value_) .buf = name_ value_, .name_offset = 0, .name_len = sizeof(name_) - 1, .val_offset = sizeof(name_) - 1, .val_len = sizeof(value_) - 1,
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1136,7 +1136,7 @@ test_one_frt (const struct frame_reader_test *frt)
 | 
			
		|||
 | 
			
		||||
  top:
 | 
			
		||||
    lsquic_mm_init(&mm);
 | 
			
		||||
    lshpack_dec_init(&hdec, LSHPACK_DEC_HTTP1X);
 | 
			
		||||
    lshpack_dec_init(&hdec);
 | 
			
		||||
    memset(&input, 0, sizeof(input));
 | 
			
		||||
    memcpy(input.in_buf, frt->frt_buf, frt->frt_bufsz);
 | 
			
		||||
    input.in_sz  = frt->frt_bufsz;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -225,7 +225,7 @@ test_rw (unsigned max_frame_sz)
 | 
			
		|||
 | 
			
		||||
    lsquic_mm_init(&mm);
 | 
			
		||||
    lshpack_enc_init(&henc);
 | 
			
		||||
    lshpack_dec_init(&hdec, LSHPACK_DEC_HTTP1X);
 | 
			
		||||
    lshpack_dec_init(&hdec);
 | 
			
		||||
    stream = stream_new();
 | 
			
		||||
    stream->sm_max_sz = 1;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -340,7 +340,7 @@ main (int argc, char **argv)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define XHDR(name_, value_) .buf = value_, .name_ptr = name_, .val_len = sizeof(value_) - 1, .name_len = sizeof(name_) - 1
 | 
			
		||||
#define XHDR(name_, value_) .buf = name_ value_, .name_offset = 0, .name_len = sizeof(name_) - 1, .val_offset = sizeof(name_) - 1, .val_len = sizeof(value_) - 1,
 | 
			
		||||
 | 
			
		||||
/* This list is hardcoded to make the test deterministic */
 | 
			
		||||
static struct lsxpack_header header_arr[N_HEADERS] =
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -63,7 +63,7 @@ output_write (struct lsquic_stream *stream, struct lsquic_reader *reader)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
#define IOV(v) { .iov_base = (v), .iov_len = sizeof(v) - 1, }
 | 
			
		||||
#define XHDR(name_, value_) .buf = value_, .name_ptr = name_, .val_len = sizeof(value_) - 1, .name_len = sizeof(name_) - 1
 | 
			
		||||
#define XHDR(name_, value_) .buf = name_ value_, .name_offset = 0, .name_len = sizeof(name_) - 1, .val_offset = sizeof(name_) - 1, .val_len = sizeof(value_) - 1,
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
| 
						 | 
				
			
			@ -162,6 +162,31 @@ test_one_header (void)
 | 
			
		|||
    lsquic_mm_cleanup(&mm);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct header_buf
 | 
			
		||||
{
 | 
			
		||||
    unsigned    off;
 | 
			
		||||
    char        buf[UINT16_MAX];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
header_set_ptr (struct lsxpack_header *hdr, struct header_buf *header_buf,
 | 
			
		||||
                const char *name, size_t name_len,
 | 
			
		||||
                const char *val, size_t val_len)
 | 
			
		||||
{
 | 
			
		||||
    if (header_buf->off + name_len + val_len <= sizeof(header_buf->buf))
 | 
			
		||||
    {
 | 
			
		||||
        memcpy(header_buf->buf + header_buf->off, name, name_len);
 | 
			
		||||
        memcpy(header_buf->buf + header_buf->off + name_len, val, val_len);
 | 
			
		||||
        lsxpack_header_set_offset2(hdr, header_buf->buf + header_buf->off,
 | 
			
		||||
                                            0, name_len, name_len, val_len);
 | 
			
		||||
        header_buf->off += name_len + val_len;
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
        return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
test_oversize_header (void)
 | 
			
		||||
| 
						 | 
				
			
			@ -172,6 +197,7 @@ test_oversize_header (void)
 | 
			
		|||
    struct lsquic_mm mm;
 | 
			
		||||
    const size_t big_len = LSXPACK_MAX_STRLEN - 20;
 | 
			
		||||
    char *value;
 | 
			
		||||
    struct header_buf hbuf;
 | 
			
		||||
 | 
			
		||||
    lshpack_enc_init(&henc);
 | 
			
		||||
    lsquic_mm_init(&mm);
 | 
			
		||||
| 
						 | 
				
			
			@ -190,8 +216,9 @@ test_oversize_header (void)
 | 
			
		|||
    {
 | 
			
		||||
        { XHDR(":status", "302") },
 | 
			
		||||
    };
 | 
			
		||||
    lsxpack_header_set_ptr(&header_arr[1], "some-header", 10, value, big_len);
 | 
			
		||||
    lsxpack_header_set_ptr(&header_arr[2], "another-header", 10, value, big_len);
 | 
			
		||||
    hbuf.off = 0;
 | 
			
		||||
    header_set_ptr(&header_arr[1], &hbuf, "some-header", 10, value, big_len);
 | 
			
		||||
    header_set_ptr(&header_arr[2], &hbuf, "another-header", 10, value, big_len);
 | 
			
		||||
 | 
			
		||||
    struct lsquic_http_headers headers = {
 | 
			
		||||
        .count = sizeof(header_arr) / sizeof(header_arr[0]),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -493,6 +493,8 @@ static const struct lsquic_stream_if packetization_inside_many_stream_if = {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define XHDR(name_, value_) .buf = name_ value_, .name_offset = 0, .name_len = sizeof(name_) - 1, .val_offset = sizeof(name_) - 1, .val_len = sizeof(value_) - 1,
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
test_hq_framing (int sched_immed, int dispatch_once, unsigned wsize,
 | 
			
		||||
                    int flush_after_each_write, size_t conn_limit,
 | 
			
		||||
| 
						 | 
				
			
			@ -509,8 +511,7 @@ test_hq_framing (int sched_immed, int dispatch_once, unsigned wsize,
 | 
			
		|||
     * data-framing writer.  This is simply so that we don't have to
 | 
			
		||||
     * expose more stream things only for testing.
 | 
			
		||||
     */
 | 
			
		||||
    struct lsxpack_header header;
 | 
			
		||||
    lsxpack_header_set_ptr(&header, ":method", 7, "GET", 3);
 | 
			
		||||
    struct lsxpack_header header = { XHDR(":method", "GET") };
 | 
			
		||||
    struct lsquic_http_headers headers = { 1, &header, };
 | 
			
		||||
 | 
			
		||||
    buf_in = malloc(buf_in_sz);
 | 
			
		||||
| 
						 | 
				
			
			@ -739,8 +740,7 @@ test_frame_header_split (unsigned n_packets, unsigned extra_sz,
 | 
			
		|||
    const unsigned wsize = 70;
 | 
			
		||||
    const size_t buf_in_sz = wsize, buf_out_sz = 0x500000;
 | 
			
		||||
 | 
			
		||||
    struct lsxpack_header header;
 | 
			
		||||
    lsxpack_header_set_ptr(&header, ":method", 7, "GET", 3);
 | 
			
		||||
    struct lsxpack_header header = { XHDR(":method", "GET") };
 | 
			
		||||
    struct lsquic_http_headers headers = { 1, &header, };
 | 
			
		||||
 | 
			
		||||
    buf_in = malloc(buf_in_sz);
 | 
			
		||||
| 
						 | 
				
			
			@ -855,8 +855,7 @@ test_zero_size_frame (void)
 | 
			
		|||
    const unsigned wsize = 7000;
 | 
			
		||||
    const size_t buf_in_sz = wsize, buf_out_sz = 0x500000;
 | 
			
		||||
 | 
			
		||||
    struct lsxpack_header header;
 | 
			
		||||
    lsxpack_header_set_ptr(&header, ":method", 7, "GET", 3);
 | 
			
		||||
    struct lsxpack_header header = { XHDR(":method", "GET") };
 | 
			
		||||
    struct lsquic_http_headers headers = { 1, &header, };
 | 
			
		||||
 | 
			
		||||
    buf_in = malloc(buf_in_sz);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,7 +35,7 @@ main (int argc, char **argv)
 | 
			
		|||
    else
 | 
			
		||||
        nelems = 1000000;
 | 
			
		||||
 | 
			
		||||
    widgets = malloc(sizeof(widgets[0]) * nelems);
 | 
			
		||||
    widgets = calloc(nelems, sizeof(widgets[0]));
 | 
			
		||||
 | 
			
		||||
    for (n = 0; n < nelems; ++n)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,7 @@
 | 
			
		|||
#ifndef WIN32
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#else
 | 
			
		||||
#include <getopt.h>
 | 
			
		||||
#include "getopt.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "lsquic_malo.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,6 +46,9 @@ test_min_heap (void)
 | 
			
		|||
    for (i = 0; i < MAX_ELEMS; ++i)
 | 
			
		||||
        lsquic_mh_insert(&heap, (void *) i, i);
 | 
			
		||||
    verify_min_heap(&heap);
 | 
			
		||||
#ifdef _MSC_VER
 | 
			
		||||
    prev_val = 0;
 | 
			
		||||
#endif
 | 
			
		||||
    for (i = 0; i < MAX_ELEMS; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        p = lsquic_mh_pop(&heap);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,11 @@
 | 
			
		|||
#include <assert.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#else
 | 
			
		||||
#include "getopt.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <openssl/rand.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,7 +38,7 @@ main (void)
 | 
			
		|||
        .sin_port = htons(443),
 | 
			
		||||
        .sin_addr = peer_addr,
 | 
			
		||||
    };
 | 
			
		||||
    lsquic_cid_t cid = {};
 | 
			
		||||
    lsquic_cid_t cid;   memset(&cid, 0, sizeof(cid));
 | 
			
		||||
    lsquic_qlog_create_connection(&cid, (const struct sockaddr *)&local,
 | 
			
		||||
                                        (const struct sockaddr *)&peer);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,10 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#ifdef WIN32
 | 
			
		||||
#include "vc_compat.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "lsquic_types.h"
 | 
			
		||||
#include "lsquic_int_types.h"
 | 
			
		||||
#include "lsquic_rechist.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,12 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#else
 | 
			
		||||
#include "vc_compat.h"
 | 
			
		||||
#include <winbase.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "lsquic.h"
 | 
			
		||||
#include "lsquic_stock_shi.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -85,7 +90,11 @@ test_shi (const struct order *order)
 | 
			
		|||
        assert(0 == s);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
    sleep(2);       /* Let the thing expire */
 | 
			
		||||
#else
 | 
			
		||||
    Sleep(2000);       /* Let the thing expire */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < N_PAIRS; ++i)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,7 +10,11 @@
 | 
			
		|||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#else
 | 
			
		||||
#include "getopt.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "lsquic.h"
 | 
			
		||||
#include "lsquic_types.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,4 @@
 | 
			
		|||
# Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc.  See LICENSE.
 | 
			
		||||
- only debug and release are expected in the Cmakelists.txt. If you need a different config, please follow the model in that file to add it.
 | 
			
		||||
 | 
			
		||||
- vcpkg does not have boringssl, so you'll have to build it yourself. Follow the instructions at the boringssl repository.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,4 @@
 | 
			
		|||
/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc.  See LICENSE. */
 | 
			
		||||
/* Getopt for GNU.
 | 
			
		||||
   NOTE: getopt is now part of the C library, so if you don't know what
 | 
			
		||||
   "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,4 @@
 | 
			
		|||
/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc.  See LICENSE. */
 | 
			
		||||
/* Declarations for getopt.
 | 
			
		||||
   Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,4 @@
 | 
			
		|||
/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc.  See LICENSE. */
 | 
			
		||||
/* getopt_long and getopt_long_only entry points for GNU getopt.
 | 
			
		||||
   Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
 | 
			
		||||
	Free Software Foundation, Inc.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,4 @@
 | 
			
		|||
/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc.  See LICENSE. */
 | 
			
		||||
/*-
 | 
			
		||||
 * SPDX-License-Identifier: BSD-3-Clause
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,4 @@
 | 
			
		|||
/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc.  See LICENSE. */
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <Windows.h>
 | 
			
		||||
#include <winsock2.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -7,7 +8,9 @@ struct iovec {
 | 
			
		|||
  size_t iov_len;     /* Number of bytes to transfer */
 | 
			
		||||
};
 | 
			
		||||
#define strcasecmp(a,b) _strcmpi(a,b)
 | 
			
		||||
#define strncasecmp _strnicmp
 | 
			
		||||
#define strdup _strdup
 | 
			
		||||
#define PATH_MAX MAX_PATH
 | 
			
		||||
 | 
			
		||||
#define posix_memalign(p, a, s) (((*(p)) = _aligned_malloc((s), (a))), *(p) ?0 :errno)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue