Commit Graph

16460 Commits

Author SHA1 Message Date
Willy Tarreau
7a1e6fe128 BUILD: makefile: avoid testing all -Wno-* options when not needed
We already have 9 different warning shutup options and this list grows
with each new version. Testing for their support takes some time at the
makefile's initialisation which is visible on all options (make clean
etc). Some compilers like clang are extremely slow to validate them all
and spend roughly half a second on modern machines to validate all
options. And some compilers are happier than others when passed a -Wno-*
option they do not know:
  - gcc < 4 complains loudly
  - gcc 4 and above do not say anything, unless there is already another
    warning, in which case they will report about the unknown option as
    well, but without affecting the return code
  - clang by default rejects unknown options but supports a special option
    -Wno-unknown-warning-option to silently ignore them

This patch improves the situation a bit by detecting if the compiler
already supports random options, only supports them when called with
-Wno-unknown-warning-option, or not at all. Based on this, a variable
is set to indicate if we can avoid testing for all unknown options and
assume they are supported, and another one is set to hold the optionally
required option to shut the warning. This results in almost halving the
makefile's startup time, which is particularly appreciable with latest
compilers which become really fat (the other half is caused by the same
tests on various cc-opt).
2022-01-31 21:00:35 +01:00
William Lallemand
ce672844dd Revert "MINOR: mworker: sets used or closed worker FDs to -1"
This reverts commit ea7371e934.

This can't work correctly as we need this FD in the worker to be
inserted in the fdtab. The correct way to do it would be to cleanup the
mworker_proc in the master after the fork().
2022-01-31 19:06:07 +01:00
Frédéric Lécaille
7fbb94da8d MINOR: quic: Do not use connection struct xprt_ctx too soon
In fact the xprt_ctx of the connection is first stored into quic_conn
struct as soon as it is initialized from qc_conn_alloc_ssl_ctx().
As quic_conn_init_timer() is run after this function, we can associate
the timer context of the timer to the one from the quic_conn struct.
2022-01-31 16:40:23 +01:00
Frédéric Lécaille
789413caf0 MINOR: quic: Initialize the connection timer asap
We must move this initialization from xprt_start() callback, which
comes too late (after handshake completion for 1RTT session). This timer must be
usable as soon as we have packets to send/receive. Let's initialize it after
the TLS context is initialized in qc_conn_alloc_ssl_ctx(). This latter function
initializes I/O handler task (quic_conn_io_cb) to send/receive packets.
2022-01-31 16:40:23 +01:00
Frédéric Lécaille
91f083a365 MINOR: quic: Do not try to accept a connection more than one time
We add a new flag to mark a connection as already enqueued for acception.
This is useful for 0-RTT session where a connection is first enqueued for
acception as soon as 0-RTT RX secrets could be derived. Then as for any other
connection, we could accept one more time this connection after handshake
completion which lead to very bad side effects.

Thank you to Amaury for this nice patch.
2022-01-31 16:40:23 +01:00
Frédéric Lécaille
298931d177 MINOR: quic: Do not try to treat 0-RTT packets without started mux
We proceed the same was as for 1-RTT packets: we do not try to treat
them until the mux is started.
2022-01-31 16:40:23 +01:00
Frédéric Lécaille
61b851d748 MINOR: quic: Try to accept 0-RTT connections
When a listener managed to derive 0-RTT RX secrets we consider it accepted
the early data. So we enqueue the connection into the accept queue.
2022-01-31 16:40:23 +01:00
William Lallemand
ea7371e934 MINOR: mworker: sets used or closed worker FDs to -1
mworker_cli_sockpair_new() is used to create the socketpair CLI listener of
the worker. Its FD is referenced in the mworker_proc structure, however,
once it's assigned to the listener the reference should be removed so we
don't use it accidentally.

The same must be done in case of errors if the FDs were already closed.
2022-01-31 11:10:34 +01:00
Tim Duesterhus
21ea8c5198 REGTESTS: Remove REQUIRE_VERSION=1.8 from all tests
HAProxy 1.8 is the lowest supported version, thus this always matches.

see 1b095cac94
2022-01-29 15:24:45 +01:00
Tim Duesterhus
f42ddf73fc CI: Consistently use actions/checkout@v2
v2 is the current version of the checkout action and faster than v1.
2022-01-29 15:24:06 +01:00
William Lallemand
56be0e0146 MINOR: mworker: allocate and initialize a mworker_proc
mworker_proc_new() allocates and initializes correctly a mworker_proc
structure.
2022-01-28 23:52:36 +01:00
William Lallemand
7e01878e45 MINOR: mworker: set the master side of ipc_fd in the worker to -1
Once the child->ipc_fd[0] is closed in the worker, set the value to -1
so we don't reference a closed FD anymore.
2022-01-28 23:52:26 +01:00
William Lallemand
55a921c914 BUG/MINOR: mworker: fix a FD leak of a sockpair upon a failed reload
When starting HAProxy in master-worker, the master pre-allocate a struct
mworker_proc and do a socketpair() before the configuration parsing. If
the configuration loading failed, the FD are never closed because they
aren't part of listener, they are not even in the fdtab.

This patch fixes the issue by cleaning the mworker_proc structure that
were not asssigned a process, and closing its FDs.

Must be backported as far as 2.0, the srv_drop() only frees the memory
and could be dropped since it's done before an exec().
2022-01-28 23:47:43 +01:00
Willy Tarreau
4c943fd60b BUILD: mworker: include tools.h for platforms without unsetenv()
In this case we fall back to my_unsetenv() thus we need tools.h
to avoid a warning.
2022-01-28 19:04:02 +01:00
Willy Tarreau
cc5cd5b8d8 BUILD: task: use list_to_mt_list() instead of casting list to mt_list
There were a few casts of list* to mt_list* that were upsetting some
old compilers (not sure about the effect on others). We had created
list_to_mt_list() purposely for this, let's use it instead of applying
this cast.
2022-01-28 19:04:02 +01:00
Willy Tarreau
f3d5c4b032 BUILD: tools: fix warning about incorrect cast with dladdr1()
dladdr1() is used on glibc and takes a void**, but we pass it a
const ElfW(Sym)** and some compilers complain that we're aliasing.
Let's just set a may_alias attribute on the local variable to
address this. There's no need to backport this unless warnings are
reported on older distros or uncommon compilers.
2022-01-28 19:04:02 +01:00
Willy Tarreau
8f0b4e97e7 BUILD: tree-wide: mark a few numeric constants as explicitly long long
At a few places in the code the switch/case ond flags are tested against
64-bit constants without explicitly being marked as long long. Some
32-bit compilers complain that the constant is too large for a long, and
other likely always use long long there. Better fix that as it's uncertain
what others which do not complain do. It may be backported to avoid doubts
on uncommon platforms if needed, as it touches very few areas.
2022-01-28 19:04:02 +01:00
Willy Tarreau
31a8306b93 BUILD: mux_fcgi: avoid aliasing of a const struct in traces
fcgi_trace() declares fconn as a const and casts its mbuf array to
(struct buffer*), which rightfully upsets some older compilers. Better
just declare it as a writable variable and get rid of the cast. It's
harmless anyway. This has been there since 2.1 with commit 5c0f859c2
("MINOR: mux-fcgi/trace: Register a new trace source with its events")
and doens't need to be backported though it would not harm either.
2022-01-28 19:04:02 +01:00
Willy Tarreau
74bc991600 BUILD: server-state: avoid using not-so-portable isblank()
Once in a while we get rid of this one. isblank() is missing on old
C libraries and only matches two values, so let's just replace it.
It was brought with this commit in 2.4:

  0bf268e18 ("MINOR: server: Be more strict on the server-state line parsing")

It may be backported though it's really not important.
2022-01-28 19:04:02 +01:00
Willy Tarreau
e90dde1edf BUILD: vars: avoid overlapping field initialization
Compiling vars.c with gcc 4.2 shows that we're initializing some local
structs field members in a not really portable way:

src/vars.c: In function 'vars_parse_cli_set_var':
src/vars.c:1195: warning: initialized field overwritten
src/vars.c:1195: warning: (near initialization for 'px.conf.args')
src/vars.c:1195: warning: initialized field overwritten
src/vars.c:1195: warning: (near initialization for 'px.conf')
src/vars.c:1201: warning: initialized field overwritten
src/vars.c:1201: warning: (near initialization for 'rule.conf')

It's totally harmless anyway, but better clean this up.
2022-01-28 19:04:02 +01:00
Willy Tarreau
95d3eaff36 BUILD: checks: fix inlining issue on set_srv_agent_[addr,port}
These functions are declared as external functions in check.h and
as inline functions in check.c. Let's move them as static inline in
check.h. This appeared in 2.4 with the following commits:

  4858fb2e1 ("MEDIUM: check: align agentaddr and agentport behaviour")
  1c921cd74 ("BUG/MINOR: check: consitent way to set agentaddr")

While harmless (it only triggers build warnings with some gcc 4.x),
it should probably be backported where the paches above are present
to keep the code consistent.
2022-01-28 19:04:02 +01:00
Willy Tarreau
a65b4933ba BUILD: cpuset: do not use const on the source of CPU_AND/CPU_ASSIGN
The man page indicates that CPU_AND() and CPU_ASSIGN() take a variable,
not a const on the source, even though it doesn't make much sense. But
with older libcs, this triggers a build warning:

  src/cpuset.c: In function 'ha_cpuset_and':
  src/cpuset.c:53: warning: initialization discards qualifiers from pointer target type
  src/cpuset.c: In function 'ha_cpuset_assign':
  src/cpuset.c:101: warning: initialization discards qualifiers from pointer target type

Better stick stricter to the documented API as this is really harmless
here. There's no need to backport it (unless build issues are reported,
which is quite unlikely).
2022-01-28 19:04:02 +01:00
Willy Tarreau
8da23393a1 BUILD: atomic: make the old HA_ATOMIC_LOAD() support const pointers
We have an implementation of atomic ops for older versions of gcc that
do not provide the __builtin_* API (< 4.4). Recent changes to the pools
broke that in pool_releasable() by having a load from a const pointer,
which doesn't work there due to a temporary local variable that is
declared then assigned. Let's make use of a compount statement to assign
it a value when declaring it.

There's no need to backport this.
2022-01-28 19:04:02 +01:00
Willy Tarreau
e08acaed19 BUG/MEDIUM: mworker: close unused transferred FDs on load failure
When the master process is reloaded on a new config, it will try to
connect to the previous process' socket to retrieve all known
listening FDs to be reused by the new listeners. If listeners were
removed, their unused FDs are simply closed.

However there's a catch. In case a socket fails to bind, the master
will cancel its startup and swithc to wait mode for a new operation
to happen. In this case it didn't close the possibly remaining FDs
that were left unused.

It is very hard to hit this case, but it can happen during a
troubleshooting session with fat fingers. For example, let's say
a config runs like this:

   frontend ftp
        bind 1.2.3.4:20000-29999

The admin wants to extend the port range down to 10000-29999 and
by mistake ends up with:

   frontend ftp
        bind 1.2.3.41:20000-29999

Upon restart the bind will fail if the address is not present, and the
master will then switch to wait mode without releasing the previous FDs
for 1.2.3.4:20000-29999 since they're now apparently unused. Then once
the admin fixes the config and does:

   frontend ftp
        bind 1.2.3.4:10000-29999

The service will start, but will bind new sockets, half of them
overlapping with the previous ones that were not properly closed. This
may result in a startup error (if SO_REUSEPORT is not enabled or not
available), in a FD number exhaustion (if the error is repeated many
times), or in connections being randomly accepted by the process if
they sometimes land on the old FD that nobody listens on.

This patch will need to be backported as far as 1.8, and depends on
previous patch:

   MINOR: sock: move the unused socket cleaning code into its own function

Note that before 2.3 most of the code was located inside haproxy.c, so
the patch above should probably relocate the function there instead of
sock.c.
2022-01-28 19:04:02 +01:00
Willy Tarreau
b510116fd2 MINOR: sock: move the unused socket cleaning code into its own function
The startup code used to scan the list of unused sockets retrieved from
an older process, and to close them one by one. This also required that
the knowledge of the internal storage of these temporary sockets was
known from outside sock.c and that the code was copy-pasted at every
call place.

This patch moves this into sock.c under the name
sock_drop_unused_old_sockets(), and removes the xfer_sock_list
definition from sock.h since the rest of the code doesn't need to know
this.

This cleanup is minimal and preliminary to a future fix that will need
to be backported to all versions featuring FD transfers over the CLI.
2022-01-28 19:04:02 +01:00
Christopher Faulet
dd0b144c3a BUG/MINOR: sink: Use the right field in appctx context in release callback
In the release callback, ctx.peers was used instead of ctx.sft. Concretly,
it is not an issue because the appctx context is an union and these both
fields are structures with a unique pointer. But it will be a problem if
that changes.

This patch must be backported as far as 2.2.
2022-01-28 17:56:18 +01:00
Christopher Faulet
c2b7fa891c DEV: flags: Add missing flags
The flags dev tool was not updated since a while. Support for several flags
was missing. It is up to date now.
2022-01-28 17:56:18 +01:00
Christopher Faulet
0a82cf4c16 BUG/MEDIUM: resolvers: Really ignore trailing dot in domain names
When a string is converted to a domain name label, the trailing dot must be
ignored. In resolv_str_to_dn_label(), there is a test to do so. However, the
trailing dot is not really ignored. The character itself is not copied but
the string index is still moved to the next char. Thus, this trailing dot is
counted in the length of the last encoded part of the domain name. Worst,
because the copy is skipped, a garbage character is included in the domain
name.

This patch should fix the issue #1528. It must be backported as far as 2.0.
2022-01-28 17:56:18 +01:00
Amaury Denoyelle
0442efd214 MINOR: quic: refactor quic CID association with threads
Do not use an extra DCID parameter on new_quic_cid to be able to
associated a new generated CID to a thread ID. Simply do the computation
inside the function. The API is cleaner this way.

This also has the effects to improve the apparent randomness of CIDs.
With the previous version the first byte of all CIDs are identical for a
connection which could lead to privacy issue. This version may not be
totally perfect on this aspect but it improves the situation.
2022-01-28 16:29:27 +01:00
Frédéric Lécaille
df1c7c78c1 MINOR: quic: Iterate over all received datagrams
Make the listener datagram handler iterate over all received datagrams
2022-01-28 16:08:07 +01:00
Frédéric Lécaille
1712b1df59 MINOR: quic: Wrong RX buffer tail handling when no more contiguous data
The producer must know where is the tailing hole in the RX buffer
when it purges it from consumed datagram. This is done allocating
a fake datagram with the remaining number of bytes which cannot be produced
at the tail of the RX buffer as length.
2022-01-28 16:08:07 +01:00
Frédéric Lécaille
dc36404c36 MINOR: quic: Drop Initial packets with wrong ODCID
According to the RFC 9000, the client ODCID must have a minimal length of 8 bytes.
2022-01-28 16:08:07 +01:00
David Carlier
629cbdf5cc MEDIUM: da: update module to handle schedule mode.
The DeviceAtlas addon can optionally interacts with the new service
 without change of configuration in the HAProxy part.
Note that however it requires the DeviceAtlas Identification C API
2.4.0 minimum from this point.

Signed-off-by: David Carlier <dcarlier@deviceatlas.com>
2022-01-28 07:29:01 +01:00
David Carlier
b81483cf2d MEDIUM: da: update doc and build for new scheduler mode service.
Mentions of the new database update runtime mode and update of
the legit module and the dummy part too.
Note the DeviceAtlas C API version 2.4.0 minimum required
alongside with libCURL, libzip and libgz.
2022-01-28 07:28:53 +01:00
David Carlier
e9cff619c1 MEDIUM: da: new optional data file download scheduler service.
New specialized service to daily handle the update of download file without
interruption of service and to be preemptively started before HAProxy.
It consists on a standalone utility which shared a memory block with
the DeviceAtlas module which handles the JSON data file update on
a daily basis.

Signed-off-by: David Carlier <dcarlier@deviceatlas.com>
2022-01-28 07:23:07 +01:00
Frédéric Lécaille
74904a4792 MINOR: quic: Make usage of by datagram handler trees
The CID trees are no more attached to the listener receiver but to the
underlying datagram handlers (one by thread) which run always on the same thread.
So, any operation on these trees do not require any locking.
2022-01-27 16:37:55 +01:00
Frédéric Lécaille
9ea9463d47 MINOR: quic: Attach all the CIDs to the same connection
We copy the first octet of the original destination connection ID to any CID for
the connection calling new_quic_cid(). So this patch modifies only this function
to take a dcid as passed parameter.
2022-01-27 16:37:55 +01:00
Frédéric Lécaille
320744b53d MINOR: quic: Do not reset a full RX buffer
As the RX buffer is not consumed by the sock i/o handler as soon as a datagram
is produced, when full an RX buffer must not be reset. The remaining room is
consumed without modifying it. The consumer has a represention of its contents:
a list of datagrams.
2022-01-27 16:37:55 +01:00
Frédéric Lécaille
37ae505c21 MINOR: quic: Do not consume the RX buffer on QUIC sock i/o handler side
Rename quic_lstnr_dgram_read() to quic_lstnr_dgram_dispatch() to reflect its new role.
After calling this latter, the sock i/o handler must consume the buffer only if
the datagram it received is detected as wrong by quic_lstnr_dgram_dispatch().
The datagram handler task mark the datagram as consumed atomically setting ->buf
to NULL value. The sock i/o handler is responsible of flushing its RX buffer
before using it. It also keeps a datagram among the consumed ones so that
to pass it to quic_lstnr_dgram_dispatch() and prevent it from allocating a new one.
2022-01-27 16:37:55 +01:00
Frédéric Lécaille
794d068d8f MINOR: proto_quic: Wrong allocations for TX rings and RX bufs
As mentionned in the comment, the tx_qrings and rxbufs members of
receiver struct must be pointers to pointers!
Modify the functions responsible of their allocations consequently.
Note that this code could work because sizeof rxbuf and sizeof tx_qrings
are greater than the size of pointer!
2022-01-27 16:37:55 +01:00
Frédéric Lécaille
d152309423 CLEANUP: quic: Remove useless definition
The quic_dgram_ctx struct has been replaced by quic_dgram struct.
There is no need to keek a typedef for a pointer to function since we
converted the UDP datagram parser (quic_dgram_read()) into a task.
2022-01-27 16:37:55 +01:00
Frédéric Lécaille
25bc8875d7 MINOR: quic: Convert quic_dgram_read() into a task
quic_dgram_read() parses all the QUIC packets from a UDP datagram. It is the best
candidate to be converted into a task, because is processing data unit is the UDP
datagram received by the QUIC sock i/o handler. If correct, this datagram is
added to the context of a task, quic_lstnr_dghdlr(), a conversion of quic_dgram_read()
into a task. This task pop a datagram from an mt_list and passes it among to
the packet handler (quic_lstnr_pkt_rcv()).
Modify the quic_dgram struct to play the role of the old quic_dgram_ctx struct when
passed to quic_lstnr_pkt_rcv().
Modify the datagram handlers allocation to set their tasks to quic_lstnr_dghdlr().
2022-01-27 16:37:55 +01:00
Frédéric Lécaille
220894a5d6 MINOR: quic: Pass CID as a buffer to quic_get_cid_tid()
Very minor modification so that this function might be used for a context
without CID (at datagram level).
2022-01-27 16:37:55 +01:00
Frédéric Lécaille
69dd5e6a0b MINOR: proto_quic: Allocate datagram handlers
Add quic_dghdlr new struct do define datagram handler tasks, one by thread.
Allocate them and attach them to the listener receiver part calling
quic_alloc_dghdlrs_listener() newly implemented function.
2022-01-27 16:37:55 +01:00
Frédéric Lécaille
3d4bfe708a MINOR: quic: Allocate QUIC datagrams from sock I/O handler
Add quic_dgram new structure to store information about datagrams received
by the sock I/O handler (quic_sock_fd_iocb) and its associated pool.
Implement quic_get_dgram_dcid() to retrieve the datagram DCID which must
be the same for all the packets in the datagram.
Modify quic_lstnr_dgram_read() called by the sock I/O handler to allocate
a quic_dgram each time a correct datagram is found and add it to the sock I/O
handler rxbuf dgram list.
2022-01-27 16:37:55 +01:00
Frédéric Lécaille
53898bba81 MINOR: quic: Add a list to QUIC sock I/O handler RX buffer
This list will be used to store datagrams in the rxbuf struct used
by the quic_sock_fd_iocb() QUIC sock I/O handler with one rxbuf by thread.
2022-01-27 16:37:55 +01:00
Frédéric Lécaille
ce521e4f15 MINOR: quic: Add new defintion about DCIDs offsets
Define the offsets of the DCIDs from the beginning of a QUIC packets.
Note that they must always be present. As QUIC servers, QUIC haproxy listeners
always use a CID, source CID on the haproxy side, which is a destination ID on the
peer side.
2022-01-27 16:37:55 +01:00
Frédéric Lécaille
9cc64e2dba MINOR: quic: Remove the QUIC haproxy server packet parser
This function is no more used anymore, broken and uses code shared with the
listener packet parser. This is becoming anoying to continue to modify
it without testing each time we modify the code it shares with the
listener packet parser.
2022-01-27 16:37:55 +01:00
Frédéric Lécaille
3d55462654 MINOR: quic: Get rid of a struct buffer in quic_lstnr_dgram_read()
This is to be sure xprt functions do not manipulate the buffer struct
passed as parameter to quic_lstnr_dgram_read() from low level datagram
I/O callback in quic_sock.c (quic_sock_fd_iocb()).
2022-01-27 16:37:55 +01:00
Frédéric Lécaille
055ee6c14b MINOR: quic: Comment fix about the token found in Initial packets
Mention that the token is sent only by servers in both server and listener
packet parsers.
Remove a "TO DO" section in listener packet parser because there is nothing
more to do in this function about the token
2022-01-27 16:37:55 +01:00