deps: update nghttp2 to v1.45.1

PR-URL: https://github.com/nodejs/node/pull/40206
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
This commit is contained in:
thunder-coding
2021-09-24 09:04:23 +00:00
committed by Node.js GitHub Bot
parent 35d9222f30
commit 43291b98ed
19 changed files with 898 additions and 1705 deletions

View File

@@ -24,7 +24,6 @@ set(NGHTTP2_SOURCES
nghttp2_http.c
nghttp2_rcbuf.c
nghttp2_debug.c
nghttp2_ksl.c
)
set(NGHTTP2_RES "")

View File

@@ -27,6 +27,7 @@ EXTRA_DIST = Makefile.msvc CMakeLists.txt version.rc.in
AM_CFLAGS = $(WARNCFLAGS) $(EXTRACFLAG)
AM_CPPFLAGS = -I$(srcdir)/includes -I$(builddir)/includes -DBUILDING_NGHTTP2 \
@DEFS@
AM_LDFLAGS = @LIBTOOL_LDFLAGS@
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libnghttp2.pc
@@ -49,8 +50,7 @@ OBJECTS = nghttp2_pq.c nghttp2_map.c nghttp2_queue.c \
nghttp2_mem.c \
nghttp2_http.c \
nghttp2_rcbuf.c \
nghttp2_debug.c \
nghttp2_ksl.c
nghttp2_debug.c
HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
nghttp2_frame.h \
@@ -66,9 +66,8 @@ HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
nghttp2_mem.h \
nghttp2_http.h \
nghttp2_rcbuf.h \
nghttp2_debug.h \
nghttp2_ksl.h
nghttp2_debug.h
libnghttp2_la_SOURCES = $(HFILES) $(OBJECTS)
libnghttp2_la_LDFLAGS = -no-undefined \
libnghttp2_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined \
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)

View File

@@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.16.2 from Makefile.am.
# Makefile.in generated by automake 1.16.4 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -162,7 +162,7 @@ am__objects_2 = nghttp2_pq.lo nghttp2_map.lo nghttp2_queue.lo \
nghttp2_hd_huffman.lo nghttp2_hd_huffman_data.lo \
nghttp2_version.lo nghttp2_priority_spec.lo nghttp2_option.lo \
nghttp2_callbacks.lo nghttp2_mem.lo nghttp2_http.lo \
nghttp2_rcbuf.lo nghttp2_debug.lo nghttp2_ksl.lo
nghttp2_rcbuf.lo nghttp2_debug.lo
am_libnghttp2_la_OBJECTS = $(am__objects_1) $(am__objects_2)
libnghttp2_la_OBJECTS = $(am_libnghttp2_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
@@ -193,9 +193,8 @@ am__depfiles_remade = ./$(DEPDIR)/nghttp2_buf.Plo \
./$(DEPDIR)/nghttp2_hd.Plo ./$(DEPDIR)/nghttp2_hd_huffman.Plo \
./$(DEPDIR)/nghttp2_hd_huffman_data.Plo \
./$(DEPDIR)/nghttp2_helper.Plo ./$(DEPDIR)/nghttp2_http.Plo \
./$(DEPDIR)/nghttp2_ksl.Plo ./$(DEPDIR)/nghttp2_map.Plo \
./$(DEPDIR)/nghttp2_mem.Plo ./$(DEPDIR)/nghttp2_npn.Plo \
./$(DEPDIR)/nghttp2_option.Plo \
./$(DEPDIR)/nghttp2_map.Plo ./$(DEPDIR)/nghttp2_mem.Plo \
./$(DEPDIR)/nghttp2_npn.Plo ./$(DEPDIR)/nghttp2_option.Plo \
./$(DEPDIR)/nghttp2_outbound_item.Plo \
./$(DEPDIR)/nghttp2_pq.Plo \
./$(DEPDIR)/nghttp2_priority_spec.Plo \
@@ -262,8 +261,6 @@ am__define_uniq_tagged_files = \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/libnghttp2.pc.in \
$(top_srcdir)/depcomp
@@ -307,11 +304,14 @@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
BOOST_LDFLAGS = @BOOST_LDFLAGS@
BOOST_SYSTEM_LIB = @BOOST_SYSTEM_LIB@
BOOST_THREAD_LIB = @BOOST_THREAD_LIB@
BPFCFLAGS = @BPFCFLAGS@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CUNIT_CFLAGS = @CUNIT_CFLAGS@
CUNIT_LIBS = @CUNIT_LIBS@
CXX = @CXX@
@@ -330,8 +330,11 @@ ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
EXTRABPFCFLAGS = @EXTRABPFCFLAGS@
EXTRACFLAG = @EXTRACFLAG@
EXTRA_DEFS = @EXTRA_DEFS@
FGREP = @FGREP@
GREP = @GREP@
HAVE_CXX14 = @HAVE_CXX14@
@@ -342,9 +345,12 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
JANSSON_CFLAGS = @JANSSON_CFLAGS@
JANSSON_LIBS = @JANSSON_LIBS@
JEMALLOC_CFLAGS = @JEMALLOC_CFLAGS@
JEMALLOC_LIBS = @JEMALLOC_LIBS@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBBPF_CFLAGS = @LIBBPF_CFLAGS@
LIBBPF_LIBS = @LIBBPF_LIBS@
LIBCARES_CFLAGS = @LIBCARES_CFLAGS@
LIBCARES_LIBS = @LIBCARES_LIBS@
LIBEVENT_OPENSSL_CFLAGS = @LIBEVENT_OPENSSL_CFLAGS@
@@ -353,9 +359,16 @@ LIBEV_CFLAGS = @LIBEV_CFLAGS@
LIBEV_LIBS = @LIBEV_LIBS@
LIBMRUBY_CFLAGS = @LIBMRUBY_CFLAGS@
LIBMRUBY_LIBS = @LIBMRUBY_LIBS@
LIBNGHTTP3_CFLAGS = @LIBNGHTTP3_CFLAGS@
LIBNGHTTP3_LIBS = @LIBNGHTTP3_LIBS@
LIBNGTCP2_CFLAGS = @LIBNGTCP2_CFLAGS@
LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS = @LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS@
LIBNGTCP2_CRYPTO_OPENSSL_LIBS = @LIBNGTCP2_CRYPTO_OPENSSL_LIBS@
LIBNGTCP2_LIBS = @LIBNGTCP2_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBTOOL_LDFLAGS = @LIBTOOL_LDFLAGS@
LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
LIBXML2_LIBS = @LIBXML2_LIBS@
LIPO = @LIPO@
@@ -393,7 +406,7 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
PYTHON_LIBS = @PYTHON_LIBS@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
@@ -487,6 +500,7 @@ AM_CFLAGS = $(WARNCFLAGS) $(EXTRACFLAG)
AM_CPPFLAGS = -I$(srcdir)/includes -I$(builddir)/includes -DBUILDING_NGHTTP2 \
@DEFS@
AM_LDFLAGS = @LIBTOOL_LDFLAGS@
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libnghttp2.pc
DISTCLEANFILES = $(pkgconfig_DATA)
@@ -506,8 +520,7 @@ OBJECTS = nghttp2_pq.c nghttp2_map.c nghttp2_queue.c \
nghttp2_mem.c \
nghttp2_http.c \
nghttp2_rcbuf.c \
nghttp2_debug.c \
nghttp2_ksl.c
nghttp2_debug.c
HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
nghttp2_frame.h \
@@ -523,11 +536,10 @@ HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
nghttp2_mem.h \
nghttp2_http.h \
nghttp2_rcbuf.h \
nghttp2_debug.h \
nghttp2_ksl.h
nghttp2_debug.h
libnghttp2_la_SOURCES = $(HFILES) $(OBJECTS)
libnghttp2_la_LDFLAGS = -no-undefined \
libnghttp2_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined \
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
all: all-recursive
@@ -619,7 +631,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_hd_huffman_data.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_helper.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_http.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_ksl.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_map.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_mem.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_npn.Plo@am__quote@ # am--include-marker
@@ -789,7 +800,6 @@ cscopelist-am: $(am__tagged_files)
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
@@ -902,7 +912,6 @@ distclean: distclean-recursive
-rm -f ./$(DEPDIR)/nghttp2_hd_huffman_data.Plo
-rm -f ./$(DEPDIR)/nghttp2_helper.Plo
-rm -f ./$(DEPDIR)/nghttp2_http.Plo
-rm -f ./$(DEPDIR)/nghttp2_ksl.Plo
-rm -f ./$(DEPDIR)/nghttp2_map.Plo
-rm -f ./$(DEPDIR)/nghttp2_mem.Plo
-rm -f ./$(DEPDIR)/nghttp2_npn.Plo
@@ -970,7 +979,6 @@ maintainer-clean: maintainer-clean-recursive
-rm -f ./$(DEPDIR)/nghttp2_hd_huffman_data.Plo
-rm -f ./$(DEPDIR)/nghttp2_helper.Plo
-rm -f ./$(DEPDIR)/nghttp2_http.Plo
-rm -f ./$(DEPDIR)/nghttp2_ksl.Plo
-rm -f ./$(DEPDIR)/nghttp2_map.Plo
-rm -f ./$(DEPDIR)/nghttp2_mem.Plo
-rm -f ./$(DEPDIR)/nghttp2_npn.Plo

View File

@@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.16.2 from Makefile.am.
# Makefile.in generated by automake 1.16.4 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -197,8 +197,6 @@ am__define_uniq_tagged_files = \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
@@ -215,11 +213,14 @@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
BOOST_LDFLAGS = @BOOST_LDFLAGS@
BOOST_SYSTEM_LIB = @BOOST_SYSTEM_LIB@
BOOST_THREAD_LIB = @BOOST_THREAD_LIB@
BPFCFLAGS = @BPFCFLAGS@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CUNIT_CFLAGS = @CUNIT_CFLAGS@
CUNIT_LIBS = @CUNIT_LIBS@
CXX = @CXX@
@@ -238,8 +239,11 @@ ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
EXTRABPFCFLAGS = @EXTRABPFCFLAGS@
EXTRACFLAG = @EXTRACFLAG@
EXTRA_DEFS = @EXTRA_DEFS@
FGREP = @FGREP@
GREP = @GREP@
HAVE_CXX14 = @HAVE_CXX14@
@@ -250,9 +254,12 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
JANSSON_CFLAGS = @JANSSON_CFLAGS@
JANSSON_LIBS = @JANSSON_LIBS@
JEMALLOC_CFLAGS = @JEMALLOC_CFLAGS@
JEMALLOC_LIBS = @JEMALLOC_LIBS@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBBPF_CFLAGS = @LIBBPF_CFLAGS@
LIBBPF_LIBS = @LIBBPF_LIBS@
LIBCARES_CFLAGS = @LIBCARES_CFLAGS@
LIBCARES_LIBS = @LIBCARES_LIBS@
LIBEVENT_OPENSSL_CFLAGS = @LIBEVENT_OPENSSL_CFLAGS@
@@ -261,9 +268,16 @@ LIBEV_CFLAGS = @LIBEV_CFLAGS@
LIBEV_LIBS = @LIBEV_LIBS@
LIBMRUBY_CFLAGS = @LIBMRUBY_CFLAGS@
LIBMRUBY_LIBS = @LIBMRUBY_LIBS@
LIBNGHTTP3_CFLAGS = @LIBNGHTTP3_CFLAGS@
LIBNGHTTP3_LIBS = @LIBNGHTTP3_LIBS@
LIBNGTCP2_CFLAGS = @LIBNGTCP2_CFLAGS@
LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS = @LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS@
LIBNGTCP2_CRYPTO_OPENSSL_LIBS = @LIBNGTCP2_CRYPTO_OPENSSL_LIBS@
LIBNGTCP2_LIBS = @LIBNGTCP2_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBTOOL_LDFLAGS = @LIBTOOL_LDFLAGS@
LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
LIBXML2_LIBS = @LIBXML2_LIBS@
LIPO = @LIPO@
@@ -301,7 +315,7 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
PYTHON_LIBS = @PYTHON_LIBS@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
@@ -497,7 +511,6 @@ cscopelist-am: $(am__tagged_files)
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am

File diff suppressed because it is too large Load Diff

View File

@@ -29,7 +29,7 @@
* @macro
* Version number of the nghttp2 library release
*/
#define NGHTTP2_VERSION "1.42.0"
#define NGHTTP2_VERSION "1.45.1"
/**
* @macro
@@ -37,6 +37,6 @@
* release. This is a 24 bit number with 8 bits for major number, 8 bits
* for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
*/
#define NGHTTP2_VERSION_NUM 0x012a00
#define NGHTTP2_VERSION_NUM 0x012d01
#endif /* NGHTTP2VER_H */

View File

@@ -57,7 +57,7 @@
/* Maximum headers block size to send, calculated using
nghttp2_hd_deflate_bound(). This is the default value, and can be
overridden by nghttp2_option_set_max_send_header_block_size(). */
overridden by nghttp2_option_set_max_send_header_block_length(). */
#define NGHTTP2_MAX_HEADERSLEN 65536
/* The number of bytes for each SETTINGS entry */

View File

@@ -507,7 +507,166 @@ int nghttp2_check_header_value(const uint8_t *value, size_t len) {
return 1;
}
/* Generated by genauthroitychartbl.py */
/* Generated by genmethodchartbl.py */
static char VALID_METHOD_CHARS[] = {
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */,
0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,
0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */,
0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */,
0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */,
0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */,
0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */,
0 /* SPC */, 1 /* ! */, 0 /* " */, 1 /* # */,
1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
0 /* ( */, 0 /* ) */, 1 /* * */, 1 /* + */,
0 /* , */, 1 /* - */, 1 /* . */, 0 /* / */,
1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */,
1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */,
1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */,
0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */,
0 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */,
1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */,
1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */,
1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */,
1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */,
1 /* X */, 1 /* Y */, 1 /* Z */, 0 /* [ */,
0 /* \ */, 0 /* ] */, 1 /* ^ */, 1 /* _ */,
1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */,
1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */,
1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */,
1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */,
1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */,
1 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */,
0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */,
0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */,
0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */,
0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */,
0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */,
0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */,
0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */,
0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */,
0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */,
0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */,
0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */,
0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */,
0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */,
0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */,
0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */,
0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */,
0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */,
0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */,
0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */,
0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */,
0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */,
0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */,
0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */,
0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */,
0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */,
0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */,
0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */,
0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */
};
int nghttp2_check_method(const uint8_t *value, size_t len) {
const uint8_t *last;
if (len == 0) {
return 0;
}
for (last = value + len; value != last; ++value) {
if (!VALID_METHOD_CHARS[*value]) {
return 0;
}
}
return 1;
}
/* Generated by genpathchartbl.py */
static char VALID_PATH_CHARS[] = {
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */,
0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,
0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */,
0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */,
0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */,
0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */,
0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */,
0 /* SPC */, 1 /* ! */, 1 /* " */, 1 /* # */,
1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */,
1 /* , */, 1 /* - */, 1 /* . */, 1 /* / */,
1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */,
1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */,
1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */,
1 /* < */, 1 /* = */, 1 /* > */, 1 /* ? */,
1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */,
1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */,
1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */,
1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */,
1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */,
1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */,
1 /* \ */, 1 /* ] */, 1 /* ^ */, 1 /* _ */,
1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */,
1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */,
1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */,
1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */,
1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
1 /* x */, 1 /* y */, 1 /* z */, 1 /* { */,
1 /* | */, 1 /* } */, 1 /* ~ */, 0 /* DEL */,
1 /* 0x80 */, 1 /* 0x81 */, 1 /* 0x82 */, 1 /* 0x83 */,
1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */, 1 /* 0x87 */,
1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */,
1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */,
1 /* 0x90 */, 1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */,
1 /* 0x94 */, 1 /* 0x95 */, 1 /* 0x96 */, 1 /* 0x97 */,
1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */, 1 /* 0x9b */,
1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */,
1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */,
1 /* 0xa4 */, 1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */,
1 /* 0xa8 */, 1 /* 0xa9 */, 1 /* 0xaa */, 1 /* 0xab */,
1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */, 1 /* 0xaf */,
1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */,
1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */,
1 /* 0xb8 */, 1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */,
1 /* 0xbc */, 1 /* 0xbd */, 1 /* 0xbe */, 1 /* 0xbf */,
1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */, 1 /* 0xc3 */,
1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */,
1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */,
1 /* 0xcc */, 1 /* 0xcd */, 1 /* 0xce */, 1 /* 0xcf */,
1 /* 0xd0 */, 1 /* 0xd1 */, 1 /* 0xd2 */, 1 /* 0xd3 */,
1 /* 0xd4 */, 1 /* 0xd5 */, 1 /* 0xd6 */, 1 /* 0xd7 */,
1 /* 0xd8 */, 1 /* 0xd9 */, 1 /* 0xda */, 1 /* 0xdb */,
1 /* 0xdc */, 1 /* 0xdd */, 1 /* 0xde */, 1 /* 0xdf */,
1 /* 0xe0 */, 1 /* 0xe1 */, 1 /* 0xe2 */, 1 /* 0xe3 */,
1 /* 0xe4 */, 1 /* 0xe5 */, 1 /* 0xe6 */, 1 /* 0xe7 */,
1 /* 0xe8 */, 1 /* 0xe9 */, 1 /* 0xea */, 1 /* 0xeb */,
1 /* 0xec */, 1 /* 0xed */, 1 /* 0xee */, 1 /* 0xef */,
1 /* 0xf0 */, 1 /* 0xf1 */, 1 /* 0xf2 */, 1 /* 0xf3 */,
1 /* 0xf4 */, 1 /* 0xf5 */, 1 /* 0xf6 */, 1 /* 0xf7 */,
1 /* 0xf8 */, 1 /* 0xf9 */, 1 /* 0xfa */, 1 /* 0xfb */,
1 /* 0xfc */, 1 /* 0xfd */, 1 /* 0xfe */, 1 /* 0xff */
};
int nghttp2_check_path(const uint8_t *value, size_t len) {
const uint8_t *last;
for (last = value + len; value != last; ++value) {
if (!VALID_PATH_CHARS[*value]) {
return 0;
}
}
return 1;
}
/* Generated by genauthoritychartbl.py */
static char VALID_AUTHORITY_CHARS[] = {
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */,
0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,

View File

@@ -360,12 +360,21 @@ int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
return NGHTTP2_ERR_IGN_HTTP_HEADER;
}
if (nv->token == NGHTTP2_TOKEN__AUTHORITY ||
nv->token == NGHTTP2_TOKEN_HOST) {
switch (nv->token) {
case NGHTTP2_TOKEN__METHOD:
rv = nghttp2_check_method(nv->value->base, nv->value->len);
break;
case NGHTTP2_TOKEN__PATH:
rv = nghttp2_check_path(nv->value->base, nv->value->len);
break;
case NGHTTP2_TOKEN__AUTHORITY:
case NGHTTP2_TOKEN_HOST:
rv = nghttp2_check_authority(nv->value->base, nv->value->len);
} else if (nv->token == NGHTTP2_TOKEN__SCHEME) {
break;
case NGHTTP2_TOKEN__SCHEME:
rv = check_scheme(nv->value->base, nv->value->len);
} else {
break;
default:
rv = nghttp2_check_header_value(nv->value->base, nv->value->len);
}

View File

@@ -1,707 +0,0 @@
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2020 nghttp2 contributors
* Copyright (c) 2018 ngtcp2 contributors
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "nghttp2_ksl.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdio.h>
#include "nghttp2_mem.h"
static size_t ksl_nodelen(size_t keylen) {
return (sizeof(nghttp2_ksl_node) + keylen - sizeof(uint64_t) + 0xf) &
(size_t)~0xf;
}
static size_t ksl_blklen(size_t nodelen) {
return sizeof(nghttp2_ksl_blk) + nodelen * NGHTTP2_KSL_MAX_NBLK -
sizeof(uint64_t);
}
/*
* ksl_node_set_key sets |key| to |node|.
*/
static void ksl_node_set_key(nghttp2_ksl *ksl, nghttp2_ksl_node *node,
const void *key) {
memcpy(node->key, key, ksl->keylen);
}
int nghttp2_ksl_init(nghttp2_ksl *ksl, nghttp2_ksl_compar compar, size_t keylen,
nghttp2_mem *mem) {
size_t nodelen = ksl_nodelen(keylen);
size_t blklen = ksl_blklen(nodelen);
nghttp2_ksl_blk *head;
ksl->head = nghttp2_mem_malloc(mem, blklen);
if (!ksl->head) {
return NGHTTP2_ERR_NOMEM;
}
ksl->front = ksl->back = ksl->head;
ksl->compar = compar;
ksl->keylen = keylen;
ksl->nodelen = nodelen;
ksl->n = 0;
ksl->mem = mem;
head = ksl->head;
head->next = head->prev = NULL;
head->n = 0;
head->leaf = 1;
return 0;
}
/*
* ksl_free_blk frees |blk| recursively.
*/
static void ksl_free_blk(nghttp2_ksl *ksl, nghttp2_ksl_blk *blk) {
size_t i;
if (!blk->leaf) {
for (i = 0; i < blk->n; ++i) {
ksl_free_blk(ksl, nghttp2_ksl_nth_node(ksl, blk, i)->blk);
}
}
nghttp2_mem_free(ksl->mem, blk);
}
void nghttp2_ksl_free(nghttp2_ksl *ksl) {
if (!ksl) {
return;
}
ksl_free_blk(ksl, ksl->head);
}
/*
* ksl_split_blk splits |blk| into 2 nghttp2_ksl_blk objects. The new
* nghttp2_ksl_blk is always the "right" block.
*
* It returns the pointer to the nghttp2_ksl_blk created which is the
* located at the right of |blk|, or NULL which indicates out of
* memory error.
*/
static nghttp2_ksl_blk *ksl_split_blk(nghttp2_ksl *ksl, nghttp2_ksl_blk *blk) {
nghttp2_ksl_blk *rblk;
rblk = nghttp2_mem_malloc(ksl->mem, ksl_blklen(ksl->nodelen));
if (rblk == NULL) {
return NULL;
}
rblk->next = blk->next;
blk->next = rblk;
if (rblk->next) {
rblk->next->prev = rblk;
} else if (ksl->back == blk) {
ksl->back = rblk;
}
rblk->prev = blk;
rblk->leaf = blk->leaf;
rblk->n = blk->n / 2;
memcpy(rblk->nodes, blk->nodes + ksl->nodelen * (blk->n - rblk->n),
ksl->nodelen * rblk->n);
blk->n -= rblk->n;
assert(blk->n >= NGHTTP2_KSL_MIN_NBLK);
assert(rblk->n >= NGHTTP2_KSL_MIN_NBLK);
return rblk;
}
/*
* ksl_split_node splits a node included in |blk| at the position |i|
* into 2 adjacent nodes. The new node is always inserted at the
* position |i+1|.
*
* It returns 0 if it succeeds, or one of the following negative error
* codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
static int ksl_split_node(nghttp2_ksl *ksl, nghttp2_ksl_blk *blk, size_t i) {
nghttp2_ksl_node *node;
nghttp2_ksl_blk *lblk = nghttp2_ksl_nth_node(ksl, blk, i)->blk, *rblk;
rblk = ksl_split_blk(ksl, lblk);
if (rblk == NULL) {
return NGHTTP2_ERR_NOMEM;
}
memmove(blk->nodes + (i + 2) * ksl->nodelen,
blk->nodes + (i + 1) * ksl->nodelen,
ksl->nodelen * (blk->n - (i + 1)));
node = nghttp2_ksl_nth_node(ksl, blk, i + 1);
node->blk = rblk;
++blk->n;
ksl_node_set_key(ksl, node,
nghttp2_ksl_nth_node(ksl, rblk, rblk->n - 1)->key);
node = nghttp2_ksl_nth_node(ksl, blk, i);
ksl_node_set_key(ksl, node,
nghttp2_ksl_nth_node(ksl, lblk, lblk->n - 1)->key);
return 0;
}
/*
* ksl_split_head splits a head (root) block. It increases the height
* of skip list by 1.
*
* It returns 0 if it succeeds, or one of the following negative error
* codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
static int ksl_split_head(nghttp2_ksl *ksl) {
nghttp2_ksl_blk *rblk = NULL, *lblk, *nhead = NULL;
nghttp2_ksl_node *node;
rblk = ksl_split_blk(ksl, ksl->head);
if (rblk == NULL) {
return NGHTTP2_ERR_NOMEM;
}
lblk = ksl->head;
nhead = nghttp2_mem_malloc(ksl->mem, ksl_blklen(ksl->nodelen));
if (nhead == NULL) {
nghttp2_mem_free(ksl->mem, rblk);
return NGHTTP2_ERR_NOMEM;
}
nhead->next = nhead->prev = NULL;
nhead->n = 2;
nhead->leaf = 0;
node = nghttp2_ksl_nth_node(ksl, nhead, 0);
ksl_node_set_key(ksl, node,
nghttp2_ksl_nth_node(ksl, lblk, lblk->n - 1)->key);
node->blk = lblk;
node = nghttp2_ksl_nth_node(ksl, nhead, 1);
ksl_node_set_key(ksl, node,
nghttp2_ksl_nth_node(ksl, rblk, rblk->n - 1)->key);
node->blk = rblk;
ksl->head = nhead;
return 0;
}
/*
* insert_node inserts a node whose key is |key| with the associated
* |data| at the index of |i|. This function assumes that the number
* of nodes contained by |blk| is strictly less than
* NGHTTP2_KSL_MAX_NBLK.
*/
static void ksl_insert_node(nghttp2_ksl *ksl, nghttp2_ksl_blk *blk, size_t i,
const nghttp2_ksl_key *key, void *data) {
nghttp2_ksl_node *node;
assert(blk->n < NGHTTP2_KSL_MAX_NBLK);
memmove(blk->nodes + (i + 1) * ksl->nodelen, blk->nodes + i * ksl->nodelen,
ksl->nodelen * (blk->n - i));
node = nghttp2_ksl_nth_node(ksl, blk, i);
ksl_node_set_key(ksl, node, key);
node->data = data;
++blk->n;
}
static size_t ksl_bsearch(nghttp2_ksl *ksl, nghttp2_ksl_blk *blk,
const nghttp2_ksl_key *key,
nghttp2_ksl_compar compar) {
ssize_t left = -1, right = (ssize_t)blk->n, mid;
nghttp2_ksl_node *node;
while (right - left > 1) {
mid = (left + right) / 2;
node = nghttp2_ksl_nth_node(ksl, blk, (size_t)mid);
if (compar((nghttp2_ksl_key *)node->key, key)) {
left = mid;
} else {
right = mid;
}
}
return (size_t)right;
}
int nghttp2_ksl_insert(nghttp2_ksl *ksl, nghttp2_ksl_it *it,
const nghttp2_ksl_key *key, void *data) {
nghttp2_ksl_blk *blk = ksl->head;
nghttp2_ksl_node *node;
size_t i;
int rv;
if (blk->n == NGHTTP2_KSL_MAX_NBLK) {
rv = ksl_split_head(ksl);
if (rv != 0) {
return rv;
}
blk = ksl->head;
}
for (;;) {
i = ksl_bsearch(ksl, blk, key, ksl->compar);
if (blk->leaf) {
if (i < blk->n &&
!ksl->compar(key, nghttp2_ksl_nth_node(ksl, blk, i)->key)) {
if (it) {
*it = nghttp2_ksl_end(ksl);
}
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
ksl_insert_node(ksl, blk, i, key, data);
++ksl->n;
if (it) {
nghttp2_ksl_it_init(it, ksl, blk, i);
}
return 0;
}
if (i == blk->n) {
/* This insertion extends the largest key in this subtree. */
for (; !blk->leaf;) {
node = nghttp2_ksl_nth_node(ksl, blk, blk->n - 1);
if (node->blk->n == NGHTTP2_KSL_MAX_NBLK) {
rv = ksl_split_node(ksl, blk, blk->n - 1);
if (rv != 0) {
return rv;
}
node = nghttp2_ksl_nth_node(ksl, blk, blk->n - 1);
}
ksl_node_set_key(ksl, node, key);
blk = node->blk;
}
ksl_insert_node(ksl, blk, blk->n, key, data);
++ksl->n;
if (it) {
nghttp2_ksl_it_init(it, ksl, blk, blk->n - 1);
}
return 0;
}
node = nghttp2_ksl_nth_node(ksl, blk, i);
if (node->blk->n == NGHTTP2_KSL_MAX_NBLK) {
rv = ksl_split_node(ksl, blk, i);
if (rv != 0) {
return rv;
}
if (ksl->compar((nghttp2_ksl_key *)node->key, key)) {
node = nghttp2_ksl_nth_node(ksl, blk, i + 1);
if (ksl->compar((nghttp2_ksl_key *)node->key, key)) {
ksl_node_set_key(ksl, node, key);
}
}
}
blk = node->blk;
}
}
/*
* ksl_remove_node removes the node included in |blk| at the index of
* |i|.
*/
static void ksl_remove_node(nghttp2_ksl *ksl, nghttp2_ksl_blk *blk, size_t i) {
memmove(blk->nodes + i * ksl->nodelen, blk->nodes + (i + 1) * ksl->nodelen,
ksl->nodelen * (blk->n - (i + 1)));
--blk->n;
}
/*
* ksl_merge_node merges 2 nodes which are the nodes at the index of
* |i| and |i + 1|.
*
* If |blk| is the direct descendant of head (root) block and the head
* block contains just 2 nodes, the merged block becomes head block,
* which decreases the height of |ksl| by 1.
*
* This function returns the pointer to the merged block.
*/
static nghttp2_ksl_blk *ksl_merge_node(nghttp2_ksl *ksl, nghttp2_ksl_blk *blk,
size_t i) {
nghttp2_ksl_blk *lblk, *rblk;
assert(i + 1 < blk->n);
lblk = nghttp2_ksl_nth_node(ksl, blk, i)->blk;
rblk = nghttp2_ksl_nth_node(ksl, blk, i + 1)->blk;
assert(lblk->n + rblk->n < NGHTTP2_KSL_MAX_NBLK);
memcpy(lblk->nodes + ksl->nodelen * lblk->n, rblk->nodes,
ksl->nodelen * rblk->n);
lblk->n += rblk->n;
lblk->next = rblk->next;
if (lblk->next) {
lblk->next->prev = lblk;
} else if (ksl->back == rblk) {
ksl->back = lblk;
}
nghttp2_mem_free(ksl->mem, rblk);
if (ksl->head == blk && blk->n == 2) {
nghttp2_mem_free(ksl->mem, ksl->head);
ksl->head = lblk;
} else {
ksl_remove_node(ksl, blk, i + 1);
ksl_node_set_key(ksl, nghttp2_ksl_nth_node(ksl, blk, i),
nghttp2_ksl_nth_node(ksl, lblk, lblk->n - 1)->key);
}
return lblk;
}
/*
* ksl_shift_left moves the first node in blk->nodes[i]->blk->nodes to
* blk->nodes[i - 1]->blk->nodes.
*/
static void ksl_shift_left(nghttp2_ksl *ksl, nghttp2_ksl_blk *blk, size_t i) {
nghttp2_ksl_node *lnode, *rnode, *dest, *src;
assert(i > 0);
lnode = nghttp2_ksl_nth_node(ksl, blk, i - 1);
rnode = nghttp2_ksl_nth_node(ksl, blk, i);
assert(lnode->blk->n < NGHTTP2_KSL_MAX_NBLK);
assert(rnode->blk->n > NGHTTP2_KSL_MIN_NBLK);
dest = nghttp2_ksl_nth_node(ksl, lnode->blk, lnode->blk->n);
src = nghttp2_ksl_nth_node(ksl, rnode->blk, 0);
memcpy(dest, src, ksl->nodelen);
ksl_node_set_key(ksl, lnode, dest->key);
++lnode->blk->n;
--rnode->blk->n;
memmove(rnode->blk->nodes, rnode->blk->nodes + ksl->nodelen,
ksl->nodelen * rnode->blk->n);
}
/*
* ksl_shift_right moves the last node in blk->nodes[i]->blk->nodes to
* blk->nodes[i + 1]->blk->nodes.
*/
static void ksl_shift_right(nghttp2_ksl *ksl, nghttp2_ksl_blk *blk, size_t i) {
nghttp2_ksl_node *lnode, *rnode, *dest, *src;
assert(i < blk->n - 1);
lnode = nghttp2_ksl_nth_node(ksl, blk, i);
rnode = nghttp2_ksl_nth_node(ksl, blk, i + 1);
assert(lnode->blk->n > NGHTTP2_KSL_MIN_NBLK);
assert(rnode->blk->n < NGHTTP2_KSL_MAX_NBLK);
memmove(rnode->blk->nodes + ksl->nodelen, rnode->blk->nodes,
ksl->nodelen * rnode->blk->n);
++rnode->blk->n;
dest = nghttp2_ksl_nth_node(ksl, rnode->blk, 0);
src = nghttp2_ksl_nth_node(ksl, lnode->blk, lnode->blk->n - 1);
memcpy(dest, src, ksl->nodelen);
--lnode->blk->n;
ksl_node_set_key(
ksl, lnode,
nghttp2_ksl_nth_node(ksl, lnode->blk, lnode->blk->n - 1)->key);
}
/*
* key_equal returns nonzero if |lhs| and |rhs| are equal using the
* function |compar|.
*/
static int key_equal(nghttp2_ksl_compar compar, const nghttp2_ksl_key *lhs,
const nghttp2_ksl_key *rhs) {
return !compar(lhs, rhs) && !compar(rhs, lhs);
}
int nghttp2_ksl_remove(nghttp2_ksl *ksl, nghttp2_ksl_it *it,
const nghttp2_ksl_key *key) {
nghttp2_ksl_blk *blk = ksl->head;
nghttp2_ksl_node *node;
size_t i;
if (!blk->leaf && blk->n == 2 &&
nghttp2_ksl_nth_node(ksl, blk, 0)->blk->n == NGHTTP2_KSL_MIN_NBLK &&
nghttp2_ksl_nth_node(ksl, blk, 1)->blk->n == NGHTTP2_KSL_MIN_NBLK) {
blk = ksl_merge_node(ksl, ksl->head, 0);
}
for (;;) {
i = ksl_bsearch(ksl, blk, key, ksl->compar);
if (i == blk->n) {
if (it) {
*it = nghttp2_ksl_end(ksl);
}
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
if (blk->leaf) {
if (ksl->compar(key, nghttp2_ksl_nth_node(ksl, blk, i)->key)) {
if (it) {
*it = nghttp2_ksl_end(ksl);
}
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
ksl_remove_node(ksl, blk, i);
--ksl->n;
if (it) {
if (blk->n == i && blk->next) {
nghttp2_ksl_it_init(it, ksl, blk->next, 0);
} else {
nghttp2_ksl_it_init(it, ksl, blk, i);
}
}
return 0;
}
node = nghttp2_ksl_nth_node(ksl, blk, i);
if (node->blk->n == NGHTTP2_KSL_MIN_NBLK) {
if (i > 0 && nghttp2_ksl_nth_node(ksl, blk, i - 1)->blk->n >
NGHTTP2_KSL_MIN_NBLK) {
ksl_shift_right(ksl, blk, i - 1);
blk = node->blk;
} else if (i + 1 < blk->n &&
nghttp2_ksl_nth_node(ksl, blk, i + 1)->blk->n >
NGHTTP2_KSL_MIN_NBLK) {
ksl_shift_left(ksl, blk, i + 1);
blk = node->blk;
} else if (i > 0) {
blk = ksl_merge_node(ksl, blk, i - 1);
} else {
assert(i + 1 < blk->n);
blk = ksl_merge_node(ksl, blk, i);
}
} else {
blk = node->blk;
}
}
}
nghttp2_ksl_it nghttp2_ksl_lower_bound(nghttp2_ksl *ksl,
const nghttp2_ksl_key *key) {
nghttp2_ksl_blk *blk = ksl->head;
nghttp2_ksl_it it;
size_t i;
for (;;) {
i = ksl_bsearch(ksl, blk, key, ksl->compar);
if (blk->leaf) {
if (i == blk->n && blk->next) {
blk = blk->next;
i = 0;
}
nghttp2_ksl_it_init(&it, ksl, blk, i);
return it;
}
if (i == blk->n) {
/* This happens if descendant has smaller key. Fast forward to
find last node in this subtree. */
for (; !blk->leaf; blk = nghttp2_ksl_nth_node(ksl, blk, blk->n - 1)->blk)
;
if (blk->next) {
blk = blk->next;
i = 0;
} else {
i = blk->n;
}
nghttp2_ksl_it_init(&it, ksl, blk, i);
return it;
}
blk = nghttp2_ksl_nth_node(ksl, blk, i)->blk;
}
}
nghttp2_ksl_it nghttp2_ksl_lower_bound_compar(nghttp2_ksl *ksl,
const nghttp2_ksl_key *key,
nghttp2_ksl_compar compar) {
nghttp2_ksl_blk *blk = ksl->head;
nghttp2_ksl_it it;
size_t i;
for (;;) {
i = ksl_bsearch(ksl, blk, key, compar);
if (blk->leaf) {
if (i == blk->n && blk->next) {
blk = blk->next;
i = 0;
}
nghttp2_ksl_it_init(&it, ksl, blk, i);
return it;
}
if (i == blk->n) {
/* This happens if descendant has smaller key. Fast forward to
find last node in this subtree. */
for (; !blk->leaf; blk = nghttp2_ksl_nth_node(ksl, blk, blk->n - 1)->blk)
;
if (blk->next) {
blk = blk->next;
i = 0;
} else {
i = blk->n;
}
nghttp2_ksl_it_init(&it, ksl, blk, i);
return it;
}
blk = nghttp2_ksl_nth_node(ksl, blk, i)->blk;
}
}
void nghttp2_ksl_update_key(nghttp2_ksl *ksl, const nghttp2_ksl_key *old_key,
const nghttp2_ksl_key *new_key) {
nghttp2_ksl_blk *blk = ksl->head;
nghttp2_ksl_node *node;
size_t i;
for (;;) {
i = ksl_bsearch(ksl, blk, old_key, ksl->compar);
assert(i < blk->n);
node = nghttp2_ksl_nth_node(ksl, blk, i);
if (blk->leaf) {
assert(key_equal(ksl->compar, (nghttp2_ksl_key *)node->key, old_key));
ksl_node_set_key(ksl, node, new_key);
return;
}
if (key_equal(ksl->compar, (nghttp2_ksl_key *)node->key, old_key) ||
ksl->compar((nghttp2_ksl_key *)node->key, new_key)) {
ksl_node_set_key(ksl, node, new_key);
}
blk = node->blk;
}
}
static void ksl_print(nghttp2_ksl *ksl, nghttp2_ksl_blk *blk, size_t level) {
size_t i;
nghttp2_ksl_node *node;
fprintf(stderr, "LV=%zu n=%zu\n", level, blk->n);
if (blk->leaf) {
for (i = 0; i < blk->n; ++i) {
node = nghttp2_ksl_nth_node(ksl, blk, i);
fprintf(stderr, " %" PRId64, *(int64_t *)(void *)node->key);
}
fprintf(stderr, "\n");
return;
}
for (i = 0; i < blk->n; ++i) {
ksl_print(ksl, nghttp2_ksl_nth_node(ksl, blk, i)->blk, level + 1);
}
}
size_t nghttp2_ksl_len(nghttp2_ksl *ksl) { return ksl->n; }
void nghttp2_ksl_clear(nghttp2_ksl *ksl) {
size_t i;
nghttp2_ksl_blk *head;
if (!ksl->head->leaf) {
for (i = 0; i < ksl->head->n; ++i) {
ksl_free_blk(ksl, nghttp2_ksl_nth_node(ksl, ksl->head, i)->blk);
}
}
ksl->front = ksl->back = ksl->head;
ksl->n = 0;
head = ksl->head;
head->next = head->prev = NULL;
head->n = 0;
head->leaf = 1;
}
void nghttp2_ksl_print(nghttp2_ksl *ksl) { ksl_print(ksl, ksl->head, 0); }
nghttp2_ksl_it nghttp2_ksl_begin(const nghttp2_ksl *ksl) {
nghttp2_ksl_it it;
nghttp2_ksl_it_init(&it, ksl, ksl->front, 0);
return it;
}
nghttp2_ksl_it nghttp2_ksl_end(const nghttp2_ksl *ksl) {
nghttp2_ksl_it it;
nghttp2_ksl_it_init(&it, ksl, ksl->back, ksl->back->n);
return it;
}
void nghttp2_ksl_it_init(nghttp2_ksl_it *it, const nghttp2_ksl *ksl,
nghttp2_ksl_blk *blk, size_t i) {
it->ksl = ksl;
it->blk = blk;
it->i = i;
}
void *nghttp2_ksl_it_get(const nghttp2_ksl_it *it) {
assert(it->i < it->blk->n);
return nghttp2_ksl_nth_node(it->ksl, it->blk, it->i)->data;
}
void nghttp2_ksl_it_prev(nghttp2_ksl_it *it) {
assert(!nghttp2_ksl_it_begin(it));
if (it->i == 0) {
it->blk = it->blk->prev;
it->i = it->blk->n - 1;
} else {
--it->i;
}
}
int nghttp2_ksl_it_begin(const nghttp2_ksl_it *it) {
return it->i == 0 && it->blk->prev == NULL;
}

View File

@@ -1,315 +0,0 @@
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2020 nghttp2 contributors
* Copyright (c) 2018 ngtcp2 contributors
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef NGHTTP2_KSL_H
#define NGHTTP2_KSL_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <stdlib.h>
#include <nghttp2/nghttp2.h>
/*
* Skip List using single key instead of range.
*/
#define NGHTTP2_KSL_DEGR 16
/* NGHTTP2_KSL_MAX_NBLK is the maximum number of nodes which a single
block can contain. */
#define NGHTTP2_KSL_MAX_NBLK (2 * NGHTTP2_KSL_DEGR - 1)
/* NGHTTP2_KSL_MIN_NBLK is the minimum number of nodes which a single
block other than root must contains. */
#define NGHTTP2_KSL_MIN_NBLK (NGHTTP2_KSL_DEGR - 1)
/*
* nghttp2_ksl_key represents key in nghttp2_ksl.
*/
typedef void nghttp2_ksl_key;
struct nghttp2_ksl_node;
typedef struct nghttp2_ksl_node nghttp2_ksl_node;
struct nghttp2_ksl_blk;
typedef struct nghttp2_ksl_blk nghttp2_ksl_blk;
/*
* nghttp2_ksl_node is a node which contains either nghttp2_ksl_blk or
* opaque data. If a node is an internal node, it contains
* nghttp2_ksl_blk. Otherwise, it has data. The key is stored at the
* location starting at key.
*/
struct nghttp2_ksl_node {
union {
nghttp2_ksl_blk *blk;
void *data;
};
union {
uint64_t align;
/* key is a buffer to include key associated to this node.
Because the length of key is unknown until nghttp2_ksl_init is
called, the actual buffer will be allocated after this
field. */
uint8_t key[1];
};
};
/*
* nghttp2_ksl_blk contains nghttp2_ksl_node objects.
*/
struct nghttp2_ksl_blk {
/* next points to the next block if leaf field is nonzero. */
nghttp2_ksl_blk *next;
/* prev points to the previous block if leaf field is nonzero. */
nghttp2_ksl_blk *prev;
/* n is the number of nodes this object contains in nodes. */
size_t n;
/* leaf is nonzero if this block contains leaf nodes. */
int leaf;
union {
uint64_t align;
/* nodes is a buffer to contain NGHTTP2_KSL_MAX_NBLK
nghttp2_ksl_node objects. Because nghttp2_ksl_node object is
allocated along with the additional variable length key
storage, the size of buffer is unknown until nghttp2_ksl_init is
called. */
uint8_t nodes[1];
};
};
/*
* nghttp2_ksl_compar is a function type which returns nonzero if key
* |lhs| should be placed before |rhs|. It returns 0 otherwise.
*/
typedef int (*nghttp2_ksl_compar)(const nghttp2_ksl_key *lhs,
const nghttp2_ksl_key *rhs);
struct nghttp2_ksl;
typedef struct nghttp2_ksl nghttp2_ksl;
struct nghttp2_ksl_it;
typedef struct nghttp2_ksl_it nghttp2_ksl_it;
/*
* nghttp2_ksl_it is a forward iterator to iterate nodes.
*/
struct nghttp2_ksl_it {
const nghttp2_ksl *ksl;
nghttp2_ksl_blk *blk;
size_t i;
};
/*
* nghttp2_ksl is a deterministic paged skip list.
*/
struct nghttp2_ksl {
/* head points to the root block. */
nghttp2_ksl_blk *head;
/* front points to the first leaf block. */
nghttp2_ksl_blk *front;
/* back points to the last leaf block. */
nghttp2_ksl_blk *back;
nghttp2_ksl_compar compar;
size_t n;
/* keylen is the size of key */
size_t keylen;
/* nodelen is the actual size of nghttp2_ksl_node including key
storage. */
size_t nodelen;
nghttp2_mem *mem;
};
/*
* nghttp2_ksl_init initializes |ksl|. |compar| specifies compare
* function. |keylen| is the length of key.
*
* It returns 0 if it succeeds, or one of the following negative error
* codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
int nghttp2_ksl_init(nghttp2_ksl *ksl, nghttp2_ksl_compar compar, size_t keylen,
nghttp2_mem *mem);
/*
* nghttp2_ksl_free frees resources allocated for |ksl|. If |ksl| is
* NULL, this function does nothing. It does not free the memory
* region pointed by |ksl| itself.
*/
void nghttp2_ksl_free(nghttp2_ksl *ksl);
/*
* nghttp2_ksl_insert inserts |key| with its associated |data|. On
* successful insertion, the iterator points to the inserted node is
* stored in |*it|.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
* NGHTTP2_ERR_INVALID_ARGUMENT
* |key| already exists.
*/
int nghttp2_ksl_insert(nghttp2_ksl *ksl, nghttp2_ksl_it *it,
const nghttp2_ksl_key *key, void *data);
/*
* nghttp2_ksl_remove removes the |key| from |ksl|.
*
* This function assigns the iterator to |*it|, which points to the
* node which is located at the right next of the removed node if |it|
* is not NULL. If |key| is not found, no deletion takes place and
* the return value of nghttp2_ksl_end(ksl) is assigned to |*it|.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_INVALID_ARGUMENT
* |key| does not exist.
*/
int nghttp2_ksl_remove(nghttp2_ksl *ksl, nghttp2_ksl_it *it,
const nghttp2_ksl_key *key);
/*
* nghttp2_ksl_lower_bound returns the iterator which points to the
* first node which has the key which is equal to |key| or the last
* node which satisfies !compar(&node->key, key). If there is no such
* node, it returns the iterator which satisfies nghttp2_ksl_it_end(it)
* != 0.
*/
nghttp2_ksl_it nghttp2_ksl_lower_bound(nghttp2_ksl *ksl,
const nghttp2_ksl_key *key);
/*
* nghttp2_ksl_lower_bound_compar works like nghttp2_ksl_lower_bound,
* but it takes custom function |compar| to do lower bound search.
*/
nghttp2_ksl_it nghttp2_ksl_lower_bound_compar(nghttp2_ksl *ksl,
const nghttp2_ksl_key *key,
nghttp2_ksl_compar compar);
/*
* nghttp2_ksl_update_key replaces the key of nodes which has |old_key|
* with |new_key|. |new_key| must be strictly greater than the
* previous node and strictly smaller than the next node.
*/
void nghttp2_ksl_update_key(nghttp2_ksl *ksl, const nghttp2_ksl_key *old_key,
const nghttp2_ksl_key *new_key);
/*
* nghttp2_ksl_begin returns the iterator which points to the first
* node. If there is no node in |ksl|, it returns the iterator which
* satisfies nghttp2_ksl_it_end(it) != 0.
*/
nghttp2_ksl_it nghttp2_ksl_begin(const nghttp2_ksl *ksl);
/*
* nghttp2_ksl_end returns the iterator which points to the node
* following the last node. The returned object satisfies
* nghttp2_ksl_it_end(). If there is no node in |ksl|, it returns the
* iterator which satisfies nghttp2_ksl_it_begin(it) != 0.
*/
nghttp2_ksl_it nghttp2_ksl_end(const nghttp2_ksl *ksl);
/*
* nghttp2_ksl_len returns the number of elements stored in |ksl|.
*/
size_t nghttp2_ksl_len(nghttp2_ksl *ksl);
/*
* nghttp2_ksl_clear removes all elements stored in |ksl|.
*/
void nghttp2_ksl_clear(nghttp2_ksl *ksl);
/*
* nghttp2_ksl_nth_node returns the |n|th node under |blk|.
*/
#define nghttp2_ksl_nth_node(KSL, BLK, N) \
((nghttp2_ksl_node *)(void *)((BLK)->nodes + (KSL)->nodelen * (N)))
/*
* nghttp2_ksl_print prints its internal state in stderr. It assumes
* that the key is of type int64_t. This function should be used for
* the debugging purpose only.
*/
void nghttp2_ksl_print(nghttp2_ksl *ksl);
/*
* nghttp2_ksl_it_init initializes |it|.
*/
void nghttp2_ksl_it_init(nghttp2_ksl_it *it, const nghttp2_ksl *ksl,
nghttp2_ksl_blk *blk, size_t i);
/*
* nghttp2_ksl_it_get returns the data associated to the node which
* |it| points to. It is undefined to call this function when
* nghttp2_ksl_it_end(it) returns nonzero.
*/
void *nghttp2_ksl_it_get(const nghttp2_ksl_it *it);
/*
* nghttp2_ksl_it_next advances the iterator by one. It is undefined
* if this function is called when nghttp2_ksl_it_end(it) returns
* nonzero.
*/
#define nghttp2_ksl_it_next(IT) \
(++(IT)->i == (IT)->blk->n && (IT)->blk->next \
? ((IT)->blk = (IT)->blk->next, (IT)->i = 0) \
: 0)
/*
* nghttp2_ksl_it_prev moves backward the iterator by one. It is
* undefined if this function is called when nghttp2_ksl_it_begin(it)
* returns nonzero.
*/
void nghttp2_ksl_it_prev(nghttp2_ksl_it *it);
/*
* nghttp2_ksl_it_end returns nonzero if |it| points to the beyond the
* last node.
*/
#define nghttp2_ksl_it_end(IT) \
((IT)->blk->n == (IT)->i && (IT)->blk->next == NULL)
/*
* nghttp2_ksl_it_begin returns nonzero if |it| points to the first
* node. |it| might satisfy both nghttp2_ksl_it_begin(&it) and
* nghttp2_ksl_it_end(&it) if the skip list has no node.
*/
int nghttp2_ksl_it_begin(const nghttp2_ksl_it *it);
/*
* nghttp2_ksl_key returns the key of the node which |it| points to.
* It is undefined to call this function when nghttp2_ksl_it_end(it)
* returns nonzero.
*/
#define nghttp2_ksl_it_key(IT) \
((nghttp2_ksl_key *)nghttp2_ksl_nth_node((IT)->ksl, (IT)->blk, (IT)->i)->key)
#endif /* NGHTTP2_KSL_H */

View File

@@ -27,14 +27,16 @@
#include <string.h>
#include <assert.h>
#include <stdio.h>
#include "nghttp2_helper.h"
#define INITIAL_TABLE_LENGTH 256
#define NGHTTP2_INITIAL_TABLE_LENBITS 8
int nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem) {
map->mem = mem;
map->tablelen = INITIAL_TABLE_LENGTH;
map->tablelen = 1 << NGHTTP2_INITIAL_TABLE_LENBITS;
map->tablelenbits = NGHTTP2_INITIAL_TABLE_LENBITS;
map->table =
nghttp2_mem_calloc(mem, map->tablelen, sizeof(nghttp2_map_bucket));
if (map->table == NULL) {
@@ -47,151 +49,145 @@ int nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem) {
}
void nghttp2_map_free(nghttp2_map *map) {
size_t i;
nghttp2_map_bucket *bkt;
if (!map) {
return;
}
for (i = 0; i < map->tablelen; ++i) {
bkt = &map->table[i];
if (bkt->ksl) {
nghttp2_ksl_free(bkt->ksl);
nghttp2_mem_free(map->mem, bkt->ksl);
}
}
nghttp2_mem_free(map->mem, map->table);
}
void nghttp2_map_each_free(nghttp2_map *map,
int (*func)(nghttp2_map_entry *entry, void *ptr),
void nghttp2_map_each_free(nghttp2_map *map, int (*func)(void *data, void *ptr),
void *ptr) {
uint32_t i;
nghttp2_map_bucket *bkt;
nghttp2_ksl_it it;
for (i = 0; i < map->tablelen; ++i) {
bkt = &map->table[i];
if (bkt->ptr) {
func(bkt->ptr, ptr);
bkt->ptr = NULL;
assert(bkt->ksl == NULL || nghttp2_ksl_len(bkt->ksl) == 0);
if (bkt->data == NULL) {
continue;
}
if (bkt->ksl) {
for (it = nghttp2_ksl_begin(bkt->ksl); !nghttp2_ksl_it_end(&it);
nghttp2_ksl_it_next(&it)) {
func(nghttp2_ksl_it_get(&it), ptr);
}
nghttp2_ksl_free(bkt->ksl);
nghttp2_mem_free(map->mem, bkt->ksl);
bkt->ksl = NULL;
}
func(bkt->data, ptr);
}
}
int nghttp2_map_each(nghttp2_map *map,
int (*func)(nghttp2_map_entry *entry, void *ptr),
int nghttp2_map_each(nghttp2_map *map, int (*func)(void *data, void *ptr),
void *ptr) {
int rv;
uint32_t i;
nghttp2_map_bucket *bkt;
nghttp2_ksl_it it;
for (i = 0; i < map->tablelen; ++i) {
bkt = &map->table[i];
if (bkt->ptr) {
rv = func(bkt->ptr, ptr);
if (rv != 0) {
return rv;
}
assert(bkt->ksl == NULL || nghttp2_ksl_len(bkt->ksl) == 0);
if (bkt->data == NULL) {
continue;
}
if (bkt->ksl) {
for (it = nghttp2_ksl_begin(bkt->ksl); !nghttp2_ksl_it_end(&it);
nghttp2_ksl_it_next(&it)) {
rv = func(nghttp2_ksl_it_get(&it), ptr);
if (rv != 0) {
return rv;
}
}
}
}
return 0;
}
void nghttp2_map_entry_init(nghttp2_map_entry *entry, key_type key) {
entry->key = key;
entry->next = NULL;
}
/* FNV1a hash */
static uint32_t hash(key_type key, uint32_t mod) {
uint8_t *p, *end;
uint32_t h = 0x811C9DC5u;
p = (uint8_t *)&key;
end = p + sizeof(key_type);
for (; p != end;) {
h ^= *p++;
h += (h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24);
}
return h & (mod - 1);
}
static int less(const nghttp2_ksl_key *lhs, const nghttp2_ksl_key *rhs) {
return *(key_type *)lhs < *(key_type *)rhs;
}
static int map_insert(nghttp2_map *map, nghttp2_map_bucket *table,
uint32_t tablelen, nghttp2_map_entry *entry) {
uint32_t h = hash(entry->key, tablelen);
nghttp2_map_bucket *bkt = &table[h];
nghttp2_mem *mem = map->mem;
int rv;
if (bkt->ptr == NULL &&
(bkt->ksl == NULL || nghttp2_ksl_len(bkt->ksl) == 0)) {
bkt->ptr = entry;
return 0;
}
if (!bkt->ksl) {
bkt->ksl = nghttp2_mem_malloc(mem, sizeof(*bkt->ksl));
if (bkt->ksl == NULL) {
return NGHTTP2_ERR_NOMEM;
}
nghttp2_ksl_init(bkt->ksl, less, sizeof(key_type), mem);
}
if (bkt->ptr) {
rv = nghttp2_ksl_insert(bkt->ksl, NULL, &bkt->ptr->key, bkt->ptr);
rv = func(bkt->data, ptr);
if (rv != 0) {
return rv;
}
bkt->ptr = NULL;
}
return nghttp2_ksl_insert(bkt->ksl, NULL, &entry->key, entry);
return 0;
}
/* new_tablelen must be power of 2 */
static int map_resize(nghttp2_map *map, uint32_t new_tablelen) {
static uint32_t hash(nghttp2_map_key_type key) {
return (uint32_t)key * 2654435769u;
}
static size_t h2idx(uint32_t hash, uint32_t bits) {
return hash >> (32 - bits);
}
static size_t distance(uint32_t tablelen, uint32_t tablelenbits,
nghttp2_map_bucket *bkt, size_t idx) {
return (idx - h2idx(bkt->hash, tablelenbits)) & (tablelen - 1);
}
static void map_bucket_swap(nghttp2_map_bucket *bkt, uint32_t *phash,
nghttp2_map_key_type *pkey, void **pdata) {
uint32_t h = bkt->hash;
nghttp2_map_key_type key = bkt->key;
void *data = bkt->data;
bkt->hash = *phash;
bkt->key = *pkey;
bkt->data = *pdata;
*phash = h;
*pkey = key;
*pdata = data;
}
static void map_bucket_set_data(nghttp2_map_bucket *bkt, uint32_t hash,
nghttp2_map_key_type key, void *data) {
bkt->hash = hash;
bkt->key = key;
bkt->data = data;
}
void nghttp2_map_print_distance(nghttp2_map *map) {
uint32_t i;
size_t idx;
nghttp2_map_bucket *bkt;
for (i = 0; i < map->tablelen; ++i) {
bkt = &map->table[i];
if (bkt->data == NULL) {
fprintf(stderr, "@%u <EMPTY>\n", i);
continue;
}
idx = h2idx(bkt->hash, map->tablelenbits);
fprintf(stderr, "@%u hash=%08x key=%d base=%zu distance=%zu\n", i,
bkt->hash, bkt->key, idx,
distance(map->tablelen, map->tablelenbits, bkt, idx));
}
}
static int insert(nghttp2_map_bucket *table, uint32_t tablelen,
uint32_t tablelenbits, uint32_t hash,
nghttp2_map_key_type key, void *data) {
size_t idx = h2idx(hash, tablelenbits);
size_t d = 0, dd;
nghttp2_map_bucket *bkt;
for (;;) {
bkt = &table[idx];
if (bkt->data == NULL) {
map_bucket_set_data(bkt, hash, key, data);
return 0;
}
dd = distance(tablelen, tablelenbits, bkt, idx);
if (d > dd) {
map_bucket_swap(bkt, &hash, &key, &data);
d = dd;
} else if (bkt->key == key) {
/* TODO This check is just a waste after first swap or if this
function is called from map_resize. That said, there is no
difference with or without this conditional in performance
wise. */
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
++d;
idx = (idx + 1) & (tablelen - 1);
}
}
/* new_tablelen must be power of 2 and new_tablelen == (1 <<
new_tablelenbits) must hold. */
static int map_resize(nghttp2_map *map, uint32_t new_tablelen,
uint32_t new_tablelenbits) {
uint32_t i;
nghttp2_map_bucket *new_table;
nghttp2_map_bucket *bkt;
nghttp2_ksl_it it;
int rv;
new_table =
@@ -202,64 +198,38 @@ static int map_resize(nghttp2_map *map, uint32_t new_tablelen) {
for (i = 0; i < map->tablelen; ++i) {
bkt = &map->table[i];
if (bkt->ptr) {
rv = map_insert(map, new_table, new_tablelen, bkt->ptr);
if (rv != 0) {
goto fail;
}
assert(bkt->ksl == NULL || nghttp2_ksl_len(bkt->ksl) == 0);
if (bkt->data == NULL) {
continue;
}
rv = insert(new_table, new_tablelen, new_tablelenbits, bkt->hash, bkt->key,
bkt->data);
if (bkt->ksl) {
for (it = nghttp2_ksl_begin(bkt->ksl); !nghttp2_ksl_it_end(&it);
nghttp2_ksl_it_next(&it)) {
rv = map_insert(map, new_table, new_tablelen, nghttp2_ksl_it_get(&it));
if (rv != 0) {
goto fail;
}
}
}
}
for (i = 0; i < map->tablelen; ++i) {
bkt = &map->table[i];
if (bkt->ksl) {
nghttp2_ksl_free(bkt->ksl);
nghttp2_mem_free(map->mem, bkt->ksl);
}
assert(0 == rv);
}
nghttp2_mem_free(map->mem, map->table);
map->tablelen = new_tablelen;
map->tablelenbits = new_tablelenbits;
map->table = new_table;
return 0;
fail:
for (i = 0; i < new_tablelen; ++i) {
bkt = &new_table[i];
if (bkt->ksl) {
nghttp2_ksl_free(bkt->ksl);
nghttp2_mem_free(map->mem, bkt->ksl);
}
}
return rv;
}
int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_entry *new_entry) {
int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data) {
int rv;
assert(data);
/* Load factor is 0.75 */
if ((map->size + 1) * 4 > map->tablelen * 3) {
rv = map_resize(map, map->tablelen * 2);
rv = map_resize(map, map->tablelen * 2, map->tablelenbits + 1);
if (rv != 0) {
return rv;
}
}
rv = map_insert(map, map->table, map->tablelen, new_entry);
rv = insert(map->table, map->tablelen, map->tablelenbits, hash(key), key,
data);
if (rv != 0) {
return rv;
}
@@ -267,68 +237,75 @@ int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_entry *new_entry) {
return 0;
}
nghttp2_map_entry *nghttp2_map_find(nghttp2_map *map, key_type key) {
nghttp2_map_bucket *bkt = &map->table[hash(key, map->tablelen)];
nghttp2_ksl_it it;
void *nghttp2_map_find(nghttp2_map *map, nghttp2_map_key_type key) {
uint32_t h = hash(key);
size_t idx = h2idx(h, map->tablelenbits);
nghttp2_map_bucket *bkt;
size_t d = 0;
if (bkt->ptr) {
if (bkt->ptr->key == key) {
return bkt->ptr;
}
return NULL;
}
for (;;) {
bkt = &map->table[idx];
if (bkt->ksl) {
it = nghttp2_ksl_lower_bound(bkt->ksl, &key);
if (nghttp2_ksl_it_end(&it) ||
*(key_type *)nghttp2_ksl_it_key(&it) != key) {
if (bkt->data == NULL ||
d > distance(map->tablelen, map->tablelenbits, bkt, idx)) {
return NULL;
}
return nghttp2_ksl_it_get(&it);
}
return NULL;
if (bkt->key == key) {
return bkt->data;
}
++d;
idx = (idx + 1) & (map->tablelen - 1);
}
}
int nghttp2_map_remove(nghttp2_map *map, key_type key) {
nghttp2_map_bucket *bkt = &map->table[hash(key, map->tablelen)];
int rv;
int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key) {
uint32_t h = hash(key);
size_t idx = h2idx(h, map->tablelenbits), didx;
nghttp2_map_bucket *bkt;
size_t d = 0;
for (;;) {
bkt = &map->table[idx];
if (bkt->data == NULL ||
d > distance(map->tablelen, map->tablelenbits, bkt, idx)) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
if (bkt->key == key) {
map_bucket_set_data(bkt, 0, 0, NULL);
didx = idx;
idx = (idx + 1) & (map->tablelen - 1);
for (;;) {
bkt = &map->table[idx];
if (bkt->data == NULL ||
distance(map->tablelen, map->tablelenbits, bkt, idx) == 0) {
break;
}
map->table[didx] = *bkt;
map_bucket_set_data(bkt, 0, 0, NULL);
didx = idx;
idx = (idx + 1) & (map->tablelen - 1);
}
if (bkt->ptr) {
if (bkt->ptr->key == key) {
bkt->ptr = NULL;
--map->size;
return 0;
}
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
if (bkt->ksl) {
rv = nghttp2_ksl_remove(bkt->ksl, NULL, &key);
if (rv != 0) {
return rv;
}
--map->size;
return 0;
++d;
idx = (idx + 1) & (map->tablelen - 1);
}
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
void nghttp2_map_clear(nghttp2_map *map) {
uint32_t i;
nghttp2_map_bucket *bkt;
for (i = 0; i < map->tablelen; ++i) {
bkt = &map->table[i];
bkt->ptr = NULL;
if (bkt->ksl) {
nghttp2_ksl_free(bkt->ksl);
nghttp2_mem_free(map->mem, bkt->ksl);
bkt->ksl = NULL;
}
}
memset(map->table, 0, sizeof(*map->table) * map->tablelen);
map->size = 0;
}

View File

@@ -33,31 +33,23 @@
#include <nghttp2/nghttp2.h>
#include "nghttp2_mem.h"
#include "nghttp2_ksl.h"
/* Implementation of unordered map */
typedef int32_t key_type;
typedef struct nghttp2_map_entry {
struct nghttp2_map_entry *next;
key_type key;
#if SIZEOF_INT_P == 4
/* we requires 8 bytes aligment */
int64_t pad;
#endif
} nghttp2_map_entry;
typedef int32_t nghttp2_map_key_type;
typedef struct nghttp2_map_bucket {
nghttp2_map_entry *ptr;
nghttp2_ksl *ksl;
uint32_t hash;
nghttp2_map_key_type key;
void *data;
} nghttp2_map_bucket;
typedef struct {
typedef struct nghttp2_map {
nghttp2_map_bucket *table;
nghttp2_mem *mem;
size_t size;
uint32_t tablelen;
uint32_t tablelenbits;
} nghttp2_map;
/*
@@ -81,21 +73,14 @@ void nghttp2_map_free(nghttp2_map *map);
/*
* Deallocates each entries using |func| function and any resources
* allocated for |map|. The |func| function is responsible for freeing
* given the |entry| object. The |ptr| will be passed to the |func| as
* given the |data| object. The |ptr| will be passed to the |func| as
* send argument. The return value of the |func| will be ignored.
*/
void nghttp2_map_each_free(nghttp2_map *map,
int (*func)(nghttp2_map_entry *entry, void *ptr),
void nghttp2_map_each_free(nghttp2_map *map, int (*func)(void *data, void *ptr),
void *ptr);
/*
* Initializes the |entry| with the |key|. All entries to be inserted
* to the map must be initialized with this function.
*/
void nghttp2_map_entry_init(nghttp2_map_entry *entry, key_type key);
/*
* Inserts the new |entry| with the key |entry->key| to the map |map|.
* Inserts the new |data| with the |key| to the map |map|.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
@@ -105,25 +90,25 @@ void nghttp2_map_entry_init(nghttp2_map_entry *entry, key_type key);
* NGHTTP2_ERR_NOMEM
* Out of memory
*/
int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_entry *entry);
int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data);
/*
* Returns the entry associated by the key |key|. If there is no such
* entry, this function returns NULL.
* Returns the data associated by the key |key|. If there is no such
* data, this function returns NULL.
*/
nghttp2_map_entry *nghttp2_map_find(nghttp2_map *map, key_type key);
void *nghttp2_map_find(nghttp2_map *map, nghttp2_map_key_type key);
/*
* Removes the entry associated by the key |key| from the |map|. The
* removed entry is not freed by this function.
* Removes the data associated by the key |key| from the |map|. The
* removed data is not freed by this function.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_INVALID_ARGUMENT
* The entry associated by |key| does not exist.
* The data associated by |key| does not exist.
*/
int nghttp2_map_remove(nghttp2_map *map, key_type key);
int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key);
/*
* Removes all entries from |map|.
@@ -136,21 +121,22 @@ void nghttp2_map_clear(nghttp2_map *map);
size_t nghttp2_map_size(nghttp2_map *map);
/*
* Applies the function |func| to each entry in the |map| with the
* Applies the function |func| to each data in the |map| with the
* optional user supplied pointer |ptr|.
*
* If the |func| returns 0, this function calls the |func| with the
* next entry. If the |func| returns nonzero, it will not call the
* next data. If the |func| returns nonzero, it will not call the
* |func| for further entries and return the return value of the
* |func| immediately. Thus, this function returns 0 if all the
* invocations of the |func| return 0, or nonzero value which the last
* invocation of |func| returns.
*
* Don't use this function to free each entry. Use
* Don't use this function to free each data. Use
* nghttp2_map_each_free() instead.
*/
int nghttp2_map_each(nghttp2_map *map,
int (*func)(nghttp2_map_entry *entry, void *ptr),
int nghttp2_map_each(nghttp2_map *map, int (*func)(void *data, void *ptr),
void *ptr);
void nghttp2_map_print_distance(nghttp2_map *map);
#endif /* NGHTTP2_MAP_H */

View File

@@ -666,7 +666,7 @@ int nghttp2_session_server_new3(nghttp2_session **session_ptr,
return 0;
}
static int free_streams(nghttp2_map_entry *entry, void *ptr) {
static int free_streams(void *entry, void *ptr) {
nghttp2_session *session;
nghttp2_stream *stream;
nghttp2_outbound_item *item;
@@ -1102,7 +1102,7 @@ nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session,
(int32_t)session->local_settings.initial_window_size,
stream_user_data, mem);
rv = nghttp2_map_insert(&session->streams, &stream->map_entry);
rv = nghttp2_map_insert(&session->streams, stream_id, stream);
if (rv != 0) {
nghttp2_stream_free(stream);
nghttp2_mem_free(mem, stream);
@@ -2424,7 +2424,7 @@ static int session_call_on_frame_send(nghttp2_session *session,
return 0;
}
static int find_stream_on_goaway_func(nghttp2_map_entry *entry, void *ptr) {
static int find_stream_on_goaway_func(void *entry, void *ptr) {
nghttp2_close_stream_on_goaway_arg *arg;
nghttp2_stream *stream;
@@ -4194,8 +4194,7 @@ static int session_process_rst_stream_frame(nghttp2_session *session) {
return nghttp2_session_on_rst_stream_received(session, frame);
}
static int update_remote_initial_window_size_func(nghttp2_map_entry *entry,
void *ptr) {
static int update_remote_initial_window_size_func(void *entry, void *ptr) {
int rv;
nghttp2_update_window_size_arg *arg;
nghttp2_stream *stream;
@@ -4248,8 +4247,7 @@ session_update_remote_initial_window_size(nghttp2_session *session,
update_remote_initial_window_size_func, &arg);
}
static int update_local_initial_window_size_func(nghttp2_map_entry *entry,
void *ptr) {
static int update_local_initial_window_size_func(void *entry, void *ptr) {
int rv;
nghttp2_update_window_size_arg *arg;
nghttp2_stream *stream;
@@ -6432,8 +6430,9 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
/* CONTINUATION won't bear NGHTTP2_PADDED flag */
iframe->frame.hd.flags = (uint8_t)(
iframe->frame.hd.flags | (cont_hd.flags & NGHTTP2_FLAG_END_HEADERS));
iframe->frame.hd.flags =
(uint8_t)(iframe->frame.hd.flags |
(cont_hd.flags & NGHTTP2_FLAG_END_HEADERS));
iframe->frame.hd.length += cont_hd.length;
busy = 1;

View File

@@ -62,7 +62,6 @@ void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
int32_t weight, int32_t remote_initial_window_size,
int32_t local_initial_window_size,
void *stream_user_data, nghttp2_mem *mem) {
nghttp2_map_entry_init(&stream->map_entry, (key_type)stream_id);
nghttp2_pq_init(&stream->obq, stream_less, mem);
stream->stream_id = stream_id;

View File

@@ -135,8 +135,6 @@ typedef enum {
} nghttp2_http_flag;
struct nghttp2_stream {
/* Intrusive Map */
nghttp2_map_entry map_entry;
/* Entry for dep_prev->obq */
nghttp2_pq_entry pq_entry;
/* Priority Queue storing direct descendant (nghttp2_stream). Only

View File

@@ -44,7 +44,6 @@
'lib/nghttp2_hd_huffman_data.c',
'lib/nghttp2_helper.c',
'lib/nghttp2_http.c',
'lib/nghttp2_ksl.c',
'lib/nghttp2_map.c',
'lib/nghttp2_mem.c',
'lib/nghttp2_npn.c',

View File

@@ -8,7 +8,7 @@ const h2 = require('http2');
const server = h2.createServer();
const methods = [undefined, 'GET', 'POST', 'PATCH', 'FOO', 'A B C'];
const methods = ['GET', 'POST', 'PATCH', 'FOO', 'A_B_C'];
let expected = methods.length;
// We use the lower-level API here

View File

@@ -29,7 +29,7 @@ server.listen(0, common.mustCall(() => {
});
function doRequest() {
const req = client.request({ ':method': 'POST ' });
const req = client.request({ ':method': 'POST' });
let data = '';
req.setEncoding('utf8');