]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
4 years agoBUILD: stick-table: include freq_ctr.h from stick_table.h
Willy Tarreau [Sat, 8 May 2021 12:08:38 +0000 (14:08 +0200)] 
BUILD: stick-table: include freq_ctr.h from stick_table.h

It's needed for update_freq_ctr_period() which is used there.

4 years agoBUILD: udp: include tools.h from proto_udp.c
Willy Tarreau [Sat, 8 May 2021 11:59:56 +0000 (13:59 +0200)] 
BUILD: udp: include tools.h from proto_udp.c

A few functions are used from there for address conversion but the
file wasn't included.

4 years agoBUILD: queue: include tools.h from queue.c
Willy Tarreau [Sat, 8 May 2021 11:59:05 +0000 (13:59 +0200)] 
BUILD: queue: include tools.h from queue.c

It uses memprintf() without including the file because it inherited
it from other ones.

4 years agoBUILD: mworker: include tools.h from mworker.c
Willy Tarreau [Sat, 8 May 2021 11:58:19 +0000 (13:58 +0200)] 
BUILD: mworker: include tools.h from mworker.c

It needs it for memprintf() but didn't include the file.

4 years agoBUILD: compression: include tools.h in compression.c
Willy Tarreau [Sat, 8 May 2021 11:57:19 +0000 (13:57 +0200)] 
BUILD: compression: include tools.h in compression.c

It needs it for memprintf() but it wasn't included.

4 years agoBUILD: vars: include tools.h in vars.c
Willy Tarreau [Sat, 8 May 2021 11:56:31 +0000 (13:56 +0200)] 
BUILD: vars: include tools.h in vars.c

A number of functions from tools.h are used there but the file was not
included.

4 years agoBUILD: payload: include tools.h in payload.c
Willy Tarreau [Sat, 8 May 2021 11:55:40 +0000 (13:55 +0200)] 
BUILD: payload: include tools.h in payload.c

It needs it for memprintf() but used to inherit it via other include files.

4 years agoBUILD: dns: include tools.h in dns.c
Willy Tarreau [Sat, 8 May 2021 11:09:46 +0000 (13:09 +0200)] 
BUILD: dns: include tools.h in dns.c

It is used for get_addr_len() without being included. It could be worth
splitting address manipulation functions to a different set of files.

4 years agoBUILD: server-state: include tools.h from server_state.c
Willy Tarreau [Sat, 8 May 2021 11:08:34 +0000 (13:08 +0200)] 
BUILD: server-state: include tools.h from server_state.c

Many functions from tools.h are called there without the file being
included.

4 years agoBUILD: connection: include tools.h in connection.c
Willy Tarreau [Sat, 8 May 2021 11:07:31 +0000 (13:07 +0200)] 
BUILD: connection: include tools.h in connection.c

Several functions from tools.h are called there without the file being
included.

4 years agoBUILD: sink: include tools.h in sink.c
Willy Tarreau [Sat, 8 May 2021 11:05:30 +0000 (13:05 +0200)] 
BUILD: sink: include tools.h in sink.c

Several functions from tools.h are used in sink.c without tools.h being
included.

4 years agoBUILD: cache: include tools.h in cache.c
Willy Tarreau [Sat, 8 May 2021 11:03:55 +0000 (13:03 +0200)] 
BUILD: cache: include tools.h in cache.c

cache.c uses a lot of functions from tools.h without including it.

4 years agoBUILD: session: include tools.h in session.c
Willy Tarreau [Sat, 8 May 2021 11:03:04 +0000 (13:03 +0200)] 
BUILD: session: include tools.h in session.c

The file session.c calls plenty of functions from tools.h but did not
include it.

4 years agoBUILD: proxy: include tools.h in proxy.c
Willy Tarreau [Sat, 8 May 2021 11:02:07 +0000 (13:02 +0200)] 
BUILD: proxy: include tools.h in proxy.c

Many functions are used from tools.h but the file wasn't included and
was inherited through others.

4 years agoBUILD: htx: include tools.h in http_htx.c
Willy Tarreau [Sat, 8 May 2021 11:01:23 +0000 (13:01 +0200)] 
BUILD: htx: include tools.h in http_htx.c

Several functions from tools.h are called there and it used to be
inherited through others.

4 years agoBUILD: config: include tools.h in cfgparse-listen.c
Willy Tarreau [Sat, 8 May 2021 11:00:23 +0000 (13:00 +0200)] 
BUILD: config: include tools.h in cfgparse-listen.c

Many functions defined in tools.h were called there but the file used
to be inherited via others.

4 years agoBUILD: resolvers: include tools.h
Willy Tarreau [Sat, 8 May 2021 10:59:47 +0000 (12:59 +0200)] 
BUILD: resolvers: include tools.h

Many functions from tools.h are called there but it was inherited via others.

4 years agoBUILD: promex: service-prometheus.c needs tools.h
Willy Tarreau [Sat, 8 May 2021 10:58:12 +0000 (12:58 +0200)] 
BUILD: promex: service-prometheus.c needs tools.h

It calls url_decode() and memprintf() but used to inherit them through
others.

4 years agoBUILD: spoe: flt_spoe.c needs tools.h
Willy Tarreau [Sat, 8 May 2021 10:57:17 +0000 (12:57 +0200)] 
BUILD: spoe: flt_spoe.c needs tools.h

It uses many functions declared there but used to inherit it through others.

4 years agoBUILD: wurfl: wurfl.c needs tools.h
Willy Tarreau [Sat, 8 May 2021 10:56:20 +0000 (12:56 +0200)] 
BUILD: wurfl: wurfl.c needs tools.h

It calls memprintf() which is defined there but used to inherit it
through others.

4 years agoBUILD: config: cfgparse-ssl.c needs tools.h
Willy Tarreau [Sat, 8 May 2021 10:54:42 +0000 (12:54 +0200)] 
BUILD: config: cfgparse-ssl.c needs tools.h

It calls parse_time_err() which is defined there but used to inherit it
through others.

4 years agoBUILD: ssl: ssl_utils requires chunk.h
Willy Tarreau [Sat, 8 May 2021 10:52:56 +0000 (12:52 +0200)] 
BUILD: ssl: ssl_utils requires chunk.h

It uses chunk_printf() so it needs it. Currently it gets it through
others.

4 years agoREORG: mworker: move proc_self from global to mworker
Willy Tarreau [Sat, 8 May 2021 10:30:50 +0000 (12:30 +0200)] 
REORG: mworker: move proc_self from global to mworker

Only mworker uses proc_self, and it was declared in global.h, forcing
users of global.h to include mworker and its dependencies.

Moving it to mworker reduces the preprocessed size of version.c from
170 to 125kB by shrinking the number of local includes from 30 to 16
and the number of system includes from 147 to 132.

4 years agoBUILD: auth: include missing list.h
Willy Tarreau [Sat, 8 May 2021 10:29:51 +0000 (12:29 +0200)] 
BUILD: auth: include missing list.h

list_for_each_entry() requires list.h but used to inherit it by accident
through global.h and mworker-t.h. Let's explicitly add it.

4 years agoBUILD: wdt: include signal-t.h
Willy Tarreau [Sat, 8 May 2021 10:27:42 +0000 (12:27 +0200)] 
BUILD: wdt: include signal-t.h

WDT_SIG is used there, thus signal-t.h is required. Currently it's
retrieved by accident through global.h.

4 years agoREORG: threads: move all_thread_mask() to thread.h
Willy Tarreau [Sat, 8 May 2021 10:26:10 +0000 (12:26 +0200)] 
REORG: threads: move all_thread_mask() to thread.h

It was declared in global.h, forcing plenty of source files to include
it only for this while it's only based on definitions from thread.h.

4 years agoREORG: vars: move the "proc" scope variables out of the global struct
Willy Tarreau [Sat, 8 May 2021 09:41:28 +0000 (11:41 +0200)] 
REORG: vars: move the "proc" scope variables out of the global struct

The presence of this field causes a long dependency chain because almost
everyone includes global-t.h, and vars include sample_data which include
some system includes as well as HTTP parts.

There is absolutely no reason for having the process-wide variables in
the global struct, let's just move them into vars.c and vars.h. This
reduces from ~190k to ~170k the preprocessed output of version.c.

4 years agoMINOR: config: mark tune.fd.edge-triggered as experimental
Willy Tarreau [Sat, 8 May 2021 09:06:32 +0000 (11:06 +0200)] 
MINOR: config: mark tune.fd.edge-triggered as experimental

This one is stated as experimental in the doc but could still be used
by accidental copy-paste. Let's mark it with KWF_EXPERIMENTAL so that
users have to opt-in to use it.

4 years agoMINOR: stats: make "show info" able to report rates as floats when asked
Willy Tarreau [Sat, 8 May 2021 06:14:04 +0000 (08:14 +0200)] 
MINOR: stats: make "show info" able to report rates as floats when asked

Now "show info float" will also report SSL rates, connection rates and
key reuse ratios as floats. This can be convenient at very low rates.

Note that the SSL reuse ratio which used to commonly oscillate between
0 and 1 under load is now more often above zero with small values. It
indicates that for better stability we shouldn't be comparing a key rate
with a connection rate but instead we should measure the reuse rate at
its source.

4 years agoMINOR: stats: report uptime and start time as floats with subsecond resolution
Willy Tarreau [Sat, 8 May 2021 05:56:56 +0000 (07:56 +0200)] 
MINOR: stats: report uptime and start time as floats with subsecond resolution

When "show info float" is used, the uptime and start time will be reported
with subsecond resolution (microsecond actually since timeval is used).

4 years agoMINOR: stats: use tv_remain() to precisely compute the uptime
Willy Tarreau [Sat, 8 May 2021 05:40:52 +0000 (07:40 +0200)] 
MINOR: stats: use tv_remain() to precisely compute the uptime

We'll have to support reporting sub-second uptimes, so let's use the
appropriate function which will automatically adjust the tv_usec field.
In addition to this, it will also report a more accurate uptime thanks
to considering the sub-second part in the result.

4 years agoMINOR: stats: support an optional "float" option to "show info"
Willy Tarreau [Sat, 8 May 2021 05:54:24 +0000 (07:54 +0200)] 
MINOR: stats: support an optional "float" option to "show info"

This will allow some fields to be produced with a higher accuracy when
the requester indicates being able to parse floats. Rates and times are
among the elements which can make sense.

4 years agoMINOR: stats: pass the appctx flags to stats_fill_info()
Willy Tarreau [Sat, 8 May 2021 05:43:53 +0000 (07:43 +0200)] 
MINOR: stats: pass the appctx flags to stats_fill_info()

Currently the stats filling function knows nothing about the caller's
needs, so let's pass the STAT_* flags so that it can adapt to the
requester's constraints.

4 years agoMINOR: stats: add the HTML conversion for float types
Willy Tarreau [Sat, 8 May 2021 05:37:38 +0000 (07:37 +0200)] 
MINOR: stats: add the HTML conversion for float types

For the prometheus exporter, a new float type was added for the fields
and its conversion was added everywhere except for the HTML output.
Now that we have F2H() we can implement it for consistency.

4 years agoMINOR: stats: avoid excessive padding of float values with trailing zeroes
Willy Tarreau [Sat, 8 May 2021 08:38:20 +0000 (10:38 +0200)] 
MINOR: stats: avoid excessive padding of float values with trailing zeroes

When emitting stats, we don't need to have 6 zeroes after the decimal point
for each value, so let's trim floating point numbers to the longest needed
only.

4 years agoMINOR: freq_ctr: add new functions to report float measurements
Willy Tarreau [Sat, 8 May 2021 06:12:37 +0000 (08:12 +0200)] 
MINOR: freq_ctr: add new functions to report float measurements

For stats reporting it can be convenient to report floats at low rates
instead of discrete integers. We do have quite some precision since we
currently divide counters by number of milliseconds, so we can usually
add 3 digits after the decimal point.

4 years agoMINOR: tools: add a float-to-ascii conversion function
Willy Tarreau [Sat, 8 May 2021 05:35:00 +0000 (07:35 +0200)] 
MINOR: tools: add a float-to-ascii conversion function

We already had ultoa_r() and friends but nothing to emit inline floats.
This is now done with ftoa_r() and F2A/F2H. Note that the latter both use
the itoa_str[] as temporary storage and that the HTML format currently is
the exact same as the ASCII one. The trailing zeroes are always timmed so
these outputs are usable in user-visible output.

4 years agoMINOR: tools: implement trimming of floating point numbers
Willy Tarreau [Sat, 8 May 2021 08:28:53 +0000 (10:28 +0200)] 
MINOR: tools: implement trimming of floating point numbers

When using "%f" to print a float, it automatically gets 6 digits after
the decimal point and there's no way to automatically adjust to the
required ones by dropping trailing zeroes. This function does exactly
this and automatically drops the decimal point if all digits after it
were zeroes. This will make numbers more friendly in stats and makes
outputs shorter (e.g. JSON where everything is just a "number").

The function is designed to be easy to use with snprint() and chunks:

  snprintf:
    flt_trim(buf, 0, snprintf(buf, sizeof(buf), "%f", x));

  chunk_printf:
    out->data = flt_trim(out->area, 0, chunk_printf(out, "%f", x));

  chunk_appendf:
    size_t prev_data = out->data;
    out->data = flt_trim(out->area, prev_data, chunk_appendf(out, "%f", x));

4 years agoDOC: management: mention that some fields may be emitted as floats
Willy Tarreau [Sat, 8 May 2021 05:46:44 +0000 (07:46 +0200)] 
DOC: management: mention that some fields may be emitted as floats

Floats in stats output are currently not emitted but are technically
possible, so let's mention that.

4 years agoMINOR: sample: improve error reporting on missing arg to strcmp() converter
Willy Tarreau [Sat, 8 May 2021 04:50:28 +0000 (06:50 +0200)] 
MINOR: sample: improve error reporting on missing arg to strcmp() converter

Calling the strcmp() converter with no argument yields this strange error:

  [ALERT]    (31439) : parsing [test.cfg:3] : error detected in frontend 'f' while parsing 'http-request redirect' rule : failed to parse sample expression <src,strcmp]> : invalid args in converter 'strcmp' : failed to register variable name ''.

This is because the vars name check tries to see if it can create such a
variable having an empty name. Let's at least make a special case of the
missing argument. Now we can read a more explicit:

  [ALERT]    (31655) : parsing [test.cfg:3] : error detected in frontend 'f' while parsing 'http-request redirect' rule : failed to parse sample expression <src,strcmp]> : invalid args in converter 'strcmp' : missing variable name.

This was done for secure_strcmp() as well.

4 years agoDOC: ssl: Add information about crl-file option
Remi Tricot-Le Breton [Tue, 4 May 2021 10:22:34 +0000 (12:22 +0200)] 
DOC: ssl: Add information about crl-file option

When using the crl-file option with multiple Certificate Authority
levels in the CA chain, there must be one CRL per CA or the verify
function on the backend side will raise an "unagle to get certificate
CRL" error (error code 3).

This was required by GitHub issue #1201.

4 years agoADDONS: make addons/ discoverable by git via .gitignore
Willy Tarreau [Fri, 7 May 2021 14:46:52 +0000 (16:46 +0200)] 
ADDONS: make addons/ discoverable by git via .gitignore

When the contrib/ parts were moved to addons/, no rule was added in
.gitignore to make addons/ searchable for new files, let's fix it.

4 years agoDOC: ssl: Extra files loading now works for backends too
Remi Tricot-Le Breton [Fri, 7 May 2021 13:28:08 +0000 (15:28 +0200)] 
DOC: ssl: Extra files loading now works for backends too

When implementing the server side certificate hot update, the ckch
mechanism was used on the backend side in order to mimic the frontend
certificate management and to enable server line certificate update via
the CLI (see GitHub issue #427). As an unexpected side effect, we now
also look for ssl extra files (cert.pem.key, cert.pem.ocsp ...) for the
backend side.
This patch updates the documentation accordingly.

This answers to GitHub issue #845.

4 years agoBUG/MINOR: server: do not report diag for peer servers with null weight
Amaury Denoyelle [Fri, 7 May 2021 13:13:51 +0000 (15:13 +0200)] 
BUG/MINOR: server: do not report diag for peer servers with null weight

Only check servers attached to a proxy with PR_CAP_LB.

This does not need to be backported as the diag message was added in the
current 2.4-dev branch.

4 years agoMINOR: proxy: define PR_CAP_LB
Amaury Denoyelle [Fri, 7 May 2021 13:12:20 +0000 (15:12 +0200)] 
MINOR: proxy: define PR_CAP_LB

Add a new proxy capability for proxy with load-balancing capabilities.
This help to differentiate listen/frontend/backend with special proxies
such as peer proxies.

4 years agoBUILD: fix usage of ha_alert without format string
Amaury Denoyelle [Fri, 7 May 2021 13:07:21 +0000 (15:07 +0200)] 
BUILD: fix usage of ha_alert without format string

The compilation is failing due to no format string used in ha_alert.
This does not need to be backported.

4 years agoMINOR: http_act: mark normalize-uri as experimental
Amaury Denoyelle [Thu, 6 May 2021 13:50:12 +0000 (15:50 +0200)] 
MINOR: http_act: mark normalize-uri as experimental

normalize-uri http rule is marked as experimental, so it cannot be
activated without the global 'expose-experimental-directives'. The
associated vtc is updated to be able to use it.

4 years agoMINOR: stats: report tainted on show info
Amaury Denoyelle [Wed, 5 May 2021 15:09:12 +0000 (17:09 +0200)] 
MINOR: stats: report tainted on show info

Add a new info field ST_F_TAINTED to dump tainted status at the end of
the 'show info' output.

4 years agoMINOR: cli: set tainted when using CLI expert/experimental mode
Amaury Denoyelle [Wed, 5 May 2021 14:29:23 +0000 (16:29 +0200)] 
MINOR: cli: set tainted when using CLI expert/experimental mode

Mark the process as tainted as soon as a command command only accessible
in expert or experimental mode is executed.

4 years agoMINOR: action: implement experimental actions
Amaury Denoyelle [Fri, 7 May 2021 12:25:01 +0000 (14:25 +0200)] 
MINOR: action: implement experimental actions

Support experimental actions. It is mandatory to use
'expose-experimental-directives' before to be able to use them.

If such action is present in the config file, the tainted status of the
process is updated. Another tainted status is set when an experimental
action is executed.

4 years agoMINOR: action: replace match_pfx by a keyword flags field
Amaury Denoyelle [Thu, 6 May 2021 13:33:09 +0000 (15:33 +0200)] 
MINOR: action: replace match_pfx by a keyword flags field

Define a new keyword flag KWF_MATCH_PREFIX. This is used to replace the
match_pfx field of action struct.

This has the benefit to have more explicit action declaration, and now
it is possible to quickly implement experimental actions.

4 years agoMINOR: cfgparse: implement experimental config keywords
Amaury Denoyelle [Thu, 6 May 2021 14:21:39 +0000 (16:21 +0200)] 
MINOR: cfgparse: implement experimental config keywords

Add a new flag to mark a keyword as experimental. An experimental
keyword cannot be used if the global 'expose-experimental-directives' is
not present first.

Only keywords parsed through a standard cfg_keywords lists in
global/proxies section will be automatically detected if declared
experimental. To support a keyword outside of these lists,
check_kw_experimental must be called manually during its parsing.

If an experimental keyword is present in the config, the tainted flag is
updated.

For the moment, no keyword is marked as experimental.

4 years agoMINOR: cfgparse: add a new field flags in cfg_keyword
Amaury Denoyelle [Thu, 6 May 2021 15:33:29 +0000 (17:33 +0200)] 
MINOR: cfgparse: add a new field flags in cfg_keyword

This field will be used to add various mechanism to config parsing.
Currently no flag value is implemented. The following commit will
implement experimental keywords.

4 years agoMINOR: global: define tainted flag
Amaury Denoyelle [Wed, 5 May 2021 14:18:45 +0000 (16:18 +0200)] 
MINOR: global: define tainted flag

Add a global flag named 'tainted'. Its purpose is to report various
status about experimental features used for the current process
lifetime.

By default it is initialized to 0. It can be set/retrieve by a couple of
new functions mark_tainted()/get_tainted(). Once a flag is set, it
cannot be resetted.

Currently, no tainted status is implemented, it will be the subject of
the following commits.

4 years agoBUG/MINOR: checks: Reschedule check on observe mode only if fastinter is set
Christopher Faulet [Fri, 7 May 2021 09:45:26 +0000 (11:45 +0200)] 
BUG/MINOR: checks: Reschedule check on observe mode only if fastinter is set

On observe mode, if a server is marked as DOWN, the server's health-check is
rescheduled using the fastinter timeout if the new expiration date is newer
that the current one. But this must only be performed if the fastinter
timeout is defined.

Internally, tick_is_lt() function only checks the date and does not perform any
verification on the provided args. Thus, we must take care of it. However, it is
possible to disable the server health-check by setting its task expiration date
to TICK_ETERNITY.

This patch must be backported as far as 2.2. It is related to

4 years agoBUG/MINOR: checks: Handle synchronous connect when a tcpcheck is started
Christopher Faulet [Thu, 6 May 2021 14:01:18 +0000 (16:01 +0200)] 
BUG/MINOR: checks: Handle synchronous connect when a tcpcheck is started

A connection may be synchronously established. In the tcpcheck context, it
may be a problem if several connections come one after another. In this
case, there is no event to close the very first connection before starting
the next one. The checks is thus blocked and timed out, a L7 timeout error
is reported.

To fix the bug, when a tcpcheck is started, we immediately evaluate its
state. Most of time, nothing is performed and we must wait. But it is thus
possible to handle the result of a successfull connection.

This patch should fix the issue #1234. It must be backported as far as 2.2.

4 years agoBUG/MINOR: stream: Reset stream final state and si error type on L7 retry
Christopher Faulet [Wed, 5 May 2021 19:05:09 +0000 (21:05 +0200)] 
BUG/MINOR: stream: Reset stream final state and si error type on L7 retry

Thanks to a previous fix, the stream error mask is now cleared on L7
retry. But the stream final state (SF_FINST_*) and the stream-interface
error type must also be reset to properly restart a new connection and be
sure to not inherit errors from the previous connection attempt.

In addition, SF_ADDR_SET flag is not systematically removed.
stream_choose_redispatch() already takes care to unset it if necessary. When
the connection is not redispatch, the server address can be preserved.

This patch must be backported as far as 2.0.

4 years agoCLEANUP: cli/tree-wide: properly re-align the CLI commands' help messages
Willy Tarreau [Fri, 7 May 2021 09:38:37 +0000 (11:38 +0200)] 
CLEANUP: cli/tree-wide: properly re-align the CLI commands' help messages

There were 102 CLI commands whose help were zig-zagging all along the dump
making them unreadable. This patch realigns all these messages so that the
command now uses up to 40 characters before the delimiting colon. About a
third of the commands did not correctly list their arguments which were
added after the first version, so they were all updated. Some abuses of
the term "id" were fixed to use a more explanatory term. The
"set ssl ocsp-response" command was not listed because it lacked a help
message, this was fixed as well. The deprecated enable/disable commands
for agent/health/server were prominently written as deprecated. Whenever
possible, clearer explanations were provided.

4 years agoMINOR: config: add a new message directive: .diag
Willy Tarreau [Fri, 7 May 2021 06:59:50 +0000 (08:59 +0200)] 
MINOR: config: add a new message directive: .diag

This one works just like .notice/.warning/.alert except that it prints
the message at level "DIAG" only when haproxy runs in diagnostic mode
(-dD). This can be convenient for example to pass a few hints to help
locate certain config parts or to leave messages about certain temporary
workarounds.

Example:

  .diag "WTA/2021-05-07: $.LINE: replace 'redirect' with 'return' after final switch to 2.4"
         http-request redirect location /goaway if ABUSE

4 years agoMEDIUM: log: slightly refine the output format of alerts/warnings/etc
Willy Tarreau [Fri, 7 May 2021 06:42:39 +0000 (08:42 +0200)] 
MEDIUM: log: slightly refine the output format of alerts/warnings/etc

For about 20 years we've been emitting cryptic messages on warnings and
alerts, that nobody knows how to parse:

  [NOTICE] 126/080118 (3115) : haproxy version is 2.4-dev18-0b7c78-49
  [NOTICE] 126/080118 (3115) : path to executable is ./haproxy
  [WARNING] 126/080119 (3115) : Server default/srv1 is DOWN via static/srv1. 0 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
  [ALERT] 126/080119 (3115) : backend 'default' has no server available!

Hint: the first 3-digit number is the day of year, and the 6 digits
after it represent the time of day in format HHMMSS, then the pid in
parenthesis. These are not quite user-friendly and such cryptic into
are not useful at all.

This patch slightly adjusts the output by performing these minimal changes:
  - removing the date/time, as they were added very early when haproxy
    was meant to be used in foreground as a debugging tool, and they're
    provided in more details in logs nowadays ;

  - better aligning the fields by padding the severity tag to 10 chars.
    The diag output was renamed to "DIAG" only.

Now the output provides this:

  [NOTICE]   (4563) : haproxy version is 2.4-dev18-75a428-51
  [NOTICE]   (4563) : path to executable is ./haproxy
  [WARNING]  (4563) : Server default/srv1 is DOWN via static/srv1. 0 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
  [ALERT]    (4563) : backend 'default' has no server available!

The useless space before the colon was kept so as not to confuse any
possible output parser.

The few entries in the doc referring to this format were adjusted to
reflect the new one.

The change was tagged "MEDIUM" as it may have visible consequences on
home-grown monitoring tools, though it is extremely unlikely due to the
limited extent of these changes.

4 years agoBUG/MINOR: stream: properly clear the previous error mask on L7 retries
Willy Tarreau [Fri, 7 May 2021 06:19:30 +0000 (08:19 +0200)] 
BUG/MINOR: stream: properly clear the previous error mask on L7 retries

The cleanup of the previous error was incorrect on L7 retries, it would
OR two values while they're part of an enum, leaving some bits set.
Depending on the errors it was possible to occasionally see an internal
error ("I" flag) being logged.

This should be backported as far as 2.0, though the do_l7_retry() function
in in proto_htx.c in older versions.

4 years agoBUG/MINOR: activity: use the new pointer to calculate the new size in realloc()
Willy Tarreau [Fri, 7 May 2021 06:01:35 +0000 (08:01 +0200)] 
BUG/MINOR: activity: use the new pointer to calculate the new size in realloc()

When memory profiling is enabled, realloc() can occasionally get the area
size wrong due to the wrong pointer being used to check the new size. When
the old area gets unmapped in the operation, this may even result in a
crash. There's no impact without memory profiling though.

No backport is needed as this is exclusively 2.4-dev.

4 years agoMINOR: config: add predicates "version_atleast" and "version_before" to cond blocks
Willy Tarreau [Thu, 6 May 2021 14:53:26 +0000 (16:53 +0200)] 
MINOR: config: add predicates "version_atleast" and "version_before" to cond blocks

These predicates respectively verify that the current version is at least
a given version or is before a specific one. The syntax is exactly the one
reported by "haproxy -v", though each component is optional, so both "1.5"
and "2.4-dev18-88910-48" are supported. Missing components equal zero, and
"dev" is below "pre" or "rc", which are both inferior to no such mention
(i.e. they are negative). Thus "2.4-dev18" is older than "2.4-rc1" which
is older than "2.4".

4 years agoMINOR: config: add predicate "feature" to detect certain built-in features
Willy Tarreau [Thu, 6 May 2021 14:34:23 +0000 (16:34 +0200)] 
MINOR: config: add predicate "feature" to detect certain built-in features

The "feature(name)" predicate will return true if <name> corresponds to
a name listed after a '+' in the features list, that is it was enabled at
build time with USE_<name>=1. Typical use cases will include OPENSSL, LUA
and LINUX_SPLICE. But maybe it will also be convenient to use with optional
addons such as PROMEX and the device detection modules to help keeping the
same configs across various deployments.

4 years agoMINOR: config: add predicates "streq()" and "strneq()" to conditional expressions
Willy Tarreau [Thu, 6 May 2021 14:10:09 +0000 (16:10 +0200)] 
MINOR: config: add predicates "streq()" and "strneq()" to conditional expressions

"streq(str1,str2)" will return true if the two strings match while
"strneq(str1,str2)" will return true only if they differ. This is
convenient to match an environment variable against a predefined value.

4 years agoMINOR: config: add predicate "defined()" to conditional expression blocks
Willy Tarreau [Thu, 6 May 2021 13:55:14 +0000 (15:55 +0200)] 
MINOR: config: add predicate "defined()" to conditional expression blocks

"defined(name)" will return true if <name> is a defined environment variable
otherwise false, regardless of its contents.

4 years agoMINOR: config: make cfg_eval_condition() support predicates with arguments
Willy Tarreau [Thu, 6 May 2021 13:49:04 +0000 (15:49 +0200)] 
MINOR: config: make cfg_eval_condition() support predicates with arguments

Now we can look up a list of known predicates and pre-parse their
arguments. For now the list is empty. The code needed to be arranged with
a common exit point to release all arguments because there's no default
argument freeing function (it likely only used to exist in the deinit
code). Since we only support simple arguments for now it's no big deal,
only a 2-liner loop.

4 years agoMINOR: config: improve .if condition error reporting
Willy Tarreau [Thu, 6 May 2021 13:07:10 +0000 (15:07 +0200)] 
MINOR: config: improve .if condition error reporting

Let's return the position of the first unparsable character on error,
so that instead of just saying "unparsable conditional expression blah"
we can have:

  [ALERT] 125/150618 (13995) : parsing [test-conds2.cfg:1]: unparsable conditional expression '12/blah' in '.if' at position 1:
    .if 12/blah
        ^
This is important because conditions will be made from environment
variables or later from more complex expressions where the error will
not always be easy to locate.

4 years agoMINOR: global: add version comparison functions
Willy Tarreau [Thu, 6 May 2021 05:43:35 +0000 (07:43 +0200)] 
MINOR: global: add version comparison functions

The new function split_version() converts a parsable haproxy version to
an array of integers. The function compare_current_version() compares an
arbitrary version to the current one. These two functions were written
by Thierry Fournier in 2013, and are still usable as-is. They will be
used to write config language predicates.

4 years agoMINOR: global: export the build features string list
Willy Tarreau [Thu, 6 May 2021 14:30:32 +0000 (16:30 +0200)] 
MINOR: global: export the build features string list

Till now it was only presented in the version output but could not be
consulted outside of haproxy.c, let's export it as a variable, and set
it to an empty string if not defined.

4 years agoMINOR: arg: improve the error message on missing closing parenthesis
Willy Tarreau [Thu, 6 May 2021 12:50:30 +0000 (14:50 +0200)] 
MINOR: arg: improve the error message on missing closing parenthesis

When the closing brace is missing after an argument (acl, ...), the
error may report something like "expected ')' before ''". Let's just
drop "before ''" when the final word is empty to make the message a
bit clearer.

4 years agoBUILD: activity: do not include malloc.h
Willy Tarreau [Thu, 6 May 2021 09:37:53 +0000 (11:37 +0200)] 
BUILD: activity: do not include malloc.h

It doesn't exist on MacOS and broke the build. We don't need it as it's
already included by compat.h when relevant. No backport is needed.

4 years agoMINOR: config: support some pseudo-variables for file/line/section
Willy Tarreau [Thu, 6 May 2021 08:25:11 +0000 (10:25 +0200)] 
MINOR: config: support some pseudo-variables for file/line/section

The new pseudo-variables ".FILE", ".LINE" and ".SECTION" will be resolved
on the fly by the config parser and will respectively retrieve the current
configuration file name, the current line number and the current section
being parsed. This may help emit logs, errors, and debugging information
(e.g. which rule matched).

The '.' in the first char was reserved for such pseudo-variables and no
other variable is permitted. This will allow to add support for new ones
in the future if they prove to be useful (e.g. randoms/uuid for secret
keying or automatic naming of configuration objects).

4 years agoMINOR: config: keep up-to-date current file/line/section in the global struct
Willy Tarreau [Thu, 6 May 2021 08:04:45 +0000 (10:04 +0200)] 
MINOR: config: keep up-to-date current file/line/section in the global struct

Let's add a few fields to the global struct to store information about
the current file being processed, the current line number and the current
section. This will be used to retrieve them using special variables.

4 years agoMINOR: config: centralize the ".if"/".elif" condition parser and evaluator
Willy Tarreau [Thu, 6 May 2021 06:19:48 +0000 (08:19 +0200)] 
MINOR: config: centralize the ".if"/".elif" condition parser and evaluator

Instead of duplicating the condition evaluations, let's have a single
function cfg_eval_condition() that returns true/false/error. It takes
less code and will ease its extension.

4 years agoBUG/MINOR: config: .if/.elif should also accept negative integers
Willy Tarreau [Thu, 6 May 2021 05:52:50 +0000 (07:52 +0200)] 
BUG/MINOR: config: .if/.elif should also accept negative integers

The doc about .if/.elif config block conditions says:

  a non-nul integer (e.g. '1'), always returns "true"

So we must accept negative integers as well. The test was made on
atoi() > 0.

No backport is needed, this is only 2.4.

4 years agoBUG/MINOR: config: add a missing "ELIF_TAKE" test for ".elif" condition evaluator
Willy Tarreau [Thu, 6 May 2021 06:48:09 +0000 (08:48 +0200)] 
BUG/MINOR: config: add a missing "ELIF_TAKE" test for ".elif" condition evaluator

This missing state was causing a second elif condition to be evaluated
after a first one succeeded after a .if failed. For example in the test
below the else would be executed:

     .if    0
     .elif  1
     .elif  0
     .else
     .endif

No backport is needed, this is 2.4-only.

4 years agoBUG/MINOR: config: fix uninitialized initial state in ".if" block evaluator
Willy Tarreau [Thu, 6 May 2021 06:46:11 +0000 (08:46 +0200)] 
BUG/MINOR: config: fix uninitialized initial state in ".if" block evaluator

The condition to skip the block in the ".if" evaluator forgot to check
that the level was high enough, resulting in rare cases where a random
value matched one of the 5 values that cause the block to be skipped.

No backport is needed as it's 2.4-only.

4 years agoBUG/MINOR: stream: Decrement server current session counter on L7 retry
Christopher Faulet [Wed, 5 May 2021 16:23:59 +0000 (18:23 +0200)] 
BUG/MINOR: stream: Decrement server current session counter on L7 retry

When a L7 retry is performed, we must not forget to decrement the current
session counter of the assigned server. Of course, it must only be done if
the current session is already counted on the server, thus if SF_CURR_SESS
flag is set on the stream.

This patch is related to the issue #1003. It must be backported as far as
2.0.

4 years agoMINOR: mux-h1: Manage processing blocking flags on the H1 stream
Christopher Faulet [Wed, 7 Apr 2021 12:18:11 +0000 (14:18 +0200)] 
MINOR: mux-h1: Manage processing blocking flags on the H1 stream

Because H1C_F_RX_BLK and H1C_F_TX_BLK flags now only concerns data
processing, at the H1 stream level, there is no reason to still manage them
on the H1 connection. Thus, these flags are now set on the H1 stream.

4 years agoCLEANUP: mux-h1: rename WAIT_INPUT/WAIT_OUTPUT flags
Christopher Faulet [Wed, 7 Apr 2021 09:50:26 +0000 (11:50 +0200)] 
CLEANUP: mux-h1: rename WAIT_INPUT/WAIT_OUTPUT flags

These flags are used to block, respectively, the output and the input
processing. Thus, to be more explicit, H1C_F_WAIT_INPUT is renamed to
H1C_F_TX_BLK and H1C_F_WAIT_OUTPUT is renamed to H1C_F_RX_BLK.

4 years agoMEDIUM: mux-h1: Wake H1 stream when both sides a synchronized
Christopher Faulet [Fri, 9 Apr 2021 10:31:48 +0000 (12:31 +0200)] 
MEDIUM: mux-h1: Wake H1 stream when both sides a synchronized

Instead of subscribing for reads or sends to restart data processing, when
both sides are synchronized, the H1 stream is woken up. This happens when
H1C_F_WAIT_INPUT or H1C_F_WAIT_OUTPUT flags are removed, Indeed, these flags
block the data processing and not raw data sending or receiving.

4 years agoMINOR: mux-h1: Always subscribe for reads when splicing is disabled
Christopher Faulet [Fri, 9 Apr 2021 09:58:49 +0000 (11:58 +0200)] 
MINOR: mux-h1: Always subscribe for reads when splicing is disabled

In h1_rcv_pipe(), when the splicing is not possible or disabled at the end
of the fnuction, we make sure to subscribe for reads. It is not a bug but it
avoid an extra call to h1_rcv_pipe() to handle the subscription in some
cases (end of message, end of chunk or read0).

In addition, the condition to detect end of splicing has been simplified. We
now only rely on H1C_F_WANT_SPLICE flags.

4 years agoMINOR: mux-h1: Subscribe for sends if output buffer is not empty in h1_snd_pipe
Christopher Faulet [Tue, 6 Apr 2021 15:27:32 +0000 (17:27 +0200)] 
MINOR: mux-h1: Subscribe for sends if output buffer is not empty in h1_snd_pipe

In h1_snd_pipe(), before sending spliced data, we take care to flush the
output buffer by subscribing for sends. However, the condition to do so is
not accurate. We test data remaining in the pipe. It works but it also
unnecessarily subscribes H1C for sends when the output buffer is empty if we
are unable to send all spliced data in one time. Instead, H1C is now
subscribed for sends if output buffer is not empty.

4 years agoMINOR: mux-h1: clean up conditions to enabled and disabled splicing
Christopher Faulet [Tue, 6 Apr 2021 15:24:39 +0000 (17:24 +0200)] 
MINOR: mux-h1: clean up conditions to enabled and disabled splicing

First, there is no reason to announce the splicing support at the
conn-stream level when it is created, at least for now. GTUNE_USE_SPLICE
option is already handled at the stream level.

Second, in h1_rcv_buf(), there is no reason to test the message state to
switch the H1C in splicing mode (via H1C_F_WANT_SPLICE flag).
h1_process_input() already takes care to set CS_FL_MAY_SPLICE flag on the
conn-stream when appropriate. Thus, in h1_rcv_buf(), we can rely on this
flag to change the H1C state.

Finally, if h1_rcv_pipe() is called, it means the H1C is already in the
splicing mode. H1C_F_WANT_SPLICE flag is necessarily already set. Thus no
reason to force it.

4 years agoREGTESTS: Add script to test abortonclose option
Christopher Faulet [Wed, 7 Apr 2021 12:37:07 +0000 (14:37 +0200)] 
REGTESTS: Add script to test abortonclose option

This script test abortonclose option for HTTP/1 client only. It may be
backported as far as 2.0. But on the 2.2 and prior, the syslog part must be
adapted to catch log messages emitted by proxy during HAProxy
startup. Following lines must be added :

    recv
    expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Proxy fe1 started."
    recv
    expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Proxy fe2 started."

4 years agoBUG/MEDIUM: mux-h1: Properly report client close if abortonclose option is set
Christopher Faulet [Thu, 8 Apr 2021 16:42:59 +0000 (18:42 +0200)] 
BUG/MEDIUM: mux-h1: Properly report client close if abortonclose option is set

On client side, if CO_RFL_KEEP_RECV flags is set when h1_rcv_buf() is
called, we force subscription for reads to be able to catch read0. This way,
the event will be reported to upper layer to let the stream abort the
request.

This patch fixes the abortonclose option for H1 connections. It depends on
following patches :

  * MEDIUM: mux-h1: Don't block reads when waiting for the other side
  * MINOR: conn-stream: Force mux to wait for read events if abortonclose is set

But to be sure the event is handled by the stream, the following patches are
also required :

  * BUG/MINOR: stream-int: Don't block reads in si_update_rx() if chn may receive
  * MINOR: channel: Rely on HTX version if appropriate in channel_may_recv()

All the series must be backported with caution as far as 2.0, and only after
a period of observation to be sure nothing broke.

4 years agoMEDIUM: mux-h1: Don't block reads when waiting for the other side
Christopher Faulet [Thu, 8 Apr 2021 16:34:30 +0000 (18:34 +0200)] 
MEDIUM: mux-h1: Don't block reads when waiting for the other side

When we are waiting for the other side to read more data, or to read the
next request, we must only stop the processing of input data and not the
data receipt. This patch don't change anything on the subscribes for
reads. So it should not change anything. The only difference is that the H1
connection will try to read data if it is woken up for an I/O event and if
it was subscribed for reads.

This patch is required to fix abortonclose option for H1 client connections.

4 years agoMINOR: conn-stream: Force mux to wait for read events if abortonclose is set
Christopher Faulet [Thu, 8 Apr 2021 16:13:25 +0000 (18:13 +0200)] 
MINOR: conn-stream: Force mux to wait for read events if abortonclose is set

When the abortonclose option is enabled, to be sure to be immediately
notified when a shutdown is received from the client, the frontend
conn-stream must be sure the mux will wait for read events. To do so, the
CO_RFL_KEEP_RECV flag is set when mux->rcv_buf() is called. This new flag
instructs the mux to wait for read events, regardless its internal state.

This patch is required to fix abortonclose option for H1 client connections.

4 years agoBUG/MINOR: stream-int: Don't block reads in si_update_rx() if chn may receive
Christopher Faulet [Wed, 7 Apr 2021 06:45:05 +0000 (08:45 +0200)] 
BUG/MINOR: stream-int: Don't block reads in si_update_rx() if chn may receive

In si_update_rx() function, the reads may be blocked because we explicitly
don't want to read or because of a lack of room in the input buffer. The
first condition is valid. However the second one only test if the channel is
empty or not. It means the reads are blocked if there are still some output
data in the input channel, in its buffer or its pipe. This condition is not
accurate. The reads must not be blocked if the channel can still receive
data. Thus instead of relying on channel_is_empty() function, we now call
channel_may_recv().

This patch is especially useful to be able to catch read0 on client side
when we are waiting for a connection to the server, when abortonclose option
is enabled. Otherwise, the client abort is not detected.

This patch depends on "MINOR: channel: Rely on HTX version if appropriate in
channel_may_recv()". Both must be backported as far as 2.0 after a period of
observation to be sure nothing broke.

4 years agoMINOR: channel: Rely on HTX version if appropriate in channel_may_recv()
Christopher Faulet [Wed, 7 Apr 2021 06:10:41 +0000 (08:10 +0200)] 
MINOR: channel: Rely on HTX version if appropriate in channel_may_recv()

When channel_may_recv() is called for an HTX stream, the HTX version,
channel_htx_may_recv() is called. This patch is mandatory to fix a bug
related to the abortonclose option.

4 years agoBUILD: makefile: add new option USE_MEMORY_PROFILING
Willy Tarreau [Wed, 5 May 2021 16:17:39 +0000 (18:17 +0200)] 
BUILD: makefile: add new option USE_MEMORY_PROFILING

It is not enabled by default, and may only work on linux-glibc for now,
though maybe other platforms could adopt it, possibly with certain
restrictions.

4 years agoMINOR: activity: add the profiling.memory global setting
Willy Tarreau [Wed, 5 May 2021 16:33:19 +0000 (18:33 +0200)] 
MINOR: activity: add the profiling.memory global setting

This allows to enable/disable memory usage profiling very early, which
can be convenient to trace the memory usage in maps, certificates, Lua
etc.

4 years agoMINOR: activity: make "show profiling" also dump the memoery usage
Willy Tarreau [Wed, 5 May 2021 16:07:02 +0000 (18:07 +0200)] 
MINOR: activity: make "show profiling" also dump the memoery usage

Now the memory usage stats are dumped. They are first sorted by total
alloc+free so that the first ones are always the most relevant, and
that most symmetric alloc/free pairs appear next to each other. This
way it becomes convenient to only show a small part of them such as:

    show profiling memory 20

It's worth noting that the sorting is performed upon each call to the
iohandler so it is technically possible that an entry could appear
twice or be dropped if the ordering changes between two calls. In
practice it is not an issue but it's worth being mentioned.

4 years agoMINOR: activity: make "show profiling" support a few arguments
Willy Tarreau [Wed, 5 May 2021 15:48:13 +0000 (17:48 +0200)] 
MINOR: activity: make "show profiling" support a few arguments

These ones allow to limit the output to only certain sections and/or
a number of lines per dump.

4 years agoMINOR: activity: clean up the show profiling io_handler a little bit
Willy Tarreau [Wed, 5 May 2021 15:33:27 +0000 (17:33 +0200)] 
MINOR: activity: clean up the show profiling io_handler a little bit

Let's rearrange it to make it more configurable and allow to iterate
over multiple parts (header, tasks, memory etc), to restart from a
given line number (previously it didn't work, though fortunately it
didn't happen), and to support dumping only certain parts and a given
number of lines. A few entries from ctx.cli are now used to store a
restart point and the current step.

4 years agoMEDIUM: activity: collect memory allocator statistics with USE_MEMORY_PROFILING
Willy Tarreau [Wed, 5 May 2021 15:07:09 +0000 (17:07 +0200)] 
MEDIUM: activity: collect memory allocator statistics with USE_MEMORY_PROFILING

When built with USE_MEMORY_PROFILING the main memory allocation functions
are diverted to collect statistics per caller. It is a bit tricky because
the only way to call the original ones is to find their pointer, which
requires dlsym(), and which is not available everywhere.

Thus all functions are designed to call their fallback function (the
original one), which is preset to an initialization function that is
supposed to call dlsym() to resolve the missing symbols, and vanish.
This saves expensive tests in the critical path.

A second problem is that dlsym() calls calloc() to initialize some
error messages. After plenty of tests with posix_memalign(), valloc()
and friends, it turns out that returning NULL still makes it happy.
Thus we currently use a visit counter (in_memprof) to detect if we're
reentering, in which case all allocation functions return NULL.

In order to convert a return address to an entry in the stats, we
perform a cheap hash consisting in multiplying the pointer by a
balanced number (as many zeros as ones) and keeping the middle bits.
The hash is already pretty good like this, achieving to store up to
638 entries in a 2048-entry table without collision. But in order to
further refine this and improve the fill ratio of the table, in case
of collision we move up to 16 adjacent entries to find a free place.
This remains quite cheap and manages to store all of these inside a
1024-entries hash table with even less risk of collision.

Also, free(NULL) does not produce any stats. By doing so we reduce
from 638 to 208 the average number of entries needed for a basic
config using SSL. free(NULL) not only provides no information as it's
a NOP, but keeping it is pure pollution as it happens all the time.

When DEBUG_MEM_STATS is enabled, malloc/calloc/realloc are redefined as
macros, preventing the code from compiling. Thus, when this option is
detected, the macros are undefined as they are pointless there anyway.

The functions are optimized to quickly jump to the fallback and as such
become almost invisible in terms of processing time, execpt an extra
"if" on a read_mostly variable and a jump. Considering that this only
happens for pool misses and library routines, this remains acceptable.

Performance tests in SSL (the most stressful test) shows less than 1%
performance loss when profiling is enabled on 2c4t.

The code was written in a way to ease backporting to modern versions
(2.2+) if needed, so it keeps the long names for integers and doesn't
use the _INC version of the atomic ops.

4 years agoMINOR: activity: declare the storage for memory usage statistics
Willy Tarreau [Wed, 5 May 2021 14:50:40 +0000 (16:50 +0200)] 
MINOR: activity: declare the storage for memory usage statistics

We'll need to store for each call place, the pointer to the caller
(the return address to be more exact as with free() it's not uncommon
to see tail calls), the number of calls to alloc/free and the total
alloc/free bytes. realloc() will be counted either as alloc or free
depending on the balance of the size before vs after.

We store 1024+1 entries. The first ones are used as hashes and the
last one for collisions.

When profiling is enabled via the CLI, all the stats are reset.

4 years agoMINOR: activity: add a "memory" entry to "profiling"
Willy Tarreau [Wed, 5 May 2021 14:44:23 +0000 (16:44 +0200)] 
MINOR: activity: add a "memory" entry to "profiling"

This adds the necessary flags to permit run-time enabling/disabling of
memory profiling. For now this is disabled.

A few words were added to the management doc about it and recalling that
this is limited to certain OSes.

4 years agoCLEANUP: activity: mark the profiling and task_profiling_mask __read_mostly
Willy Tarreau [Wed, 5 May 2021 14:28:31 +0000 (16:28 +0200)] 
CLEANUP: activity: mark the profiling and task_profiling_mask __read_mostly

These ones are only read by the scheduler and occasionally written to
by the CLI parser, so let's move them to read_mostly so that they do
not risk to suffer from cache line pollution.