diff options
author | aszh07 <mail2szahir@gmail.com> | 2024-03-21 15:33:32 +0530 |
---|---|---|
committer | Steve Sakoman <steve@sakoman.com> | 2024-04-05 07:23:58 -0700 |
commit | cf1c9d3daaccb5909d19d1cf4baaa6a152e0e73a (patch) | |
tree | 34ce7b2faf0214e245486515bdb258ae80dc3474 | |
parent | b6f6c729453cb88961488e3332046517e2fe99bb (diff) | |
download | poky-cf1c9d3daaccb5909d19d1cf4baaa6a152e0e73a.tar.gz |
nghttp2: fix CVE-2023-44487
The HTTP/2 protocol allows a denial of service (server resource consumption)
because request cancellation can reset many streams quickly, as exploited in
the wild in August through October 2023.
References:
https://nvd.nist.gov/vuln/detail/CVE-2023-44487
https://github.com/nghttp2/nghttp2/commit/72b4af6143681f528f1d237b21a9a7aee1738832
(From OE-Core rev: 0156b57dcdb2e5acdd9421a7c24c235f13da2d97)
Signed-off-by: Zahir Hussain <zahir.basha@kpit.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
-rw-r--r-- | meta/recipes-support/nghttp2/nghttp2/CVE-2023-44487.patch | 927 | ||||
-rw-r--r-- | meta/recipes-support/nghttp2/nghttp2_1.47.0.bb | 1 |
2 files changed, 928 insertions, 0 deletions
diff --git a/meta/recipes-support/nghttp2/nghttp2/CVE-2023-44487.patch b/meta/recipes-support/nghttp2/nghttp2/CVE-2023-44487.patch new file mode 100644 index 0000000000..3cba83307c --- /dev/null +++ b/meta/recipes-support/nghttp2/nghttp2/CVE-2023-44487.patch | |||
@@ -0,0 +1,927 @@ | |||
1 | From 72b4af6143681f528f1d237b21a9a7aee1738832 Mon Sep 17 00:00:00 2001 | ||
2 | From: Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | ||
3 | Date: Sun, 1 Oct 2023 00:05:01 +0900 | ||
4 | Subject: [PATCH] Rework session management | ||
5 | |||
6 | CVE: CVE-2023-44487 | ||
7 | |||
8 | Upstream-Status: Backport [https://github.com/nghttp2/nghttp2/commit/72b4af6143681f528f1d237b21a9a7aee1738832] | ||
9 | |||
10 | Signed-off-by: Zahir Hussain zahir.basha@kpit.com | ||
11 | Signed-off-by: aszh07 <mail2szahir@gmail.com> | ||
12 | --- | ||
13 | CMakeLists.txt | 4 ++ | ||
14 | cmakeconfig.h.in | 9 +++ | ||
15 | configure.ac | 21 +++++++ | ||
16 | doc/Makefile.am | 1 + | ||
17 | lib/CMakeLists.txt | 2 + | ||
18 | lib/Makefile.am | 4 ++ | ||
19 | lib/includes/nghttp2/nghttp2.h | 17 ++++++ | ||
20 | lib/nghttp2_option.c | 7 +++ | ||
21 | lib/nghttp2_ratelim.c | 75 ++++++++++++++++++++++++ | ||
22 | lib/nghttp2_ratelim.h | 57 ++++++++++++++++++ | ||
23 | lib/nghttp2_session.c | 34 ++++++++++- | ||
24 | lib/nghttp2_session.h | 12 +++- | ||
25 | lib/nghttp2_time.c | 62 ++++++++++++++++++++ | ||
26 | lib/nghttp2_time.h | 38 ++++++++++++ | ||
27 | tests/nghttp2_ratelim_test.c | 101 ++++++++++++++++++++++++++++++++ | ||
28 | tests/nghttp2_ratelim_test.h | 35 +++++++++++ | ||
29 | tests/nghttp2_session_test.c | 103 +++++++++++++++++++++++++++++++++ | ||
30 | tests/nghttp2_session_test.h | 1 + | ||
31 | tests/CMakeLists.txt | 1 + | ||
32 | tests/Makefile.am | 6 +- | ||
33 | lib/nghttp2_option.h | 6 ++ | ||
34 | tests/main.c | 7 ++- | ||
35 | 22 files changed, 598 insertions(+), 5 deletions(-) | ||
36 | create mode 100644 lib/nghttp2_ratelim.c | ||
37 | create mode 100644 lib/nghttp2_ratelim.h | ||
38 | create mode 100644 lib/nghttp2_time.c | ||
39 | create mode 100644 lib/nghttp2_time.h | ||
40 | create mode 100644 tests/nghttp2_ratelim_test.c | ||
41 | create mode 100644 tests/nghttp2_ratelim_test.h | ||
42 | |||
43 | --- a/CMakeLists.txt | ||
44 | +++ b/CMakeLists.txt | ||
45 | @@ -262,6 +262,7 @@ check_include_file("netinet/in.h" HAVE | ||
46 | check_include_file("pwd.h" HAVE_PWD_H) | ||
47 | check_include_file("sys/socket.h" HAVE_SYS_SOCKET_H) | ||
48 | check_include_file("sys/time.h" HAVE_SYS_TIME_H) | ||
49 | +check_include_file("sysinfoapi.h" HAVE_SYSINFOAPI_H) | ||
50 | check_include_file("syslog.h" HAVE_SYSLOG_H) | ||
51 | check_include_file("time.h" HAVE_TIME_H) | ||
52 | check_include_file("unistd.h" HAVE_UNISTD_H) | ||
53 | @@ -302,8 +303,11 @@ check_type_size("time_t" SIZEOF_TIME_T) | ||
54 | include(CheckFunctionExists) | ||
55 | check_function_exists(_Exit HAVE__EXIT) | ||
56 | check_function_exists(accept4 HAVE_ACCEPT4) | ||
57 | +check_function_exists(clock_gettime HAVE_CLOCK_GETTIME) | ||
58 | check_function_exists(mkostemp HAVE_MKOSTEMP) | ||
59 | |||
60 | +check_symbol_exists(GetTickCount64 sysinfoapi.h HAVE_GETTICKCOUNT64) | ||
61 | + | ||
62 | include(CheckSymbolExists) | ||
63 | # XXX does this correctly detect initgroups (un)availability on cygwin? | ||
64 | check_symbol_exists(initgroups grp.h HAVE_DECL_INITGROUPS) | ||
65 | --- a/cmakeconfig.h.in | ||
66 | +++ b/cmakeconfig.h.in | ||
67 | @@ -34,9 +34,15 @@ | ||
68 | /* Define to 1 if you have the `accept4` function. */ | ||
69 | #cmakedefine HAVE_ACCEPT4 1 | ||
70 | |||
71 | +/* Define to 1 if you have the `clock_gettime` function. */ | ||
72 | +#cmakedefine HAVE_CLOCK_GETTIME 1 | ||
73 | + | ||
74 | /* Define to 1 if you have the `mkostemp` function. */ | ||
75 | #cmakedefine HAVE_MKOSTEMP 1 | ||
76 | |||
77 | +/* Define to 1 if you have the `GetTickCount64` function. */ | ||
78 | +#cmakedefine HAVE_GETTICKCOUNT64 1 | ||
79 | + | ||
80 | /* Define to 1 if you have the `initgroups` function. */ | ||
81 | #cmakedefine01 HAVE_DECL_INITGROUPS | ||
82 | |||
83 | @@ -73,6 +79,9 @@ | ||
84 | /* Define to 1 if you have the <sys/time.h> header file. */ | ||
85 | #cmakedefine HAVE_SYS_TIME_H 1 | ||
86 | |||
87 | +/* Define to 1 if you have the <sysinfoapi.h> header file. */ | ||
88 | +#cmakedefine HAVE_SYSINFOAPI_H 1 | ||
89 | + | ||
90 | /* Define to 1 if you have the <syslog.h> header file. */ | ||
91 | #cmakedefine HAVE_SYSLOG_H 1 | ||
92 | |||
93 | --- a/configure.ac | ||
94 | +++ b/configure.ac | ||
95 | @@ -607,6 +607,7 @@ AC_CHECK_HEADERS([ \ | ||
96 | string.h \ | ||
97 | sys/socket.h \ | ||
98 | sys/time.h \ | ||
99 | + sysinfoapi.h \ | ||
100 | syslog.h \ | ||
101 | time.h \ | ||
102 | unistd.h \ | ||
103 | @@ -681,6 +682,7 @@ AC_FUNC_STRNLEN | ||
104 | AC_CHECK_FUNCS([ \ | ||
105 | _Exit \ | ||
106 | accept4 \ | ||
107 | + clock_gettime \ | ||
108 | dup2 \ | ||
109 | getcwd \ | ||
110 | getpwnam \ | ||
111 | @@ -706,6 +708,25 @@ AC_CHECK_FUNCS([ \ | ||
112 | AC_CHECK_FUNC([timerfd_create], | ||
113 | [have_timerfd_create=yes], [have_timerfd_create=no]) | ||
114 | |||
115 | +AC_MSG_CHECKING([checking for GetTickCount64]) | ||
116 | +AC_LINK_IFELSE([AC_LANG_PROGRAM( | ||
117 | +[[ | ||
118 | +#include <sysinfoapi.h> | ||
119 | +]], | ||
120 | +[[ | ||
121 | +GetTickCount64(); | ||
122 | +]])], | ||
123 | +[have_gettickcount64=yes], | ||
124 | +[have_gettickcount64=no]) | ||
125 | + | ||
126 | +if test "x${have_gettickcount64}" = "xyes"; then | ||
127 | + AC_MSG_RESULT([yes]) | ||
128 | + AC_DEFINE([HAVE_GETTICKCOUNT64], [1], | ||
129 | + [Define to 1 if you have `GetTickCount64` function.]) | ||
130 | +else | ||
131 | + AC_MSG_RESULT([no]) | ||
132 | +fi | ||
133 | + | ||
134 | # For cygwin: we can link initgroups, so AC_CHECK_FUNCS succeeds, but | ||
135 | # cygwin disables initgroups due to feature test macro magic with our | ||
136 | # configuration. FreeBSD declares initgroups() in unistd.h. | ||
137 | --- a/doc/Makefile.am | ||
138 | +++ b/doc/Makefile.am | ||
139 | @@ -69,6 +69,7 @@ APIDOCS= \ | ||
140 | nghttp2_option_set_user_recv_extension_type.rst \ | ||
141 | nghttp2_option_set_max_outbound_ack.rst \ | ||
142 | nghttp2_option_set_max_settings.rst \ | ||
143 | + nghttp2_option_set_stream_reset_rate_limit.rst \ | ||
144 | nghttp2_pack_settings_payload.rst \ | ||
145 | nghttp2_priority_spec_check_default.rst \ | ||
146 | nghttp2_priority_spec_default_init.rst \ | ||
147 | --- a/lib/CMakeLists.txt | ||
148 | +++ b/lib/CMakeLists.txt | ||
149 | @@ -23,6 +23,8 @@ set(NGHTTP2_SOURCES | ||
150 | nghttp2_mem.c | ||
151 | nghttp2_http.c | ||
152 | nghttp2_rcbuf.c | ||
153 | + nghttp2_ratelim.c | ||
154 | + nghttp2_time.c | ||
155 | nghttp2_debug.c | ||
156 | ) | ||
157 | |||
158 | --- a/lib/Makefile.am | ||
159 | +++ b/lib/Makefile.am | ||
160 | @@ -49,6 +49,8 @@ OBJECTS = nghttp2_pq.c nghttp2_map.c ngh | ||
161 | nghttp2_mem.c \ | ||
162 | nghttp2_http.c \ | ||
163 | nghttp2_rcbuf.c \ | ||
164 | + nghttp2_ratelim.c \ | ||
165 | + nghttp2_time.c \ | ||
166 | nghttp2_debug.c | ||
167 | |||
168 | HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \ | ||
169 | @@ -65,6 +67,8 @@ HFILES = nghttp2_pq.h nghttp2_int.h nght | ||
170 | nghttp2_mem.h \ | ||
171 | nghttp2_http.h \ | ||
172 | nghttp2_rcbuf.h \ | ||
173 | + nghttp2_ratelim.h \ | ||
174 | + nghttp2_time.h \ | ||
175 | nghttp2_debug.h | ||
176 | |||
177 | libnghttp2_la_SOURCES = $(HFILES) $(OBJECTS) | ||
178 | --- a/lib/includes/nghttp2/nghttp2.h | ||
179 | +++ b/lib/includes/nghttp2/nghttp2.h | ||
180 | @@ -2763,6 +2763,23 @@ nghttp2_session_client_new2(nghttp2_sess | ||
181 | /** | ||
182 | * @function | ||
183 | * | ||
184 | + * This function sets the rate limit for the incoming stream reset | ||
185 | + * (RST_STREAM frame). It is server use only. It is a token-bucket | ||
186 | + * based rate limiter. |burst| specifies the number of tokens that is | ||
187 | + * initially available. The maximum number of tokens is capped to | ||
188 | + * this value. |rate| specifies the number of tokens that are | ||
189 | + * regenerated per second. An incoming RST_STREAM consumes one token. | ||
190 | + * If there is no token available, GOAWAY is sent to tear down the | ||
191 | + * connection. |burst| and |rate| default to 1000 and 33 | ||
192 | + * respectively. | ||
193 | + */ | ||
194 | +NGHTTP2_EXTERN void | ||
195 | +nghttp2_option_set_stream_reset_rate_limit(nghttp2_option *option, | ||
196 | + uint64_t burst, uint64_t rate); | ||
197 | + | ||
198 | +/** | ||
199 | + * @function | ||
200 | + * | ||
201 | * Like `nghttp2_session_server_new()`, but with additional options | ||
202 | * specified in the |option|. | ||
203 | * | ||
204 | --- a/lib/nghttp2_option.c | ||
205 | +++ b/lib/nghttp2_option.c | ||
206 | @@ -126,3 +126,10 @@ void nghttp2_option_set_max_settings(ngh | ||
207 | option->opt_set_mask |= NGHTTP2_OPT_MAX_SETTINGS; | ||
208 | option->max_settings = val; | ||
209 | } | ||
210 | + | ||
211 | +void nghttp2_option_set_stream_reset_rate_limit(nghttp2_option *option, | ||
212 | + uint64_t burst, uint64_t rate) { | ||
213 | + option->opt_set_mask |= NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT; | ||
214 | + option->stream_reset_burst = burst; | ||
215 | + option->stream_reset_rate = rate; | ||
216 | +} | ||
217 | --- /dev/null | ||
218 | +++ b/lib/nghttp2_ratelim.c | ||
219 | @@ -0,0 +1,75 @@ | ||
220 | +/* | ||
221 | + * nghttp2 - HTTP/2 C Library | ||
222 | + * | ||
223 | + * Copyright (c) 2023 nghttp2 contributors | ||
224 | + * | ||
225 | + * Permission is hereby granted, free of charge, to any person obtaining | ||
226 | + * a copy of this software and associated documentation files (the | ||
227 | + * "Software"), to deal in the Software without restriction, including | ||
228 | + * without limitation the rights to use, copy, modify, merge, publish, | ||
229 | + * distribute, sublicense, and/or sell copies of the Software, and to | ||
230 | + * permit persons to whom the Software is furnished to do so, subject to | ||
231 | + * the following conditions: | ||
232 | + * | ||
233 | + * The above copyright notice and this permission notice shall be | ||
234 | + * included in all copies or substantial portions of the Software. | ||
235 | + * | ||
236 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
237 | + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
238 | + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
239 | + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
240 | + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
241 | + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
242 | + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
243 | + */ | ||
244 | +#include "nghttp2_ratelim.h" | ||
245 | +#include "nghttp2_helper.h" | ||
246 | + | ||
247 | +void nghttp2_ratelim_init(nghttp2_ratelim *rl, uint64_t burst, uint64_t rate) { | ||
248 | + rl->val = rl->burst = burst; | ||
249 | + rl->rate = rate; | ||
250 | + rl->tstamp = 0; | ||
251 | +} | ||
252 | + | ||
253 | +void nghttp2_ratelim_update(nghttp2_ratelim *rl, uint64_t tstamp) { | ||
254 | + uint64_t d, gain; | ||
255 | + | ||
256 | + if (tstamp == rl->tstamp) { | ||
257 | + return; | ||
258 | + } | ||
259 | + | ||
260 | + if (tstamp > rl->tstamp) { | ||
261 | + d = tstamp - rl->tstamp; | ||
262 | + } else { | ||
263 | + d = 1; | ||
264 | + } | ||
265 | + | ||
266 | + rl->tstamp = tstamp; | ||
267 | + | ||
268 | + if (UINT64_MAX / d < rl->rate) { | ||
269 | + rl->val = rl->burst; | ||
270 | + | ||
271 | + return; | ||
272 | + } | ||
273 | + | ||
274 | + gain = rl->rate * d; | ||
275 | + | ||
276 | + if (UINT64_MAX - gain < rl->val) { | ||
277 | + rl->val = rl->burst; | ||
278 | + | ||
279 | + return; | ||
280 | + } | ||
281 | + | ||
282 | + rl->val += gain; | ||
283 | + rl->val = nghttp2_min(rl->val, rl->burst); | ||
284 | +} | ||
285 | + | ||
286 | +int nghttp2_ratelim_drain(nghttp2_ratelim *rl, uint64_t n) { | ||
287 | + if (rl->val < n) { | ||
288 | + return -1; | ||
289 | + } | ||
290 | + | ||
291 | + rl->val -= n; | ||
292 | + | ||
293 | + return 0; | ||
294 | +} | ||
295 | --- /dev/null | ||
296 | +++ b/lib/nghttp2_ratelim.h | ||
297 | @@ -0,0 +1,57 @@ | ||
298 | +/* | ||
299 | + * nghttp2 - HTTP/2 C Library | ||
300 | + * | ||
301 | + * Copyright (c) 2023 nghttp2 contributors | ||
302 | + * | ||
303 | + * Permission is hereby granted, free of charge, to any person obtaining | ||
304 | + * a copy of this software and associated documentation files (the | ||
305 | + * "Software"), to deal in the Software without restriction, including | ||
306 | + * without limitation the rights to use, copy, modify, merge, publish, | ||
307 | + * distribute, sublicense, and/or sell copies of the Software, and to | ||
308 | + * permit persons to whom the Software is furnished to do so, subject to | ||
309 | + * the following conditions: | ||
310 | + * | ||
311 | + * The above copyright notice and this permission notice shall be | ||
312 | + * included in all copies or substantial portions of the Software. | ||
313 | + * | ||
314 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
315 | + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
316 | + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
317 | + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
318 | + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
319 | + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
320 | + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
321 | + */ | ||
322 | +#ifndef NGHTTP2_RATELIM_H | ||
323 | +#define NGHTTP2_RATELIM_H | ||
324 | + | ||
325 | +#ifdef HAVE_CONFIG_H | ||
326 | +# include <config.h> | ||
327 | +#endif /* HAVE_CONFIG_H */ | ||
328 | + | ||
329 | +#include <nghttp2/nghttp2.h> | ||
330 | + | ||
331 | +typedef struct nghttp2_ratelim { | ||
332 | + /* burst is the maximum value of val. */ | ||
333 | + uint64_t burst; | ||
334 | + /* rate is the amount of value that is regenerated per 1 tstamp. */ | ||
335 | + uint64_t rate; | ||
336 | + /* val is the amount of value available to drain. */ | ||
337 | + uint64_t val; | ||
338 | + /* tstamp is the last timestamp in second resolution that is known | ||
339 | + to this object. */ | ||
340 | + uint64_t tstamp; | ||
341 | +} nghttp2_ratelim; | ||
342 | + | ||
343 | +/* nghttp2_ratelim_init initializes |rl| with the given parameters. */ | ||
344 | +void nghttp2_ratelim_init(nghttp2_ratelim *rl, uint64_t burst, uint64_t rate); | ||
345 | + | ||
346 | +/* nghttp2_ratelim_update updates rl->val with the current |tstamp| | ||
347 | + given in second resolution. */ | ||
348 | +void nghttp2_ratelim_update(nghttp2_ratelim *rl, uint64_t tstamp); | ||
349 | + | ||
350 | +/* nghttp2_ratelim_drain drains |n| from rl->val. It returns 0 if it | ||
351 | + succeeds, or -1. */ | ||
352 | +int nghttp2_ratelim_drain(nghttp2_ratelim *rl, uint64_t n); | ||
353 | + | ||
354 | +#endif /* NGHTTP2_RATELIM_H */ | ||
355 | --- a/lib/nghttp2_session.c | ||
356 | +++ b/lib/nghttp2_session.c | ||
357 | @@ -36,6 +36,7 @@ | ||
358 | #include "nghttp2_option.h" | ||
359 | #include "nghttp2_http.h" | ||
360 | #include "nghttp2_pq.h" | ||
361 | +#include "nghttp2_time.h" | ||
362 | #include "nghttp2_debug.h" | ||
363 | |||
364 | /* | ||
365 | @@ -443,6 +444,10 @@ static int session_new(nghttp2_session * | ||
366 | NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS; | ||
367 | (*session_ptr)->pending_enable_push = 1; | ||
368 | |||
369 | + nghttp2_ratelim_init(&(*session_ptr)->stream_reset_ratelim, | ||
370 | + NGHTTP2_DEFAULT_STREAM_RESET_BURST, | ||
371 | + NGHTTP2_DEFAULT_STREAM_RESET_RATE); | ||
372 | + | ||
373 | if (server) { | ||
374 | (*session_ptr)->server = 1; | ||
375 | } | ||
376 | @@ -527,6 +532,12 @@ static int session_new(nghttp2_session * | ||
377 | option->max_settings) { | ||
378 | (*session_ptr)->max_settings = option->max_settings; | ||
379 | } | ||
380 | + | ||
381 | + if (option->opt_set_mask & NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT) { | ||
382 | + nghttp2_ratelim_init(&(*session_ptr)->stream_reset_ratelim, | ||
383 | + option->stream_reset_burst, | ||
384 | + option->stream_reset_rate); | ||
385 | + } | ||
386 | } | ||
387 | |||
388 | rv = nghttp2_hd_deflate_init2(&(*session_ptr)->hd_deflater, | ||
389 | @@ -4144,6 +4155,23 @@ static int session_process_priority_fram | ||
390 | return nghttp2_session_on_priority_received(session, frame); | ||
391 | } | ||
392 | |||
393 | +static int session_update_stream_reset_ratelim(nghttp2_session *session) { | ||
394 | + if (!session->server || (session->goaway_flags & NGHTTP2_GOAWAY_SUBMITTED)) { | ||
395 | + return 0; | ||
396 | + } | ||
397 | + | ||
398 | + nghttp2_ratelim_update(&session->stream_reset_ratelim, | ||
399 | + nghttp2_time_now_sec()); | ||
400 | + | ||
401 | + if (nghttp2_ratelim_drain(&session->stream_reset_ratelim, 1) == 0) { | ||
402 | + return 0; | ||
403 | + } | ||
404 | + | ||
405 | + return nghttp2_session_add_goaway(session, session->last_recv_stream_id, | ||
406 | + NGHTTP2_INTERNAL_ERROR, NULL, 0, | ||
407 | + NGHTTP2_GOAWAY_AUX_NONE); | ||
408 | +} | ||
409 | + | ||
410 | int nghttp2_session_on_rst_stream_received(nghttp2_session *session, | ||
411 | nghttp2_frame *frame) { | ||
412 | int rv; | ||
413 | @@ -4173,7 +4201,8 @@ int nghttp2_session_on_rst_stream_receiv | ||
414 | if (nghttp2_is_fatal(rv)) { | ||
415 | return rv; | ||
416 | } | ||
417 | - return 0; | ||
418 | + | ||
419 | + return session_update_stream_reset_ratelim(session); | ||
420 | } | ||
421 | |||
422 | static int session_process_rst_stream_frame(nghttp2_session *session) { | ||
423 | @@ -6965,6 +6994,9 @@ int nghttp2_session_add_goaway(nghttp2_s | ||
424 | nghttp2_mem_free(mem, item); | ||
425 | return rv; | ||
426 | } | ||
427 | + | ||
428 | + session->goaway_flags |= NGHTTP2_GOAWAY_SUBMITTED; | ||
429 | + | ||
430 | return 0; | ||
431 | } | ||
432 | |||
433 | --- a/lib/nghttp2_session.h | ||
434 | +++ b/lib/nghttp2_session.h | ||
435 | @@ -39,6 +39,7 @@ | ||
436 | #include "nghttp2_buf.h" | ||
437 | #include "nghttp2_callbacks.h" | ||
438 | #include "nghttp2_mem.h" | ||
439 | +#include "nghttp2_ratelim.h" | ||
440 | |||
441 | /* The global variable for tests where we want to disable strict | ||
442 | preface handling. */ | ||
443 | @@ -102,6 +103,10 @@ typedef struct { | ||
444 | /* The default value of maximum number of concurrent streams. */ | ||
445 | #define NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS 0xffffffffu | ||
446 | |||
447 | +/* The default values for stream reset rate limiter. */ | ||
448 | +#define NGHTTP2_DEFAULT_STREAM_RESET_BURST 1000 | ||
449 | +#define NGHTTP2_DEFAULT_STREAM_RESET_RATE 33 | ||
450 | + | ||
451 | /* Internal state when receiving incoming frame */ | ||
452 | typedef enum { | ||
453 | /* Receiving frame header */ | ||
454 | @@ -176,7 +181,9 @@ typedef enum { | ||
455 | /* Flag means GOAWAY was sent */ | ||
456 | NGHTTP2_GOAWAY_SENT = 0x4, | ||
457 | /* Flag means GOAWAY was received */ | ||
458 | - NGHTTP2_GOAWAY_RECV = 0x8 | ||
459 | + NGHTTP2_GOAWAY_RECV = 0x8, | ||
460 | + /* Flag means GOAWAY has been submitted at least once */ | ||
461 | + NGHTTP2_GOAWAY_SUBMITTED = 0x10 | ||
462 | } nghttp2_goaway_flag; | ||
463 | |||
464 | /* nghttp2_inflight_settings stores the SETTINGS entries which local | ||
465 | @@ -230,6 +237,9 @@ struct nghttp2_session { | ||
466 | /* Queue of In-flight SETTINGS values. SETTINGS bearing ACK is not | ||
467 | considered as in-flight. */ | ||
468 | nghttp2_inflight_settings *inflight_settings_head; | ||
469 | + /* Stream reset rate limiter. If receiving excessive amount of | ||
470 | + stream resets, GOAWAY will be sent. */ | ||
471 | + nghttp2_ratelim stream_reset_ratelim; | ||
472 | /* The number of outgoing streams. This will be capped by | ||
473 | remote_settings.max_concurrent_streams. */ | ||
474 | size_t num_outgoing_streams; | ||
475 | --- /dev/null | ||
476 | +++ b/lib/nghttp2_time.c | ||
477 | @@ -0,0 +1,62 @@ | ||
478 | +/* | ||
479 | + * nghttp2 - HTTP/2 C Library | ||
480 | + * | ||
481 | + * Copyright (c) 2023 nghttp2 contributors | ||
482 | + * | ||
483 | + * Permission is hereby granted, free of charge, to any person obtaining | ||
484 | + * a copy of this software and associated documentation files (the | ||
485 | + * "Software"), to deal in the Software without restriction, including | ||
486 | + * without limitation the rights to use, copy, modify, merge, publish, | ||
487 | + * distribute, sublicense, and/or sell copies of the Software, and to | ||
488 | + * permit persons to whom the Software is furnished to do so, subject to | ||
489 | + * the following conditions: | ||
490 | + * | ||
491 | + * The above copyright notice and this permission notice shall be | ||
492 | + * included in all copies or substantial portions of the Software. | ||
493 | + * | ||
494 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
495 | + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
496 | + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
497 | + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
498 | + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
499 | + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
500 | + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
501 | + */ | ||
502 | +#include "nghttp2_time.h" | ||
503 | + | ||
504 | +#ifdef HAVE_TIME_H | ||
505 | +# include <time.h> | ||
506 | +#endif /* HAVE_TIME_H */ | ||
507 | + | ||
508 | +#ifdef HAVE_SYSINFOAPI_H | ||
509 | +# include <sysinfoapi.h> | ||
510 | +#endif /* HAVE_SYSINFOAPI_H */ | ||
511 | + | ||
512 | +#ifndef HAVE_GETTICKCOUNT64 | ||
513 | +static uint64_t time_now_sec(void) { | ||
514 | + time_t t = time(NULL); | ||
515 | + | ||
516 | + if (t == -1) { | ||
517 | + return 0; | ||
518 | + } | ||
519 | + | ||
520 | + return (uint64_t)t; | ||
521 | +} | ||
522 | +#endif /* HAVE_GETTICKCOUNT64 */ | ||
523 | + | ||
524 | +#ifdef HAVE_CLOCK_GETTIME | ||
525 | +uint64_t nghttp2_time_now_sec(void) { | ||
526 | + struct timespec tp; | ||
527 | + int rv = clock_gettime(CLOCK_MONOTONIC, &tp); | ||
528 | + | ||
529 | + if (rv == -1) { | ||
530 | + return time_now_sec(); | ||
531 | + } | ||
532 | + | ||
533 | + return (uint64_t)tp.tv_sec; | ||
534 | +} | ||
535 | +#elif defined(HAVE_GETTICKCOUNT64) | ||
536 | +uint64_t nghttp2_time_now_sec(void) { return GetTickCount64() / 1000; } | ||
537 | +#else /* !HAVE_CLOCK_GETTIME && !HAVE_GETTICKCOUNT64 */ | ||
538 | +uint64_t nghttp2_time_now_sec(void) { return time_now_sec(); } | ||
539 | +#endif /* !HAVE_CLOCK_GETTIME && !HAVE_GETTICKCOUNT64 */ | ||
540 | --- /dev/null | ||
541 | +++ b/lib/nghttp2_time.h | ||
542 | @@ -0,0 +1,38 @@ | ||
543 | +/* | ||
544 | + * nghttp2 - HTTP/2 C Library | ||
545 | + * | ||
546 | + * Copyright (c) 2023 nghttp2 contributors | ||
547 | + * | ||
548 | + * Permission is hereby granted, free of charge, to any person obtaining | ||
549 | + * a copy of this software and associated documentation files (the | ||
550 | + * "Software"), to deal in the Software without restriction, including | ||
551 | + * without limitation the rights to use, copy, modify, merge, publish, | ||
552 | + * distribute, sublicense, and/or sell copies of the Software, and to | ||
553 | + * permit persons to whom the Software is furnished to do so, subject to | ||
554 | + * the following conditions: | ||
555 | + * | ||
556 | + * The above copyright notice and this permission notice shall be | ||
557 | + * included in all copies or substantial portions of the Software. | ||
558 | + * | ||
559 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
560 | + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
561 | + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
562 | + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
563 | + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
564 | + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
565 | + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
566 | + */ | ||
567 | +#ifndef NGHTTP2_TIME_H | ||
568 | +#define NGHTTP2_TIME_H | ||
569 | + | ||
570 | +#ifdef HAVE_CONFIG_H | ||
571 | +# include <config.h> | ||
572 | +#endif /* HAVE_CONFIG_H */ | ||
573 | + | ||
574 | +#include <nghttp2/nghttp2.h> | ||
575 | + | ||
576 | +/* nghttp2_time_now_sec returns seconds from implementation-specific | ||
577 | + timepoint. If it is unable to get seconds, it returns 0. */ | ||
578 | +uint64_t nghttp2_time_now_sec(void); | ||
579 | + | ||
580 | +#endif /* NGHTTP2_TIME_H */ | ||
581 | --- /dev/null | ||
582 | +++ b/tests/nghttp2_ratelim_test.c | ||
583 | @@ -0,0 +1,101 @@ | ||
584 | +/* | ||
585 | + * nghttp2 - HTTP/2 C Library | ||
586 | + * | ||
587 | + * Copyright (c) 2023 nghttp2 contributors | ||
588 | + * | ||
589 | + * Permission is hereby granted, free of charge, to any person obtaining | ||
590 | + * a copy of this software and associated documentation files (the | ||
591 | + * "Software"), to deal in the Software without restriction, including | ||
592 | + * without limitation the rights to use, copy, modify, merge, publish, | ||
593 | + * distribute, sublicense, and/or sell copies of the Software, and to | ||
594 | + * permit persons to whom the Software is furnished to do so, subject to | ||
595 | + * the following conditions: | ||
596 | + * | ||
597 | + * The above copyright notice and this permission notice shall be | ||
598 | + * included in all copies or substantial portions of the Software. | ||
599 | + * | ||
600 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
601 | + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
602 | + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
603 | + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
604 | + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
605 | + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
606 | + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
607 | + */ | ||
608 | +#include "nghttp2_ratelim_test.h" | ||
609 | + | ||
610 | +#include <stdio.h> | ||
611 | + | ||
612 | +#include <CUnit/CUnit.h> | ||
613 | + | ||
614 | +#include "nghttp2_ratelim.h" | ||
615 | + | ||
616 | +void test_nghttp2_ratelim_update(void) { | ||
617 | + nghttp2_ratelim rl; | ||
618 | + | ||
619 | + nghttp2_ratelim_init(&rl, 1000, 21); | ||
620 | + | ||
621 | + CU_ASSERT(1000 == rl.val); | ||
622 | + CU_ASSERT(1000 == rl.burst); | ||
623 | + CU_ASSERT(21 == rl.rate); | ||
624 | + CU_ASSERT(0 == rl.tstamp); | ||
625 | + | ||
626 | + nghttp2_ratelim_update(&rl, 999); | ||
627 | + | ||
628 | + CU_ASSERT(1000 == rl.val); | ||
629 | + CU_ASSERT(999 == rl.tstamp); | ||
630 | + | ||
631 | + nghttp2_ratelim_drain(&rl, 100); | ||
632 | + | ||
633 | + CU_ASSERT(900 == rl.val); | ||
634 | + | ||
635 | + nghttp2_ratelim_update(&rl, 1000); | ||
636 | + | ||
637 | + CU_ASSERT(921 == rl.val); | ||
638 | + | ||
639 | + nghttp2_ratelim_update(&rl, 1002); | ||
640 | + | ||
641 | + CU_ASSERT(963 == rl.val); | ||
642 | + | ||
643 | + nghttp2_ratelim_update(&rl, 1004); | ||
644 | + | ||
645 | + CU_ASSERT(1000 == rl.val); | ||
646 | + CU_ASSERT(1004 == rl.tstamp); | ||
647 | + | ||
648 | + /* timer skew */ | ||
649 | + nghttp2_ratelim_init(&rl, 1000, 21); | ||
650 | + nghttp2_ratelim_update(&rl, 1); | ||
651 | + | ||
652 | + CU_ASSERT(1000 == rl.val); | ||
653 | + | ||
654 | + nghttp2_ratelim_update(&rl, 0); | ||
655 | + | ||
656 | + CU_ASSERT(1000 == rl.val); | ||
657 | + | ||
658 | + /* rate * duration overflow */ | ||
659 | + nghttp2_ratelim_init(&rl, 1000, 100); | ||
660 | + nghttp2_ratelim_drain(&rl, 999); | ||
661 | + | ||
662 | + CU_ASSERT(1 == rl.val); | ||
663 | + | ||
664 | + nghttp2_ratelim_update(&rl, UINT64_MAX); | ||
665 | + | ||
666 | + CU_ASSERT(1000 == rl.val); | ||
667 | + | ||
668 | + /* val + rate * duration overflow */ | ||
669 | + nghttp2_ratelim_init(&rl, UINT64_MAX - 1, 2); | ||
670 | + nghttp2_ratelim_update(&rl, 1); | ||
671 | + | ||
672 | + CU_ASSERT(UINT64_MAX - 1 == rl.val); | ||
673 | +} | ||
674 | + | ||
675 | +void test_nghttp2_ratelim_drain(void) { | ||
676 | + nghttp2_ratelim rl; | ||
677 | + | ||
678 | + nghttp2_ratelim_init(&rl, 100, 7); | ||
679 | + | ||
680 | + CU_ASSERT(-1 == nghttp2_ratelim_drain(&rl, 101)); | ||
681 | + CU_ASSERT(0 == nghttp2_ratelim_drain(&rl, 51)); | ||
682 | + CU_ASSERT(0 == nghttp2_ratelim_drain(&rl, 49)); | ||
683 | + CU_ASSERT(-1 == nghttp2_ratelim_drain(&rl, 1)); | ||
684 | +} | ||
685 | --- /dev/null | ||
686 | +++ b/tests/nghttp2_ratelim_test.h | ||
687 | @@ -0,0 +1,35 @@ | ||
688 | +/* | ||
689 | + * nghttp2 - HTTP/2 C Library | ||
690 | + * | ||
691 | + * Copyright (c) 2023 nghttp2 contributors | ||
692 | + * | ||
693 | + * Permission is hereby granted, free of charge, to any person obtaining | ||
694 | + * a copy of this software and associated documentation files (the | ||
695 | + * "Software"), to deal in the Software without restriction, including | ||
696 | + * without limitation the rights to use, copy, modify, merge, publish, | ||
697 | + * distribute, sublicense, and/or sell copies of the Software, and to | ||
698 | + * permit persons to whom the Software is furnished to do so, subject to | ||
699 | + * the following conditions: | ||
700 | + * | ||
701 | + * The above copyright notice and this permission notice shall be | ||
702 | + * included in all copies or substantial portions of the Software. | ||
703 | + * | ||
704 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
705 | + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
706 | + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
707 | + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
708 | + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
709 | + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
710 | + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
711 | + */ | ||
712 | +#ifndef NGHTTP2_RATELIM_TEST_H | ||
713 | +#define NGHTTP2_RATELIM_TEST_H | ||
714 | + | ||
715 | +#ifdef HAVE_CONFIG_H | ||
716 | +# include <config.h> | ||
717 | +#endif /* HAVE_CONFIG_H */ | ||
718 | + | ||
719 | +void test_nghttp2_ratelim_update(void); | ||
720 | +void test_nghttp2_ratelim_drain(void); | ||
721 | + | ||
722 | +#endif /* NGHTTP2_RATELIM_TEST_H */ | ||
723 | --- a/tests/nghttp2_session_test.c | ||
724 | +++ b/tests/nghttp2_session_test.c | ||
725 | @@ -10813,6 +10813,109 @@ void test_nghttp2_session_set_stream_use | ||
726 | nghttp2_session_del(session); | ||
727 | } | ||
728 | |||
729 | +void test_nghttp2_session_stream_reset_ratelim(void) { | ||
730 | + nghttp2_session *session; | ||
731 | + nghttp2_session_callbacks callbacks; | ||
732 | + nghttp2_frame frame; | ||
733 | + ssize_t rv; | ||
734 | + nghttp2_bufs bufs; | ||
735 | + nghttp2_buf *buf; | ||
736 | + nghttp2_mem *mem; | ||
737 | + size_t i; | ||
738 | + nghttp2_hd_deflater deflater; | ||
739 | + size_t nvlen; | ||
740 | + nghttp2_nv *nva; | ||
741 | + int32_t stream_id; | ||
742 | + nghttp2_outbound_item *item; | ||
743 | + nghttp2_option *option; | ||
744 | + | ||
745 | + mem = nghttp2_mem_default(); | ||
746 | + frame_pack_bufs_init(&bufs); | ||
747 | + | ||
748 | + memset(&callbacks, 0, sizeof(nghttp2_session_callbacks)); | ||
749 | + callbacks.send_callback = null_send_callback; | ||
750 | + | ||
751 | + nghttp2_option_new(&option); | ||
752 | + nghttp2_option_set_stream_reset_rate_limit( | ||
753 | + option, NGHTTP2_DEFAULT_STREAM_RESET_BURST, 0); | ||
754 | + | ||
755 | + nghttp2_session_server_new2(&session, &callbacks, NULL, option); | ||
756 | + | ||
757 | + nghttp2_frame_settings_init(&frame.settings, NGHTTP2_FLAG_NONE, NULL, 0); | ||
758 | + rv = nghttp2_frame_pack_settings(&bufs, &frame.settings); | ||
759 | + | ||
760 | + CU_ASSERT(0 == rv); | ||
761 | + | ||
762 | + nghttp2_frame_settings_free(&frame.settings, mem); | ||
763 | + | ||
764 | + buf = &bufs.head->buf; | ||
765 | + rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_buf_len(buf)); | ||
766 | + | ||
767 | + CU_ASSERT((ssize_t)nghttp2_buf_len(buf) == rv); | ||
768 | + | ||
769 | + /* Send SETTINGS ACK */ | ||
770 | + rv = nghttp2_session_send(session); | ||
771 | + | ||
772 | + CU_ASSERT(0 == rv); | ||
773 | + | ||
774 | + nghttp2_hd_deflate_init(&deflater, mem); | ||
775 | + | ||
776 | + for (i = 0; i < NGHTTP2_DEFAULT_STREAM_RESET_BURST + 2; ++i) { | ||
777 | + stream_id = (int32_t)(i * 2 + 1); | ||
778 | + | ||
779 | + nghttp2_bufs_reset(&bufs); | ||
780 | + | ||
781 | + /* HEADERS */ | ||
782 | + nvlen = ARRLEN(reqnv); | ||
783 | + nghttp2_nv_array_copy(&nva, reqnv, nvlen, mem); | ||
784 | + nghttp2_frame_headers_init(&frame.headers, NGHTTP2_FLAG_END_HEADERS, | ||
785 | + stream_id, NGHTTP2_HCAT_HEADERS, NULL, nva, | ||
786 | + nvlen); | ||
787 | + rv = nghttp2_frame_pack_headers(&bufs, &frame.headers, &deflater); | ||
788 | + | ||
789 | + CU_ASSERT(0 == rv); | ||
790 | + | ||
791 | + nghttp2_frame_headers_free(&frame.headers, mem); | ||
792 | + | ||
793 | + buf = &bufs.head->buf; | ||
794 | + rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_buf_len(buf)); | ||
795 | + | ||
796 | + CU_ASSERT((ssize_t)nghttp2_buf_len(buf) == rv); | ||
797 | + | ||
798 | + nghttp2_bufs_reset(&bufs); | ||
799 | + | ||
800 | + /* RST_STREAM */ | ||
801 | + nghttp2_frame_rst_stream_init(&frame.rst_stream, stream_id, | ||
802 | + NGHTTP2_NO_ERROR); | ||
803 | + nghttp2_frame_pack_rst_stream(&bufs, &frame.rst_stream); | ||
804 | + nghttp2_frame_rst_stream_free(&frame.rst_stream); | ||
805 | + | ||
806 | + buf = &bufs.head->buf; | ||
807 | + rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_buf_len(buf)); | ||
808 | + | ||
809 | + CU_ASSERT((ssize_t)nghttp2_buf_len(buf) == rv); | ||
810 | + | ||
811 | + if (i < NGHTTP2_DEFAULT_STREAM_RESET_BURST) { | ||
812 | + CU_ASSERT(0 == nghttp2_outbound_queue_size(&session->ob_reg)); | ||
813 | + | ||
814 | + continue; | ||
815 | + } | ||
816 | + | ||
817 | + CU_ASSERT(1 == nghttp2_outbound_queue_size(&session->ob_reg)); | ||
818 | + | ||
819 | + item = nghttp2_session_get_next_ob_item(session); | ||
820 | + | ||
821 | + CU_ASSERT(NGHTTP2_GOAWAY == item->frame.hd.type); | ||
822 | + CU_ASSERT(NGHTTP2_DEFAULT_STREAM_RESET_BURST * 2 + 1 == | ||
823 | + item->frame.goaway.last_stream_id); | ||
824 | + } | ||
825 | + | ||
826 | + nghttp2_hd_deflate_free(&deflater); | ||
827 | + nghttp2_session_del(session); | ||
828 | + nghttp2_bufs_free(&bufs); | ||
829 | + nghttp2_option_del(option); | ||
830 | +} | ||
831 | + | ||
832 | static void check_nghttp2_http_recv_headers_fail( | ||
833 | nghttp2_session *session, nghttp2_hd_deflater *deflater, int32_t stream_id, | ||
834 | int stream_state, const nghttp2_nv *nva, size_t nvlen) { | ||
835 | --- a/tests/nghttp2_session_test.h | ||
836 | +++ b/tests/nghttp2_session_test.h | ||
837 | @@ -160,6 +160,7 @@ void test_nghttp2_session_removed_closed | ||
838 | void test_nghttp2_session_pause_data(void); | ||
839 | void test_nghttp2_session_no_closed_streams(void); | ||
840 | void test_nghttp2_session_set_stream_user_data(void); | ||
841 | +void test_nghttp2_session_stream_reset_ratelim(void); | ||
842 | void test_nghttp2_http_mandatory_headers(void); | ||
843 | void test_nghttp2_http_content_length(void); | ||
844 | void test_nghttp2_http_content_length_mismatch(void); | ||
845 | --- a/tests/CMakeLists.txt | ||
846 | +++ b/tests/CMakeLists.txt | ||
847 | @@ -21,6 +21,7 @@ if(HAVE_CUNIT) | ||
848 | nghttp2_npn_test.c | ||
849 | nghttp2_helper_test.c | ||
850 | nghttp2_buf_test.c | ||
851 | + nghttp2_ratelim_test.c | ||
852 | ) | ||
853 | |||
854 | add_executable(main EXCLUDE_FROM_ALL | ||
855 | --- a/tests/Makefile.am | ||
856 | +++ b/tests/Makefile.am | ||
857 | @@ -40,14 +40,16 @@ OBJECTS = main.c nghttp2_pq_test.c nghtt | ||
858 | nghttp2_hd_test.c \ | ||
859 | nghttp2_npn_test.c \ | ||
860 | nghttp2_helper_test.c \ | ||
861 | - nghttp2_buf_test.c | ||
862 | + nghttp2_buf_test.c \ | ||
863 | + nghttp2_ratelim_test.c | ||
864 | |||
865 | HFILES = nghttp2_pq_test.h nghttp2_map_test.h nghttp2_queue_test.h \ | ||
866 | nghttp2_session_test.h \ | ||
867 | nghttp2_frame_test.h nghttp2_stream_test.h nghttp2_hd_test.h \ | ||
868 | nghttp2_npn_test.h nghttp2_helper_test.h \ | ||
869 | nghttp2_test_helper.h \ | ||
870 | - nghttp2_buf_test.h | ||
871 | + nghttp2_buf_test.h \ | ||
872 | + nghttp2_ratelim_test.h | ||
873 | |||
874 | main_SOURCES = $(HFILES) $(OBJECTS) | ||
875 | |||
876 | --- a/lib/nghttp2_option.h | ||
877 | +++ b/lib/nghttp2_option.h | ||
878 | @@ -68,6 +68,7 @@ typedef enum { | ||
879 | NGHTTP2_OPT_NO_CLOSED_STREAMS = 1 << 10, | ||
880 | NGHTTP2_OPT_MAX_OUTBOUND_ACK = 1 << 11, | ||
881 | NGHTTP2_OPT_MAX_SETTINGS = 1 << 12, | ||
882 | + NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT = 1 << 15, | ||
883 | } nghttp2_option_flag; | ||
884 | |||
885 | /** | ||
886 | @@ -75,6 +76,11 @@ typedef enum { | ||
887 | */ | ||
888 | struct nghttp2_option { | ||
889 | /** | ||
890 | + * NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT | ||
891 | + */ | ||
892 | + uint64_t stream_reset_burst; | ||
893 | + uint64_t stream_reset_rate; | ||
894 | + /** | ||
895 | * NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH | ||
896 | */ | ||
897 | size_t max_send_header_block_length; | ||
898 | --- a/tests/main.c | ||
899 | +++ b/tests/main.c | ||
900 | @@ -40,6 +40,7 @@ | ||
901 | #include "nghttp2_npn_test.h" | ||
902 | #include "nghttp2_helper_test.h" | ||
903 | #include "nghttp2_buf_test.h" | ||
904 | +#include "nghttp2_ratelim_test.h" | ||
905 | |||
906 | extern int nghttp2_enable_strict_preface; | ||
907 | |||
908 | @@ -323,6 +324,8 @@ int main() { | ||
909 | test_nghttp2_session_no_closed_streams) || | ||
910 | !CU_add_test(pSuite, "session_set_stream_user_data", | ||
911 | test_nghttp2_session_set_stream_user_data) || | ||
912 | + !CU_add_test(pSuite, "session_stream_reset_ratelim", | ||
913 | + test_nghttp2_session_stream_reset_ratelim) || | ||
914 | !CU_add_test(pSuite, "http_mandatory_headers", | ||
915 | test_nghttp2_http_mandatory_headers) || | ||
916 | !CU_add_test(pSuite, "http_content_length", | ||
917 | @@ -418,7 +421,9 @@ int main() { | ||
918 | !CU_add_test(pSuite, "bufs_advance", test_nghttp2_bufs_advance) || | ||
919 | !CU_add_test(pSuite, "bufs_next_present", | ||
920 | test_nghttp2_bufs_next_present) || | ||
921 | - !CU_add_test(pSuite, "bufs_realloc", test_nghttp2_bufs_realloc)) { | ||
922 | + !CU_add_test(pSuite, "bufs_realloc", test_nghttp2_bufs_realloc) || | ||
923 | + !CU_add_test(pSuite, "ratelim_update", test_nghttp2_ratelim_update) || | ||
924 | + !CU_add_test(pSuite, "ratelim_drain", test_nghttp2_ratelim_drain)) { | ||
925 | CU_cleanup_registry(); | ||
926 | return (int)CU_get_error(); | ||
927 | } | ||
diff --git a/meta/recipes-support/nghttp2/nghttp2_1.47.0.bb b/meta/recipes-support/nghttp2/nghttp2_1.47.0.bb index 0b9091f7e8..b67313b5c2 100644 --- a/meta/recipes-support/nghttp2/nghttp2_1.47.0.bb +++ b/meta/recipes-support/nghttp2/nghttp2_1.47.0.bb | |||
@@ -10,6 +10,7 @@ SRC_URI = "\ | |||
10 | https://github.com/nghttp2/nghttp2/releases/download/v${PV}/nghttp2-${PV}.tar.xz \ | 10 | https://github.com/nghttp2/nghttp2/releases/download/v${PV}/nghttp2-${PV}.tar.xz \ |
11 | file://0001-fetch-ocsp-response-use-python3.patch \ | 11 | file://0001-fetch-ocsp-response-use-python3.patch \ |
12 | file://CVE-2023-35945.patch \ | 12 | file://CVE-2023-35945.patch \ |
13 | file://CVE-2023-44487.patch \ | ||
13 | " | 14 | " |
14 | SRC_URI[sha256sum] = "68271951324554c34501b85190f22f2221056db69f493afc3bbac8e7be21e7cc" | 15 | SRC_URI[sha256sum] = "68271951324554c34501b85190f22f2221056db69f493afc3bbac8e7be21e7cc" |
15 | 16 | ||