Commit Graph

116 Commits

Author SHA1 Message Date
Tatsuhiro Tsujikawa f23e34fa3c Handle response in nghttp2_on_begin_frame_callback
Previously, nghttp2_session_end_request_headers_received assumes
stream is still writable (in other words, local endpoint has not sent
END_STREAM).  But this assumption is false, because application can
send response in nghttp2_on_begin_frame_callback.  Probably, this
assumption was made before the callback was introduced.  This commit
addresses this issue.  Since all
nghttp2_session_end_*_headers_received functions are identical, we
refactored them into one function.
2015-11-27 22:50:13 +09:00
Tatsuhiro Tsujikawa 4960583637 Increase NGHTTP2_MAX_OBQ_FLOOD_ITEM to avoid false positives 2015-10-25 16:23:29 +09:00
Tatsuhiro Tsujikawa ce74a30990 Use -fvisibility=hidden for internal functions
This will improve performance since we can avoid indirect call of
internal functions.  The downside is we now require libnghttp2 static
library to run unit tests.
2015-10-23 00:08:15 +09:00
Tatsuhiro Tsujikawa cea76226b1 Avoid excessive WINDOW_UPDATE queuing 2015-10-01 01:19:57 +09:00
Tatsuhiro Tsujikawa d22ced77c0 Return fatal error if flooding is detected to close session immediately
This change adds new return error code from nghttp2_session_mem_recv
and nghttp2_session_recv functions, namely NGHTTP2_ERR_FLOODED.  It is
fatal error, and is returned when flooding was detected.
2015-09-30 22:19:03 +09:00
Tatsuhiro Tsujikawa 0cb8c82125 Detect flooding and tear down session 2015-09-30 00:44:08 +09:00
Tatsuhiro Tsujikawa 28fe3e7e89 More warning flags for --enable-werror 2015-09-23 16:49:45 +09:00
Tatsuhiro Tsujikawa 928a81885c Limit the number of incoming reserved (remote) streams
RFC 7540 does not enforce any limit on the number of incoming reserved
streams (in RFC 7540 terms, streams in reserved (remote) state).  This
only affects client side, since only server can push streams.
Malicious server can push arbitrary number of streams, and make
client's memory exhausted.  The new option,
nghttp2_set_max_reserved_remote_streams, can set the maximum number of
such incoming streams to avoid possible memory exhaustion.  If this
option is set, and pushed streams are automatically closed on
reception, without calling user provided callback, if they exceed the
given limit.  The default value is 200.  If session is configured as
server side, this option has no effect.  Server can control the number
of streams to push.
2015-08-23 21:43:41 +09:00
Tatsuhiro Tsujikawa 5b59e46e2b Rewrite priority handling
We now use priority queue per stream, which contains the stream which
has ready to send a frame, or one of its descendants have a frame to
send.  We maintain invariant that if a stream is queued, then its
ancestors are also queued (except for root).  When we re-schedule
stream after transmission, we re-schedule all ancestors, so that
streams on the other path can get a chance to send.  This is basically
the same mechanism h2o project uses, but there are differences in the
details.
2015-08-17 22:35:50 +09:00
Tatsuhiro Tsujikawa d1e49a196d Remove restriction in regard to number of stream in dependency tree
Previously, the number of stream in one dependency tree (not including
root) is limited to 120.  This is due to the fact that we use
recursive calls to traverse trees.  Now we replaced recursive calls
with loop, we can remove this limitation.  Also now all streams are
descendant of root stream, rather than linked list of individual
subtree root.
2015-08-15 00:53:09 +09:00
Tatsuhiro Tsujikawa 7f71fed963 Allow multiple in-flight SETTINGS 2015-07-23 00:36:00 +09:00
Tatsuhiro Tsujikawa 2224b98c9c Remove duplicated dependency validation in nghttp2_session_reprioritize_stream 2015-06-21 16:31:30 +09:00
Tatsuhiro Tsujikawa e63d6e490a Merge branch 'master' into v1.0.0
Conflicts:
	lib/nghttp2_option.h
	lib/nghttp2_session.h
	src/HttpServer.cc
2015-05-08 19:21:51 +09:00
Alexis La Goutte a62778d6b0 fix comma at end of enumerator list [-Wpedantic] 2015-04-30 07:49:55 +02:00
Tatsuhiro Tsujikawa 1ad1fe6005 Merge branch 'master' into v1.0.0 2015-04-28 22:48:34 +09:00
Tatsuhiro Tsujikawa c41f413978 Fix compile error with --enable-werror 2015-04-25 02:23:01 +09:00
Tatsuhiro Tsujikawa e38dd37667 Update doc 2015-04-25 01:00:02 +09:00
Tatsuhiro Tsujikawa f2cf2b625c Replace priority queue with linear queue where possible
After reviewing codebase, only queue for DATA frames requires
priorities.  Other frames can be replaced multiple linear queues.
Replacing priority queue with linear queue allows us to simplify
codebase a bit; for example, now nghttp2_session.next_seq is gone.
2015-04-25 00:56:46 +09:00
Tatsuhiro Tsujikawa 5937b4b6f7 Merge branch 'master' into v1.0.0 2015-04-19 23:13:38 +09:00
Tatsuhiro Tsujikawa dc335b9025 Improve weight handling a bit 2015-04-16 21:38:13 +09:00
Tatsuhiro Tsujikawa d0c27d5229 Send 24 bytes client magic byte string by library
Previously nghttp2_session_send() and nghttp2_session_mem_send() did
not send 24 bytes client magic byte string (MAGIC).  We made
nghttp2_session_recv() and nghttp2_session_mem_recv() process MAGIC by
default, so it is natural to make library send MAGIC as well.  This
commit makes nghttp2_session_send() and nghttp2_session_mem_send()
send MAGIC.  This commit also replace "connection preface" with
"client magic", since we call MAGIC as "connection preface" but it is
just a part of connection preface.  NGHTTP2_CLIENT_CONNECTION_PREFACE
macro was replaced with NGHTTP2_CLIENT_MAGIC.  The already deprecated
NGHTTP2_CLIENT_CONNECTION_HEADER macro was removed permanently.
nghttp2_option_set_no_recv_client_preface() was renamed as
nghttp2_option_set_no_recv_client_magic().  NGHTTP2_ERR_BAD_PREFACE
was renamed as NGHTTP2_ERR_BAD_CLIENT_MAGIC.
2015-04-05 23:15:20 +09:00
Tatsuhiro Tsujikawa 250ea53e4b Deal with 24 bytes client connection preface by default
Since HTTP/2 spec requires for client to send connection preface, it
is reasonable to make this option enabled by default.  It is still a
use case to disable this, so replace this option with
nghttp2_option_set_no_recv_client_preface().
2015-04-05 23:15:20 +09:00
Tatsuhiro Tsujikawa 9eff511c5e Add nghttp2_send_data_callback to send DATA payload without copying
To avoid buffer copy in nghttp2_data_source_read_callback, this commit
introduces NGHTTP2_DATA_FLAG_NO_COPY and nghttp2_send_data_callback.
By using NGHTTP2_DATA_FLAG_NO_COPY in
nghttp2_data_source_read_callback, application can avoid to copy
application data to given buffer.  Instead, application has to
implement nghttp2_send_data_callback to send complete DATA frame by
itself.  We see noticeable performance increase in nghttpd and
tiny-nghttpd using this new feature.  On the other hand, nghttpx does
not show such difference, probably because buffer copy is not
bottleneck.  Using nghttp2_send_data_callback adds complexity, so it
is recommended to measure the performance to see whether this extra
complexity worth it.
2015-04-04 21:23:50 +09:00
Tatsuhiro Tsujikawa 505a300d93 Refuse PUSH_PROMISE while unacked local ENABLE_PUSH is 0
After we sent SETTINGS including ENABLE_PUSH = 0, peer may already
issue PUSH_PROMISE before receiving our SETTINGS and react it to
SETTINGS ACK.  Previously we accept this PUSH_PROMISE.  In this
commit, we check the pending ENABLE_PUSH value and if it means
disabling push, we refuse PUSH_PROMISE with RST_STREAM of error
REFUSED_STREAM.
2015-03-07 16:17:40 +09:00
Tatsuhiro Tsujikawa b3846d6c27 Rename NGHTTP2_OPTMASK_NO_HTTP_SEMANTICS with NGHTTP2_OPTMASK_NO_HTTP_MESSAGING 2015-02-20 23:07:48 +09:00
Tatsuhiro Tsujikawa b157d4ebb2 Validate HTTP semantics by default
Previously we did not check HTTP semantics and it is left out for
application.  Although checking is relatively easy, but they are
scattered and error prone.  We have implemented these checks in our
applications and also feel they are tedious.  To make application
development a bit easier, this commit adds basic HTTP semantics
validation to library code.  We do following checks:

server:

* HEADERS is either request header or trailer header.  Other type of
header is disallowed.

client:

* HEADERS is either zero or more non-final response header or final
  response header or trailer header.  Other type of header is
  disallowed.

For both:

* Check mandatory pseudo header fields.
* Make sure that content-length matches the amount of DATA we
  received.

If validation fails, RST_STREAM of type PROTOCOL_ERROR is issued.
2015-02-20 01:01:10 +09:00
Tatsuhiro Tsujikawa 9c30211da9 Ignore all incoming bytes when first SETTINGS is not received 2015-02-15 01:20:10 +09:00
Tatsuhiro Tsujikawa eec8870ac1 Fix bug that client may send PROTOCOL_ERROR upon canceled push stream
Previously we treat stream in NGHTTP2_STREAM_RESERVED state specially,
that is we don't increment or decrement streams counts if stream is in
that state.  Because of this, we don't change the stream state to
NGHTTP2_STREAM_CLOSING if stream is in NGHTTP2_STREAM_RESERVED.  But
it turns out that it causes a problem.  If client canceled pushed
stream before push response HEADERS, stream is still in
NGHTTP2_STREAM_RESERVED state.  If push response HEADERS arrived in
this state, library happily accepts it and passed to application.

With this commit, this bug was corrected.  We now change stream state
to NGHTTP2_STREAM_CLOSING even if it was in NGHTTP2_STREAM_RESERVED
state.  We now use NGHTTP2_STREAM_FLAG_PUSH to determine whether we
have to increase/decrase stream count.
2015-02-09 22:23:20 +09:00
Tatsuhiro Tsujikawa b685747643 Add nghttp2_submit_shutdown_notice() to start graceful shutdown
nghttp2_submit_shutdown_notice() is used to notify the client that
graceful shutdown is started.  We expect that after this call, the
server application should send another GOAWAY using
nghttp2_submit_goaway() with appropriate last_stream_id.  In this
commit, we also added nghttp2_session_get_last_proc_stream_id(), which
can be used as last_stream_id parameter.

This commit implements graceful shutdown in nghttpx.  The integration
test for graceful shutdown is also added.
2015-01-22 23:21:58 +09:00
Tatsuhiro Tsujikawa a804117c83 Fix GOAWAY handling
On reception of GOAWAY, new stream creation is disallowed regardless
of last-stream-id in GOAWAY is larger than next stream ID.
2015-01-07 22:53:43 +09:00
Tatsuhiro Tsujikawa 280c9dfcf3 Keep idle streams in separate list
Previously we handle idle streams as closed streams.  We only keeps
sum of closed streams and active streams under max concurrent streams
limit, idle streams gets deleted earlier than client expects.

In this change, idle streams are kept in separate list and not handled
as closed streams.  To mitigate possible attack vector to make
unlimited idle streams, we cap the number of idle streams in a half of
max concurrent streams.  This is arbitrary choice.  It may be adjusted
in the future when we have interop experience.
2014-12-13 00:14:52 +09:00
Tatsuhiro Tsujikawa c0ffed7788 Support custom memory allocator
nghttp2_mem structure is introduced to hold custom memory allocator
functions and user supplied pointer.  nghttp2_mem object can be passed
to nghttp2_session_client_new3(), nghttp2_session_server_new3(),
nghttp2_hd_deflate_new2() and nghttp2_hd_inflate_new2() to replace
standard malloc(), free(), calloc() and realloc().  nghttp2_mem
structure has user supplied pointer mem_user_data which can be used as
per session/object memory pool.
2014-12-08 00:55:55 +09:00
Tatsuhiro Tsujikawa 21b48d24e4 Remove altsvc 2014-12-07 23:11:54 +09:00
Tatsuhiro Tsujikawa ca57c2f6b6 Rename NGHTTP2_GOAWAY_FAIL_ON_SEND with NGHTTP2_GOAWAY_TERM_ON_FAIL 2014-11-29 16:28:08 +09:00
Tatsuhiro Tsujikawa 9ff1925538 Robust GOAWAY handling
This change will utilize last_stream_id in GOAWAY extensively.  When
GOAWAY is received with a last_stream_id, library closes all outgoing
streams whose stream_id > received last_stream_id.
nghttp2_on_stream_callback is called for each stream to be closed.

When GOAWAY is sent with a last_stream_id, library closes all incoming
streams whose stream_id > sent last_stream_id.
nghttp2_on_stream_callback is called for each stream to be closed.
2014-11-29 16:02:13 +09:00
Tatsuhiro Tsujikawa b1f807abd1 Reformat lines with clang-format-3.5 2014-11-27 23:56:30 +09:00
Tatsuhiro Tsujikawa 8e94551881 Handle idle stream in priority field 2014-11-24 15:25:19 +09:00
Tatsuhiro Tsujikawa ae93f6345c Allow PRIORITY frame at anytime.
Allowing PRIORITY frame at anytime so that PRIORITY frame to idle
stream can create anchor node in dependency tree.  In this change, we
open stream with new NGHTTP2_STREAM_IDLE state, which is linked in
session->closed_stream_head and is treated as if it is closed stream.
One difference is that if the stream is opened, we remove it from
linked list and change the state to the appropriate one.  To O(1)
removal from linked list, we change session->closed_stream_head to
doubly linked list.
2014-11-24 15:25:19 +09:00
Tatsuhiro Tsujikawa 49b8d1d88c Rename max_header_set_size as max_header_list_size 2014-10-30 22:42:15 +09:00
Tatsuhiro Tsujikawa 80dcb565eb Check first SETTINGS strictly 2014-10-09 21:37:18 +09:00
Tatsuhiro Tsujikawa 1d138accb9 Unify DATA and other frames in nghttp2_outbound_item and save malloc() 2014-10-03 21:31:37 +09:00
Tatsuhiro Tsujikawa e20b417b84 Embed aux_data to nghttp2_outbound_item so that we can save some malloc() calls 2014-09-30 21:45:15 +09:00
Tatsuhiro Tsujikawa a11fbf6e2f Optimize connection level remote flow control
Previously when connection level remote flow control window gets 0, we
mark the stream having DATA frame with
NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL.  When connection level
WINDOW_UPDATE is received, we checks all existing streams, including
closed ones, and call nghttp2_stream_resume_deferred_data().  The
profiler shows this is expensive.

Now we prepare dedicated priority queue for DATA frames.  And we don't
mark stream with NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL when DATA
cannot be sent solely due to connection level flow control.  Instead,
we just queue DATA item to queue.  We won't pop DATA item from queue
when connection level remote window size is 0.  This way, we avoid the
expensive operation for all streams when WINDOW_UPDATE is arrived.
2014-09-26 00:01:51 +09:00
Tatsuhiro Tsujikawa 901de5fbce Add nghttp2_option_set_recv_client_preface()
By default, nghttp2 library only handles HTTP/2 frames and does not
recognize first 24 bytes of client connection preface. This design
choice is done due to the fact that server may want to detect the
application protocol based on first few bytes on clear text
communication. But for simple servers which only speak HTTP/2, it is
easier for developers if nghttp2 library takes care of client
connection preface.

If this option is used with nonzero val, nghttp2 library checks first
24 bytes client connection preface. If it is not a valid one,
nghttp2_session_recv() and nghttp2_session_mem_recv() will return
error NGHTTP2_ERR_BAD_PREFACE, which is fatal error.
2014-09-13 19:50:44 +09:00
Tatsuhiro Tsujikawa 31528b6267 Use uint32_t for HTTP/2 error_code
h2-14 now allows extensions to define new error codes.  To allow
application callback to access such error codes, we uses uint32_t as
error_code type for structs and function parameters.  Previously we
treated unknown error code as INTERNAL_ERROR, but this change removes
this and unknown error code is passed to application callback as is.
2014-08-25 21:24:04 +09:00
Tatsuhiro Tsujikawa ab5b81bee1 Hide nghttp2_session_callbacks details and provide setter like functions
To make it possible to add new callbacks without bumping so name, we
decided to hide details of nghttp2_session_callbacks.  We provide
setter like functions to set individual callback function.
2014-08-25 21:24:04 +09:00
Tatsuhiro Tsujikawa 86b089f957 Fix buffer overrun in raw_sbuf 2014-08-06 01:49:36 +09:00
Tatsuhiro Tsujikawa 77374ac6e2 Implement SETTINGS_MAX_FRAME_SIZE and SETTINGS_MAX_HEADER_LIST_SIZE 2014-07-31 23:05:53 +09:00
Tatsuhiro Tsujikawa 8d5422c9bb Remove check for incoming header block size
The application should be responsible for the size of incoming header
block size.  Framing layer just passes everything (we have size limit
for one header/field though) to application.
2014-07-31 23:05:53 +09:00
Tatsuhiro Tsujikawa 079db14d45 Add nghttp2_session_consume() API
Reworked no automatic WINDOW_UPDATE feature.  We added new API
nghttp2_session_consume() which tells the library how many bytes are
consumed by the application.  Instead of submitting WINDOW_UPDATE by
the application, the library is now responsible to submit
WINDOW_UPDATE based on consumed bytes.  This is more reliable method,
since it enables us to properly send WINDOW_UPDATE for stream and
connection individually.  The previous implementation of nghttpx had
broken connection window management.
2014-07-31 23:05:53 +09:00