]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
3 years agoMINOR: log: Remove log-error-via-logformat option
Remi Tricot-Le Breton [Tue, 31 Aug 2021 10:08:51 +0000 (12:08 +0200)] 
MINOR: log: Remove log-error-via-logformat option

This option will be replaced by a "error-log-format" that enables to use
a dedicated log-format for connection error messages instead of the
regular log-format (in which most of the fields would be invalid in such
a case).
The "log-error-via-logformat" mechanism will then be replaced by a test
on the presence of such an error log format or not. If a format is
defined, it is used for connection error messages, otherwise the legacy
error log format is used.

3 years agoBUILD: globally enable -Wundef
Willy Tarreau [Mon, 30 Aug 2021 04:02:47 +0000 (06:02 +0200)] 
BUILD: globally enable -Wundef

As seen in issue #1369, supporting #if with unknown macros can silently
hide typos that may result in suboptimal code paths to be used, or even
possibly bugs. It looks like our code base does not rely that much on
this, so it's worth enabling -Wundef to catch future ones and have them
turned to more explicit "#if defined()" or #ifdef.

3 years agoBUILD: tools: properly guard __GLIBC__ with defined()
Willy Tarreau [Mon, 30 Aug 2021 08:15:35 +0000 (10:15 +0200)] 
BUILD: tools: properly guard __GLIBC__ with defined()

The test on the glibc versions based on #if (__GLIBC > 2 ...) fails to
build under -Wundef, let's prepend defined(__GLIBC__) first.

3 years agoBUILD: ssl: fix two remaining occurrences of #if USE_OPENSSL
Willy Tarreau [Mon, 30 Aug 2021 07:35:18 +0000 (09:35 +0200)] 
BUILD: ssl: fix two remaining occurrences of #if USE_OPENSSL

One was in backend.c and the other one in hlua.c. No other candidate
was found with "git grep '^#if\s*USE'". It's worth noting that 3
other such tests exist for SSL_OP_NO_{SSLv3,TLSv1_1,TLSv1_2} but
that these ones are properly set to 0 in openssl-compat.h when not
defined.

3 years agoBUILD: ssl: next round of build warnings on LIBRESSL_VERSION_NUMBER
Willy Tarreau [Mon, 30 Aug 2021 04:10:04 +0000 (06:10 +0200)] 
BUILD: ssl: next round of build warnings on LIBRESSL_VERSION_NUMBER

Other build warnings were emitted on LIBRESSL_VERSION_NUMBER with -Wundef
under openssl < 1.1. Related to GH issue #1369. Seems like some of them
could be simplified a little bit.

3 years agoBUG/MINOR: tools: Fix loop condition in dump_text()
Tim Duesterhus [Sat, 28 Aug 2021 22:58:22 +0000 (00:58 +0200)] 
BUG/MINOR: tools: Fix loop condition in dump_text()

The condition should first check whether `bsize` is reached, before
dereferencing the offset. Even if this always works fine, due to the
string being null-terminated, this certainly looks odd.

Found using GitHub's CodeQL scan.

This bug traces back to at least 97c2ae13bc0d7961a348102d6719fbcaf34d46d5
(1.7.0+) and this patch should be backported accordingly.

3 years agoBUG/MINOR threads: Use get_(local|gm)time instead of (local|gm)time
Tim Duesterhus [Sat, 28 Aug 2021 21:57:01 +0000 (23:57 +0200)] 
BUG/MINOR threads: Use get_(local|gm)time instead of (local|gm)time

Using localtime / gmtime is not thread-safe, whereas the `get_*` wrappers are.

Found using GitHub's CodeQL scan.

The use in sample_conv_ltime() can be traced back to at least
fac9ccfb705702f211f99e67d5f5d5129002086a (first appearing in 1.6-dev3), so all
supported branches with thread support are affected.

3 years ago[RELEASE] Released version 2.5-dev5 v2.5-dev5
Willy Tarreau [Sat, 28 Aug 2021 11:46:11 +0000 (13:46 +0200)] 
[RELEASE] Released version 2.5-dev5

Released version 2.5-dev5 with the following main changes :
    - MINOR: httpclient: initialize the proxy
    - MINOR: httpclient: implement a simple HTTP Client API
    - MINOR: httpclient/cli: implement a simple client over the CLI
    - MINOR: httpclient/cli: change the User-Agent to "HAProxy"
    - MEDIUM: ssl: Keep a reference to the client's certificate for use in logs
    - BUG/MEDIUM: h2: match absolute-path not path-absolute for :path
    - BUILD/MINOR: ssl: Fix compilation with OpenSSL 1.0.2
    - MINOR: server: check if srv is NULL in free_server()
    - MINOR: proxy: check if p is NULL in free_proxy()
    - BUG/MEDIUM: cfgparse: do not allocate IDs to automatic internal proxies
    - BUG/MINOR: http_client: make sure to preset the proxy's default settings
    - REGTESTS: http_upgrade: fix incorrect expectation on TCP->H1->H2
    - REGTESTS: abortonclose: after retries, 503 is expected, not close
    - REGTESTS: server: fix agent-check syntax and expectation
    - BUG/MINOR: httpclient: fix uninitialized sl variable
    - BUG/MINOR: httpclient/cli: change the appctx test in the callbacks
    - BUG/MINOR: httpclient: check if hdr_num is not 0
    - MINOR: httpclient: cleanup the include files
    - MINOR: hlua: take the global Lua lock inside a global function
    - MINOR: tools: add FreeBSD support to get_exec_path()
    - BUG/MINOR: systemd: ExecStartPre must use -Ws
    - MINOR: systemd: remove the ExecStartPre line in the unit file
    - MINOR: ssl: add an openssl version string parser
    - MINOR: cfgcond: implements openssl_version_atleast and openssl_version_before
    - CLEANUP: ssl: remove useless check on p in openssl_version_parser()
    - BUG/MINOR: stick-table: fix the sc-set-gpt* parser when using expressions
    - BUG/MINOR: httpclient: remove deinit of the httpclient
    - BUG/MEDIUM: base64: check output boundaries within base64{dec,urldec}
    - MINOR: httpclient: set verify none on the https server
    - MINOR: httpclient: add the server to the proxy
    - BUG/MINOR: httpclient: fix Host header
    - BUILD: httpclient: fix build without OpenSSL
    - CI: github-actions: remove obsolete options
    - CLEANUP: assorted typo fixes in the code and comments
    - MINOR: proc: setting the process to produce a core dump on FreeBSD.
    - BUILD: adopt script/build-ssl.sh for OpenSSL-3.0.0beta2
    - MINOR: server: return the next srv instance on free_server
    - BUG/MINOR: stats: use refcount to protect dynamic server on dump
    - MEDIUM: server: extend refcount for all servers
    - MINOR: server: define non purgeable server flag
    - MINOR: server: mark referenced servers as non purgeable
    - MINOR: server: mark servers referenced by LUA script as non purgeable
    - MEDIUM: server: allow to remove servers at runtime except non purgeable
    - BUG/MINOR: base64: base64urldec() ignores padding in output size check
    - REGTEST: add missing lua requirements on server removal test
    - REGTEST: fix haproxy required version for server removal test
    - BUG/MINOR: proxy: don't dump servers of internal proxies
    - REGTESTS: Use `feature cmd` for 2.5+ tests
    - REGTESTS: Remove REQUIRE_VERSION=1.5 from all tests
    - BUG/MINOR: resolvers: mark servers with name-resolution as non purgeable
    - MINOR: compiler: implement an ONLY_ONCE() macro
    - BUG/MINOR: lua: use strlcpy2() not strncpy() to copy sample keywords
    - MEDIUM: ssl: Capture more info from Client Hello
    - MINOR: sample: Expose SSL captures using new fetchers
    - MINOR: sample: Add be2dec converter
    - MINOR: sample: Add be2hex converter
    - MEDIUM: config: Deprecate tune.ssl.capture-cipherlist-size
    - BUG/MINOR: time: fix idle time computation for long sleeps
    - MINOR: time: add report_idle() to report process-wide idle time
    - BUG/MINOR: ebtree: remove dependency on incorrect macro for bits per long
    - BUILD: activity: use #ifdef not #if on USE_MEMORY_PROFILING
    - BUILD/MINOR: defaults: eliminate warning on MAXHOSTNAMELEN with -Wundef
    - BUILD/MINOR: ssl: avoid a build warning on LIBRESSL_VERSION with -Wundef
    - IMPORT: slz: silence a build warning with -Wundef
    - BUILD/MINOR: regex: avoid a build warning on USE_PCRE2 with -Wundef

3 years agoBUILD/MINOR: regex: avoid a build warning on USE_PCRE2 with -Wundef
Willy Tarreau [Sat, 28 Aug 2021 10:49:58 +0000 (12:49 +0200)] 
BUILD/MINOR: regex: avoid a build warning on USE_PCRE2 with -Wundef

regex-t emits a warning on #elif USE_PCRE2 when built with -Wundef,
let's just fix it. This was reported in GH issue #1369.

3 years agoIMPORT: slz: silence a build warning with -Wundef
Willy Tarreau [Sat, 28 Aug 2021 10:10:49 +0000 (12:10 +0200)] 
IMPORT: slz: silence a build warning with -Wundef

The test on FIND_OPTIMAL_MATCH for the experimental code can yield a
build warning when using -Wundef, let's turn it into a regular ifdef.

This is slz upstream commit 05630ae8f22b71022803809eb1e7deb707bb30fb

3 years agoBUILD/MINOR: ssl: avoid a build warning on LIBRESSL_VERSION with -Wundef
Willy Tarreau [Sat, 28 Aug 2021 10:06:51 +0000 (12:06 +0200)] 
BUILD/MINOR: ssl: avoid a build warning on LIBRESSL_VERSION with -Wundef

Openssl-compat emits a warning for the test on LIBRESSL_VERSION that might
be underfined, if built with -Wundef. The fix is easy, let's do it. Related
to GH issue #1369.

3 years agoBUILD/MINOR: defaults: eliminate warning on MAXHOSTNAMELEN with -Wundef
Willy Tarreau [Sat, 28 Aug 2021 10:05:32 +0000 (12:05 +0200)] 
BUILD/MINOR: defaults: eliminate warning on MAXHOSTNAMELEN with -Wundef

As reported in GH issue #1369, there is a single case of #if with a
possibly undefined value in defaults.h which is on MAXHOSTNAMELEN. Let's
turn it to a #ifdef.

3 years agoBUILD: activity: use #ifdef not #if on USE_MEMORY_PROFILING
Willy Tarreau [Sat, 28 Aug 2021 10:04:25 +0000 (12:04 +0200)] 
BUILD: activity: use #ifdef not #if on USE_MEMORY_PROFILING

This avoids most build warnings with -Wundef, and all other USE_* flags
are tested this way, let's do it there as well. See gh issue #1369.

3 years agoBUG/MINOR: ebtree: remove dependency on incorrect macro for bits per long
Willy Tarreau [Sat, 28 Aug 2021 09:55:53 +0000 (11:55 +0200)] 
BUG/MINOR: ebtree: remove dependency on incorrect macro for bits per long

The code used to rely on BITS_PER_LONG to decide on the most efficient
way to perform a 64-bit shift, but this macro is not defined (at best
it's __BITS_PER_LONG) and it's likely that it's been like this since
the early implementation of ebtrees designed on i386. Let's remove the
test on this macro and rely on sizeof(long) instead, it also has the
benefit of letting the compiler validate the two branches.

This can be backported to all versions. Thanks to Ezequiel Garcia for
reporting this one in issue #1369.

3 years agoMINOR: time: add report_idle() to report process-wide idle time
Willy Tarreau [Sat, 28 Aug 2021 09:07:31 +0000 (11:07 +0200)] 
MINOR: time: add report_idle() to report process-wide idle time

Before threads were introduced in 1.8, idle_pct used to be a global
variable indicating the overall process idle time. Threads made it
thread-local, meaning that its reporting in the stats made little
sense, though this was not easy to spot. In 2.0, the idle_pct variable
moved to the struct thread_info via commit 81036f273 ("MINOR: time:
move the cpu, mono, and idle time to thread_info"). It made it more
obvious that the idle_pct was per thread, and also allowed to more
accurately measure it. But no more effort was made in that direction.

This patch introduces a new report_idle() function that accurately
averages the per-thread idle time over all running threads (i.e. it
should remain valid even if some threads are paused or stopped), and
makes use of it in the stats / "show info" reports.

Sending traffic over only two connections of an 8-thread process
would previously show this erratic CPU usage pattern:

  $ while :; do socat /tmp/sock1 - <<< "show info"|grep ^Idle;sleep 0.1;done
  Idle_pct: 30
  Idle_pct: 35
  Idle_pct: 100
  Idle_pct: 100
  Idle_pct: 100
  Idle_pct: 100
  Idle_pct: 100
  Idle_pct: 100
  Idle_pct: 35
  Idle_pct: 33
  Idle_pct: 100
  Idle_pct: 100
  Idle_pct: 100
  Idle_pct: 100
  Idle_pct: 100
  Idle_pct: 100

Now it shows this more accurate measurement:

  $ while :; do socat /tmp/sock1 - <<< "show info"|grep ^Idle;sleep 0.1;done
  Idle_pct: 83
  Idle_pct: 83
  Idle_pct: 83
  Idle_pct: 83
  Idle_pct: 83
  Idle_pct: 83
  Idle_pct: 83
  Idle_pct: 83
  Idle_pct: 83
  Idle_pct: 83
  Idle_pct: 83
  Idle_pct: 83
  Idle_pct: 83
  Idle_pct: 83
  Idle_pct: 83

This is not technically a bug but this lack of precision definitely affects
some users who rely on the idle_pct measurement. This should at least be
backported to 2.4, and might be to some older releases depending on users
demand.

3 years agoBUG/MINOR: time: fix idle time computation for long sleeps
Willy Tarreau [Fri, 27 Aug 2021 21:16:58 +0000 (23:16 +0200)] 
BUG/MINOR: time: fix idle time computation for long sleeps

In 2.4 we extended the max poll time from 1s to 60s with commit
4f59d3861 ("MINOR: time: increase the minimum wakeup interval to 60s").

This had the consequence that the calculation of the idle time percentage
may overflow during the multiply by 100 if the thread had slept 43s or
more. Let's change this to a 64 bit computation. This will have no
performance impact since this is done at most twice per second.

This should fix github issue #1366.

This must be backported to 2.4.

3 years agoMEDIUM: config: Deprecate tune.ssl.capture-cipherlist-size
Marcin Deranek [Tue, 13 Jul 2021 17:04:24 +0000 (19:04 +0200)] 
MEDIUM: config: Deprecate tune.ssl.capture-cipherlist-size

Deprecate tune.ssl.capture-cipherlist-size in favor of
tune.ssl.capture-buffer-size which better describes the purpose of the
setting.

3 years agoMINOR: sample: Add be2hex converter
Marcin Deranek [Tue, 13 Jul 2021 12:08:56 +0000 (14:08 +0200)] 
MINOR: sample: Add be2hex converter

Add be2hex converter to convert big-endian binary data into hex string
with optional string separators.

3 years agoMINOR: sample: Add be2dec converter
Marcin Deranek [Tue, 13 Jul 2021 12:05:24 +0000 (14:05 +0200)] 
MINOR: sample: Add be2dec converter

Add be2dec converter which allows to build JA3 compatible TLS
fingerprints by converting big-endian binary data into string
separated unsigned integers eg.

http-request set-header X-SSL-JA3 %[ssl_fc_protocol_hello_id],\
    %[ssl_fc_cipherlist_bin(1),be2dec(-,2)],\
    %[ssl_fc_extlist_bin(1),be2dec(-,2)],\
    %[ssl_fc_eclist_bin(1),be2dec(-,2)],\
    %[ssl_fc_ecformats_bin,be2dec(-,1)]

3 years agoMINOR: sample: Expose SSL captures using new fetchers
Marcin Deranek [Tue, 13 Jul 2021 13:14:21 +0000 (15:14 +0200)] 
MINOR: sample: Expose SSL captures using new fetchers

To be able to provide JA3 compatible TLS Fingerprints we need to expose
all Client Hello captured data using fetchers. Patch provides new
and modifies existing fetchers to add ability to filter out GREASE values:
- ssl_fc_cipherlist_*
- ssl_fc_ecformats_bin
- ssl_fc_eclist_bin
- ssl_fc_extlist_bin
- ssl_fc_protocol_hello_id

3 years agoMEDIUM: ssl: Capture more info from Client Hello
Marcin Deranek [Mon, 12 Jul 2021 12:16:55 +0000 (14:16 +0200)] 
MEDIUM: ssl: Capture more info from Client Hello

When we set tune.ssl.capture-cipherlist-size to a non-zero value
we are able to capture cipherlist supported by the client. To be able to
provide JA3 compatible TLS fingerprinting we need to capture more
information from Client Hello message:
- SSL Version
- SSL Extensions
- Elliptic Curves
- Elliptic Curve Point Formats
This patch allows HAProxy to capture such information and store it for
later use.

3 years agoBUG/MINOR: lua: use strlcpy2() not strncpy() to copy sample keywords
Willy Tarreau [Thu, 26 Aug 2021 14:48:53 +0000 (16:48 +0200)] 
BUG/MINOR: lua: use strlcpy2() not strncpy() to copy sample keywords

The lua initialization code which creates the Lua mapping of all converters
and sample fetch keywords makes use of strncpy(), and as such can take ages
to start with large values of tune.bufsize because it spends its time zeroing
gigabytes of memory for nothing. A test performed with an extreme value of
16 MB takes roughly 4 seconds, so it's possible that some users with huge
1 MB buffers (e.g. for payload analysis) notice a small startup latency.
However this does not affect config checks since the Lua stack is not yet
started. Let's replace this with strlcpy2().

This should be backported to all supported versions.

3 years agoMINOR: compiler: implement an ONLY_ONCE() macro
Willy Tarreau [Thu, 26 Aug 2021 13:46:51 +0000 (15:46 +0200)] 
MINOR: compiler: implement an ONLY_ONCE() macro

There are regularly places, especially in config analysis, where we
need to report certain things (warnings or errors) only once, but
where implementing a counter is sufficiently deterrent so that it's
not done.

Let's add a simple ONLY_ONCE() macro that implements a static variable
(char) which is atomically turned on, and returns true if it's set for
the first time. This uses fairly compact code, a single byte of BSS
and is thread-safe. There are probably a number of places in the config
parser where this could be used. It may also be used to implement a
WARN_ON() similar to BUG_ON() but which would only warn once.

3 years agoBUG/MINOR: resolvers: mark servers with name-resolution as non purgeable
Amaury Denoyelle [Thu, 26 Aug 2021 13:35:59 +0000 (15:35 +0200)] 
BUG/MINOR: resolvers: mark servers with name-resolution as non purgeable

When a server is configured with name-resolution, resolvers objects are
created with reference to this server. Thus the server is marked as non
purgeable to prevent its removal at runtime.

This does not need to be backport.

3 years agoREGTESTS: Remove REQUIRE_VERSION=1.5 from all tests
Tim Duesterhus [Wed, 25 Aug 2021 17:17:28 +0000 (19:17 +0200)] 
REGTESTS: Remove REQUIRE_VERSION=1.5 from all tests

HAProxy 1.5 is EOL, thus this always matches.

1.6 / 1.7 were already removed in:
d8be0018fe85b5f815d59cdf1e0400274a99a9b1 (1.6)
1b095cac9468d0c3eeb157e9b1a2947487bd3c83 (1.7)

3 years agoREGTESTS: Use `feature cmd` for 2.5+ tests
Tim Duesterhus [Wed, 25 Aug 2021 17:14:01 +0000 (19:14 +0200)] 
REGTESTS: Use `feature cmd` for 2.5+ tests

Using `REQUIRE_VERSION` is deprecated for tests targeting HAProxy with `-cc`
support.

3 years agoBUG/MINOR: proxy: don't dump servers of internal proxies
William Lallemand [Wed, 25 Aug 2021 16:15:31 +0000 (18:15 +0200)] 
BUG/MINOR: proxy: don't dump servers of internal proxies

Patch 211c967 ("MINOR: httpclient: add the server to the proxy") broke
the reg-tests that do a "show servers state".

Indeed the servers of the proxies flagged with PR_CAP_INT are dumped in
the output of this CLI command.

This patch fixes the issue par ignoring the PR_CA_INT proxies in the
dump.

3 years agoREGTEST: fix haproxy required version for server removal test
Amaury Denoyelle [Wed, 25 Aug 2021 14:35:25 +0000 (16:35 +0200)] 
REGTEST: fix haproxy required version for server removal test

The ability to delete all servers is introduced in 2.5 release.

3 years agoREGTEST: add missing lua requirements on server removal test
Amaury Denoyelle [Wed, 25 Aug 2021 14:24:23 +0000 (16:24 +0200)] 
REGTEST: add missing lua requirements on server removal test

The test that removes server via CLI is using LUA to check that servers
referenced in a LUA script cannot be removed. This requires LUA support
to be built in haproxy.

Split the test and create a new one containing only the LUA relevant
test. Mark it as LUA dependant.

3 years agoBUG/MINOR: base64: base64urldec() ignores padding in output size check
Dragan Dosen [Wed, 25 Aug 2021 09:57:01 +0000 (11:57 +0200)] 
BUG/MINOR: base64: base64urldec() ignores padding in output size check

Without this fix, the decode function would proceed even when the output
buffer is not large enough, because the padding was not considered. For
example, it would not fail with the input length of 23 and the output
buffer size of 15, even the actual decoded output size is 17.

This patch should be backported to all stable branches that have a
base64urldec() function available.

3 years agoMEDIUM: server: allow to remove servers at runtime except non purgeable
Amaury Denoyelle [Mon, 23 Aug 2021 12:10:51 +0000 (14:10 +0200)] 
MEDIUM: server: allow to remove servers at runtime except non purgeable

Relax the condition on "delete server" CLI handler to be able to remove
all servers, even non dynamic, except if they are flagged as non
purgeable.

This change is necessary to extend the use cases for dynamic servers
with reload. It's expected that each dynamic server created via the CLI
is manually commited in the haproxy configuration by the user. Dynamic
servers will be present on reload only if they are present in the
configuration file. This means that non-dynamic servers must be allowed
to be removable at runtime.

The dynamic servers removal reg-test has been updated and renamed to
reflect its purpose. A new test is present to check that non-purgeable
servers cannot be removed.

3 years agoMINOR: server: mark servers referenced by LUA script as non purgeable
Amaury Denoyelle [Mon, 23 Aug 2021 12:06:31 +0000 (14:06 +0200)] 
MINOR: server: mark servers referenced by LUA script as non purgeable

Each server that is retrieved by a LUA script is marked as non
purgeable. Note that for this to work, the script must have been
executed already once.

3 years agoMINOR: server: mark referenced servers as non purgeable
Amaury Denoyelle [Mon, 23 Aug 2021 12:05:07 +0000 (14:05 +0200)] 
MINOR: server: mark referenced servers as non purgeable

Mark servers that are referenced by configuration elements as non
purgeable. This includes the following list :
- tracked servers
- servers referenced in a use-server rule
- servers referenced in a sample fetch

3 years agoMINOR: server: define non purgeable server flag
Amaury Denoyelle [Mon, 23 Aug 2021 12:03:20 +0000 (14:03 +0200)] 
MINOR: server: define non purgeable server flag

Define a flag to mark a server as non purgeable. This flag will be used
for "delete server" CLI handler. All servers without this flag will be
eligible to runtime suppression.

3 years agoMEDIUM: server: extend refcount for all servers
Amaury Denoyelle [Wed, 25 Aug 2021 13:34:53 +0000 (15:34 +0200)] 
MEDIUM: server: extend refcount for all servers

In a future patch, it will be possible to remove at runtime every
servers, both static and dynamic. This requires to extend the server
refcount for all instances.

First, refcount manipulation functions have been renamed to better
express the API usage.

* srv_refcount_use -> srv_take
The refcount is always initialize to 1 on the server creation in
new_server. It's also incremented for each check/agent configured on a
server instance.

* free_server -> srv_drop
This decrements the refcount and if null, the server is freed, so code
calling it must not use the server reference after it. As a bonus, this
function now returns the next server instance. This is useful when
calling on the server loop without having to save the next pointer
before each invocation.

In these functions, remove the checks that prevent refcount on
non-dynamic servers. Each reference to "dynamic" in variable/function
naming have been eliminated as well.

3 years agoBUG/MINOR: stats: use refcount to protect dynamic server on dump
Amaury Denoyelle [Wed, 25 Aug 2021 12:39:53 +0000 (14:39 +0200)] 
BUG/MINOR: stats: use refcount to protect dynamic server on dump

A dynamic server may be deleted at runtime at the same moment when the
stats applet is pointing to it. Use the server refcount to prevent
deletion in this case.

This should be backported up to 2.4, with an observability period of 2
weeks. Note that it requires the dynamic server refcounting feature
which has been implemented on 2.5; the following commits are required :

- MINOR: server: implement a refcount for dynamic servers
- BUG/MINOR: server: do not use refcount in free_server in stopping mode
- MINOR: server: return the next srv instance on free_server

3 years agoMINOR: server: return the next srv instance on free_server
Amaury Denoyelle [Wed, 25 Aug 2021 13:03:46 +0000 (15:03 +0200)] 
MINOR: server: return the next srv instance on free_server

As a convenience, return the next server instance from servers list on
free_server.

This is particularily useful when using this function on the servers
list without having to save of the next pointer before calling it.

3 years agoBUILD: adopt script/build-ssl.sh for OpenSSL-3.0.0beta2
Ilya Shipitsin [Sat, 21 Aug 2021 11:01:25 +0000 (16:01 +0500)] 
BUILD: adopt script/build-ssl.sh for OpenSSL-3.0.0beta2

starting with
https://github.com/openssl/openssl/commit/74b7f339aa58af57c0e71b7efca66e6f2db5ae2e,
libs are installed to "lib64", to get back required behaviour, let us
set libdir explicitly

3 years agoMINOR: proc: setting the process to produce a core dump on FreeBSD.
devnexen@gmail.com [Sat, 21 Aug 2021 08:13:10 +0000 (09:13 +0100)] 
MINOR: proc: setting the process to produce a core dump on FreeBSD.

using the procctl api to set the current process as traceable, thus being able to produce a core dump as well.

making it as compile option if not wished or using freebsd prior to 11.x (last no EOL release).

3 years agoCLEANUP: assorted typo fixes in the code and comments
Ilya Shipitsin [Sun, 22 Aug 2021 17:18:07 +0000 (22:18 +0500)] 
CLEANUP: assorted typo fixes in the code and comments

This is 26th iteration of typo fixes

3 years agoCI: github-actions: remove obsolete options
Willy Tarreau [Wed, 25 Aug 2021 03:10:29 +0000 (05:10 +0200)] 
CI: github-actions: remove obsolete options

2.5-dev1 removed http-use-htx but the h2spec config was not updated
accordingly, causing failures. In addition, let's also remove the
unneeded "nbthread 4" which is either too much or not enough (it's
automatic nowadays), and remove "option httplog" which causes a
warning since there's no defined log destination.

3 years agoBUILD: httpclient: fix build without OpenSSL
William Lallemand [Tue, 24 Aug 2021 16:33:28 +0000 (18:33 +0200)] 
BUILD: httpclient: fix build without OpenSSL

Add some defines around the ssl server so we can build without OpenSSL.

3 years agoBUG/MINOR: httpclient: fix Host header
William Lallemand [Tue, 24 Aug 2021 15:53:03 +0000 (17:53 +0200)] 
BUG/MINOR: httpclient: fix Host header

THe http_update_update_host function takes an URL and extract the domain
to use as a host header. However it only update an existing host header
and does not create one.

This patch add an empty host header so the function can update it.

3 years agoMINOR: httpclient: add the server to the proxy
William Lallemand [Tue, 24 Aug 2021 15:18:13 +0000 (17:18 +0200)] 
MINOR: httpclient: add the server to the proxy

Add the raw and ssl server to the proxy list so they can be freed during
the deinit() of HAProxy. As a side effect the 2 servers need to have a
different ID so the SSL one was renamed "<HTTPSCLIENT>".

3 years agoMINOR: httpclient: set verify none on the https server
William Lallemand [Tue, 24 Aug 2021 15:15:58 +0000 (17:15 +0200)] 
MINOR: httpclient: set verify none on the https server

There is currently no way to specify the CA to verify from the
httpclient API. Sets the verify to none so we can still do https
request.

3 years agoBUG/MEDIUM: base64: check output boundaries within base64{dec,urldec}
Dragan Dosen [Tue, 24 Aug 2021 07:48:04 +0000 (09:48 +0200)] 
BUG/MEDIUM: base64: check output boundaries within base64{dec,urldec}

Ensure that no more than olen bytes is written to the output buffer,
otherwise we might experience an unexpected behavior.

While the original code used to validate that the output size was
always large enough before starting to write, this validation was
later broken by the commit below, allowing to 3-byte blocks to
areas whose size is not multiple of 3:

  commit ed697e4856e5ac0b9931fd50fd8ff1b7739e5d88
  Author: Emeric Brun <ebrun@haproxy.com>
  Date:   Mon Jan 14 14:38:39 2019 +0100

    BUG/MINOR: base64: dec func ignores padding for output size checking

    Decode function returns an error even if the ouptut buffer is
    large enought because the padding was not considered. This
    case was never met with current code base.

For base64urldec(), it's basically the same problem except that since
the input format supports arbitrary lengths, the problem has always
been there since its introduction in 2.4.

This should be backported to all stable branches having a backport of
the patch above (i.e. 2.0), with some adjustments depending on the
availability of the base64dec() and base64urldec().

3 years agoBUG/MINOR: httpclient: remove deinit of the httpclient
William Lallemand [Tue, 24 Aug 2021 13:09:15 +0000 (15:09 +0200)] 
BUG/MINOR: httpclient: remove deinit of the httpclient

The httpclient does a free of the servers and proxies it uses, however
since we are including them in the global proxy list, haproxy already
free them during the deinit. We can safely remove these free.

3 years agoBUG/MINOR: stick-table: fix the sc-set-gpt* parser when using expressions
Willy Tarreau [Tue, 24 Aug 2021 12:57:28 +0000 (14:57 +0200)] 
BUG/MINOR: stick-table: fix the sc-set-gpt* parser when using expressions

The sc-set-gpt0() parser was extended in 2.1 by commit 0d7712dff ("MINOR:
stick-table: allow sc-set-gpt0 to set value from an expression") to support
sample expressions in addition to plain integers. However there is a
subtlety there, which is that while the arg position must be incremented
when parsing an integer, it must not be touched when calling an expression
since the expression parser already does it.

The effect is that rules making use of sc-set-gpt0() followed by an
expression always ignore one word after that expression, and will typically
fail to parse if followed by an "if" as the parser will restart after the
"if". With no condition it's different because an empty condition doesn't
result in trying to parse anything.

This patch moves the increment at the right place and adds a few
explanations for a code part that was far from being obvious.

This should be backported to branches having the commit above (2.1+).

3 years agoCLEANUP: ssl: remove useless check on p in openssl_version_parser()
William Lallemand [Sun, 22 Aug 2021 11:36:11 +0000 (13:36 +0200)] 
CLEANUP: ssl: remove useless check on p in openssl_version_parser()

Remove a  useless check on a pointer which reports a NULL dereference on
coverity.

Fixes issue #1358.

3 years agoMINOR: cfgcond: implements openssl_version_atleast and openssl_version_before
William Lallemand [Sat, 21 Aug 2021 21:59:56 +0000 (23:59 +0200)] 
MINOR: cfgcond: implements openssl_version_atleast and openssl_version_before

Implements a way of checking the running openssl version:

If the OpenSSL support was not compiled within HAProxy it will returns a
error, so it's recommanded to do a SSL feature check before:

$ ./haproxy -cc 'feature(OPENSSL) && openssl_version_atleast(0.9.8zh) && openssl_version_before(3.0.0)'

This will allow to select the SSL reg-tests more carefully.

3 years agoMINOR: ssl: add an openssl version string parser
William Lallemand [Sat, 21 Aug 2021 21:16:06 +0000 (23:16 +0200)] 
MINOR: ssl: add an openssl version string parser

openssl_version_parser() parse a string in the OpenSSL version format
which is documented here:

https://www.openssl.org/docs/man1.1.1/man3/OPENSSL_VERSION_NUMBER.html

The function returns an unsigned int that could be used for comparing
openssl versions.

3 years agoMINOR: systemd: remove the ExecStartPre line in the unit file
William Lallemand [Fri, 20 Aug 2021 21:36:45 +0000 (23:36 +0200)] 
MINOR: systemd: remove the ExecStartPre line in the unit file

The ExecStartPre line was introduced a long time ago in the systemd unit
file, at the time of systemd wrapper. With the haproxy master worker
mode, this line is now useless, since starting haproxy itself will check
the configuration.

However this does not concern the check in the ExecReload which is still
needed to return a reload status to HAProxy.

It probably shouldn't be backported.

3 years agoBUG/MINOR: systemd: ExecStartPre must use -Ws
William Lallemand [Fri, 20 Aug 2021 21:29:53 +0000 (23:29 +0200)] 
BUG/MINOR: systemd: ExecStartPre must use -Ws

This line should disappear in a future version but we should still fix
ExecStartPre with -Ws like we've done in 9def142.

It's a complementary fix that must be backported with 9def142
("BUG/MINOR: systemd: must check the configuration using -Ws").

3 years agoMINOR: tools: add FreeBSD support to get_exec_path()
devnexen@gmail.com [Tue, 17 Aug 2021 11:55:49 +0000 (12:55 +0100)] 
MINOR: tools: add FreeBSD support to get_exec_path()

FreeBSD stores the absolute path into the auxiliary vector as well.
The auxiliary vector is found in __elf_aux_vector there.

3 years agoMINOR: hlua: take the global Lua lock inside a global function
Willy Tarreau [Fri, 20 Aug 2021 13:47:25 +0000 (15:47 +0200)] 
MINOR: hlua: take the global Lua lock inside a global function

Some users are facing huge CPU usage or even watchdog panics due to
the Lua global lock when many threads compete on it, but they have
no way to see that in the usual dumps. We take the lock at 2 or 3
places only, thus it's trivial to move it to a global function so
that stack dumps will now explicitly show it, increasing the change
that it rings a bell and someone suggests switch to lua-load-per-thread:

  Current executing Lua from a stream analyser -- stack traceback:
      loop.lua:1: in function line 1
  call trace(27):
  |       0x5ff157 [48 83 c4 10 5b 5d 41 5c]: wdt_handler+0xf7/0x104
  | 0x7fe37fe82690 [48 c7 c0 0f 00 00 00 0f]: libpthread:+0x13690
  |       0x614340 [66 48 0f 7e c9 48 01 c2]: main+0x1e8a40
  |       0x607b85 [48 83 c4 08 48 89 df 31]: main+0x1dc285
  |       0x6070bc [48 8b 44 24 20 48 8b 14]: main+0x1db7bc
  |       0x607d37 [41 89 c4 89 44 24 1c 83]: lua_resume+0xc7/0x214
  |       0x464ad6 [83 f8 06 0f 87 f1 01 00]: main+0x391d6
  |       0x4691a7 [83 f8 06 0f 87 03 20 fc]: main+0x3d8a7
  |       0x51dacb [85 c0 74 61 48 8b 5d 20]: sample_process+0x4b/0xf7
  |       0x51e55c [48 85 c0 74 3f 64 48 63]: sample_fetch_as_type+0x3c/0x9b
  |       0x525613 [48 89 c6 48 85 c0 0f 84]: sess_build_logline+0x2443/0x3cae
  |       0x4af0be [4c 63 e8 4c 03 6d 10 4c]: http_apply_redirect_rule+0xbfe/0xdf8
  |       0x4af523 [83 f8 01 19 c0 83 e0 03]: main+0x83c23
  |       0x4b2326 [83 f8 07 0f 87 99 00 00]: http_process_req_common+0xf6/0x15f6
  |       0x4d5b30 [85 c0 0f 85 9f f5 ff ff]: process_stream+0x2010/0x4e18

It also allows "perf top" to directly show the time spent on this lock.

This may be backported to some stable versions as it improves the
overall debuggability.

3 years agoMINOR: httpclient: cleanup the include files
William Lallemand [Fri, 20 Aug 2021 12:25:15 +0000 (14:25 +0200)] 
MINOR: httpclient: cleanup the include files

Include the correct .h files in http_client.c and http_client.h.

The api.h is needed in http_client.c and http_client-t.h is now include
directly from http_client.h

3 years agoBUG/MINOR: httpclient: check if hdr_num is not 0
William Lallemand [Fri, 20 Aug 2021 09:59:49 +0000 (11:59 +0200)] 
BUG/MINOR: httpclient: check if hdr_num is not 0

Check if hdr_num is not 0 before allocating or copying the headers to
the hc->hdrs space.

3 years agoBUG/MINOR: httpclient/cli: change the appctx test in the callbacks
William Lallemand [Fri, 20 Aug 2021 09:35:29 +0000 (11:35 +0200)] 
BUG/MINOR: httpclient/cli: change the appctx test in the callbacks

The callbacks of the CLI httpclient are testing the appctx pointer
before doing the appctx_wakeup but was dereferencing the appctx pointer
before.

3 years agoBUG/MINOR: httpclient: fix uninitialized sl variable
William Lallemand [Fri, 20 Aug 2021 09:24:13 +0000 (11:24 +0200)] 
BUG/MINOR: httpclient: fix uninitialized sl variable

Reported by coverity in ticket #1355

  CID 1461505:  Memory - illegal accesses  (UNINIT)
  Using uninitialized value "sl".

Fix the problem by initializing sl to NULL.

3 years agoREGTESTS: server: fix agent-check syntax and expectation
Willy Tarreau [Fri, 20 Aug 2021 09:28:15 +0000 (11:28 +0200)] 
REGTESTS: server: fix agent-check syntax and expectation

Since commit 8d6c6bd ("Leak-plugging on barriers") VTest has become
stricter in its expectations, making this one fail. The agent-check
test was expecting a close on the server, which normally does not
happen before the server responds. In addition, it was really sending
"hello" (with the quotes) due to the config file syntax, which explains
why test test log reported that '"hell' was received, and complained
that 0x6f ('o') was read instead of a shutdown. This has been fixed
as well by using single-quotes.

There is no need to backport this test as it's only in 2.5.

3 years agoREGTESTS: abortonclose: after retries, 503 is expected, not close
Willy Tarreau [Fri, 20 Aug 2021 09:12:47 +0000 (11:12 +0200)] 
REGTESTS: abortonclose: after retries, 503 is expected, not close

The abortonclose test was only expecting a close after all server
retries were exhausted, it didn't check for the pending 503, which
fails with new versions of vtest starting with commit 8d6c6bd
("Leak-plugging on barriers").

This may be backported, but carefully in case older versions would
really close without responding.

3 years agoREGTESTS: http_upgrade: fix incorrect expectation on TCP->H1->H2
Willy Tarreau [Fri, 20 Aug 2021 09:02:28 +0000 (11:02 +0200)] 
REGTESTS: http_upgrade: fix incorrect expectation on TCP->H1->H2

Commit e1b9e1bb1 ("REGTESTS: Add script to tests TCP to HTTP upgrades")
included a mistake in the TCP->H1->H2 test, it expected a close while
it ought to expect a 400 bad req, which is what the mux returns in this
case. It happens that this used to work fine with older versions of
vtest which see the close regardless of the 400, but since Vtest commit
8d6c6bd ("Leak-plugging on barriers"), this doesn't work anymore.

Let's fix this by expecting the proper response. This should be backported
where this regtest is present, but only after verifying that it still
works; indeed at the time of writing it's uncertain whether an earlier
version used to immediately close.

3 years agoBUG/MINOR: http_client: make sure to preset the proxy's default settings
Willy Tarreau [Fri, 20 Aug 2021 08:23:12 +0000 (10:23 +0200)] 
BUG/MINOR: http_client: make sure to preset the proxy's default settings

Proxies must call proxy_preset_defaults() to initialize their settings
that are usually learned from defaults sections (e.g. connection retries,
pool purge delay etc). At the moment there was likely no impact, but not
doing so could cause trouble soon when using the client more extensively
or when new defaults are introduced and failed to be initialized.

No backport is needed.

3 years agoBUG/MEDIUM: cfgparse: do not allocate IDs to automatic internal proxies
Willy Tarreau [Fri, 20 Aug 2021 08:15:40 +0000 (10:15 +0200)] 
BUG/MEDIUM: cfgparse: do not allocate IDs to automatic internal proxies

Recent commit 83614a9fb ("MINOR: httpclient: initialize the proxy") broke
reg tests that match the output of "show stats" or "show servers state"
because it changed the proxies' numeric ID.

In fact it did nothing wrong, it just registers a proxy and adds it at
the head of the list. But the automatic numbering scheme, which was made
to make sure that temporarily disabled proxies in the config keep their
ID instead of shifting all others, sees one more proxy and increments
next_pxid for all subsequent proxies.

This patch avoids this by not assigning automatic IDs to such internal
proxies, leaving them with their ID of -1, and by not shifting next_pxid
for them. This is important because the user might experience them
appearing or disappearing depending on apparently unrelated config
options or build options, and this must not cause visible proxy IDs
to change (e.g. stats or minitoring may break).

Though the issue has always been there, it only became a problem with
the recent proxy additions so there is no need to backport this.

3 years agoMINOR: proxy: check if p is NULL in free_proxy()
William Lallemand [Fri, 20 Aug 2021 08:16:37 +0000 (10:16 +0200)] 
MINOR: proxy: check if p is NULL in free_proxy()

Check if p is NULL before trying to do anything  in free_proxy(),
like most free()-like function do.

3 years agoMINOR: server: check if srv is NULL in free_server()
William Lallemand [Fri, 20 Aug 2021 08:10:15 +0000 (10:10 +0200)] 
MINOR: server: check if srv is NULL in free_server()

Check if srv is NULL before trying to do anything  in free_server(),
like most free()-like function do.

3 years agoBUILD/MINOR: ssl: Fix compilation with OpenSSL 1.0.2
Remi Tricot-Le Breton [Fri, 20 Aug 2021 07:51:23 +0000 (09:51 +0200)] 
BUILD/MINOR: ssl: Fix compilation with OpenSSL 1.0.2

The X509_STORE_CTX_get0_cert did not exist yet on OpenSSL 1.0.2 and
neither did X509_STORE_CTX_get0_chain, which was not actually needed
since its get1 equivalent already existed.

3 years agoBUG/MEDIUM: h2: match absolute-path not path-absolute for :path
Willy Tarreau [Thu, 19 Aug 2021 21:06:58 +0000 (23:06 +0200)] 
BUG/MEDIUM: h2: match absolute-path not path-absolute for :path

RFC7540 states that :path follows RFC3986's path-absolute. However
that was a bug introduced in the spec between draft 04 and draft 05
of the spec, which implicitly causes paths starting with "//" to be
forbidden. HTTP/1 (and now HTTP core semantics) made it explicit
that the request-target in origin-form follows a purposely defined
absolute-path defined as 1*(/ segment) to explicitly allow "//".

http2bis now fixes this by relying on absolute-path so that "//"
becomes valid and matches other versions. Full discussion here:

  https://lists.w3.org/Archives/Public/ietf-http-wg/2021JulSep/0245.html

This issue appeared in haproxy with commit 4b8852c70 ("BUG/MAJOR: h2:
verify that :path starts with a '/' before concatenating it") when
making the checks on :path fully comply with the spec, and was backported
as far as 2.0, so this fix must be backported there as well to allow
"//" in H2 again.

3 years agoMEDIUM: ssl: Keep a reference to the client's certificate for use in logs
Remi Tricot-Le Breton [Thu, 19 Aug 2021 16:06:30 +0000 (18:06 +0200)] 
MEDIUM: ssl: Keep a reference to the client's certificate for use in logs

Most of the SSL sample fetches related to the client certificate were
based on the SSL_get_peer_certificate function which returns NULL when
the verification process failed. This made it impossible to use those
fetches in a log format since they would always be empty.

The patch adds a reference to the X509 object representing the client
certificate in the SSL structure and makes use of this reference in the
fetches.

The reference can only be obtained in ssl_sock_bind_verifycbk which
means that in case of an SSL error occurring before the verification
process ("no shared cipher" for instance, which happens while processing
the Client Hello), we won't ever start the verification process and it
will be impossible to get information about the client certificate.

This patch also allows most of the ssl_c_XXX fetches to return a usable
value in case of connection failure (because of a verification error for
instance) by making the "conn->flags & CO_FL_WAIT_XPRT" test (which
requires a connection to be established) less strict.

Thanks to this patch, a log-format such as the following should return
usable information in case of an error occurring during the verification
process :
    log-format "DN=%{+Q}[ssl_c_s_dn] serial=%[ssl_c_serial,hex] \
                hash=%[ssl_c_sha1,hex]"

It should answer to GitHub issue #693.

3 years agoMINOR: httpclient/cli: change the User-Agent to "HAProxy"
William Lallemand [Thu, 19 Aug 2021 13:55:19 +0000 (15:55 +0200)] 
MINOR: httpclient/cli: change the User-Agent to "HAProxy"

Change the User-Agent from "HAProxy HTTP client" to "HAProxy" as the
previous name is not valid according to RFC 7231#5.5.3.

This patch fixes issue #1354.

3 years agoMINOR: httpclient/cli: implement a simple client over the CLI
William Lallemand [Wed, 18 Aug 2021 14:46:21 +0000 (16:46 +0200)] 
MINOR: httpclient/cli: implement a simple client over the CLI

This commit implements an HTTP Client over the CLI, this was made as
working example for the HTTP Client API.

It usable over the CLI by specifying a method and an URL:

    echo "httpclient GET http://127.0.0.1:8000/demo.file" | socat /tmp/haproxy.sock -

Only IP addresses are accessibles since the API does not allow to
resolve addresses yet.

3 years agoMINOR: httpclient: implement a simple HTTP Client API
William Lallemand [Fri, 13 Aug 2021 14:05:53 +0000 (16:05 +0200)] 
MINOR: httpclient: implement a simple HTTP Client API

This commit implements a very simple HTTP Client API.

A client can be operated by several functions:

    - httpclient_new(), httpclient_destroy(): create
      and destroy the struct httpclient instance.

    - httpclient_req_gen(): generate a complete HTX request using the
      the absolute URL, the method and a list of headers. This request
      is complete and sets the HTX End of Message flag. This is limited
      to small request we don't need a body.

    - httpclient_start() fill a sockaddr storage with a IP extracted
      from the URL (it cannot resolve an fqdm for now), start the
      applet. It also stores the ptr of the caller which could be an
      appctx or something else.

   - hc->ops contains a list of callbacks used by the
     HTTPClient, they should be filled manually after an
     httpclient_new():

        * res_stline(): the client received a start line, its content
          will be stored in hc->res.vsn, hc->res.status, hc->res.reason

        * res_headers(): the client received headers, they are stored in
          hc->res.hdrs.

        * res_payload(): the client received some payload data, they are
        stored in the hc->res.buf buffer and could be extracted with the
        httpclient_res_xfer() function, which takes a destination buffer
        as a parameter

        * res_end(): this callback is called once we finished to receive
        the response.

3 years agoMINOR: httpclient: initialize the proxy
William Lallemand [Fri, 13 Aug 2021 12:47:57 +0000 (14:47 +0200)] 
MINOR: httpclient: initialize the proxy

Initialize a proxy which contain a server for the raw HTTP, and another
one for the HTTPS. This proxy will use the global server log definition
and the 'option httplog' directive.

This proxy is internal and will only be used for the HTTP Client API.

3 years ago[RELEASE] Released version 2.5-dev4 v2.5-dev4
Willy Tarreau [Tue, 17 Aug 2021 12:08:55 +0000 (14:08 +0200)] 
[RELEASE] Released version 2.5-dev4

Released version 2.5-dev4 with the following main changes :
    - MINOR: log: rename 'dontloglegacyconnerr' to 'log-error-via-logformat'
    - MINOR: doc: rename conn_status in `option httsplog`
    - MINOR: proxy: disabled takes a stopping and a disabled state
    - MINOR: stats: shows proxy in a stopped state
    - BUG/MINOR: server: fix race on error path of 'add server' CLI if track
    - CLEANUP: thread: fix fantaisist indentation of thread_harmless_till_end()
    - MINOR: threads: make thread_release() not wait for other ones to complete
    - MEDIUM: threads: add a stronger thread_isolate_full() call
    - MEDIUM: servers: make the server deletion code run under full thread isolation
    - BUG/MINOR: server: remove srv from px list on CLI 'add server' error
    - MINOR: activity/fd: remove the dead_fd counter
    - MAJOR: fd: get rid of the DWCAS when setting the running_mask
    - CLEANUP: fd: remove the now unused fd_set_running()
    - CLEANUP: fd: remove the now unneeded fd_mig_lock
    - BUG/MINOR: server: update last_change on maint->ready transitions too
    - MINOR: spoe: Add a pointer on the filter config in the spoe_agent structure
    - BUG/MEDIUM: spoe: Create a SPOE applet if necessary when the last one is released
    - BUG/MEDIUM: spoe: Fix policy to close applets when SPOE connections are queued
    - MINOR: server: unmark deprecated on enable health/agent cli
    - MEDIUM: task: implement tasklet kill
    - MINOR: server: initialize fields for dynamic server check
    - MINOR: check: allocate default check ruleset for every backends
    - MINOR: check: export check init functions
    - MINOR: check: do not increment global maxsock at runtime
    - MINOR: server: implement a refcount for dynamic servers
    - MEDIUM: check: implement check deletion for dynamic servers
    - MINOR: check: enable safe keywords for dynamic servers
    - MEDIUM: server: implement check for dynamic servers
    - MEDIUM: server: implement agent check for dynamic servers
    - REGTESTS: server: add dynamic check server test
    - MINOR: doc: specify ulimit-n usage for dynamic servers
    - REGTESTS: server: fix dynamic server with checks test
    - CI: travis-ci: temporarily disable arm64 builds
    - BUG/MINOR: check: test if server is not null in purge
    - MINOR: global: define MODE_STOPPING
    - BUG/MINOR: server: do not use refcount in free_server in stopping mode
    - ADMIN: dyncookie: implement a simple dynamic cookie calculator
    - BUG/MINOR: check: do not reset check flags on purge
    - BUG/MINOR: check: fix leak on add dynamic server with agent-check error
    - BUG/MEDIUM: check: fix leak on agent-check purge
    - BUG/MEDIUM: server: support both check/agent-check on a dynamic instance
    - BUG/MINOR: buffer: fix buffer_dump() formatting
    - MINOR: channel: remove an htx block from a channel
    - BUG/MINOR: tcpcheck: Properly detect pending HTTP data in output buffer
    - BUG/MINOR: stream: Don't release a stream if FLT_END is still registered
    - MINOR: lua: Add a flag on lua context to know the yield capability at run time
    - BUG/MINOR: lua: Yield in channel functions only if lua context can yield
    - BUG/MINOR: lua: Don't yield in channel.append() and channel.set()
    - MINOR: filters/lua: Release filters before the lua context
    - MINOR: lua: Add a function to get a reference on a table in the stack
    - MEDIUM: lua: Process buffer data using an offset and a length
    - MEDIUM: lua: Improve/revisit the lua api to manipulate channels
    - DOC: Improve the lua documentation
    - MEDIUM: filters/lua: Add support for dummy filters written in lua
    - MINOR: lua: Add a function to get a filter attached to a channel class
    - MINOR: lua: Add flags on the lua TXN to know the execution context
    - MEDIUM: filters/lua: Be prepared to filter TCP payloads
    - MEDIUM: filters/lua: Support declaration of some filter callback functions in lua
    - MEDIUM: filters/lua: Add HTTPMessage class to help HTTP filtering
    - MINOR: filters/lua: Add request and response HTTP messages in the lua TXN
    - MINOR: filters/lua: Support the HTTP filtering from filters written in lua
    - DOC: config: Fix 'http-response send-spoe-group' documentation
    - BUG/MINOR: lua: Properly check negative offset in Channel/HttpMessage functions
    - BUG/MINOR: lua: Properly catch alloc errors when parsing lua filter directives
    - BUG/MEDIUM: cfgcheck: verify existing log-forward listeners during config check
    - MINOR: cli: delare the CLI frontend as an internal proxy
    - MINOR: proxy: disable warnings for internal proxies
    - BUG/MINOR: filters: Always set FLT_END analyser when CF_FLT_ANALYZE flag is set
    - BUG/MINOR: lua/filters: Return right code when txn:done() is called
    - DOC: lua-api: Add documentation about lua filters
    - CI: Remove obsolete USE_SLZ=1 CI job
    - CLEANUP: assorted typo fixes in the code and comments
    - CI: github actions: relax OpenSSL-3.0.0 version comparision
    - BUILD: tools: get the absolute path of the current binary on NetBSD.
    - DOC: Minor typo fix - 'question mark' -> 'exclamation mark'
    - DOC/MINOR: fix typo in management document
    - MINOR: http: add a new function http_validate_scheme() to validate a scheme
    - BUG/MAJOR: h2: verify early that non-http/https schemes match the valid syntax
    - BUG/MAJOR: h2: verify that :path starts with a '/' before concatenating it
    - BUG/MAJOR: h2: enforce stricter syntax checks on the :method pseudo-header
    - BUG/MEDIUM: h2: give :authority precedence over Host
    - REGTESTS: add a test to prevent h2 desync attacks

3 years agoREGTESTS: add a test to prevent h2 desync attacks
Amaury Denoyelle [Fri, 13 Aug 2021 07:43:24 +0000 (09:43 +0200)] 
REGTESTS: add a test to prevent h2 desync attacks

This test ensure that h2 pseudo headers are properly checked for invalid
characters and the host header is ignored if :authority is present. This
is necessary to prevent h2 desync attacks as described here
https://portswigger.net/research/http2

3 years agoBUG/MEDIUM: h2: give :authority precedence over Host
Willy Tarreau [Wed, 11 Aug 2021 13:39:13 +0000 (15:39 +0200)] 
BUG/MEDIUM: h2: give :authority precedence over Host

The wording regarding Host vs :authority in RFC7540 is ambiguous as it
says that an intermediary must produce a host header from :authority if
Host is missing, but, contrary to HTTP/1.1, doesn't say anything regarding
the possibility that Host and :authority differ, which leaves Host with
higher precedence there. In addition it mentions that clients should use
:authority *instead* of Host, and that H1->H2 should use :authority only
if the original request was in authority form. This leaves some gray
area in the middle of the chain for fully valid H2 requests arboring a
Host header that are forwarded to the other side where it's possible to
drop the Host header and use the authority only after forwarding to a
second H2 layer, thus possibly seeing two different values of Host at
a different stage. There's no such issue when forwarding from H2 to H1
as the authority is dropped only only the Host is kept.

Note that the following request is sufficient to re-normalize such a
request:

   http-request set-header host %[req.hdr(host)]

The new spec in progress (draft-ietf-httpbis-http2bis-03) addresses
this trouble by being a bit is stricter on these rules. It clarifies
that :authority must always be used instead of Host and that Host ought
to be ignored. This is much saner as it avoids to convey two distinct
values along the chain. This becomes the protocol-level equivalent of:

   http-request set-uri %[url]

So this patch does exactly this, which we were initially a bit reluctant
to do initially by lack of visibility about other implementations'
expectations. In addition it slightly simplifies the Host header field
creation by always placing it first in the list of headers instead of
last; this could also speed up the look up a little bit.

This needs to be backported to 2.0. Non-HTX versions are safe regarding
this because they drop the URI during the conversion to HTTP/1.1 so
only Host is used and transmitted.

Thanks to Tim Düsterhus for reporting that one.

3 years agoBUG/MAJOR: h2: enforce stricter syntax checks on the :method pseudo-header
Willy Tarreau [Wed, 11 Aug 2021 09:12:46 +0000 (11:12 +0200)] 
BUG/MAJOR: h2: enforce stricter syntax checks on the :method pseudo-header

Before HTX was introduced, all the HTTP request elements passed in
pseudo-headers fields were used to build an HTTP/1 request whose syntax
was then scrutinized by the HTTP/1 parser, leaving no room to inject
invalid characters.

While NUL, CR and LF are properly blocked, it is possible to inject
spaces in the method so that once translated to HTTP/1, fields are
shifted by one spcae, and a lenient HTTP/1 server could possibly be
fooled into using a part of the method as the URI. For example, the
following request:

   H2 request
     :method: "GET /admin? HTTP/1.1"
     :path:   "/static/images"

would become:

   GET /admin? HTTP/1.1 /static/images HTTP/1.1

It's important to note that the resulting request is *not* valid, and
that in order for this to be a problem, it requires that this request
is delivered to an already vulnerable HTTP/1 server.

A workaround here is to reject malformed methods by placing this rule
in the frontend or backend, at least before leaving haproxy in H1:

   http-request reject if { method -m reg [^A-Z0-9] }

Alternately H2 may be globally disabled by commenting out the "alpn"
directive on "bind" lines, and by rejecting H2 streams creation by
adding the following statement to the global section:

   tune.h2.max-concurrent-streams 0

This patch adds a check for each character of the method to make sure
they belong to the ones permitted in a token, as mentioned in RFC7231#4.1.

This should be backported to versions 2.0 and above. For older versions
not having HTX_FL_PARSING_ERROR, a "goto fail" works as well as it
results in a protocol error at the stream level. Non-HTX versions are
safe because the resulting invalid request will be rejected by the
internal HTTP/1 parser.

Thanks to Tim Düsterhus for reporting that one.

3 years agoBUG/MAJOR: h2: verify that :path starts with a '/' before concatenating it
Willy Tarreau [Tue, 10 Aug 2021 14:30:55 +0000 (16:30 +0200)] 
BUG/MAJOR: h2: verify that :path starts with a '/' before concatenating it

Tim Düsterhus found that while the H2 path is checked for non-emptiness,
invalid chars and '*', a test is missing to verify that except for '*',
it always starts with exactly one '/'. During the reconstruction of the
full URI when passing to HTX, this missing test allows to affect the
apparent authority by appending a port number or a suffix name.

This only affects H2-to-H2 communications, as H2-to-H1 do not use the
full URI. Like for previous fix, the following rule inserted before
other ones in the frontend is sufficient to renormalize the internal
URI and let haproxy see the same authority as the target server:

    http-request set-uri %[url]

This needs to be backported to 2.2. Earlier versions do not rebuild a
full URI using the authority and will fail on the malformed path at the
HTTP layer, so they are safe.

3 years agoBUG/MAJOR: h2: verify early that non-http/https schemes match the valid syntax
Willy Tarreau [Tue, 10 Aug 2021 13:37:34 +0000 (15:37 +0200)] 
BUG/MAJOR: h2: verify early that non-http/https schemes match the valid syntax

While we do explicitly check for strict character sets in the scheme,
this is only done when extracting URL components from an assembled one,
and we have special handling for "http" and "https" schemes directly in
the H2-to-HTX conversion. Sadly, this lets all other ones pass through
if they start exactly with "http://" or "https://", allowing the
reconstructed URI to start with a different looking authority if it was
part of the scheme.

It's interesting to note that in this case the valid authority is in
the Host header and that the request will only be wrong if emitted over
H2 on the backend side, since H1 will not emit an absolute URI by
default and will drop the scheme. So in essence, this is a variant of
the scheme-based attack described below in that it only affects H2-H2
and not H2-H1 forwarding:

   https://portswigger.net/research/http2

As such, a simple workaround consists in just inserting the following
rule before other ones in the frontend, which will have for effect to
renormalize the authority in the request line according to the
concatenated version (making haproxy see the same authority and host
as what the target server will see):

   http-request set-uri %[url]

This patch simply adds the missing syntax checks for non-http/https
schemes before the concatenation in the H2 code. An improvement may
consist in the future in splitting these ones apart in the start
line so that only the "url" sample fetch function requires to access
them together and that all other places continue to access them
separately. This will then allow the core code to perform such checks
itself.

The patch needs to be backported as far as 2.2. Before 2.2 the full
URI was not being reconstructed so the scheme and authority part were
always dropped from H2 requests to leave only origin requests. Note
for backporters: this depends on this previous patch:

  MINOR: http: add a new function http_validate_scheme() to validate a scheme

Many thanks to Tim Düsterhus for figuring that one and providing a
reproducer.

3 years agoMINOR: http: add a new function http_validate_scheme() to validate a scheme
Willy Tarreau [Tue, 10 Aug 2021 13:35:36 +0000 (15:35 +0200)] 
MINOR: http: add a new function http_validate_scheme() to validate a scheme

While http_parse_scheme() extracts a scheme from a URI by extracting
exactly the valid characters and stopping on delimiters, this new
function performs the same on a fixed-size string.

3 years agoDOC/MINOR: fix typo in management document
Jonathon Lacher [Wed, 4 Aug 2021 05:29:05 +0000 (00:29 -0500)] 
DOC/MINOR: fix typo in management document

s/Not/Note.

3 years agoDOC: Minor typo fix - 'question mark' -> 'exclamation mark'
Kunal Gangakhedkar [Tue, 17 Aug 2021 06:25:45 +0000 (11:55 +0530)] 
DOC: Minor typo fix - 'question mark' -> 'exclamation mark'

Signed-off-by: Kunal Gangakhedkar <kunal.gangakhedkar@gmail.com>
3 years agoBUILD: tools: get the absolute path of the current binary on NetBSD.
David Carlier [Tue, 17 Aug 2021 07:44:25 +0000 (08:44 +0100)] 
BUILD: tools: get the absolute path of the current binary on NetBSD.

NetBSD stores the absolute path into the auxiliary vector as well.

3 years agoCI: github actions: relax OpenSSL-3.0.0 version comparision
Ilya Shipitsin [Sun, 15 Aug 2021 07:55:08 +0000 (12:55 +0500)] 
CI: github actions: relax OpenSSL-3.0.0 version comparision

we better to check for 3.0.0 presense, than exact version

3 years agoCLEANUP: assorted typo fixes in the code and comments
Ilya Shipitsin [Sat, 7 Aug 2021 09:41:56 +0000 (14:41 +0500)] 
CLEANUP: assorted typo fixes in the code and comments

This is 25th iteration of typo fixes

3 years agoCI: Remove obsolete USE_SLZ=1 CI job
Tim Duesterhus [Sat, 14 Aug 2021 12:36:55 +0000 (14:36 +0200)] 
CI: Remove obsolete USE_SLZ=1 CI job

Using SLZ is a default, thus this build is equivalent to the "no features"
build.

3 years agoDOC: lua-api: Add documentation about lua filters
Christopher Faulet [Sun, 15 Aug 2021 18:35:25 +0000 (20:35 +0200)] 
DOC: lua-api: Add documentation about lua filters

Lua filter support is highly experimental. The documentation was added to
allow first lua filter implementations. The API is not stabilized and must
be improved to be fully usable. This docuementation is quite light for
now. But more will be added.

3 years agoBUG/MINOR: lua/filters: Return right code when txn:done() is called
Christopher Faulet [Fri, 13 Aug 2021 12:11:17 +0000 (14:11 +0200)] 
BUG/MINOR: lua/filters: Return right code when txn:done() is called

txn functions can now be called from an action or a filter context. Thus the
return code must be adapted depending on this context. From an action, act.ABORT
is returned. From a filter, -1 is returned. It is the filter error code.

This bug only affects 2.5-dev. No backport needed.

3 years agoBUG/MINOR: filters: Always set FLT_END analyser when CF_FLT_ANALYZE flag is set
Christopher Faulet [Fri, 13 Aug 2021 12:00:46 +0000 (14:00 +0200)] 
BUG/MINOR: filters: Always set FLT_END analyser when CF_FLT_ANALYZE flag is set

CF_FLT_ANALYZE flags may be set before the FLT_END analyser. Thus if an error is
triggered in the mean time, this may block the stream and prevent it to be
released. It is indeed a problem only for the response channel because the
response analysers may be skipped on early errors.

So, to prevent any issue, depending on the code path, the FLT_END analyser is
systematically set when the CF_FLT_ANALYZE flag is set.

This patch must be backported in all stable branches.

3 years agoMINOR: proxy: disable warnings for internal proxies
William Lallemand [Fri, 13 Aug 2021 13:21:12 +0000 (15:21 +0200)] 
MINOR: proxy: disable warnings for internal proxies

The internal proxies should be part of the proxies list, because of
this, the check_config_validity() fonction could emit warnings about
these proxies.

This patch disables 3 startup warnings for internal proxies:

- "has no 'bind' directive" (this one was already ignored for the CLI
frontend, but we made it generic instead)
- "missing timeouts"
- "log format ignored"

3 years agoMINOR: cli: delare the CLI frontend as an internal proxy
William Lallemand [Fri, 13 Aug 2021 13:31:33 +0000 (15:31 +0200)] 
MINOR: cli: delare the CLI frontend as an internal proxy

Declare the CLI frontend as an internal proxy so we can check the
PR_CAP_INT flag instead of the global.fe_cli pointer for generic use
cases.

3 years agoBUG/MEDIUM: cfgcheck: verify existing log-forward listeners during config check
Emeric Brun [Fri, 13 Aug 2021 07:32:50 +0000 (09:32 +0200)] 
BUG/MEDIUM: cfgcheck: verify existing log-forward listeners during config check

User reported that the config check returns an error with the message:
"Configuration file has no error but will not start (no listener) => exit(2)."
if the configuration present only a log-forward section with bind or dgram-bind
listeners but no listen/backend nor peer sections.

The process checked if there was 'peers' section avalaible with
an internal frontend (and so a listener) or a 'listen/backend'
section not disabled with at least one configured listener (into the
global proxies_list). Since the log-forward proxies appear in a
different list, they were not checked.

This patch adds a lookup on the 'log-forward' proxies list to check
if one of them presents a listener and is not disabled. And
this is done only if there was no available listener found into
'listen/backend' sections.

I have also studied how to re-work this check considering the 'listeners'
counter used after startup/init to keep the same algo and avoid further
mistakes but currently this counter seems increased during config parsing
and if a proxy is disabled, decreased during startup/init which is done
after the current config check. So the fix still not rely on this
counter.

This patch should fix the github issue #1346

This patch should be backported as far as 2.3 (so on branches
including the "log-forward" feature)

3 years agoBUG/MINOR: lua: Properly catch alloc errors when parsing lua filter directives
Christopher Faulet [Fri, 13 Aug 2021 06:33:57 +0000 (08:33 +0200)] 
BUG/MINOR: lua: Properly catch alloc errors when parsing lua filter directives

When a lua filter declaration is parsed, some allocation errors were not
properly handled. In addition, we must be sure the filter identifier is defined
in lua to duplicate it when the filter configuration is filled.

This patch fix a defect reported in the issue #1347. It only concerns
2.5-dev. No backport needed.

3 years agoBUG/MINOR: lua: Properly check negative offset in Channel/HttpMessage functions
Christopher Faulet [Fri, 13 Aug 2021 06:11:00 +0000 (08:11 +0200)] 
BUG/MINOR: lua: Properly check negative offset in Channel/HttpMessage functions

In Channel and HTTPMessage classes, several functions uses an offset that
may be negative to start from the end of incoming data. But, after
calculation, the offset must never be negative. However, there is a bug
because of a bad cast to unsigned when "input + offset" is performed. The
result must be a signed integer.

This patch should fix most of defects reported in the issue #1347. It only
affects 2.5-dev. No backport needed.

3 years agoDOC: config: Fix 'http-response send-spoe-group' documentation
Christopher Faulet [Thu, 12 Aug 2021 07:32:07 +0000 (09:32 +0200)] 
DOC: config: Fix 'http-response send-spoe-group' documentation

Arguments were missing in the rule heading. This patch may be backported as
far as 2.0.

3 years agoMINOR: filters/lua: Support the HTTP filtering from filters written in lua
Christopher Faulet [Wed, 26 Feb 2020 16:15:48 +0000 (17:15 +0100)] 
MINOR: filters/lua: Support the HTTP filtering from filters written in lua

Now an HTTPMessage class is available to manipulate HTTP message from a filter
it is possible to bind HTTP filters callback function on lua functions. Thus,
following methods may now be defined by a lua filter:

  * Filter:http_headers(txn, http_msg)
  * Filter:http_payload(txn, http_msg, offset, len)
  * Filter:http_end(txn, http_msg)

http_headers() and http_end() may return one of the constant filter.CONTINUE,
filter.WAIT or filter.ERROR. If nothing is returned, filter.CONTINUE is used as
the default value. On its side, http_payload() may return the amount of data to
forward. If nothing is returned, all incoming data are forwarded.

For now, these functions are not allowed to yield because this interferes with
the filter workflow.

3 years agoMINOR: filters/lua: Add request and response HTTP messages in the lua TXN
Christopher Faulet [Wed, 26 Feb 2020 16:14:08 +0000 (17:14 +0100)] 
MINOR: filters/lua: Add request and response HTTP messages in the lua TXN

When a lua TXN is created from a filter context, the request and the response
HTTP message objects are accessible from ".http_req" and ".http_res" fields. For
an HTTP proxy, these objects are always defined. Otherwise, for a TCP proxy, no
object is created and nil is used instead. From any other context (action or
sample fetch), these fields don't exist.

3 years agoMEDIUM: filters/lua: Add HTTPMessage class to help HTTP filtering
Christopher Faulet [Wed, 26 Feb 2020 15:57:19 +0000 (16:57 +0100)] 
MEDIUM: filters/lua: Add HTTPMessage class to help HTTP filtering

This new class exposes methods to manipulate HTTP messages from a filter
written in lua. Like for the HTTP class, there is a bunch of methods to
manipulate the message headers. But there are also methods to manipulate the
message payload. This part is similar to what is available in the Channel
class. Thus the payload can be duplicated, erased, modified or
forwarded. For now, only DATA blocks can be retrieved and modified because
the current API is limited. No HTTPMessage method is able to yield. Those
manipulating the headers are always called on messages containing all the
headers, so there is no reason to yield. Those manipulating the payload are
called from the http_payload filters callback function where yielding is
forbidden.

When an HTTPMessage object is instantiated, the underlying Channel object
can be retrieved via the ".channel" field.

For now this class is not used because the HTTP filtering is not supported
yet. It will be the purpose of another commit.

There is no documentation for now.

3 years agoMEDIUM: filters/lua: Support declaration of some filter callback functions in lua
Christopher Faulet [Wed, 26 Feb 2020 14:03:09 +0000 (15:03 +0100)] 
MEDIUM: filters/lua: Support declaration of some filter callback functions in lua

It is now possible to write some filter callback functions in lua. All
filter callbacks are not supported yet but the mechanism to call them is now
in place. Following method may be defined in the Lua filter class to be
bound on filter callbacks:

  * Filter:start_analyse(txn, chn)
  * Filter:end_analyse(txn, chn)
  * Filter:tcp_payload(txn, chn, offset, length)

hlua_filter_callback() function is responsible to call the good lua function
depending on the filter callback function. Using some flags it is possible
to allow a lua call to yield or not, to retrieve a return value or not, and
to specify if a channel or an http message must be passed as second
argument. For now, the HTTP part has not been added yet. It is also possible
to add extra argument adding them on the stack before the call.

3 new functions are exposed by the global object "filter". The first one,
filter.wake_time(ms_delay), to set the wake_time when a Lua callback
function yields (if allowed). The two others,
filter.register_data_filter(filter, chn) and
filter.unregister_data_filter(filter, chn), to enable or disable the data
filtering on a channel for a specific lua filter instance.

start_analyse() and end_analyse() may return one of the constant
filter.CONTINUE, filter.WAIT or filter.ERROR. If nothing is returned,
filter.CONTINUE is used as the default value. On its side, tcp_payload() may
return the amount of data to forward. If nothing is returned, all incoming
data are forwarded.

For now, these functions are not allowed to yield because this interferes
with the filter workflow.

Here is a simple example :

    MyFilter = {}
    MyFilter.id = "My Lua filter"
    MyFilter.flags = filter.FLT_CFG_FL_HTX
    MyFilter.__index = MyFilter

    function MyFilter:new()
        flt = {}
        setmetatable(flt, MyFilter)
        flt.req_len = 0
        flt.res_len = 0
        return flt
     end

    function MyFilter:start_analyze(txn, chn)
        filter.register_data_filter(self, chn)
    end

    function MyFilter:end_analyze(txn, chn)
        print("<Total> request: "..self.req_len.." - response: "..self.res_len)
    end

    function MyFilter:tcp_payload(txn, chn)
        offset = chn:ouput()
len    = chn:input()
        if chn:is_resp() then
            self.res_len = self.res_len + len
            print("<TCP:Response> offset: "..offset.." - length: "..len)
        else
            self.req_len = self.req_len + len
            print("<TCP:Request> offset: "..offset.." - length: "..len)
        end
    end

3 years agoMEDIUM: filters/lua: Be prepared to filter TCP payloads
Christopher Faulet [Mon, 9 Aug 2021 08:22:46 +0000 (10:22 +0200)] 
MEDIUM: filters/lua: Be prepared to filter TCP payloads

For filters written in lua, the tcp payloads will be filtered using methods
exposed by the Channel class. So the corrsponding C binding functions must
be prepared to process payload in a filter context and not only in an action
context.

The main change is the offset where to start to process data in the channel
buffer, and the length of these data. For an action, all input data are
considered. But for a filter, it depends on what the filter is allow to
forward when the tcp_payload callback function is called. It depends on
previous calls but also on other filters.

In addition, when the payload is modified by a lua filter, its context must
be updated. Note also that channel functions cannot yield when called from a
filter context.

For now, it is not possible to define callbacks to filter data and the
documentation has not been updated.