Commit Graph

5985 Commits

Author SHA1 Message Date
Vladimir Homutov
0946f8c3ca QUIC: revised value separators in debug and error messages.
All values are prefixed with name and separated from it using colon.
Multiple values are listed without commas in between.

Rationale: this greatly simplifies log parsing for analysis.
2020-10-27 14:12:31 +03:00
Vladimir Homutov
528e5bd1fb QUIC: single function for frame debug logging.
The function may be called for any initialized frame, both rx and tx.

While there, shortened level names.
2020-10-27 14:32:08 +03:00
Vladimir Homutov
83d7a949e8 QUIC: optimized acknowledgement generation.
For application level packets, only every second packet is now acknowledged,
respecting max ack delay.

13.2.1 Sending ACK Frames

   In order to assist loss detection at the sender, an endpoint SHOULD
   generate and send an ACK frame without delay when it receives an ack-
   eliciting packet either:

   *  when the received packet has a packet number less than another
      ack-eliciting packet that has been received, or

   *  when the packet has a packet number larger than the highest-
      numbered ack-eliciting packet that has been received and there are
      missing packets between that packet and this packet.


13.2.2.  Acknowledgement Frequency

    A receiver SHOULD send an ACK frame after receiving at least two
    ack-eliciting packets.
2020-10-23 17:08:50 +03:00
Vladimir Homutov
b92e596918 QUIC: added missing "quic" prefix in debug messages. 2020-10-23 18:22:01 +03:00
Maxim Dounin
9cdb278454 SSL: ssl_reject_handshake directive (ticket #195).
In some cases it might be needed to reject SSL handshake based on SNI
server name provided, for example, to make sure an invalid certificate
is not returned to clients trying to contact a name-based virtual server
without SSL configured.  Previously, a "ssl_ciphers aNULL;" was used for
this.  This workaround, however, is not compatible with TLSv1.3, in
particular, when using BoringSSL, where it is not possible to configure
TLSv1.3 ciphers at all.

With this change, the ssl_reject_handshake directive is introduced,
which instructs nginx to reject SSL handshakes with an "unrecognized_name"
alert in a particular server block.

For example, to reject handshake with names other than example.com,
one can use the following configuration:

    server {
        listen 443 ssl;
        ssl_reject_handshake on;
    }

    server {
        listen 443 ssl;
        server_name example.com;
        ssl_certificate example.com.crt;
        ssl_certificate_key example.com.key;
    }

The following configuration can be used to reject all SSL handshakes
without SNI server name provided:

    server {
        listen 443 ssl;
        ssl_reject_handshake on;
    }

    server {
        listen 443 ssl;
        server_name ~^;
        ssl_certificate example.crt;
        ssl_certificate_key example.key;
    }

Additionally, the ssl_reject_handshake directive makes configuring
certificates for the default server block optional.  If no certificates
are configured in the default server for a given listening socket,
certificates must be defined in all non-default server blocks with
the listening socket in question.
2020-10-22 18:02:28 +03:00
Maxim Dounin
f9a37243c9 Stream: proxy_ssl_conf_command directive.
Similarly to ssl_conf_command, proxy_ssl_conf_command can be used to
set arbitrary OpenSSL configuration parameters as long as nginx is
compiled with OpenSSL 1.0.2 or later, when connecting to upstream
servers with SSL.  Full list of available configuration commands
can be found in the SSL_CONF_cmd manual page
(https://www.openssl.org/docs/man1.1.1/man3/SSL_CONF_cmd.html).
2020-10-22 18:00:27 +03:00
Maxim Dounin
9a72ac799c Upstream: proxy_ssl_conf_command and friends.
Similarly to ssl_conf_command, proxy_ssl_conf_command (grpc_ssl_conf_command,
uwsgi_ssl_conf_command) can be used to set arbitrary OpenSSL configuration
parameters as long as nginx is compiled with OpenSSL 1.0.2 or later,
when connecting to upstream servers with SSL.  Full list of available
configuration commands can be found in the SSL_CONF_cmd manual page
(https://www.openssl.org/docs/man1.1.1/man3/SSL_CONF_cmd.html).
2020-10-22 18:00:23 +03:00
Maxim Dounin
ac9c162282 SSL: ssl_conf_command directive.
With the ssl_conf_command directive it is now possible to set
arbitrary OpenSSL configuration parameters as long as nginx is compiled
with OpenSSL 1.0.2 or later.  Full list of available configuration
commands can be found in the SSL_CONF_cmd manual page
(https://www.openssl.org/docs/man1.1.1/man3/SSL_CONF_cmd.html).

In particular, this allows configuring PrioritizeChaCha option
(ticket #1445):

    ssl_conf_command Options PrioritizeChaCha;

It can be also used to configure TLSv1.3 ciphers in OpenSSL,
which fails to configure them via the SSL_CTX_set_cipher_list()
interface (ticket #1529):

    ssl_conf_command Ciphersuites TLS_CHACHA20_POLY1305_SHA256;

Configuration commands are applied after nginx own configuration
for SSL, so they can be used to override anything set by nginx.
Note though that configuring OpenSSL directly with ssl_conf_command
might result in a behaviour nginx does not expect, and should be
done with care.
2020-10-22 18:00:22 +03:00
Maxim Dounin
af05f05f91 Core: ngx_conf_set_keyval_slot() now accepts NGX_CONF_UNSET_PTR.
With this change, it is now possible to use ngx_conf_merge_ptr_value()
to merge keyval arrays.  This change actually follows much earlier
changes in ngx_conf_merge_ptr_value() and ngx_conf_set_str_array_slot()
in 1452:cd586e963db0 (0.6.10) and 1701:40d004d95d88 (0.6.22).

To preserve compatibility with existing 3rd party modules, both NULL
and NGX_CONF_UNSET_PTR are accepted for now.
2020-10-22 18:00:20 +03:00
Sergey Kandaurov
fec3d792c9 QUIC: restored proper usage of ngx_quic_drop_ack_ranges().
ACK Ranges are again managed based on the remembered Largest Acknowledged
sent in the packet being acknowledged, which partially reverts c01964fd7b8b.
2020-10-22 11:05:50 +01:00
Vladimir Homutov
ff26faaf77 QUIC: fixed dropping output ack ranges on input ack.
While there, additional debug messages were added.
2020-10-21 20:39:25 +03:00
Vladimir Homutov
1506c7b825 QUIC: added macro for unset packet number. 2020-10-21 18:44:25 +03:00
Vladimir Homutov
cb3a1d7f49 QUIC: drop acknowledged ranges.
13.2.4.  Limiting Ranges by Tracking ACK Frames

   When a packet containing an ACK frame is sent, the largest
   acknowledged in that frame may be saved.  When a packet containing an
   ACK frame is acknowledged, the receiver can stop acknowledging
   packets less than or equal to the largest acknowledged in the sent
   ACK frame.
2020-10-20 18:53:25 +03:00
Vladimir Homutov
6e412bf182 QUIC: added ACK frame range support.
The history of acknowledged packet is kept in send context as ranges.
Up to NGX_QUIC_MAX_RANGES ranges is stored.

As a result, instead of separate ack frames, single frame with ranges
is sent.
2020-10-20 18:53:00 +03:00
Sergey Kandaurov
74f6c92529 QUIC: expand UDP datagrams with an ack-eliciting Initial packet.
Per draft-ietf-quic-transport-32 on the topic:

:   Similarly, a server MUST expand the payload of all UDP datagrams carrying
:   ack-eliciting Initial packets to at least the smallest allowed maximum
:   datagram size of 1200 bytes.
2020-10-21 12:46:23 +01:00
Sergey Kandaurov
e1982a1aba QUIC: teach how to compute only the length of created QUIC headers.
It will be used for precise expansion of UDP datagram payload.
2020-10-21 12:03:23 +01:00
Sergey Kandaurov
fe2c392551 QUIC: simplified ngx_quic_create_long_header().
As seen in the quic-transport draft, which this implementation follows:
Initial packets sent by the server MUST set the Token Length field to zero.
2020-10-21 12:03:22 +01:00
Sergey Kandaurov
a47a4400b8 QUIC: avoided excessive initialization in ngx_quic_send_frames().
A zero-length token was used to initialize a prezeroed packet header.
2020-10-21 12:03:22 +01:00
Sergey Kandaurov
c405a364eb QUIC: sorted ngx_quic_send_frames() declarations. 2020-10-21 12:03:21 +01:00
Vladimir Homutov
d54fd4ed34 QUIC: account packet header length in amplification limit.
This is the restoration of 02ee77f8d53d accidentally reverted by 93be5658a250.
2020-10-19 12:19:38 +03:00
Vladimir Homutov
743cc99781 QUIC: reverted previous 3 commits.
Changes were intended for the test repository.
2020-10-19 10:32:53 +03:00
Vladimir Homutov
2d65615b42 try: --skiptests 2020-10-19 10:10:21 +03:00
Vladimir Homutov
622a65edea QUIC: added ACK frame range support.
The history of acknowledged packet is kept in send context as ranges.
Up to NGX_QUIC_MAX_RANGES ranges is stored.

As a result, instead of separate ack frames, single frame with ranges
is sent.
2020-10-14 23:21:36 +03:00
Ruslan Ermilov
2ba670a925 Cpp test: added stream. 2020-10-13 07:44:09 +03:00
Maxim Dounin
9381ecb185 Limit req: unlocking of nodes on complex value errors.
Previously, if there were multiple limits configured, errors in
ngx_http_complex_value() during processing of a non-first limit
resulted in reference count leak in shared memory nodes of already
processed limits.  Fix is to explicity unlock relevant nodes, much
like we do when rejecting requests.
2020-10-08 17:44:34 +03:00
Maxim Dounin
1e92a0a4ce Mail: proxy_smtp_auth directive.
The proxy_smtp_auth directive instructs nginx to authenticate users
on backend via the AUTH command (using the PLAIN SASL mechanism),
similar to what is normally done for IMAP and POP3.

If xclient is enabled along with proxy_smtp_auth, the XCLIENT command
won't try to send the LOGIN parameter.
2020-10-03 21:04:57 +03:00
Maxim Dounin
8523ef8e86 Version bump. 2020-10-03 21:01:12 +03:00
Maxim Dounin
e64f7fe7c9 Proxy: error checking for array init, missed in 7716:d6a5e14aa3e4.
Found by Coverity (CID 1467637).
2020-09-29 15:54:09 +03:00
Maxim Dounin
718d589091 Userid: userid_flags fixup.
In 7717:e3e8b8234f05, the 1st bit was incorrectly used.  It shouldn't
be used for bitmask values, as it is used by NGX_CONF_BITMASK_SET.

Additionally, special value "off" added to make it possible to clear
inherited userid_flags value.
2020-09-29 15:52:18 +03:00
Maxim Dounin
279efaab66 Resolver: improved error messages (ticket #2024). 2020-09-28 17:41:22 +03:00
Maxim Dounin
c511f3de3e Userid: userid_flags directive to set cookie flags. 2020-09-28 17:07:48 +03:00
Ruslan Ermilov
21b903f8e3 Proxy: added the "proxy_cookie_flags" directive. 2020-09-27 23:21:11 +03:00
Ruslan Ermilov
8b3f778cbc Proxy: changed interface of some internal functions.
This is in preparation for the next change.

Also, moved optimization from ngx_http_proxy_rewrite_regex_handler()
to ngx_http_proxy_rewrite().
2020-09-27 23:21:10 +03:00
Ruslan Ermilov
b2b8f226f1 Proxy: strengthen syntax checking for some directives.
The "false" parameter of the proxy_redirect directive is deprecated.
Warning has been emitted since c2230102df6f (0.7.54).

The "off" parameter of the proxy_redirect, proxy_cookie_domain, and
proxy_cookie_path directives tells nginx not to inherit the
configuration from the previous configuration level.

Previously, after specifying the directive with the "off" parameter,
any other directives were ignored, and syntax checking was disabled.

The syntax was enforced to allow either one directive with the "off"
parameter, or several directives with other parameters.

Also, specifying "proxy_redirect default foo" no longer works like
"proxy_redirect default".
2020-09-27 23:21:09 +03:00
Vladimir Homutov
e8277e4224 SSL: added the "ssl_keys_file" directive. 2020-09-15 22:44:46 +03:00
Vladimir Homutov
26102d7ad7 QUIC: account packet header length in amplification limit.
Header length calculation is adjusted to account real connection id lengths
instead of worst case.
2020-10-15 11:37:01 +03:00
Sergey Kandaurov
72b566cea5 QUIC: fixed ngx_http_upstream_init() much like HTTP/2 connections. 2020-10-12 14:00:00 +01:00
Vladimir Homutov
bb64f2017a QUIC: reset error and error_reason prior to processing packet. 2020-10-09 16:57:19 +03:00
Sergey Kandaurov
c245c9ea20 QUIC: fixed dead store assignment.
Found by Clang Static Analyzer.
2020-10-07 14:51:05 +01:00
Vladimir Homutov
017e3bd8a8 QUIC: fixed format specifier in debug message. 2020-10-07 15:29:23 +03:00
Vladimir Homutov
5a07601a3c QUIC: added debug message with final packet processing status. 2020-10-02 16:20:41 +03:00
Roman Arutyunyan
783df73ba0 QUIC: set local_socklen in stream connections.
Previously, this field was not set while creating a QUIC stream connection.
As a result, calling ngx_connection_local_sockaddr() led to getsockname()
bad descriptor error.
2020-10-07 12:24:03 +01:00
Vladimir Homutov
d600364887 QUIC: enabled more key-related debug by default. 2020-10-02 12:40:49 +03:00
Vladimir Homutov
9f583efe3d QUIC: added connection id debug. 2020-10-02 12:56:34 +03:00
Vladimir Homutov
7369bdc47c QUIC: updated c->log->action strings to reflect proper state. 2020-10-07 13:38:17 +03:00
Vladimir Homutov
7250a7688d QUIC: fixed memory leak in ngx_quic_send_frames().
The function did not free passed frames in case of error.
2020-10-07 10:14:02 +03:00
Sergey Kandaurov
46a01acdc0 QUIC: fixed measuring ACK Delay against 0-RTT packets. 2020-10-06 18:08:55 +01:00
Sergey Kandaurov
f09be89a52 QUIC: do not resend empty queue when speeding up handshake.
If client acknowledged an Initial packet with CRYPTO frame and then
sent another Initial packet containing duplicate CRYPTO again, this
could result in resending frames off the empty send queue.
2020-10-05 13:02:53 +01:00
Sergey Kandaurov
3309b1e8df QUIC: zero out packet length in frames prior to send.
It could be that a frame was previously sent and may have stale information.
This was previously broken by merging frames on resend in b383120afca3.
2020-10-05 13:02:38 +01:00
Vladimir Homutov
4ed768d3d1 QUIC: fixed build with clang and NGX_QUIC_DEBUG_CRYPTO enabled.
The ngx_quic_hexdump() function is wrapped into macros to cast "data"
argument to "* u_char".
2020-10-05 14:36:17 +03:00
Vladimir Homutov
b99a4a0b82 QUIC: inline function instead of macro for hexdump.
This prevents name clashes with local variables.
2020-10-05 10:03:01 +03:00
Vladimir Homutov
a06a3f6aba QUIC: fixed handling of incorrect packets.
Instead of ignoring, connection was closed. This was broken in d0d3fc0697a0.
2020-10-01 22:20:51 +03:00
Sergey Kandaurov
88cb4d3ab0 Merged with the default branch. 2020-10-01 12:21:11 +01:00
Sergey Kandaurov
ee4a6024cc QUIC: a bandaid for calculating ack_delay with non-monotonic time. 2020-10-01 12:10:37 +01:00
Sergey Kandaurov
7bd3868715 QUIC: speeding up handshake completion.
As per quic-recovery draft, section-6.2.3: resend CRYPTO frames
when receiving an Initial packet containing duplicate CRYPTO data.
2020-10-01 12:10:22 +01:00
Sergey Kandaurov
b64446f6f9 QUIC: fixed clang-ast asserts. 2020-10-01 12:09:47 +01:00
Sergey Kandaurov
154536a64f QUIC: fixed build with OpenSSL after bed310672f39. 2020-10-01 12:00:12 +01:00
Vladimir Homutov
0f843cfb74 QUIC: moved ssl configuration pointer to quic configuration.
The ssl configuration is obtained at config time and saved for future use.
2020-10-01 10:04:35 +03:00
Vladimir Homutov
f797a8a5b5 QUIC: added stateless reset support.
The new "quic_stateless_reset_token_key" directive is added.  It sets the
endpoint key used to generate stateless reset tokens and enables feature.

If the endpoint receives short-header packet that can't be matched to
existing  connection, a stateless reset packet is generated with
a proper token.

If a valid stateless reset token is found in the incoming packet,
the connection is closed.

Example configuration:

http {
    quic_stateless_reset_token_key  "foo";
    ...
}
2020-09-30 20:54:46 +03:00
Vladimir Homutov
2c3ada5722 QUIC: refined the "c->quic->initialized" flag usage.
The flag is tied to the initial secret creation.  The presence of c->quic
pointer is sufficient to enable execution of ngx_quic_close_quic().

The ngx_quic_new_connection() function now returns the allocated quic
connection object and the c->quic pointer is set by the caller.

If an early error occurs before secrets initialization (i.e. in cases
of invalid retry token or nginx exiting), it is still possible to
generate an error response by trying to initialize secrets directly
in the ngx_quic_send_cc() function.

Before the change such early errors failed to send proper connection close
message and logged an error.

An auxilliary ngx_quic_init_secrets() function is introduced to avoid
verbose call to ngx_quic_set_initial_secret() requiring local variable.
2020-09-30 21:27:52 +03:00
Vladimir Homutov
99d4f2399d QUIC: packet processing refactoring.
All packet header parsing is now performed by ngx_quic_parse_packet()
function, located in the ngx_quic_transport.c file.

The packet processing is centralized in the ngx_quic_process_packet()
function which decides if the packet should be accepted, ignored or
connection should be closed, depending on the connection state.

As a result of refactoring, behavior has changed in some places:

 - minimal size of Initial packet is now always tested
 - connection IDs are always tested in existing connections
 - old keys are discarded on encryption level switch
2020-09-30 15:14:09 +03:00
Vladimir Homutov
fe626bda84 QUIC: simplified packet header parsing.
Now flags are processed in ngx_quic_input(), and raw->pos points to the first
byte after the flags. Redundant checks from ngx_quic_parse_short_header() and
ngx_quic_parse_long_header() are removed.
2020-09-25 21:47:28 +03:00
Roman Arutyunyan
80958b29a2 QUIC: keep the entire packet size in pkt->len.
Previously pkt->len kept the length of the packet remainder starting from
pkt->raw->pos.
2020-09-25 21:46:55 +03:00
Vladimir Homutov
6c0be4b4cf QUIC: switched to using fixed-length server connection IDs. 2020-09-18 15:53:37 +03:00
Roman Arutyunyan
469f69bf2c QUIC: resend frames by moving them to output queue.
Previously, when a packet was declared lost, another packet was sent with the
same frames.  Now lost frames are moved to the output frame queue and push
event is posted.  This has the advantage of forming packets with more frames
than before.

Also, the start argument is removed from the ngx_quic_resend_frames()
function as excess information.
2020-09-30 20:23:16 +01:00
Roman Arutyunyan
1f90fccd97 QUIC: switch stream context to a server selected by SNI.
Previously the default server configuration context was used until the
:authority or host header was parsed.  This led to using the configuration
parameters like client_header_buffer_size or request_pool_size from the default
server rather than from the server selected by SNI.

Also, the switch to the right server log is implemented.  This issue manifested
itself as QUIC stream being logged to the default server log until :authority
or host is parsed.
2020-09-29 22:09:09 +01:00
Sergey Kandaurov
0824d61fc9 QUIC: unbreak client certificate verification after 0d2b2664b41c.
Initially, client certificate verification didn't work due to the missing
hc->ssl on a QUIC stream, which is started to be set in 7738:7f0981be07c4.
Then it was lost in 7999:0d2b2664b41c introducing "quic" listen parameter.

This change re-adds hc->ssl back for all QUIC connections, similar to SSL.
2020-09-23 13:13:04 +01:00
Vladimir Homutov
766fc16f55 QUIC: prevented posted push event while in the draining state.
If the push event was posted before ngx_quic_close_connection(), it could send
data in the draining state.
2020-09-21 13:58:17 +03:00
Roman Arutyunyan
be719bbec8 HTTP/3: rearranged length check when parsing header.
The new code looks simpler and is similar to other checks.
2020-09-16 20:21:03 +01:00
Roman Arutyunyan
ebbcc329cb HTTP/3: removed HTTP/3 parser call from discard body filter.
Request body discard is disabled for QUIC streams anyway.
2020-09-16 19:48:33 +01:00
Roman Arutyunyan
9fff3b7516 HTTP/3: reject HTTP/2 frames.
As per HTTP/3 draft 30, section 7.2.8:

   Frame types that were used in HTTP/2 where there is no corresponding
   HTTP/3 frame have also been reserved (Section 11.2.1).  These frame
   types MUST NOT be sent, and their receipt MUST be treated as a
   connection error of type H3_FRAME_UNEXPECTED.
2020-09-16 12:27:23 +01:00
Pavel Pautov
c85d6fec21 Stream: set module.
Adds 'set' directive to the stream server context.
2020-08-28 14:10:54 -07:00
Sergey Kandaurov
3bbeb1b8de SSL: abort handshake on SSL_set_SSL_CTX() errors.
In rare cases, such as memory allocation failure, SSL_set_SSL_CTX() returns
NULL, which could mean that a different SSL configuration has not been set.
Note that this new behaviour seemingly originated in OpenSSL-1.1.0 release.
2020-09-24 13:51:29 +01:00
Maxim Dounin
6c89d752c8 HTTP/2: run posted requests after reading body.
HTTP/2 code failed to run posted requests after calling the request body
handler, and this resulted in connection hang if a subrequest was created
in the body handler and no other actions were made.
2020-09-23 19:52:31 +03:00
Maxim Dounin
7c67ff7363 HTTP/2: fixed segfault on DATA frames after 400 errors.
If 400 errors were redirected to an upstream server using the error_page
directive, DATA frames from the client might cause segmentation fault
due to null pointer dereference.  The bug had appeared in 6989:2c4dbcd6f2e4
(1.13.0).

Fix is to skip such frames in ngx_http_v2_state_read_data() (similarly
to 7561:9f1f9d6e056a).  With the fix, behaviour of 400 errors in HTTP/2
is now similar to one in HTTP/1.x, that is, nginx doesn't try to read the
request body.

Note that proxying 400 errors, as well as other early stage errors, to
upstream servers might not be a good idea anyway.  These errors imply
that reading and processing of the request (and the request headers)
wasn't complete, and proxying of such incomplete request might lead to
various errors.

Reported by Chenglong Zhang.
2020-09-23 19:50:49 +03:00
Maxim Dounin
e9a8612c13 SSL: disabled shutdown when there are buffered data.
This fixes "SSL_shutdown() failed (SSL: ... bad write retry)" errors
as observed on the second SSL_shutdown() call after SSL shutdown fixes in
09fb2135a589 (1.19.2), notably when HTTP/2 connections are closed due
to read timeouts while there are incomplete writes.
2020-09-16 18:26:25 +03:00
Maxim Dounin
f6c28f93af SSL: disabled shutdown after connection errors.
This fixes "SSL_shutdown() failed (SSL: ... bad write retry)" errors
as observed on the second SSL_shutdown() call after SSL shutdown fixes in
09fb2135a589 (1.19.2), notably when sending fails in ngx_http_test_expect(),
similarly to ticket #1194.

Note that there are some places where c->error is misused to prevent
further output, such as ngx_http_v2_finalize_connection() if there
are pending streams, or in filter finalization.  These places seem
to be extreme enough to don't care about missing shutdown though.
For example, filter finalization currently prevents keepalive from
being used.
2020-09-16 18:26:24 +03:00
Maxim Dounin
a1864c2586 SSL: fixed event handling during shutdown.
The c->read->ready and c->write->ready flags need to be cleared to ensure
that appropriate read or write events will be reported by kernel.  Without
this, SSL shutdown might wait till the timeout after blocking on writing
or reading even if there is a socket activity.
2020-09-16 18:26:23 +03:00
Maxim Dounin
82cf625ab5 SSL: workaround for incorrect SSL_write() errors in OpenSSL 1.1.1.
OpenSSL 1.1.1 fails to return SSL_ERROR_SYSCALL if an error happens
during SSL_write() after close_notify alert from the peer, and returns
SSL_ERROR_ZERO_RETURN instead.  Broken by this commit, which removes
the "i == 0" check around the SSL_RECEIVED_SHUTDOWN one:

https://git.openssl.org/?p=openssl.git;a=commitdiff;h=8051ab2

In particular, if a client closed the connection without reading
the response but with properly sent close_notify alert, this resulted in
unexpected "SSL_write() failed while ..." critical log message instead
of correct "SSL_write() failed (32: Broken pipe)" at the info level.

Since SSL_ERROR_ZERO_RETURN cannot be legitimately returned after
SSL_write(), the fix is to convert all SSL_ERROR_ZERO_RETURN errors
after SSL_write() to SSL_ERROR_SYSCALL.
2020-09-16 18:26:22 +03:00
Sergey Kandaurov
dc1b14126e Cache: keep c->body_start when Vary changes (ticket #2029).
If the variant hash doesn't match one we used as a secondary cache key,
we switch back to the original key.  In this case, c->body_start was kept
updated from an existing cache node overwriting the new response value.
After file cache update, it led to discrepancy between a cache node and
cache file seen as critical errors "file cache .. has too long header".
2020-09-09 19:26:27 +03:00
Roman Arutyunyan
d294369915 HTTP/3: skip unknown frames on request stream.
As per HTTP/3 draft 29, section 4.1:

   Frames of unknown types (Section 9), including reserved frames
   (Section 7.2.8) MAY be sent on a request or push stream before,
   after, or interleaved with other frames described in this section.

Also, trailers frame is now used as an indication of the request body end.
2020-08-24 09:56:36 +03:00
Roman Arutyunyan
46173bd4b4 HTTP/3: fixed handling request body eof.
While for HTTP/1 unexpected eof always means an error, for HTTP/3 an eof right
after a DATA frame end means the end of the request body.  For this reason,
since adding HTTP/3 support, eof no longer produced an error right after recv()
but was passed to filters which would make a decision.  This decision was made
in ngx_http_parse_chunked() and ngx_http_v3_parse_request_body() based on the
b->last_buf flag.

Now that since 0f7f1a509113 (1.19.2) rb->chunked->length is a lower threshold
for the expected number of bytes, it can be set to zero to indicate that more
bytes may or may not follow.  Now it's possible to move the check for eof from
parser functions to ngx_http_request_body_chunked_filter() and clean up the
parsing code.

Also, in the default branch, in case of eof, the following three things
happened, which were replaced with returning NGX_ERROR while implementing
HTTP/3:

- "client prematurely closed connection" message was logged
- c->error flag was set
- NGX_HTTP_BAD_REQUEST was returned

The change brings back this behavior for HTTP/1 as well as HTTP/3.
2020-09-16 18:59:25 +01:00
Vladimir Homutov
0bc772d1fb QUIC: switched to draft 29 by default. 2020-09-11 10:56:05 +03:00
Roman Arutyunyan
2e24e3811b QUIC: allowed old DCID for initial packets until first ACK.
If a packet sent in response to an initial client packet was lost, then
successive client initial packets were dropped by nginx with the unexpected
dcid message logged.  This was because the new DCID generated by the server was
not available to the client.
2020-09-09 16:35:29 +03:00
Roman Arutyunyan
f3bed9cd67 QUIC: eliminated idle timeout restart for dropped packets. 2020-09-08 15:54:02 +03:00
Sergey Kandaurov
786a74e34e QUIC: removed check for packet size beyond MAX_UDP_PAYLOAD_SIZE.
The check tested the total size of a packet header and unprotected packet
payload, which doesn't include the packet number length and expansion of
the packet protection AEAD.  If the packet was corrupted, it could cause
false triggering of the condition due to unsigned type underflow leading
to a connection error.

Existing checks for the QUIC header and protected packet payload lengths
should be enough.
2020-09-08 13:35:50 +03:00
Sergey Kandaurov
d8360f912a QUIC: check that the packet length is of at least sample size.
From quic-tls draft, section 5.4.2:
   An endpoint MUST discard packets that are not long enough to contain
   a complete sample.

The check includes the Packet Number field assumed to be 4 bytes long.
2020-09-08 13:28:56 +03:00
Sergey Kandaurov
952c6f1989 QUIC: update packet length for short packets too.
During long packet header parsing, pkt->len is updated with the Length
field value that is used to find next coalesced packets in a datagram.
For short packets it still contained the whole QUIC packet size.

This change uniforms packet length handling to always contain the total
length of the packet number and protected packet payload in pkt->len.
2020-09-08 13:27:39 +03:00
Roman Arutyunyan
e43ef3dda9 QUIC: added logging output stream frame offset. 2020-09-07 20:55:36 +03:00
Vladimir Homutov
6f78befe99 QUIC: refactored ngx_quic_retry_input().
The function now returns NGX_DECLINED for packets that need to be ignored
and integrates nicely into ngx_quic_input().
2020-09-04 15:48:53 +03:00
Roman Arutyunyan
6983bc0a37 QUIC: do not send STOP_SENDING after STREAM fin.
Previously STOP_SENDING was sent to client upon stream closure if rev->eof and
rev->error were not set.  This was an indirect indication that no RESET_STREAM
or STREAM fin has arrived.  But it is indeed possible that rev->eof is not set,
but STREAM fin has already been received, just not read out by the application.
In this case sending STOP_SENDING does not make sense and can be misleading for
some clients.
2020-09-06 14:51:23 +03:00
Vladimir Homutov
d6065b2791 QUIC: added support for multiple connection IDs.
The peer may issue additional connection IDs up to the limit defined by
transport parameter "active_connection_id_limit", using NEW_CONNECTION_ID
frames, and retire such IDs using RETIRE_CONNECTION_ID frame.
2020-09-03 13:11:27 +03:00
Vladimir Homutov
c36c54f500 QUIC: style.
Moved processing of RETIRE_CONNECTION_ID right after the NEW_CONNECTION_ID.
2020-08-27 10:15:37 +03:00
Vladimir Homutov
fb54f2acd9 QUIC: pass return code from ngx_quic_decrypt() to the caller.
It is required to distinguish internal errors from corrupted packets and
perform actions accordingly: drop the packet or close the connection.

While there, made processing of ngx_quic_decrypt() erorrs similar and
removed couple of protocol violation errors.
2020-09-02 22:34:15 +03:00
Vladimir Homutov
ff4cfa80e5 QUIC: discard unrecognized long packes.
While there, updated comment about discarded packets.
2020-09-02 09:54:15 +03:00
Roman Arutyunyan
e443b1244f HTTP/3: do not set the never-indexed literal bit by default.
The "Literal Header Field Never Indexed" header field representation is not
used in HTTP/2, and it makes little sense to make a distinction in HTTP/3.
2020-08-31 18:42:26 +03:00
Vladimir Homutov
d73a289c43 QUIC: discard incorrect packets instead of closing the connection.
quic-transport

5.2:
    Packets that are matched to an existing connection are discarded if
    the packets are inconsistent with the state of that connection.

5.2.2:
   Servers MUST drop incoming packets under all other circumstances.
2020-09-01 17:20:42 +03:00
Roman Arutyunyan
2087359675 QUIC: do not update largest packet number from a bad packet.
The removal of QUIC packet protection depends on the largest packet number
received.  When a garbage packet was received, the decoder still updated the
largest packet number from that packet.  This could affect removing protection
from subsequent QUIC packets.
2020-09-01 15:21:49 +03:00
Roman Arutyunyan
6f0e1bc14f QUIC: handle PATH_CHALLENGE frame.
A PATH_RESPONSE frame with the same data is sent in response.
2020-08-28 12:01:35 +03:00
Roman Arutyunyan
d69471b81b QUIC: enforce flow control on incoming STREAM and CRYPTO frames. 2020-08-25 17:22:57 +03:00
Roman Arutyunyan
693e55a4b2 HTTP/3: drop the unwanted remainder of the request.
As per HTTP/3 draft 29, section 4.1:

   When the server does not need to receive the remainder of the request,
   it MAY abort reading the request stream, send a complete response, and
   cleanly close the sending part of the stream.
2020-08-25 12:45:21 +03:00
Roman Arutyunyan
4e4d0938b9 QUIC: send STOP_SENDING on stream closure.
The frame is sent for a read-enabled stream which has not received a FIN or
RESET_STREAM.
2020-08-25 14:07:26 +03:00
Sergey Kandaurov
e153f4993c QUIC: disabled bidirectional SSL shutdown after 09fb2135a589.
On QUIC connections, SSL_shutdown() is used to call the send_alert callback
to send a CONNECTION_CLOSE frame.  The reverse side is handled by other means.
At least BoringSSL doesn't differentiate whether this is a QUIC SSL method,
so waiting for the peer's close_notify alert should be explicitly disabled.
2020-08-21 14:41:42 +03:00
Sergey Kandaurov
6c089cda29 QUIC: stripped down debug traces that have served its purpose.
The most observable remainers are incoming packet and stream payload
that could still be useful to debug various QUIC and HTTP/3 frames.
2020-08-21 14:41:41 +03:00
Vladimir Homutov
fb21151ff8 QUIC: dead code removed.
This case was already handled in c70446e3d771.
2020-08-21 10:00:25 +03:00
Vladimir Homutov
51b4d208d6 QUIC: removed outdated TODOs.
The logical quic connection state is tested by handler functions that
process corresponding types of packets (initial/handshake/application).
The packet is declined if state is incorrect.

No timeout is required for the input queue.
2020-08-20 16:45:48 +03:00
Vladimir Homutov
4ecea6cbed QUIC: added version negotiation support.
If a client attemtps to start a new connection with unsupported version,
a version negotiation packet is sent that contains a list of supported
versions (currently this is a single version, selected at compile time).
2020-08-20 17:11:04 +03:00
Roman Arutyunyan
5a4aaa6aed HTTP/3: special handling of client errors in the upstream module.
The function ngx_http_upstream_check_broken_connection() terminates the HTTP/1
request if client sends eof.  For QUIC (including HTTP/3) the c->write->error
flag is now checked instead.  This flag is set when the entire QUIC connection
is closed or STOP_SENDING was received from client.
2020-08-20 12:33:00 +03:00
Roman Arutyunyan
7ce1a68aad HTTP/3: request more client body bytes.
Previously the request body DATA frame header was read by one byte because
filters were called only when the requested number of bytes were read.  Now,
after 08ff2e10ae92 (1.19.2), filters are called after each read.  More bytes
can be read at once, which simplifies and optimizes the code.

This also reduces diff with the default branch.
2020-08-18 17:23:16 +03:00
Sergey Kandaurov
338c401534 QUIC: fixed format specifiers. 2020-08-19 16:00:12 +03:00
Sergey Kandaurov
a4e06606c5 QUIC: changed c->quic->pto_count type to ngx_uint_t.
This field is served as a simple counter for PTO backoff.
2020-08-19 15:58:03 +03:00
Sergey Kandaurov
f760147d9d QUIC: do not artificially delay sending queued frames.
This interacts badly with retransmissions of lost packets
and can provoke spurious client retransmits.
2020-08-19 13:24:54 +03:00
Sergey Kandaurov
3b83a140ff QUIC: do not arm loss detection timer on packet threshold. 2020-08-19 13:24:53 +03:00
Sergey Kandaurov
391abc00c9 QUIC: do not arm loss detection timer for succeeding packets. 2020-08-19 13:24:47 +03:00
Sergey Kandaurov
3bf7b02e6e QUIC: handling packets with send time equal to lost send time.
Previously, such packets weren't handled as the resulting zero remaining time
prevented setting the loss detection timer, which, instead, could be disarmed.
For implementation details, see quic-recovery draft 29, appendix A.10.
2020-08-19 13:24:30 +03:00
Sergey Kandaurov
fa82dccd2a QUIC: sending probe packets on PTO timer expiration.
The PTO handler is split into separate PTO and loss detection handlers
that operate interchangeably depending on which timer should be set.

The present ngx_quic_lost_handler is now only used for packet loss detection.
It replaces ngx_quic_pto_handler if there are packets preceeding largest_ack.
Once there is no more such packets, ngx_quic_pto_handler is installed again.

Probes carry unacknowledged data previously sent in the oldest packet number,
one per each packet number space.  That is, it could be up to two probes.

PTO backoff is now increased before scheduling next probes.
2020-08-19 13:24:23 +03:00
Sergey Kandaurov
160242dd2e QUIC: changed ctx->largest_ack initial value to type maximum.
In particular, this prevents declaring packet number 0 as lost if
there aren't yet any acknowledgements in this packet number space.
For example, only Initial packets were acknowledged in handshake.
2020-08-18 23:33:40 +03:00
Sergey Kandaurov
9a0fb643bf HTTP/3: fixed context storage in request body parser. 2020-08-18 17:11:32 +03:00
Roman Arutyunyan
fd6df645eb Merged with the default branch. 2020-08-18 16:22:00 +03:00
Roman Arutyunyan
ff1941d6dd QUIC: coalesce neighbouring stream send buffers.
Previously a single STREAM frame was created for each buffer in stream output
chain which is wasteful with respect to memory.  The following changes were
made in the stream send code:

- ngx_quic_stream_send_chain() no longer calls ngx_quic_stream_send() and got
  a separate implementation that coalesces neighbouring buffers into a single
  frame
- the new ngx_quic_stream_send_chain() respects the limit argument, which fixes
  sendfile_max_chunk and limit_rate
- ngx_quic_stream_send() is reimplemented to call ngx_quic_stream_send_chain()
- stream frame size limit is moved out to a separate function
  ngx_quic_max_stream_frame()
- flow control is moved out to a separate function ngx_quic_max_stream_flow()
- ngx_quic_stream_send_chain() is relocated next to ngx_quic_stream_send()
2020-08-18 12:28:33 +03:00
Sergey Kandaurov
6e17937db4 QUIC: packet based bytes_in_flight accounting.
A packet size is kept in one of the frames belonging to the packet.
2020-08-14 16:54:13 +03:00
Sergey Kandaurov
81e9a5d77c QUIC: fixed leak of bytes_in_flight on keys discard.
This applies to discarding Initial and Handshake keys.
2020-08-14 16:54:06 +03:00
Sergey Kandaurov
f1b0afde65 QUIC: fixed leak of bytes_in_flight attributed to lost packets. 2020-08-14 16:53:56 +03:00
Maxim Dounin
348bc94086 Core: reusing connections in advance.
Reworked connections reuse, so closing connections is attempted in
advance, as long as number of free connections is less than 1/16 of
worker connections configured.  This ensures that new connections can
be handled even if closing a reusable connection requires some time,
for example, for a lingering close (ticket #2017).

The 1/16 ratio is selected to be smaller than 1/8 used for disabling
accept when working with accept mutex, so nginx will try to balance
new connections to different workers first, and will start reusing
connections only if this won't help.
2020-08-10 18:53:07 +03:00
Maxim Dounin
e240d88d44 Core: added a warning about reusing connections.
Previously, reusing connections happened silently and was only
visible in monitoring systems.  This was shown to be not very user-friendly,
and administrators often didn't realize there were too few connections
available to withstand the load, and configured timeouts (keepalive_timeout
and http2_idle_timeout) were effectively reduced to keep things running.

To provide at least some information about this, a warning is now logged
(at most once per second, to avoid flooding the logs).
2020-08-10 18:52:59 +03:00
Maxim Dounin
eae2b2fdf1 SSL: disabled sending shutdown after ngx_http_test_reading().
Sending shutdown when ngx_http_test_reading() detects the connection is
closed can result in "SSL_shutdown() failed (SSL: ... bad write retry)"
critical log messages if there are blocked writes.

Fix is to avoid sending shutdown via the c->ssl->no_send_shutdown flag,
similarly to how it is done in ngx_http_keepalive_handler() for kqueue
when pending EOF is detected.

Reported by Jan Prachař
(http://mailman.nginx.org/pipermail/nginx-devel/2018-December/011702.html).
2020-08-10 18:52:34 +03:00
Maxim Dounin
1d696cd379 HTTP/2: fixed c->timedout flag on timed out connections.
Without the flag, SSL shutdown is attempted on such connections,
resulting in useless work and/or bogus "SSL_shutdown() failed
(SSL: ... bad write retry)" critical log messages if there are
blocked writes.
2020-08-10 18:52:20 +03:00
Maxim Dounin
e01cdfbd8c SSL: fixed shutdown handling.
Previously, bidirectional shutdown never worked, due to two issues
in the code:

1. The code only tested SSL_ERROR_WANT_READ and SSL_ERROR_WANT_WRITE
   when there was an error in the error queue, which cannot happen.
   The bug was introduced in an attempt to fix unexpected error logging
   as reported with OpenSSL 0.9.8g
   (http://mailman.nginx.org/pipermail/nginx/2008-January/003084.html).

2. The code never called SSL_shutdown() for the second time to wait for
   the peer's close_notify alert.

This change fixes both issues.

Note that after this change bidirectional shutdown is expected to work for
the first time, so c->ssl->no_wait_shutdown now makes a difference.  This
is not a problem for HTTP code which always uses c->ssl->no_wait_shutdown,
but might be a problem for stream and mail code, as well as 3rd party
modules.

To minimize the effect of the change, the timeout, which was used to be 30
seconds and not configurable, though never actually used, is now set to
3 seconds.  It is also expanded to apply to both SSL_ERROR_WANT_READ and
SSL_ERROR_WANT_WRITE, so timeout is properly set if writing to the socket
buffer is not possible.
2020-08-10 18:52:09 +03:00
Maxim Dounin
130a5e7126 Request body: optimized handling of small chunks.
If there is a previous buffer, copy small chunks into it instead of
allocating additional buffer.
2020-08-06 05:02:57 +03:00
Maxim Dounin
150cbb017b Request body: allowed large reads on chunk boundaries.
If some additional data from a pipelined request happens to be
read into the body buffer, we copy it to r->header_in or allocate
an additional large client header buffer for it.
2020-08-06 05:02:55 +03:00
Maxim Dounin
9edc93fe0e Request body: all read data are now sent to filters.
This is a prerequisite for the next change to allow large reads
on chunk boundaries.
2020-08-06 05:02:44 +03:00
Maxim Dounin
bd7dad5b0e Added size check to ngx_http_alloc_large_header_buffer().
This ensures that copying won't write more than the buffer size
even if the buffer comes from hc->free and it is smaller than the large
client header buffer size in the virtual host configuration.  This might
happen if size of large client header buffers is different in name-based
virtual hosts, similarly to the problem with number of buffers fixed
in 6926:e662cbf1b932.
2020-08-06 05:02:22 +03:00
Roman Arutyunyan
cb0e3a2658 QUIC: handle client RESET_STREAM and STOP_SENDING.
For RESET_STREAM the c->read->error flag is set.
For STOP_SENDING the c->write->error flag is set.
2020-08-03 13:31:48 +03:00
Roman Arutyunyan
e97c50cdd6 QUIC: create streams for STREAM_DATA_BLOCKED and MAX_STREAM_DATA.
Creating client-initiated streams is moved from ngx_quic_handle_stream_frame()
to a separate function ngx_quic_create_client_stream().  This function is
responsible for creating streams with lower ids as well.

Also, simplified and fixed initial data buffering in
ngx_quic_handle_stream_frame().  It is now done before calling the initial
handler as the handler can destroy the stream.
2020-08-11 19:10:57 +03:00
Roman Arutyunyan
68c5d80ee5 QUIC: fixed ngx_http_test_reading() for QUIC streams.
Previously this function generated an error trying to figure out if client shut
down the write end of the connection.  The reason for this error was that a
QUIC stream has no socket descriptor.  However checking for eof is not the
right thing to do for an HTTP/3 QUIC stream since HTTP/3 clients are expected
to shut down the write end of the stream after sending the request.

Now the function handles QUIC streams separately.  It checks if c->read->error
is set.  The error flags for c->read and c->write are now set for all streams
when closing the QUIC connection instead of setting the pending_eof flag.
2020-08-11 10:41:39 +03:00
Sergey Kandaurov
e4ca695700 QUIC: fixed ACK Ranges processing.
According to quic-transport draft 29, section 19.3.1:

   The value of the Gap field establishes the largest packet number
   value for the subsequent ACK Range using the following formula:

      largest = previous_smallest - gap - 2

   Thus, given a largest packet number for the range, the smallest value
   is determined by the formula:

      smallest = largest - ack_range

While here, changed min/max to uint64_t for consistency.
2020-08-07 12:34:15 +03:00
Sergey Kandaurov
7d1a1fb6de QUIC: fixed possible use-after-free on stream cleanup.
A QUIC stream could be destroyed by handler while in ngx_quic_stream_input().
To detect this, ngx_quic_find_stream() is used to check that it still exists.

Previously, a stream id was passed to this routine off the frame structure.
In case of stream cleanup, it is freed along with other frames belonging to
the stream on cleanup.  Then, a cleanup handler reuses last frames to update
MAX_STREAMS and serve other purpose.  Thus, ngx_quic_find_stream() is passed
a reused frame with zeroed out part pointed by stream_id.  If a stream with
id 0x0 still exists, this leads to use-after-free.
2020-08-07 12:34:11 +03:00
Sergey Kandaurov
4ded4e3402 QUIC: fixed format specifiers and removed casts. 2020-07-28 18:54:20 +03:00
Sergey Kandaurov
c2e9b362ed QUIC: consistent Stream ID logging format. 2020-07-28 17:11:25 +03:00
Maxim Dounin
d2744ad26f FastCGI: fixed zero size buf alerts on extra data (ticket #2018).
After 05e42236e95b (1.19.1) responses with extra data might result in
zero size buffers being generated and "zero size buf" alerts in writer
(if f->rest happened to be 0 when processing additional stdout data).
2020-07-27 16:02:15 +03:00
balus
c3db6f729f Core: enclosed parameters of the ngx_buf.h macros in parentheses. 2020-07-27 13:21:51 +03:00
Sergey Kandaurov
4ee66b3f7b OCSP: fixed certificate reference leak. 2020-07-23 17:31:09 +03:00
Roman Arutyunyan
6d064c94e0 HTTP/3: server pushes.
New directives are added:
- http3_max_concurrent_pushes
- http3_push
- http3_push_preload
2020-07-23 13:41:24 +03:00
Roman Arutyunyan
77384356ce QUIC: limited the number of client-initiated streams.
The limits on active bidi and uni client streams are maintained at their
initial values initial_max_streams_bidi and initial_max_streams_uni by sending
a MAX_STREAMS frame upon each client stream closure.

Also, the following is changed for data arriving to non-existing streams:

- if a stream was already closed, such data is ignored
- when creating a new stream, all streams of the same type with lower ids are
  created too
2020-07-27 19:15:17 +03:00
Roman Arutyunyan
a1f7106bf7 QUIC: limited the number of server-initiated streams.
Also, ngx_quic_create_uni_stream() is replaced with
ngx_quic_open_stream() which is capable of creating a bidi stream.
2020-07-27 18:51:42 +03:00
Roman Arutyunyan
4dd43dfca7 Xslt: disabled ranges.
Previously, the document generated by the xslt filter was always fully sent
to client even if a range was requested and response status was 206 with
appropriate Content-Range.

The xslt module is unable to serve a range because of suspending the header
filter chain.  By the moment full response xml is buffered by the xslt filter,
range header filter is not called yet, but the range body filter has already
been called and did nothing.

The fix is to disable ranges by resetting the r->allow_ranges flag much like
the image filter that employs a similar technique.
2020-07-22 22:16:19 +03:00
Ruslan Ermilov
80daef96f1 Core: close PID file when writing fails.
Reported by Jinhua Tan.
2020-07-21 20:34:29 +03:00
Roman Arutyunyan
5e036a6bef HTTP/3: support $server_protocol variable.
Now it holds "HTTP/3.0".  Previously it was empty.
2020-07-14 16:52:44 +03:00
Roman Arutyunyan
c8a194b29a Style: moved function declarations to match usual code style.
Plus a few other minor style changes.
2020-07-23 11:40:10 +03:00
Roman Arutyunyan
f2368597c2 HTTP/3: renamed server configuration variables from v3cf to h3scf.
Now they are similar to HTTP/2 where they are called h2scf.
2020-07-23 13:12:01 +03:00