aboutsummaryrefslogtreecommitdiff
path: root/src
Commit message (Collapse)AuthorAge
...
* SSL: available bytes handling (ticket #1431).Maxim Dounin2019-10-17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Added code to track number of bytes available in the socket. This makes it possible to avoid looping for a long time while working with fast enough peer when data are added to the socket buffer faster than we are able to read and process data. When kernel does not provide number of bytes available, it is retrieved using ioctl(FIONREAD) as long as a buffer is filled by SSL_read(). It is assumed that number of bytes returned by SSL_read() is close to the number of bytes read from the socket, as we do not use SSL compression. But even if it is not true for some reason, this is not important, as we post an additional reading event anyway. Note that data can be buffered at SSL layer, and it is not possible to simply stop reading at some point and wait till the event will be reported by the kernel again. This can be only done when there are no data in SSL buffers, and there is no good way to find out if it's the case. Instead of trying to figure out if SSL buffers are empty, this patch introduces events posted for the next event loop iteration - such events will be processed only on the next event loop iteration, after going into the kernel and retrieving additional events. This seems to be simple and reliable approach.
* Events: available bytes calculation via ioctl(FIONREAD).Maxim Dounin2019-10-17
| | | | | | | | | | | | | | | | | | | | | This makes it possible to avoid looping for a long time while working with a fast enough peer when data are added to the socket buffer faster than we are able to read and process them (ticket #1431). This is basically what we already do on FreeBSD with kqueue, where information about the number of bytes in the socket buffer is returned by the kevent() call. With other event methods rev->available is now set to -1 when the socket is ready for reading. Later in ngx_recv() and ngx_recv_chain(), if full buffer is received, real number of bytes in the socket buffer is retrieved using ioctl(FIONREAD). Reading more than this number of bytes ensures that even with edge-triggered event methods the event will be triggered again, so it is safe to stop processing of the socket and switch to other connections. Using ioctl(FIONREAD) only after reading a full buffer is an optimization. With this approach we only call ioctl(FIONREAD) when there are at least two recv()/readv() calls.
* SSL: improved ngx_ssl_recv_chain() to stop if c->read->ready is 0.Maxim Dounin2019-10-17
| | | | | | | | As long as there are data to read in the socket, yet the amount of data is less than total size of the buffers in the chain, this saves one unneeded read() syscall. Before this change, reading only stopped if ngx_ssl_recv() returned no data, that is, two read() syscalls in a row returned EAGAIN.
* Event pipe: disabled c->read->available checking for SSL.Maxim Dounin2019-10-17
| | | | | | | | | | In SSL connections, data can be buffered by the SSL layer, and it is wrong to avoid doing c->recv_chain() if c->read->available is 0 and c->read->pending_eof is set. And tests show that the optimization in question indeed can result in incorrect detection of premature connection close if upstream closes the connection without sending a close notify alert at the same time. Fix is to disable c->read->available optimization for SSL connections.
* Fixed header parsing with ignore_invalid_headers switched off.Ruslan Ermilov2019-10-15
| | | | | | The parsing was broken when the first character of the header name was invalid. Based on a patch by Alan Kemp.
* Fixed URI normalization with merge_slashes switched off.Maxim Dounin2019-10-08
| | | | | Previously, "/foo///../bar" was normalized into "/foo/bar" instead of "/foo//bar".
* The "/." and "/.." at the end of URI should be normalized.Ruslan Ermilov2019-10-08
|
* Improved detection of broken percent encoding in URI.Ruslan Ermilov2019-10-08
|
* Core: removed dead code in ngx_rbtree_delete().Vladimir Homutov2019-09-30
| | | | | The result of ngx_rbtree_min() is always a node with the left child equal to sentinel, thus the check is unnecessary.
* Version bump.Vladimir Homutov2019-09-30
|
* HTTP/2: fixed worker_shutdown_timeout.Ruslan Ermilov2019-09-23
|
* HTTP/2: fixed possible alert about left open socket on shutdown.Ruslan Ermilov2019-09-23
| | | | | | | | | | | | | | This could happen when graceful shutdown configured by worker_shutdown_timeout times out and is then followed by another timeout such as proxy_read_timeout. In this case, the HEADERS frame is added to the output queue, but attempt to send it fails (due to c->error forcibly set during graceful shutdown timeout). This triggers request finalization which attempts to close the stream. But the stream cannot be closed because there is a frame in the output queue, and the connection cannot be finalized. This leaves the connection open without any timer events leading to alert. The fix is to post write event when sending output queue fails on c->error. That will finalize the connection.
* HTTP/2: traffic-based flood detection.Maxim Dounin2019-09-18
| | | | | | | With this patch, all traffic over an HTTP/2 connection is counted in the h2c->total_bytes field, and payload traffic is counted in the h2c->payload_bytes field. As long as total traffic is many times larger than payload traffic, we consider this to be a flood.
* HTTP/2: switched back to RST_STREAM with NO_ERROR.Maxim Dounin2019-09-18
| | | | | | | | | In 8df664ebe037, we've switched to maximizing stream window instead of sending RST_STREAM. Since then handling of RST_STREAM with NO_ERROR was fixed at least in Chrome, hence we switch back to using RST_STREAM. This allows more effective rejecting of large bodies, and also minimizes non-payload traffic to be accounted in the next patch.
* SSL: fixed ssl_verify_client error message.Sergey Kandaurov2019-09-16
|
* Resolver: fixed possible use-after-free while resolving PTR.Sergey Kandaurov2019-09-10
| | | | | | | | | | Previously, if a response to the PTR request was cached, and ngx_resolver_dup() failed to allocate memory for the resulting name, then the original node was freed but left in expire_queue. A subsequent address resolving would end up in a use-after-free memory access of the node either in ngx_resolver_expire() or ngx_resolver_process_ptr(), when accessing it through expire_queue. The fix is to leave the resolver node intact.
* HTTP/2: close connection on zero WINDOW_UPDATE.Ruslan Ermilov2019-09-10
| | | | | | Don't waste server resources by sending RST_STREAM frames. Instead, reject WINDOW_UPDATE frames with invalid zero increment by closing connection with PROTOCOL_ERROR.
* HTTP/2: close connection on frames with self-dependency.Ruslan Ermilov2019-09-10
| | | | | | Don't waste server resources by sending RST_STREAM frames. Instead, reject HEADERS and PRIORITY frames with self-dependency by closing connection with PROTOCOL_ERROR.
* Fixed "return" with discarding invalid chunked body.Sergey Kandaurov2019-09-04
| | | | | | | | | When ngx_http_discard_request_body() call was added to ngx_http_send_response(), there were no return codes other than NGX_OK and NGX_HTTP_INTERNAL_SERVER_ERROR. Now it can also return NGX_HTTP_BAD_REQUEST, but ngx_http_send_response() still incorrectly transforms it to NGX_HTTP_INTERNAL_SERVER_ERROR. The fix is to propagate ngx_http_discard_request_body() errors.
* Detect runaway chunks in ngx_http_parse_chunked().Sergey Kandaurov2019-09-03
| | | | | | | | | | | | | | | | | As defined in HTTP/1.1, body chunks have the following ABNF: chunk = chunk-size [ chunk-ext ] CRLF chunk-data CRLF where chunk-data is a sequence of chunk-size octets. With this change, chunk-data that doesn't end up with CRLF at chunk-size offset will be treated as invalid, such as in the example provided below: 4 SEE-THIS-AND- 4 THAT 0
* HTTP/2: discard remaining request body after redirect.Sergey Kandaurov2019-08-19
| | | | | | | | | | | | | | | | | | | | | Previously, if unbuffered request body reading wasn't finished before the request was redirected to a different location using error_page or X-Accel-Redirect, and the request body is read again, this could lead to disastrous effects, such as a duplicate post_handler call or "http request count is zero" alert followed by a segmentation fault. This happened in the following configuration (ticket #1819): location / { proxy_request_buffering off; proxy_pass http://bad; proxy_intercept_errors on; error_page 502 = /error; } location /error { proxy_pass http://backend; }
* SSL: lowered log level for WSAECONNABORTED errors on Windows.Maxim Dounin2019-08-16
| | | | | | | | Winsock uses ECONNABORTED instead of ECONNRESET in some cases. For non-SSL connections this is already handled since baad3036086e. Reported at http://mailman.nginx.org/pipermail/nginx-ru/2019-August/062363.html.
* Version bump.Maxim Dounin2019-08-16
|
* HTTP/2: limited number of PRIORITY frames.Ruslan Ermilov2019-08-13
| | | | | Fixed excessive CPU usage caused by a peer that continuously shuffles priority of streams. Fix is to limit the number of PRIORITY frames.
* HTTP/2: limited number of DATA frames.Ruslan Ermilov2019-08-13
| | | | | | Fixed excessive memory growth and CPU usage if stream windows are manipulated in a way that results in generating many small DATA frames. Fix is to limit the number of simultaneously allocated DATA frames.
* HTTP/2: reject zero length headers with PROTOCOL_ERROR.Sergey Kandaurov2019-08-13
| | | | | | Fixed uncontrolled memory growth if peer sends a stream of headers with a 0-length header name and 0-length header value. Fix is to reject headers with zero name length.
* Mail: fixed duplicate resolving.Maxim Dounin2019-08-01
| | | | | | | | | | | | When using SMTP with SSL and resolver, read events might be enabled during address resolving, leading to duplicate ngx_mail_ssl_handshake_handler() calls if something arrives from the client, and duplicate session initialization - including starting another resolving. This can lead to a segmentation fault if the session is closed after first resolving finished. Fix is to block read events while resolving. Reported by Robert Norris, http://mailman.nginx.org/pipermail/nginx/2019-July/058204.html.
* Gzip: fixed "zero size buf" alerts after ac5a741d39cf.Maxim Dounin2019-07-31
| | | | | | | | | | | | | | | | After ac5a741d39cf it is now possible that after zstream.avail_out reaches 0 and we allocate additional buffer, there will be no more data to put into this buffer, triggering "zero size buf" alert. Fix is to reset b->temporary flag in this case. Additionally, an optimization added to avoid allocating additional buffer in this case, by checking if last deflate() call returned Z_STREAM_END. Note that checking for Z_STREAM_END by itself is not enough to fix alerts, as deflate() can return Z_STREAM_END without producing any output if the buffer is smaller than gzip trailer. Reported by Witold Filipczyk, http://mailman.nginx.org/pipermail/nginx-devel/2019-July/012469.html.
* Version bump.Maxim Dounin2019-07-31
|
* Core: fixed memory leak on error, missed in c3f60d618c17.Maxim Dounin2019-07-19
| | | | Found by Coverity (CID 1451664).
* Xslt: fixed potential buffer overflow with null character.Maxim Dounin2019-07-18
| | | | | | | | | | Due to shortcomings of the ccv->zero flag implementation in complex value interface, length of the resulting string from ngx_http_complex_value() might either not include terminating null character or include it, so the only safe way to work with the result is to use it as a null-terminated string. Reported by Patrick Wollgast.
* SSI: avoid potential buffer overflow.Maxim Dounin2019-07-18
| | | | | | | | | | When "-" follows a parameter of maximum length, a single byte buffer overflow happens, since the error branch does not check parameter length. Fix is to avoid saving "-" to the parameter key, and instead use an error message with "-" explicitly written. The message is mostly identical to one used in similar cases in the preequal state. Reported by Patrick Wollgast.
* Upstream: fixed EOF handling in unbuffered and upgraded modes.Maxim Dounin2019-07-18
| | | | | | | | With level-triggered event methods it is important to specify the NGX_CLOSE_EVENT flag to ngx_handle_read_event(), otherwise the event won't be removed, resulting in CPU hog. Reported by Patrick Wollgast.
* HTTP/2: return error on output on closed stream.Maxim Dounin2019-07-18
| | | | | Without this, an (incorrect) output on a closed stream could result in a socket leak.
* Core: fixed segfault with too large bucket sizes (ticket #1806).Maxim Dounin2019-07-18
| | | | | | | | | | To save memory hash code uses u_short to store resulting bucket sizes, so maximum bucket size is limited to 65536 minus ngx_cacheline_size (larger values will be aligned to 65536 which will overflow u_short). However, there were no checks to enforce this, and using larger bucket sizes resulted in overflows and segmentation faults. Appropriate safety checks to enforce this added to ngx_hash_init().
* Perl: removed unused variable, forgotten in 975d7ab37b39.Maxim Dounin2019-07-17
|
* Gzip: use zlib to write header and trailer.Ilya Leoshkevich2019-07-12
| | | | | | | | | | | | | | | | | | | | | When nginx is used with zlib patched with [1], which provides integration with the future IBM Z hardware deflate acceleration, it ends up computing CRC32 twice: one time in hardware, which always does this, and one time in software by explicitly calling crc32(). crc32() calls were added in changesets 133:b27548f540ad ("nginx-0.0.1- 2003-09-24-23:51:12 import") and 134:d57c6835225c ("nginx-0.0.1- 2003-09-26-09:45:21 import") as part of gzip wrapping feature - back then zlib did not support it. However, since then gzip wrapping was implemented in zlib v1.2.0.4, and it's already being used by nginx for log compression. This patch replaces hand-written gzip wrapping with the one provided by zlib. It simplifies the code, and makes it avoid computing CRC32 twice when using hardware acceleration. [1] https://github.com/madler/zlib/pull/410
* Perl: named locations in $r->internal_redirect().Maxim Dounin2019-07-12
|
* Perl: expect escaped URIs in $r->internal_redirect().Maxim Dounin2019-07-12
| | | | | | Similarly to the change in 5491:74bfa803a5aa (1.5.9), we should accept properly escaped URIs and unescape them as needed, else it is not possible to handle URIs with question marks.
* Perl: additional ctx->header_sent checks.Maxim Dounin2019-07-12
| | | | | | | | | As we now have ctx->header_sent flag, it is further used to prevent duplicate $r->send_http_header() calls, prevent output before sending header, and $r->internal_redirect() after sending header. Further, $r->send_http_header() protected from calls after $r->internal_redirect().
* Perl: avoid returning 500 if header was already sent.Maxim Dounin2019-07-12
| | | | | | | Returning NGX_HTTP_INTERNAL_SERVER_ERROR if a perl code died after sending header will lead to a "header already sent" alert. To avoid it, we now check if header was already sent, and return NGX_ERROR instead if it was.
* Perl: avoid redirects on errors.Maxim Dounin2019-07-12
| | | | | | Previously, redirects scheduled with $r->internal_redirect() were followed even if the code then died. Now these are ignored and nginx will return an error instead.
* Perl: disabled unrelated calls from variable handlers.Maxim Dounin2019-07-12
| | | | | | Variable handlers are not expected to send anything to the client, cannot sleep or read body, and are not expected to modify the request. Added appropriate protection to prevent accidental foot shooting.
* Perl: protection against duplicate $r->sleep() calls.Maxim Dounin2019-07-12
| | | | | | Duplicate $r->sleep() and/or $r->has_request_body() calls result in undefined behaviour (in practice, connection leaks were observed). To prevent this, croak() added in appropriate places.
* Perl: handling of allocation errors.Maxim Dounin2019-07-12
| | | | | | | | | | | Previously, allocation errors in nginx.xs were more or less ignored, potentially resulting in incorrect code execution in specific low-memory conditions. This is changed to use ctx->error bit and croak(), similarly to how output errors are now handled. Note that this is mostly a cosmetic change, as Perl itself exits on memory allocation errors, and hence nginx with Perl is hardly usable in low-memory conditions.
* Perl: propagate errors.Maxim Dounin2019-07-12
| | | | | | | | | | | | | | | | | | When an error happens, the ctx->error bit is now set, and croak() is called to terminate further processing. The ctx->error bit is checked in ngx_http_perl_call_handler() to cancel further processing, and is also checked in various output functions - to make sure these won't be called if croak() was handled by an eval{} in perl code. In particular, this ensures that output chain won't be called after errors, as filters might not expect this to happen. This fixes some segmentation faults under low memory conditions. Also this stops request processing after filter finalization or request body reading errors. For cases where an HTTP error status can be additionally returned (for example, 416 (Requested Range Not Satisfiable) from the range filter), the ctx->status field is also added.
* Perl: reworked perl module to pass ctx instead of request.Maxim Dounin2019-07-12
| | | | | | | | | | | | | | | | | | | | | | This ensures that correct ctx is always available, including after filter finalization. In particular, this fixes a segmentation fault with the following configuration: location / { image_filter test; perl 'sub { my $r = shift; $r->send_http_header(); $r->print("foo\n"); $r->print("bar\n"); }'; } This also seems to be the only way to correctly handle filter finalization in various complex cases, for example, when embedded perl is used both in the original handler and in an error page called after filter finalization.
* Perl: removed unneeded NGX_DONE test.Maxim Dounin2019-07-11
| | | | | | | The NGX_DONE test in ngx_http_perl_handle_request() was introduced in 1702:86bb52e28ce0, which also modified ngx_http_perl_call_handler() to return NGX_DONE with c->destroyed. The latter part was then removed in 3050:f54b02dbb12b, so NGX_DONE test is no longer needed.
* Version bump.Maxim Dounin2019-07-09
|
* Perl: disabled not_modified filter (ticket #1786).Maxim Dounin2019-06-17
| | | | | | | | | | | | | | | | Embedded perl does not set any request fields needed for conditional requests processing. Further, filter finalization in the not_modified filter can cause segmentation faults due to cleared ctx as in ticket #1786. Before 5fb1e57c758a (1.7.3) the not_modified filter was implicitly disabled for perl responses, as r->headers_out.last_modified_time was -1. This change restores this behaviour by using the explicit r->disable_not_modified flag. Note that this patch doesn't try to address perl module robustness against filter finalization and other errors returned from filter chains. It should be eventually reworked to handle errors instead of ignoring them.