Commit Graph

14033 Commits

Author SHA1 Message Date
Willy Tarreau
0bae075928 MEDIUM: pools: add CONFIG_HAP_NO_GLOBAL_POOLS and CONFIG_HAP_GLOBAL_POOLS
We've reached a point where the global pools represent a significant
bottleneck with threads. On a 64-core machine, the performance was
divided by 8 between 32 and 64 H2 connections only because there were
not enough entries in the local caches to avoid picking from the global
pools, and the contention on the list there was very high. It becomes
obvious that we need to have an array of lists, but that will require
more changes.

In parallel, standard memory allocators have improved, with tcmalloc
and jemalloc finding their ways through mainstream systems, and glibc
having upgraded to a thread-aware ptmalloc variant, keeping this level
of contention here isn't justified anymore when we have both the local
per-thread pool caches and a fast process-wide allocator.

For these reasons, this patch introduces a new compile time setting
CONFIG_HAP_NO_GLOBAL_POOLS which is set by default when threads are
enabled with thread local pool caches, and we know we have a fast
thread-aware memory allocator (currently set for glibc>=2.26). In this
case we entirely bypass the global pool and directly use the standard
memory allocator when missing objects from the local pools. It is also
possible to force it at compile time when a good allocator is used with
another setup.

It is still possible to re-enable the global pools using
CONFIG_HAP_GLOBAL_POOLS, if a corner case is discovered regarding the
operating system's default allocator, or when building with a recent
libc but a different allocator which provides other benefits but does
not scale well with threads.
2021-03-05 08:30:08 +01:00
Willy Tarreau
566cebc1fc BUG/MINOR: ssl: don't truncate the file descriptor to 16 bits in debug mode
Errors reported by ssl_sock_dump_errors() to stderr would only report the
16 lower bits of the file descriptor because it used to be casted to ushort.
This can be backported to all versions but has really no importance in
practice since this is never seen.
2021-03-05 08:30:08 +01:00
Ubuntu
f8fb4f75f1 MINOR: atomic: implement a more efficient arm64 __ha_cas_dw() using pairs
There finally is a way to support register pairs on aarch64 assembly
under gcc, it's just undocumented, like many of the options there :-(
As indicated below, it's possible to pass "%H" to mention the high
part of a register pair (e.g. "%H0" to go with "%0"):

  https://patchwork.ozlabs.org/project/gcc/patch/59368A74.2060908@foss.arm.com/

By making local variables from pairs of registers via a struct (as
is used in IST for example), we can let gcc choose the correct register
pairs and avoid a few moves in certain situations. The code is now slightly
more efficient than the previous one on AWS' Graviton2 platform, and
noticeably smaller (by 4.5kB approx). A few tests on older releases show
that even Linaro's gcc-4.7 used to support such register pairs and %H,
and by then ATOMICS were not supported so this should not cause build
issues, and as such this patch replaces the earlier implementation.
2021-03-05 08:30:08 +01:00
Willy Tarreau
46cca86900 MINOR: atomic: add armv8.1-a atomics variant for cas-dw
This variant uses the CASP instruction available on armv8.1-a CPU cores,
which is detected when __ARM_FEATURE_ATOMICS is set (gcc-linaro >= 7,
mainline >= 9). This one was tested on cortex-A55 (S905D3) and on AWS'
Graviton2 CPUs.

The instruction performs way better on high thread counts since it
guarantees some forward progress when facing extreme contention while
the original LL/SC approach is light on low-thread counts but doesn't
guarantee progress.

The implementation is not the most optimal possible. In particular since
the instruction requires to work on register pairs and there doesn't seem
to be a way to force gcc to emit register pairs, we have to decide to force
to use the pair (x0,x1) to store the old value, and (x2,x3) to store the
new one, and this necessarily involves some extra moves. But at least it
does improve the situation with 16 threads and more. See issue #958 for
more context.

Note, a first implementation of this function was making use of an
input/output constraint passed using "+Q"(*(void**)target), which was
resulting in smaller overall code than passing "target" as an input
register only. It turned out that the cause was directly related to
whether the function was inlined or not, hence the "forceinline"
attribute. Any changes to this code should still pay attention to this
important factor.
2021-03-05 08:30:08 +01:00
Willy Tarreau
168fc5332c BUG/MINOR: mt-list: always perform a cpu_relax call on failure
On highly threaded machines it is possible to occasionally trigger the
watchdog on certain contended areas like the server's connection list,
because while the mechanism inherently cannot guarantee a constant
progress, it lacks CPU relax calls which are absolutely necessary in
this situation to let a thread finish its job.

The loop's "while (1)" was changed to use a "for" statement calling
__ha_cpu_relax() as its continuation expression. This way the "continue"
statements jump to the unique place containing the pause without
excessively inflating the code.

This was sufficient to definitely fix the problem on 64-core ARM Graviton2
machines. This patch should probably be backported once it's confirmed it
also helps on many-cores x86 machines since some people are facing
contention in these environments. This patch depends on previous commit
"REORG: atomic: reimplement pl_cpu_relax() from atomic-ops.h".

An attempt was made to first read the value before exchanging, and it
significantly degraded the performance. It's very likely that this caused
other cores to lose exclusive ownership on their line and slow down their
next xchg operation.

In addition it was found that MT_LIST_ADD is significantly faster than
MT_LIST_ADDQ under high contention, because it fails one step earlier
when conflicting with an adjacent MT_LIST_DEL(). It might be worth
switching some operations' order to favor MT_LIST_ADDQ() instead.
2021-03-05 08:30:08 +01:00
Willy Tarreau
958ae26c35 REORG: atomic: reimplement pl_cpu_relax() from atomic-ops.h
There is some confusion here as we need to place some cpu_relax statements
in some loops where it's not easily possible to condition them on the use
of threads. That's what atomic.h already does. So let's take the various
pl_cpu_relax() implementations from there and place them in atomic.h under
the name __ha_cpu_relax() and let them adapt to the presence or absence of
threads and to the architecture (currently only x86 and aarch64 use a barrier
instruction), though it's very likely that arm would work well with a cache
flushing ISB instruction as well).

This time they were implemented as expressions returning 1 rather than
statements, in order to ease their placement as the loop condition or the
continuation expression inside "for" loops. We should probably do the same
with barriers and a few such other ones.
2021-03-05 08:30:08 +01:00
Tim Duesterhus
1568355afd CLEANUP: Replace for loop with only a condition by while
Refactoring performed with the following Coccinelle patch:

    @@
    expression e;
    statement S;
    @@

    - for (;e;)
    + while (e)
      S
2021-03-05 08:28:53 +01:00
Tim Duesterhus
dcf753aabe CLEANUP: Use the ist() macro whenever possible
Refactoring performed with the following Coccinelle patch:

    @@
    char *s;
    @@

    (
    - ist2(s, strlen(s))
    + ist(s)
    |
    - ist2(strdup(s), strlen(s))
    + ist(strdup(s))
    )

Note that this replacement is safe even in the strdup() case, because `ist()`
will not call `strlen()` on a `NULL` pointer. Instead is inserts a length of
`0`, effectively resulting in `IST_NULL`.
2021-03-05 08:28:53 +01:00
Amaury Denoyelle
f8b4292560 DOC: fix originalto except clause on destination address
Fix the description of the except clause of the originalto option. The
destination address and not the source is compared with the except range
address to prevent the addition of the X-Original-To header.

This can be backported in every releases.
2021-03-04 18:58:29 +01:00
Christopher Faulet
1e711beb51 CLEANUP: dns: Remove useless test on ns->dgram in dns_connect_nameserver()
When dns_connect_nameserver() is called, the nameserver has always a dgram
field properly defined. The caller, dns_send_nameserver(), already performed
the appropriate verification.
2021-03-04 16:58:36 +01:00
Christopher Faulet
1a1b674c2c CLEANUP: dns: Use DISGUISE() on a never-failing ring_attach() call
When a DNS session is created, the call to ring_attach() never fails. The
ring is freshly initialized and there is other watcher on it. Thus, the call
always succeeds.

Instead of catching an error that must never happen, we use the DISGUISE()
macro to make static analyzers happy.
2021-03-04 16:53:28 +01:00
Christopher Faulet
6f69110191 BUG/MINOR: server-state: Don't load server-state file for disabled backends
Recent changes on the server-state file loading have introduced a
regression. HAproxy crashes if a backend with no server-state file is
disabled in the configuration. Indeed, configuration of such backends is not
finalized. Thus many fields are not defined.

To fix the bug, disabled backends must be ignored. In addition a BUG_ON()
has been added to verify the proxy mode regarding the server-state file. It
must be specified (none, global or local) for enabled backends.

No backport needed.
2021-03-04 16:49:10 +01:00
Christopher Faulet
2ec4e3c1ac BUG/MINOR: hlua: Don't strip last non-LWS char in hlua_pushstrippedstring()
hlua_pushstrippedstring() function strips leading and trailing LWS
characters. But the result length it too short by 1 byte. Thus the last
non-LWS character is stripped. Note that a string containing only LWS
characters resulting to a stipped string with an invalid length (-1). This
leads to a lua runtime error.

This bug was reported in the issue #1155. It must be backported as far as
1.7.
2021-03-03 19:48:12 +01:00
Amaury Denoyelle
a47dfab673 REGTESTS: test http-reuse if no server target
Add two new regtests which check the behavior of http-reuse when the
connection target is not a server. More specifically check the dispatch
and transparent backend. In these cases, the behavior should be similar
to http-reuse never mode.
2021-03-03 11:40:25 +01:00
Amaury Denoyelle
8ede3db080 MINOR: backend: handle reuse for conns with no server as target
If dispatch mode or transparent backend is used, the backend connection
target is a proxy instead of a server. In these cases, the reuse of
backend connections is not consistent.

With the default behavior, no reuse is done and every new request uses a
new connection. However, if http-reuse is set to never, the connection
are stored by the mux in the session and can be reused for future
requests in the same session.

As no server is used for these connections, no reuse can be made outside
of the session, similarly to http-reuse never mode. A different
http-reuse config value should not have an impact. To achieve this, mark
these connections as private to have a defined behavior.

For this feature to properly work, the connection hash has been slightly
adjusted. The server pointer as an input as been replaced by a generic
target pointer to refer to the server or proxy instance. The hash is
always calculated on connect_server even if the connection target is not
a server. This also requires to allocate the connection hash node for
every backend connections, not just the one with a server target.
2021-03-03 11:31:19 +01:00
Amaury Denoyelle
68967e595b BUG/MINOR: backend: free allocated bind_addr if reuse conn
Fix a leak in connect_server which happens when a connection is reused
and a bind_addr was allocated because transparent mode is active. The
connection has already an allocated bind_addr so free the newly
allocated one.

No backport needed.
2021-03-03 11:28:02 +01:00
Amaury Denoyelle
603657835f CLEANUP: backend: fix a wrong comment
missing 'not' when skipping reuse if proxy mode not HTTP
2021-03-03 11:28:02 +01:00
Tim Duesterhus
2ca0bbc7d8 Revert "CI: Pin VTest to a known good commit"
The issue with VTest now is fixed in VTest master since commit
vtest/VTest@040bb6737a.

This reverts commit 24105300b8.
2021-03-03 05:07:10 +01:00
Tim Duesterhus
7b5777d9b4 CLEANUP: Use isttest(const struct ist) whenever possible
Refactoring performed with the following Coccinelle patch:

    @@
    struct ist i;
    @@

    - i.ptr != NULL
    + isttest(i)
2021-03-03 05:07:10 +01:00
Tim Duesterhus
154374cbc8 CLEANUP: Use istadv(const struct ist, const size_t) whenever possible
Refactoring performed with the following Coccinelle patch:

    @@
    struct ist i;
    expression e;
    @@

    - i.ptr += e;
    - i.len -= e;
    + i = istadv(i, e);
2021-03-03 05:07:10 +01:00
Tim Duesterhus
9f75ed114f CLEANUP: Reapply the ist2() replacement patch
One location was not matched due to a typo. Reapply the patch for consistency.

see 92c696e663
see a3298023b0
2021-03-03 05:07:10 +01:00
Tim Duesterhus
a3298023b0 BUG/MINOR: mux-h2: Fix typo in scheme adjustment
That comma should've been a semicolon. Fortunately, as it is now there
is no impact thanks to operators precedence, and all expressions are
properly evaluated. But this is troubling and the risk is high to
turn it into an effective bug with a minor change.

Introduced in b8ce8905cf which first
appeared in 2.1-dev3. This fix must be backported to 2.1+.
2021-03-02 14:13:57 +01:00
Frédéric Lécaille
8d4f1dd704 MINOR: contrib: Enhance peers dissector heuristic.
When receiving a stick-table message header as two first bytes of a TCP segement
we consider this as being part of a peer protocol session.
2021-03-02 11:08:45 +01:00
Frédéric Lécaille
200f8fc9c2 MINOR: contrib: add support for heartbeat control messages.
Nothing really complicated: add a new control message type for such heartbeat
messages.
2021-03-02 11:08:37 +01:00
Christopher Faulet
9536ad707f DOC: spoe: Add a note about fragmentation support in HAProxy
Add a note in SPOE.txt to make it clear that HAPRoxy does not support the
fragmentation. It can send fragmented frames if an agent supports it but it
cannot receives and handles fragmented frames.

This patch should fix the issue #659. It may be backported as far as 1.8.
2021-03-02 10:34:18 +01:00
Frédéric Lécaille
b28812af7a BUILD: quic: Implicit conversion between SSL related enums.
Fix such compilation issues:

include/haproxy/quic_tls.h:157:10: error: implicit conversion from
'enum ssl_encryption_level_t' to 'enum quic_tls_enc_level'
[-Werror=enum-conversion]
  157 |   return ssl_encryption_application;
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~
src/xprt_quic.c: In function 'quic_conn_enc_level_init':
src/xprt_quic.c:2358:13: error: implicit conversion from
'enum quic_tls_enc_level' to 'enum ssl_encryption_level_t'
[-Werror=enum-conversion]
 2358 |  qel->level = quic_to_ssl_enc_level(level);
      |             ^

Not detected by all the compilators.
2021-03-02 10:34:18 +01:00
Frédéric Lécaille
f57c64fc06 BUILD: proxy: Missing header inclusion for quic_transport_params_init()
Since this commit:
144289b45 ("REORG: move init_default_instance() to proxy.c and pass it the defproxy pointer")
as quic_transport_params_init() has been moved from cfgparse.c to proxy.c this
latter source file must include xprt_quic.h header.

Should fix #1153 issue.
2021-03-02 09:45:49 +01:00
Tim Duesterhus
68a088d851 CLEANUP: Use IST_NULL whenever possible
Refactoring performed with the following Coccinelle patch:

    @@
    @@

    - ist2(NULL, 0)
    + IST_NULL
2021-03-01 15:44:28 +01:00
Tim Duesterhus
92c696e663 CLEANUP: Use ist2(const void*, size_t) whenever possible
Refactoring performed with the following Coccinelle patch:

    @@
    struct ist i;
    expression p, l;
    @@

    - i.ptr = p;
    - i.len = l;
    + i = ist2(p, l);
2021-03-01 15:44:20 +01:00
Christopher Faulet
9e647e5af7 BUG/MEDIUM: spoe: Kill applets if there are pending connections and nbthread > 1
When the processing stage is finished for a SPOE applet, before returning it
into the idle list, we check if the assigned server appears as full or if
there are some pending connections on the backend or the assigned server. If
yes, it means we reach a maxconn and we close the applet to free a
slot. Otherwise, the applet can be reused. This test is only performed if
there are more than one thread.

It is important to close SPOE applets when there are pending connections for
multithreaded instances because connections with the SPOE agents are
persistent and local to a thread (applets are local to a thread). If a
maxconn is configured, some threads may take all available slots for a
while, leaving remaining threads without any free slot to process SPOE
messages. It is especially true if the maxconn is low.

This patch should fix the issue #705. It must be backported as far as
1.8. However, the code in 1.8 is quite different, a test must be performed
to be sure it works well.
2021-03-01 15:10:19 +01:00
Christopher Faulet
ae3056157c BUG/MINOR: connection: Use the client's dst family for adressless servers
When the selected server has no address, the destination address of the
client is used. However, for now, only the address is set, not the
family. Thus depending on how the server is configured and the client's
destination address, the server address family may be wrong.

For instance, with such server :

   server srv 0.0.0.0:0

The server address family is AF_INET. The server connection will fail if a
client is asking for an IPv6 destination.

To fix the bug, we take care to set the rigth family, the family of the
client destination address.

This patch should fix the issue #202. It must be backported to all stable
versions.
2021-03-01 11:34:00 +01:00
Christopher Faulet
e01ca0fbc9 BUG/MINOR: tcp-act: Don't forget to set the original port for IPv4 set-dst rule
If an IPv4 is set via a TCP/HTTP set-dst rule, the original port must be
preserved or set to 0 if the previous family was neither AF_INET nor
AF_INET6. The first case is not an issue because the port remains the
same. But if the previous family was, for instance, AF_UNIX, the port is not
set to 0 and have an undefined value.

This patch must be backported as far as 1.7.
2021-03-01 11:28:54 +01:00
Ilya Shipitsin
0de36adb5c CLEANUP: assorted typo fixes in the code and comments
This is 18th iteration of typo fixes
2021-02-27 09:01:43 +01:00
Ilya Shipitsin
0879c22723 CI: codespell: skip Makefile for spell check
checking Makefile is noisy, we do not benefit from it
2021-02-27 09:01:36 +01:00
Willy Tarreau
8ab65c201a [RELEASE] Released version 2.4-dev10
Released version 2.4-dev10 with the following main changes :
    - BUILD: SSL: introduce fine guard for RAND_keep_random_devices_open
    - MINOR: Configure the `cpp` userdiff driver for *.[ch] in .gitattributes
    - BUG/MINOR: ssl/cli: potential null pointer dereference in "set ssl cert"
    - BUG/MINOR: sample: secure convs that accept base64 string and var name as args
    - BUG/MEDIUM: vars: make functions vars_get_by_{name,desc} thread-safe
    - CLEANUP: vars: make smp_fetch_var() to reuse vars_get_by_desc()
    - DOC: muxes: add a diagram of the exchanges between muxes and outer world
    - BUG/MEDIUM: proxy: use thread-safe stream killing on hard-stop
    - BUG/MEDIUM: cli/shutdown sessions: make it thread-safe
    - BUG/MINOR: proxy: wake up all threads when sending the hard-stop signal
    - MINOR: stream: add an "epoch" to figure which streams appeared when
    - MINOR: cli/streams: make "show sess" dump all streams till the new epoch
    - MINOR: streams: use one list per stream instead of a global one
    - MEDIUM: streams: do not use the streams lock anymore
    - BUILD: dns: avoid a build warning when threads are disabled (dss unused)
    - MEDIUM: task: remove the tasks_run_queue counter and have one per thread
    - MINOR: tasks: do not maintain the rqueue_size counter anymore
    - CLEANUP: tasks: use a less confusing name for task_list_size
    - CLEANUP: task: move the tree root detection from __task_wakeup() to task_wakeup()
    - MINOR: task: limit the remote thread wakeup to the global runqueue only
    - MINOR: task: move the allocated tasks counter to the per-thread struct
    - CLEANUP: task: split the large tasklet_wakeup_on() function in two
    - BUG/MINOR: fd: properly wait for !running_mask in fd_set_running_excl()
    - BUG/MINOR: resolvers: Fix condition to release received ARs if not assigned
    - BUG/MINOR: resolvers: Only renew TTL for SRV records with an additional record
    - BUG/MINOR: resolvers: new callback to properly handle SRV record errors
    - BUG/MEDIUM: resolvers: Reset server address and port for obselete SRV records
    - BUG/MEDIUM: resolvers: Reset address for unresolved servers
    - DOC: Update the module list in MAINTAINERS file
    - MINOR: htx: Add function to reserve the max possible size for an HTX DATA block
    - DOC: Update the HTX API documentation
    - DOC: Update the filters guide
    - BUG/MEDIUM: contrib/prometheus-exporter: fix segfault in listener name dump
    - MINOR: task: split the counts of local and global tasks picked
    - MINOR: task: do not use __task_unlink_rq() from process_runnable_tasks()
    - MINOR: task: don't decrement then increment the local run queue
    - CLEANUP: task: re-merge __task_unlink_rq() with task_unlink_rq()
    - MINOR: task: make grq_total atomic to move it outside of the grq_lock
    - MINOR: tasks: also compute the tasklet latency when DEBUG_TASK is set
    - MINOR: task: make tasklet wakeup latency measurements more accurate
    - MINOR: server: Be more strict on the server-state line parsing
    - MINOR: server: Only fill one array when parsing a server-state line
    - MEDIUM: server: Refactor apply_server_state() to make it more readable
    - CLEANUP: server: Rename state_line node to node instead of name_name
    - CLEANUP: server: Rename state_line structure into server_state_line
    - CLEANUP: server: Use a local eb-tree to store lines of the global server-state file
    - MINOR: server: Be more strict when reading the version of a server-state file
    - MEDIUM: server: Store parsed params of a server-state line in the tree
    - MINOR: server: Remove cached line from global server-state tree when found
    - MINOR: server: Move loading state of servers in a dedicated function
    - MEDIUM: server: Use a tree to store local server-state lines
    - MINOR: server: Parse and store server-state lines in a dedicated function
    - MEDIUM: server: Don't load server-state file if a line is corrupted
    - REORG: server: Export and rename some functions updating server info
    - REORG: server-state: Move functions to deal with server-state in its own file
    - MINOR: server-state: Don't load server-state file for serverless proxies
    - CLEANUP: muxes: Remove useless if condition in show_fd function
    - BUG/MINOR: stats: fix compare of no-maint url suffix
    - MINOR: task: limit the number of subsequent heavy tasks with flag TASK_HEAVY
    - MINOR: ssl: mark the SSL handshake tasklet as heavy
    - CLEANUP: server: rename srv_cleanup_{idle,toremove}_connections()
    - BUG/MINOR: ssl: potential null pointer dereference in ckchs_dup()
    - MINOR: task: add one extra tasklet class: TL_HEAVY
    - MINOR: task: place the heavy elements in TL_HEAVY
    - MINOR: task: only limit TL_HEAVY tasks but not others
    - BUG/MINOR: http-ana: Only consider dst address to process originalto option
    - MINOR: tools: Add net_addr structure describing a network addess
    - MINOR: tools: Add function to compare an address to a network address
    - MEDIUM: http-ana: Add IPv6 support for forwardfor and orignialto options
    - CLEANUP: hlua: Use net_addr structure internally to parse and compare addresses
    - REGTESTS: Add script to test except param for fowardedfor/originalto options
    - DOC: scheduler: add a diagram showing the different queues and their usages
    - CLEANUP: tree-wide: replace free(x);x=NULL with ha_free(&x)
    - CLEANUP: config: replace a few free() with ha_free()
    - CLEANUP: vars: always zero the pointers after a free()
    - CLEANUP: ssl: remove a useless "if" before freeing an error message
    - CLEANUP: ssl: make ssl_sock_free_srv_ctx() zero the pointers after free
    - CLEANUP: ssl: use realloc() instead of free()+malloc()
2021-02-26 22:49:10 +01:00
Willy Tarreau
3bda3f422e CLEANUP: ssl: use realloc() instead of free()+malloc()
There was a free(ptr) followed by ptr=malloc(ptr, len), which is the
equivalent of ptr = realloc(ptr, len) but slower and less clean. Let's
replace this.
2021-02-26 21:27:33 +01:00
Willy Tarreau
e709e82173 CLEANUP: ssl: make ssl_sock_free_srv_ctx() zero the pointers after free
In ssl_sock_free_srv_ctx() there are some calls to free() which are not
followed by a zeroing of the pointers. For now this function is only used
during deinit but it could be used at run time in the near future, so
better secure this.
2021-02-26 21:23:06 +01:00
Willy Tarreau
01acf563a7 CLEANUP: ssl: remove a useless "if" before freeing an error message
Just an old "if (err) free(err)" that managed to escape cleanups.
2021-02-26 21:22:20 +01:00
Willy Tarreau
5b52b00393 CLEANUP: vars: always zero the pointers after a free()
In sample_store(), depending on the new sample types, the area pointer
was not always zeroed after being freed. Let's make sure it's always the
case to avoid the risk of dangling pointers being misused.
2021-02-26 21:21:21 +01:00
Willy Tarreau
35cd734356 CLEANUP: config: replace a few free() with ha_free()
A few occurrences of calls to free() to free a section name,
peers name or server name were using casts and didn't include
the trailing free, let's switch them to ha_free().
2021-02-26 21:21:21 +01:00
Willy Tarreau
61cfdf4fd8 CLEANUP: tree-wide: replace free(x);x=NULL with ha_free(&x)
This makes the code more readable and less prone to copy-paste errors.
In addition, it allows to place some __builtin_constant_p() predicates
to trigger a link-time error in case the compiler knows that the freed
area is constant. It will also produce compile-time error if trying to
free something that is not a regular pointer (e.g. a function).

The DEBUG_MEM_STATS macro now also defines an instance for ha_free()
so that all these calls can be checked.

178 occurrences were converted. The vast majority of them were handled
by the following Coccinelle script, some slightly refined to better deal
with "&*x" or with long lines:

  @ rule @
  expression E;
  @@
  - free(E);
  - E = NULL;
  + ha_free(&E);

It was verified that the resulting code is the same, more or less a
handful of cases where the compiler optimized slightly differently
the temporary variable that holds the copy of the pointer.

A non-negligible amount of {free(str);str=NULL;str_len=0;} are still
present in the config part (mostly header names in proxies). These
ones should also be cleaned for the same reasons, and probably be
turned into ist strings.
2021-02-26 21:21:09 +01:00
Willy Tarreau
ee17b97eea DOC: scheduler: add a diagram showing the different queues and their usages
The scheduler has become complex over time and the latest updates were a
good opportunity to document it. This diagram shows the time-based wait
queue(s), the priority-based run queue(s), and the class-based tasklet
queues, trying to emphasize what is local-only and what is shared between
threads. The diagram is provided in .fig, .svg, .png, and .pdf.
2021-02-26 17:49:37 +01:00
Christopher Faulet
3820ff8d2f REGTESTS: Add script to test except param for fowardedfor/originalto options
IPv6 support was added for these options. This script test different IPv4
and IPv6 combinations.
2021-02-26 13:53:26 +01:00
Christopher Faulet
29e9326f2f CLEANUP: hlua: Use net_addr structure internally to parse and compare addresses
hlua_addr structure may be replaced by net_addr structure to parse and
compare addresses. Both structures are similar.
2021-02-26 13:53:26 +01:00
Christopher Faulet
5d1def623a MEDIUM: http-ana: Add IPv6 support for forwardfor and orignialto options
A network may be specified to avoid header addition for "forwardfor" and
"orignialto" option via the "except" parameter. However, only IPv4
networks/addresses are supported. This patch adds the support of IPv6.

To do so, the net_addr structure is used to store the parameter value in the
proxy structure. And ipcmp2net() function is used to perform the comparison.

This patch should fix the issue #1145. It depends on the following commit:

  * c6ce0ab MINOR: tools: Add function to compare an address to a network address
  * 5587287 MINOR: tools: Add net_addr structure describing a network addess
2021-02-26 13:52:48 +01:00
Christopher Faulet
9553de7fec MINOR: tools: Add function to compare an address to a network address
ipcmp2net() function may be used to compare an addres (struct
sockaddr_storage) to a network address (struct net_addr). Among other
things, this function will be used to add support of IPv6 for "except"
parameter of "forwardfor" and "originalto" options.
2021-02-26 13:52:06 +01:00
Christopher Faulet
01f02a4d84 MINOR: tools: Add net_addr structure describing a network addess
The net_addr structure describes a IPv4 or IPv6 address. Its ip and mask are
represented. Among other things, this structure will be used to add support
of IPv6 for "except" parameter of "forwardfor" and "originalto" options.
2021-02-26 13:32:17 +01:00
Christopher Faulet
cccded98c7 BUG/MINOR: http-ana: Only consider dst address to process originalto option
When an except parameter is used for originalto option, only the destination
address must be evaluated. Especially, the address family of the destination
must be tested and not the source one.

This patch must be backported to all stable versions. However be careful,
depending the versions the code may be slightly different.
2021-02-26 13:32:14 +01:00
Willy Tarreau
76390dac06 MINOR: task: only limit TL_HEAVY tasks but not others
The preliminary approach to dealing with heavy tasks forced us to quit
the poller after meeting one. Now instead we process at most one per poll
loop and ignore the next ones, so that we get more bandwidth to process
all other classes.

Doing so further reduced the induced HTTP request latency at 100k req/s
under the stress of 1000 concurrent SSL handshakes in the following
proportions:

            |   default  | low-latency
   ---------+------------+--------------
    before  |   2.75 ms  |   2.0 ms
    after   |   1.38 ms  |   0.98 ms

In both cases, the latency is roughly halved. It's worth noting that
both values are now exactly 10 times better than in 2.4-dev9. Even the
percentiles have much improved. For 16 HTTP connections (1 per thread)
competing with 1000 SSL handshakes, we're seeing these long-tail
latencies (in milliseconds) :

              |  99.5%  |  99.9%  |  100%
   -----------+---------+---------+--------
   2.4-dev9   |  48.4   |  58.1   |  78.5
   previous   |   6.2   |  11.4   |  67.8
   this patch |   2.8   |   2.9   |   6.1

The task latency profiling report now shows this in default mode:
  $ socat - /tmp/sock1 <<< "show profiling"
  Per-task CPU profiling              : on      # set profiling tasks {on|auto|off}
  Tasks activity:
    function                      calls   cpu_tot   cpu_avg   lat_tot   lat_avg
    si_cs_io_cb                 3061966   2.224s    726.0ns   42.03s    13.72us
    h1_io_cb                    3061960   6.418s    2.096us   18.76m    367.6us
    process_stream              3059982   9.137s    2.985us   15.52m    304.3us
    ssl_sock_io_cb               602657   4.265m    424.7us   4.736h    28.29ms
    h1_timeout_task              202973      -         -      6.254s    30.81us
    accept_queue_process         135547   1.179s    8.699us   16.29s    120.1us
    srv_cleanup_toremove_conns       81   15.64ms   193.1us   30.87ms   381.1us
    task_run_applet                  10   758.7us   75.87us   51.77us   5.176us
    srv_cleanup_idle_conns            4   375.3us   93.83us   54.52us   13.63us

And this in low-latency mode, showing that both si_cs_io_cb() and process_stream()
have significantly benefitted from the improvement, with values 50 to 200 times
smaller than 2.4-dev9:
  $ socat - /tmp/sock1 <<< "show profiling"
  Per-task CPU profiling              : on      # set profiling tasks {on|auto|off}
  Tasks activity:
    function                      calls   cpu_tot   cpu_avg   lat_tot   lat_avg
    h1_io_cb                    6407006   11.86s    1.851us   31.14m    291.6us
    process_stream              6403890   18.40s    2.873us   2.134m    20.00us
    si_cs_io_cb                 6403866   4.139s    646.0ns   1.773m    16.61us
    ssl_sock_io_cb               894326   6.407m    429.9us   7.326h    29.49ms
    h1_timeout_task              301189      -         -      8.440s    28.02us
    accept_queue_process         211989   1.691s    7.977us   21.48s    101.3us
    srv_cleanup_toremove_conns      220   23.46ms   106.7us   65.61ms   298.2us
    task_run_applet                  16   1.219ms   76.17us   181.7us   11.36us
    srv_cleanup_idle_conns           12   713.3us   59.44us   168.4us   14.03us

The changes are slightly more invasive than previous ones and depend on
recent patches so they are not likely well suited for backporting.
2021-02-26 12:00:53 +01:00
Willy Tarreau
826fa87246 MINOR: task: place the heavy elements in TL_HEAVY
Instead of placing heavy tasklets into the TL_BULK queue, we now place
them into the TL_HEAVY one, which is assigned a default weight of ~1%
load at once. This way heavy tasks will not block TL_BULK anymore.
2021-02-26 12:00:53 +01:00