Commit Graph

711 Commits

Author SHA1 Message Date
Tatsuhiro Tsujikawa
ca81d89fe1 Port ngtcp2_map changes 2025-11-03 21:44:05 +09:00
Tatsuhiro Tsujikawa
43b4369fba Fix assertion failure
Fix assertion failure due to the missing check for NGHTTP2_IB_IGN_ALL
state.  Add tests.
2025-09-15 17:56:17 +09:00
Tatsuhiro Tsujikawa
daa4260f61 tests: Swap the positions of expected and actual values 2025-08-24 10:44:30 +09:00
Tatsuhiro Tsujikawa
dfab53ef65 Make glitch counter configurable 2025-08-23 19:49:14 +09:00
Tatsuhiro Tsujikawa
06fb688be2 Add "glitch" counter
Any suspicious activity such as DATA frames to a stream which does not
exist are counted to so called "glitch" counter.  If it increases more
than the configured rate, GOAWAY is sent and the connection is closed.
2025-08-23 17:04:27 +09:00
Tatsuhiro Tsujikawa
7784fa979d Make error handling robust
Stream errors are now promoted to connection errors.  This means that
an event that previously just resets a single stream now closes a
connection entirely.  The promoted errors are mostly implementation
errors.  Some involve HTTP fields, but they are already treated stream
error.  People who care about that should have already raised any
issues.  We do not have any outstanding related issues now, so it
seems OK to treat it as connection error.

We have some contradictory specifications around
nghttp2_on_invalid_header and nghttp2_on_invalid_header2 callbacks.
nghttp2_on_invalid_header says that if it is omitted, a stream is
reset.  Meanwhile, nghttp2_on_invalid_header2 says that if it is
omitted, invalid field is silently ignored.  In actual implementation,
if both omitted, we treat it as stream error.  In practice, it is
often required not to bail out if invalid header is received.  In this
change, if both callbacks are omitted, invalid field is silently
ignored as the documentation of nghttp2_on_invalid_header2 says.  The
connection error promotion is applied here as well.  So if invalid
field is received, and callback returns
NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE, it is treated as connection
error.
2025-08-17 16:50:49 +09:00
Tatsuhiro Tsujikawa
a9b0230e57 Add nghttp2_rand_callback
Add nghttp2_rand_callback.  Seed nghttp2_map with the unpredictable
value from the callback.
2025-07-01 19:25:33 +09:00
Tatsuhiro Tsujikawa
01b16f64f4 Port ngtcp2_map changes 2025-07-01 18:25:24 +09:00
Tatsuhiro Tsujikawa
a158d1dbb4 Bump munit 2025-05-11 21:33:51 +09:00
Tatsuhiro Tsujikawa
6e60f76825 Do not submit RST_STREAM more than once
Do not submit RST_STREAM more than once for a same stream with
nghttp2_submit_rst_stream.  Historically, nghttp2_submit_rst_stream
allows this.  nghttp2 also allows receiving multiple RST_STREAM
frames.  To keep compatibility, nghttp2_submit_rst_stream does not
fail if it attempts to submit RST_STREAM to already closed stream.
2025-05-09 18:41:30 +09:00
Tatsuhiro Tsujikawa
3dd61f8ec3 Remove RFC 7540 priorities
Summary of the behavioral changes in public API functions:

- nghttp2_session_change_stream_priority: This function is noop.  It
  always returns 0.
- nghttp2_session_create_idle_stream: This function is noop.  It
  always returns 0.
- nghttp2_submit_request: pri_spec is ignored.
- nghttp2_submit_request2: pri_spec is ignored.
- nghttp2_submit_headers: pri_spec is ignored.
- nghttp2_submit_priority: This function is noop.  It always returns
  0.
- nghttp2_stream_get_parent: This function always returns NULL.
- nghttp2_stream_get_next_sibling: This function always returns NULL.
- nghttp2_stream_get_previous_sibling: This function always returns
  NULL.
- nghttp2_stream_get_first_child: This function always returns NULL.
- nghttp2_stream_get_weight: This function always returns
  NGHTTP2_DEFAULT_WEIGHT.
- nghttp2_stream_get_sum_dependency_weight: This function always
  returns 0.
2025-01-10 18:29:38 +09:00
Tatsuhiro Tsujikawa
a8d731d81f Bump munit 2025-01-03 13:07:12 +09:00
Tatsuhiro Tsujikawa
01ec93ad0f Remove extra semicolons 2024-10-18 19:29:47 +09:00
Tatsuhiro Tsujikawa
8655d26de4 nghttp2_map: Port ngtcp2 changes 2024-09-10 18:08:24 +09:00
Tatsuhiro Tsujikawa
292bcbca4f Change clang-format options 2024-08-28 18:55:57 +09:00
Tatsuhiro Tsujikawa
80b5d9a131 clang-format 2024-08-02 18:25:33 +09:00
Tatsuhiro Tsujikawa
3f9a980ecb Introduce typed nghttp2_min and nghttp2_max 2024-05-12 09:48:11 +09:00
Tatsuhiro Tsujikawa
4bd5bebc46 Bump munit 2024-04-22 21:03:37 +09:00
Tatsuhiro Tsujikawa
f15e3713ad Bump munit 2024-04-03 19:36:36 +09:00
Tatsuhiro Tsujikawa
f35defd57a Remove stream from queue on deletion
Remove stream from queue on deletion.  Run on_stream_close_callback
before deallocating item in case that a frame is submitted in the
callback which is highly unusual in practice.
2024-03-25 23:15:16 +09:00
Tatsuhiro Tsujikawa
97c4b72b6a Decrement num_idle_streams when opening idle stream 2024-03-25 23:14:04 +09:00
Tatsuhiro Tsujikawa
93c4d8bc34 Introduce nghttp2_ssize API
This commit deprecates all APIs, including structs and callback
functions, that use ssize_t.  New APIs that use nghttp2_ssize are
added as a replacement.  The usage of ssize_t is problematic for
several reasons.  Some platforms do not define ssize_t.  The minimum
value of ssize_t that POSIX requires is -1 which makes nghttp2 error
code out of range.  nghttp2_ssize is an alias of ptrdiff_t that is in
C standard and covers our error code range.

New code should use new nghttp2_ssize APIs.  The existing applications
should consider migrating to new APIs.

The deprecated ssize_t APIs continue to work for backward
compatibility.

Here is the summary of the deprecated APIs and their replacements:

Callback functions:

- nghttp2_data_source_read_callback => nghttp2_data_source_read_callback2
- nghttp2_data_source_read_length_callback => nghttp2_data_source_read_length_callback2
- nghttp2_pack_extension_callback => nghttp2_pack_extension_callback2
- nghttp2_recv_callback => nghttp2_recv_callback2
- nghttp2_select_padding_callback => nghttp2_select_padding_callback2
- nghttp2_send_callback => nghttp2_send_callback2

Structs:

- nghttp2_data_provider => nghttp2_data_provider2

Functions:

- nghttp2_hd_deflate_hd => nghttp2_hd_deflate_hd2
- nghttp2_hd_deflate_hd_vec => nghttp2_hd_deflate_hd_vec2
- nghttp2_hd_inflate_hd2 => nghttp2_hd_inflate_hd3
- nghttp2_pack_settings_payload => nghttp2_pack_settings_payload2
- nghttp2_session_callbacks_set_data_source_read_length_callback =>
  nghttp2_session_callbacks_set_data_source_read_length_callback2
- nghttp2_session_callbacks_set_pack_extension_callback =>
  nghttp2_session_callbacks_set_pack_extension_callback2
- nghttp2_session_callbacks_set_recv_callback =>
  nghttp2_session_callbacks_set_recv_callback2
- nghttp2_session_callbacks_set_select_padding_callback =>
  nghttp2_session_callbacks_set_select_padding_callback2
- nghttp2_session_callbacks_set_send_callback =>
  nghttp2_session_callbacks_set_send_callback2
- nghttp2_session_mem_recv => nghttp2_session_mem_recv2
- nghttp2_session_mem_send => nghttp2_session_mem_send2
- nghttp2_submit_data => nghttp2_submit_data2
- nghttp2_submit_request => nghttp2_submit_request2
- nghttp2_submit_response => nghttp2_submit_response2

For those applications that do not want to see ssize_t in nghttp2.h
header file, define NGHTTP2_NO_SSIZE_T macro before including
nghttp2.h.  It hides all ssize_t APIs.
2024-02-15 18:19:11 +09:00
Tatsuhiro Tsujikawa
3884aa166e Remove munit dependency from nghttp2_test_helper.h 2024-02-14 17:39:10 +09:00
Tatsuhiro Tsujikawa
be8a327258 Migrate to munit from cunit 2024-02-12 14:01:35 +09:00
Tatsuhiro Tsujikawa
5ba03f63c6 Merge pull request #2021 from nghttp2/remove-end-to-end-py
Remove end_to_end.py
2023-12-24 16:09:11 +09:00
Tatsuhiro Tsujikawa
361e5d3066 Remove end_to_end.py 2023-12-24 12:38:00 +09:00
Tatsuhiro Tsujikawa
c306390c93 Add nghttp2_select_alpn and deprecate nghttp2_select_next_protocol 2023-12-24 12:29:07 +09:00
Tatsuhiro Tsujikawa
eaedf85f3e Add API to get and parse RFC 9218 priority 2023-11-05 16:02:05 +09:00
Tatsuhiro Tsujikawa
ec362f77e4 tests: Define NGHTTP2_STATICLIB 2023-10-18 21:30:33 +09:00
Tatsuhiro Tsujikawa
72b4af6143 Rework session management 2023-10-10 22:41:58 +09:00
Tatsuhiro Tsujikawa
98df5b59e5 frame: Make functions that always succeed return void 2023-07-15 16:15:25 +09:00
Tatsuhiro Tsujikawa
cdfb517528 Make functions that always succeed return void 2023-07-15 15:36:50 +09:00
Tatsuhiro Tsujikawa
ce385d3f55 Fix memory leak
This commit fixes memory leak that happens when PUSH_PROMISE or
HEADERS frame cannot be sent, and nghttp2_on_stream_close_callback
fails with a fatal error.  For example, if GOAWAY frame has been
received, a HEADERS frame that opens new stream cannot be sent.

This issue has already been made public via CVE-2023-35945 [1] issued
by envoyproxy/envoy project.  During embargo period, the patch to fix
this bug was accidentally submitted to nghttp2/nghttp2 repository [2].
And they decided to disclose CVE early.  I was notified just 1.5 hours
before disclosure.  I had no time to respond.

PoC described in [1] is quite simple, but I think it is not enough to
trigger this bug.  While it is true that receiving GOAWAY prevents a
client from opening new stream, and nghttp2 enters error handling
branch, in order to cause the memory leak,
nghttp2_session_close_stream function must return a fatal error.
nghttp2 defines 2 fatal error codes:

- NGHTTP2_ERR_NOMEM
- NGHTTP2_ERR_CALLBACK_FAILURE

NGHTTP2_ERR_NOMEM, as its name suggests, indicates out of memory.  It
is unlikely that a process gets short of memory with this simple PoC
scenario unless application does something memory heavy processing.

NGHTTP2_ERR_CALLBACK_FAILURE is returned from application defined
callback function (nghttp2_on_stream_close_callback, in this case),
which indicates something fatal happened inside a callback, and a
connection must be closed immediately without any further action.  As
nghttp2_on_stream_close_error_callback documentation says, any error
code other than 0 or NGHTTP2_ERR_CALLBACK_FAILURE is treated as fatal
error code.  More specifically, it is treated as if
NGHTTP2_ERR_CALLBACK_FAILURE is returned.  I guess that envoy returns
NGHTTP2_ERR_CALLBACK_FAILURE or other error code which is translated
into NGHTTP2_ERR_CALLBACK_FAILURE.

[1] https://github.com/envoyproxy/envoy/security/advisories/GHSA-jfxv-29pc-x22r
[2] https://github.com/nghttp2/nghttp2/pull/1929
2023-07-14 21:37:37 +09:00
Tatsuhiro Tsujikawa
2ee33fe8cd Import ngtcp2/sfparse, Structured Field Values parser 2023-04-22 17:42:12 +09:00
Tatsuhiro Tsujikawa
4bb4ff06e3 Fix function signature 2023-04-21 18:02:33 +09:00
Tatsuhiro Tsujikawa
8610758e14 Include stdio.h to workaround error due to legacy CUnit snprintf macro 2023-04-21 17:46:06 +09:00
Tatsuhiro Tsujikawa
c03cd59274 Fix compile errors with clang-15 2023-03-15 21:57:45 +09:00
Tatsuhiro Tsujikawa
2ca0bb0a2f Remove src/includes 2022-12-26 19:45:33 +09:00
Tatsuhiro Tsujikawa
eb06e33e38 Add nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation 2022-09-07 16:34:12 +09:00
Tatsuhiro Tsujikawa
2da1713200 Define BUILDING_NGHTTP2 for tests to make linker work 2022-07-05 18:10:35 +09:00
Tatsuhiro Tsujikawa
7f4c2f9ec3 Add nghttp2_check_header_value_rfc9113
Add nghttp2_check_header_value_rfc9113 which verifies the additional
rule imposed by RFC 9113, section 8.2.1, that is a field value must
not start or end with 0x20(SPC) or 0x09(HTAB).

libnghttp2 uses this new function internally.
2022-06-24 19:44:13 +09:00
Tatsuhiro Tsujikawa
d115f580e2 Do not parse priority header field value included in PUSH_PROMISE 2022-06-23 22:44:01 +09:00
Tatsuhiro Tsujikawa
41955b3878 Allow server to override RFC 9218 stream priority
Allow server to override RFC 9218 stream priority with
nghttp2_session_change_extpri_stream_priority.
2022-06-16 19:49:53 +09:00
Tatsuhiro Tsujikawa
8c2386c221 Add a server option to fallback to RFC 7540 priorities
Add nghttp2_option_set_server_fallback_rfc7540_priorities.  If it is
set to nonzero, and server submits SETTINGS_NO_RFC7540_PRIORITIES = 1,
but it does not receive SETTINGS_NO_RFC7540_PRIORITIES from client,
server falls back to RFC 7540 priorities.  Only minimal set of
features are enabled in this fallback case.
2022-06-14 23:47:42 +09:00
Tatsuhiro Tsujikawa
b0fbb93022 Add PRIORITY_UPDATE frame support
This commit adds PRIORITY_UPDATE frame support.  Applying incoming
PRIORITY_UPDATE frame to server push stream is not implemented.

Client can send PRIORITY_UPDATE frame by calling
nghttp2_submit_priority_update.

Server opts to receive PRIORITY_UPDATE frame by the call
nghttp2_option_set_builtin_recv_extension_type(option,
NGHTTP2_PRIORITY_UPDATE), and passing the option to
nghttp2_session_server_new2 or nghttp2_session_server_new3.
2022-06-13 20:04:30 +09:00
Tatsuhiro Tsujikawa
c10a55588b Implement RFC 9218 extensible prioritization scheme
This commit implements RFC 9218 extensible prioritization scheme.  It
is enabled when a local endpoint submits
SETTINGS_NO_RFC7540_PRIORITIES = 1.  This commit only handles priority
signal in HTTP request header field.  Priority header field in
PUSH_PROMISE is not supported.

HTTP messaging must be enabled to take advantage of this
prioritization scheme because HTTP fields are not parsed if HTTP
messaging is disabled.
2022-06-12 16:06:04 +09:00
Tatsuhiro Tsujikawa
ac3f846f29 Merge pull request #1727 from nghttp2/host-in-resp-field-section
Do not verify host field specific characters for response field
2022-06-11 17:33:44 +09:00
Tatsuhiro Tsujikawa
a26bad3324 Do not verify host field specific characters for response field
Do not verify host field specific characters for response field
section because host field in response field section is undefined.
2022-06-11 17:08:51 +09:00
Tatsuhiro Tsujikawa
9812a0bc81 Add SETTINGS_NO_RFC7540_PRIORITIES
Add SETTINGS_NO_RFC7540_PRIORITIES to disable RFC7540 priorities.  If
disabled, streams are served in FIFO.
2022-06-11 16:50:07 +09:00
Tatsuhiro Tsujikawa
129daeff6f Fix stream stall when initial window size is decreased
Fix the bug that causes a stream to stall when a receiver, which
enables nghttp2_option_set_no_auto_window_update() option on, sends
SETTINGS_INITIAL_WINDOW_SIZE with the value that is less than or equal
to the amount of data received.  Previously, in this particular case,
when SETTINGS is acknowledged by the sender, the receiver does not try
to send WINDOW_UPDATE frame.  The sender is unable to send more data
because its stream-level window size is smaller than or equal to the
amount of data it has sent.
2022-03-12 17:05:42 +09:00