Commit Graph

15662 Commits

Author SHA1 Message Date
Willy Tarreau
0d1dd0e894 BUILD: cfgparse-ssl: add missing errors.h
ha_warning(), ha_alert() and friends are in errors.h and it used
to be inherited via other files.
2021-10-07 01:36:51 +02:00
Willy Tarreau
b7fc4c4e9f BUILD: tree-wide: add missing http_ana.h from many places
At least 6 files make use of s->txn without including http_ana which
defines it. They used to get it from other includes.
2021-10-07 01:36:51 +02:00
Willy Tarreau
fa17d9f92c BUILD: connection: connection.h needs list.h and server.h
It manipulates lists and calls srv_add_conn().
2021-10-07 01:36:51 +02:00
Willy Tarreau
63617dbec6 BUILD: idleconns: include missing ebmbtree.h at several places
backend.c, all muxes, backend.c started manipulating ebmb_nodes with
the introduction of idle conns but the types were inherited through
other includes. Let's add ebmbtree.h there.
2021-10-07 01:36:51 +02:00
Willy Tarreau
337f23a112 BUILD: compiler: add the container_of() and container_of_safe() macros
These ones are called from a few places in the code and are only provided
by ebtree.h, which is not normal given that some callers do not even use
ebtree.
2021-10-07 01:36:51 +02:00
Willy Tarreau
74f2456c42 BUILD: ssl_ckch: include ebpttree.h in ssl_ckch.c
It's used but is only found through other includes.
2021-10-07 01:36:51 +02:00
Willy Tarreau
8db34cc974 BUILD: peers: need to include eb{32/mb/pt}tree.h
peers.c uses them all and used to only find them through other includes.
2021-10-07 01:36:51 +02:00
Willy Tarreau
b555eb1176 BUILD: vars: need to include xxhash
It's needed for XXH3(), and it used to get it through other includes.
2021-10-07 01:36:51 +02:00
Willy Tarreau
0ce6dc0107 BUILD: http_rules: requires http_ana-t.h for REDIRECT_*
It used to inherit it through other includes.
2021-10-07 01:36:51 +02:00
Willy Tarreau
ab46ac8343 BUILD: http_ana: need to include proxy-t to get redirect_rule
The struct was only defined inside function arguments there and
inherited from other files.
2021-10-07 01:36:51 +02:00
Willy Tarreau
286631a1a0 BUILD: sample: include openssl-compat
It's needed for EVP_*.
2021-10-07 01:36:51 +02:00
Willy Tarreau
1df20428f1 BUILD: httpclient: include missing ssl_sock-t
It's needed for SSL_SOCK_VERIFY_NONE.
2021-10-07 01:36:51 +02:00
Willy Tarreau
d2d968a9bf BUILD: resolvers: define missing types in resolvers.h
proxy, server, stream_interface and list were used but not defined. Let's
define them as well as act_rule and drop action-t.h.
2021-10-07 01:36:51 +02:00
Willy Tarreau
59be17a29a BUILD: stats: define several missing structures in stats.h
channel, stream_interface, appctx, buffer, proxy and htx ones are used
in function arguments and most of them are not defined but were inherited
from intermediary inclues. Let's define them here and drop the unneeded
includes.
2021-10-07 01:36:51 +02:00
Willy Tarreau
27539409fd BUILD: hlua: needs to include stream-t.h
It uses the SF_ERR_* error codes and currently gets them via
intermediary includes.
2021-10-07 01:36:51 +02:00
Willy Tarreau
397ad4135a BUILD: extcheck: needs to include stream-t.h
It uses the SF_ERR_* error codes and currently gets them via
intermediary includes.
2021-10-07 01:36:51 +02:00
Willy Tarreau
b70596df0a BUILD: action: add the relevant structures for function arguments
Some structures are inherited via intermediary includes (e.g. dns_counters
comes from a long path). Let's define the missing ones and includes vars-t
that is needed in the structure.
2021-10-07 01:36:51 +02:00
Willy Tarreau
2476ff102f BUG/MEDIUM: sample: properly verify that variables cast to sample
The various variable-to-sample converters allow to turn a variable to
a sample of type string, sint or binary, but both the string one used
by strcmp() and the binary one used by secure_memcmp() are missing a
pointer check on the ability to the cast, making them crash if a
variable of type addr is used with strcmp(), or if an addr or bool is
used with secure_memcmp().

Let's rely on the new sample_conv_var2smp() function to run the proper
checks.

This will need to be backported to all supported version. It relies on
previous commits:

  CLEANUP: server: always include the storage for SSL settings
  CLEANUP: sample: rename sample_conv_var2smp() to *_sint
  CLEANUP: sample: uninline sample_conv_var2smp_str()
  MINOR: sample: provide a generic var-to-sample conversion function

For backports it's probably easier to check the sample_casts[] pointer
before calling it in sample_conv_strcmp() and sample_conv_secure_memcmp().
2021-10-07 01:36:51 +02:00
Willy Tarreau
168e8de1d0 MINOR: sample: provide a generic var-to-sample conversion function
We're using variable-to-sample conversion at least 4 times in the code,
two of which are bogus. Let's introduce a generic conversion function
that performs the required checks.
2021-10-07 01:36:51 +02:00
Willy Tarreau
4034e2cb58 CLEANUP: sample: uninline sample_conv_var2smp_str()
There's no reason to limit this one to this file, it could be used in
other contexts.
2021-10-07 01:36:51 +02:00
Willy Tarreau
d9be599529 CLEANUP: sample: rename sample_conv_var2smp() to *_sint
This one only handles integers, contrary to its sibling with the suffix
_str that only handles strings. Let's rename it and uninline it since it
may well be used from outside.
2021-10-07 01:36:51 +02:00
Willy Tarreau
80527bcb9d CLEANUP: server: always include the storage for SSL settings
The SSL stuff in struct server takes less than 3% of it and requires
lots of annoying ifdefs in the code just to take care of the cases
where the field is absent. Let's get rid of this and stop including
openssl-compat from server.c to detect NPN and ALPN capabilities.

This reduces the total LoC by another 0.4%.
2021-10-07 01:36:51 +02:00
William Lallemand
746e6f3f8e MINOR: httpclient/lua: supports headers via named arguments
Migrate the httpclient:get() method to named arguments so we can
specify optional arguments.

This allows to pass headers as an optional argument as an array.

The () in the method call must be replaced by {}:

	local res = httpclient:get{url="http://127.0.0.1:9000/?s=99",
	            headers= {["X-foo"]  = { "salt" }, ["X-bar"] = {"pepper" }}}
2021-10-06 15:21:02 +02:00
William Lallemand
ef574b2101 BUG/MINOR: httpclient/lua: does not process headers when failed
Do not try to process the header list when it is NULL. This case can
arrive when the request failed and did not return a response.
2021-10-06 15:15:03 +02:00
William Lallemand
2a879001b5 MINOR: httpclient: destroy checks if a client was started but not stopped
During httpclient_destroy, add a condition in the BUG_ON which checks
that the client was started before it has ended. A httpclient structure
could have been created without being started.
2021-10-06 15:15:03 +02:00
William Lallemand
4d60184887 BUG/MEDIUM: httpclient/lua: crash because of b_xfer and get_trash_chunk()
When using the lua httpclient, haproxy could crash because a b_xfer is
done in httpclient_xfer, which will do a zero-copy swap of the data in
the buffers. The ptr will then be free() by the pool.

However this can't work with a trash buffer, because the area was not
allocated from the pool buffer, so the pool is not suppose to free it
because it does not know this ptr, using -DDEBUG_MEMORY_POOLS will
result with a crash during the free.

Fix the problem by using b_force_xfer() instead of b_xfer which copy
the data instead. The problem still exist with the trash however, and
the trash API must be reworked.
2021-10-06 15:15:03 +02:00
William Lallemand
f77f1de802 MINOR: httpclient/lua: implement garbage collection
Implement the garbage collector of the lua httpclient.

This patch declares the __gc method of the httpclient object which only
does a httpclient_stop_and_destroy().
2021-10-06 15:15:03 +02:00
William Lallemand
b8b1370307 MINOR: httpclient: test if started during stop_and_destroy()
If the httpclient was never started, it is safe to destroy completely
the httpclient.
2021-10-06 15:15:03 +02:00
William Lallemand
ecb83e13eb MINOR: httpclient: stop_and_destroy() ask the applet to autokill
httpclient_stop_and_destroy() tries to destroy the httpclient structure
if the client was stopped.

In the case the client wasn't stopped, it ask the client to stop itself
and to destroy the httpclient structure itself during the release of the
applet.
2021-10-06 15:15:03 +02:00
William Lallemand
739f90a6ef MINOR: httpclient: set HTTPCLIENT_F_ENDED only in release
Only set the HTTPCLIENT_F_ENDED flag in httpclient_applet_release()
function so we are sure that the appctx is not used anymore once the
flag is set.
2021-10-06 15:15:03 +02:00
William Lallemand
03f5a1c77d MINOR: httpclient: destroy() must free the headers and the ists
httpclient_destroy() must free all the ist in the httpclient structure,
the URL in the request, the vsn and reason in the response.

It also must free the list of headers of the response.
2021-10-06 15:15:03 +02:00
Christopher Faulet
d34758849e BUG/MEDIUM: http-ana: Clear request analyzers when applying redirect rule
A bug was introduced by the commit 2d5650082 ("BUG/MEDIUM: http-ana: Reset
channels analysers when returning an error").

The request analyzers must be cleared when a redirect rule is applied. It is
not a problem if the redirect rule is inside an http-request ruleset because
the analyzer takes care to clear it. However, when it comes from a redirect
ruleset (via the "redirect ..."  directive), because of the above commit,
the request analyzers are no longer cleared. It means some HTTP request
analyzers may be called while the request channel was already flushed. It is
totally unexpected and may lead to crash.

Thanks to Yves Lafon for reporting the problem.

This patch must be backported everywhere the above commit was backported.
2021-10-04 14:32:02 +02:00
Christopher Faulet
d28b2b2352 BUG/MEDIUM: filters: Fix a typo when a filter is attached blocking the release
When a filter is attached to a stream, the wrong FLT_END analyzer is added
on the request channel. AN_REQ_FLT_END must be added instead of
AN_RES_FLT_END. Because of this bug, the stream may hang on the filter
release stage.

It seems to be ok for HTTP filters (cache & compression) in HTTP mode. But
when enabled on a TCP proxy, the stream is blocked until the client or the
server timeout expire because data forwarding is blocked. The stream is then
prematurely aborted.

This bug was introduced by commit 26eb5ea35 ("BUG/MINOR: filters: Always set
FLT_END analyser when CF_FLT_ANALYZE flag is set"). The patch must be
backported in all stable versions.
2021-10-04 08:28:44 +02:00
Willy Tarreau
1cdb531ec8 REORG: sched: move the stolen CPU time detection to sched_entering_poll()
That's where that code initially was but it had been moved to
activity_count_runtime() for pure reasons of dependency loops. These
ones are no longer true so we can move that code back to the scheduler
and keep it where the information are updated and checked.
2021-10-01 18:37:51 +02:00
Willy Tarreau
6dfab112e1 REORG: sched: move idle time calculation from time.h to task.h
time.h is a horrible place to put activity calculation, it's a
historical mistake because the functions were there. We already have
most of the parts in sched.{c,h} and these ones make an exception in
the middle, forcing time.h to include some thread stuff and to access
the before/after_poll and idle_pct values.

Let's move these 3 functions to task.h with the other ones. They were
prefixed with "sched_" instead of the historical "tv_" which already
made no sense anymore.
2021-10-01 18:37:51 +02:00
Willy Tarreau
6136989a22 MINOR: time: uninline report_idle() and move it to task.c
I don't know why I inlined this one, this makes no sense given that it's
only used for stats, and it starts a circular dependency on tinfo.h which
can be problematic in the future. In addition, all the stuff related to
idle time calculation should be with the rest of the scheduler, which
currently is in task.{c,h}, so let's move it there.
2021-10-01 18:37:50 +02:00
Willy Tarreau
beeabf5314 MINOR: task: provide 3 task_new_* wrappers to simplify the API
We'll need to improve the API to pass other arguments in the future, so
let's start to adapt better to the current use cases. task_new() is used:
  - 18 times as task_new(tid_bit)
  - 18 times as task_new(MAX_THREADS_MASK)
  - 2 times with a single bit (in a loop)
  - 1 in the debug code that uses a mask

This patch provides 3 new functions to achieve this:
  - task_new_here()     to create a task on the calling thread
  - task_new_anywhere() to create a task to be run anywhere
  - task_new_on()       to create a task to run on a specific thread

The change is trivial and will allow us to later concentrate the
required adaptations to these 3 functions only. It's still possible
to call task_new() if needed but a comment was added to encourage the
use of the new ones instead. The debug code was not changed and still
uses it.
2021-10-01 18:36:29 +02:00
Willy Tarreau
6a2a912cb8 CLEANUP: tasks: remove the long-unused work_lists
Work lists were a mechanism introduced in 1.8 to asynchronously delegate
some work to be performed on another thread via a dedicated task.
The only user was the listeners, to deal with the queue. Nowadays
the tasklets have made this much more convenient, and have replaced
work_lists in the listeners. It seems there will be no valid use case
of work lists anymore, so better get rid of them entirely and keep the
scheduler code cleaner.
2021-10-01 18:30:14 +02:00
William Lallemand
f542941f71 REGTESTS: ssl: wrong feature cmd in show_ssl_ocspresponse.vtc
The "feature cmd" needs to be separated in 2 parts to check the openssl
command.
2021-09-30 18:45:18 +02:00
William Lallemand
2655f2ba33 REGTESTS: ssl: show_ssl_ocspresponse w/ freebsd won't use base64
The reg-test show_ssl_ocspresponse.vtc won't use the "base64" binary on
freebsd, replace it by a "openssl base64" which does the same thing.
2021-09-30 17:58:58 +02:00
Willy Tarreau
7a9699916a MINOR: tasks: catch TICK_ETERNITY with BUG_ON() in __task_queue()
__task_queue() must absolutely not be called with TICK_ETERNITY or it
will place a never-expiring node upfront in the timers queue, preventing
any timer from expiring until the process is restarted. Code was found
to cause this using "task_schedule(task, now_ms)" which does this one
millisecond every 49.7 days, so let's add a condition against this. It
must never trigger since any process susceptible to trigger it would
already accumulate tasks until it dies.

An extra test was added in wake_expired_tasks() to detect tasks whose
timeout would have been changed after being queued.

An improvement over this could be in the future to use a non-scalar
type (union/struct) for expiration dates so as to avoid the risk of
using them directly like this. But now_ms is already such a valid
time and this specific construct would still not be caught.

This could even be backported to stable versions to help detect other
occurrences if any.
2021-09-30 17:09:39 +02:00
Christopher Faulet
cb59e0bc3c BUG/MINOR: tcp-rules: Stop content rules eval on read error and end-of-input
For now, tcp-request and tcp-response content rules evaluation is
interrupted before the inspect-delay when the channel's buffer is full, the
RX path is blocked or when a shutdown for reads was received. To sum up, the
evaluation is interrupted when no more input data are expected. However, it
is not exhaustive. It also happens when end of input is reached (CF_EOI flag
set) or when a read error occurred (CF_READ_ERROR flag set).

Note that, AFAIK, it is only a problem on HAProy 2.3 and prior when a H1 to
H2 upgrade is performed. On newer versions, it works as expected because the
stream is not created at this stage.

This patch must be backported as far as 2.0.
2021-09-30 16:37:29 +02:00
Christopher Faulet
eaba25dd97 BUG/MINOR: tcpcheck: Don't use arg list for default proxies during parsing
During tcp/http check rules parsing, when a sample fetch or a log-format
string is parsed, the proxy's argument list used to track unresolved
argument is no longer passed for default proxies. It means it is no longer
possible to rely on sample fetches depending on the execution context (for
instance 'nbsrv').

It is important to avoid HAProxy crashes because these arguments are
resolved during the configuration validity check. But, default proxies are
not evaluated during this stage. Thus, these arguments remain unresolved.

It will probably be possible to relax this rule. But to ease backports, it
is forbidden for now.

This patch must be backported as far as 2.2. It depends on the commit
"MINOR: arg: Be able to forbid unresolved args when building an argument
list".  It must be adapted for the 2.3 because PR_CAP_DEF capability was
introduced in the 2.4. A solution may be to test The proxy's id agains NULL.
2021-09-30 16:37:05 +02:00
Christopher Faulet
35926a16ac MINOR: arg: Be able to forbid unresolved args when building an argument list
In make_arg_list() function, unresolved dependencies are pushed in an
argument list to be resolved later, during the configuration validity
check. It is now possible to forbid such unresolved dependencies by omitting
<al> parameter (setting it to NULL). It is usefull when the parsing context
is not the same than the running context or when the parsing context is lost
after the startup stage. For instance, an argument may be defined in
defaults section during parsing and executed in a frontend/backend section.
2021-09-30 16:37:05 +02:00
Willy Tarreau
e3957f83e0 BUG/MAJOR: lua: use task_wakeup() to properly run a task once
The Lua tasks registered vi core.register_task() use a dangerous
task_schedule(task, now_ms) to start them, that will most of the
time work by accident, except when the time wraps every 49.7 days,
if now_ms is 0, because it's not valid to queue a task with an
expiration date set to TICK_ETERNITY, as it will fail all wakeup
checks and prevent all subsequent timers from being seen as expired.
The only solution in this case is to restart the process.

Fortunately for the vast majority of users it is extremely unlikely
to ever be met (only one millisecond every 49.7 days is at risk), but
this can be systematic for a process dealing with 1000 req/s, hence
the major tag.

The bug was introduced in 1.6-dev with commit 24f335340 ("MEDIUM: lua:
add coroutine as tasks."), so the fix must be backported to all stable
branches.
2021-09-30 16:26:51 +02:00
Willy Tarreau
12c02701d3 BUG/MEDIUM: lua: fix wakeup condition from sleep()
A time comparison was wrong in hlua_sleep_yield(), making the sleep()
code do nothing for periods of 24 days every 49 days. An arithmetic
comparison was performed on now_ms instead of using tick_is_expired().

This bug was added in 1.6-dev by commit 5b8608f1e ("MINOR: lua: core:
add sleep functions") so the fix should be backported to all stable
versions.
2021-09-30 16:26:51 +02:00
William Lallemand
8d264387c3 REGTESTS: ssl: enable ssl_crt-list_filters.vtc again
ssl_crt-list_filters.vtc was deactivated because they were not compatible with
previous version of OpenSSL and it was not possible to
filter by versions.

Activate it again with a openssl_version_atleast(1.1.1)
check.
2021-09-30 15:39:59 +02:00
William Lallemand
2f52fdb52e REGTESTS: ssl: enable show_ssl_ocspresponse.vtc again
Since we disabled boringssl from the CI we can enable this test again.
2021-09-30 15:28:30 +02:00
Remi Tricot-Le Breton
9543d5ad5b MINOR: ssl: Store the last SSL error code in case of read or write failure
In case of error while calling a SSL_read or SSL_write, the
SSL_get_error function is called in order to know more about the error
that happened. If the error code is SSL_ERROR_SSL or SSL_ERROR_SYSCALL,
the error queue might contain more information on the error. This error
code was not used until now. But we now need to store it in order for
backend error fetches to catch all handshake related errors.

The change was required because the previous backend fetch would not
have raised anything if the client's certificate was rejected by the
server (and the connection interrupted). This happens because starting
from TLS1.3, the 'Finished' state on the client is reached before its
certificate is sent to the server (see the "Protocol Overview" part of
RFC 8446). The only place where we can detect that the server rejected the
certificate is after the first SSL_read call after the SSL_do_handshake
function.

This patch then adds an extra ERR_peek_error after the SSL_read and
SSL_write calls in ssl_sock_to_buf and ssl_sock_from_buf. This means
that it could set an error code in the SSL context a long time after the
handshake is over, hence the change in the error fetches.
2021-09-30 11:04:35 +02:00
Remi Tricot-Le Breton
1fe0fad88b MINOR: ssl: Rename ssl_bc_hsk_err to ssl_bc_err
The ssl_bc_hsk_err sample fetch will need to raise more errors than only
handshake related ones hence its renaming to a more generic ssl_bc_err.
This patch is required because some handshake failures that should have
been caught by this fetch (verify error on the server side for instance)
were missed. This is caused by a change in TLS1.3 in which the
'Finished' state on the client is reached before its certificate is sent
(and verified) on the server side (see the "Protocol Overview" part of
RFC 8446).
This means that the SSL_do_handshake call is finished long before the
server can verify and potentially reject the client certificate.

The ssl_bc_hsk_err will then need to be expanded to catch other types of
errors.

This change is also applied to the frontend fetches (ssl_fc_hsk_err
becomes ssl_fc_err) and to their string counterparts.
2021-09-30 11:04:35 +02:00