]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
6 years agoMEDIUM: connections: Change struct wait_list to wait_event.
Olivier Houchard [Wed, 10 Oct 2018 16:25:41 +0000 (18:25 +0200)] 
MEDIUM: connections: Change struct wait_list to wait_event.

When subscribing, we don't need to provide a list element, only the h2 mux
needs it. So instead, Add a list element to struct h2s, and use it when a
list is needed.
This forces us to use the unsubscribe method, since we can't just unsubscribe
by using LIST_DEL anymore.
This patch is larger than it should be because it includes some renaming.

6 years agoMINOR: connections: Introduce an unsubscribe method.
Olivier Houchard [Fri, 28 Sep 2018 15:57:58 +0000 (17:57 +0200)] 
MINOR: connections: Introduce an unsubscribe method.

As we don't know how subscriptions are handled, we can't just assume we can
use LIST_DEL() to unsubscribe, so introduce a new method to mux and connections
to do so.

6 years agoBUG/MINOR: checks: queues null-deref
mildis [Tue, 2 Oct 2018 14:46:34 +0000 (16:46 +0200)] 
BUG/MINOR: checks: queues null-deref

queues can be null if calloc() failed.
Bypass free* calls when calloc did fail.

6 years agoBUG/MINOR: h2: null-deref
mildis [Tue, 2 Oct 2018 14:44:18 +0000 (16:44 +0200)] 
BUG/MINOR: h2: null-deref

h2c can be null if pool_alloc() failed.
Bypass tasklet_free and pool_free if pool_alloc did fail.

6 years agoOPTIM: tools: optimize my_ffsl() for x86_64
Willy Tarreau [Wed, 10 Oct 2018 17:05:56 +0000 (19:05 +0200)] 
OPTIM: tools: optimize my_ffsl() for x86_64

This call is now used quite a bit in the fd cache, to decide which cache
to add/remove the fd to/from, when waking up a task for a single thread
in __task_wakeup(), in fd_cant_recv() and in fd_process_cached_events(),
and we can replace it with a single instruction, removing ~30 instructions
and ~80 bytes from the inner loop of some of these functions.

In addition the test for zero value was replaced with a comment saying
that it is illegal and leads to an undefined behaviour. The code does
not make use of this useless case today.

6 years agoBUG/MINOR: threads: move declaration of capabilities to config.h
Willy Tarreau [Wed, 10 Oct 2018 16:29:23 +0000 (18:29 +0200)] 
BUG/MINOR: threads: move declaration of capabilities to config.h

In commit f161d0f51 ("BUG/MINOR: pools/threads: don't ignore DEBUG_UAF
on double-word CAS capable archs") I moved some defines and accidently
messed up with lockfree pools. The problem is that the HA_HAVE_CAS_DW
macro is not defined anymore where the CONFIG_HAP_LOCKLESS_POOLS macro
is set, so this fix implicitly disabled lockfree pools.

This patch fixes this by moving the capabilities definition to config.h
(probably that we'd benefit from having an "arch.h" file to declare the
capabilities offered by the architecture). In a test on a 12-core machine,
we used to measure 19s spent in the pool lock for 1M requests without
this patch, and 0 with it so that's definitely a net saving.

No backport is required, this is only for 1.9.

6 years agoBUG/MEDIUM: Cur/CumSslConns counters not threadsafe.
Emeric Brun [Wed, 10 Oct 2018 12:51:02 +0000 (14:51 +0200)] 
BUG/MEDIUM: Cur/CumSslConns counters not threadsafe.

CurSslConns inc/dec operations are not threadsafe. The unsigned CurSslConns
counter can wrap to a negative value. So we could notice connection rejects
because of MaxSslConns limit artificially exceeded.

CumSslConns inc operation are also not threadsafe so we could miss
some connections and show inconsistenties values compared to CumConns.

This fix should be backported to v1.8.

6 years agoMEDIUM: task: perform a single tree lookup per run queue batch
Willy Tarreau [Wed, 10 Oct 2018 14:39:22 +0000 (16:39 +0200)] 
MEDIUM: task: perform a single tree lookup per run queue batch

The run queue is designed to perform a single tree lookup and to
use multiple passes to eb32sc_next(). The scheduler rework took a
conservative approach first but this is not needed anymore and it
increases the processing cost of process_runnable_tasks() and even
the time during which the RQ lock is held if the global queue is
heavily loaded. Let's simply move the initial lookup to the entry
of the loop like the previous scheduler used to do. This has reduced
by a factor of 5.5 the number of calls to eb32sc_lookup_get() there.

6 years agoCLEANUP: stick-tables: Remove unneeded double (()) around conditional clause
Dirkjan Bussink [Fri, 14 Sep 2018 12:31:22 +0000 (14:31 +0200)] 
CLEANUP: stick-tables: Remove unneeded double (()) around conditional clause

In the past this conditional had multiple conditionals which is why the
additional parentheses were needed. The conditional was simplified but
the duplicate parentheses were not cleaned up.

6 years agoCLEANUP: h1: Fix debug warnings for h1 headers
Dirkjan Bussink [Fri, 14 Sep 2018 12:30:25 +0000 (14:30 +0200)] 
CLEANUP: h1: Fix debug warnings for h1 headers

The wrong method was used to debug the h1m state here. This fixes both
the signature of the h1m method and also fixes the invocation to be
correct.

6 years agoCLEANUP: haproxy: Remove unused variable
Dirkjan Bussink [Fri, 14 Sep 2018 12:29:16 +0000 (14:29 +0200)] 
CLEANUP: haproxy: Remove unused variable

Looking at the code, this variable is no longer used and referenced
nowhere. That means it can be safely removed.

6 years agoMEDIUM: ssl: add support for ciphersuites option for TLSv1.3
Dirkjan Bussink [Fri, 14 Sep 2018 09:14:21 +0000 (11:14 +0200)] 
MEDIUM: ssl: add support for ciphersuites option for TLSv1.3

OpenSSL released support for TLSv1.3. It also added a separate function
SSL_CTX_set_ciphersuites that is used to set the ciphers used in the
TLS 1.3 handshake. This change adds support for that new configuration
option by adding a ciphersuites configuration variable that works
essentially the same as the existing ciphers setting.

Note that it should likely be backported to 1.8 in order to ease usage
of the now released openssl-1.1.1.

6 years agoBUG/MEDIUM: buffers: Make sure we don't wrap in ci_insert_line2/b_rep_blk.
Olivier Houchard [Wed, 26 Sep 2018 13:09:58 +0000 (15:09 +0200)] 
BUG/MEDIUM: buffers: Make sure we don't wrap in ci_insert_line2/b_rep_blk.

In ci_insert_line2() and b_rep_blk(), we can't afford to wrap, so don't use
b_tail() to check if we do, use __b_tail() instead.

This should be backported to previous versions.

6 years agoMINOR: ssl: generate-certificates for BoringSSL
Emmanuel Hocdet [Mon, 1 Oct 2018 16:45:19 +0000 (18:45 +0200)] 
MINOR: ssl: generate-certificates for BoringSSL

6 years agoMINOR: ssl: cleanup old openssl API call
Emmanuel Hocdet [Mon, 1 Oct 2018 16:41:36 +0000 (18:41 +0200)] 
MINOR: ssl: cleanup old openssl API call

For generate-certificates, X509V3_EXT_conf is used but it's an old API
call: X509V3_EXT_nconf must be preferred. Openssl compatibility is ok
because it's inside #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME, introduce 5
years after X509V3_EXT_nconf.

6 years agoREGTEST/MINOR: compatibility: use unix@ instead of abns@ sockets
PiBa-NL [Wed, 3 Oct 2018 21:54:49 +0000 (23:54 +0200)] 
REGTEST/MINOR: compatibility: use unix@ instead of abns@ sockets

Changes the /reg-tests/connection/b00000.vtc test to use unix@ instead of abns@ sockets.
This to allow the test to complete on other operating systems like FreeBSD that do not have 'namespaces'.

6 years agoBUG/MEDIUM: h2: make h2_stream_new() return an error on memory allocation failure
Willy Tarreau [Wed, 3 Oct 2018 16:27:52 +0000 (18:27 +0200)] 
BUG/MEDIUM: h2: make h2_stream_new() return an error on memory allocation failure

Commit 8ae735da0 ("MEDIUM: mux_h2: Revamp the send path when blocking.")
added a tasklet allocation in h2_stream_new(), however the error exit path
fails to reset h2s in case the tasklet cannot be allocated, resulting in
the h2s pointer to be returned as valid to the caller. Let's readjust the
exit path to always return NULL on error and to always log as well (since
there is no reason for not logging on such important errors).

No backport is needed, this is strictly 1.9-dev.

6 years agoBUG/MEDIUM: h2: check that the connection is still valid at the end of init()
Willy Tarreau [Wed, 3 Oct 2018 12:22:21 +0000 (14:22 +0200)] 
BUG/MEDIUM: h2: check that the connection is still valid at the end of init()

Since commit 7505f94f9 ("MEDIUM: h2: Don't use a wake() method anymore."),
the H2 mux's init() calls h2_process(). But this last one may detect an
early error and call h2_release(), destroying the connection, and return
-1. At this point we're screwed because the caller will still dereference
the connection for various things ranging from the configuration of the
proxy protocol header to the retries. We could simply return -1 here upon
failure but that's not enough since the stream layer really needs to keep
its connection structure allocated (to clean it up in session_kill_embryonic
or for example because it holds the destination address to reconnect to
when the connection goes to the backend). Thus the correct solution here is
to only schedule a wakeup of the I/O callback so that the init succeeds,
and that the connection is only handled later.

No backport is needed, this is 1.9-specific.

6 years agoBUG/MINOR: backend: check that the mux installed properly
Willy Tarreau [Wed, 3 Oct 2018 08:20:19 +0000 (10:20 +0200)] 
BUG/MINOR: backend: check that the mux installed properly

The return value from conn_install_mux() was not checked, so if an
inconsistency happens in the code, or a memory allocation fails while
initializing the mux, we can crash while using an uninitialized mux.
In practice the code inconsistency does not really happen since we
cannot configure such a situation, except during development, but
the out of memory condition could definitely happen.

This should be backported to 1.8 (the code is a bit different there,
there are two calls to conn_install_mux()).

6 years agoBUILD: Makefile: speed up compiler options detection
Willy Tarreau [Wed, 3 Oct 2018 07:52:51 +0000 (09:52 +0200)] 
BUILD: Makefile: speed up compiler options detection

Commits b78016649 and d3a7f4035 brought the ability to detect the build
options and warnings that the compiler supports. However, they're detected
using "$(CC) -c", which is 50% slower than "$(CC) -E" for the same result,
just because it starts the assembler at the end. Given that we're starting
to check for a number of warnings, this detection alone starts to become
visible, taking a bit more than 300 ms on the build time. Let's switch to
-E instead to shrink this incompressible time by roughly 100 ms.

6 years agoBUILD: Makefile: add a "make opts" target to simply show the build options
Willy Tarreau [Wed, 3 Oct 2018 07:40:22 +0000 (09:40 +0200)] 
BUILD: Makefile: add a "make opts" target to simply show the build options

We're often missing an easy way to map input variables to output ones.
The "opts" build target will simply show the input variables and the ones
passed to the compiler and linker. This way it's easier to quickly see
what a given build script or package will use, or the detected warnings
supported by the compiler.

6 years agoCLEANUP: http: remove some leftovers from recent cleanups
Willy Tarreau [Tue, 2 Oct 2018 16:37:27 +0000 (18:37 +0200)] 
CLEANUP: http: remove some leftovers from recent cleanups

The prototypes of functions find_hdr_value_end(), extract_cookie_value()
and http_header_match2() were still in proto_http.h while some of them
don't exist anymore and the others were just moved. Let's remove them.
In addition, da.c was updated to use http_extract_cookie_value() which
is the correct one.

6 years agoREORG: http: move HTTP rules parsing to http_rules.c
Willy Tarreau [Tue, 2 Oct 2018 14:43:32 +0000 (16:43 +0200)] 
REORG: http: move HTTP rules parsing to http_rules.c

These ones are mostly called from cfgparse.c for the parsing and do
not depend on the HTTP representation. The functions's prototypes
were moved to proto/http_rules.h, making this file work exactly like
tcp_rules. Ideally we should stop calling these functions directly
from cfgparse and register keywords, but there are a few cases where
that wouldn't work (stats http-request) so it's probably not worth
trying to go this far.

6 years agoREORG: http: move the code to different files
Willy Tarreau [Tue, 2 Oct 2018 14:01:16 +0000 (16:01 +0200)] 
REORG: http: move the code to different files

The current proto_http.c file is huge and contains different processing
domains making it very difficult to work on an alternative representation.
This commit moves some parts to other files :

  - ACL registration code => http_acl.c
    This code only creates some ACL mappings and doesn't know anything
    about HTTP nor about the representation. This code could even have
    moved to acl.c but it was not worth polluting it again.

  - HTTP sample conversion => http_conv.c
    This code doesn't depend on the internal representation but definitely
    manipulates some HTTP elements, such as dates. It also has access to
    captures.

  - HTTP sample fetching => http_fetch.c
    This code does depend entirely on the internal representation but is
    totally independent on the analysers. Placing it into a different
    file will ease the transition to the new representation and the
    creation of a wrapper if required. An include file was created due
    to CHECK_HTTP_MESSAGE_FIRST() being used at various places.

  - HTTP action registration => http_act.c
    This code doesn't directly interact with the messages nor the
    transaction but it does so via some exported http functions like
    http_replace_req_line() or http_set_status() so it will be easier
    to change only this after the conversion.

  - a few very generic parts were found and moved to http.{c,h} as
    relevant.

It is worth noting that the functions moved to these new files are not
referenced anywhere outside of the files and are only called as registered
callbacks, so these files do not even require associated include files.

6 years agoBUG/MINOR: connection: avoid null pointer dereference in send-proxy-v2
Ilya Shipitsin [Fri, 14 Sep 2018 19:50:05 +0000 (00:50 +0500)] 
BUG/MINOR: connection: avoid null pointer dereference in send-proxy-v2

found by coverity.

[wt: this bug was introduced by commit 404d978 ("MINOR: add ALPN
 information to send-proxy-v2"). It might be triggered by a health
 check on a server using ppv2 or by an applet making use of such a
 server, if at all configurable].

This needs to be backported to 1.8.

6 years agoDOC: clarify force-private-cache is an option
Lukas Tribus [Mon, 1 Oct 2018 00:00:16 +0000 (02:00 +0200)] 
DOC: clarify force-private-cache is an option

"boolean" may confuse users into thinking they need to provide
additional arguments, like false or true. This is a simple option
like many others, so lets not confuse the users with internals.

Also fixes an additional typo.

Should be backported to 1.8 and 1.7.

6 years agoBUILD: Allow configuration of pcre-config path
Fabrice Fontaine [Fri, 28 Sep 2018 17:21:26 +0000 (19:21 +0200)] 
BUILD: Allow configuration of pcre-config path

Add PCRE_CONFIG and PCRE2_CONFIG variables to allow the user to
configure path of pcre-config or pcre2-config instead of using the one
in his path.
This is particulary useful when cross-compiling.

Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
6 years ago[RELEASE] Released version 1.9-dev3 v1.9-dev3
Willy Tarreau [Sat, 29 Sep 2018 18:17:33 +0000 (20:17 +0200)] 
[RELEASE] Released version 1.9-dev3

Released version 1.9-dev3 with the following main changes :
    - BUG/MINOR: h1: don't consider the status for each header
    - MINOR: h1: report in the h1m struct if the HTTP version is 1.1 or above
    - MINOR: h1: parse the Connection header field
    - DOC: Fix typos in lua documentation
    - MINOR: h1: Add H1_MF_XFER_LEN flag
    - MINOR: http: add http_hdr_del() to remove a header from a list
    - MINOR: h1: add headers to the list after controls, not before
    - MEDIUM: h1: better handle transfer-encoding vs content-length
    - MEDIUM: h1: deduplicate the content-length header
    - BUG/MEDIUM: patterns: fix possible double free when reloading a pattern list
    - BUG/MEDIUM: h1: Really skip all updates when incomplete messages are parsed
    - CLEANUP/CONTRIB: hpack: remove some h1 build warnings
    - BUG/MINOR: tools: fix set_net_port() / set_host_port() on IPv4
    - BUG/MINOR: cli: make sure the "getsock" command is only called on connections
    - MINOR: stktable: provide an unchecked version of stktable_data_ptr()
    - MINOR: stream-int: make si_appctx() never fail
    - BUILD: ssl_sock: remove build warnings on potential null-derefs
    - BUILD: stats: remove build warnings on potential null-derefs
    - BUILD: stream: address null-deref build warnings at -Wextra
    - BUILD: http: address a couple of null-deref warnings at -Wextra
    - BUILD: log: silent build warnings due to unchecked __objt_{server,applet}
    - BUILD: dns: fix null-deref build warning at -Wextra
    - BUILD: checks: silence a null-deref build warning at -Wextra
    - BUILD: connection: silence a couple of null-deref build warnings at -Wextra
    - BUILD: backend: fix 3 build warnings related to null-deref at -Wextra
    - BUILD: sockpair: silence a build warning at -Wextra
    - BUILD: build with -Wextra and sort out certain warnings
    - BUG/CRITICAL: hpack: fix improper sign check on the header index value
    - BUG/MEDIUM: http: Don't parse chunked body if there is no input data
    - DOC: Update configuration doc about the maximum number of stick counters.
    - BUG/MEDIUM: process_stream: Don't use si_cs_io_cb() in process_stream().
    - MINOR: h2/stream_interface: Reintroduce te wake() method.
    - BUG/MEDIUM: h2: Wake the task instead of calling h2_recv()/h2_process().
    - BUG/MEDIUM: process_stream(): Don't wake the task if no new data was received.
    - MEDIUM: lua: Add stick table support for Lua.

6 years agoMEDIUM: lua: Add stick table support for Lua.
Adis Nezirovic [Fri, 13 Jul 2018 10:18:33 +0000 (12:18 +0200)] 
MEDIUM: lua: Add stick table support for Lua.

This ads support for accessing stick tables from Lua. The supported
operations are reading general table info, lookup by string/IP key, and
dumping the table.

Similar to "show table", a data filter is available during dump, and as
an improvement over "show table" it's possible to use up to 4 filter
expressions instead of just one (with implicit AND clause binding the
expressions). Dumping with/without filters can take a long time for
large tables, and should be used sparingly.

6 years agoBUG/MEDIUM: process_stream(): Don't wake the task if no new data was received.
Olivier Houchard [Fri, 28 Sep 2018 12:38:51 +0000 (14:38 +0200)] 
BUG/MEDIUM: process_stream(): Don't wake the task if no new data was received.

At the eand of process_stream(), we wake the task if there's something in
the input buffer, after attempting a recv. However this is wrong, and we should
only do so if we received new data. Just check the CF_READ_PARTIAL flag.

This is 1.9-specific and should not be backported.

6 years agoBUG/MEDIUM: h2: Wake the task instead of calling h2_recv()/h2_process().
Olivier Houchard [Mon, 24 Sep 2018 16:02:03 +0000 (18:02 +0200)] 
BUG/MEDIUM: h2: Wake the task instead of calling h2_recv()/h2_process().

In a number of cases, we may end up recursively calling h2_recv() via
h2_process(), so just wake the tasklet up instead.

6 years agoMINOR: h2/stream_interface: Reintroduce te wake() method.
Olivier Houchard [Fri, 14 Sep 2018 21:21:44 +0000 (23:21 +0200)] 
MINOR: h2/stream_interface: Reintroduce te wake() method.

For the time being, reintroduce the wake methods, it may be revisited later.h

6 years agoBUG/MEDIUM: process_stream: Don't use si_cs_io_cb() in process_stream().
Olivier Houchard [Fri, 14 Sep 2018 17:41:13 +0000 (19:41 +0200)] 
BUG/MEDIUM: process_stream: Don't use si_cs_io_cb() in process_stream().

Instead of using si_cs_io_cb() in process_stream()  use si_cs_send/si_cs_recv
instead, as si_cs_io_cb() may lead to process_stream being woken up when it
shouldn't be, and thus timeout would never get triggered.

6 years agoDOC: Update configuration doc about the maximum number of stick counters.
Moemen MHEDHBI [Tue, 25 Sep 2018 15:50:53 +0000 (17:50 +0200)] 
DOC: Update configuration doc about the maximum number of stick counters.

Previous patches added support to tracking up to MAX_SESS_STKCTR stick
counters in the same connection, but without updating the DOC, it is done
here.

6 years agoBUG/MEDIUM: http: Don't parse chunked body if there is no input data
Christopher Faulet [Thu, 20 Sep 2018 09:31:01 +0000 (11:31 +0200)] 
BUG/MEDIUM: http: Don't parse chunked body if there is no input data

With recent modifications on the buffers API, when a buffer is released (calling
b_free), we replace it by BUF_NULL where the area pointer is NULL. So many
operations, like b_peek, must be avoided on a released or not allocated
buffer. These changes were mainly made in the commit c9fa048 ("MAJOR: buffer:
finalize buffer detachment").

Since this commit, HAProxy can crash during the body parsing of chunked HTTP
messages because there is no check on the channel's buffer in HTTP analyzers
(http_request_forward_body and http_response_forward_body) nor in H1 functions
reponsible to parse chunked content (h1_skip_chunk_crlf & co). If a stream is
woken up after all input data were forwarded, its input channel's buffer is
released (so set to BUF_NULL). In this case, if we resume the parsing of a
chunk, HAProxy crashes.

To fix this issue, we just skip the parsing of chunks if there is no input data
for the corresponding channel. This is only done if the message state is
strickly lower to HTTP_MSG_ENDING.

6 years agoBUG/CRITICAL: hpack: fix improper sign check on the header index value
Willy Tarreau [Mon, 17 Sep 2018 12:07:33 +0000 (14:07 +0200)] 
BUG/CRITICAL: hpack: fix improper sign check on the header index value

Tim Düsterhus found using afl-fuzz that some parts of the HPACK decoder
use incorrect bounds checking which do not catch negative values after
a type cast. The first culprit is hpack_valid_idx() which takes a signed
int and is fed with an unsigned one, but a few others are affected as
well due to being designed to work with an uint16_t as in the table
header, thus not being able to detect the high offset bits, though they
are not exposed if hpack_valid_idx() is fixed.

The impact is that the HPACK decoder can be crashed by an out-of-bounds
read. The only work-around without this patch is to disable H2 in the
configuration.

CVE-2018-14645 was assigned to this bug.

This patch addresses all of these issues at once. It must be backported
to 1.8.

6 years agoBUILD: build with -Wextra and sort out certain warnings
Willy Tarreau [Thu, 20 Sep 2018 08:38:08 +0000 (10:38 +0200)] 
BUILD: build with -Wextra and sort out certain warnings

We're not far from being able to build with -Wextra -Werror. The
following warnings had to be disabled to enable a clean build at
-Wextra on x86_64 using gcc 4.7, 5.5, 6.4 and 7.3 :

   sign-compare, unused-parameter, old-style-declaration,
   ignored-qualifiers, clobbered, missing-field-initializers,
   implicit-fallthrough

The following extra warnings could be added without side effects :

   type-limits, shift-negative-value, shift-overflow=2 duplicated-cond,
   null-dereference

As a result, -Wextra was enabled by default, hoping it will help catch
issues over the long term. If new undesired warnings pop up, it's easy
to disable them using the nowarn call.

6 years agoBUILD: sockpair: silence a build warning at -Wextra
Willy Tarreau [Thu, 20 Sep 2018 09:39:39 +0000 (11:39 +0200)] 
BUILD: sockpair: silence a build warning at -Wextra

An invalid null-deref warning is emitted because cmsg is not checked,
though it definitely is valid given the test performed 10 lines above,
but the compiler cannot necessarily guess this. Adding a null test to
the problematic condition is enough to get rid of it and cheap enough.

6 years agoBUILD: backend: fix 3 build warnings related to null-deref at -Wextra
Willy Tarreau [Thu, 20 Sep 2018 09:29:28 +0000 (11:29 +0200)] 
BUILD: backend: fix 3 build warnings related to null-deref at -Wextra

These ones are not valid either since the checks are performed a few
lines above the call. Let's switch to __objt_server() instead.

6 years agoBUILD: connection: silence a couple of null-deref build warnings at -Wextra
Willy Tarreau [Thu, 20 Sep 2018 09:26:52 +0000 (11:26 +0200)] 
BUILD: connection: silence a couple of null-deref build warnings at -Wextra

These ones don't need to be checked either.

6 years agoBUILD: checks: silence a null-deref build warning at -Wextra
Willy Tarreau [Thu, 20 Sep 2018 09:25:12 +0000 (11:25 +0200)] 
BUILD: checks: silence a null-deref build warning at -Wextra

Simply don't use cs_conn() on a valid CS.

6 years agoBUILD: dns: fix null-deref build warning at -Wextra
Willy Tarreau [Thu, 20 Sep 2018 09:15:27 +0000 (11:15 +0200)] 
BUILD: dns: fix null-deref build warning at -Wextra

Like for the other checks, the type is being tested just before calling
objt_{server,dns_srvrq}() so let's use the unguarded version instead to
silence the warning.

6 years agoBUILD: log: silent build warnings due to unchecked __objt_{server,applet}
Willy Tarreau [Thu, 20 Sep 2018 09:13:58 +0000 (11:13 +0200)] 
BUILD: log: silent build warnings due to unchecked __objt_{server,applet}

These ones are safe to use there since the same check is performed in
the switch/case they're used it. Let's use the unguarded versions
instead.

6 years agoBUILD: http: address a couple of null-deref warnings at -Wextra
Willy Tarreau [Thu, 20 Sep 2018 09:12:58 +0000 (11:12 +0200)] 
BUILD: http: address a couple of null-deref warnings at -Wextra

These two warnings are caused by the use of objt_server() without
checking its result. These are turned to __objt_server() which is
safe there.

6 years agoBUILD: stream: address null-deref build warnings at -Wextra
Willy Tarreau [Thu, 20 Sep 2018 09:11:15 +0000 (11:11 +0200)] 
BUILD: stream: address null-deref build warnings at -Wextra

These warnings are caused by the improper use of stktable_data_ptr()
whose result is not checked instead of using __stktable_data_ptr().

6 years agoBUILD: stats: remove build warnings on potential null-derefs
Willy Tarreau [Thu, 20 Sep 2018 09:01:01 +0000 (11:01 +0200)] 
BUILD: stats: remove build warnings on potential null-derefs

A couple of objt_appctx() could be replaced with their unchecked
equivalent since the pointer is guaranteed and not checked there.

6 years agoBUILD: ssl_sock: remove build warnings on potential null-derefs
Willy Tarreau [Thu, 20 Sep 2018 08:57:52 +0000 (10:57 +0200)] 
BUILD: ssl_sock: remove build warnings on potential null-derefs

When building with -Wnull-dereferences, gcc sees some cases where a
pointer is dereferenced after a check may set it to null. While all of
these are already guarded by either a preliminary test or the code's
construction (eg: listeners code being called only on listeners), it
cannot be blamed for not "seeing" this, so better use the unguarded
calls everywhere this happens, particularly after checks. This is a
step towards building with -Wextra.

6 years agoMINOR: stream-int: make si_appctx() never fail
Willy Tarreau [Thu, 20 Sep 2018 09:08:47 +0000 (11:08 +0200)] 
MINOR: stream-int: make si_appctx() never fail

Callers of si_appctx() always use the result without checking it because
they know by construction that it's valid. This results in unchecked null
pointer warnings at -Wextra, so let's remove this test and make it clear
that it's up to the caller to check validity first.

6 years agoMINOR: stktable: provide an unchecked version of stktable_data_ptr()
Willy Tarreau [Thu, 20 Sep 2018 09:06:33 +0000 (11:06 +0200)] 
MINOR: stktable: provide an unchecked version of stktable_data_ptr()

stktable_data_ptr() currently performs null pointer checks but most
callers don't check the result since they know by construction that
it cannot be null. This causes valid warnings when building with
-Wextra which are worth addressing since it will result in better
code. Let's provide an unguarded version of this function for use
where the check is known to be useless and untested.

6 years agoBUG/MINOR: cli: make sure the "getsock" command is only called on connections
Willy Tarreau [Thu, 20 Sep 2018 09:22:29 +0000 (11:22 +0200)] 
BUG/MINOR: cli: make sure the "getsock" command is only called on connections

Theorically nothing would prevent a front applet form connecting to a stats
socket, and if a "getsock" command was issued, it would cause a crash. Right
now nothing in the code does this so in its current form there is no impact.

It may or may not be backported to 1.8.

6 years agoBUG/MINOR: tools: fix set_net_port() / set_host_port() on IPv4
Willy Tarreau [Thu, 20 Sep 2018 08:48:35 +0000 (10:48 +0200)] 
BUG/MINOR: tools: fix set_net_port() / set_host_port() on IPv4

These two functions were apparently written on the same model as their
parents when added by commit 11bcb6c4f ("[MEDIUM] IPv6 support for syslog")
except that they perform an assignment instead of a return, and as a
result fall through the next case where the assigned value may possibly
be partially overwritten. At least under Linux the port offset is the
same in both sockaddr_in and sockaddr_in6 so the value is written twice
without side effects.

This needs to be backported as far as 1.5.

6 years agoCLEANUP/CONTRIB: hpack: remove some h1 build warnings
Willy Tarreau [Mon, 17 Sep 2018 09:44:09 +0000 (11:44 +0200)] 
CLEANUP/CONTRIB: hpack: remove some h1 build warnings

These are inherited by recent reorganization to the H1 code.

6 years agoBUG/MEDIUM: h1: Really skip all updates when incomplete messages are parsed
Christopher Faulet [Wed, 19 Sep 2018 12:01:04 +0000 (14:01 +0200)] 
BUG/MEDIUM: h1: Really skip all updates when incomplete messages are parsed

In h1_headers_to_hdr_list, when an incomplete message is parsed, all updates
must be skipped until the end of the message is found. Then the parsing is
restarted from the beginning. But not all updates were skipped, leading to
invalid rewritting or segfault.

No backport is needed.

6 years agoBUG/MEDIUM: patterns: fix possible double free when reloading a pattern list
Dragan Dosen [Tue, 18 Sep 2018 18:18:09 +0000 (20:18 +0200)] 
BUG/MEDIUM: patterns: fix possible double free when reloading a pattern list

A null pointer assignment was missing after free() in function
pat_ref_reload() which can lead to segfault.

This bug was introduced in commit b5997f7 ("MAJOR: threads/map: Make
acls/maps thread safe").

Must be backported to 1.8.

6 years agoMEDIUM: h1: deduplicate the content-length header
Willy Tarreau [Fri, 14 Sep 2018 15:11:33 +0000 (17:11 +0200)] 
MEDIUM: h1: deduplicate the content-length header

Just like we used to do in proto_http, we now check that each and every
occurrence of the content-length header field and each of its values are
exactly identical, and we normalize the header to return the last value
of the first header with spaces trimmed.

6 years agoMEDIUM: h1: better handle transfer-encoding vs content-length
Willy Tarreau [Fri, 14 Sep 2018 14:34:47 +0000 (16:34 +0200)] 
MEDIUM: h1: better handle transfer-encoding vs content-length

The transfer-encoding header processing was a bit lenient in this part
because it was made to read messages already validated by haproxy. We
absolutely need to reinstate the strict processing defined in RFC7230
as is currently being done in proto_http.c. That is, transfer-encoding
presence alone is enough to cancel content-length, and must be
terminated by the "chunked" token, except in the response where we
can fall back to the close mode if it's not last.

For this we now use a specific parsing function which updates the
flags and we introduce a new flag H1_MF_XFER_ENC indicating that the
transfer-encoding header is present.

Last, if such a header is found, we delete all content-length header
fields found in the message.

6 years agoMINOR: h1: add headers to the list after controls, not before
Willy Tarreau [Fri, 14 Sep 2018 14:28:15 +0000 (16:28 +0200)] 
MINOR: h1: add headers to the list after controls, not before

This will ease removal/skipping of duplicates such as content-length.

6 years agoMINOR: http: add http_hdr_del() to remove a header from a list
Willy Tarreau [Fri, 14 Sep 2018 15:32:05 +0000 (17:32 +0200)] 
MINOR: http: add http_hdr_del() to remove a header from a list

This one removes all occurrences of the specified header field name from
a complete list and returns the new count.

6 years agoMINOR: h1: Add H1_MF_XFER_LEN flag
Christopher Faulet [Fri, 14 Sep 2018 09:15:52 +0000 (11:15 +0200)] 
MINOR: h1: Add H1_MF_XFER_LEN flag

This flag is usefull to handle cases where there is no body, regardless of CL or
TE headers (for instance, responses to HEAD requests). It will not be set by the
parser itself.

6 years agoDOC: Fix typos in lua documentation
Bertrand Jacquin [Mon, 10 Sep 2018 20:26:07 +0000 (21:26 +0100)] 
DOC: Fix typos in lua documentation

6 years agoMINOR: h1: parse the Connection header field
Willy Tarreau [Thu, 13 Sep 2018 12:15:58 +0000 (14:15 +0200)] 
MINOR: h1: parse the Connection header field

The new function h1_parse_connection_header() is called when facing a
connection header in the generic parser, and it will set up to 3 bits
in h1m->flags indicating if at least one "close", "keep-alive" or "upgrade"
tokens was seen.

6 years agoMINOR: h1: report in the h1m struct if the HTTP version is 1.1 or above
Willy Tarreau [Thu, 13 Sep 2018 09:32:51 +0000 (11:32 +0200)] 
MINOR: h1: report in the h1m struct if the HTTP version is 1.1 or above

This will be needed for the mux to know how to process the Connection
header, and will save it from having to re-parse the request line since
it's captured on the fly.

6 years agoBUG/MINOR: h1: don't consider the status for each header
Willy Tarreau [Thu, 13 Sep 2018 09:52:20 +0000 (11:52 +0200)] 
BUG/MINOR: h1: don't consider the status for each header

While it was possible to consider the status before parsing response
headers, it's wrong to do it for request headers and could lead to
random behaviours due to this status matching other fields instead.
Additionnally there is little to no value in doing this for each and
every new header field. It's much better to reset the content-length
at once in the callerwhen seeing such statuses (which currently is only
the H2 mux).

No backport is needed, this is purely 1.9.

6 years ago[RELEASE] Released version 1.9-dev2 v1.9-dev2
Willy Tarreau [Wed, 12 Sep 2018 16:59:48 +0000 (18:59 +0200)] 
[RELEASE] Released version 1.9-dev2

Released version 1.9-dev2 with the following main changes :
    - BUG/MINOR: buffers: Fix b_slow_realign when a buffer is realign without output
    - BUG/MEDIUM: threads: fix the no-thread case after the change to the sync point
    - BUG/MEDIUM: servers: check the queues once enabling a server
    - BUG/MEDIUM: queue: prevent a backup server from draining the proxy's connections
    - MEDIUM: mux: Remove const on the buffer in mux->snd_buf()
    - CLEANUP: backend: Move mux install to call it at only one place
    - MINOR: conn_stream: add an tx buffer to the conn_stream
    - MINOR: conn_stream: add cs_send() as a default snd_buf() function
    - MINOR: backend: Try to find the best mux for outgoing connections
    - MEDIUM: backend: don't rely on mux_pt_ops in connect_server()
    - MINOR: mux: Add info about the supported side in alpn_mux_list structure
    - MINOR: mux: Unlink ALPN and multiplexers to rather speak of mux protocols
    - MINOR: mux: Print the list of existing mux protocols during HA startup
    - MEDIUM: checks: use the new rendez-vous point to spread check result
    - MEDIUM: haproxy: don't use sync_poll_loop() anymore in the main loop
    - MINOR: threads: remove the previous synchronization point
    - MAJOR: server: make server state changes synchronous again
    - CLEANUP: server: remove the update list and the update lock
    - BUG/MINOR: threads: Remove the unexisting lock label "UPDATED_SERVERS_LOCK"
    - BUG/MEDIUM: stream_int: Don't check CO_FL_SOCK_RD_SH flag to trigger cs receive
    - MINOR: mux: Change get_mux_proto to get an ist as parameter
    - MINOR: mux: Improve the message with the list of existing mux protocols
    - MINOR: mux/frontend: Add 'proto' keyword to force the mux protocol
    - MINOR: mux/server: Add 'proto' keyword to force the multiplexer's protocol
    - MEDIUM: mux: Use the mux protocol specified on bind/server lines
    - BUG/MEDIUM: connection/mux: take care of serverless proxies
    - MINOR: queue: make sure the pendconn is released before logging
    - MINOR: stream: rename {srv,prx}_queue_size to *_queue_pos
    - MINOR: queue: store the queue index in the stream when enqueuing
    - MINOR: queue: replace the linked list with a tree
    - MEDIUM: add set-priority-class and set-priority-offset
    - MEDIUM: queue: adjust position based on priority-class and priority-offset
    - DOC: update the roadmap about priority queues
    - BUG/MINOR: ssl: empty connections reported as errors.
    - MINOR: connections: Make rcv_buf mandatory and nuke cs_recv().
    - MINOR: connections: Move rxbuf from the conn_stream to the h2s.
    - MINOR: connections: Get rid of txbuf.
    - MINOR: tasks: Allow tasklet_wakeup() to wakeup a task.
    - MINOR: connections/mux: Add the wait reason(s) to wait_list.
    - MINOR: stream_interface: Don't use si_cs_send() as a task handler.
    - MINOR: stream_interface: Give stream_interface its own wait_list.
    - MINOR: mux_h2: Don't use h2_send() as a callback.
    - MINOR: checks: Add event_srv_chk_io().
    - BUG/MEDIUM: tasks: Don't insert in the global rqueue if nbthread == 1
    - BUG/MEDIUM: sessions: Don't use t->state.
    - BUG/MEDIUM: ssl: fix missing error loading a keytype cert from a bundle.
    - BUG/MEDIUM: ssl: loading dh param from certifile causes unpredictable error.
    - BUG/MINOR: map: fix map_regm with backref
    - DOC: dns: explain set server ... fqdn requires resolver
    - DOC: add documentation for prio_class and prio_offset sample fetches.
    - DOC: ssl: Use consistent naming for TLS protocols
    - DOC: update the layering design notes
    - MINOR: tasks: Don't special-case when nbthreads == 1
    - MINOR: fd cache: And the thread_mask with all_threads_mask.
    - BUG/MEDIUM: lua: socket timeouts are not applied
    - BUG/MINOR: lua: fix extra 500ms added to socket timeouts
    - BUG/MEDIUM: server: update our local state before propagating changes
    - BUG/MEDIUM: cli/threads: protect all "proxy" commands against concurrent updates
    - DOC: server/threads: document which functions need to be called with/without locks
    - BUG/MEDIUM: cli/threads: protect some server commands against concurrent operations
    - BUG/MEDIUM: streams: Don't forget to remove the si from the wait list.
    - BUG/MEDIUM: tasklets: Add the thread as active when waking a tasklet.
    - BUG/MEDIUM: stream-int: Check if the conn_stream exist in si_cs_io_cb.
    - BUG/MEDIUM: H2: Activate polling after successful h2_snd_buf().
    - BUG/MEDIUM: stream_interface: Call the wake callback after sending.
    - BUG/MAJOR: queue/threads: make pendconn_redistribute not lock the server
    - BUG/MEDIUM: connection: don't forget to always delete the list's head
    - BUG/MEDIUM: lb/threads: always properly lock LB algorithms on maintenance operations
    - BUG/MEDIUM: check/threads: do not involve the rendez-vous point for status updates
    - BUG/MINOR: chunks: do not store -1 into chunk_printf() in case of error
    - BUG/MEDIUM: http: don't store exp_replace() result in the trash's length
    - BUG/MEDIUM: http: don't store url_decode() result in the samples's length
    - BUG/MEDIUM: dns: don't store dns_build_query() result in the trash's length
    - BUG/MEDIUM: map: don't store exp_replace() result in the trash's length
    - BUG/MEDIUM: connection: don't store recv() result into trash.data
    - BUG/MEDIUM: cli/ssl: don't store base64dec() result in the trash's length
    - MINOR: chunk: remove impossible tests on negative chunk->data
    - MINOR: sample: remove impossible tests on negative smp->data.u.str.data
    - DOC: Fix spelling error in configuration doc
    - REGTEST/MINOR: Missing mandatory "ignore_unknown_macro".
    - REGTEST/MINOR: Add a new class of regression testing files.
    - BUG/MEDIUM: unix: provide a ->drain() function
    - MINOR: connection: make conn_sock_drain() work for all socket families
    - BUG/MINOR: lua: Bad HTTP client request duration.
    - REGEST/MINOR: Add reg testing files.
    - BUG/MEDIUM: mux_pt: dereference the connection with care in mux_pt_wake()
    - REGTEST/MINOR: Add a reg testing file for b406b87 commit.
    - BUG/MEDIUM: lua: reset lua transaction between http requests
    - MINOR: add be_conn_free sample fetch
    - MINOR: Add srv_conn_free sample fetch
    - BUG/MEDIUM: hlua: Make sure we drain the output buffer when done.
    - MINOR: checks: Call wake_srv_chk() when we can finally send data.
    - BUG/MEDIUM: stream_interface: try to call si_cs_send() earlier.
    - BUG/MAJOR: thread: lua: Wrong SSL context initialization.
    - REGTEST/MINOR: Add a reg testing file for 3e60b11.
    - BUG/MEDIUM: hlua: Don't call RESET_SAFE_LJMP if SET_SAFE_LJMP returns 0.
    - REGTEST/MINOR: lua: Add reg testing files for 70d318c.
    - BUG/MEDIUM: dns/server: fix incomatibility between SRV resolution and server state file
    - BUG/MEDIUM: ECC cert should work with TLS < v1.2 and openssl >= 1.1.1
    - MINOR: tools: make date2str_log() take some consts
    - MINOR: thread: implement HA_ATOMIC_XADD()
    - BUG/MINOR: stream: use atomic increments for the request counter
    - BUG/MEDIUM: session: fix reporting of handshake processing time in the logs
    - BUG/MEDIUM: h2: fix risk of memory leak on malformated wrapped frames
    - BUG/MAJOR: buffer: fix incorrect check in __b_putblk()
    - MINOR: log: move the log code to sess_build_logline() to add extra arguments
    - MINOR: log: make the backend fall back to the frontend when there's no stream
    - MINOR: log: make sess_build_logline() not dereference a NULL stream for txn
    - MINOR: log: don't unconditionally pick log info from s->logs
    - CLEANUP: log: make the low_level lf_{ip,port,text,text_len} functions take consts
    - MINOR: log: keep a copy of the backend connection early in sess_build_logline()
    - MINOR: log: do not dereference a null stream to access captures
    - MINOR: log: be sure not to dereference a null stream for a target
    - MINOR: log: don't check the stream-int's conn_retries if the stream is NULL
    - MINOR: log: use NULL for the unique_id if there is no stream
    - MINOR: log: keep a copy of s->flags early to avoid a dereference
    - MINOR: log: use zero as the request counter if there is no stream
    - MEDIUM: log: make sess_build_logline() support being called with no stream
    - MINOR: log: provide a function to emit a log for a session
    - MEDIUM: h2: produce some logs on early errors that prevent streams from being created
    - BUG/MINOR: h1: fix buffer shift after realignment
    - MINOR: connection: make the initialization more consistent
    - MINOR: connection: add new function conn_get_proxy()
    - MINOR: connection: add new function conn_is_back()
    - MINOR: log: One const should be enough.
    - BUG/MINOR: dns: check and link servers' resolvers right after config parsing
    - BUG/MINOR: http/threads: atomically increment the error snapshot ID
    - MINOR: snapshot: restart on the event ID and not the stream ID
    - MINOR: snapshot: split the error snapshots into common and proto-specific parts
    - MEDIUM: snapshot: start to reorder the HTTP snapshot output a little bit
    - MEDIUM: snapshot: implement a show() callback and use it for HTTP
    - MINOR: proxy: add a new generic proxy_capture_error()
    - MINOR: http: make the HTTP error capture rely on the generic proxy code
    - MINOR: http: remove the pointer to the error snapshot in http_capture_bad_message()
    - REORG: cli: move the "show errors" handler from http to proxy
    - BUG/MEDIUM: snapshot: take the proxy's lock while dumping errors
    - MEDIUM: snapshots: dynamically allocate the snapshots
    - MEDIUM: snapshot: merge the captured data after the descriptor
    - MEDIUM: mworker: remove register/unregister signal functions
    - MEDIUM: mworker: use the haproxy poll loop
    - BUG/MINOR: mworker: no need to stop peers for each proxy
    - MINOR: mworker: mworker_cleanlisteners() delete the listeners
    - MEDIUM: mworker: block SIGCHLD until the master is ready
    - MEDIUM: mworker: never block SIG{TERM,INT} during reload
    - MEDIUM: startup: unify signal init between daemon and mworker mode
    - MINOR: mworker: don't deinit the poller fd when in wait mode
    - MEDIUM: mworker: master wait mode use its own initialization
    - MEDIUM: mworker: replace the master pipe by socketpairs
    - MINOR: mworker: keep and clean the listeners
    - MEDIUM: threads: close the thread-waker pipe during deinit
    - MEDIUM: mworker: call per_thread deinit in mworker_reload()
    - REORG: http: move the HTTP semantics definitions to http.h/http.c
    - REORG: http: move http_get_path() to http.c
    - REORG: http: move error codes production and processing to http.c
    - REORG: http: move the log encoding tables to log.c
    - REORG: http: move some header value processing functions to http.c
    - BUG/MAJOR: kqueue: Don't reset the changes number by accident.
    - MEDIUM: protocol: use a custom AF_MAX to help protocol parser
    - MEDIUM: protocol: sockpair protocol
    - TESTS: add a python wrapper for sockpair@
    - BUG/MINOR: server: Crash when setting FQDN via CLI.
    - BUG/MINOR: h2: report asynchronous end of stream on closed connections
    - BUILD: fix build without thread
    - BUG/MEDIUM: tasks: Don't forget to decrement task_list_size in tasklet_free().
    - MEDIUM: connections: Don't reset the polling flags in conn_fd_handler().
    - MEDIUM: connections/mux: Add a recv and a send+recv wait list.
    - MEDIUM: connections: Get rid of the recv() method.
    - MINOR: h2: Let user of h2_recv() and h2_send() know xfer has been done.
    - MEDIUM: h2: always subscribe to receive if allowed.
    - MEDIUM: h2: Don't use a wake() method anymore.
    - MEDIUM: stream_interface: Make recv() subscribe when more data is needed.
    - MINOR: connections: Add a "handle" field to wait_list.
    - MEDIUM: mux_h2: Revamp the send path when blocking.
    - MEDIUM: stream_interfaces: Starts receiving from the upper layers.
    - MINOR: checks: Give checks their own wait_list.
    - MINOR: conn_streams: Remove wait_list from conn_streams.
    - REORG: h1: create a new h1m_state
    - MINOR: h1: add the restart offsets into struct h1m
    - MINOR: h1: remove the unused states from h1m_state
    - MINOR: h1: provide a distinct init() function for request and response
    - MINOR: h1: add a message flag to indicate that a message carries a response
    - MINOR: h2: make sure h1m->err_pos field is correct on chunk error
    - MINOR: h1: properly pre-initialize err_pos to -2
    - MINOR: mux_h2: replace the req,res h1 messages with a single h1 message
    - MINOR: h2: pre-initialize h1m->err_pos to -1 on the output path
    - MEDIUM: h1: consider err_pos before deciding to accept a header name or not
    - MEDIUM: h1: make the parser support a pointer to a start line
    - MEDIUM: h1: let the caller pass the initial parser's state
    - MINOR: h1: make the message parser support a null <hdr> argument
    - MEDIUM: h1: support partial message parsing
    - MEDIUM: h1: remove the useless H1_MSG_BODY state
    - MINOR: h2: store the HTTP status into the H2S, not the H1M
    - MINOR: h1: remove the HTTP status from the H1M struct
    - MEDIUM: h1: implement the request parser as well
    - MINOR: h1: add H1_MF_TOLOWER to decide when to turn header names to lower case
    - MINOR: connection: pass the proxy when creating a connection
    - BUG/MEDIUM: h2: Don't forget to empty the wait lists on destroy.
    - BUG/MEDIUM: h2: Don't forget to set recv_wait_list to NULL in h2_detach.
    - BUG/MAJOR: h2: reset the parser's state on mux buffer full

6 years agoBUG/MAJOR: h2: reset the parser's state on mux buffer full
Willy Tarreau [Wed, 12 Sep 2018 16:51:18 +0000 (18:51 +0200)] 
BUG/MAJOR: h2: reset the parser's state on mux buffer full

The h2 parser has this specificity that if it cannot send the headers
frame resulting from the headers it just parsed, it needs to drop it
and parse it again later. Since commit 8852850 ("MEDIUM: h1: let the
caller pass the initial parser's state"), when this happens the parser
remains in the data state and the headers are not parsed again next
time, resulting in a parse error. Let's reset the parser on exit there.

No backport is needed.

6 years agoBUG/MEDIUM: h2: Don't forget to set recv_wait_list to NULL in h2_detach.
Olivier Houchard [Wed, 12 Sep 2018 15:56:08 +0000 (17:56 +0200)] 
BUG/MEDIUM: h2: Don't forget to set recv_wait_list to NULL in h2_detach.

If we're detaching the conn_stream, and it was subscribed to be waken up
when more data was available to receive, unsubscribe it.

No backport is needed.

6 years agoBUG/MEDIUM: h2: Don't forget to empty the wait lists on destroy.
Olivier Houchard [Wed, 12 Sep 2018 15:52:46 +0000 (17:52 +0200)] 
BUG/MEDIUM: h2: Don't forget to empty the wait lists on destroy.

Empty both send_list and fctl_list when destroying the h2 context, so that
if we're freeing the stream after, it doesn't try to remove itself from the
now-deleted list.

No backport is needed.

6 years agoMINOR: connection: pass the proxy when creating a connection
Willy Tarreau [Wed, 12 Sep 2018 10:02:05 +0000 (12:02 +0200)] 
MINOR: connection: pass the proxy when creating a connection

Till now it was very difficult for a mux to know what proxy it was
working for. Let's pass the proxy when the mux is instanciated at
init() time. It's not yet used but the H1 mux will definitely need
it, just like the H2 mux when dealing with backend connections.

6 years agoMINOR: h1: add H1_MF_TOLOWER to decide when to turn header names to lower case
Willy Tarreau [Wed, 12 Sep 2018 07:54:00 +0000 (09:54 +0200)] 
MINOR: h1: add H1_MF_TOLOWER to decide when to turn header names to lower case

The h1 parser used to systematically turn header field names to lower
case because it was designed for H2. Let's add a flag which is off by
default to condition this behaviour so that when using it from an H1
parser it will not affect the message.

6 years agoMEDIUM: h1: implement the request parser as well
Willy Tarreau [Tue, 11 Sep 2018 15:57:05 +0000 (17:57 +0200)] 
MEDIUM: h1: implement the request parser as well

The original H1 request parsing code was reintroduced into the generic
H1 parser so that it can be used regardless of the direction. If the
parser is interrupted and restarts, it makes use of the H1_MF_RESP
flag to decide whether to re-parse a request or a response. While
parsing the request, the method is decoded and set into the start line
structure.

6 years agoMINOR: h1: remove the HTTP status from the H1M struct
Willy Tarreau [Tue, 11 Sep 2018 17:23:04 +0000 (19:23 +0200)] 
MINOR: h1: remove the HTTP status from the H1M struct

It has nothing to do there and is not used from there anymore, let's
get rid of it.

6 years agoMINOR: h2: store the HTTP status into the H2S, not the H1M
Willy Tarreau [Tue, 11 Sep 2018 17:22:14 +0000 (19:22 +0200)] 
MINOR: h2: store the HTTP status into the H2S, not the H1M

The HTTP status is not relevant to the H1 message but to the H2 stream
itself. It used to be placed there by pure convenience but better move
it before it's too hard to remove.

6 years agoMEDIUM: h1: remove the useless H1_MSG_BODY state
Willy Tarreau [Wed, 12 Sep 2018 15:25:32 +0000 (17:25 +0200)] 
MEDIUM: h1: remove the useless H1_MSG_BODY state

This state was only a delimiter between headers and body but it now
causes more harm than good because it requires someone to change it.
Since the H1 parser knows if we're in DATA or CHUNK_SIZE, simply let
it set the right next state so that h1m->state constantly matches
what is expected afterwards.

6 years agoMEDIUM: h1: support partial message parsing
Willy Tarreau [Tue, 11 Sep 2018 14:20:30 +0000 (16:20 +0200)] 
MEDIUM: h1: support partial message parsing

While it was not needed in the H2 mux which was reading full H1 messages
from the channel, it is mandatory for the H1 mux reading contents from
outside to be able to restart on a message. The problem is that the
headers are indexed on the fly, and it's not fun to have to store
everything between calls.

The solution here is to complete the first pass doing a partial restart,
and only once the end of message was found, to start over it again at
once, filling entries. This way there is a bounded number of passes on
the contents and no need to store an intermediary result anymore. Later
this principle could even be used to decide to completely drop an output
buffer to save memory.

6 years agoMINOR: h1: make the message parser support a null <hdr> argument
Willy Tarreau [Tue, 11 Sep 2018 14:04:48 +0000 (16:04 +0200)] 
MINOR: h1: make the message parser support a null <hdr> argument

This will allow some iterative calls to be made on incomplete messages
without having to store all the headers.

6 years agoMEDIUM: h1: let the caller pass the initial parser's state
Willy Tarreau [Tue, 11 Sep 2018 13:33:32 +0000 (15:33 +0200)] 
MEDIUM: h1: let the caller pass the initial parser's state

This way the caller controls if it's the request or response which has
to be used, and it will allow to restart after an incomplete parsing.

6 years agoMEDIUM: h1: make the parser support a pointer to a start line
Willy Tarreau [Tue, 11 Sep 2018 13:34:50 +0000 (15:34 +0200)] 
MEDIUM: h1: make the parser support a pointer to a start line

This will allow the parser to fill some extra fields like the method or
status without having to store them permanently in the HTTP message. At
this point however the parser cannot restart from an interrupted read.

6 years agoMEDIUM: h1: consider err_pos before deciding to accept a header name or not
Willy Tarreau [Wed, 12 Sep 2018 07:20:40 +0000 (09:20 +0200)] 
MEDIUM: h1: consider err_pos before deciding to accept a header name or not

Till now the H1 parser made for H2 used to be lenient on invalid header
field names because they were supposed to be produced by haproxy. Now
instead we'll rely on err_pos to know how to act (ie: -2 == must block).

6 years agoMINOR: h2: pre-initialize h1m->err_pos to -1 on the output path
Willy Tarreau [Wed, 12 Sep 2018 07:24:38 +0000 (09:24 +0200)] 
MINOR: h2: pre-initialize h1m->err_pos to -1 on the output path

We don't want to trigger an error while parsing a response coming from
haproxy (it could be an errorfile for example), so let's set this to
-1.

6 years agoMINOR: mux_h2: replace the req,res h1 messages with a single h1 message
Willy Tarreau [Tue, 11 Sep 2018 11:52:04 +0000 (13:52 +0200)] 
MINOR: mux_h2: replace the req,res h1 messages with a single h1 message

There's no reason to have the two sides in H1 format since we only use
one at a time (the response at the moment). While completely removing
the request declaration, let's rename the response to "h1m" to clarify
that it's the unique h1 message there.

6 years agoMINOR: h1: properly pre-initialize err_pos to -2
Willy Tarreau [Wed, 12 Sep 2018 07:08:54 +0000 (09:08 +0200)] 
MINOR: h1: properly pre-initialize err_pos to -2

This way we maintain the old mechanism stating that -2 means we block
on errors, -1 means we only capture them, and a positive value indicates
the position of the first error.

6 years agoMINOR: h2: make sure h1m->err_pos field is correct on chunk error
Willy Tarreau [Wed, 12 Sep 2018 07:05:16 +0000 (09:05 +0200)] 
MINOR: h2: make sure h1m->err_pos field is correct on chunk error

This never happens but in case it would, it's better to report the
correct offset of the error instead of a negative value.

6 years agoMINOR: h1: add a message flag to indicate that a message carries a response
Willy Tarreau [Tue, 11 Sep 2018 14:47:23 +0000 (16:47 +0200)] 
MINOR: h1: add a message flag to indicate that a message carries a response

This flag is H1_MF_RESP. It will be used by the parser during restarts when
it supports requests.

6 years agoMINOR: h1: provide a distinct init() function for request and response
Willy Tarreau [Tue, 11 Sep 2018 11:51:19 +0000 (13:51 +0200)] 
MINOR: h1: provide a distinct init() function for request and response

h1m_init() used to handle response only since it was used by the H1
client code. Let's have one init per direction.

6 years agoMINOR: h1: remove the unused states from h1m_state
Willy Tarreau [Tue, 11 Sep 2018 10:01:48 +0000 (12:01 +0200)] 
MINOR: h1: remove the unused states from h1m_state

States ERROR, 100_SENT, ENDING, CLOSE, CLOSING are not used at all for
the parsers. It's possible that a few others may disappear as well.

6 years agoMINOR: h1: add the restart offsets into struct h1m
Willy Tarreau [Tue, 11 Sep 2018 09:51:31 +0000 (11:51 +0200)] 
MINOR: h1: add the restart offsets into struct h1m

Currently the only user of struct h1m is the h2 mux when it has to parse
an H1 message coming from the channel. Unfortunately this is not enough
to efficiently parse HTTP/1 messages like those coming from the network
as we don't want to restart from scratch at every byte received.

This patch reintroduces the "next" offset into the H1 message so that any
H1 parser can use it to restart when called with a state that is not the
initial state.

6 years agoREORG: h1: create a new h1m_state
Willy Tarreau [Tue, 11 Sep 2018 09:45:04 +0000 (11:45 +0200)] 
REORG: h1: create a new h1m_state

This is the *parsing* state of an HTTP/1 message. Currently the h1_state
is composite as it's made both of parsing and control (100SENT, BODY,
DONE, TUNNEL, ENDING etc). The purpose here is to have a purely H1 state
that can be used by H1 parsers. For now it's equivalent to h1_state.

6 years agoMINOR: conn_streams: Remove wait_list from conn_streams.
Olivier Houchard [Wed, 12 Sep 2018 13:21:03 +0000 (15:21 +0200)] 
MINOR: conn_streams: Remove wait_list from conn_streams.

The conn_streams won't be used for subscribing/waiting for I/O events, after
all, so just remove its wait_list, and send/recv/_wait_list.

6 years agoMINOR: checks: Give checks their own wait_list.
Olivier Houchard [Wed, 12 Sep 2018 13:15:12 +0000 (15:15 +0200)] 
MINOR: checks: Give checks their own wait_list.

Instead of (ab)using the conn_stream's wait_list, which should disappear,
give the checks their own wait_list.

6 years agoMEDIUM: stream_interfaces: Starts receiving from the upper layers.
Olivier Houchard [Tue, 11 Sep 2018 16:27:21 +0000 (18:27 +0200)] 
MEDIUM: stream_interfaces: Starts receiving from the upper layers.

Instead of waiting for the connection layer to let us know we can read,
attempt to receive as soon as process_stream() is called, and subscribe
to receive events if we can't receive yet.

Now, except for idle connections, the recv(), send() and wake() methods are
no more, all the lower layers do is waking tasklet for anybody waiting
for I/O events.

6 years agoMEDIUM: mux_h2: Revamp the send path when blocking.
Olivier Houchard [Tue, 11 Sep 2018 16:24:28 +0000 (18:24 +0200)] 
MEDIUM: mux_h2: Revamp the send path when blocking.

Change fctl_list and send_list to be lists of struct wait_list, and nuke
send_wait_list, as it's now redundant.
Make the code responsible for shutr/shutw subscribe to those lists.

6 years agoMINOR: connections: Add a "handle" field to wait_list.
Olivier Houchard [Fri, 31 Aug 2018 15:43:32 +0000 (17:43 +0200)] 
MINOR: connections: Add a "handle" field to wait_list.

Add a new field to struct wait_list, "handle", that can be used by the
entity in charge of subscribing.

6 years agoMEDIUM: stream_interface: Make recv() subscribe when more data is needed.
Olivier Houchard [Fri, 31 Aug 2018 15:29:12 +0000 (17:29 +0200)] 
MEDIUM: stream_interface: Make recv() subscribe when more data is needed.

Refactor the code so that si_cs_recv() subscribes to receive events.

6 years agoMEDIUM: h2: Don't use a wake() method anymore.
Olivier Houchard [Tue, 21 Aug 2018 16:10:44 +0000 (18:10 +0200)] 
MEDIUM: h2: Don't use a wake() method anymore.

Instead of having our wake() method called each time a fd event happens,
just subscribe to recv/send events, and get our tasklet called when that
happens. If any recv/send was possible, the equivalent of what h2_wake_cb()
will be done.

6 years agoMEDIUM: h2: always subscribe to receive if allowed.
Olivier Houchard [Fri, 17 Aug 2018 16:42:48 +0000 (18:42 +0200)] 
MEDIUM: h2: always subscribe to receive if allowed.

Let the connection layer know we're always interested in getting more data,
so that we get scheduled as soon as data is available, instead of relying
on the wake() method.

6 years agoMINOR: h2: Let user of h2_recv() and h2_send() know xfer has been done.
Olivier Houchard [Fri, 17 Aug 2018 16:39:46 +0000 (18:39 +0200)] 
MINOR: h2: Let user of h2_recv() and h2_send() know xfer has been done.

Make h2_recv() and h2_send() return 1 if data has been sent/received, or 0
if it did not. That way the caller will be able to know if more work may
have to be done.

6 years agoMEDIUM: connections: Get rid of the recv() method.
Olivier Houchard [Thu, 9 Aug 2018 11:06:55 +0000 (13:06 +0200)] 
MEDIUM: connections: Get rid of the recv() method.

Remove the recv() method from mux and conn_stream.
The goal is to always receive from the upper layers, instead of waiting
for the connection later. For now, recv() is still called from the wake()
method, but that should change soon.

6 years agoMEDIUM: connections/mux: Add a recv and a send+recv wait list.
Olivier Houchard [Thu, 2 Aug 2018 17:23:05 +0000 (19:23 +0200)] 
MEDIUM: connections/mux: Add a recv and a send+recv wait list.

For struct connection, struct conn_stream, and for the h2 mux, add 2 new
lists, one that handles waiters for recv, and one that handles waiters for
recv and send. That way we can ask to subscribe for either recv or send.

6 years agoMEDIUM: connections: Don't reset the polling flags in conn_fd_handler().
Olivier Houchard [Wed, 12 Sep 2018 15:12:53 +0000 (17:12 +0200)] 
MEDIUM: connections: Don't reset the polling flags in conn_fd_handler().

Resetting the polling flags at the end of conn_fd_handler() shouldn't be
needed anymore, and it will create problem when we won't handle send/recv
from conn_fd_handler() anymore.

6 years agoBUG/MEDIUM: tasks: Don't forget to decrement task_list_size in tasklet_free().
Olivier Houchard [Wed, 12 Sep 2018 12:55:03 +0000 (14:55 +0200)] 
BUG/MEDIUM: tasks: Don't forget to decrement task_list_size in tasklet_free().

In tasklet_free(), if we're currently in the runnable task list, don't
forget to decrement taks_list_size, or it'll end up being to big, and we may
not process tasks in the global runqueue.