]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
4 years agoBUILD: trace: always have an argument before variadic args in macros
Willy Tarreau [Thu, 10 Sep 2020 07:35:54 +0000 (09:35 +0200)] 
BUILD: trace: always have an argument before variadic args in macros

tcc supports variadic macros provided that there is always at least one
argument, like older gcc versions. Thus we need to always keep one and
define args as the remaining ones. It's not an issue at all and doesn't
change the way to use them, just the internal definitions.

4 years agoBUILD: intops: on x86_64, the bswap instruction is called bswapq
Willy Tarreau [Thu, 10 Sep 2020 07:31:50 +0000 (09:31 +0200)] 
BUILD: intops: on x86_64, the bswap instruction is called bswapq

Building with tcc fails on "bswap" which in fact ought to be called
"bswapq". Let's rename it as gas doesn't care.

4 years agoBUILD: compiler: workaround a glibc madness around __attribute__()
Willy Tarreau [Thu, 10 Sep 2020 07:26:50 +0000 (09:26 +0200)] 
BUILD: compiler: workaround a glibc madness around __attribute__()

For whatever reason, glibc decided that the __attribute__ keyword is
the exclusive property of gcc, and redefines it to an empty macro on
other compilers. Some non-gcc compilers also support it (possibly
partially), tinycc is one of them. By doing this, glibc silently
broke all constructors, resulting in code that arrives in main() with
uninitialized variables.

The solution we use here consists in undefining the macro on non-gcc
compilers, and redefining it to itself in order to cause a conflict in
the event the redefinition would happen afterwards. This visibly solved
the problem.

4 years agoBUILD: compiler: reserve the gcc version checks to the gcc compiler
Willy Tarreau [Thu, 10 Sep 2020 06:33:01 +0000 (08:33 +0200)] 
BUILD: compiler: reserve the gcc version checks to the gcc compiler

Some checks on __GNUC__ imply that if it's undefined it will match a
low value but that's not always what we want, like for example in the
VAR_ARRAY definition which is not needed on tcc. Let's always be explicit
on these tests.

4 years agoBUILD: threads: better workaround for late loading of libgcc_s
Willy Tarreau [Wed, 9 Sep 2020 15:07:54 +0000 (17:07 +0200)] 
BUILD: threads: better workaround for late loading of libgcc_s

Commit 77b98220e ("BUG/MINOR: threads: work around a libgcc_s issue with
chrooting") tried to address an issue with libgcc_s being loaded too late.
But it turns out that the symbol used there isn't present on armhf, thus
it breaks the build.

Given that the issue manifests itself during pthread_exit(), the safest
and most portable way to test this is to call pthread_exit(). For this
we create a dummy thread which exits, during the early boot. This results
in the relevant library to be loaded if needed, making sure that a later
call to pthread_exit() will still work. It was tested to work fine under
linux on the following platforms:

 glibc:
   - armhf
   - aarch64
   - x86_64
   - sparc64
   - ppc64le

 musl:
   - mipsel

Just running the code under strace easily shows the call in the dummy
thread, for example here on armhf:

  $ strace -fe trace=file ./haproxy -v 2>&1 | grep gcc_s
  [pid 23055] open("/lib/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3

The code was isolated so that it's easy to #ifdef it out if needed.
This should be backported where the patch above is backported (likely
2.0).

4 years agoBUG/MEDIUM: mux-h1: always apply the timeout on half-closed connections
Willy Tarreau [Tue, 8 Sep 2020 13:40:57 +0000 (15:40 +0200)] 
BUG/MEDIUM: mux-h1: always apply the timeout on half-closed connections

The condition in h1_refresh_timeout() seems insufficient to properly
take care of the half-closed timeout, because depending on the ordering
of operations when performing the last send() to a client, the stream
may or may not still be there and we may fail to shrink the client
timeout on our last opportunity to do so.

Here we want to make sure that the timeout is always reduced when the
last chunk was sent and the shutdown completed, regardless of the
presence of a stream or not. This is what this patch does.

This should be backported as far as 2.0, and should fix the issue
reported in #541.

4 years agoBUG/MINOR: auth: report valid crypto(3) support depending on build options
Victor Kislov [Thu, 6 Aug 2020 16:21:39 +0000 (19:21 +0300)] 
BUG/MINOR: auth: report valid crypto(3) support depending on build options

Since 1.8 with commit e8692b41e ("CLEANUP: auth: use the build options list
to report its support"), crypt(3) is always reported as being supported in
"haproxy -vv" because no test on USE_LIBCRYPT is made anymore when
producing the output.

This reintroduces the distinction between with and without USE_LIBCRYPT
in the output by indicating "yes" or "no". It may be backported as far
as 1.8, though the code differs due to a number of include files cleanups.

4 years agoDOC: ssl-load-extra-files only applies to certificates on bind lines
Jerome Magnin [Mon, 7 Sep 2020 09:55:57 +0000 (11:55 +0200)] 
DOC: ssl-load-extra-files only applies to certificates on bind lines

Be explicit about ssl-load-extra-files not applying to certificates
referenced with the crt keyword on server lines.

It must be backported in 2.2.

4 years agoMINOR: server: Improve log message sent when server address is updated
Christopher Faulet [Tue, 8 Sep 2020 08:38:40 +0000 (10:38 +0200)] 
MINOR: server: Improve log message sent when server address is updated

When the server address is set for the first time, the log message is a bit ugly
because there is no old ip address to report. Thus in the log, we can see :

  PX/SRV changed its IP from  to A.B.C.D by DNS additional record.

Now, when this happens, "(none)" is reported :

  PX/SRV changed its IP from (none) to A.B.C.D by DNS additional record.

This patch may be backported to 2.2.

4 years agoBUG/MEDIUM: dns: Be sure to renew IP address for already known servers
Christopher Faulet [Tue, 8 Sep 2020 08:27:24 +0000 (10:27 +0200)] 
BUG/MEDIUM: dns: Be sure to renew IP address for already known servers

When a SRV record for an already known server is processed, only the weight is
updated, if not configured to be ignored. It is a problem if the IP address
carried by the associated additional record changes. Because the server IP
address is never renewed.

To fix this bug, If there is an addition record attached to a SRV record, we
always try to set the IP address. If it is the same, no change is
performed. This way, IP changes are always handled.

This patch should fix the issue #841. It must be backported to 2.2.

4 years agoBUG/MEDIUM: dns: Don't store additional records in a linked-list
Christopher Faulet [Tue, 8 Sep 2020 08:06:01 +0000 (10:06 +0200)] 
BUG/MEDIUM: dns: Don't store additional records in a linked-list

A SRV record keeps a reference on the corresponding additional record, if
any. But this additional record is also inserted in a separate linked-list into
the dns response. The problems arise when obsolete additional records are
released. The additional records list is purged but the SRV records always
reference these objects, leading to an undefined behavior. Worst, this happens
very quickly because additional records are never renewed. Thus, once received,
an additional record will always expire.

Now, the addtional record are only associated to a SRV record or simply
ignored. And the last version is always used.

This patch helps to fix the issue #841. It must be backported to 2.2.

4 years agoCLEANUP: Update .gitignore
Tim Duesterhus [Sun, 6 Sep 2020 16:34:12 +0000 (18:34 +0200)] 
CLEANUP: Update .gitignore

This excludes the currently tracked files from being ignored.

4 years agoMINOR: Commit .gitattributes
Tim Duesterhus [Sat, 5 Sep 2020 10:46:11 +0000 (12:46 +0200)] 
MINOR: Commit .gitattributes

Commit .gitattributes to the repository to allow GitHub downloads to
properly fill in the SUBVERS and VERDATE files. It also prevents the
engineer in charge of the release to forget creating it when a new branch
is released.

see https://www.mail-archive.com/haproxy@formilux.org/msg38107.html

No functional change, may be backported everywhere.

4 years agoREGTEST: Add a test for request path manipulations, with and without the QS
Christopher Faulet [Thu, 3 Sep 2020 09:53:50 +0000 (11:53 +0200)] 
REGTEST: Add a test for request path manipulations, with and without the QS

This new script tests set-path/replace-path and set-pathq/replace-pathq
rules. It also tests path and pathq sample fetches.

This patch should be backported to 2.2 if corresponding keywords are also
backported.

4 years agoMINOR: http-fetch: Add pathq sample fetch
Christopher Faulet [Wed, 2 Sep 2020 15:25:18 +0000 (17:25 +0200)] 
MINOR: http-fetch: Add pathq sample fetch

The pathq sample fetch extract the relative URI of a request, i.e the path with
the query-string, excluding the scheme and the authority, if any. It is pretty
handy to always get a relative URI independently on the HTTP version. Indeed,
while relative URIs are common in HTTP/1.1, in HTTP/2, most of time clients use
absolute URIs.

This patch may be backported to 2.2.

4 years agoMINOR: http-rules: Add set-pathq and replace-pathq actions
Christopher Faulet [Wed, 2 Sep 2020 15:17:44 +0000 (17:17 +0200)] 
MINOR: http-rules: Add set-pathq and replace-pathq actions

These actions do the same as corresponding "-path" versions except the
query-string is included to the manipulated request path. This means set-pathq
action replaces the path and the query-string and replace-pathq action matches
and replace the path including the query-string.

This patch may be backported to 2.2.

4 years agoBUG/MEDIUM: doc: Fix replace-path action description
Christopher Faulet [Wed, 2 Sep 2020 12:16:59 +0000 (14:16 +0200)] 
BUG/MEDIUM: doc: Fix replace-path action description

The description of the replace-path action does not reflect what the code
do. When the request path is replaced, the query-string is preserved. But the
documentation stated the query-string is part of the replacement, if any is
present. Most of time, when the doc and the code differ, the code is fixed. But
here, the replace-path action is pretty confusing because the set-path action is
only applied on the path. The query-string is left intact. And the path sample
fetch also ignores the query-string. In addition, the replace-path action is
quite recent. It was added in the 2.2. Thus, exceptionally, the documentation is
fixed instead.

Note that set-pathq and replace-pathq actions and pathq sample fetch will be
added to manipulate the path with the query-string.

This patch must be backported as far as 2.0.

4 years agoRevert "BUG/MINOR: http-rules: Replace path and query-string in "replace-path" action"
Christopher Faulet [Wed, 2 Sep 2020 09:10:38 +0000 (11:10 +0200)] 
Revert "BUG/MINOR: http-rules: Replace path and query-string in "replace-path" action"

This reverts commit 4b9c0d1fc08388bf44c6ebbd88f786032dd010fc.

Actually, the "replace-path" action is ambiguous. "set-path" action preserves
the query-string. The "path" sample fetch does not contain the query-string. But
"replace-path" action is documented to handle the query-string. It is probably
not the expected behavior. So instead of fixing the code, we will fix the
documentation to make "replace-path" action consistent with other parts of the
code. In addition actions and sample fetches to handle the path with the
query-string will be added.

If the commit above is ever backported, this one must be as well.

4 years agoBUG/MINOR: startup: haproxy -s cause 100% cpu
William Lallemand [Wed, 2 Sep 2020 14:12:23 +0000 (16:12 +0200)] 
BUG/MINOR: startup: haproxy -s cause 100% cpu

It was reported in bug #837 that haproxy -s causes a 100% CPU.

However this option does not exist and haproxy must exit with the
usage message.

The parser was not handling the case where -s is not followed by 't' or
'f' which are the only two valid cases.

This bug was introduced by df6c5a ("BUG/MEDIUM: mworker: fix the copy of
options in copy_argv()") which was backported as far as 1.8.

This fix must be backported as far as 1.8.

4 years agoMAJOR: init: start all listeners via protocols and not via proxies anymore
Willy Tarreau [Wed, 2 Sep 2020 09:11:43 +0000 (11:11 +0200)] 
MAJOR: init: start all listeners via protocols and not via proxies anymore

Ever since the protocols were added in 1.3.13, listeners used to be
started twice:
  - once by start_proxies(), which iteratees over all proxies then all
    listeners ;
  - once by protocol_bind_all() which iterates over all protocols then
    all listeners ;

It's a real mess because error reporting is not even consistent, and
more importantly now that some protocols do not appear in regular
proxies (peers, logs), there is no way to retry their binding should
it fail on the last step.

What this patch does is to make sure that listeners are exclusively
started by protocols. The failure to start a listener now causes the
emission of an error indicating the proxy's name (as it used to be
the case per proxy), and retryable failures are silently ignored
during all but last attempts.

The start_proxies() function was kept solely for setting the proxy's
state to READY and emitting the "Proxy started" message and log that
some have likely got used to seeking in their logs.

4 years agoCLEANUP: protocol: remove all ->bind_all() and ->unbind_all() functions
Willy Tarreau [Tue, 1 Sep 2020 16:54:13 +0000 (18:54 +0200)] 
CLEANUP: protocol: remove all ->bind_all() and ->unbind_all() functions

These ones were not used anymore since the two previous patches, let's
drop them.

4 years agoMINOR: protocol: do not call proto->unbind_all() anymore
Willy Tarreau [Wed, 2 Sep 2020 08:31:31 +0000 (10:31 +0200)] 
MINOR: protocol: do not call proto->unbind_all() anymore

Similarly to previous commit about ->bind_all(), we have the same
construct for ->unbind_all() which ought not to be used either. Let's
make protocol_unbind_all() iterate over all listeners and directly
call unbind_listener() instead.

It's worth noting that for uxst there was originally a specific
->unbind_all() function but the simplifications that came over the
years have resulted in a locally reimplemented version of the same
function: the test on (state > LI_ASSIGNED) there is equivalent to
the one on (state >= LI_PAUSED) that is used in do_unbind_listener(),
and it seems these have been equivalent since at least commit dabf2e264
("[MAJOR] added a new state to listeners")) (1.3.14).

4 years agoMINOR: protocol: do not call proto->bind_all() anymore
Willy Tarreau [Tue, 1 Sep 2020 16:48:35 +0000 (18:48 +0200)] 
MINOR: protocol: do not call proto->bind_all() anymore

All protocols only iterate over their own listeners list and start
the listeners using a direct call to their ->bind() function. This
code duplication doesn't make sense and prevents us from centralizing
the startup error handling. Worse, it's not even symmetric because
there's an unbind_all_listeners() function common to all protocols
without any equivalent for binding. Let's start by directly calling
each protocol's bind() function from protocol_bind_all().

4 years agoBUILD: thread: limit the libgcc_s workaround to glibc only
Willy Tarreau [Wed, 2 Sep 2020 07:53:47 +0000 (09:53 +0200)] 
BUILD: thread: limit the libgcc_s workaround to glibc only

Previous commit 77b98220e ("BUG/MINOR: threads: work around a libgcc_s
issue with chrooting") broke the build on cygwin. I didn't even know we
supported threads on cygwin. But the point is that it's actually the
glibc-based libpthread which requires libgcc_s, so in absence of other
reports we should not apply the workaround on other libraries.

This should be backported along with the aforementioned patch.

4 years agoBUG/MINOR: threads: work around a libgcc_s issue with chrooting
Willy Tarreau [Wed, 2 Sep 2020 06:04:35 +0000 (08:04 +0200)] 
BUG/MINOR: threads: work around a libgcc_s issue with chrooting

Sander Hoentjen reported another issue related to libgcc_s in issue #671.
What happens is that when the old process quits, pthread_exit() calls
something from libgcc_s.so after the process was chrooted, and this is
the first call to that library, causing an attempt to load it. In a
chroot, this fails, thus libthread aborts. The behavior widely differs
between operating systems because some decided to use a static build for
this library.

In 2.2 this was resolved as a side effect of a workaround for the same issue
with the backtrace() call, which is also in libgcc_s. This was in commit
0214b45 ("MINOR: debug: call backtrace() once upon startup"). But backtraces
are not necessarily enabled, and we need something for older versions.

By inspecting a significant number of ligcc_s on various gcc versions and
platforms, it appears that a few functions have been present since gcc 3.0,
one of which, _Unwind_Find_FDE() has no side effect (it only returns a
pointer). What this patch does is that in the thread initialization code,
if built with gcc >= 3.0, a call to this function is made in order to make
sure that libgcc_s is loaded at start up time and that there will be no
need to load it upon exit.

An easy way to check which libs are loaded under Linux is :

  $ strace -e trace=openat ./haproxy -v

With this patch applied, libgcc_s now appears during init.

Sander confirmed that this patch was enough to put an end to the core
dumps on exit in 2.0, so this patch should be backported there, and maybe
as far as 1.8.

4 years agoREGTEST: increase some short timeouts to make tests more reliable
Willy Tarreau [Wed, 2 Sep 2020 05:26:08 +0000 (07:26 +0200)] 
REGTEST: increase some short timeouts to make tests more reliable

A few regtests continue to regularly fail in highly loaded VMs because
they have very short timeouts. Actually the goal of running with short
timeouts was to make sure we do not uselessly wait during tests designed
to trigger them, but these timeouts here are never supposed to fire at
all, so they don't need to be kept in the 15-20ms range. They do not
pose any issue on any regular machine, but VMs are often suffering from
huge time jumps and cannot always produce responses in that short of a
time.

Just like with commit ce6fc25b1 ("REGTEST: increase timeouts on the
seamless-reload test"), let's raise these short timeouts to 1 second.
A few other ones remain set to 150-200ms and do not seem to cause any
issue. Some are actually expected to trigger so let's not touch them
for now.

4 years agoCLEANUP: http: silence a cppcheck warning in get_http_auth()
Willy Tarreau [Wed, 2 Sep 2020 05:08:47 +0000 (07:08 +0200)] 
CLEANUP: http: silence a cppcheck warning in get_http_auth()

In issue #777, cppcheck wrongly assumes a useless null pointer check
in the expression below while it's obvious that in a 3G/1G split on
32-bit, len can become positive if p is NULL:

     p = memchr(ctx.value.ptr, ' ', ctx.value.len);
     len = p - ctx.value.ptr;
     if (!p || len <= 0)
           return 0;

In addition, on 64 bits you never know given that len is a 32-bit signed
int thus the sign of the result in case of a null p will always be the
opposite of the 32th bit of ctx.value.ptr. Admittedly the test is ugly.

Tim proposed this fix consisting in checking for p == ctx.value.ptr
instead when checking for first character only, which Ilya confirmed is
enough to shut cppcheck up. No backport is needed.

4 years agoBUG/MEDIUM: contrib/spoa-server: Fix ipv4_address used instead of ipv6_address
Gilchrist Dadaglo [Mon, 24 Aug 2020 19:21:35 +0000 (19:21 +0000)] 
BUG/MEDIUM: contrib/spoa-server: Fix ipv4_address used instead of ipv6_address

Typo leads to checking the wrong object for memory issues

This patch must be backported as far as 2.0.

4 years agoBUG/MINOR: contrib/spoa-server: Updating references to free in case of failure
Gilchrist Dadaglo [Mon, 24 Aug 2020 19:21:34 +0000 (19:21 +0000)] 
BUG/MINOR: contrib/spoa-server: Updating references to free in case of failure

When we encounter a failure, all previously borrowed references should
be freed. Especially if the program is not failing immediately

This patch must be backported as far as 2.0.

4 years agoBUG/MINOR: contrib/spoa-server: Do not free reference to NULL
Gilchrist Dadaglo [Mon, 24 Aug 2020 19:21:33 +0000 (19:21 +0000)] 
BUG/MINOR: contrib/spoa-server: Do not free reference to NULL

As per https://docs.python.org/3/c-api/refcounting.html, Py_DECREF
should not be called on NULL objects.

This patch must be backported as far as 2.0.

4 years agoBUG/MINOR: contrib/spoa-server: Ensure ip address references are freed
Gilchrist Dadaglo [Mon, 24 Aug 2020 19:21:32 +0000 (19:21 +0000)] 
BUG/MINOR: contrib/spoa-server: Ensure ip address references are freed

IP addresses references passed in argument for ps_python are not freed after
they have been used. Leading to a small chance of mem leak if a lot of ip
addresses are passed around

This patch must be backported as far as 2.0.

4 years agoBUG/MAJOR: contrib/spoa-server: Fix unhandled python call leading to memory leak
Gilchrist Dadaglo [Mon, 24 Aug 2020 19:21:31 +0000 (19:21 +0000)] 
BUG/MAJOR: contrib/spoa-server: Fix unhandled python call leading to memory leak

The result from spoa evaluation of the user provided python code is
never passed back to the main spoa process nor freed.
Same for the keyword list passed.
This results into the elements never freed by Python as reference count
never goes down.
https://docs.python.org/3/extending/extending.html#reference-counting-in-python

This patch must be backported as far as 2.0.

4 years agoMINOR: contrib/spoa-server: allow MAX_FRAME_SIZE override
Bertrand Jacquin [Mon, 24 Aug 2020 19:21:30 +0000 (19:21 +0000)] 
MINOR: contrib/spoa-server: allow MAX_FRAME_SIZE override

MAX_FRAME_SIZE is forced to the default value of tune.bufsize, however
they don't necessarily have to be tight together.

4 years agoMINOR: http-htx: Handle an optional reason when replacing the response status
Christopher Faulet [Mon, 31 Aug 2020 14:43:34 +0000 (16:43 +0200)] 
MINOR: http-htx: Handle an optional reason when replacing the response status

When calling the http_replace_res_status() function, an optional reason may now
be set. It is ignored if it points to NULL and the original reason is
preserved. Only the response status is replaced. Otherwise both the status and
the reason are replaced.

It simplifies the API and most of time, avoids an extra call to
http_replace_res_reason().

4 years agoBUG/MINOR: http-rules: Replace path and query-string in "replace-path" action
Christopher Faulet [Mon, 31 Aug 2020 14:27:42 +0000 (16:27 +0200)] 
BUG/MINOR: http-rules: Replace path and query-string in "replace-path" action

The documentation stated the "replace-path" action replaces the path, including
the query-string if any is present. But in the code, only the path is
replaced. The query-string is preserved. So, now, instead of relying on the same
action code than "set-uri" action (1), a new action code (4) is used for
"replace-path" action. In http_req_replace_stline() function, when the action
code is 4, we call http_replace_req_path() setting the last argument (with_qs)
to 1. This way, the query-string is not skipped but included to the path to be
replaced.

This patch relies on the commit b8ce505c6 ("MINOR: http-htx: Add an option to
eval query-string when the path is replaced"). Both must be backported as far as
2.0. It should fix the issue #829.

4 years agoMINOR: http-htx: Add an option to eval query-string when the path is replaced
Christopher Faulet [Mon, 31 Aug 2020 14:11:57 +0000 (16:11 +0200)] 
MINOR: http-htx: Add an option to eval query-string when the path is replaced

The http_replace_req_path() function now takes a third argument to evaluate the
query-string as part of the path or to preserve it. If <with_qs> is set, the
query-string is replaced with the path. Otherwise, only the path is replaced.

This patch is mandatory to fix issue #829. The next commit depends on it. So be
carefull during backports.

4 years agoBUG/MEDIUM: http-ana: Don't wait to send 1xx responses received from servers
Christopher Faulet [Mon, 31 Aug 2020 09:07:07 +0000 (11:07 +0200)] 
BUG/MEDIUM: http-ana: Don't wait to send 1xx responses received from servers

When an informational response (1xx) is received, we must be sure to send it
ASAP. To do so, CF_SEND_DONTWAIT flag must be set on the response channel to
instruct the stream-interface to not set the CO_SFL_MSG_MORE flag on the
transport layer. Otherwise the response delivery may be delayed, because of the
commit 8945bb6c0 ("BUG/MEDIUM: stream-int: fix loss of CO_SFL_MSG_MORE flag in
forwarding").

Note that a previous patch (cf6898cd ["BUG/MINOR: http-ana: Don't wait to send
1xx responses generated by HAProxy"]) add this flag on 1xx responses generated
by HAProxy but not on responses coming from servers.

This patch must be backported to 2.2 and may be backported as far as 1.9, for
HTX part only. But this part has changed in the 2.2, so it may be a bit
tricky. Note it does not fix any known bug on 2.1 and below because the
CO_SFL_MSG_MORE flag is ignored by the h1 mux.

4 years agoBUILD: sock_unix: fix build issue with isdigit()
Willy Tarreau [Sat, 29 Aug 2020 04:44:37 +0000 (06:44 +0200)] 
BUILD: sock_unix: fix build issue with isdigit()

Commit 0d06df6 ("MINOR: sock: introduce sock_inet and sock_unix")
made use of isdigit() on the UNIX socket path without casting the
value to unsigned char, breaking the build on cygwin and possibly
other platforms. No backport is needed.

4 years agoMINOR: sock: distinguish dgram from stream types when retrieving old sockets
Willy Tarreau [Fri, 28 Aug 2020 17:20:23 +0000 (19:20 +0200)] 
MINOR: sock: distinguish dgram from stream types when retrieving old sockets

For now we still don't retrieve dgram sockets, but the code must be able
to distinguish them before we switch to receivers. This adds a new flag
to the xfer_sock_list indicating that a socket is of type SOCK_DGRAM. The
way to set the flag for now is by looking at the dummy address family which
equals AF_CUST_UDP{4,6} in this case (given that other dgram sockets are not
yet supported).

4 years agoMINOR: sock: do not use LI_O_* in xfer_sock_list anymore
Willy Tarreau [Fri, 28 Aug 2020 17:09:19 +0000 (19:09 +0200)] 
MINOR: sock: do not use LI_O_* in xfer_sock_list anymore

We'll want to store more info there and some info that are not represented
in listener options at the moment (such as dgram vs stream) so let's get
rid of these and instead use a new set of options (SOCK_XFER_OPT_*).

4 years agoREORG: sock: move get_old_sockets() from haproxy.c
Willy Tarreau [Fri, 28 Aug 2020 16:42:45 +0000 (18:42 +0200)] 
REORG: sock: move get_old_sockets() from haproxy.c

The new function was called sock_get_old_sockets() and was left as-is
except a minimum amount of style lifting to make it more readable. It
will never be awesome anyway since it's used very early in the boot
sequence and needs to perform socket I/O without any external help.

4 years agoMINOR: sock_inet: move the IPv4/v6 transparent mode code to sock_inet
Willy Tarreau [Fri, 28 Aug 2020 15:23:40 +0000 (17:23 +0200)] 
MINOR: sock_inet: move the IPv4/v6 transparent mode code to sock_inet

This code was highly redundant, existing for TCP clients, TCP servers
and UDP servers. Let's move it to sock_inet where it belongs. The new
functions are sock_inet4_make_foreign() and sock_inet6_make_foreign().

4 years agoMINOR: sock: implement sock_find_compatible_fd()
Willy Tarreau [Fri, 28 Aug 2020 14:49:41 +0000 (16:49 +0200)] 
MINOR: sock: implement sock_find_compatible_fd()

This is essentially a merge from tcp_find_compatible_fd() and
uxst_find_compatible_fd() that relies on a listener's address and
compare function and still checks for other variations. For AF_INET6
it compares a few of the listener's bind options. A minor change for
UNIX sockets is that transparent mode, interface and namespace used
to be ignored when trying to pick a previous socket while now if they
are changed, the socket will not be reused. This could be refined but
it's still better this way as there is no more risk of using a
differently bound socket by accident.

Eventually we should not pass a listener there but a set of binding
parameters (address, interface, namespace etc...) which ultimately will
be grouped into a receiver. For now this still doesn't exist so let's
stick to the listener to break dependencies in the rest of the code.

4 years agoMINOR: sock: add interface and namespace length to xfer_sock_list
Willy Tarreau [Fri, 28 Aug 2020 14:35:06 +0000 (16:35 +0200)] 
MINOR: sock: add interface and namespace length to xfer_sock_list

This will ease and speed up comparisons in FD lookups.

4 years agoREORG: listener: move xfer_sock_list to sock.{c,h}.
Willy Tarreau [Fri, 28 Aug 2020 14:29:53 +0000 (16:29 +0200)] 
REORG: listener: move xfer_sock_list to sock.{c,h}.

This will be used for receivers as well thus it is not specific to
listeners but to sockets.

4 years agoREORG: sock_inet: move default_tcp_maxseg from proto_tcp.c
Willy Tarreau [Fri, 28 Aug 2020 16:03:10 +0000 (18:03 +0200)] 
REORG: sock_inet: move default_tcp_maxseg from proto_tcp.c

Let's determine it at boot time instead of doing it on first use. It
also saves us from having to keep it thread local. It's been moved to
the new sock_inet_prepare() function, and the variables were renamed
to sock_inet_tcp_maxseg_default and sock_inet6_tcp_maxseg_default.

4 years agoREORG: sock_inet: move v6only_default from proto_tcp.c to sock_inet.c
Willy Tarreau [Fri, 28 Aug 2020 14:06:01 +0000 (16:06 +0200)] 
REORG: sock_inet: move v6only_default from proto_tcp.c to sock_inet.c

The v6only_default variable is not specific to TCP but to AF_INET6, so
let's move it to the right file. It's now immediately filled on startup
during the PREPARE stage so that it doesn't have to be tested each time.
The variable's name was changed to sock_inet6_v6only_default.

4 years agoREORG: inet: replace tcp_is_foreign() with sock_inet_is_foreign()
Willy Tarreau [Fri, 28 Aug 2020 13:40:33 +0000 (15:40 +0200)] 
REORG: inet: replace tcp_is_foreign() with sock_inet_is_foreign()

The function now makes it clear that it's independent on the socket
type and solely relies on the address family. Note that it supports
both IPv4 and IPv6 as we don't seem to need it per-family.

4 years agoMINOR: sock_inet: implement sock_inet_get_dst()
Willy Tarreau [Fri, 28 Aug 2020 13:19:45 +0000 (15:19 +0200)] 
MINOR: sock_inet: implement sock_inet_get_dst()

This one is common to the TCPv4 and UDPv4 code, it retrieves the
destination address of a socket, taking care of the possiblity that for
an incoming connection the traffic was possibly redirected. The TCP and
UDP definitions were updated to rely on it and remove duplicated code.

4 years agoMINOR: tcp/udp/unix: make use of proto->addrcmp() to compare addresses
Willy Tarreau [Fri, 28 Aug 2020 13:30:11 +0000 (15:30 +0200)] 
MINOR: tcp/udp/unix: make use of proto->addrcmp() to compare addresses

The new addrcmp() protocol member points to the function to be used to
compare two addresses of the same family.

When picking an FD from a previous process, we can now use the address
specific address comparison functions instead of having to rely on a
local implementation. This will help move that code to a more central
place.

4 years agoMINOR: sock: introduce sock_inet and sock_unix
Willy Tarreau [Fri, 28 Aug 2020 13:10:11 +0000 (15:10 +0200)] 
MINOR: sock: introduce sock_inet and sock_unix

These files will regroup everything specific to AF_INET, AF_INET6 and
AF_UNIX socket definitions and address management. Some code there might
be agnostic to the socket type and could later move to af_xxxx.c but for
now we only support regular sockets so no need to go too far.

The files are quite poor at this step, they only contain the address
comparison function for each address family.

4 years agoREORG: sock: start to move some generic socket code to sock.c
Willy Tarreau [Fri, 28 Aug 2020 10:07:22 +0000 (12:07 +0200)] 
REORG: sock: start to move some generic socket code to sock.c

The new file sock.c will contain generic code for standard sockets
relying on file descriptors. We currently have way too much duplication
between proto_uxst, proto_tcp, proto_sockpair and proto_udp.

For now only get_src, get_dst and sock_create_server_socket were moved,
and are used where appropriate.

4 years agoREORG: unix: move UNIX bind/server keywords from proto_uxst.c to cfgparse-unix.c
Willy Tarreau [Fri, 28 Aug 2020 09:54:59 +0000 (11:54 +0200)] 
REORG: unix: move UNIX bind/server keywords from proto_uxst.c to cfgparse-unix.c

Let's finish the cleanup and get rid of all bind and server keywords
parsers from proto_uxst.c. They're now moved to cfgparse-unix.c. Now
proto_uxst.c is clean and only contains code related to binding and
connecting.

4 years agoREORG: tcp: move TCP bind/server keywords from proto_tcp.c to cfgparse-tcp.c
Willy Tarreau [Fri, 28 Aug 2020 09:49:31 +0000 (11:49 +0200)] 
REORG: tcp: move TCP bind/server keywords from proto_tcp.c to cfgparse-tcp.c

Let's continue the cleanup and get rid of all bind and server keywords
parsers from proto_tcp.c. They're now moved to cfgparse-tcp.c, just as
was done for ssl before 2.2 release. Nothing has changed beyond this.
Now proto_tcp.c is clean and only contains code related to binding and
connecting.

4 years agoREORG: tcp: move TCP sample fetches from proto_tcp.c to tcp_sample.c
Willy Tarreau [Fri, 28 Aug 2020 09:37:21 +0000 (11:37 +0200)] 
REORG: tcp: move TCP sample fetches from proto_tcp.c to tcp_sample.c

Let's continue the cleanup and get rid of all sample fetch functions
from proto_tcp.c. They're now moved to tcp_sample.c, just as was done
for ssl before 2.2 release. Nothing has changed beyond this.

4 years agoCLEANUP: tcp: stop exporting smp_fetch_src()
Willy Tarreau [Fri, 28 Aug 2020 09:31:31 +0000 (11:31 +0200)] 
CLEANUP: tcp: stop exporting smp_fetch_src()

This is totally ugly, smp_fetch_src() is exported only so that stick_table.c
can (ab)use it in the {sc,src}_* sample fetch functions. It could be argued
that the sample could have been reconstructed there in place, but we don't
even need to duplicate the code. We'd rather simply retrieve the "src"
fetch's function from where it's used at init time and be done with it.

4 years agoREORG: tcp: move TCP actions from proto_tcp.c to tcp_act.c
Willy Tarreau [Fri, 28 Aug 2020 09:03:28 +0000 (11:03 +0200)] 
REORG: tcp: move TCP actions from proto_tcp.c to tcp_act.c

The file proto_tcp.c has become a real mess because it still contains
tons of definitions that have nothing to do with the TCP protocol setup.
This commit moves the ruleset actions "set-src-port", "set-dst-port",
"set-src", "set-dst", and "silent-drop" to a new file "tcp_act.c".
Nothing has changed beyond this.

4 years agoBUG/MINOR: reload: do not fail when no socket is sent
Willy Tarreau [Fri, 28 Aug 2020 16:45:01 +0000 (18:45 +0200)] 
BUG/MINOR: reload: do not fail when no socket is sent

get_old_sockets() mistakenly sets ret=0 instead of ret2=0 before leaving
when the old process announces zero FD. So it will return an error
instead of success. This must be particularly rare not to have a
single socket to offer though!

A few comments were added to make it more obvious what to expect in
return.

This must be backported to 1.8 since the bug has always been there.

4 years agoDOC: add description of pidfile in master-worker mode
MIZUTA Takeshi [Wed, 26 Aug 2020 04:46:19 +0000 (13:46 +0900)] 
DOC: add description of pidfile in master-worker mode

Previously, pidfile was only described for daemon mode. In the case of
master-worker mode, the handling of pidfile is different from daemon mode,
so the description has been added.

4 years agoMEDIUM: reload: pass all exportable FDs, not just listeners
Willy Tarreau [Wed, 19 Aug 2020 15:03:55 +0000 (17:03 +0200)] 
MEDIUM: reload: pass all exportable FDs, not just listeners

Now we don't limit ourselves to listeners found in proxies nor peers
anymore, we're instead scanning all known FDs for those marked with
".exported=1". Just doing so has significantly simplified the code,
and will later allow to yield while sending FDs if desired.

When it comes to retrieving a possible namespace name or interface
name, for now this is only performed on listeners since these are the
only ones carrying such info. Once this moves somewhere else, we'll
be able to also pass these info for UDP receivers for example, with
only tiny changes.

4 years agoMINOR: fd: add a new "exported" flag and use it for all regular listeners
Willy Tarreau [Wed, 19 Aug 2020 08:00:57 +0000 (10:00 +0200)] 
MINOR: fd: add a new "exported" flag and use it for all regular listeners

This new flag will be used to mark FDs that must be passed to any future
process across the CLI's "_getsocks" command.

The scheme here is quite complex and full of special cases:
  - FDs inherited from parent processes are *not* exported this way, as
    they are supposed to instead be passed by the master process itself
    across reloads. However such FDs ought never to be paused otherwise
    this would disrupt the socket in the parent process as well;

  - FDs resulting from a "bind" performed over a socket pair, which are
    in fact one side of a socket pair passed inside another control socket
    pair must not be passed either. Since all of them are used the same
    way, for now it's enough never to put this "exported" flag to FDs
    bound by the socketpair code.

  - FDs belonging to temporary listeners (e.g. a passive FTP data port)
    must not be passed either. Fortunately we don't have such FDs yet.

  - the rest of the listeners for now are made of TCP, UNIX stream, ABNS
    sockets and are exportable, so they get the flag.

  - UDP listeners were wrongly created as listeners and are not suitable
    here. Their FDs should be passed but for now they are not since the
    client doesn't even distinguish the SO_TYPE of the retrieved sockets.

In addition, it's important to keep in mind that:
  - inherited FDs may never be closed in master process but may be closed
    in worker processes if the service is shut down (useless since still
    bound, but technically possible) ;

  - inherited FDs may not be disabled ;

  - exported FDs may be disabled because the caller will perform the
    subsequent listen() on them. However that might not work for all OSes

  - exported FDs may be closed, it just means the service was shut down
    from the worker, and will be rebound in the new process. This implies
    that we have to disable exported on close().

=> as such, contrary to an apparently obvious equivalence, the "exported"
   status doesn't imply anything regarding the ability to close a
   listener's FD or not.

4 years agoCLEANUP: fd: remove fd_remove() and rename fd_dodelete() to fd_delete()
Willy Tarreau [Wed, 26 Aug 2020 09:54:06 +0000 (11:54 +0200)] 
CLEANUP: fd: remove fd_remove() and rename fd_dodelete() to fd_delete()

This essentially undoes what we did in fd.c in 1.8 to support seamless
reload. Since we don't need to remove an fd anymore we can turn
fd_delete() to the simple function it used to be.

4 years agoMEDIUM: fd: replace usages of fd_remove() with fd_stop_both()
Willy Tarreau [Wed, 26 Aug 2020 09:44:17 +0000 (11:44 +0200)] 
MEDIUM: fd: replace usages of fd_remove() with fd_stop_both()

We used to require fd_remove() to remove an FD from a poller when we
still had the FD cache and it was not possible to directly act on the
pollers. Nowadays we don't need this anymore as the pollers will
automatically unregister disabled FDs. The fd_remove() hack is
particularly problematic because it additionally hides the FD from
the known FD list and could make one think it's closed.

It's used at two places:
  - with the async SSL engine
  - with the listeners (when unbinding from an fd for another process)

Let's just use fd_stop_both() instead, which will propagate down the
stack to do the right thing, without removing the FD from the array
of known ones.

Now when dumping FDs using "show fd" on a process which still knows some
of the other workers' FDs, the FD will properly be listed with a listener
state equal to "ZOM" for "zombie". This guarantees that the FD is still
known and will properly be passed using _getsocks().

4 years agoBUG/MEDIUM: ssl: fix ssl_bind_conf double free w/ wildcards
William Lallemand [Wed, 26 Aug 2020 15:34:44 +0000 (17:34 +0200)] 
BUG/MEDIUM: ssl: fix ssl_bind_conf double free w/ wildcards

The fix 7df5c2d ("BUG/MEDIUM: ssl: fix ssl_bind_conf double free") was
not complete. The problem still occurs when using wildcards in
certificate, during the deinit.

This patch removes the free of the ssl_conf structure in
ssl_sock_free_all_ctx() since it's already done in the crtlist deinit.

It must be backported in 2.2.

4 years agoMEDIUM: reload: stop passing listener options along with FDs
Willy Tarreau [Wed, 26 Aug 2020 08:30:09 +0000 (10:30 +0200)] 
MEDIUM: reload: stop passing listener options along with FDs

During a reload operation, we used to send listener options associated
with each passed file descriptor. These were passed as binary contents
for the size of the "options" field in the struct listener. This means
that any flag value change or field size change would be problematic,
the former failing to properly grab certain options, the latter possibly
causing permanent failures during this operation.

Since these two previous commits:
  MINOR: reload: determine the foreing binding status from the socket
  BUG/MINOR: reload: detect the OS's v6only status before choosing an old socket

we don't need this anymore as the values are determined from the file
descriptor itself.

Let's just turn the previous 32 bits to vestigal space, send them as
zeroes and ignore them on receipt. The only possible side effect is if
someone would want to roll back from a 2.3 to 2.2 or earlier, such options
might be ignored during this reload. But other forthcoming changes might
make this fail as well anyway so that's not a reason for keeping this
behavior.

4 years agoMINOR: reload: determine the foreing binding status from the socket
Willy Tarreau [Wed, 26 Aug 2020 08:23:40 +0000 (10:23 +0200)] 
MINOR: reload: determine the foreing binding status from the socket

Let's not look at the listener options passed by the original process
and determine from the socket itself whether it is configured for
transparent mode or not. This is cleaner and safer, and doesn't rely
on flag values that could possibly change between versions.

4 years agoBUG/MINOR: reload: detect the OS's v6only status before choosing an old socket
Willy Tarreau [Wed, 26 Aug 2020 07:29:21 +0000 (09:29 +0200)] 
BUG/MINOR: reload: detect the OS's v6only status before choosing an old socket

The v4v6 and v6only options are passed as data during the socket transfer
between processes so that the new process can decide whether it wants to
reuse a socket or not. But this actually misses one point: if no such option
is set and the OS defaults are changed between the reloads, then the socket
will still be inherited and will never be rebound using the new options.

This can be seen by starting the following config:

  global
    stats socket /tmp/haproxy.sock level admin expose-fd listeners

  frontend testme
    bind :::1234
    timeout client          2000ms

Having a look at the OS settins, v6only is disabled:

  $ cat /proc/sys/net/ipv6/bindv6only
  0

A first check shows it's indeed bound to v4 and v6:

  $ ss -an -6|grep 1234
  tcp   LISTEN 0      2035                                   *:1234             *:*

Reloading the process doesn't change anything (which is expected). Now let's set
bindv6only:

  $ echo 1 | sudo tee /proc/sys/net/ipv6/bindv6only
  1
  $ cat /proc/sys/net/ipv6/bindv6only
  1

Reloading gives the same state:

  $ ss -an -6|grep 1234
  tcp   LISTEN 0      2035                                   *:1234             *:*

However a restart properly shows a correct bind:

  $ ss -an -6|grep 1234
  tcp   LISTEN 0      2035                                [::]:1234          [::]:*

This one doesn't change once bindv6only is reset, for the same reason.

This patch attacks this problem differently. Instead of passing the two
options at once for each listening fd, it ignores the options and reads
the socket's current state for the IPV6_V6ONLY flag and sets it only.
Then before looking for a compatible FD, it checks the OS's defaults
before deciding which of the v4v6 and v6only needs to be kept on the
listener. And the selection is only made on this.

First, it addresses this issue. Second, it also ensures that if such
options are changed between reloads to identical states, the socket
can still be inherited. For example adding v4v6 when bindv6only is not
set will allow the socket to still be usable. Third, it avoids an
undesired dependency on the LI_O_* bit values between processes across
a reload (for these ones at least).

It might make sense to backport this to some recent stable versions, but
quite frankly the likelyhood that anyone will ever notice it is extremely
faint.

4 years agoMINOR: tcp: don't try to set/clear v6only on inherited sockets
Willy Tarreau [Wed, 26 Aug 2020 08:21:06 +0000 (10:21 +0200)] 
MINOR: tcp: don't try to set/clear v6only on inherited sockets

If a socket was already bound (inherited from a parent or retrieved from
a previous process), there's no point trying to change its IPV6_V6ONLY
state since it will fail. This is visible in strace as an EINVAL during
a reload when passing FDs.

4 years agoMINOR: ssl: Support SAN extension for certificate generation
Shimi Gersner [Sun, 23 Aug 2020 10:58:13 +0000 (13:58 +0300)] 
MINOR: ssl: Support SAN extension for certificate generation

The use of Common Name is fading out in favor of the RFC recommended
way of using SAN extensions. For example, Chrome from version 58
will only match server name against SAN.

The following patch adds SAN extension by default to all generated certificates.
The SAN extension will be of type DNS and based on the server name.

4 years agoMEDIUM: ssl: Support certificate chaining for certificate generation
Shimi Gersner [Sun, 23 Aug 2020 10:58:12 +0000 (13:58 +0300)] 
MEDIUM: ssl: Support certificate chaining for certificate generation

haproxy supports generating SSL certificates based on SNI using a provided
CA signing certificate. Because CA certificates may be signed by multiple
CAs, in some scenarios, it is neccesary for the server to attach the trust chain
in addition to the generated certificate.

The following patch adds the ability to serve the entire trust chain with
the generated certificate. The chain is loaded from the provided
`ca-sign-file` PEM file.

4 years agoBUILD: task: work around a bogus warning in gcc 4.7/4.8 at -O1
Willy Tarreau [Fri, 21 Aug 2020 03:48:34 +0000 (05:48 +0200)] 
BUILD: task: work around a bogus warning in gcc 4.7/4.8 at -O1

As reported in issue #816, when building task.o at -O1 with gcc 4.7 or
4.8, we get the following warning:

    CC      src/task.o
  In file included from include/haproxy/proxy.h:31:0,
                   from include/haproxy/cfgparse.h:27,
                   from src/task.c:19:
  src/task.c: In function 'next_timer_expiry':
  include/haproxy/ticks.h:121:10: warning: 'key' may be used uninitialized in this function [-Wmaybe-uninitialized]
  src/task.c:349:2: note: 'key' was declared here

It is wrong since the condition to use 'key' is exactly the same as
the one used to set it. This warning disappears at -O2 and disappeared
from gcc 5 and above. Let's just initialize 'key' there, it only adds
16 bytes of code and remains cheap enough for this function.

This should be backported to 2.2.

4 years agoBUILD: tools: include auxv a bit later
Willy Tarreau [Thu, 20 Aug 2020 14:39:14 +0000 (16:39 +0200)] 
BUILD: tools: include auxv a bit later

As reported in https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=24745,
haproxy fails to build with TARGET=generic and without extra options due
to auxv.h not being included, since the __GLIBC__ macro is not yet defined.
Let's include it after other libc headers so that the __GLIBC__ definition
is known. Thanks to David and Tim for the diag.

This should be backported to 2.2.

4 years agoMINOR: stats: prevent favicon.ico requests for stats page
zurikus [Tue, 18 Aug 2020 08:16:05 +0000 (11:16 +0300)] 
MINOR: stats: prevent favicon.ico requests for stats page

Haproxy stats page don't have a favicon.ico, but browsers always makes a request for it.
This lead to errors during stats page requests:

Aug 18 08:46:41 somehost.example.net haproxy[1521534]: X.X.X.X:61403 [18/Aug/2020:08:46:41.437] stats stats/ -1/-1/-1/-1/0 503 222 - - SC-- 2/2/0/0/0 0/0 "GET /favicon.ico HTTP/1.1"
Aug 18 08:46:42 somehost.example.net haproxy[1521534]: X.X.X.X:61403 [18/Aug/2020:08:46:42.650] stats stats/ -1/-1/-1/-1/0 503 222 - - SC-- 2/2/0/0/0 0/0 "GET /favicon.ico HTTP/1.1"

Patch provided disables favicon.ico requests for haproxy stats page.

4 years agoREGTEST: remove stray leading spaces in converteers_ref_cnt_never_dec.vtc
Willy Tarreau [Wed, 19 Aug 2020 09:20:28 +0000 (11:20 +0200)] 
REGTEST: remove stray leading spaces in converteers_ref_cnt_never_dec.vtc

Since commit f92afb732 ("MEDIUM: cfgparse: Emit hard error on truncated lines")
we now produce parsing errors on truncated lines, in an effort to clean
up dangerous or broken config files. And it turns out that one of our own
regression tests was suffering from this, as diagnosed by William and Tim.
The cause is the leading spaces in front of "} -start" that vtest makes
part of the output file, so the file finishes with a partial line made
of spaces.

4 years agoMINOR: cache: Reject duplicate cache names
Tim Duesterhus [Tue, 18 Aug 2020 20:20:27 +0000 (22:20 +0200)] 
MINOR: cache: Reject duplicate cache names

Using a duplicate cache name most likely is the result of a misgenerated
configuration. There is no good reason to allow this, as the duplicate
caches can't be referred to.

This commit resolves GitHub issue #820.

It can be argued whether this is a fix for a bug or not. I'm erring on the
side of caution and marking this as a "new feature". It can be considered for
backporting to 2.2, but for other branches the risk of accidentally breaking
some working (but non-ideal) configuration might be too large.

4 years agoDOC: cache: Use '<name>' instead of '<id>' in error message
Tim Duesterhus [Tue, 18 Aug 2020 20:06:51 +0000 (22:06 +0200)] 
DOC: cache: Use '<name>' instead of '<id>' in error message

When the cache name is left out in 'filter cache' the error message refers
to a missing '<id>'. The name of the cache is called 'name' within the docs.

Adjust the error message for consistency.

The error message was introduced in 99a17a2d91f9044ea20bba6617048488aed80555.
This commit first appeared in 1.9, thus the patch must be backported to 1.9+.

4 years agoMEDIUM: cfgparse: Emit hard error on truncated lines
Tim Duesterhus [Tue, 18 Aug 2020 20:00:04 +0000 (22:00 +0200)] 
MEDIUM: cfgparse: Emit hard error on truncated lines

As announced within the emitted log message this is going to become a hard
error in 2.3. It's 2.3 time now, let's do this.

see 2fd5bdb439da29f15381aeb57c51327ba57674fc

4 years agoDOC: overhauling github issue templates
Lukas Tribus [Mon, 17 Aug 2020 18:17:11 +0000 (20:17 +0200)] 
DOC: overhauling github issue templates

as per the suggestions from Cyril and Willy on the mailing list:

Message-ID: <a0010c72-70b8-0647-c269-55c6614627c3@free.fr>

and with direct contributions from Tim, this changes large parts
of the bug issue template.

The Feature template is also updated as well as a new template for
Code Reports is introduced.

Co-authored-by: Tim Duesterhus <tim@bastelstu.be>
4 years agoBUG/MEDIUM: ssl: crt-list negative filters don't work
William Lallemand [Mon, 17 Aug 2020 12:31:19 +0000 (14:31 +0200)] 
BUG/MEDIUM: ssl: crt-list negative filters don't work

The negative filters which are supposed to exclude a SNI from a
wildcard, never worked. Indeed the negative filters were skipped in the
code.

To fix the issue, this patch looks for negative filters that are on the
same line as a the wildcard that just matched.

This patch should fix issue #818. It must be backported in 2.2.  The
problem also exists in versions > 1.8 but the infrastructure required to
fix this was only introduced in 2.1.  In older versions we should
probably change the documentation to state that negative filters are
useless.

4 years agoMINOR: hlua: Add error message relative to the Channel manipulation and HTTP mode
Thierry Fournier [Sat, 15 Aug 2020 12:35:51 +0000 (14:35 +0200)] 
MINOR: hlua: Add error message relative to the Channel manipulation and HTTP mode

When the developper try to manipulate HAProxy channels in HTTP mode,
an error throws without explanation. This patch adds an explanation.

4 years ago[RELEASE] Released version 2.3-dev3 v2.3-dev3
Willy Tarreau [Fri, 14 Aug 2020 16:54:05 +0000 (18:54 +0200)] 
[RELEASE] Released version 2.3-dev3

Released version 2.3-dev3 with the following main changes :
    - SCRIPTS: git-show-backports: make -m most only show the left branch
    - SCRIPTS: git-show-backports: emit the shell command to backport a commit
    - BUILD: Makefile: require SSL_LIB, SSL_INC to be explicitly set
    - CI: travis-ci: specify SLZ_LIB, SLZ_INC for travis builds
    - BUG/MEDIUM: mux-h1: Refresh H1 connection timeout after a synchronous send
    - CLEANUP: dns: typo in reported error message
    - BUG/MAJOR: dns: disabled servers through SRV records never recover
    - BUG/MINOR: spoa-server: fix size_t format printing
    - DOC: spoa-server: fix false friends `actually`
    - BUG/MINOR: ssl: fix memory leak at OCSP loading
    - BUG/MEDIUM: ssl: memory leak of ocsp data at SSL_CTX_free()
    - BUG/MEDIUM: map/lua: Return an error if a map is loaded during runtime
    - MINOR: arg: Add an argument type to keep a reference on opaque data
    - BUG/MINOR: converters: Store the sink in an arg pointer for debug() converter
    - BUG/MINOR: lua: Duplicate map name to load it when a new Map object is created
    - BUG/MINOR: arg: Fix leaks during arguments validation for fetches/converters
    - BUG/MINOR: lua: Check argument type to convert it to IPv4/IPv6 arg validation
    - BUG/MINOR: lua: Check argument type to convert it to IP mask in arg validation
    - MINOR: hlua: Don't needlessly copy lua strings in trash during args validation
    - BUG/MINOR: lua: Duplicate lua strings in sample fetches/converters arg array
    - MEDIUM: lua: Don't filter exported fetches and converters
    - MINOR: lua: Add support for userlist as fetches and converters arguments
    - MINOR: lua: Add support for regex as fetches and converters arguments
    - MINOR: arg: Use chunk_destroy() to release string arguments
    - BUG/MINOR: snapshots: leak of snapshots on deinit()
    - CLEANUP: ssl: ssl_sock_crt2der semicolon and spaces
    - MINOR: ssl: add ssl_{c,s}_chain_der fetch methods
    - CLEANUP: fix all duplicated semicolons
    - BUG/MEDIUM: ssl: fix the ssl-skip-self-issued-ca option
    - BUG/MINOR: ssl: ssl-skip-self-issued-ca requires >= 1.0.2
    - BUG/MINOR: stats: use strncmp() instead of memcmp() on health states
    - BUILD: makefile: don't disable -Wstringop-overflow anymore
    - BUG/MINOR: ssl: double free w/ smp_fetch_ssl_x_chain_der()
    - BUG/MEDIUM: htx: smp_prefetch_htx() must always validate the direction
    - BUG/MEDIUM: ssl: never generates the chain from the verify store
    - OPTIM: regex: PCRE2 use JIT match when JIT optimisation occured.
    - BUG/MEDIUM: ssl: does not look for all SNIs before chosing a certificate
    - CLEANUP: ssl: remove poorly readable nested ternary

4 years agoCLEANUP: ssl: remove poorly readable nested ternary
William Lallemand [Fri, 14 Aug 2020 13:30:13 +0000 (15:30 +0200)] 
CLEANUP: ssl: remove poorly readable nested ternary

Replace a four level nested ternary expression by an if/else expression
in ssl_sock_switchctx_cbk()

4 years agoBUG/MEDIUM: ssl: does not look for all SNIs before chosing a certificate
William Lallemand [Fri, 14 Aug 2020 12:43:35 +0000 (14:43 +0200)] 
BUG/MEDIUM: ssl: does not look for all SNIs before chosing a certificate

In bug #810, the SNI are not matched correctly, indeed when trying to
match a certificate type in ssl_sock_switchctx_cbk() all SNIs were not
looked up correctly.

In the case you have in a crt-list:

wildcard.subdomain.domain.tld.pem.rsa *.subdomain.domain.tld record.subdomain.domain.tld
record.subdomain.domain.tld.pem.ecdsa record.subdomain.domain.tld another-record.subdomain.domain.tld

If the client only supports RSA and requests
"another-record.subdomain.domain.tld", HAProxy will find the single
ECDSA certificate and won't try to look up for a wildcard RSA
certificate.

This patch fixes the code so we look for all single and
wildcard before chosing the certificate type.

This bug was introduced by commit 3777e3a ("BUG/MINOR: ssl: certificate
choice can be unexpected with openssl >= 1.1.1").

It must be backported as far as 1.8 once it is heavily tested.

4 years agoOPTIM: regex: PCRE2 use JIT match when JIT optimisation occured.
David Carlier [Thu, 13 Aug 2020 13:53:41 +0000 (14:53 +0100)] 
OPTIM: regex: PCRE2 use JIT match when JIT optimisation occured.

When a regex had been succesfully compiled by the JIT pass, it is better
 to use the related match, thanksfully having same signature, for better
 performance.

Signed-off-by: David Carlier <devnexen@gmail.com>
4 years agoBUG/MEDIUM: ssl: never generates the chain from the verify store
William Lallemand [Wed, 12 Aug 2020 18:02:10 +0000 (20:02 +0200)] 
BUG/MEDIUM: ssl: never generates the chain from the verify store

In bug #781 it was reported that HAProxy completes the certificate chain
using the verify store in the case there is no chain.

Indeed, according to OpenSSL documentation, when generating the chain,
OpenSSL use the chain store OR the verify store in the case there is no
chain store.

As a workaround, this patch always put a NULL chain in the SSL_CTX so
OpenSSL does not tries to complete it.

This must be backported in all branches, the code could be different,
the important part is to ALWAYS set a chain, and uses sk_X509_new_null()
if the chain is NULL.

4 years agoBUG/MEDIUM: htx: smp_prefetch_htx() must always validate the direction
Willy Tarreau [Wed, 12 Aug 2020 12:04:52 +0000 (14:04 +0200)] 
BUG/MEDIUM: htx: smp_prefetch_htx() must always validate the direction

It is possible to process a channel based on desynchronized info if a
request fetch is called from a response and conversely. However, the
code in smp_prefetch_htx() already makes sure the analysis has already
started before trying to fetch from a buffer, so the problem effectively
lies in response rules making use of request expressions only.

Usually it's not a problem as extracted data are checked against the
current HTTP state, except when it comes to the start line, which is
usually accessed directly from sample fetch functions such as status,
path, url, url32, query and so on. In this case, trying to access the
request buffer from the response path will lead to unpredictable
results. When building with DEBUG_STRICT, a process violating these
rules will simply die after emitting:

  FATAL: bug condition "htx->first == -1" matched at src/http_htx.c:67

But when this is not enabled, it may or may not crash depending on what
the pending request buffer data look like when trying to spot a start
line there. This is typically what happens in issue #806.

This patch adds a test in smp_prefetch_htx() so that it does not try
to parse an HTX buffer in a channel belonging to the wrong direction.

There's one special case on the "method" sample fetch since it can
retrieve info even without a buffer, from the other direction, as
long as the method is one of the well known ones. Three, we call
smp_prefetch_htx() only if needed.

This was reported in 2.0 and must be backported there (oldest stable
version with HTX).

4 years agoBUG/MINOR: ssl: double free w/ smp_fetch_ssl_x_chain_der()
William Lallemand [Tue, 11 Aug 2020 09:18:46 +0000 (11:18 +0200)] 
BUG/MINOR: ssl: double free w/ smp_fetch_ssl_x_chain_der()

smp_fetch_ssl_x_chain_der() uses the SSL_get_peer_cert_chain() which
does not increment the refcount of the chain, so it should not be free'd.

The bug was introduced by a598b50 ("MINOR: ssl: add ssl_{c,s}_chain_der
fetch methods"). No backport needed.

4 years agoBUILD: makefile: don't disable -Wstringop-overflow anymore
Willy Tarreau [Tue, 11 Aug 2020 08:31:18 +0000 (10:31 +0200)] 
BUILD: makefile: don't disable -Wstringop-overflow anymore

This basically reverts commit c4e6460f6 ("MINOR: build: Disable
-Wstringop-overflow.") which is no more needed after previous one.

4 years agoBUG/MINOR: stats: use strncmp() instead of memcmp() on health states
Willy Tarreau [Tue, 11 Aug 2020 08:26:36 +0000 (10:26 +0200)] 
BUG/MINOR: stats: use strncmp() instead of memcmp() on health states

The reports for health states are checked using memcmp() in order to
only focus on the first word and possibly ignore trailing %d/%d etc.
This makes gcc unhappy about a potential use of "" as the string, which
never happens since the string is always set. This resulted in commit
c4e6460f6 ("MINOR: build: Disable -Wstringop-overflow.") to silence
these messages. However some lengths are incorrect (though cannot cause
trouble), and in the end strncmp() is just safer and cleaner.

This can be backported to all stable branches as it will shut a warning
with gcc 8 and above.

4 years agoBUG/MINOR: ssl: ssl-skip-self-issued-ca requires >= 1.0.2
William Lallemand [Mon, 10 Aug 2020 15:28:23 +0000 (17:28 +0200)] 
BUG/MINOR: ssl: ssl-skip-self-issued-ca requires >= 1.0.2

The previous fix for ssl-skip-self-issued-ca requires the use of
SSL_CTX_build_cert_chain() which is only available starting from OpenSSL
1.0.2

4 years agoBUG/MEDIUM: ssl: fix the ssl-skip-self-issued-ca option
William Lallemand [Mon, 10 Aug 2020 14:18:45 +0000 (16:18 +0200)] 
BUG/MEDIUM: ssl: fix the ssl-skip-self-issued-ca option

In commit f187ce6, the ssl-skip-self-issued-ca option was accidentally
made useless by reverting the SSL_CTX reworking.

The previous attempt of making this feature was putting each certificate
of the chain in the SSL_CTX with SSL_CTX_add_extra_chain_cert() and was
skipping the Root CA.
The problem here is that doing it this way instead of doing a
SSL_CTX_set1_chain() break the support of the multi-certificate bundles.

The SSL_CTX_build_cert_chain() function allows one to remove the Root CA
with the SSL_BUILD_CHAIN_FLAG_NO_ROOT flag. Use it instead of doing
tricks with the CA.

Should fix issue #804.

Must be backported in 2.2.

4 years agoCLEANUP: fix all duplicated semicolons
William Dauchy [Fri, 7 Aug 2020 20:19:23 +0000 (22:19 +0200)] 
CLEANUP: fix all duplicated semicolons

trivial commit, does not change the code behaviour

Signed-off-by: William Dauchy <w.dauchy@criteo.com>
4 years agoMINOR: ssl: add ssl_{c,s}_chain_der fetch methods
William Dauchy [Thu, 6 Aug 2020 16:11:38 +0000 (18:11 +0200)] 
MINOR: ssl: add ssl_{c,s}_chain_der fetch methods

Following work from Arjen and Mathilde, it adds ssl_{c,s}_chain_der
methods; it returns DER encoded certs from SSL_get_peer_cert_chain

Also update existing vtc tests to add random intermediate certificates

When getting the result through this header:
  http-response add-header x-ssl-chain-der %[ssl_c_chain_der,hex]
One can parse it with any lib accepting ASN.1 DER data, such as in go:
  bin, err := encoding/hex.DecodeString(cert)
  certs_parsed, err := x509.ParseCertificates(bin)

Cc: Arjen Nienhuis <arjen@zorgdoc.nl>
Signed-off-by: Mathilde Gilles <m.gilles@criteo.com>
Signed-off-by: William Dauchy <w.dauchy@criteo.com>
4 years agoCLEANUP: ssl: ssl_sock_crt2der semicolon and spaces
William Dauchy [Thu, 6 Aug 2020 16:11:37 +0000 (18:11 +0200)] 
CLEANUP: ssl: ssl_sock_crt2der semicolon and spaces

trivial commit, does not change the code behaviour

Signed-off-by: William Dauchy <w.dauchy@criteo.com>
4 years agoBUG/MINOR: snapshots: leak of snapshots on deinit()
William Lallemand [Fri, 7 Aug 2020 12:48:37 +0000 (14:48 +0200)] 
BUG/MINOR: snapshots: leak of snapshots on deinit()

Free the snapshots on deinit() when they were initialized in a proxy
upon an error.

This was introduced by c55015e ("MEDIUM: snapshots: dynamically allocate
the snapshots").

Should be backported as far as 1.9.

4 years agoMINOR: arg: Use chunk_destroy() to release string arguments
Christopher Faulet [Fri, 7 Aug 2020 09:45:18 +0000 (11:45 +0200)] 
MINOR: arg: Use chunk_destroy() to release string arguments

This way, all fields of the buffer structure are reset when a string argument
(ARGT_STR) is released.  It is also a good way to explicitly specify this kind
of argument is a chunk. So .data and .size fields must be set.

This patch may be backported to ease backports.

4 years agoMINOR: lua: Add support for regex as fetches and converters arguments
Christopher Faulet [Thu, 6 Aug 2020 09:10:57 +0000 (11:10 +0200)] 
MINOR: lua: Add support for regex as fetches and converters arguments

It means now regsub() converter is now exported to the lua. Map converters based
on regex are not available because the map arguments are not supported.

4 years agoMINOR: lua: Add support for userlist as fetches and converters arguments
Christopher Faulet [Thu, 6 Aug 2020 09:04:46 +0000 (11:04 +0200)] 
MINOR: lua: Add support for userlist as fetches and converters arguments

It means now http_auth() and http_auth_group() sample fetches are now exported
to the lua.

4 years agoMEDIUM: lua: Don't filter exported fetches and converters
Christopher Faulet [Thu, 6 Aug 2020 08:32:28 +0000 (10:32 +0200)] 
MEDIUM: lua: Don't filter exported fetches and converters

Thanks to previous commits, it is now safe to use from lua the sample fetches
and sample converters that convert arguments, especially the strings
(ARGT_STR). So now, there are all exported to the lua. They was filtered on the
validation functions. Only fetches without validation functions or with val_hdr
or val_payload_lv functions were exported, and converters without validation
functions.

This patch depends on following commits :

  * aec27ef44 "BUG/MINOR: lua: Duplicate lua strings in sample fetches/converters arg array"
  * fdea1b631 "MINOR: hlua: Don't needlessly copy lua strings in trash during args validation"

It must be backported as far as 2.1 because the date() and http_date()
converters are no longer exported because of the filter on the validation
function, since the commit ae6f125c7 ("MINOR: sample: add us/ms support to
date/http_date)".

4 years agoBUG/MINOR: lua: Duplicate lua strings in sample fetches/converters arg array
Christopher Faulet [Thu, 6 Aug 2020 06:54:25 +0000 (08:54 +0200)] 
BUG/MINOR: lua: Duplicate lua strings in sample fetches/converters arg array

Strings in the argument array used by sample fetches and converters must be
duplicated. This is mandatory because, during the arguments validations, these
strings may be converted and released. It works this way during the
configuration parsing and there is no reason to adapt this behavior during the
runtime when a sample fetch or a sample converter is called from the lua. In
fact, there is a reason to not change the behavior. It must reamain simple for
everyone to add new fetches or converters.

Thus, lua strings are duplicated. It is only performed at the end of the
hlua_lua2arg_check() function, if the argument is still a ARGT_STR. Of course,
it requires a cleanup loop after the call or when an error is triggered.

This patch depends on following commits:

  * 959171376 "BUG/MINOR: arg: Fix leaks during arguments validation for fetches/converters"
  * fdea1b631 "MINOR: hlua: Don't needlessly copy lua strings in trash during args validation"

It may be backported to all supported versions, most probably as far as 2.1
only.