summaryrefslogtreecommitdiffhomepage
path: root/src (follow)
AgeCommit message (Collapse)AuthorFilesLines
2021-12-27Support for sendfile(SF_NOCACHE).Maxim Dounin3-4/+25
The SF_NOCACHE flag, introduced in FreeBSD 11 along with the new non-blocking sendfile() implementation by glebius@, makes it possible to use sendfile() along with the "directio" directive.
2021-12-27SSL: SSL_sendfile(SF_NODISKIO) support.Maxim Dounin1-2/+29
2021-12-27Simplified sendfile(SF_NODISKIO) usage.Maxim Dounin7-169/+30
Starting with FreeBSD 11, there is no need to use AIO operations to preload data into cache for sendfile(SF_NODISKIO) to work. Instead, sendfile() handles non-blocking loading data from disk by itself. It still can, however, return EBUSY if a page is already being loaded (for example, by a different process). If this happens, we now post an event for the next event loop iteration, so sendfile() is retried "after a short period", as manpage recommends. The limit of the number of EBUSY tolerated without any progress is preserved, but now it does not result in an alert, since on an idle system event loop iteration might be very short and EBUSY can happen many times in a row. Instead, SF_NODISKIO is simply disabled for one call once the limit is reached. With this change, sendfile(SF_NODISKIO) is now used automatically as long as sendfile() is enabled, and no longer requires "aio on;".
2021-12-27Removed "aio sendfile", deprecated since 1.7.11.Maxim Dounin1-13/+0
2021-12-25Core: added NGX_REGEX_MULTILINE for 3rd party modules.Maxim Dounin2-2/+11
Notably, NAXSI is known to misuse ngx_regex_compile() with rc.options set to PCRE_CASELESS | PCRE_MULTILINE. With PCRE2 support, and notably binary compatibility changes, it is no longer possible to set PCRE[2]_MULTILINE option without using proper interface. To facilitate correct usage, this change adds the NGX_REGEX_MULTILINE option.
2021-12-25PCRE2 and PCRE binary compatibility.Maxim Dounin2-15/+48
With this change, dynamic modules using nginx regex interface can be used regardless of the variant of the PCRE library nginx was compiled with. If a module is compiled with different PCRE library variant, in case of ngx_regex_exec() errors it will report wrong function name in error messages. This is believed to be tolerable, given that fixing this will require interface changes.
2021-12-25PCRE2 library support.Maxim Dounin2-10/+351
The PCRE2 library is now used by default if found, instead of the original PCRE library. If needed for some reason, this can be disabled with the --without-pcre2 configure option. To make it possible to specify paths to the library and include files via --with-cc-opt / --with-ld-opt, the library is first tested without any additional paths and options. If this fails, the pcre2-config script is used. Similarly to the original PCRE library, it is now possible to build PCRE2 from sources with nginx configure, by using the --with-pcre= option. It automatically detects if PCRE or PCRE2 sources are provided. Note that compiling PCRE2 10.33 and later requires inttypes.h. When compiling on Windows with MSVC, inttypes.h is only available starting with MSVC 2013. In older versions some replacement needs to be provided ("echo '#include <stdint.h>' > pcre2-10.xx/src/inttypes.h" is good enough for MSVC 2010). The interface on nginx side remains unchanged.
2021-12-25Core: ngx_regex.c style cleanup.Maxim Dounin1-17/+17
Notably, ngx_pcre_pool and ngx_pcre_studies are renamed to ngx_regex_pool and ngx_regex_studies, respectively.
2021-12-25Core: fixed ngx_pcre_studies cleanup.Maxim Dounin1-40/+43
If a configuration parsing fails for some reason, ngx_regex_module_init() is not called, and ngx_pcre_studies remained set despite the fact that the pool it was allocated from is already freed. This might result in a segmentation fault during runtime regular expression compilation, such as in SSI, for example, in the single process mode, or if a worker process died and was respawned from a master process in such an inconsistent state. Fix is to clear ngx_pcre_studies from the pool cleanup handler (which is anyway used to free JIT-compiled patterns).
2021-12-21Moved Huffman coding out of HTTP/2.Ruslan Ermilov7-43/+45
ngx_http_v2_huff_decode.c and ngx_http_v2_huff_encode.c are renamed to ngx_http_huff_decode.c and ngx_http_huff_encode.c.
2021-11-25HTTP/2: fixed sendfile() aio handling.Maxim Dounin3-10/+65
With sendfile() in threads ("aio threads; sendfile on;"), client connection can block on writing, waiting for sendfile() to complete. In HTTP/2 this might result in the request hang, since an attempt to continue processing in thread event handler will call request's write event handler, which is usually stopped by ngx_http_v2_send_chain(): it does nothing if there are no additional data and stream->queued is set. Further, HTTP/2 resets stream's c->write->ready to 0 if writing blocks, so just fixing ngx_http_v2_send_chain() is not enough. Can be reproduced with test suite on Linux with: TEST_NGINX_GLOBALS_HTTP="aio threads; sendfile on;" prove h2*.t The following tests currently fail: h2_keepalive.t, h2_priority.t, h2_proxy_max_temp_file_size.t, h2.t, h2_trailers.t. Similarly, sendfile() with AIO preloading on FreeBSD can block as well, with similar results. This is, however, harder to reproduce, especially on modern FreeBSD systems, since sendfile() usually does not return EBUSY. Fix is to modify ngx_http_v2_send_chain() so it actually tries to send data to the main connection when called, and to make sure that c->write->ready is set by the relevant event handlers.
2021-11-25HTTP/2: fixed "task already active" with sendfile in threads.Maxim Dounin4-24/+58
With sendfile in threads, "task already active" alerts might appear in logs if a write event happens on the main HTTP/2 connection, triggering a sendfile in threads while another thread operation is already running. Observed with "aio threads; aio_write on; sendfile on;" and with thread event handlers modified to post a write event to the main HTTP/2 connection (though can happen without any modifications). Similarly, sendfile() with AIO preloading on FreeBSD can trigger duplicate aio operation, resulting in "second aio post" alerts. This is, however, harder to reproduce, especially on modern FreeBSD systems, since sendfile() usually does not return EBUSY. Fix is to avoid starting a sendfile operation if other thread operation is active by checking r->aio in the thread handler (and, similarly, in aio preload handler). The added check also makes duplicate calls protection redundant, so it is removed.
2021-11-01SSL: $ssl_curve (ticket #2135).Sergey Kandaurov4-0/+44
The variable contains a negotiated curve used for the handshake key exchange process. Known curves are listed by their names, unknown ones are shown in hex. Note that for resumed sessions in TLSv1.2 and older protocols, $ssl_curve contains the curve used during the initial handshake, while in TLSv1.3 it contains the curve used during the session resumption (see the SSL_get_negotiated_group manual page for details). The variable is only meaningful when using OpenSSL 3.0 and above. With older versions the variable is empty.
2021-11-23Version bump.Sergey Kandaurov1-2/+2
2021-10-30Changed ngx_chain_update_chains() to test tag first (ticket #2248).Maxim Dounin1-4/+4
Without this change, aio used with HTTP/2 can result in connection hang, as observed with "aio threads; aio_write on;" and proxying (ticket #2248). The problem is that HTTP/2 updates buffers outside of the output filters (notably, marks them as sent), and then posts a write event to call output filters. If a filter does not call the next one for some reason (for example, because of an AIO operation in progress), this might result in a state when the owner of a buffer already called ngx_chain_update_chains() and can reuse the buffer, while the same buffer is still sitting in the busy chain of some other filter. In the particular case a buffer was sitting in output chain's ctx->busy, and was reused by event pipe. Output chain's ctx->busy was permanently blocked by it, and this resulted in connection hang. Fix is to change ngx_chain_update_chains() to skip buffers from other modules unconditionally, without trying to wait for these buffers to become empty.
2021-10-29Changed default value of sendfile_max_chunk to 2m.Maxim Dounin1-1/+1
The "sendfile_max_chunk" directive is important to prevent worker monopolization by fast connections. The 2m value implies maximum 200ms delay with 100 Mbps links, 20ms delay with 1 Gbps links, and 2ms on 10 Gbps links. It also seems to be a good value for disks.
2021-10-29Upstream: sendfile_max_chunk support.Maxim Dounin2-3/+10
Previously, connections to upstream servers used sendfile() if it was enabled, but never honored sendfile_max_chunk. This might result in worker monopolization for a long time if large request bodies are allowed.
2021-10-29Fixed sendfile() limit handling on Linux.Maxim Dounin1-1/+3
On Linux starting with 2.6.16, sendfile() silently limits all operations to MAX_RW_COUNT, defined as (INT_MAX & PAGE_MASK). This incorrectly triggered the interrupt check, and resulted in 0-sized writev() on the next loop iteration. Fix is to make sure the limit is always checked, so we will return from the loop if the limit is already reached even if number of bytes sent is not exactly equal to the number of bytes we've tried to send.
2021-10-29Simplified sendfile_max_chunk handling.Maxim Dounin1-5/+1
Previously, it was checked that sendfile_max_chunk was enabled and almost whole sendfile_max_chunk was sent (see e67ef50c3176), to avoid delaying connections where sendfile_max_chunk wasn't reached (for example, when sending responses smaller than sendfile_max_chunk). Now we instead check if there are unsent data, and the connection is still ready for writing. Additionally we also check c->write->delayed to ignore connections already delayed by limit_rate. This approach is believed to be more robust, and correctly handles not only sendfile_max_chunk, but also internal limits of c->send_chain(), such as sendfile() maximum supported length (ticket #1870).
2021-10-29Switched to using posted next events after sendfile_max_chunk.Maxim Dounin1-2/+1
Previously, 1 millisecond delay was used instead. In certain edge cases this might result in noticeable performance degradation though, notably on Linux with typical CONFIG_HZ=250 (so 1ms delay becomes 4ms), sendfile_max_chunk 2m, and link speed above 2.5 Gbps. Using posted next events removes the artificial delay and makes processing fast in all cases.
2021-10-28Mp4: mp4_start_key_frame directive.Roman Arutyunyan1-27/+194
The directive enables including all frames from start time to the most recent key frame in the result. Those frames are removed from presentation timeline using mp4 edit lists. Edit lists are currently supported by popular players and browsers such as Chrome, Safari, QuickTime and ffmpeg. Among those not supporting them properly is Firefox[1]. Based on a patch by Tracey Jaquith, Internet Archive. [1] https://bugzilla.mozilla.org/show_bug.cgi?id=1735300
2021-10-28Mp4: added ngx_http_mp4_update_mdhd_atom() function.Roman Arutyunyan1-8/+32
The function updates the duration field of mdhd atom. Previously it was updated in ngx_http_mp4_read_mdhd_atom(). The change makes it possible to alter track duration as a result of processing track frames.
2021-08-19Core: removed unnecessary restriction in hash initialization.Alexey Radkov1-0/+4
Hash initialization ignores elements with key.data set to NULL. Nevertheless, the initial hash bucket size check didn't skip them, resulting in unnecessary restrictions on, for example, variables with long names and with the NGX_HTTP_VARIABLE_NOHASH flag. Fix is to update the initial hash bucket size check to skip elements with key.data set to NULL, similarly to how it is done in other parts of the code.
2021-10-21SSL: SSL_sendfile() support with kernel TLS.Maxim Dounin4-9/+211
Requires OpenSSL 3.0 compiled with "enable-ktls" option. Further, KTLS needs to be enabled in kernel, and in OpenSSL, either via OpenSSL configuration file or with "ssl_conf_command Options KTLS;" in nginx configuration. On FreeBSD, kernel TLS is available starting with FreeBSD 13.0, and can be enabled with "sysctl kern.ipc.tls.enable=1" and "kldload ktls_ocf" to load a software backend, see man ktls(4) for details. On Linux, kernel TLS is available starting with kernel 4.13 (at least 5.2 is recommended), and needs kernel compiled with CONFIG_TLS=y (with CONFIG_TLS=m, which is used at least on Ubuntu 21.04 by default, the tls module needs to be loaded with "modprobe tls").
2021-10-21Style: added missing "static" specifiers.Maxim Dounin2-4/+5
Mostly found by gcc -Wtraditional, per "non-static declaration of ... follows static declaration [-Wtraditional]" warnings.
2021-10-21Removed CLOCK_MONOTONIC_COARSE support.Maxim Dounin1-4/+0
While clock_gettime(CLOCK_MONOTONIC_COARSE) is faster than clock_gettime(CLOCK_MONOTONIC), the latter is fast enough on Linux for practical usage, and the difference is negligible compared to other costs at each event loop iteration. On the other hand, CLOCK_MONOTONIC_COARSE causes various issues with typical CONFIG_HZ=250, notably very inaccurate limit_rate handling in some edge cases (ticket #1678) and negative difference between $request_time and $upstream_response_time (ticket #1965).
2021-10-20Mail: connections with wrong ALPN protocols are now rejected.Vladimir Homutov5-0/+62
This is a recommended behavior by RFC 7301 and is useful for mitigation of protocol confusion attacks [1]. For POP3 and IMAP protocols IANA-assigned ALPN IDs are used [2]. For the SMTP protocol "smtp" is used. [1] https://alpaca-attack.com/ [2] https://www.iana.org/assignments/tls-extensiontype-values/
2021-10-20HTTP: connections with wrong ALPN protocols are now rejected.Vladimir Homutov1-7/+6
This is a recommended behavior by RFC 7301 and is useful for mitigation of protocol confusion attacks [1]. To avoid possible negative effects, list of supported protocols was extended to include all possible HTTP protocol ALPN IDs registered by IANA [2], i.e. "http/1.0" and "http/0.9". [1] https://alpaca-attack.com/ [2] https://www.iana.org/assignments/tls-extensiontype-values/
2021-10-19Stream: the "ssl_alpn" directive.Vladimir Homutov3-0/+121
The directive sets the server list of supported application protocols and requires one of this protocols to be negotiated if client is using ALPN.
2021-10-14SSL: added $ssl_alpn_protocol variable.Vladimir Homutov4-0/+38
The variable contains protocol selected by ALPN during handshake and is empty otherwise.
2021-10-15HTTP/2: removed support for NPN.Vladimir Homutov4-72/+9
NPN was replaced with ALPN, published as RFC 7301 in July 2014. It used to negotiate SPDY (and, in transition, HTTP/2). NPN supported appeared in OpenSSL 1.0.1. It does not work with TLSv1.3 [1]. ALPN is supported since OpenSSL 1.0.2. The NPN support was dropped in Firefox 53 [2] and Chrome 51 [3]. [1] https://github.com/openssl/openssl/issues/3665. [2] https://bugzilla.mozilla.org/show_bug.cgi?id=1248198 [3] https://www.chromestatus.com/feature/5767920709795840
2021-10-18Upstream: fixed logging level of upstream invalid header errors.Maxim Dounin4-4/+4
In b87b7092cedb (nginx 1.21.1), logging level of "upstream sent invalid header" errors was accidentally changed to "info". This change restores the "error" level, which is a proper logging level for upstream-side errors.
2021-10-12Synced ngx_http_subrequest() argument names (ticket #2255).Maxim Dounin1-2/+2
2021-10-07Proxy: disabled keepalive on extra data in non-buffered mode.Awdhesh Mathpal1-0/+1
The u->keepalive flag is initialized early if the response has no body (or an empty body), and needs to be reset if there are any extra data, similarly to how it is done in ngx_http_proxy_copy_filter(). Missed in 83c4622053b0.
2021-10-06Fixed $content_length cacheability with chunked (ticket #2252).Maxim Dounin1-0/+4
2021-09-22Stream: added half-close support.Vladimir Homutov2-0/+37
The "proxy_half_close" directive enables handling of TCP half close. If enabled, connection to proxied server is kept open until both read ends get EOF. Write end shutdown is properly transmitted via proxy.
2021-09-10Request body: do not create temp file if there's nothing to write.Roman Arutyunyan1-1/+1
Do this only when the entire request body is empty and r->request_body_in_file_only is set. The issue manifested itself with missing warning "a client request body is buffered to a temporary file" when the entire rb->buf is full and all buffers are delayed by a filter.
2021-09-14Version bump.Roman Arutyunyan1-2/+2
2021-09-06HTTP/2: optimized processing of small DATA frames.Maxim Dounin1-54/+12
The request body filter chain is no longer called after processing a DATA frame. Instead, we now post a read event to do this. This ensures that multiple small DATA frames read during the same event loop iteration are coalesced together, resulting in much faster processing. Since rb->buf can now contain unprocessed data, window update is no longer sent in ngx_http_v2_state_read_data() in case of flow control being used due to filter buffering. Instead, window will be updated by ngx_http_v2_read_client_request_body_handler() in the posted read event.
2021-09-06HTTP/2: fixed timers left after request body reading.Maxim Dounin1-12/+12
Following rb->filter_need_buffering changes, request body reading is only finished after the filter chain is called and rb->last_saved is set. As such, with r->request_body_no_buffering, timer on fc->read is no longer removed when the last part of the body is received, potentially resulting in incorrect behaviour. The fix is to call ngx_http_v2_process_request_body() from the ngx_http_v2_read_unbuffered_request_body() function instead of directly calling ngx_http_v2_filter_request_body(), so the timer is properly removed.
2021-09-06HTTP/2: fixed window updates when buffering in filters.Maxim Dounin1-2/+18
In the body read handler, the window was incorrectly calculated based on the full buffer size instead of the amount of free space in the buffer. If the request body is buffered by a filter, and the buffer is not empty after the read event is generated by the filter to resume request body processing, this could result in "http2 negative window update" alerts. Further, in the body ready handler and in ngx_http_v2_state_read_data() the buffer wasn't cleared when the data were already written to disk, so the client might stuck without window updates.
2021-09-02Fixed debug logging.Roman Arutyunyan1-2/+2
2021-09-03Version bump.Roman Arutyunyan1-2/+2
2021-08-31HTTP/2: avoid memcpy() with NULL source and zero length.Maxim Dounin1-1/+3
Prodded by Clang Static Analyzer.
2021-08-30Give GCC atomics precedence over deprecated Darwin atomic(3).Sergey Kandaurov1-33/+33
This allows to build nginx on macOS with -Wdeprecated-declarations.
2021-08-29Request body: reading body buffering in filters.Maxim Dounin3-26/+182
If a filter wants to buffer the request body during reading (for example, to check an external scanner), it can now do so. To make it possible, the code now checks rb->last_saved (introduced in the previous change) along with rb->rest == 0. Since in HTTP/2 this requires flow control to avoid overflowing the request body buffer, so filters which need buffering have to set the rb->filter_need_buffering flag on the first filter call. (Note that each filter is expected to call the next filter, so all filters will be able set the flag if needed.)
2021-08-29Request body: introduced rb->last_saved flag.Maxim Dounin2-15/+54
It indicates that the last buffer was received by the save filter, and can be used to check this at higher levels. To be used in the following changes.
2021-08-29Request body: added alert to catch duplicate body saving.Maxim Dounin1-0/+6
If due to an error ngx_http_request_body_save_filter() is called more than once with rb->rest == 0, this used to result in a segmentation fault. Added an alert to catch such errors, just in case.
2021-08-29Request body: missing comments about initialization.Maxim Dounin1-0/+2
2021-08-29HTTP/2: improved handling of preread unbuffered requests.Maxim Dounin1-1/+1
Previously, fully preread unbuffered requests larger than client body buffer size were saved to disk, despite the fact that "unbuffered" is expected to imply no disk buffering.