Skip to content

Commit ea0b069

Browse files
committedMay 1, 2021
deps: update nghttp2 to 1.42.0
Refs: https://github.com/nghttp2/nghttp2/releases/tag/v1.42.0 PR-URL: #36842 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Yongsheng Zhang <zyszys98@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
1 parent aef7697 commit ea0b069

15 files changed

+3109
-78
lines changed
 

‎deps/nghttp2/lib/CMakeLists.txt

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
add_subdirectory(includes)
2+
3+
include_directories(
4+
"${CMAKE_CURRENT_SOURCE_DIR}/includes"
5+
"${CMAKE_CURRENT_BINARY_DIR}/includes"
6+
)
7+
8+
add_definitions(-DBUILDING_NGHTTP2)
9+
10+
set(NGHTTP2_SOURCES
11+
nghttp2_pq.c nghttp2_map.c nghttp2_queue.c
12+
nghttp2_frame.c
13+
nghttp2_buf.c
14+
nghttp2_stream.c nghttp2_outbound_item.c
15+
nghttp2_session.c nghttp2_submit.c
16+
nghttp2_helper.c
17+
nghttp2_npn.c
18+
nghttp2_hd.c nghttp2_hd_huffman.c nghttp2_hd_huffman_data.c
19+
nghttp2_version.c
20+
nghttp2_priority_spec.c
21+
nghttp2_option.c
22+
nghttp2_callbacks.c
23+
nghttp2_mem.c
24+
nghttp2_http.c
25+
nghttp2_rcbuf.c
26+
nghttp2_debug.c
27+
nghttp2_ksl.c
28+
)
29+
30+
set(NGHTTP2_RES "")
31+
32+
if(WIN32)
33+
configure_file(
34+
version.rc.in
35+
${CMAKE_CURRENT_BINARY_DIR}/version.rc
36+
@ONLY)
37+
38+
set(NGHTTP2_RES ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
39+
endif()
40+
41+
# Public shared library
42+
if(ENABLE_SHARED_LIB)
43+
add_library(nghttp2 SHARED ${NGHTTP2_SOURCES} ${NGHTTP2_RES})
44+
set_target_properties(nghttp2 PROPERTIES
45+
COMPILE_FLAGS "${WARNCFLAGS}"
46+
VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION}
47+
C_VISIBILITY_PRESET hidden
48+
)
49+
target_include_directories(nghttp2 INTERFACE
50+
"${CMAKE_CURRENT_BINARY_DIR}/includes"
51+
"${CMAKE_CURRENT_SOURCE_DIR}/includes"
52+
)
53+
54+
install(TARGETS nghttp2
55+
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
56+
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
57+
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
58+
endif()
59+
60+
if(HAVE_CUNIT OR ENABLE_STATIC_LIB)
61+
# Static library (for unittests because of symbol visibility)
62+
add_library(nghttp2_static STATIC ${NGHTTP2_SOURCES})
63+
set_target_properties(nghttp2_static PROPERTIES
64+
COMPILE_FLAGS "${WARNCFLAGS}"
65+
VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION}
66+
ARCHIVE_OUTPUT_NAME nghttp2${STATIC_LIB_SUFFIX}
67+
)
68+
target_compile_definitions(nghttp2_static PUBLIC "-DNGHTTP2_STATICLIB")
69+
if(ENABLE_STATIC_LIB)
70+
install(TARGETS nghttp2_static
71+
DESTINATION "${CMAKE_INSTALL_LIBDIR}")
72+
endif()
73+
endif()
74+
75+
76+
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libnghttp2.pc"
77+
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")

‎deps/nghttp2/lib/Makefile.am

+4-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ OBJECTS = nghttp2_pq.c nghttp2_map.c nghttp2_queue.c \
4949
nghttp2_mem.c \
5050
nghttp2_http.c \
5151
nghttp2_rcbuf.c \
52-
nghttp2_debug.c
52+
nghttp2_debug.c \
53+
nghttp2_ksl.c
5354

5455
HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
5556
nghttp2_frame.h \
@@ -65,7 +66,8 @@ HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
6566
nghttp2_mem.h \
6667
nghttp2_http.h \
6768
nghttp2_rcbuf.h \
68-
nghttp2_debug.h
69+
nghttp2_debug.h \
70+
nghttp2_ksl.h
6971

7072
libnghttp2_la_SOURCES = $(HFILES) $(OBJECTS)
7173
libnghttp2_la_LDFLAGS = -no-undefined \

‎deps/nghttp2/lib/Makefile.in

+1,028
Large diffs are not rendered by default.

‎deps/nghttp2/lib/includes/Makefile.in

+658
Large diffs are not rendered by default.

‎deps/nghttp2/lib/includes/nghttp2/nghttp2.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -2851,9 +2851,11 @@ NGHTTP2_EXTERN void nghttp2_session_del(nghttp2_session *session);
28512851
*
28522852
* This function retrieves the highest prioritized frame from the
28532853
* outbound queue and sends it to the remote peer. It does this as
2854-
* many as possible until the user callback
2854+
* many times as possible until the user callback
28552855
* :type:`nghttp2_send_callback` returns
2856-
* :enum:`NGHTTP2_ERR_WOULDBLOCK` or the outbound queue becomes empty.
2856+
* :enum:`NGHTTP2_ERR_WOULDBLOCK`, the outbound queue becomes empty
2857+
* or flow control is triggered (remote window size becomes depleted
2858+
* or maximum number of concurrent streams is reached).
28572859
* This function calls several callback functions which are passed
28582860
* when initializing the |session|. Here is the simple time chart
28592861
* which tells when each callback is invoked:

‎deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@
2929
* @macro
3030
* Version number of the nghttp2 library release
3131
*/
32-
#define NGHTTP2_VERSION "1.41.0"
32+
#define NGHTTP2_VERSION "1.42.0"
3333

3434
/**
3535
* @macro
3636
* Numerical representation of the version number of the nghttp2 library
3737
* release. This is a 24 bit number with 8 bits for major number, 8 bits
3838
* for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
3939
*/
40-
#define NGHTTP2_VERSION_NUM 0x012900
40+
#define NGHTTP2_VERSION_NUM 0x012a00
4141

4242
#endif /* NGHTTP2VER_H */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* nghttp2 - HTTP/2 C Library
3+
*
4+
* Copyright (c) 2012, 2013 Tatsuhiro Tsujikawa
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining
7+
* a copy of this software and associated documentation files (the
8+
* "Software"), to deal in the Software without restriction, including
9+
* without limitation the rights to use, copy, modify, merge, publish,
10+
* distribute, sublicense, and/or sell copies of the Software, and to
11+
* permit persons to whom the Software is furnished to do so, subject to
12+
* the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be
15+
* included in all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21+
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22+
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23+
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24+
*/
25+
#ifndef NGHTTP2VER_H
26+
#define NGHTTP2VER_H
27+
28+
/**
29+
* @macro
30+
* Version number of the nghttp2 library release
31+
*/
32+
#define NGHTTP2_VERSION "@PACKAGE_VERSION@"
33+
34+
/**
35+
* @macro
36+
* Numerical representation of the version number of the nghttp2 library
37+
* release. This is a 24 bit number with 8 bits for major number, 8 bits
38+
* for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
39+
*/
40+
#define NGHTTP2_VERSION_NUM @PACKAGE_VERSION_NUM@
41+
42+
#endif /* NGHTTP2VER_H */

‎deps/nghttp2/lib/nghttp2_buf.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,10 @@ void nghttp2_buf_reset(nghttp2_buf *buf) {
8282
}
8383

8484
void nghttp2_buf_wrap_init(nghttp2_buf *buf, uint8_t *begin, size_t len) {
85-
buf->begin = buf->pos = buf->last = buf->mark = begin;
86-
buf->end = begin + len;
85+
buf->begin = buf->pos = buf->last = buf->mark = buf->end = begin;
86+
if (len) {
87+
buf->end += len;
88+
}
8789
}
8890

8991
static int buf_chain_new(nghttp2_buf_chain **chain, size_t chunk_length,

‎deps/nghttp2/lib/nghttp2_frame.c

+23-5
Original file line numberDiff line numberDiff line change
@@ -818,8 +818,10 @@ int nghttp2_frame_unpack_origin_payload(nghttp2_extension *frame,
818818
size_t len = 0;
819819

820820
origin = frame->payload;
821-
p = payload;
822-
end = p + payloadlen;
821+
p = end = payload;
822+
if (payloadlen) {
823+
end += payloadlen;
824+
}
823825

824826
for (; p != end;) {
825827
if (end - p < 2) {
@@ -897,9 +899,25 @@ nghttp2_settings_entry *nghttp2_frame_iv_copy(const nghttp2_settings_entry *iv,
897899
}
898900

899901
int nghttp2_nv_equal(const nghttp2_nv *a, const nghttp2_nv *b) {
900-
return a->namelen == b->namelen && a->valuelen == b->valuelen &&
901-
memcmp(a->name, b->name, a->namelen) == 0 &&
902-
memcmp(a->value, b->value, a->valuelen) == 0;
902+
if (a->namelen != b->namelen || a->valuelen != b->valuelen) {
903+
return 0;
904+
}
905+
906+
if (a->name == NULL || b->name == NULL) {
907+
assert(a->namelen == 0);
908+
assert(b->namelen == 0);
909+
} else if (memcmp(a->name, b->name, a->namelen) != 0) {
910+
return 0;
911+
}
912+
913+
if (a->value == NULL || b->value == NULL) {
914+
assert(a->valuelen == 0);
915+
assert(b->valuelen == 0);
916+
} else if (memcmp(a->value, b->value, a->valuelen) != 0) {
917+
return 0;
918+
}
919+
920+
return 1;
903921
}
904922

905923
void nghttp2_nv_array_del(nghttp2_nv *nva, nghttp2_mem *mem) {

‎deps/nghttp2/lib/nghttp2_ksl.c

+707
Large diffs are not rendered by default.

‎deps/nghttp2/lib/nghttp2_ksl.h

+315
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,315 @@
1+
/*
2+
* nghttp2 - HTTP/2 C Library
3+
*
4+
* Copyright (c) 2020 nghttp2 contributors
5+
* Copyright (c) 2018 ngtcp2 contributors
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining
8+
* a copy of this software and associated documentation files (the
9+
* "Software"), to deal in the Software without restriction, including
10+
* without limitation the rights to use, copy, modify, merge, publish,
11+
* distribute, sublicense, and/or sell copies of the Software, and to
12+
* permit persons to whom the Software is furnished to do so, subject to
13+
* the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be
16+
* included in all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22+
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23+
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24+
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25+
*/
26+
#ifndef NGHTTP2_KSL_H
27+
#define NGHTTP2_KSL_H
28+
29+
#ifdef HAVE_CONFIG_H
30+
# include <config.h>
31+
#endif /* HAVE_CONFIG_H */
32+
33+
#include <stdlib.h>
34+
35+
#include <nghttp2/nghttp2.h>
36+
37+
/*
38+
* Skip List using single key instead of range.
39+
*/
40+
41+
#define NGHTTP2_KSL_DEGR 16
42+
/* NGHTTP2_KSL_MAX_NBLK is the maximum number of nodes which a single
43+
block can contain. */
44+
#define NGHTTP2_KSL_MAX_NBLK (2 * NGHTTP2_KSL_DEGR - 1)
45+
/* NGHTTP2_KSL_MIN_NBLK is the minimum number of nodes which a single
46+
block other than root must contains. */
47+
#define NGHTTP2_KSL_MIN_NBLK (NGHTTP2_KSL_DEGR - 1)
48+
49+
/*
50+
* nghttp2_ksl_key represents key in nghttp2_ksl.
51+
*/
52+
typedef void nghttp2_ksl_key;
53+
54+
struct nghttp2_ksl_node;
55+
typedef struct nghttp2_ksl_node nghttp2_ksl_node;
56+
57+
struct nghttp2_ksl_blk;
58+
typedef struct nghttp2_ksl_blk nghttp2_ksl_blk;
59+
60+
/*
61+
* nghttp2_ksl_node is a node which contains either nghttp2_ksl_blk or
62+
* opaque data. If a node is an internal node, it contains
63+
* nghttp2_ksl_blk. Otherwise, it has data. The key is stored at the
64+
* location starting at key.
65+
*/
66+
struct nghttp2_ksl_node {
67+
union {
68+
nghttp2_ksl_blk *blk;
69+
void *data;
70+
};
71+
union {
72+
uint64_t align;
73+
/* key is a buffer to include key associated to this node.
74+
Because the length of key is unknown until nghttp2_ksl_init is
75+
called, the actual buffer will be allocated after this
76+
field. */
77+
uint8_t key[1];
78+
};
79+
};
80+
81+
/*
82+
* nghttp2_ksl_blk contains nghttp2_ksl_node objects.
83+
*/
84+
struct nghttp2_ksl_blk {
85+
/* next points to the next block if leaf field is nonzero. */
86+
nghttp2_ksl_blk *next;
87+
/* prev points to the previous block if leaf field is nonzero. */
88+
nghttp2_ksl_blk *prev;
89+
/* n is the number of nodes this object contains in nodes. */
90+
size_t n;
91+
/* leaf is nonzero if this block contains leaf nodes. */
92+
int leaf;
93+
union {
94+
uint64_t align;
95+
/* nodes is a buffer to contain NGHTTP2_KSL_MAX_NBLK
96+
nghttp2_ksl_node objects. Because nghttp2_ksl_node object is
97+
allocated along with the additional variable length key
98+
storage, the size of buffer is unknown until nghttp2_ksl_init is
99+
called. */
100+
uint8_t nodes[1];
101+
};
102+
};
103+
104+
/*
105+
* nghttp2_ksl_compar is a function type which returns nonzero if key
106+
* |lhs| should be placed before |rhs|. It returns 0 otherwise.
107+
*/
108+
typedef int (*nghttp2_ksl_compar)(const nghttp2_ksl_key *lhs,
109+
const nghttp2_ksl_key *rhs);
110+
111+
struct nghttp2_ksl;
112+
typedef struct nghttp2_ksl nghttp2_ksl;
113+
114+
struct nghttp2_ksl_it;
115+
typedef struct nghttp2_ksl_it nghttp2_ksl_it;
116+
117+
/*
118+
* nghttp2_ksl_it is a forward iterator to iterate nodes.
119+
*/
120+
struct nghttp2_ksl_it {
121+
const nghttp2_ksl *ksl;
122+
nghttp2_ksl_blk *blk;
123+
size_t i;
124+
};
125+
126+
/*
127+
* nghttp2_ksl is a deterministic paged skip list.
128+
*/
129+
struct nghttp2_ksl {
130+
/* head points to the root block. */
131+
nghttp2_ksl_blk *head;
132+
/* front points to the first leaf block. */
133+
nghttp2_ksl_blk *front;
134+
/* back points to the last leaf block. */
135+
nghttp2_ksl_blk *back;
136+
nghttp2_ksl_compar compar;
137+
size_t n;
138+
/* keylen is the size of key */
139+
size_t keylen;
140+
/* nodelen is the actual size of nghttp2_ksl_node including key
141+
storage. */
142+
size_t nodelen;
143+
nghttp2_mem *mem;
144+
};
145+
146+
/*
147+
* nghttp2_ksl_init initializes |ksl|. |compar| specifies compare
148+
* function. |keylen| is the length of key.
149+
*
150+
* It returns 0 if it succeeds, or one of the following negative error
151+
* codes:
152+
*
153+
* NGHTTP2_ERR_NOMEM
154+
* Out of memory.
155+
*/
156+
int nghttp2_ksl_init(nghttp2_ksl *ksl, nghttp2_ksl_compar compar, size_t keylen,
157+
nghttp2_mem *mem);
158+
159+
/*
160+
* nghttp2_ksl_free frees resources allocated for |ksl|. If |ksl| is
161+
* NULL, this function does nothing. It does not free the memory
162+
* region pointed by |ksl| itself.
163+
*/
164+
void nghttp2_ksl_free(nghttp2_ksl *ksl);
165+
166+
/*
167+
* nghttp2_ksl_insert inserts |key| with its associated |data|. On
168+
* successful insertion, the iterator points to the inserted node is
169+
* stored in |*it|.
170+
*
171+
* This function returns 0 if it succeeds, or one of the following
172+
* negative error codes:
173+
*
174+
* NGHTTP2_ERR_NOMEM
175+
* Out of memory.
176+
* NGHTTP2_ERR_INVALID_ARGUMENT
177+
* |key| already exists.
178+
*/
179+
int nghttp2_ksl_insert(nghttp2_ksl *ksl, nghttp2_ksl_it *it,
180+
const nghttp2_ksl_key *key, void *data);
181+
182+
/*
183+
* nghttp2_ksl_remove removes the |key| from |ksl|.
184+
*
185+
* This function assigns the iterator to |*it|, which points to the
186+
* node which is located at the right next of the removed node if |it|
187+
* is not NULL. If |key| is not found, no deletion takes place and
188+
* the return value of nghttp2_ksl_end(ksl) is assigned to |*it|.
189+
*
190+
* This function returns 0 if it succeeds, or one of the following
191+
* negative error codes:
192+
*
193+
* NGHTTP2_ERR_INVALID_ARGUMENT
194+
* |key| does not exist.
195+
*/
196+
int nghttp2_ksl_remove(nghttp2_ksl *ksl, nghttp2_ksl_it *it,
197+
const nghttp2_ksl_key *key);
198+
199+
/*
200+
* nghttp2_ksl_lower_bound returns the iterator which points to the
201+
* first node which has the key which is equal to |key| or the last
202+
* node which satisfies !compar(&node->key, key). If there is no such
203+
* node, it returns the iterator which satisfies nghttp2_ksl_it_end(it)
204+
* != 0.
205+
*/
206+
nghttp2_ksl_it nghttp2_ksl_lower_bound(nghttp2_ksl *ksl,
207+
const nghttp2_ksl_key *key);
208+
209+
/*
210+
* nghttp2_ksl_lower_bound_compar works like nghttp2_ksl_lower_bound,
211+
* but it takes custom function |compar| to do lower bound search.
212+
*/
213+
nghttp2_ksl_it nghttp2_ksl_lower_bound_compar(nghttp2_ksl *ksl,
214+
const nghttp2_ksl_key *key,
215+
nghttp2_ksl_compar compar);
216+
217+
/*
218+
* nghttp2_ksl_update_key replaces the key of nodes which has |old_key|
219+
* with |new_key|. |new_key| must be strictly greater than the
220+
* previous node and strictly smaller than the next node.
221+
*/
222+
void nghttp2_ksl_update_key(nghttp2_ksl *ksl, const nghttp2_ksl_key *old_key,
223+
const nghttp2_ksl_key *new_key);
224+
225+
/*
226+
* nghttp2_ksl_begin returns the iterator which points to the first
227+
* node. If there is no node in |ksl|, it returns the iterator which
228+
* satisfies nghttp2_ksl_it_end(it) != 0.
229+
*/
230+
nghttp2_ksl_it nghttp2_ksl_begin(const nghttp2_ksl *ksl);
231+
232+
/*
233+
* nghttp2_ksl_end returns the iterator which points to the node
234+
* following the last node. The returned object satisfies
235+
* nghttp2_ksl_it_end(). If there is no node in |ksl|, it returns the
236+
* iterator which satisfies nghttp2_ksl_it_begin(it) != 0.
237+
*/
238+
nghttp2_ksl_it nghttp2_ksl_end(const nghttp2_ksl *ksl);
239+
240+
/*
241+
* nghttp2_ksl_len returns the number of elements stored in |ksl|.
242+
*/
243+
size_t nghttp2_ksl_len(nghttp2_ksl *ksl);
244+
245+
/*
246+
* nghttp2_ksl_clear removes all elements stored in |ksl|.
247+
*/
248+
void nghttp2_ksl_clear(nghttp2_ksl *ksl);
249+
250+
/*
251+
* nghttp2_ksl_nth_node returns the |n|th node under |blk|.
252+
*/
253+
#define nghttp2_ksl_nth_node(KSL, BLK, N) \
254+
((nghttp2_ksl_node *)(void *)((BLK)->nodes + (KSL)->nodelen * (N)))
255+
256+
/*
257+
* nghttp2_ksl_print prints its internal state in stderr. It assumes
258+
* that the key is of type int64_t. This function should be used for
259+
* the debugging purpose only.
260+
*/
261+
void nghttp2_ksl_print(nghttp2_ksl *ksl);
262+
263+
/*
264+
* nghttp2_ksl_it_init initializes |it|.
265+
*/
266+
void nghttp2_ksl_it_init(nghttp2_ksl_it *it, const nghttp2_ksl *ksl,
267+
nghttp2_ksl_blk *blk, size_t i);
268+
269+
/*
270+
* nghttp2_ksl_it_get returns the data associated to the node which
271+
* |it| points to. It is undefined to call this function when
272+
* nghttp2_ksl_it_end(it) returns nonzero.
273+
*/
274+
void *nghttp2_ksl_it_get(const nghttp2_ksl_it *it);
275+
276+
/*
277+
* nghttp2_ksl_it_next advances the iterator by one. It is undefined
278+
* if this function is called when nghttp2_ksl_it_end(it) returns
279+
* nonzero.
280+
*/
281+
#define nghttp2_ksl_it_next(IT) \
282+
(++(IT)->i == (IT)->blk->n && (IT)->blk->next \
283+
? ((IT)->blk = (IT)->blk->next, (IT)->i = 0) \
284+
: 0)
285+
286+
/*
287+
* nghttp2_ksl_it_prev moves backward the iterator by one. It is
288+
* undefined if this function is called when nghttp2_ksl_it_begin(it)
289+
* returns nonzero.
290+
*/
291+
void nghttp2_ksl_it_prev(nghttp2_ksl_it *it);
292+
293+
/*
294+
* nghttp2_ksl_it_end returns nonzero if |it| points to the beyond the
295+
* last node.
296+
*/
297+
#define nghttp2_ksl_it_end(IT) \
298+
((IT)->blk->n == (IT)->i && (IT)->blk->next == NULL)
299+
300+
/*
301+
* nghttp2_ksl_it_begin returns nonzero if |it| points to the first
302+
* node. |it| might satisfy both nghttp2_ksl_it_begin(&it) and
303+
* nghttp2_ksl_it_end(&it) if the skip list has no node.
304+
*/
305+
int nghttp2_ksl_it_begin(const nghttp2_ksl_it *it);
306+
307+
/*
308+
* nghttp2_ksl_key returns the key of the node which |it| points to.
309+
* It is undefined to call this function when nghttp2_ksl_it_end(it)
310+
* returns nonzero.
311+
*/
312+
#define nghttp2_ksl_it_key(IT) \
313+
((nghttp2_ksl_key *)nghttp2_ksl_nth_node((IT)->ksl, (IT)->blk, (IT)->i)->key)
314+
315+
#endif /* NGHTTP2_KSL_H */

‎deps/nghttp2/lib/nghttp2_map.c

+203-57
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
/*
22
* nghttp2 - HTTP/2 C Library
33
*
4-
* Copyright (c) 2012 Tatsuhiro Tsujikawa
4+
* Copyright (c) 2017 ngtcp2 contributors
5+
* Copyright (c) 2012 nghttp2 contributors
56
*
67
* Permission is hereby granted, free of charge, to any person obtaining
78
* a copy of this software and associated documentation files (the
@@ -25,14 +26,17 @@
2526
#include "nghttp2_map.h"
2627

2728
#include <string.h>
29+
#include <assert.h>
30+
31+
#include "nghttp2_helper.h"
2832

2933
#define INITIAL_TABLE_LENGTH 256
3034

3135
int nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem) {
3236
map->mem = mem;
3337
map->tablelen = INITIAL_TABLE_LENGTH;
3438
map->table =
35-
nghttp2_mem_calloc(mem, map->tablelen, sizeof(nghttp2_map_entry *));
39+
nghttp2_mem_calloc(mem, map->tablelen, sizeof(nghttp2_map_bucket));
3640
if (map->table == NULL) {
3741
return NGHTTP2_ERR_NOMEM;
3842
}
@@ -43,21 +47,51 @@ int nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem) {
4347
}
4448

4549
void nghttp2_map_free(nghttp2_map *map) {
50+
size_t i;
51+
nghttp2_map_bucket *bkt;
52+
53+
if (!map) {
54+
return;
55+
}
56+
57+
for (i = 0; i < map->tablelen; ++i) {
58+
bkt = &map->table[i];
59+
if (bkt->ksl) {
60+
nghttp2_ksl_free(bkt->ksl);
61+
nghttp2_mem_free(map->mem, bkt->ksl);
62+
}
63+
}
64+
4665
nghttp2_mem_free(map->mem, map->table);
4766
}
4867

4968
void nghttp2_map_each_free(nghttp2_map *map,
5069
int (*func)(nghttp2_map_entry *entry, void *ptr),
5170
void *ptr) {
5271
uint32_t i;
72+
nghttp2_map_bucket *bkt;
73+
nghttp2_ksl_it it;
74+
5375
for (i = 0; i < map->tablelen; ++i) {
54-
nghttp2_map_entry *entry;
55-
for (entry = map->table[i]; entry;) {
56-
nghttp2_map_entry *next = entry->next;
57-
func(entry, ptr);
58-
entry = next;
76+
bkt = &map->table[i];
77+
78+
if (bkt->ptr) {
79+
func(bkt->ptr, ptr);
80+
bkt->ptr = NULL;
81+
assert(bkt->ksl == NULL || nghttp2_ksl_len(bkt->ksl) == 0);
82+
continue;
83+
}
84+
85+
if (bkt->ksl) {
86+
for (it = nghttp2_ksl_begin(bkt->ksl); !nghttp2_ksl_it_end(&it);
87+
nghttp2_ksl_it_next(&it)) {
88+
func(nghttp2_ksl_it_get(&it), ptr);
89+
}
90+
91+
nghttp2_ksl_free(bkt->ksl);
92+
nghttp2_mem_free(map->mem, bkt->ksl);
93+
bkt->ksl = NULL;
5994
}
60-
map->table[i] = NULL;
6195
}
6296
}
6397

@@ -66,13 +100,29 @@ int nghttp2_map_each(nghttp2_map *map,
66100
void *ptr) {
67101
int rv;
68102
uint32_t i;
103+
nghttp2_map_bucket *bkt;
104+
nghttp2_ksl_it it;
105+
69106
for (i = 0; i < map->tablelen; ++i) {
70-
nghttp2_map_entry *entry;
71-
for (entry = map->table[i]; entry; entry = entry->next) {
72-
rv = func(entry, ptr);
107+
bkt = &map->table[i];
108+
109+
if (bkt->ptr) {
110+
rv = func(bkt->ptr, ptr);
73111
if (rv != 0) {
74112
return rv;
75113
}
114+
assert(bkt->ksl == NULL || nghttp2_ksl_len(bkt->ksl) == 0);
115+
continue;
116+
}
117+
118+
if (bkt->ksl) {
119+
for (it = nghttp2_ksl_begin(bkt->ksl); !nghttp2_ksl_it_end(&it);
120+
nghttp2_ksl_it_next(&it)) {
121+
rv = func(nghttp2_ksl_it_get(&it), ptr);
122+
if (rv != 0) {
123+
return rv;
124+
}
125+
}
76126
}
77127
}
78128
return 0;
@@ -83,72 +133,133 @@ void nghttp2_map_entry_init(nghttp2_map_entry *entry, key_type key) {
83133
entry->next = NULL;
84134
}
85135

86-
/* Same hash function in android HashMap source code. */
87-
/* The |mod| must be power of 2 */
88-
static uint32_t hash(int32_t key, uint32_t mod) {
89-
uint32_t h = (uint32_t)key;
90-
h ^= (h >> 20) ^ (h >> 12);
91-
h ^= (h >> 7) ^ (h >> 4);
136+
/* FNV1a hash */
137+
static uint32_t hash(key_type key, uint32_t mod) {
138+
uint8_t *p, *end;
139+
uint32_t h = 0x811C9DC5u;
140+
141+
p = (uint8_t *)&key;
142+
end = p + sizeof(key_type);
143+
144+
for (; p != end;) {
145+
h ^= *p++;
146+
h += (h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24);
147+
}
148+
92149
return h & (mod - 1);
93150
}
94151

95-
static int insert(nghttp2_map_entry **table, uint32_t tablelen,
96-
nghttp2_map_entry *entry) {
152+
static int less(const nghttp2_ksl_key *lhs, const nghttp2_ksl_key *rhs) {
153+
return *(key_type *)lhs < *(key_type *)rhs;
154+
}
155+
156+
static int map_insert(nghttp2_map *map, nghttp2_map_bucket *table,
157+
uint32_t tablelen, nghttp2_map_entry *entry) {
97158
uint32_t h = hash(entry->key, tablelen);
98-
if (table[h] == NULL) {
99-
table[h] = entry;
100-
} else {
101-
nghttp2_map_entry *p;
102-
/* We won't allow duplicated key, so check it out. */
103-
for (p = table[h]; p; p = p->next) {
104-
if (p->key == entry->key) {
105-
return NGHTTP2_ERR_INVALID_ARGUMENT;
106-
}
159+
nghttp2_map_bucket *bkt = &table[h];
160+
nghttp2_mem *mem = map->mem;
161+
int rv;
162+
163+
if (bkt->ptr == NULL &&
164+
(bkt->ksl == NULL || nghttp2_ksl_len(bkt->ksl) == 0)) {
165+
bkt->ptr = entry;
166+
return 0;
167+
}
168+
169+
if (!bkt->ksl) {
170+
bkt->ksl = nghttp2_mem_malloc(mem, sizeof(*bkt->ksl));
171+
if (bkt->ksl == NULL) {
172+
return NGHTTP2_ERR_NOMEM;
107173
}
108-
entry->next = table[h];
109-
table[h] = entry;
174+
nghttp2_ksl_init(bkt->ksl, less, sizeof(key_type), mem);
110175
}
111-
return 0;
176+
177+
if (bkt->ptr) {
178+
rv = nghttp2_ksl_insert(bkt->ksl, NULL, &bkt->ptr->key, bkt->ptr);
179+
if (rv != 0) {
180+
return rv;
181+
}
182+
183+
bkt->ptr = NULL;
184+
}
185+
186+
return nghttp2_ksl_insert(bkt->ksl, NULL, &entry->key, entry);
112187
}
113188

114189
/* new_tablelen must be power of 2 */
115-
static int resize(nghttp2_map *map, uint32_t new_tablelen) {
190+
static int map_resize(nghttp2_map *map, uint32_t new_tablelen) {
116191
uint32_t i;
117-
nghttp2_map_entry **new_table;
192+
nghttp2_map_bucket *new_table;
193+
nghttp2_map_bucket *bkt;
194+
nghttp2_ksl_it it;
195+
int rv;
118196

119197
new_table =
120-
nghttp2_mem_calloc(map->mem, new_tablelen, sizeof(nghttp2_map_entry *));
198+
nghttp2_mem_calloc(map->mem, new_tablelen, sizeof(nghttp2_map_bucket));
121199
if (new_table == NULL) {
122200
return NGHTTP2_ERR_NOMEM;
123201
}
124202

125203
for (i = 0; i < map->tablelen; ++i) {
126-
nghttp2_map_entry *entry;
127-
for (entry = map->table[i]; entry;) {
128-
nghttp2_map_entry *next = entry->next;
129-
entry->next = NULL;
130-
/* This function must succeed */
131-
insert(new_table, new_tablelen, entry);
132-
entry = next;
204+
bkt = &map->table[i];
205+
206+
if (bkt->ptr) {
207+
rv = map_insert(map, new_table, new_tablelen, bkt->ptr);
208+
if (rv != 0) {
209+
goto fail;
210+
}
211+
assert(bkt->ksl == NULL || nghttp2_ksl_len(bkt->ksl) == 0);
212+
continue;
213+
}
214+
215+
if (bkt->ksl) {
216+
for (it = nghttp2_ksl_begin(bkt->ksl); !nghttp2_ksl_it_end(&it);
217+
nghttp2_ksl_it_next(&it)) {
218+
rv = map_insert(map, new_table, new_tablelen, nghttp2_ksl_it_get(&it));
219+
if (rv != 0) {
220+
goto fail;
221+
}
222+
}
223+
}
224+
}
225+
226+
for (i = 0; i < map->tablelen; ++i) {
227+
bkt = &map->table[i];
228+
if (bkt->ksl) {
229+
nghttp2_ksl_free(bkt->ksl);
230+
nghttp2_mem_free(map->mem, bkt->ksl);
133231
}
134232
}
233+
135234
nghttp2_mem_free(map->mem, map->table);
136235
map->tablelen = new_tablelen;
137236
map->table = new_table;
138237

139238
return 0;
239+
240+
fail:
241+
for (i = 0; i < new_tablelen; ++i) {
242+
bkt = &new_table[i];
243+
if (bkt->ksl) {
244+
nghttp2_ksl_free(bkt->ksl);
245+
nghttp2_mem_free(map->mem, bkt->ksl);
246+
}
247+
}
248+
249+
return rv;
140250
}
141251

142252
int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_entry *new_entry) {
143253
int rv;
254+
144255
/* Load factor is 0.75 */
145256
if ((map->size + 1) * 4 > map->tablelen * 3) {
146-
rv = resize(map, map->tablelen * 2);
257+
rv = map_resize(map, map->tablelen * 2);
147258
if (rv != 0) {
148259
return rv;
149260
}
150261
}
151-
rv = insert(map->table, map->tablelen, new_entry);
262+
rv = map_insert(map, map->table, map->tablelen, new_entry);
152263
if (rv != 0) {
153264
return rv;
154265
}
@@ -157,33 +268,68 @@ int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_entry *new_entry) {
157268
}
158269

159270
nghttp2_map_entry *nghttp2_map_find(nghttp2_map *map, key_type key) {
160-
uint32_t h;
161-
nghttp2_map_entry *entry;
162-
h = hash(key, map->tablelen);
163-
for (entry = map->table[h]; entry; entry = entry->next) {
164-
if (entry->key == key) {
165-
return entry;
271+
nghttp2_map_bucket *bkt = &map->table[hash(key, map->tablelen)];
272+
nghttp2_ksl_it it;
273+
274+
if (bkt->ptr) {
275+
if (bkt->ptr->key == key) {
276+
return bkt->ptr;
277+
}
278+
return NULL;
279+
}
280+
281+
if (bkt->ksl) {
282+
it = nghttp2_ksl_lower_bound(bkt->ksl, &key);
283+
if (nghttp2_ksl_it_end(&it) ||
284+
*(key_type *)nghttp2_ksl_it_key(&it) != key) {
285+
return NULL;
166286
}
287+
return nghttp2_ksl_it_get(&it);
167288
}
289+
168290
return NULL;
169291
}
170292

171293
int nghttp2_map_remove(nghttp2_map *map, key_type key) {
172-
uint32_t h;
173-
nghttp2_map_entry **dst;
174-
175-
h = hash(key, map->tablelen);
294+
nghttp2_map_bucket *bkt = &map->table[hash(key, map->tablelen)];
295+
int rv;
176296

177-
for (dst = &map->table[h]; *dst; dst = &(*dst)->next) {
178-
if ((*dst)->key != key) {
179-
continue;
297+
if (bkt->ptr) {
298+
if (bkt->ptr->key == key) {
299+
bkt->ptr = NULL;
300+
--map->size;
301+
return 0;
180302
}
303+
return NGHTTP2_ERR_INVALID_ARGUMENT;
304+
}
181305

182-
*dst = (*dst)->next;
306+
if (bkt->ksl) {
307+
rv = nghttp2_ksl_remove(bkt->ksl, NULL, &key);
308+
if (rv != 0) {
309+
return rv;
310+
}
183311
--map->size;
184312
return 0;
185313
}
314+
186315
return NGHTTP2_ERR_INVALID_ARGUMENT;
187316
}
188317

318+
void nghttp2_map_clear(nghttp2_map *map) {
319+
uint32_t i;
320+
nghttp2_map_bucket *bkt;
321+
322+
for (i = 0; i < map->tablelen; ++i) {
323+
bkt = &map->table[i];
324+
bkt->ptr = NULL;
325+
if (bkt->ksl) {
326+
nghttp2_ksl_free(bkt->ksl);
327+
nghttp2_mem_free(map->mem, bkt->ksl);
328+
bkt->ksl = NULL;
329+
}
330+
}
331+
332+
map->size = 0;
333+
}
334+
189335
size_t nghttp2_map_size(nghttp2_map *map) { return map->size; }

‎deps/nghttp2/lib/nghttp2_map.h

+15-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
/*
22
* nghttp2 - HTTP/2 C Library
33
*
4-
* Copyright (c) 2012 Tatsuhiro Tsujikawa
4+
* Copyright (c) 2017 ngtcp2 contributors
5+
* Copyright (c) 2012 nghttp2 contributors
56
*
67
* Permission is hereby granted, free of charge, to any person obtaining
78
* a copy of this software and associated documentation files (the
@@ -30,8 +31,9 @@
3031
#endif /* HAVE_CONFIG_H */
3132

3233
#include <nghttp2/nghttp2.h>
33-
#include "nghttp2_int.h"
34+
3435
#include "nghttp2_mem.h"
36+
#include "nghttp2_ksl.h"
3537

3638
/* Implementation of unordered map */
3739

@@ -46,8 +48,13 @@ typedef struct nghttp2_map_entry {
4648
#endif
4749
} nghttp2_map_entry;
4850

51+
typedef struct nghttp2_map_bucket {
52+
nghttp2_map_entry *ptr;
53+
nghttp2_ksl *ksl;
54+
} nghttp2_map_bucket;
55+
4956
typedef struct {
50-
nghttp2_map_entry **table;
57+
nghttp2_map_bucket *table;
5158
nghttp2_mem *mem;
5259
size_t size;
5360
uint32_t tablelen;
@@ -118,6 +125,11 @@ nghttp2_map_entry *nghttp2_map_find(nghttp2_map *map, key_type key);
118125
*/
119126
int nghttp2_map_remove(nghttp2_map *map, key_type key);
120127

128+
/*
129+
* Removes all entries from |map|.
130+
*/
131+
void nghttp2_map_clear(nghttp2_map *map);
132+
121133
/*
122134
* Returns the number of items stored in the map |map|.
123135
*/

‎deps/nghttp2/lib/nghttp2_session.c

+26-5
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,18 @@ int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
959959
return 0;
960960
}
961961

962+
/* Sending RST_STREAM to an idle stream is subject to protocol
963+
violation. Historically, nghttp2 allows this. In order not to
964+
disrupt the existing applications, we don't error out this case
965+
and simply ignore it. */
966+
if (nghttp2_session_is_my_stream_id(session, stream_id)) {
967+
if ((uint32_t)stream_id >= session->next_stream_id) {
968+
return 0;
969+
}
970+
} else if (session->last_recv_stream_id < stream_id) {
971+
return 0;
972+
}
973+
962974
/* Cancel pending request HEADERS in ob_syn if this RST_STREAM
963975
refers to that stream. */
964976
if (!session->server && nghttp2_session_is_my_stream_id(session, stream_id) &&
@@ -969,8 +981,7 @@ int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
969981
headers_frame = &nghttp2_outbound_queue_top(&session->ob_syn)->frame;
970982
assert(headers_frame->hd.type == NGHTTP2_HEADERS);
971983

972-
if (headers_frame->hd.stream_id <= stream_id &&
973-
(uint32_t)stream_id < session->next_stream_id) {
984+
if (headers_frame->hd.stream_id <= stream_id) {
974985

975986
for (item = session->ob_syn.head; item; item = item->qnext) {
976987
aux_data = &item->aux_data.headers;
@@ -5353,9 +5364,11 @@ static ssize_t inbound_frame_effective_readlen(nghttp2_inbound_frame *iframe,
53535364
return (ssize_t)(readlen);
53545365
}
53555366

5367+
static const uint8_t static_in[] = {0};
5368+
53565369
ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
53575370
size_t inlen) {
5358-
const uint8_t *first = in, *last = in + inlen;
5371+
const uint8_t *first, *last;
53595372
nghttp2_inbound_frame *iframe = &session->iframe;
53605373
size_t readlen;
53615374
ssize_t padlen;
@@ -5366,6 +5379,14 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
53665379
size_t pri_fieldlen;
53675380
nghttp2_mem *mem;
53685381

5382+
if (in == NULL) {
5383+
assert(inlen == 0);
5384+
in = static_in;
5385+
}
5386+
5387+
first = in;
5388+
last = in + inlen;
5389+
53695390
DEBUGF("recv: connection recv_window_size=%d, local_window=%d\n",
53705391
session->recv_window_size, session->local_window_size);
53715392

@@ -7448,8 +7469,8 @@ static int nghttp2_session_upgrade_internal(nghttp2_session *session,
74487469
return NGHTTP2_ERR_INVALID_ARGUMENT;
74497470
}
74507471
/* SETTINGS frame contains too many settings */
7451-
if (settings_payloadlen / NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH
7452-
> session->max_settings) {
7472+
if (settings_payloadlen / NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH >
7473+
session->max_settings) {
74537474
return NGHTTP2_ERR_TOO_MANY_SETTINGS;
74547475
}
74557476
rv = nghttp2_frame_unpack_settings_payload2(&iv, &niv, settings_payload,

‎deps/nghttp2/nghttp2.gyp

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
'lib/nghttp2_hd_huffman_data.c',
4545
'lib/nghttp2_helper.c',
4646
'lib/nghttp2_http.c',
47+
'lib/nghttp2_ksl.c',
4748
'lib/nghttp2_map.c',
4849
'lib/nghttp2_mem.c',
4950
'lib/nghttp2_npn.c',

0 commit comments

Comments
 (0)
Please sign in to comment.