Stefan Eissing [Fri, 4 Feb 2022 12:22:26 +0000 (12:22 +0000)]
*) core/mod_ssl/mpm_event: reverting changes to nonblocing SSL handshakes
to stabilize CI tests again. Previous revision of trunk has been copied
to branches/trunk-ssl-handshake-unblocking to make those into a PR where
changes can be discussed and tested separately.
Yann Ylavic [Wed, 2 Feb 2022 10:02:26 +0000 (10:02 +0000)]
core: Follow up to r1897240: Opt-out for AP_HAS_THREAD_LOCAL and/or pcre's usage.
If the compiler's thread_local is not efficient enough on some platforms, or
not desired, have a way to disable its usage in httpd (at compile time).
Handle -DAP_NO_THREAD_LOCAL and/or -DAPREG_NO_THREAD_LOCAL as build opt-out for
thread_local usage in httpd gobally and/or in ap_regex only (respectively).
Stefan Eissing [Tue, 1 Feb 2022 10:40:30 +0000 (10:40 +0000)]
*) test cases
- disabling test_h2_105_02 due to handshake timeouts no longer working
- adjusting some log levels
- ignoring new handshake error AHLOGNOs
Yann Ylavic [Fri, 28 Jan 2022 12:32:25 +0000 (12:32 +0000)]
mod_cgi[d]: Close the connection after handling nph- scripts.
The HTTP output filters chain is bypassed for nph- scripts (whatever this
means), so there is no way to know whether the connection is reusable after
sending the cgi response (opaque header + body).
Set r->connection->keepalive = AP_CONN_CLOSE unconditionally.
For instance test frameork's "nph-foldhdr.pl" script responds with HTTP/1.0
and no Content-Length so closing the connection is the only way to detect the
end of response for the peer.
Yann Ylavic [Thu, 27 Jan 2022 15:06:55 +0000 (15:06 +0000)]
mpm_event: Use APR_POLLEXCL when available to prevent thundering hurd.
If APR_POLLEXCL is available, use it to prevent the thundering
herd issue. The listening sockets are potentially polled by all
the children at the same time, when new connections arrive this
avoids all of them to be woken up while most would get EAGAIN
on accept().
Yann Ylavic [Thu, 27 Jan 2022 12:34:53 +0000 (12:34 +0000)]
core: Follow up to r1897460: Provide ap_thread_main_create().
Replace ap_thread_current_create() by ap_thread_main_create() which is how
it's used by httpd. The former is now a local helper only to implement the
latter.
This allows to consolidate/factorize common code in the main() of httpd and
the unix MPMs.
Yann Ylavic [Tue, 25 Jan 2022 17:34:57 +0000 (17:34 +0000)]
core: Efficient ap_thread_current() when apr_thread_local() is missing.
#define ap_thread_create, ap_thread_current_create and ap_thread_current to
their apr-1.8+ equivalent if available, or implement them using the compiler's
thread_local mechanism if available, or finally provide stubs otherwise.
#define AP_HAS_THREAD_LOCAL to 1 in the two former case or 0 otherwise, while
AP_THREAD_LOCAL is defined to the compiler's keyword iff AP_HAS_THREAD_LOCAL.
Replace all apr_thread_create() calls with ap_thread_create() so that httpd
threads can use ap_thread_current()'s pool data as Thread Local Storage.
Bump MMN minor.
* include/httpd.h():
Define AP_HAS_THREAD_LOCAL, AP_THREAD_LOCAL (eventually), ap_thread_create(),
ap_thread_current_create() and ap_thread_current().
* server/util.c:
Implement ap_thread_create(), ap_thread_current_create() and
ap_thread_current() when APR < 1.8.
* modules/core/mod_watchdog.c, modules/http2/h2_workers.c,
modules/ssl/mod_ssl_ct.c:
Use ap_thread_create() instead of apr_thread_create.
* server/main.c:
Use AP_HAS_THREAD_LOCAL and ap_thread_current_create instead of APR's.
* server/util_pcre.c:
Use AP_HAS_THREAD_LOCAL and ap_thread_current instead of APR's.
* server/mpm/event/event.c, server/mpm/worker/worker.c,
server/mpm/prefork/prefork.c:
Use ap_thread_create() instead of apr_thread_create.
Create an apr_thread_t/ap_thread_current() for the main chaild thread usable
at child_init().
* server/mpm/winnt/child.c:
Use ap_thread_create() instead of CreateThread().
Create an apr_thread_t/ap_thread_current() for the main chaild thread usable
Graham Leggett [Tue, 25 Jan 2022 15:54:22 +0000 (15:54 +0000)]
ab: Respond appropriately to SSL_ERROR_WANT_READ and SSL_ERROR_WANT_WRITE.
Previously the correct event was polled for, but the response to the poll
would call write instead of read, and read instead of write. PR 55952
Yann Ylavic [Mon, 24 Jan 2022 16:08:14 +0000 (16:08 +0000)]
mod_reqtimeout: Set socket timeout for AP_MODE_INIT.
If the SSL handshake is initiated by ssl_hook_process_connection() in
AP_MODE_INIT mode, we still want to adapt the socket timeout according
to the time left for the handshake.
Graham Leggett [Sun, 23 Jan 2022 20:41:05 +0000 (20:41 +0000)]
event: Allow the MPM to explicitly handle CONN_SENSE_WANT_WRITE instead
of support being implicit. Pass the desired sense depending on the state,
no longer default to write.
Graham Leggett [Sat, 22 Jan 2022 22:02:11 +0000 (22:02 +0000)]
mod_ssl: An edge case exists where SSL_read might return SSL_ERROR_WANT_READ
even in blocking BIO cases. Set guards so that an async MPM is not accessed
at this point. There is no need to set non blocking, mod_ssl's BIO already
knows how to do this.
Graham Leggett [Sat, 22 Jan 2022 20:05:21 +0000 (20:05 +0000)]
mod_ssl: Add the missing SSL_ERROR_WANT_WRITE case in the SSL_read. Make
sure the sense is correctly specified in response to SSL_ERROR_WANT_READ
and SSL_ERROR_WANT_WRITE so we don't poll for the wrong case.
Graham Leggett [Fri, 21 Jan 2022 00:09:24 +0000 (00:09 +0000)]
event: Add support for non blocking behaviour in the
CONN_STATE_READ_REQUEST_LINE phase, in addition to the existing
CONN_STATE_WRITE_COMPLETION phase. Update mod_ssl to perform non blocking
TLS handshakes.
Yann Ylavic [Thu, 20 Jan 2022 17:01:40 +0000 (17:01 +0000)]
ap_regex: Follow up to r1897240: runtime fallback to alloc/free.
Even though APR_HAS_THREAD_LOCAL is compiled in, ap_regexec() might still be
called by non a apr_thread_t thread, let's fall back to alloc/free in this
case too.
Stefan Eissing [Thu, 20 Jan 2022 15:36:50 +0000 (15:36 +0000)]
*) test:
- modules/http2: ignore some SSL library error logs when using openssl 3.x
- modules/tls: right now, we seem unable to force curl to use TLSv1.3, adjust
test case expectations accordingly. Use --tls-max to force v1.2 where needed.
Yann Ylavic [Thu, 20 Jan 2022 13:15:36 +0000 (13:15 +0000)]
ap_regex: Follow up to r1897240: Fix issues spotted by Rüdiger (thanks!).
#include "apr_thread_proc.h" is enough/needed by util_pcre.c and main.c.
Fix compilation (vector => ovector) for !HAVE_PCRE2 && APR_HAS_THREAD_LOCAL.
Check pcre2_match_data_create() return value for HAVE_PCRE2 && !APR_HAS_THREAD_LOCAL.
Yann Ylavic [Thu, 20 Jan 2022 12:16:58 +0000 (12:16 +0000)]
ap_regex: PCRE needs buffers sized against the number of captures only.
No more (useless), no less (or PCRE will allocate a new buffer by itself to
satisfy the needs), so we should base our buffer size solely on the number
of captures in the regex (determined at compile time from the pattern).
The nmatch provided by the user is used to fill in pmatch only (up to that),
but "our" buffers are sized exactly as needed to avoid oversized allocations
or PCRE allocating by itself.
Yann Ylavic [Thu, 20 Jan 2022 11:09:34 +0000 (11:09 +0000)]
ap_regex: Use Thread Local Storage (if efficient) to avoid allocations.
PCRE2 wants an opaque context by providing the API to allocate and free it, so
to minimize these calls we maintain one opaque context per thread (in Thread
Local Storage, TLS) grown as needed, and while at it we do the same for PCRE1
ints vectors. Note that this requires a fast TLS mechanism to be worth it,
which is the case of apr_thread_data_get/set() from/to apr_thread_current()
when APR_HAS_THREAD_LOCAL; otherwise we'll do the allocation and freeing for
each ap_regexec().
The small stack vector is used for PCRE1 && !APR_HAS_THREAD_LOCAL only now.
Yann Ylavic [Tue, 18 Jan 2022 20:51:42 +0000 (20:51 +0000)]
mod_dav: Follow up to r1897156: Fix warning.
In file included from mod_dav.c:51:
mod_dav.c: In function ‘uripath_is_canonical’:
mod_dav.c:774:38: error: passing argument 1 of ‘ap_strchr’ discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]
774 | dot_pos = strchr(dot_pos + 1, '.')) {
| ~~~~~~~~^~~
/home/travis/build/apache/httpd/include/httpd.h:2469:34: note: in definition of macro ‘strchr’
2469 | # define strchr(s, c) ap_strchr(s,c)
| ^
/home/travis/build/apache/httpd/include/httpd.h:2457:36: note: expected ‘char *’ but argument is of type ‘const char *’
2457 | AP_DECLARE(char *) ap_strchr(char *s, int c);
| ~~~~~~^
Ruediger Pluem [Tue, 18 Jan 2022 20:13:29 +0000 (20:13 +0000)]
* Allocate the dav_liveprop_elem structure only once in the lifetime of the
resource->pool and reuse it to avoid unnecessary huge memory allocations
during collection walks.
Graham Leggett [Mon, 17 Jan 2022 16:10:51 +0000 (16:10 +0000)]
core: Allow an optional expression to be specified for an effective
path in the DirectoryMatch and LocationMatch directives. This allows
modules like mod_dav to map URLs to URL spaces or to directories on
the filesystem.
Yann Ylavic [Wed, 29 Dec 2021 13:12:44 +0000 (13:12 +0000)]
mpm_event: Fix a possible listener deadlock. PR 65769.
When the listener starts accepting more connections than the number of workers
already started (due to scheduling), the listening sockets gets disabled (per
AH03269) but nothing was re-enabling them before the end of the connections,
despite the creation of more idle/available workers in the meantime.
In the wost case there is no idle worker when the listener accepts the first
connection thus nothing to wake up the listener blocked in poll() with no
socket, hence a deadlock.
Fix this by waking up the listener when a worker becomes idle and this unblocks
connections_above_limit(). This is also worthwhile when all the workers are
started (fully initialized runtime) since the number of idle workers is a
condition for connections_above_limit() anyway so the sooner the listeners are
re-enabled the better (the other condition is the number of connections which
is unblocked appropriately by decrement_connection_count() already).
Also when a child exists with ps->quiescing == 1 and it's caught by
server_main_loop() before perform_idle_server_maintenance(), active_daemons was
not decrement as needed (including accross restarts), leading to an invalid
active_daemons accounting.
* server/mpm/event/event.c(should_enable_listensocks):
New helper that returns whether listenning sockets can be poll()ed again.
* server/mpm/event/event.c(decrement_connection_count, listener_thread):
Use should_enable_listensocks() where previously open-coded.
* server/mpm/event/event.c(worker_thread):
Wake up the listener when is_idle => 1 and should_enable_listensocks().
Have a single point of exit when workers_may_exit to make sure that the
wake always occurs (even when exiting).
* server/mpm/event/event.c(server_main_loop):
Decrement active_daemons not only when !ps->quiescing but also when
ps->quiescing == 1, i.e. all the cases not handled by
perform_idle_server_maintenance() already.