]> git.kaiwu.me - nginx.git/log
nginx.git
4 years agoSSL: use of the SSL_OP_IGNORE_UNEXPECTED_EOF option.
Sergey Kandaurov [Tue, 10 Aug 2021 20:43:17 +0000 (23:43 +0300)]
SSL: use of the SSL_OP_IGNORE_UNEXPECTED_EOF option.

A new behaviour was introduced in OpenSSL 1.1.1e, when a peer does not send
close_notify before closing the connection.  Previously, it was to return
SSL_ERROR_SYSCALL with errno 0, known since at least OpenSSL 0.9.7, and is
handled gracefully in nginx.  Now it returns SSL_ERROR_SSL with a distinct
reason SSL_R_UNEXPECTED_EOF_WHILE_READING ("unexpected eof while reading").
This leads to critical errors seen in nginx within various routines such as
SSL_do_handshake(), SSL_read(), SSL_shutdown().  The behaviour was restored
in OpenSSL 1.1.1f, but presents in OpenSSL 3.0 by default.

Use of the SSL_OP_IGNORE_UNEXPECTED_EOF option added in OpenSSL 3.0 allows
to set a compatible behaviour to return SSL_ERROR_ZERO_RETURN:
https://git.openssl.org/?p=openssl.git;a=commitdiff;h=09b90e0

See for additional details: https://github.com/openssl/openssl/issues/11381

4 years agoSSL: silenced warnings when building with OpenSSL 3.0.
Sergey Kandaurov [Tue, 10 Aug 2021 20:43:16 +0000 (23:43 +0300)]
SSL: silenced warnings when building with OpenSSL 3.0.

The OPENSSL_SUPPRESS_DEPRECATED macro is used to suppress deprecation warnings.
This covers Session Tickets keys, SSL Engine, DH low level API for DHE ciphers.

Unlike OPENSSL_API_COMPAT, it works well with OpenSSL built with no-deprecated.
In particular, it doesn't unhide various macros in OpenSSL includes, which are
meant to be hidden under OPENSSL_NO_DEPRECATED.

4 years agoSSL: ERR_peek_error_line_data() compatibility with OpenSSL 3.0.
Sergey Kandaurov [Tue, 10 Aug 2021 20:43:16 +0000 (23:43 +0300)]
SSL: ERR_peek_error_line_data() compatibility with OpenSSL 3.0.

ERR_peek_error_line_data() was deprecated in favour of ERR_peek_error_all().
Here we use the ERR_peek_error_data() helper to pass only used arguments.

4 years agoSSL: using SSL_CTX_set0_tmp_dh_pkey() with OpenSSL 3.0 in dhparam.
Sergey Kandaurov [Tue, 10 Aug 2021 20:43:16 +0000 (23:43 +0300)]
SSL: using SSL_CTX_set0_tmp_dh_pkey() with OpenSSL 3.0 in dhparam.

Using PEM_read_bio_DHparams() and SSL_CTX_set_tmp_dh() is deprecated
as part of deprecating the low level DH functions in favor of EVP_PKEY:
https://git.openssl.org/?p=openssl.git;a=commitdiff;h=163f6dc

4 years agoSSL: SSL_get_peer_certificate() is deprecated in OpenSSL 3.0.
Sergey Kandaurov [Tue, 10 Aug 2021 20:43:16 +0000 (23:43 +0300)]
SSL: SSL_get_peer_certificate() is deprecated in OpenSSL 3.0.

Switch to SSL_get1_peer_certificate() when building with OpenSSL 3.0
and OPENSSL_NO_DEPRECATED defined.

4 years agoSSL: RSA data type is deprecated in OpenSSL 3.0.
Sergey Kandaurov [Tue, 10 Aug 2021 20:42:59 +0000 (23:42 +0300)]
SSL: RSA data type is deprecated in OpenSSL 3.0.

The only consumer is a callback function for SSL_CTX_set_tmp_rsa_callback()
deprecated in OpenSSL 1.1.0.  Now the function is conditionally compiled too.

4 years agoDisabled HTTP/1.0 requests with Transfer-Encoding.
Sergey Kandaurov [Mon, 9 Aug 2021 15:12:12 +0000 (18:12 +0300)]
Disabled HTTP/1.0 requests with Transfer-Encoding.

The latest HTTP/1.1 draft describes Transfer-Encoding in HTTP/1.0 as having
potentially faulty message framing as that could have been forwarded without
handling of the chunked encoding, and forbids processing subsequest requests
over that connection: https://github.com/httpwg/http-core/issues/879.

While handling of such requests is permitted, the most secure approach seems
to reject them.

4 years agoSSL: SSL_CTX_set_tmp_dh() error handling.
Sergey Kandaurov [Wed, 4 Aug 2021 18:27:51 +0000 (21:27 +0300)]
SSL: SSL_CTX_set_tmp_dh() error handling.

For example, it can fail due to weak DH parameters.

4 years agoSSL: set events ready flags after handshake.
Maxim Dounin [Tue, 3 Aug 2021 17:50:30 +0000 (20:50 +0300)]
SSL: set events ready flags after handshake.

The c->read->ready and c->write->ready flags might be reset during
the handshake, and not set again if the handshake was finished on
the other event.  At the same time, some data might be read from
the socket during the handshake, so missing c->read->ready flag might
result in a connection hang, for example, when waiting for an SMTP
greeting (which was already received during the handshake).

Found by Sergey Kandaurov.

4 years agoVersion bump.
Maxim Dounin [Tue, 3 Aug 2021 17:50:08 +0000 (20:50 +0300)]
Version bump.

4 years agorelease-1.21.1 tag
Maxim Dounin [Tue, 6 Jul 2021 14:59:17 +0000 (17:59 +0300)]
release-1.21.1 tag

4 years agonginx-1.21.1-RELEASE release-1.21.1
Maxim Dounin [Tue, 6 Jul 2021 14:59:16 +0000 (17:59 +0300)]
nginx-1.21.1-RELEASE

4 years agoWin32: use only preallocated memory in send/recv chain functions.
Ruslan Ermilov [Mon, 5 Jul 2021 10:26:49 +0000 (13:26 +0300)]
Win32: use only preallocated memory in send/recv chain functions.

The ngx_wsasend_chain() and ngx_wsarecv_chain() functions were
modified to use only preallocated memory, and the number of
preallocated wsabufs was increased to 64.

4 years agoUse only preallocated memory in ngx_readv_chain() (ticket #1408).
Ruslan Ermilov [Mon, 5 Jul 2021 10:09:23 +0000 (13:09 +0300)]
Use only preallocated memory in ngx_readv_chain() (ticket #1408).

In d1bde5c3c5d2, the number of preallocated iovec's for ngx_readv_chain()
was increased.  Still, in some setups, the function might allocate memory
for iovec's from a connection pool, which is only freed when closing the
connection.

The ngx_readv_chain() function was modified to use only preallocated
memory, similarly to the ngx_writev_chain() change in 8e903522c17a.

4 years agoDisabled control characters in the Host header.
Maxim Dounin [Mon, 28 Jun 2021 15:01:24 +0000 (18:01 +0300)]
Disabled control characters in the Host header.

Control characters (0x00-0x1f, 0x7f) and space are not expected to appear
in the Host header.  Requests with such characters in the Host header are
now unconditionally rejected.

4 years agoImproved logging of invalid headers.
Maxim Dounin [Mon, 28 Jun 2021 15:01:20 +0000 (18:01 +0300)]
Improved logging of invalid headers.

In 71edd9192f24 logging of invalid headers which were rejected with the
NGX_HTTP_PARSE_INVALID_HEADER error was restricted to just the "client
sent invalid header line" message, without any attempts to log the header
itself.

This patch returns logging of the header up to the invalid character and
the character itself.  The r->header_end pointer is now properly set
in all cases to make logging possible.

The same logging is also introduced when parsing headers from upstream
servers.

4 years agoDisabled control characters and space in header names.
Maxim Dounin [Mon, 28 Jun 2021 15:01:18 +0000 (18:01 +0300)]
Disabled control characters and space in header names.

Control characters (0x00-0x1f, 0x7f), space, and colon were never allowed in
header names.  The only somewhat valid use is header continuation which nginx
never supported and which is explicitly obsolete by RFC 7230.

Previously, such headers were considered invalid and were ignored by default
(as per ignore_invalid_headers directive).  With this change, such headers
are unconditionally rejected.

It is expected to make nginx more resilient to various attacks, in particular,
with ignore_invalid_headers switched off (which is inherently unsecure, though
nevertheless sometimes used in the wild).

4 years agoDisabled control characters in URIs.
Maxim Dounin [Mon, 28 Jun 2021 15:01:15 +0000 (18:01 +0300)]
Disabled control characters in URIs.

Control characters (0x00-0x1f, 0x7f) were never allowed in URIs, and must
be percent-encoded by clients.  Further, these are not believed to appear
in practice.  On the other hand, passing such characters might make various
attacks possible or easier, despite the fact that currently allowed control
characters are not significant for HTTP request parsing.

4 years agoDisabled spaces in URIs (ticket #196).
Maxim Dounin [Mon, 28 Jun 2021 15:01:13 +0000 (18:01 +0300)]
Disabled spaces in URIs (ticket #196).

From now on, requests with spaces in URIs are immediately rejected rather
than allowed.  Spaces were allowed in 31e9677b15a1 (0.8.41) to handle bad
clients.  It is believed that now this behaviour causes more harm than
good.

4 years agoCore: escaping of chars not allowed in URIs per RFC 3986.
Maxim Dounin [Mon, 28 Jun 2021 15:01:11 +0000 (18:01 +0300)]
Core: escaping of chars not allowed in URIs per RFC 3986.

Per RFC 3986 only the following characters are allowed in URIs unescaped:

unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
gen-delims    = ":" / "/" / "?" / "#" / "[" / "]" / "@"
sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
              / "*" / "+" / "," / ";" / "="

And "%" can appear as a part of escaping itself.  The following
characters are not allowed and need to be escaped: %00-%1F, %7F-%FF,
" ", """, "<", ">", "\", "^", "`", "{", "|", "}".

Not escaping ">" is known to cause problems at least with MS Exchange (see
http://nginx.org/pipermail/nginx-ru/2010-January/031261.html) and in
Tomcat (ticket #2191).

The patch adds escaping of the following chars in all URI parts: """, "<",
">", "\", "^", "`", "{", "|", "}".  Note that comments are mostly preserved
to outline important characters being escaped.

4 years agoCore: fixed comment about escaping in arguments.
Maxim Dounin [Mon, 28 Jun 2021 15:01:09 +0000 (18:01 +0300)]
Core: fixed comment about escaping in arguments.

After 4954530db2af, the ";" character is escaped by
ngx_escape_uri(NGX_ESCAPE_ARGS).

4 years agoDisabled requests with both Content-Length and Transfer-Encoding.
Maxim Dounin [Mon, 28 Jun 2021 15:01:06 +0000 (18:01 +0300)]
Disabled requests with both Content-Length and Transfer-Encoding.

HTTP clients are not allowed to generate such requests since Transfer-Encoding
introduction in RFC 2068, and they are not expected to appear in practice
except in attempts to perform a request smuggling attack.  While handling of
such requests is strictly defined, the most secure approach seems to reject
them.

4 years agoAdded CONNECT method rejection.
Maxim Dounin [Mon, 28 Jun 2021 15:01:04 +0000 (18:01 +0300)]
Added CONNECT method rejection.

No valid CONNECT requests are expected to appear within nginx, since it
is not a forward proxy.  Further, request line parsing will reject
proper CONNECT requests anyway, since we don't allow authority-form of
request-target.  On the other hand, RFC 7230 specifies separate message
length rules for CONNECT which we don't support, so make sure to always
reject CONNECTs to avoid potential abuse.

4 years agoMoved TRACE method rejection to a better place.
Maxim Dounin [Mon, 28 Jun 2021 15:01:00 +0000 (18:01 +0300)]
Moved TRACE method rejection to a better place.

Previously, TRACE requests were rejected before parsing Transfer-Encoding.
This is not important since keepalive is not enabled at this point anyway,
though rejecting such requests after properly parsing other headers is
less likely to cause issues in case of further code changes.

4 years agoCore: added the ngx_rbtree_data() macro.
Vladimir Homutov [Mon, 21 Jun 2021 06:42:43 +0000 (09:42 +0300)]
Core: added the ngx_rbtree_data() macro.

4 years agoFixed format strings for ngx_win32_version.
Maxim Dounin [Fri, 18 Jun 2021 01:00:21 +0000 (04:00 +0300)]
Fixed format strings for ngx_win32_version.

4 years agogRPC: RST_STREAM(NO_ERROR) handling micro-optimization.
Sergey Kandaurov [Thu, 17 Jun 2021 08:44:06 +0000 (11:44 +0300)]
gRPC: RST_STREAM(NO_ERROR) handling micro-optimization.

After 2096b21fcd10, a single RST_STREAM(NO_ERROR) may not result in an error.
This change removes several unnecessary ctx->type checks for such a case.

4 years agogRPC: handling GOAWAY with a higher last stream identifier.
Sergey Kandaurov [Thu, 17 Jun 2021 08:43:55 +0000 (11:43 +0300)]
gRPC: handling GOAWAY with a higher last stream identifier.

Previously, once received from upstream, it couldn't limit
opening additional streams in a cached keepalive connection.

4 years agoFixed SSL logging with lingering close.
Maxim Dounin [Tue, 1 Jun 2021 14:37:51 +0000 (17:37 +0300)]
Fixed SSL logging with lingering close.

Recent fixes to SSL shutdown with lingering close (554c6ae25ffc, 1.19.5)
broke logging of SSL variables.  To make sure logging of SSL variables
works properly, avoid freeing c->ssl when doing an SSL shutdown before
lingering close.

Reported by Reinis Rozitis
(http://mailman.nginx.org/pipermail/nginx/2021-May/060670.html).

4 years agoSSL: ngx_ssl_shutdown() rework.
Maxim Dounin [Tue, 1 Jun 2021 14:37:49 +0000 (17:37 +0300)]
SSL: ngx_ssl_shutdown() rework.

Instead of calling SSL_free() with each return point, introduced a single
place where cleanup happens.  As a positive side effect, this fixes two
potential memory leaks on ngx_handle_read_event() and ngx_handle_write_event()
errors where there were no SSL_free() calls (though unlikely practical,
as errors there are only expected to happen due to bugs or kernel issues).

4 years agoContrib: vim syntax, update core and 3rd party module directives.
Gena Makhomed [Sun, 30 May 2021 09:26:00 +0000 (12:26 +0300)]
Contrib: vim syntax, update core and 3rd party module directives.

4 years agoCore: disabled SO_REUSEADDR on UDP sockets while testing config.
Maxim Dounin [Mon, 31 May 2021 13:36:51 +0000 (16:36 +0300)]
Core: disabled SO_REUSEADDR on UDP sockets while testing config.

On Linux, SO_REUSEADDR allows completely duplicate UDP sockets, so using
SO_REUSEADDR when testing configuration results in packets being dropped
if there is an existing traffic on the sockets being tested (ticket #2187).
While dropped packets are expected with UDP, it is better to avoid this
when possible.

With this change, SO_REUSEADDR is no longer set on datagram sockets when
testing configuration.

4 years agoCore: disabled cloning sockets when testing config (ticket #2188).
Maxim Dounin [Mon, 31 May 2021 13:36:37 +0000 (16:36 +0300)]
Core: disabled cloning sockets when testing config (ticket #2188).

Since we anyway do not set SO_REUSEPORT when testing configuration
(see ecb5cd305b06), trying to open additional sockets does not make much
sense, as all these additional sockets are expected to result in EADDRINUSE
errors from bind().  On the other hand, there are reports that trying
to open these sockets takes significant time under load: total configuration
testing time greater than 15s was observed in ticket #2188, compared to less
than 1s without load.

With this change, no additional sockets are opened during testing
configuration.

4 years agoVersion bump.
Maxim Dounin [Mon, 31 May 2021 13:36:12 +0000 (16:36 +0300)]
Version bump.

4 years agorelease-1.21.0 tag
Maxim Dounin [Tue, 25 May 2021 12:28:56 +0000 (15:28 +0300)]
release-1.21.0 tag

4 years agonginx-1.21.0-RELEASE release-1.21.0
Maxim Dounin [Tue, 25 May 2021 12:28:55 +0000 (15:28 +0300)]
nginx-1.21.0-RELEASE

4 years agoResolver: explicit check for compression pointers in question.
Maxim Dounin [Tue, 25 May 2021 12:17:50 +0000 (15:17 +0300)]
Resolver: explicit check for compression pointers in question.

Since nginx always uses exactly one entry in the question section of
a DNS query, and never uses compression pointers in this entry, parsing
of a DNS response in ngx_resolver_process_response() does not expect
compression pointers to appear in the question section of the DNS
response.  Indeed, compression pointers in the first name of a DNS response
hardly make sense, do not seem to be allowed by RFC 1035 (which says
"a pointer to a prior occurance of the same name", note "prior"), and
were never observed in practice.

Added an explicit check to ngx_resolver_process_response()'s parsing
of the question section to properly report an error if compression pointers
nevertheless appear in the question section.

4 years agoResolver: simplified ngx_resolver_copy().
Maxim Dounin [Tue, 25 May 2021 12:17:45 +0000 (15:17 +0300)]
Resolver: simplified ngx_resolver_copy().

Instead of checking on each label if we need to place a dot or not,
now it always adds a dot after a label, and reduces the resulting
length afterwards.

4 years agoResolver: reworked ngx_resolver_copy() copy loop.
Maxim Dounin [Tue, 25 May 2021 12:17:43 +0000 (15:17 +0300)]
Resolver: reworked ngx_resolver_copy() copy loop.

To make the code easier to read, reworked the ngx_resolver_copy()
copy loop to match the one used to calculate length.  No functional
changes.

4 years agoResolver: fixed label types handling in ngx_resolver_copy().
Maxim Dounin [Tue, 25 May 2021 12:17:41 +0000 (15:17 +0300)]
Resolver: fixed label types handling in ngx_resolver_copy().

Previously, anything with any of the two high bits set were interpreted
as compression pointers.  This is incorrect, as RFC 1035 clearly states
that "The 10 and 01 combinations are reserved for future use".  Further,
the 01 combination is actually allocated for EDNS extended label type
(see RFC 2671 and RFC 6891), not really used though.

Fix is to reject unrecognized label types rather than misinterpreting
them as compression pointers.

4 years agoResolver: fixed off-by-one read in ngx_resolver_copy().
Maxim Dounin [Tue, 25 May 2021 12:17:38 +0000 (15:17 +0300)]
Resolver: fixed off-by-one read in ngx_resolver_copy().

It is believed to be harmless, and in the worst case it uses some
uninitialized memory as a part of the compression pointer length,
eventually leading to the "name is out of DNS response" error.

4 years agoResolver: fixed off-by-one write in ngx_resolver_copy().
Maxim Dounin [Tue, 25 May 2021 12:17:36 +0000 (15:17 +0300)]
Resolver: fixed off-by-one write in ngx_resolver_copy().

Reported by Luis Merino, Markus Vervier, Eric Sesterhenn, X41 D-Sec GmbH.

4 years agoLocation header escaping in redirects (ticket #882).
Ruslan Ermilov [Mon, 24 May 2021 18:55:20 +0000 (21:55 +0300)]
Location header escaping in redirects (ticket #882).

The header is escaped in redirects based on request URI or
location name (auto redirect).

4 years agoFixed log action when using SSL certificates with variables.
Maxim Dounin [Mon, 24 May 2021 15:23:42 +0000 (18:23 +0300)]
Fixed log action when using SSL certificates with variables.

When variables are used in ssl_certificate or ssl_certificate_key, a request
is created in the certificate callback to evaluate the variables, and then
freed.  Freeing it, however, updates c->log->action to "closing request",
resulting in confusing error messages like "client timed out ... while
closing request" when a client times out during the SSL handshake.

Fix is to restore c->log->action after calling ngx_http_free_request().

4 years agoStream: the "fastopen" parameter of the "listen" directive.
Ruslan Ermilov [Thu, 20 May 2021 16:59:16 +0000 (19:59 +0300)]
Stream: the "fastopen" parameter of the "listen" directive.

Based on a patch by Anbang Wen.

4 years agoCore: fixed comment about msie_refresh escaping.
Ruslan Ermilov [Wed, 19 May 2021 13:24:13 +0000 (16:24 +0300)]
Core: fixed comment about msie_refresh escaping.

After 12a656452ad1, the "%" character is no longer escaped by
ngx_escape_uri(NGX_ESCAPE_REFRESH).

4 years agoMail: max_errors directive.
Maxim Dounin [Wed, 19 May 2021 00:13:31 +0000 (03:13 +0300)]
Mail: max_errors directive.

Similarly to smtpd_hard_error_limit in Postfix and smtp_max_unknown_commands
in Exim, specifies the number of errors after which the connection is closed.

4 years agoMail: IMAP pipelining support.
Maxim Dounin [Wed, 19 May 2021 00:13:28 +0000 (03:13 +0300)]
Mail: IMAP pipelining support.

The change is mostly the same as the SMTP one (04e43d03e153 and 3f5d0af4e40a),
and ensures that nginx is able to properly handle or reject multiple IMAP
commands.  The s->cmd field is not really used and set for consistency.

Non-synchronizing literals handling in invalid/unknown commands is limited,
so when a non-synchronizing literal is detected at the end of a discarded
line, the connection is closed.

4 years agoMail: stricter checking of IMAP tags.
Maxim Dounin [Wed, 19 May 2021 00:13:26 +0000 (03:13 +0300)]
Mail: stricter checking of IMAP tags.

Only "A-Za-z0-9-._" characters now allowed (which is stricter than what
RFC 3501 requires, but expected to be enough for all known clients),
and tags shouldn't be longer than 32 characters.

4 years agoMail: fixed backslash handling in IMAP literals.
Maxim Dounin [Wed, 19 May 2021 00:13:23 +0000 (03:13 +0300)]
Mail: fixed backslash handling in IMAP literals.

Previously, s->backslash was set if any of the arguments was a quoted
string with a backslash character.  After successful command parsing
this resulted in all arguments being filtered to remove backslashes.
This is, however, incorrect, as backslashes should not be removed from
IMAP literals.  For example:

   S: * OK IMAP4 ready
   C: a01 login {9}
   S: + OK
   C: user\name "pass\"word"
   S: * BAD internal server error

resulted in "Auth-User: username" instead of "Auth-User: user\name"
as it should.

Fix is to apply backslash filtering on per-argument basis during parsing.

4 years agoMail: removed dead s->arg_start handling.
Maxim Dounin [Wed, 19 May 2021 00:13:22 +0000 (03:13 +0300)]
Mail: removed dead s->arg_start handling.

As discussed in the previous change, s->arg_start handling in the "done"
labels of ngx_mail_pop3_parse_command(), ngx_mail_imap_parse_command(),
and ngx_mail_smtp_parse_command() is wrong: s->arg_start cannot be
set there, as it is handled and cleared on all code paths where the
"done" labels are reached.  The relevant code is dead and now removed.

4 years agoMail: fixed s->arg_start clearing on invalid IMAP commands.
Maxim Dounin [Wed, 19 May 2021 00:13:20 +0000 (03:13 +0300)]
Mail: fixed s->arg_start clearing on invalid IMAP commands.

Previously, s->arg_start was left intact after invalid IMAP commands,
and this might result in an argument incorrectly added to the following
command.  Similarly, s->backslash was left intact as well, leading
to unneeded backslash removal.

For example (LFs from the client are explicitly shown as "<LF>"):

  S: * OK IMAP4 ready
  C: a01 login "\<LF>
  S: a01 BAD invalid command
  C: a0000000000\2 authenticate <LF>
  S: a00000000002 aBAD invalid command

The backslash followed by LF generates invalid command with s->arg_start
and s->backslash set, the following command incorrectly treats anything
from the old s->arg_start to the space after the command as an argument,
and removes the backslash from the tag.  If there is no space, s->arg_end
will be NULL.

Both things seem to be harmless though.  In particular:

- This can be used to provide an incorrect argument to a command without
  arguments.  The only command which seems to look at the single argument
  is AUTHENTICATE, and it checks the argument length before trying to
  access it.

- Backslash removal uses the "end" pointer, and stops due to "src < end"
  condition instead of scanning all the process memory if s->arg_end is
  NULL (and arg[0].len is huge).

- There should be no backslashes in unquoted strings.

An obvious fix is to clear s->arg_start and s->backslash on invalid commands,
similarly to how it is done in POP3 parsing (added in 810:e3aa8f305d21) and
SMTP parsing.

This, however, makes it clear that s->arg_start handling in the "done"
label is wrong: s->arg_start cannot be legitimately set there, as it
is expected to be cleared in all possible cases when the "done" label is
reached.  The relevant code is dead and will be removed by the following
change.

4 years agoMail: POP3 pipelining support.
Maxim Dounin [Wed, 19 May 2021 00:13:18 +0000 (03:13 +0300)]
Mail: POP3 pipelining support.

The change is mostly the same as the SMTP one (04e43d03e153 and 3f5d0af4e40a),
and ensures that nginx is able to properly handle or reject multiple POP3
commands, as required by the PIPELINING capability (RFC 2449).  The s->cmd
field is not really used and set for consistency.

4 years agoMail: optimized discarding invalid SMTP commands.
Maxim Dounin [Wed, 19 May 2021 00:13:17 +0000 (03:13 +0300)]
Mail: optimized discarding invalid SMTP commands.

There is no need to scan buffer from s->buffer->pos, as we already scanned
the buffer till "p" and wasn't able to find an LF.

There is no real need for this change in SMTP, since it is at most a
microoptimization of a non-common code path.  Similar code in IMAP, however,
will have to start scanning from "p" to be correct, since there can be
newlines in IMAP literals.

4 years agoMail: fixed handling of invalid SMTP commands split between reads.
Maxim Dounin [Wed, 19 May 2021 00:13:15 +0000 (03:13 +0300)]
Mail: fixed handling of invalid SMTP commands split between reads.

Previously, if an invalid SMTP command was split between reads, nginx failed
to wait for LF before returning an error, and interpreted the rest of the
command received later as a separate command.

The sw_invalid state in ngx_mail_smtp_parse_command(), introduced in
04e43d03e153, did not work, since ngx_mail_smtp_auth_state() clears
s->state when returning an error due to NGX_MAIL_PARSE_INVALID_COMMAND.
And not clearing s->state will introduce another problem: the rest
of the command would trigger duplicate error when rest of the command is
received.

Fix is to return NGX_AGAIN from ngx_mail_smtp_parse_command() until full
command is received.

4 years agoMail: fixed SMTP pipelining to send the response immediately.
Maxim Dounin [Wed, 19 May 2021 00:13:12 +0000 (03:13 +0300)]
Mail: fixed SMTP pipelining to send the response immediately.

Previously, if there were some pipelined SMTP data in the buffer when
a proxied connection with the backend was established, nginx called
ngx_mail_proxy_handler() to send these data, and not tried to send the
response to the last command.  In most cases, this response was later sent
along with the response to the pipelined command, but if for some reason
client decides to wait for the response before finishing the next command
this might result in a connection hang.

Fix is to always call ngx_mail_proxy_handler() to send the response, and
additionally post an event to send the pipelined data if needed.

5 years agoMIME: added application/wasm type (ticket #1606).
Maxim Dounin [Sat, 8 May 2021 17:31:03 +0000 (20:31 +0300)]
MIME: added application/wasm type (ticket #1606).

5 years agoUpstream: variables support in certificates.
Maxim Dounin [Wed, 5 May 2021 23:22:09 +0000 (02:22 +0300)]
Upstream: variables support in certificates.

5 years agoAuth basic: changed alcf->user_file to be a pointer.
Maxim Dounin [Wed, 5 May 2021 23:22:07 +0000 (02:22 +0300)]
Auth basic: changed alcf->user_file to be a pointer.

This saves some memory in typical case when auth_basic_user_file is not
explicitly set, and unifies the code with alcf->realm.

5 years agoChanged complex value slots to use NGX_CONF_UNSET_PTR.
Maxim Dounin [Wed, 5 May 2021 23:22:03 +0000 (02:22 +0300)]
Changed complex value slots to use NGX_CONF_UNSET_PTR.

With this change, it is now possible to use ngx_conf_merge_ptr_value()
to merge complex values.  This change 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), and the
change in ngx_conf_set_keyval_slot() (7728:485dba3e2a01, 1.19.4).

To preserve compatibility with existing 3rd party modules, both NULL
and NGX_CONF_UNSET_PTR are accepted for now.

5 years agoRestored zeroing of ngx_channel_t in ngx_pass_open_channel().
Ruslan Ermilov [Thu, 22 Apr 2021 13:12:52 +0000 (16:12 +0300)]
Restored zeroing of ngx_channel_t in ngx_pass_open_channel().

Due to structure's alignment, some uninitialized memory contents may have
been passed between processes.

Zeroing was removed in 0215ec9aaa8a.

Reported by Johnny Wang.

5 years agoMail: fixed reading with fully filled buffer (ticket #2159).
Maxim Dounin [Wed, 21 Apr 2021 20:24:59 +0000 (23:24 +0300)]
Mail: fixed reading with fully filled buffer (ticket #2159).

With SMTP pipelining, ngx_mail_read_command() can be called with s->buffer
without any space available, to parse additional commands received to the
buffer on previous calls.  Previously, this resulted in recv() being called
with zero length, resulting in zero being returned, which was interpreted
as a connection close by the client, so nginx silently closed connection.

Fix is to avoid calling c->recv() if there is no free space in the buffer,
but continue parsing of the already received commands.

5 years agoVersion bump.
Maxim Dounin [Wed, 21 Apr 2021 20:24:48 +0000 (23:24 +0300)]
Version bump.

5 years agorelease-1.19.10 tag
Maxim Dounin [Tue, 13 Apr 2021 15:13:59 +0000 (18:13 +0300)]
release-1.19.10 tag

5 years agonginx-1.19.10-RELEASE release-1.19.10
Maxim Dounin [Tue, 13 Apr 2021 15:13:58 +0000 (18:13 +0300)]
nginx-1.19.10-RELEASE

5 years agoChanged keepalive_requests default to 1000 (ticket #2155).
Maxim Dounin [Wed, 7 Apr 2021 21:16:30 +0000 (00:16 +0300)]
Changed keepalive_requests default to 1000 (ticket #2155).

It turns out no browsers implement HTTP/2 GOAWAY handling properly, and
large enough number of resources on a page results in failures to load
some resources.  In particular, Chrome seems to experience errors if
loading of all resources requires more than 1 connection (while it
is usually able to retry requests at least once, even with 2 connections
there are occasional failures for some reason), Safari if loading requires
more than 3 connections, and Firefox if loading requires more than 10
connections (can be configured with network.http.request.max-attempts,
defaults to 10).

It does not seem to be possible to resolve this on nginx side, even strict
limiting of maximum concurrency does not help, and loading issues seems to
be triggered by merely queueing of a request for a particular connection.
The only available mitigation seems to use higher keepalive_requests value.

The new default is 1000 and matches previously used default for
http2_max_requests.  It is expected to be enough for 99.98% of the pages
(https://httparchive.org/reports/state-of-the-web?start=latest#reqTotal)
even in Chrome.

5 years agoAdded $connection_time variable.
Maxim Dounin [Wed, 7 Apr 2021 21:16:17 +0000 (00:16 +0300)]
Added $connection_time variable.

5 years agoIntroduced the "keepalive_time" directive.
Maxim Dounin [Wed, 7 Apr 2021 21:15:48 +0000 (00:15 +0300)]
Introduced the "keepalive_time" directive.

Similar to lingering_time, it limits total connection lifetime before
keepalive is switched off.  The default is 1 hour, which is close to
the total maximum connection lifetime possible with default
keepalive_requests and keepalive_timeout.

5 years agoHTTP/2: relaxed PRIORITY frames limit.
Maxim Dounin [Tue, 6 Apr 2021 23:03:29 +0000 (02:03 +0300)]
HTTP/2: relaxed PRIORITY frames limit.

Firefox uses several idle streams for PRIORITY frames[1], and
"http2_max_concurrent_streams 1;" results in "client sent too many
PRIORITY frames" errors when a connection is established by Firefox.

Fix is to relax the PRIORITY frames limit to use at least 100 as
the initial value (which is the recommended by the HTTP/2 protocol
minimum limit on the number of concurrent streams, so it is not
unreasonable for clients to assume that similar number of idle streams
can be used for prioritization).

[1] https://hg.mozilla.org/mozilla-central/file/32a9e6e145d6e3071c3993a20bb603a2f388722b/netwerk/protocol/http/Http2Stream.cpp#l1270

5 years agoConfigure: fixed --test-build-epoll on FreeBSD 13.
Maxim Dounin [Mon, 5 Apr 2021 17:14:16 +0000 (20:14 +0300)]
Configure: fixed --test-build-epoll on FreeBSD 13.

In FreeBSD 13, eventfd(2) was added, and this breaks build
with --test-build-epoll and without --with-file-aio.  Fix is
to move eventfd(2) detection to auto/os/linux, as it is used
only on Linux as a notification mechanism for epoll().

5 years agoGzip: updated handling of zlib variant from Intel.
Maxim Dounin [Mon, 5 Apr 2021 01:07:17 +0000 (04:07 +0300)]
Gzip: updated handling of zlib variant from Intel.

In current versions (all versions based on zlib 1.2.11, at least
since 2018) it no longer uses 64K hash and does not force window
bits to 13 if it is less than 13.  That is, it needs just 16 bytes
more memory than normal zlib, so these bytes are simply added to
the normal size calculation.

5 years agoGzip: support for zlib-ng.
Maxim Dounin [Mon, 5 Apr 2021 01:06:58 +0000 (04:06 +0300)]
Gzip: support for zlib-ng.

5 years agoVersion bump.
Maxim Dounin [Mon, 5 Apr 2021 01:03:10 +0000 (04:03 +0300)]
Version bump.

5 years agorelease-1.19.9 tag
Maxim Dounin [Tue, 30 Mar 2021 14:47:11 +0000 (17:47 +0300)]
release-1.19.9 tag

5 years agonginx-1.19.9-RELEASE release-1.19.9
Maxim Dounin [Tue, 30 Mar 2021 14:47:11 +0000 (17:47 +0300)]
nginx-1.19.9-RELEASE

5 years agoUpdated OpenSSL used for win32 builds.
Maxim Dounin [Tue, 30 Mar 2021 14:44:36 +0000 (17:44 +0300)]
Updated OpenSSL used for win32 builds.

5 years agoFixed handling of already closed connections.
Maxim Dounin [Sun, 28 Mar 2021 14:45:39 +0000 (17:45 +0300)]
Fixed handling of already closed connections.

In limit_req, auth_delay, and upstream code to check for broken
connections, tests for possible connection close by the client
did not work if the connection was already closed when relevant
event handler was set.  This happened because there were no additional
events in case of edge-triggered event methods, and read events
were disabled in case of level-triggered ones.

Fix is to explicitly post a read event if the c->read->ready flag
is set.

5 years agoUpstream: fixed broken connection check with eventport.
Maxim Dounin [Sun, 28 Mar 2021 14:45:37 +0000 (17:45 +0300)]
Upstream: fixed broken connection check with eventport.

For connection close to be reported with eventport on Solaris,
ngx_handle_read_event() needs to be called.

5 years agoUpstream: fixed non-buffered proxying with eventport.
Maxim Dounin [Sun, 28 Mar 2021 14:45:35 +0000 (17:45 +0300)]
Upstream: fixed non-buffered proxying with eventport.

For new data to be reported with eventport on Solaris,
ngx_handle_read_event() needs to be called after reading response
headers.  To do so, ngx_http_upstream_process_non_buffered_upstream()
now called unconditionally if there are no prepread data.  This
won't cause any read() syscalls as long as upstream connection
is not ready for reading (c->read->ready is not set), but will result
in proper handling of all events.

5 years agoResolver: added missing event handling after reading.
Maxim Dounin [Sun, 28 Mar 2021 14:45:31 +0000 (17:45 +0300)]
Resolver: added missing event handling after reading.

If we need to be notified about further events, ngx_handle_read_event()
needs to be called after a read event is processed.  Without this,
an event can be removed from the kernel and won't be reported again,
notably when using oneshot event methods, such as eventport on Solaris.

While here, error handling is also added, similar to one present in
ngx_resolver_tcp_read().  This is not expected to make a difference
and mostly added for consistency.

5 years agoEvents: fixed "port_dissociate() failed" alerts with eventport.
Maxim Dounin [Sun, 28 Mar 2021 14:45:29 +0000 (17:45 +0300)]
Events: fixed "port_dissociate() failed" alerts with eventport.

If an attempt is made to delete an event which was already reported,
port_dissociate() returns an error.  Fix is avoid doing anything if
ev->active is not set.

Possible alternative approach would be to avoid calling ngx_del_event()
at all if ev->active is not set.  This approach, however, will require
something else to re-add the other event of the connection, since both
read and write events are dissociated if an event is reported on a file
descriptor.  Currently ngx_eventport_del_event() re-associates write
event if called to delete read event, and vice versa.

5 years agoEvents: fixed expiration of timers in the past.
Maxim Dounin [Thu, 25 Mar 2021 22:44:59 +0000 (01:44 +0300)]
Events: fixed expiration of timers in the past.

If, at the start of an event loop iteration, there are any timers
in the past (including timers expiring now), the ngx_process_events()
function is called with zero timeout, and returns immediately even
if there are no events.  But the following code only calls
ngx_event_expire_timers() if time actually changed, so this results
in nginx spinning in the event loop till current time changes.

While such timers are not expected to appear under normal conditions,
as all such timers should be removed on previous event loop iterations,
they still can appear due to bugs, zero timeouts set in the configuration
(if this is not explicitly handled by the code), or due to external
time changes on systems without clock_gettime(CLOCK_MONOTONIC).

Fix is to call ngx_event_expire_timers() unconditionally.  Calling
it on each event loop iteration is not expected to be significant from
performance point of view, especially compared to a syscall in
ngx_process_events().

5 years agoHTTP/2: improved handling of "keepalive_timeout 0".
Maxim Dounin [Thu, 25 Mar 2021 22:44:57 +0000 (01:44 +0300)]
HTTP/2: improved handling of "keepalive_timeout 0".

Without explicit handling, a zero timer was actually added, leading to
multiple unneeded syscalls.  Further, sending GOAWAY frame early might
be beneficial for clients.

Reported by Sergey Kandaurov.

5 years agoCancel keepalive and lingering close on EOF better (ticket #2145).
Sergey Kandaurov [Wed, 24 Mar 2021 11:03:33 +0000 (14:03 +0300)]
Cancel keepalive and lingering close on EOF better (ticket #2145).

Unlike in 75e908236701, which added the logic to ngx_http_finalize_request(),
this change moves it to a more generic routine ngx_http_finalize_connection()
to cover cases when a request is finalized with NGX_DONE.

In particular, this fixes unwanted connection transition into the keepalive
state after receiving EOF while discarding request body.  With edge-triggered
event methods that means the connection will last for extra seconds as set in
the keepalive_timeout directive.

5 years agogRPC: fixed handling of padding on DATA frames.
Maxim Dounin [Tue, 23 Mar 2021 13:52:23 +0000 (16:52 +0300)]
gRPC: fixed handling of padding on DATA frames.

The response size check introduced in 39501ce97e29 did not take into
account possible padding on DATA frames, resulting in incorrect
"upstream sent response body larger than indicated content length" errors
if upstream server used padding in responses with known length.

Fix is to check the actual size of response buffers produced by the code,
similarly to how it is done in other protocols, instead of checking
the size of DATA frames.

Reported at:
http://mailman.nginx.org/pipermail/nginx-devel/2021-March/013907.html

5 years agoRemoved "ch" argument from ngx_pass_open_channel().
Ruslan Ermilov [Thu, 11 Mar 2021 06:58:45 +0000 (09:58 +0300)]
Removed "ch" argument from ngx_pass_open_channel().

5 years agoMail: fixed build without SSL.
Maxim Dounin [Thu, 11 Mar 2021 01:46:26 +0000 (04:46 +0300)]
Mail: fixed build without SSL.

Broken by d84f13618277 and 12ea1de7d87c (1.19.8).

Reported by Sergey Osokin.

5 years agoVersion bump.
Maxim Dounin [Thu, 11 Mar 2021 01:46:22 +0000 (04:46 +0300)]
Version bump.

5 years agorelease-1.19.8 tag
Maxim Dounin [Tue, 9 Mar 2021 15:27:51 +0000 (18:27 +0300)]
release-1.19.8 tag

5 years agonginx-1.19.8-RELEASE release-1.19.8
Maxim Dounin [Tue, 9 Mar 2021 15:27:50 +0000 (18:27 +0300)]
nginx-1.19.8-RELEASE

5 years agoUpdated OpenSSL used for win32 builds.
Maxim Dounin [Tue, 9 Mar 2021 13:38:55 +0000 (16:38 +0300)]
Updated OpenSSL used for win32 builds.

5 years agoMail: sending of the PROXY protocol to backends.
Maxim Dounin [Fri, 5 Mar 2021 14:16:32 +0000 (17:16 +0300)]
Mail: sending of the PROXY protocol to backends.

Activated with the "proxy_protocol" directive.  Can be combined with
"listen ... proxy_protocol;" and "set_real_ip_from ...;" to pass
client address provided to nginx in the PROXY protocol header.

5 years agoMail: realip module.
Maxim Dounin [Fri, 5 Mar 2021 14:16:29 +0000 (17:16 +0300)]
Mail: realip module.

When configured with the "set_real_ip_from", it can set client's IP
address as visible in logs to the one obtained via the PROXY protocol.

5 years agoMail: parsing of the PROXY protocol from clients.
Maxim Dounin [Fri, 5 Mar 2021 14:16:24 +0000 (17:16 +0300)]
Mail: parsing of the PROXY protocol from clients.

Activated with the "proxy_protocol" parameter of the "listen" directive.
Obtained information is passed to the auth_http script in Proxy-Protocol-Addr,
Proxy-Protocol-Port, Proxy-Protocol-Server-Addr, and Proxy-Protocol-Server-Port
headers.

5 years agoMail: made auth http creating request easier to extend.
Maxim Dounin [Fri, 5 Mar 2021 14:16:23 +0000 (17:16 +0300)]
Mail: made auth http creating request easier to extend.

5 years agoMail: fixed log action after SSL handshake.
Maxim Dounin [Fri, 5 Mar 2021 14:16:20 +0000 (17:16 +0300)]
Mail: fixed log action after SSL handshake.

5 years agoMail: postponed session initialization under accept mutex.
Maxim Dounin [Fri, 5 Mar 2021 14:16:19 +0000 (17:16 +0300)]
Mail: postponed session initialization under accept mutex.

Similarly to 40e8ce405859 in the stream module, this reduces the time
accept mutex is held.  This also simplifies following changes to
introduce PROXY protocol support.

5 years agoMail: added missing event handling after reading data.
Maxim Dounin [Fri, 5 Mar 2021 14:16:17 +0000 (17:16 +0300)]
Mail: added missing event handling after reading data.

If we need to be notified about further events, ngx_handle_read_event()
needs to be called after a read event is processed.  Without this,
an event can be removed from the kernel and won't be reported again,
notably when using oneshot event methods, such as eventport on Solaris.

For consistency, existing ngx_handle_read_event() call removed from
ngx_mail_read_command(), as this call only covers one of the code paths
where ngx_mail_read_command() returns NGX_AGAIN.  Instead, appropriate
processing added to the callers, covering all code paths where NGX_AGAIN
is returned.

5 years agoMail: added missing event handling after blocking events.
Maxim Dounin [Fri, 5 Mar 2021 14:16:16 +0000 (17:16 +0300)]
Mail: added missing event handling after blocking events.

As long as a read event is blocked (ignored), ngx_handle_read_event()
needs to be called to make sure no further notifications will be
triggered when using level-triggered event methods, such as select() or
poll().

5 years agoEvents: fixed eventport handling in ngx_handle_read_event().
Maxim Dounin [Fri, 5 Mar 2021 14:16:15 +0000 (17:16 +0300)]
Events: fixed eventport handling in ngx_handle_read_event().

The "!rev->ready" test seems to be a typo, introduced in the original
commit (719:f30b1a75fd3b).  The ngx_handle_write_event() code properly
tests for "rev->ready" instead.

Due to this typo, read events might be unexpectedly removed during
proxying after an event on the other part of the proxied connection.
Catched by mail proxying tests.