]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
6 years agoBUG/MINOR: mux-h1: Add the header connection in lower case in outgoing messages
Christopher Faulet [Mon, 17 Jun 2019 12:07:46 +0000 (14:07 +0200)] 
BUG/MINOR: mux-h1: Add the header connection in lower case in outgoing messages

When necessary, this header is directly added in outgoing messages by the H1
multiplexer. Because there is no HTX conversion first, the header name is not
converserted to its lower case version. So, it must be added in lower case by
the multiplexer.

This patch must be backported to 2.0 and 1.9.

6 years agoBUG/MINOR: lua/htx: Make txn.req_req_* and txn.res_rep_* HTX aware
Christopher Faulet [Mon, 17 Jun 2019 11:36:06 +0000 (13:36 +0200)] 
BUG/MINOR: lua/htx: Make txn.req_req_* and txn.res_rep_* HTX aware

These bindings were not updated to support HTX streams.

This patch must be backported to 2.0 and 1.9. It fixes the issue #124.

6 years agoMEDIUM: server: server-state global file stored in a tree
Baptiste Assmann [Thu, 13 Jun 2019 11:24:29 +0000 (13:24 +0200)] 
MEDIUM: server: server-state global file stored in a tree

Server states can be recovered from either a "global" file (all backends)
or a "local" file (per backend).

The way the algorithm to parse the state file was first implemented was good
enough for a low number of backends and servers per backend.
Basically, for each backend the state file (global or local) is opened,
parsed entirely and for each line we check if it contains data related to
a server from the backend we're currently processing.
We must read the file entirely, just in case some lines for the current
backend are stored at the end of the file.
This does not scale at all!

This patch changes the behavior above for the "global" file only. Now,
the global file is read and parsed once and all lines it contains are
stored in a tree, for faster discovery.
This result in way much less fopen, fgets, and strcmp calls, which make
loading of very big state files very quick now.

6 years agoMINOR: sample: Add sha2([<bits>]) converter
Tim Duesterhus [Mon, 17 Jun 2019 10:41:44 +0000 (12:41 +0200)] 
MINOR: sample: Add sha2([<bits>]) converter

This adds a converter for the SHA-2 family, supporting SHA-224, SHA-256
SHA-384 and SHA-512.

The converter relies on the OpenSSL implementation, thus only being available
when HAProxy is compiled with USE_OPENSSL.

See GitHub issue #123. The hypothetical `ssl_?_sha256` fetch can then be
simulated using `ssl_?_der,sha2(256)`:

  http-response set-header Server-Cert-FP %[ssl_f_der,sha2(256),hex]

6 years agoMEDIUM: Remove 'option independant-streams'
Tim Duesterhus [Tue, 14 May 2019 18:58:01 +0000 (20:58 +0200)] 
MEDIUM: Remove 'option independant-streams'

It is deprecated with HAProxy 1.5. Time to remove it.

6 years agoMEDIUM: Make '(cli|con|srv)timeout' directive fatal
Tim Duesterhus [Tue, 14 May 2019 18:57:59 +0000 (20:57 +0200)] 
MEDIUM: Make '(cli|con|srv)timeout' directive fatal

They were deprecated with HAProxy 1.5. Time to remove them.

6 years agoMEDIUM: Make 'redispatch' directive fatal
Tim Duesterhus [Tue, 14 May 2019 18:57:58 +0000 (20:57 +0200)] 
MEDIUM: Make 'redispatch' directive fatal

It was deprecated with HAProxy 1.5. Time to remove it.

6 years agoMEDIUM: Make 'block' directive fatal
Tim Duesterhus [Tue, 14 May 2019 18:57:57 +0000 (20:57 +0200)] 
MEDIUM: Make 'block' directive fatal

It was deprecated with HAProxy 1.5. Time to remove it.

6 years agoDOC: this is a development branch again.
Willy Tarreau [Mon, 17 Jun 2019 11:35:23 +0000 (13:35 +0200)] 
DOC: this is a development branch again.

This effectively reverts 4bc567c5.

6 years agoBUG/MEDIUM: h2/htx: Update data length of the HTX when the cookie list is built
Christopher Faulet [Mon, 17 Jun 2019 09:44:47 +0000 (11:44 +0200)] 
BUG/MEDIUM: h2/htx: Update data length of the HTX when the cookie list is built

When an H2 request is converted into an HTX message, All cookie headers are
grouped into one, each value separated by a semicolon (;). To do so, we add the
header "cookie" with the first value and then we update the value by appending
other cookies. But during this operation, only the size of the HTX block is
updated. And not the data length of the whole HTX message.

It is an old bug and it seems to work by chance till now. But it may lead to
undefined behaviour by time to time.

This patch must be backported to 2.0 and 1.9

6 years ago[RELEASE] Released version 2.1-dev0 v2.1-dev0
Willy Tarreau [Sun, 16 Jun 2019 19:49:47 +0000 (21:49 +0200)] 
[RELEASE] Released version 2.1-dev0

Released version 2.1-dev0 with the following main changes :
    - exact copy of 2.0.0

6 years ago[RELEASE] Released version 2.0.0 v2.0.0
Willy Tarreau [Sun, 16 Jun 2019 18:00:26 +0000 (20:00 +0200)] 
[RELEASE] Released version 2.0.0

Released version 2.0.0 with the following main changes :
    - MINOR: fd: Don't use atomic operations when it's not needed.
    - DOC: mworker-prog: documentation for the program section
    - MINOR: http: add a new "http-request replace-uri" action
    - BUG/MINOR: 51d/htx: The _51d_fetch method, and the methods it calls are now HTX aware.
    - MINOR: 51d: Added dummy libraries for the 51Degrees module for testing.
    - MINOR: mworker: change formatting in uptime field of "show proc"
    - MINOR: mworker: add the HAProxy version in "show proc"
    - MINOR: doc: Remove -Ds option in man page
    - MINOR: doc: add master-worker in the man page
    - MINOR: doc: mention HAPROXY_LOCALPEER in the man
    - BUILD: Silence gcc warning about unused return value
    - CLEANUP: 51d: move the 51d dummy lib to contrib/51d/src to match the real lib
    - BUILD: travis-ci: add 51Degree device detection, update openssl to 1.1.1c
    - MINOR: doc: update the manpage and usage message about -S
    - BUILD/MINOR: 51d: Updated build registration output to indicate thatif the library is a dummy one or not.
    - BUG/MEDIUM: h1: Don't wait for handshake if we had an error.
    - BUG/MEDIUM: h1: Wait for the connection if the handshake didn't complete.
    - BUG/MINOR: task: prevent schedulable tasks from starving under high I/O activity
    - BUG/MINOR: fl_trace/htx: Be sure to always forward trailers and EOM
    - BUG/MINOR: channel/htx: Call channel_htx_full() from channel_full()
    - BUG/MINOR: http: Use the global value to limit the number of parsed headers
    - BUG/MINOR: htx: Detect when tail_addr meet end_addr to maximize free rooms
    - BUG/MEDIUM: htx: Don't change position of the first block during HTX analysis
    - CLEANUP: channel: Remove channel_htx_fwd_payload() and channel_htx_fwd_all()
    - BUG/MEDIUM: proto_htx: Introduce the state ENDING during forwarding
    - MINOR: htx: Add 3 flags on the start-line to deal with the request schemes
    - MINOR: h2: Set flags about the request's scheme on the start-line
    - MINOR: mux-h1: Set flags about the request's scheme on the start-line
    - MINOR: mux-h2: Forward clients scheme to servers checking start-line flags
    - MEDIUM: server: server-state only rely on server name
    - CLEANUP: connection: rename the wait_event.task field to .tasklet
    - CLEANUP: tasks: rename task_remove_from_tasklet_list() to tasklet_remove_*
    - BUG/MEDIUM: connections: Don't call shutdown() if we want to disable linger.
    - DOC: add some environment variables in section 2.3
    - BUILD: makefile: clarify the "help" output and list options
    - BUG/MINOR: mux-h1: Wake busy mux for I/O when message is fully sent
    - BUG: tasks: fix bug introduced by latest scheduler cleanup
    - BUG/MEDIUM: mux-h2: fix early close with option abortonclose
    - BUG/MEDIUM: connections: Don't use ALPN to pick mux when in mode TCP.
    - BUG/MEDIUM: connections: Don't try to send early data if we have no mux.
    - BUG/MEDIUM: mux-h2: properly account for the appended data in HTX
    - BUILD: makefile: further clarify the "help" output and list targets
    - BUILD: makefile: rename "linux2628" to "linux-glibc" and remove older targets
    - BUILD: travis-ci: switch to linux-glibc instead of linux2628
    - DOC: update few references to the linux* targets and change them to linux-glibc
    - BUILD: makefile: detect and reject recently removed linux targets
    - BUILD: makefile: enable linux namespaces by default on linux
    - BUILD: makefile: enable TFO on linux platforms
    - BUILD: makefile: enable getaddrinfo on the linux-glibc target
    - DOC: small updates to the CONTRIBUTING file
    - BUG/MEDIUM: ssl: Make sure we initiate the handshake after using early data.
    - CLEANUP: removed obsolete examples an move a few to better places
    - DOC: Fix typos in CONTRIBUTING
    - DOC: update the outdated ROADMAP file
    - DOC: create a BRANCHES file to explain the life cycle
    - DOC: mention in INSTALL haproxy 2.0 is a long-term supported stable version
    - BUILD: travis-ci: TFO and GETADDRINFO are now enabled by default
    - BUILD: makefile: make the obsolete target detection compatible with make-3.80
    - BUILD: tools: work around an internal compiler bug in gcc-3.4
    - BUILD: pattern: work around an internal compiler bug in gcc-3.4
    - BUILD: makefile: enable USE_RT on Solaris
    - BUILD: makefile: do not use echo -n
    - DOC: mention a few common build errors in the INSTALL file

6 years agoDOC: mention a few common build errors in the INSTALL file
Willy Tarreau [Sun, 16 Jun 2019 17:39:44 +0000 (19:39 +0200)] 
DOC: mention a few common build errors in the INSTALL file

These are some errors met when trying to build with gcc 3.4 on an
old (13 years-old) Solaris 10 and on an even older Linux 2.4 with
glibc 2.2.5. A few options were enough to fix the build there.

6 years agoBUILD: makefile: do not use echo -n
Willy Tarreau [Sun, 16 Jun 2019 17:26:18 +0000 (19:26 +0200)] 
BUILD: makefile: do not use echo -n

On certain UNIXes (Solaris at least), echo -n displays "-n". Let's
simply re-arrange the "if" block in the help message not to use it.

6 years agoBUILD: makefile: enable USE_RT on Solaris
Willy Tarreau [Sun, 16 Jun 2019 17:13:28 +0000 (19:13 +0200)] 
BUILD: makefile: enable USE_RT on Solaris

It doesn't build on Ultra5 under Solaris 10 without this due to
clock_gettime() not being found.

6 years agoBUILD: pattern: work around an internal compiler bug in gcc-3.4
Willy Tarreau [Sun, 16 Jun 2019 16:40:33 +0000 (18:40 +0200)] 
BUILD: pattern: work around an internal compiler bug in gcc-3.4

gcc-3.4 fails to compile pattern.c :

src/pattern.c: In function `pat_match_ip':
src/pattern.c:1092: error: unrecognizable insn:
(insn 186 185 187 9 src/pattern.c:970 (set (reg/f:SI 179)
        (high:SI (const:SI (plus:SI (symbol_ref:SI ("static_pattern") [flags 0x22] <var_decl fe5bae80 static_pattern>)
                    (const_int 8 [0x8]))))) -1 (nil)
    (nil))
src/pattern.c:1092: internal compiler error: in extract_insn, at recog.c:2083

This happens when performing the memcpy() on the union, and in this
case the workaround is trivial (and even cleaner) using a cast instead.

6 years agoBUILD: tools: work around an internal compiler bug in gcc-3.4
Willy Tarreau [Sun, 16 Jun 2019 16:16:33 +0000 (18:16 +0200)] 
BUILD: tools: work around an internal compiler bug in gcc-3.4

gcc-3.4 fails to compile standard.c :

src/standard.c: In function `str2sa_range':
src/standard.c:1034: error: unrecognizable insn:
(insn 582 581 583 37 src/standard.c:949 (set (reg/f:SI 262)
        (high:SI (const:SI (plus:SI (symbol_ref:SI ("*ss.4") [flags 0x22] <var_decl fe782e80 ss>)
                    (const_int 2 [0x2]))))) -1 (nil)
    (nil))
src/standard.c:1034: internal compiler error: in extract_insn, at recog.c:2083

The workaround is explained here :

    https://gcc.gnu.org/bugzilla/show_bug.cgi?id=21613

It only requires creating a local variable containing the result of the
cast, which is totally harmless, so let's do it.

6 years agoBUILD: makefile: make the obsolete target detection compatible with make-3.80
Willy Tarreau [Sun, 16 Jun 2019 15:53:39 +0000 (17:53 +0200)] 
BUILD: makefile: make the obsolete target detection compatible with make-3.80

Older versions of GNU make do not support "else ifneq", let's split
this in two lines.

6 years agoBUILD: travis-ci: TFO and GETADDRINFO are now enabled by default
Ilya Shipitsin [Sat, 15 Jun 2019 20:19:27 +0000 (01:19 +0500)] 
BUILD: travis-ci: TFO and GETADDRINFO are now enabled by default

This default changed in the linux-glibc target with commits 364d6f5
and a26181e.

6 years agoDOC: mention in INSTALL haproxy 2.0 is a long-term supported stable version
Willy Tarreau [Sat, 15 Jun 2019 17:07:54 +0000 (19:07 +0200)] 
DOC: mention in INSTALL haproxy 2.0 is a long-term supported stable version

Let's switch back to the stable wording now.

6 years agoDOC: create a BRANCHES file to explain the life cycle
Willy Tarreau [Sat, 15 Jun 2019 19:53:40 +0000 (21:53 +0200)] 
DOC: create a BRANCHES file to explain the life cycle

This file tries to describe development versus maintenance and gives hints
about what version to pick depending on the user's skills and goals.

6 years agoDOC: update the outdated ROADMAP file
Willy Tarreau [Sat, 15 Jun 2019 19:58:44 +0000 (21:58 +0200)] 
DOC: update the outdated ROADMAP file

At least the load load balancing was done. Other points are being carried
since 1.5 or so, they should go into the issue tracker with no version
indication.

6 years agoDOC: Fix typos in CONTRIBUTING
Tim Duesterhus [Sat, 15 Jun 2019 17:47:29 +0000 (19:47 +0200)] 
DOC: Fix typos in CONTRIBUTING

Fixes typos introduced in 09e0d7422e64645ad6b03b66e94e5df80a6177fa
as well as anything found by `spell`.

6 years agoCLEANUP: removed obsolete examples an move a few to better places
Willy Tarreau [Sat, 15 Jun 2019 16:56:48 +0000 (18:56 +0200)] 
CLEANUP: removed obsolete examples an move a few to better places

The following example files awere removed as irrelevant by this
time :
  auth.cfg check.conf ssl.cfg haproxy.spec

The following scripts were removed as having been unused for more
than a decade :
  debug2ansi debug2html debugfind check init.haproxy stats_haproxy.sh

seemless_reload.txt was moved to doc/ where it's more suitable.

haproxy.vim was moved to contrib/syntax-highlight/

scripts/create-release was updated not to try to update haproxy.spec
anymore.

6 years agoBUG/MEDIUM: ssl: Make sure we initiate the handshake after using early data.
Olivier Houchard [Sat, 15 Jun 2019 18:59:30 +0000 (20:59 +0200)] 
BUG/MEDIUM: ssl: Make sure we initiate the handshake after using early data.

When we're done sending/receiving early data, and we add the handshake
flags on the connection, make sure we wake the associated tasklet up, so that
the handshake will be initiated.

6 years agoDOC: small updates to the CONTRIBUTING file
Willy Tarreau [Sat, 15 Jun 2019 15:15:12 +0000 (17:15 +0200)] 
DOC: small updates to the CONTRIBUTING file

There's an abstract explaining what is discussed in the file, a small
explanation of how the project works, which justifies the measures
taken here, and instructions about what to do when a patch is ignored,
or how to annoy everyone.

6 years agoBUILD: makefile: enable getaddrinfo on the linux-glibc target
Willy Tarreau [Fri, 14 Jun 2019 16:33:56 +0000 (18:33 +0200)] 
BUILD: makefile: enable getaddrinfo on the linux-glibc target

getaddrinfo() has been available since glibc 2.3.3 or so and is generally
enabled by distro packagers. The main reason for not enabling it on Linux
in the past is that it was known broken on some libc alternatives. It's
the right moment to enable it by default with glibc.

6 years agoBUILD: makefile: enable TFO on linux platforms
Willy Tarreau [Fri, 14 Jun 2019 14:57:42 +0000 (16:57 +0200)] 
BUILD: makefile: enable TFO on linux platforms

TCP Fast Open is supported on all supported Linux kernels and on all
kernels shipped in supported distros, except the older 2.6.32 that
comes with RHEL6. However the option is harmless, will not prevent
from building and smoothly falls back even if forcefully enabled, so
it makes sense to enable it by default. It's still possible to pass
"USE_TFO=" to force it disabled if really desired.

6 years agoBUILD: makefile: enable linux namespaces by default on linux
Willy Tarreau [Fri, 14 Jun 2019 14:54:51 +0000 (16:54 +0200)] 
BUILD: makefile: enable linux namespaces by default on linux

Oldest kernel found on a supported Linux distro (2.6.32 + backports on
RHEL6) supports network namespaces, so we have no reason not to enable
them by default on the linux-glibc target.

6 years agoBUILD: makefile: detect and reject recently removed linux targets
Willy Tarreau [Fri, 14 Jun 2019 14:44:49 +0000 (16:44 +0200)] 
BUILD: makefile: detect and reject recently removed linux targets

We've just removed old linux targets "linux22", "linux24", "linux24e",
"linux26" and "linux2628" and it's likely that many build scripts and
packages will still reference these. So let's have the makefile detect
these and reject with instructions instead of silently building with
incorrect options.

6 years agoDOC: update few references to the linux* targets and change them to linux-glibc
Willy Tarreau [Fri, 14 Jun 2019 16:40:48 +0000 (18:40 +0200)] 
DOC: update few references to the linux* targets and change them to linux-glibc

The INSTALL guide, the Lua doc and the Prometheus exporter's README all
used to reference "linux2628", "linux26" or even "linux". These were all
updated to consistently reflect "linux-glibc" instead. The default options
were updated there as well so that it should build cleanly on most distros.

6 years agoBUILD: travis-ci: switch to linux-glibc instead of linux2628
Willy Tarreau [Fri, 14 Jun 2019 16:32:34 +0000 (18:32 +0200)] 
BUILD: travis-ci: switch to linux-glibc instead of linux2628

The Linux target has changed and only linux-glibc is known now.

6 years agoBUILD: makefile: rename "linux2628" to "linux-glibc" and remove older targets
Willy Tarreau [Fri, 14 Jun 2019 14:32:09 +0000 (16:32 +0200)] 
BUILD: makefile: rename "linux2628" to "linux-glibc" and remove older targets

The linux targets have become more than confusing over time. We used to
have "linux2628" to match the features available in kernels 2.6.28 and
above, without consideration for the libc, and due to many new features
appearing later in kernels, some other options were added that are not
enabled by default in linux2628, so this target doesn't make any sense
anymore. The older ones (linux 2.2, linux 2.4, ...) do not make sense
either since these versions are not supported anymore. Let's clean things
up by creating a new "linux-glibc" target that matches what is available
by default on Linux kernels and glibc present on supported distros at the
time of release. Other libc implementation may use a custom or generic
target or be added later if needed.

All the older linux targets were removed.

6 years agoBUILD: makefile: further clarify the "help" output and list targets
Willy Tarreau [Fri, 14 Jun 2019 13:52:01 +0000 (15:52 +0200)] 
BUILD: makefile: further clarify the "help" output and list targets

When a target is not set we now also list the known ones. A minor
alignment issue in the output was also addressed.

6 years agoBUG/MEDIUM: mux-h2: properly account for the appended data in HTX
Willy Tarreau [Sat, 15 Jun 2019 09:34:41 +0000 (11:34 +0200)] 
BUG/MEDIUM: mux-h2: properly account for the appended data in HTX

When commit 0350b90e3 ("MEDIUM: htx: make htx_add_data() never defragment
the buffer") was introduced, it made htx_add_data() actually be able to
add less data than it was asked for, and the callers must use the returned
value to know how much was added. The H2 code used to rely on the frame
length instead of the return value. A version of the code doing this was
written but is obviously not the one that got merged, resulting in breaking
large uploads or downloads when HTX would have instead defragmented the
buffer because the HTX side sees less contents than what the H2 side sees.

This patch fixes this again. No backport is needed.

6 years agoBUG/MEDIUM: connections: Don't try to send early data if we have no mux.
Olivier Houchard [Fri, 14 Jun 2019 22:14:05 +0000 (00:14 +0200)] 
BUG/MEDIUM: connections: Don't try to send early data if we have no mux.

In connect_server(), if we don't yet have a mux, because we're choosing
one depending on the ALPN, don't attempt to send early data. We can't do
it because those data would depend on the mux, that will only be determined
by the handshake.

This should be backported to 1.9.

6 years agoBUG/MEDIUM: connections: Don't use ALPN to pick mux when in mode TCP.
Olivier Houchard [Fri, 14 Jun 2019 22:13:15 +0000 (00:13 +0200)] 
BUG/MEDIUM: connections: Don't use ALPN to pick mux when in mode TCP.

In connect_server(), don't wait until we negociate the ALPN to choose the
mux, the only mux we want to use is the mux_pt anyway.

This should be backported to 1.9.

6 years agoBUG/MEDIUM: mux-h2: fix early close with option abortonclose
Willy Tarreau [Sat, 15 Jun 2019 07:55:50 +0000 (09:55 +0200)] 
BUG/MEDIUM: mux-h2: fix early close with option abortonclose

Olivier found that commit 99ad1b3e8 ("MINOR: mux-h2: stop relying on
CS_FL_REOS") managed to break abortonclose again with H2. What happens
is that while the CS_FL_REOS flag was set on some transitions to the
HREM state, it's not set on all and is in fact only set when the low
level connection is closed. So making the replacement condition match
the HREM and ERROR states is not correct and causes completely correct
requests to send advertise an early close of the connection layer while
only the stream's input is closed.

In order to avoid this, we now properly split the checks for the CLOSED
state and for the closed connection. This way there is no risk to set
the EOS flag too early on the connection.

No backport is needed.

6 years agoBUG: tasks: fix bug introduced by latest scheduler cleanup
Willy Tarreau [Fri, 14 Jun 2019 16:05:54 +0000 (18:05 +0200)] 
BUG: tasks: fix bug introduced by latest scheduler cleanup

In commit 86eded6c6 ("CLEANUP: tasks: rename task_remove_from_tasklet_list()
to tasklet_remove_*") which consisted in removing the casts between tasks
and tasklet, I was a bit too fast to believe that we only saw tasklets in
this function since process_runnable_tasks() also uses it with tasks under
a cast. So removing the bookkeeping on task_list_size was not appropriate.
Bah, the joy of casts which hide the real thing...

This patch does two things at once to address this mess once for all:
  - it restores the decrement of task_list_size when it's a real task,
    but moves it to process_runnable_task() since it's the only place
    where it's allowed to call it with a task

  - it moves the increment there as well and renames
    task_insert_into_tasklet_list() to tasklet_insert_into_tasklet_list()
    of obvious consistency reasons.

This way the increment/decrement of task_list_size is made at the only
places where the cast is enforced, so it has less risks to be missed.
The comments on top of these functions were updated to reflect that they
are only supposed to be used with tasklets and that the caller is responsible
for keeping task_list_size up to date if it decides to enforce a task there.

Now we don't have to worry anymore about how these functions work outside
of the scheduler, which is better longterm-wise. Thanks to Christopher for
spotting this mistake.

No backport is needed.

6 years agoBUG/MINOR: mux-h1: Wake busy mux for I/O when message is fully sent
Christopher Faulet [Fri, 14 Jun 2019 14:54:15 +0000 (16:54 +0200)] 
BUG/MINOR: mux-h1: Wake busy mux for I/O when message is fully sent

If a mux is in busy mode when the outgoing EOM is consummed, it is important to
wake it up for I/O. Because in busy mode, the mux is not subscribed for
receive. Otherwise, it depends on the applicative layer to shutdown the H1
stream. Wake it up allows the mux to catch the read0 as soon as possible.

This patch must be backported to 1.9.

6 years agoBUILD: makefile: clarify the "help" output and list options
Willy Tarreau [Fri, 14 Jun 2019 13:52:01 +0000 (15:52 +0200)] 
BUILD: makefile: clarify the "help" output and list options

The list of enable and disabled build options now appears separately
at the end of "make help". This is convenient to know what is enabled
by default on a given target. For example :

  $ make help TARGET=linux2628
  Enabled features for TARGET 'linux2628' (disable with 'USE_xxx=') :
    EPOLL NETFILTER POLL THREAD TPROXY LINUX_TPROXY LINUX_SPLICE LIBCRYPT
    CRYPT_H FUTEX ACCEPT4 CPU_AFFINITY DL RT PRCTL THREAD_DUMP

  Disabled features for TARGET 'linux2628' (enable with 'USE_xxx=1') :
    KQUEUE MY_EPOLL MY_SPLICE PCRE PCRE_JIT PCRE2 PCRE2_JIT PRIVATE_CACHE
    PTHREAD_PSHARED REGPARM STATIC_PCRE STATIC_PCRE2 VSYSCALL GETADDRINFO
    OPENSSL LUA MY_ACCEPT4 ZLIB SLZ TFO NS DEVICEATLAS 51DEGREES WURFL
    SYSTEMD OBSOLETE_LINKER EVPORTS

6 years agoDOC: add some environment variables in section 2.3
William Lallemand [Fri, 14 Jun 2019 13:35:37 +0000 (15:35 +0200)] 
DOC: add some environment variables in section 2.3

Add the missing environment variable in the 2.3 section.

6 years agoBUG/MEDIUM: connections: Don't call shutdown() if we want to disable linger.
Olivier Houchard [Fri, 14 Jun 2019 13:26:06 +0000 (15:26 +0200)] 
BUG/MEDIUM: connections: Don't call shutdown() if we want to disable linger.

In conn_sock_shutw(), avoid calling shutdown() if linger_risk is set. Not
doing so will result in getting sockets in TIME_WAIT for some time.
This is particularly observable with health checks.

This should be backported to 1.9.

6 years agoCLEANUP: tasks: rename task_remove_from_tasklet_list() to tasklet_remove_*
Willy Tarreau [Fri, 14 Jun 2019 12:47:49 +0000 (14:47 +0200)] 
CLEANUP: tasks: rename task_remove_from_tasklet_list() to tasklet_remove_*

The function really only operates on tasklets, its arguments are always
tasklets cast as tasks to match the function's type, to be cast back to
a struct tasklet. Let's rename it to tasklet_remove_from_tasklet_list(),
take a struct tasklet, and get rid of the undesired task casts.

6 years agoCLEANUP: connection: rename the wait_event.task field to .tasklet
Willy Tarreau [Fri, 14 Jun 2019 12:42:29 +0000 (14:42 +0200)] 
CLEANUP: connection: rename the wait_event.task field to .tasklet

It's really confusing to call it a task because it's a tasklet and used
in places where tasks and tasklets are used together. Let's rename it
to tasklet to remove this confusion.

6 years agoMEDIUM: server: server-state only rely on server name
Baptiste Assmann [Tue, 11 Jun 2019 12:51:49 +0000 (14:51 +0200)] 
MEDIUM: server: server-state only rely on server name

Since h7da71293e431b5ebb3d6289a55b0102331788ee6as has been added, the
server name (srv->id in the code) is now unique per backend, which
means it can reliabely be used to identify a server recovered from the
server-state file.

This patch cleans up the parsing of server-state file and ensure we use
only the server name as a reliable key.

6 years agoMINOR: mux-h2: Forward clients scheme to servers checking start-line flags
Christopher Faulet [Fri, 14 Jun 2019 08:46:51 +0000 (10:46 +0200)] 
MINOR: mux-h2: Forward clients scheme to servers checking start-line flags

By default, the scheme "https" is always used. But when an explicit scheme was
defined and when this scheme is "http", we use it in the request sent to the
server. This is done by checking flags of the start-line. If the flag
HTX_SL_F_HAS_SCHM is set, it means an explicit scheme was defined on the client
side. And if the flag HTX_SL_F_SCHM_HTTP is set, it means the scheme "http" was
used.

6 years agoMINOR: mux-h1: Set flags about the request's scheme on the start-line
Christopher Faulet [Fri, 14 Jun 2019 08:31:25 +0000 (10:31 +0200)] 
MINOR: mux-h1: Set flags about the request's scheme on the start-line

We first try to figure out if the URI of the start-line is absolute or not. So,
if it does not start by a slash ("/"), it means the URI is an absolute one and
the flag HTX_SL_F_HAS_SCHM is set. Then checks are performed to know if the
scheme is "http" or "https" and the corresponding flag is set,
HTX_SL_F_SCHM_HTTP or HTX_SL_F_SCHM_HTTPS. Other schemes, for instance ftp, are
ignored.

6 years agoMINOR: h2: Set flags about the request's scheme on the start-line
Christopher Faulet [Fri, 14 Jun 2019 08:25:47 +0000 (10:25 +0200)] 
MINOR: h2: Set flags about the request's scheme on the start-line

The flag HTX_SL_F_HAS_SCHM is always set because H2 requests have always an
explicit scheme. Then, the pseudo-header ":scheme" is tested. If it is set to
"http", the flag HTX_SL_F_SCHM_HTTP is set. Otherwise, for all other cases, the
flag HTX_SL_F_SCHM_HTTPS is set. For now, it seems reasonable to have a fallback
on the scheme "https".

6 years agoMINOR: htx: Add 3 flags on the start-line to deal with the request schemes
Christopher Faulet [Fri, 14 Jun 2019 08:08:13 +0000 (10:08 +0200)] 
MINOR: htx: Add 3 flags on the start-line to deal with the request schemes

The first one, HTX_SL_F_HAS_SCHM, will be used to know the request has an
explicit scheme. So, in H2, it is always true because the pseudo-header
":scheme" is mandatory. In H1, it is only true when an absolute URI is found on
the start-line. The other flags, HTX_SL_F_SCHM_HTTP and HTX_SL_F_SCHM_HTTPS,
will be used to know which scheme the request have. For now, other protocols are
not handled.

The aim of these flags is to pass this information to the backend side in
general, and to the H2 mux in particular. So the multiplexer will have a chance
to use this information to send the right scheme to the server.

6 years agoBUG/MEDIUM: proto_htx: Introduce the state ENDING during forwarding
Christopher Faulet [Thu, 13 Jun 2019 14:43:22 +0000 (16:43 +0200)] 
BUG/MEDIUM: proto_htx: Introduce the state ENDING during forwarding

This state is used in the legacy HTTP when everything was received from an
endpoint but a filter doesn't forward all the data. It is used to not report a
client or a server abort, depending on channels flags.

The same must be done on HTX streams. Otherwise, the message may be
truncated. For instance, it may happen with the filter trace with the random
forwarding enabled on the response channel.

This patch must be backported to 1.9.

6 years agoCLEANUP: channel: Remove channel_htx_fwd_payload() and channel_htx_fwd_all()
Christopher Faulet [Thu, 13 Jun 2019 09:31:24 +0000 (11:31 +0200)] 
CLEANUP: channel: Remove channel_htx_fwd_payload() and channel_htx_fwd_all()

These functions are unused now. No backport needed.

6 years agoBUG/MEDIUM: htx: Don't change position of the first block during HTX analysis
Christopher Faulet [Thu, 13 Jun 2019 09:16:45 +0000 (11:16 +0200)] 
BUG/MEDIUM: htx: Don't change position of the first block during HTX analysis

In the HTX structure, the field <first> is used to know where to (re)start the
analysis. It may differ from the message's head. It is especially important to
update it to handle 1xx messages, to be sure to restart the analysis on the next
message (another 1xx message or the final one). It is also updated when some
data are forwarded (the headers or part of the body). But this update is an
error and must never be done at the analysis level. It is a bug, because some
sample fetches may be used after the data forwarding (but before the first send
of course). At this stage, if the first block position does not point on the
start-line, most of HTTP sample fetches fail.

So now, when something is forwarding by HTX analyzers, the first block position
is not update anymore.

This issue was reported on Github. See #119. No backport needed.

6 years agoBUG/MINOR: htx: Detect when tail_addr meet end_addr to maximize free rooms
Christopher Faulet [Wed, 12 Jun 2019 09:08:11 +0000 (11:08 +0200)] 
BUG/MINOR: htx: Detect when tail_addr meet end_addr to maximize free rooms

When a block's payload is moved during an expansion or when the whole block is
removed, the addresses of free spaces are updated accordingly. We must be
careful to reset them when <tail_addr> becomes equal to <end_addr>. In this
situation, we can maximize the free space between the blocks and their payload
and set the other one to 0. It is also important to be sure to never have
<end_addr> greater than <tail_addr>.

6 years agoBUG/MINOR: http: Use the global value to limit the number of parsed headers
Christopher Faulet [Tue, 11 Jun 2019 13:05:37 +0000 (15:05 +0200)] 
BUG/MINOR: http: Use the global value to limit the number of parsed headers

Instead of using the macro MAX_HTTP_HDR to limit the number of headers parsed
before throwing an error, we now use the custom global variable
global.tune.max_http_hdr.

This patch must be backported to 1.9.

6 years agoBUG/MINOR: channel/htx: Call channel_htx_full() from channel_full()
Christopher Faulet [Tue, 11 Jun 2019 12:14:49 +0000 (14:14 +0200)] 
BUG/MINOR: channel/htx: Call channel_htx_full() from channel_full()

When channel_full() is called for an HTX stream, we fall back on the HTX
version. This function is called, among other, from tcp_inspect_request(). With
this patch, the inspect delay is respected again.

This patch must be backported to 1.9.

6 years agoBUG/MINOR: fl_trace/htx: Be sure to always forward trailers and EOM
Christopher Faulet [Wed, 12 Jun 2019 14:07:48 +0000 (16:07 +0200)] 
BUG/MINOR: fl_trace/htx: Be sure to always forward trailers and EOM

Previous fix about the random forwarding on the message body was not enough to
fix the bug in all cases. Among others, when there is no data but only the EOM,
we must forward everything.

This patch must be backported to 1.9 if the patch 0bdeeaacb ("BUG/MINOR:
flt_trace/htx: Only apply the random forwarding on the message body.") is also
backported.

6 years agoBUG/MINOR: task: prevent schedulable tasks from starving under high I/O activity
Willy Tarreau [Fri, 14 Jun 2019 06:30:10 +0000 (08:30 +0200)] 
BUG/MINOR: task: prevent schedulable tasks from starving under high I/O activity

With both I/O and tasks in the same tasklet list, we now have a very
smooth and responsive scheduler, providing a good fairness between I/O
activities. With the lower layers relying on tasklet a lot (I/O wakeup,
subscribe, etc), there may often be a large number of totally autonomous
tasklets doing their business such as forwarding data between two muxes.

But the task scheduler historically refrained from picking tasks from the
priority-ordered run queue to put them into the tasklet list until this
later had less than max_runqueue_depth entries. This was to make sure that
low-latency, high-priority tasks would have an opportunity to be dequeued
before others even if they arrive late. But the counter used for this is
still the tasklet list size, which contains countless I/O events. This
causes an unfairness between unbounded I/Os and bounded tasks, resulting
for example in the CLI responding slower when forwarding 40 Gbps of HTTP
traffic spread over a thousand of connections.

A good solution consists in sticking to the initial intent of
max_runqueue_depth which is to limit the number of tasks in the list
(to maintain fairness between them) and not to limit the number of these
tasks among tasklets. It just turns out that the task_list_size initially
was this task counter and changed over time to be a tasklet list size.
Let's simply refrain from updating it for pure tasklets so that it takes
back its original role of counting real tasks as its name implies. With
this change the CLI becomes instantly responsive under load again.

This patch may possibly be backported to 1.9 though it requires some
careful checks.

6 years agoBUG/MEDIUM: h1: Wait for the connection if the handshake didn't complete.
Olivier Houchard [Thu, 13 Jun 2019 15:54:33 +0000 (17:54 +0200)] 
BUG/MEDIUM: h1: Wait for the connection if the handshake didn't complete.

In h1_init(), also add the H1C_F_CS_WAIT_CONN flag if the handshake didn't
complete, otherwise we may end up letting the upper layer sending data too
soon.

6 years agoBUG/MEDIUM: h1: Don't wait for handshake if we had an error.
Olivier Houchard [Thu, 13 Jun 2019 15:37:00 +0000 (17:37 +0200)] 
BUG/MEDIUM: h1: Don't wait for handshake if we had an error.

In h1_process(), only wait for the handshake if we had no error on the
connection. If the handshake failed, we have to let the upper layer know.

6 years agoBUILD/MINOR: 51d: Updated build registration output to indicate thatif the library...
Ben51Degrees [Thu, 13 Jun 2019 15:51:59 +0000 (16:51 +0100)] 
BUILD/MINOR: 51d: Updated build registration output to indicate thatif the library is a dummy one or not.

When built with the dummy 51Degrees library for testing, the output will
include "(dummy library)" to ensure it is clear that this is this is not
the API.

6 years agoMINOR: doc: update the manpage and usage message about -S
William Lallemand [Thu, 13 Jun 2019 15:03:37 +0000 (17:03 +0200)] 
MINOR: doc: update the manpage and usage message about -S

Add -S in the manpage, and update the usage message.

Should be backported to 1.9.

6 years agoBUILD: travis-ci: add 51Degree device detection, update openssl to 1.1.1c
Ilya Shipitsin [Thu, 13 Jun 2019 15:00:05 +0000 (20:00 +0500)] 
BUILD: travis-ci: add 51Degree device detection, update openssl to 1.1.1c

6 years agoCLEANUP: 51d: move the 51d dummy lib to contrib/51d/src to match the real lib
Willy Tarreau [Thu, 13 Jun 2019 13:56:10 +0000 (15:56 +0200)] 
CLEANUP: 51d: move the 51d dummy lib to contrib/51d/src to match the real lib

This way the directory structure remains the same as with the real lib and
one can apply the same build options regardless of where the lib is stored,
removing any possible confusion.

6 years agoBUILD: Silence gcc warning about unused return value
Tim Duesterhus [Wed, 12 Jun 2019 18:47:30 +0000 (20:47 +0200)] 
BUILD: Silence gcc warning about unused return value

gcc (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

complains:

> src/debug.c: In function "ha_panic":
> src/debug.c:162:2: warning: ignoring return value of "write", declared with attribute warn_unused_result [-Wunused-result]
>  (void) write(2, trash.area, trash.data);
>    ^

6 years agoMINOR: doc: mention HAPROXY_LOCALPEER in the man
William Lallemand [Thu, 13 Jun 2019 13:39:48 +0000 (15:39 +0200)] 
MINOR: doc: mention HAPROXY_LOCALPEER in the man

vMention the HAPROXY_LOCALPEER environment variable in the -L argument
of the manpage.

Should be backported in 1.9.

6 years agoMINOR: doc: add master-worker in the man page
William Lallemand [Thu, 13 Jun 2019 09:51:09 +0000 (11:51 +0200)] 
MINOR: doc: add master-worker in the man page

Add some information about the master-worker in the man page.

Should be backported in every version since 1.8.

6 years agoMINOR: doc: Remove -Ds option in man page
Kazuo Yagi [Thu, 13 Jun 2019 08:14:57 +0000 (17:14 +0900)] 
MINOR: doc: Remove -Ds option in man page

Remove -Ds option in man page.

Should be backported in every version since 1.8.

6 years agoMINOR: mworker: add the HAProxy version in "show proc"
William Lallemand [Wed, 12 Jun 2019 17:11:33 +0000 (19:11 +0200)] 
MINOR: mworker: add the HAProxy version in "show proc"

Displays the HAProxy version so you can compare the version of old
processes and new ones.

6 years agoMINOR: mworker: change formatting in uptime field of "show proc"
William Lallemand [Wed, 12 Jun 2019 16:21:17 +0000 (18:21 +0200)] 
MINOR: mworker: change formatting in uptime field of "show proc"

Change the formatting of the uptime field in "show proc" so it's easier
to parse it. Remove the space between the day and the hour and align the
field on 15 characters.

6 years agoMINOR: 51d: Added dummy libraries for the 51Degrees module for testing.
Ben51Degrees [Wed, 12 Jun 2019 14:42:53 +0000 (15:42 +0100)] 
MINOR: 51d: Added dummy libraries for the 51Degrees module for testing.

These are intended for use by HAProxy developers to ensure any changes
did not affect the 51Degrees implementation. The 51Degrees module can be
enabled and used by using the source in contrib/51d. This will run
without breaking, but will not return any meaningful information.

This is ideal for testing HAProxy core code, and other modules alongside
51Degrees, but should never be used as an actual module as it does
nothing.

6 years agoBUG/MINOR: 51d/htx: The _51d_fetch method, and the methods it calls are now HTX aware.
Ben51Degrees [Wed, 12 Jun 2019 14:19:12 +0000 (15:19 +0100)] 
BUG/MINOR: 51d/htx: The _51d_fetch method, and the methods it calls are now HTX aware.

The _51d_fetch method, and the two methods it calls to fetch HTTP
headers (_51d_set_device_offsets, and _51d_set_headers), now support
both legacy and HTX operation.

This should be backported to 1.9.

6 years agoMINOR: http: add a new "http-request replace-uri" action
Willy Tarreau [Wed, 12 Jun 2019 15:44:02 +0000 (17:44 +0200)] 
MINOR: http: add a new "http-request replace-uri" action

This action is particularly convenient to replace some deprecated usees
of "reqrep". It takes a match and a format string including back-
references. The reqrep warning was updated to suggest it as well.

6 years agoDOC: mworker-prog: documentation for the program section
William Lallemand [Wed, 12 Jun 2019 14:32:11 +0000 (16:32 +0200)] 
DOC: mworker-prog: documentation for the program section

This patch documents the program feature.

6 years agoMINOR: fd: Don't use atomic operations when it's not needed.
Olivier Houchard [Wed, 12 Jun 2019 12:31:08 +0000 (14:31 +0200)] 
MINOR: fd: Don't use atomic operations when it's not needed.

In updt_fd_polling(), when updating fd_nbupdt, there's no need to use an
atomic operation, as it's a TLS variable.

6 years ago[RELEASE] Released version 2.0-dev7 v2.0-dev7
Willy Tarreau [Tue, 11 Jun 2019 17:28:00 +0000 (19:28 +0200)] 
[RELEASE] Released version 2.0-dev7

Released version 2.0-dev7 with the following main changes :
    - BUG/MEDIUM: mux-h2: make sure the connection timeout is always set
    - MINOR: tools: add new bitmap manipulation functions
    - MINOR: logs: use the new bitmap functions instead of fd_sets for encoding maps
    - MINOR: chunks: Make sure trash_size is only set once.
    - Revert "MINOR: chunks: Make sure trash_size is only set once."
    - MINOR: threads: serialize threads initialization
    - MINOR peers: data structure simplifications for server names dictionary cache.
    - DOC: peers: Update for dictionary cache entries for peers protocol.
    - MINOR: dict: Store the length of the dictionary entries.
    - MINOR: peers: A bit of optimization when encoding cached server names.
    - MINOR: peers: Optimization for dictionary cache lookup.
    - MEDIUM: tools: improve time format error detection
    - BUG/MEDIUM: H1: When upgrading, make sure we don't free the buffer too early.
    - BUG/MEDIUM: stream_interface: Make sure we call si_cs_process() if CS_FL_EOI.
    - MINOR: threads: avoid clearing harmless twice in thread_release()
    - MEDIUM: threads: add thread_sync_release() to synchronize steps
    - BUG/MEDIUM: init/threads: prevent initialized threads from starting before others
    - OPTIM/MINOR: init/threads: only call protocol_enable_all() on first thread
    - BUG/MINOR: dict: race condition fix when inserting dictionary entries.
    - MEDIUM: init/threads: don't use spinlocks during the init phase
    - BUG/MINOR: cache/htx: Fix the counting of data already sent by the cache applet
    - BUG/MEDIUM: compression/htx: Fix the adding of the last data block
    - MINOR: flt_trace: Don't scrash the original offset during the random forwarding
    - MAJOR: htx: Rework how free rooms are tracked in an HTX message
    - MINOR: htx: Add the function htx_move_blk_before()
    - Revert "BUG/MEDIUM: H1: When upgrading, make sure we don't free the buffer too early."
    - BUG/MINOR: http-rules: mention "deny_status" for "deny" in the error message
    - MINOR: http: turn default error files to HTTP/1.1
    - BUG/MEDIUM: h1: Don't try to subscribe if we had a connection error.
    - BUG/MEDIUM: h1: Don't consider we're connected if the handshake isn't done.
    - MINOR: contrib/spoa_server: Upgrade SPOP to 2.0
    - BUG/MEDIUM: contrib/spoa_server: Set FIN flag on agent frames
    - MINOR: contrib/spoa_server: Add random IP score
    - DOC/MINOR: contrib/spoa_server: Fix typo in README

6 years agoDOC/MINOR: contrib/spoa_server: Fix typo in README
Daniel Corbett [Tue, 11 Jun 2019 14:08:53 +0000 (10:08 -0400)] 
DOC/MINOR: contrib/spoa_server: Fix typo in README

Fix typo in README ps_pyhton.py -> ps_python.py

6 years agoMINOR: contrib/spoa_server: Add random IP score
Daniel Corbett [Tue, 11 Jun 2019 14:04:15 +0000 (10:04 -0400)] 
MINOR: contrib/spoa_server: Add random IP score

The example configuration uses sess.ip_score however this variable
is not referenced within the example scripts.  This patch adds support
for sess.ip_score to the python + lua scripts and generates a
random number between 1 and 100.

6 years agoBUG/MEDIUM: contrib/spoa_server: Set FIN flag on agent frames
Daniel Corbett [Tue, 11 Jun 2019 13:46:27 +0000 (09:46 -0400)] 
BUG/MEDIUM: contrib/spoa_server: Set FIN flag on agent frames

When communicating over SPOP the AGENT-HELLO, AGENT-DISCONNECT,
and ACK frames must have the FIN flag set.

6 years agoMINOR: contrib/spoa_server: Upgrade SPOP to 2.0
Daniel Corbett [Tue, 11 Jun 2019 01:01:32 +0000 (21:01 -0400)] 
MINOR: contrib/spoa_server: Upgrade SPOP to 2.0

Upgrade SPOP version to 2.0

6 years agoBUG/MEDIUM: h1: Don't consider we're connected if the handshake isn't done.
Olivier Houchard [Tue, 11 Jun 2019 14:37:24 +0000 (16:37 +0200)] 
BUG/MEDIUM: h1: Don't consider we're connected if the handshake isn't done.

In h1_process(), don't consider we're connected if we still have handshakes
pending. It used not to happen, because we would not be called if there
were any ongoing handshakes, but that changed now that the handshakes are
handled by a xprt, and not by conn_fd_handler() directly.

6 years agoBUG/MEDIUM: h1: Don't try to subscribe if we had a connection error.
Olivier Houchard [Tue, 11 Jun 2019 14:36:33 +0000 (16:36 +0200)] 
BUG/MEDIUM: h1: Don't try to subscribe if we had a connection error.

If the CO_FL_ERROR flag is set, and we weren't connected yet, don't attempt
to subscribe, as the underlying xprt may already have been destroyed.

6 years agoMINOR: http: turn default error files to HTTP/1.1
Willy Tarreau [Tue, 11 Jun 2019 14:08:25 +0000 (16:08 +0200)] 
MINOR: http: turn default error files to HTTP/1.1

For quite a long time we've been saying that the default error files
should produce HTTP/1.1 responses and since it's of low importance, it
always gets forgotten.

So here it finally comes. Each status code now properly contains a
content-length header so that the output is clean and doesn't force
upstream proxies to switch to chunked encoding or to close the connection
immediately after the response, which is particularly annoying for 401
or 407 for example. It's worth noting that the 3xx codes had already
been turned to HTTP/1.1.

This patch will obviously not change anything for user-provided error files.

6 years agoBUG/MINOR: http-rules: mention "deny_status" for "deny" in the error message
Willy Tarreau [Tue, 11 Jun 2019 14:01:56 +0000 (16:01 +0200)] 
BUG/MINOR: http-rules: mention "deny_status" for "deny" in the error message

The error message indicating an unknown keyword on an http-request rule
doesn't mention the "deny_status" option which comes with the "deny" rule,
this is particularly confusing.

This can be backported to all versions supporting this option.

6 years agoRevert "BUG/MEDIUM: H1: When upgrading, make sure we don't free the buffer too early."
Olivier Houchard [Tue, 11 Jun 2019 12:06:23 +0000 (14:06 +0200)] 
Revert "BUG/MEDIUM: H1: When upgrading, make sure we don't free the buffer too early."

This reverts commit 6c7fe5c3700fac7cc945b2b756df30874cbf77a6.

This patch was harmless, but not needed, conn_upgrade_mux_fe() already takes
care of setting the buffer to BUF_NULL.

6 years agoMINOR: htx: Add the function htx_move_blk_before()
Christopher Faulet [Tue, 11 Jun 2019 08:41:19 +0000 (10:41 +0200)] 
MINOR: htx: Add the function htx_move_blk_before()

The function htx_add_data_before() was removed because it was buggy. The
function htx_move_blk_before() may be used if necessary to do something
equivalent, except it just moves blocks. It doesn't handle the adding.

6 years agoMAJOR: htx: Rework how free rooms are tracked in an HTX message
Christopher Faulet [Tue, 11 Jun 2019 08:40:43 +0000 (10:40 +0200)] 
MAJOR: htx: Rework how free rooms are tracked in an HTX message

In an HTX message, it may have 2 available rooms to store a new block. The first
one is between the blocks and their payload. Blocks are added starting from the
end of the buffer and their payloads are added starting from the begining. So
the first free room is between these 2 edges. The second one is at the begining
of the buffer, when we start to wrap to add new payloads. Once we start to use
this one, the other one is ignored until the next defragmentation of the HTX
message.

In theory, there is no problem. But in practice, some lacks in the HTX structure
force us to defragment too often HTX messages to always be in a known state. The
second free room is not tracked as it should do and the first one may be easily
corrupted when rewrites happen.

So to fix the problem and avoid unecessary defragmentation, the HTX structure
has been refactored. The front (the block's position of the first payload before
the blocks) is no more stored. Instead we keep the relative addresses of 3 edges:

 * tail_addr : The start address of the free space in front of the the blocks
               table
 * head_addr : The start address of the free space at the beginning
 * end_addr  : The end address of the free space at the beginning

Here is the general view of the HTX message now:

           head_addr     end_addr    tail_addr
               |            |            |
               V            V            V
  +------------+------------+------------+------------+------------------+
  |            |            |            |            |                  |
  |  PAYLOAD   | Free space |  PAYLOAD   | Free space |    Blocks area   |
  |    ==>     |     1      |    ==>     |     2      |        <==       |
  +------------+------------+------------+------------+------------------+

<head_addr> is always lower or equal to <end_addr> and <tail_addr>. <end_addr>
is always lower or equal to <tail_addr>.

In addition;, to simplify everything, the blocks area are now contiguous. It
doesn't wrap anymore. So the head is always the block with the lowest position,
and the tail is always the one with the highest position.

6 years agoMINOR: flt_trace: Don't scrash the original offset during the random forwarding
Christopher Faulet [Tue, 11 Jun 2019 08:20:57 +0000 (10:20 +0200)] 
MINOR: flt_trace: Don't scrash the original offset during the random forwarding

There is no bug here, but this patch improves the debug message reported during
the random forwarding. The original offset is kept untouched so its value may be
used to format the message. Before, 0 was always reported.

6 years agoBUG/MEDIUM: compression/htx: Fix the adding of the last data block
Christopher Faulet [Tue, 11 Jun 2019 08:38:38 +0000 (10:38 +0200)] 
BUG/MEDIUM: compression/htx: Fix the adding of the last data block

The function htx_add_data_before() is buggy and cannot work. It first add a data
block and then move it before another one, passed in argument. The problem
happens when a defragmentation is done to add the new block. In this case, the
reference is no longer valid, because the blocks are rearranged. So, instead of
moving the new block before the reference, it is moved at the head of the HTX
message.

So this function has been removed. It was only used by the compression filter to
add a last data block before a TLR, EOT or EOM block. Now, the new function
htx_add_last_data() is used. It adds a last data block, after all others and
before any TLR, EOT or EOM block. Then, the next bock is get. It is the first
non-data block after data in the HTX message. The compression loop continues
with it.

This patch must be backported to 1.9.

6 years agoBUG/MINOR: cache/htx: Fix the counting of data already sent by the cache applet
Christopher Faulet [Tue, 11 Jun 2019 07:58:09 +0000 (09:58 +0200)] 
BUG/MINOR: cache/htx: Fix the counting of data already sent by the cache applet

Since the commit 8f3c256f7 ("MEDIUM: cache/htx: Always store info about HTX
blocks in the cache"), it is possible to read info about a data block without
sending anything. It is possible because we rely on the function htx_add_data(),
which will try to add data without any defragmentation. In such case, info about
the data block are skipped but don't count in data sent.

No need to backport this patch, expect if the commit 8f3c256f7 is backported
too.

6 years agoMEDIUM: init/threads: don't use spinlocks during the init phase
Willy Tarreau [Tue, 11 Jun 2019 07:16:41 +0000 (09:16 +0200)] 
MEDIUM: init/threads: don't use spinlocks during the init phase

PiBa-NL found some pathological cases where starting threads can hinder
each other and cause a measurable slow down. This problem is reproducible
with the following config (haproxy must be built with -DDEBUG_DEV) :

    global
stats socket /tmp/sock1 mode 666 level admin
nbthread 64

    backend stopme
timeout server  1s
option tcp-check
tcp-check send "debug dev exit\n"
server cli unix@/tmp/sock1 check

This will cause the process to be stopped once the checks are ready to
start. Binding all these to just a few cores magnifies the problem.
Starting them in loops shows a significant time difference among the
commits :

  # before startup serialization
  $ time for i in {1..20}; do taskset -c 0,1,2,3 ./haproxy-e186161 -db -f slow-init.cfg >/dev/null 2>&1; done

  real    0m1.581s
  user    0m0.621s
  sys     0m5.339s

  # after startup serialization
  $ time for i in {1..20}; do taskset -c 0,1,2,3 ./haproxy-e4d7c9dd -db -f slow-init.cfg >/dev/null 2>&1; done

  real    0m2.366s
  user    0m0.894s
  sys     0m8.238s

In order to address this, let's use plain mutexes and cond_wait during
the init phase. With this done, waiting threads now sleep and the problem
completely disappeared :

  $ time for i in {1..20}; do taskset -c 0,1,2,3 ./haproxy -db -f slow-init.cfg >/dev/null 2>&1; done

  real    0m0.161s
  user    0m0.079s
  sys     0m0.149s

6 years agoBUG/MINOR: dict: race condition fix when inserting dictionary entries.
Frédéric Lécaille [Tue, 11 Jun 2019 06:34:26 +0000 (08:34 +0200)] 
BUG/MINOR: dict: race condition fix when inserting dictionary entries.

When checking the result of an ebis_insert() call in an ebtree with unique keys,
if already present, in place of freeing() the old one and return the new one,
rather the correct way is to free the new one, and return the old one. For
this, the __dict_insert() function was folded into dict_insert() as this
significantly simplifies the test of duplicates.

Thanks to Olivier for having reported this bug which came with this one:
"MINOR: dict: Add dictionary new data structure".

6 years agoOPTIM/MINOR: init/threads: only call protocol_enable_all() on first thread
Willy Tarreau [Mon, 10 Jun 2019 08:14:52 +0000 (10:14 +0200)] 
OPTIM/MINOR: init/threads: only call protocol_enable_all() on first thread

There's no point in calling this on each and every thread since the first
thread passing there will enable the listeners, and the next ones will
simply scan all of them in turn to discover that they are already
initialized. Let's only initilize them on the first thread. This could
slightly speed up start up on very large configurations, eventhough most
of the time is still spent in the main thread binding the sockets.

A few measurements have constantly shown that this decreases the startup
time by ~0.1s for 150k listeners. Starting all of them in parallel doesn't
provide better results and can still expose some undesired races.

6 years agoBUG/MEDIUM: init/threads: prevent initialized threads from starting before others
Willy Tarreau [Mon, 10 Jun 2019 07:51:04 +0000 (09:51 +0200)] 
BUG/MEDIUM: init/threads: prevent initialized threads from starting before others

Since commit 6ec902a ("MINOR: threads: serialize threads initialization")
we now serialize threads initialization. But doing so has emphasized another
race which is that some threads may actually start the loop before others
are done initializing.

As soon as all threads enter the first thread_release() call, their rdv
bit is cleared and they're all waiting for all others' rdv to be cleared
as well, with their harmless bit set. The first one to notice the cleared
mask will progress through thread_isolate(), take rdv again preventing
most others from noticing its short pass to zero, and this first one will
be able to run all the way through the initialization till the last call
to thread_release() which it happily crosses, being the only one with the
rdv bit, leaving the room for one or a few others to do the same. This
results in some threads entering the loop before others are done with
their initialization, which is particularly bad. PiBa-NL reported that
some regtests fail for him due to this (which was impossible to reproduce
here, but races are racy by definition). However placing some printf()
in the initialization code definitely shows this unsychronized startup.

This patch takes a different approach in three steps :
  - first, we don't start with thread_release() anymore and we don't
    set the rdv mask anymore in the main call. This was initially done
    to let all threads start toghether, which we don't want. Instead
    we just start with thread_isolate(). Since all threads are harmful
    by default, they all wait for each other's readiness before starting.

  - second, we don't release with thread_release() but with
    thread_sync_release(), meaning that we don't leave the function until
    other ones have reached the point in the function where they decide
    to leave it as well.

  - third, it makes sure we don't start the listeners using
    protocol_enable_all() before all threads have allocated their local
    FD tables or have initialized their pollers, otherwise startup could
    be racy as well. It's worth noting that it is even possible to limit
    this call to thread #0 as it only needs to be performed once.

This now guarantees that all thread init calls start only after all threads
are ready, and that no thread enters the polling loop before all others have
completed their initialization.

Please check GH issues #111 and #117 for more context.

No backport is needed, though if some new init races are reported in
1.9 (or even 1.8) which do not affect 2.0, then it may make sense to
carefully backport this small series.

6 years agoMEDIUM: threads: add thread_sync_release() to synchronize steps
Willy Tarreau [Sun, 9 Jun 2019 10:20:02 +0000 (12:20 +0200)] 
MEDIUM: threads: add thread_sync_release() to synchronize steps

This function provides an alternate way to leave a critical section run
under thread_isolate(). Currently, a thread may remain in thread_release()
without having the time to notice that the rdv mask was released and taken
again by another thread entering thread_isolate() (often the same that just
released it). This is because threads wait in harmless mode in the loop,
which is compatible with the conditions to enter thread_isolate(). It's
not possible to make them wait with the harmless bit off or we cannot know
when the job is finished for the next thread to start in thread_isolate(),
and if we don't clear the rdv bit when going there, we create another
race on the start point of thread_isolate().

This new synchronous variant of thread_release() makes use of an extra
mask to indicate the threads that want to be synchronously released. In
this case, they will be marked harmless before releasing their sync bit,
and will wait for others to release their bit as well, guaranteeing that
thread_isolate() cannot be started by any of them before they all left
thread_sync_release(). This allows to construct synchronized blocks like
this :

     thread_isolate()
     /* optionally do something alone here */
     thread_sync_release()
     /* do something together here */
     thread_isolate()
     /* optionally do something alone here */
     thread_sync_release()

And so on. This is particularly useful during initialization where several
steps have to be respected and no thread must start a step before the
previous one is completed by other threads.

This one must not be placed after any call to thread_release() or it would
risk to block an earlier call to thread_isolate() which the current thread
managed to leave without waiting for others to complete, and end up here
with the thread's harmless bit cleared, blocking others. This might be
improved in the future.

6 years agoMINOR: threads: avoid clearing harmless twice in thread_release()
Willy Tarreau [Sun, 9 Jun 2019 06:44:19 +0000 (08:44 +0200)] 
MINOR: threads: avoid clearing harmless twice in thread_release()

thread_release() is to be called after thread_isolate(), i.e. when the
thread already has its harmless bit cleared. No need to clear it twice,
thus avoid calling thread_harmless_end() and directly check the rdv
bits then loop on them.

6 years agoBUG/MEDIUM: stream_interface: Make sure we call si_cs_process() if CS_FL_EOI.
Olivier Houchard [Fri, 7 Jun 2019 16:10:52 +0000 (18:10 +0200)] 
BUG/MEDIUM: stream_interface: Make sure we call si_cs_process() if CS_FL_EOI.

In si_cs_recv(), if we got the CS_FL_EOI flag on the conn_stream, make sure
we return 1, so that si_cs_process() will be called, and wake
process_stream() up, otherwise if we're unlucky the flag will never be
noticed, and the stream won't be woken up.

6 years agoBUG/MEDIUM: H1: When upgrading, make sure we don't free the buffer too early.
Olivier Houchard [Fri, 7 Jun 2019 16:08:17 +0000 (18:08 +0200)] 
BUG/MEDIUM: H1: When upgrading, make sure we don't free the buffer too early.

In h1_release(), when we want to upgrade the mux to h2, make sure we set
h1c->ibuf to BUF_NULL before calling conn_upgrade_mux_fe().
If the upgrade is successful, the buffer will be provided to the new mux,
h1_release() will be called recursively, it will so try to free h1c->ibuf,
and freeing the buffer we just provided to the new mux would be unfortunate.

6 years agoMEDIUM: tools: improve time format error detection
Willy Tarreau [Fri, 7 Jun 2019 17:00:37 +0000 (19:00 +0200)] 
MEDIUM: tools: improve time format error detection

As reported in GH issue #109 and in discourse issue
https://discourse.haproxy.org/t/haproxy-returns-408-or-504-error-when-timeout-client-value-is-every-25d
the time parser doesn't error on overflows nor underflows. This is a
recurring problem which additionally has the bad taste of taking a long
time before hitting the user.

This patch makes parse_time_err() return special error codes for overflows
and underflows, and adds the control in the call places to report suitable
errors depending on the requested unit. In practice, underflows are almost
never returned as the parsing function takes care of rounding values up,
so this might possibly happen on 64-bit overflows returning exactly zero
after rounding though. It is not really possible to cut the patch into
pieces as it changes the function's API, hence all callers.

Tests were run on about every relevant part (cookie maxlife/maxidle,
server inter, stats timeout, timeout*, cli's set timeout command,
tcp-request/response inspect-delay).

6 years agoMINOR: peers: Optimization for dictionary cache lookup.
Frédéric Lécaille [Fri, 7 Jun 2019 12:25:25 +0000 (14:25 +0200)] 
MINOR: peers: Optimization for dictionary cache lookup.

When we look up an dictionary entry in the cache used upon transmission
we store the last result in ->prev_lookup of struct dcache_tx so that
to compare it with the subsequent entries to look up and save performances.