Commit Graph

8903 Commits

Author SHA1 Message Date
Olivier Houchard
ffda58b546 BUG/MEDIUM: h2: Don't destroy the h2s if it still has a cs attached.
In h2_deferred_shut, if we're done sending the shutr/shutw, don't destroy
the h2s if it still has a conn_stream attached, or the conn_stream may try
to access it again.
2018-12-16 08:22:01 +01:00
Willy Tarreau
bce4d8a37d MINOR: debug: make the ABORT_NOW macro use a volatile int
Similar to previous commit, let's make the macro use a volatile when
dereferencing NULL so that clang doesn't optimize it away.
2018-12-16 08:17:23 +01:00
Olivier Houchard
51e474136b MINOR: pools: Cast to volatile int * instead of int *.
When using DEBUG_MEMORY_POOLS, when we want to crash, instead of using
*(int *)0 = 0, use *(volatile int *)0 = 0, or clang will just translate it
to a nop, instead of dereferencing 0.
2018-12-16 08:15:16 +01:00
Willy Tarreau
efef323783 BUG/MINOR: cache: also consider CF_SHUTR to abort delivery
The cache runs in an applet, so it delivers data into the input side
of the channel's buffer. Thus it must also abort feeding the buffer
as soon as CF_SHUTR is present, not just CF_SHUTW*, since these last
ones may only appear later. There doesn't seem to be an observable
side effect of this bug, the fix probably doesn't even need to be
backported.
2018-12-16 00:40:31 +01:00
Willy Tarreau
273e964f6e BUG/MEDIUM: htx/cache: use the correct class of error codes on abort
The HTX-specific cache code uses HTX_CACHE_* states which overlap with
the legacy HTTP states. A typo in the error handling made the state
become HTTP_CACHE_END, which equals 3 and is the value for HTX_CACHE_EOD,
which explains why we were seeing a transition to trailers and memory
corruption.

no backport needed.
2018-12-16 00:40:30 +01:00
Olivier Houchard
746fb772f1 MEDIUM: mux_h2: Always set CS_FL_NOT_FIRST for new conn_streams.
When creating new conn_streams, always set the CS_FL_NOT_FIRST flag. We
don't really care about being the first request for HTTP/2, this only
really makes sense for HTTP/1, and that way we can reuse connections.
2018-12-15 23:50:11 +01:00
Olivier Houchard
7aec9ed2f8 MEDIUM: servers: Be more agressive when adding H2 connection to idle lists.
Add the newly created to the idle list as long as http-reuse != never, and
when completing a H2 request, add the connection to the safe list instead of
the idle list, if we have to add it at that point, that means we created
many streams so we know it's safe.
2018-12-15 23:50:10 +01:00
Olivier Houchard
a4d4fdfaa3 MEDIUM: sessions: Don't keep an infinite number of idling connections.
In session, don't keep an infinite number of connection that can idle.
Add a new frontend parameter, "max-session-srv-conns" to set a max number,
with a default value of 5.
2018-12-15 23:50:10 +01:00
Olivier Houchard
f502aca5c2 MEDIUM: mux: provide the session to the init() and attach() method.
Instead of trying to get the session from the connection, which is not
always there, and of course there could be multiple sessions per connection,
provide it with the init() and attach() methods, so that we know the
session for each outgoing stream.
2018-12-15 23:50:09 +01:00
Olivier Houchard
8a78690229 MEDIUM: mux: Destroy the stream before trying to add the conn to the idle list.
In the mux_h1 and mux_h2, move the test to see if we should add the
connection in the idle list until after we destroyed the h1s/h2s, that way
later we'll be able to check if the connection has no stream at all, and if
it should be added to the server idling list.
2018-12-15 23:50:09 +01:00
Olivier Houchard
b7b3faa79c MEDIUM: servers: Replace idle-timeout with pool-purge-delay.
Instead of the old "idle-timeout" mechanism, add a new option,
"pool-purge-delay", that sets the delay before purging idle connections.
Each time the delay happens, we destroy half of the idle connections.
2018-12-15 23:50:09 +01:00
Olivier Houchard
006e3101f9 MEDIUM: servers: Add a command to limit the number of idling connections.
Add a new command, "pool-max-conn" that sets the maximum number of connections
waiting in the orphan idling connections list (as activated with idle-timeout).
Using "-1" means unlimited. Using pools is now dependant on this.
2018-12-15 23:50:08 +01:00
Olivier Houchard
86006a561e MEDIUM: proxy: Set http-reuse safe as default.
Change the default for http-reuse from "never" to "safe", as it has been
the recommended setting for a few versions now and backend H2 makes little
sense without it.

Some warnings were removed from the config parser since it can dynamically
be disabled depending on the server's configuration, so there's no need to
disable it on a whole backend just for one server.
2018-12-15 23:50:08 +01:00
Olivier Houchard
2c68a462e1 BUG/MEDIUM: h2: Don't forget to destroy the h2s after deferred shut.
If we had to defer shutr/shutw, and we're now done, destroy the h2s, or
nobody will do so.
2018-12-15 23:50:07 +01:00
Christopher Faulet
27d93c3f94 BUG/MAJOR: compression/cache: Make it really works with these both filters
Caching the response with the compression enabled was totally broken. To fix the
problem, the compression must be done after caching the response. Otherwise it
needs to change the cache to store compressed and uncompressed objects for the
same ressource. So, because it is not possible for now, it is forbidden to
declare the compression filter before the cache one. To ease the configuration,
both can be implicitly declared (without "filter" keyword). The compression will
automatically be inserted after the cache.

Then, to make it works this way, the compression filter has been slighly
modified. Now, the response headers are updated after http-response rules
evaluations, instead of before. So, if the response contains a "Content-length"
header, it will be kept with the response stored in the cache. So this cached
response will be able to be served to clients not supporting the compression at
all.
2018-12-15 23:50:07 +01:00
William Lallemand
808e1b7c40 BUG/MEDIUM: threads: don't close the thread waker pipe if not init
This bugfix concerns the thread deinit but affects the master process.

When the master process falls in wait mode (it fails to reload the
configuration), it launches the deinit_pollers_per_thread and close the
thread waker pipe. It closes rd (-1) and wr (0).

Closing a FD in the master can have several sides effects and the
process will probably quit at some point.

In this case it assigns 0 to the socketpair of a worker during the next
correct reload, and then closes the socketpair once it falls in wait
mode again. The worker assumes that the master died and leaves.
2018-12-15 23:33:32 +01:00
Willy Tarreau
a648399c90 BUG/MINOR: logs: leave startup-logs global and not per-thread
Commit f8188c6 ("MEDIUM: threads/logs: Make logs thread-safe") made logs
thread-local but it also made the copy of the startup-logs thread-local,
meaning that when threads are configured, upon startup the list of startup
logs appears to be empty. Let's just remove the THEAD_LOCAL directive
there, as the check for the startup period is already present.

This fix should be backported to 1.8.
2018-12-15 16:55:36 +01:00
Willy Tarreau
8459f25e03 BUILD: thread: properly report multi-thread support
When refactoring the build option strings in 1.9, the thread support
was placed outside of the ifdef block resulting in threads always being
mentioned even if that was not true. Let's fix this and also mention
when threads are disabled to help troubleshooting.
2018-12-15 16:48:14 +01:00
Rosen Penev
6818595b57 BUILD: ssl: Fix compilation without deprecated OpenSSL 1.1 APIs
Removing deprecated APIs is an optional part of OpenWrt's build system to
save some space on embedded devices.

Also added compatibility for LibreSSL.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2018-12-15 16:34:38 +01:00
Frédéric Lécaille
c11ec4a6d5 REGTEST: Add a reg test for HTTP cookies.
This script tests the "cookie <name> insert indirect" directive with
header checks on server and client side. syslog messages are also
checked, especially --II (invalid, insert) flags logging.

Signed-off-by: Frdric Lcaille <flecaille@haproxy.com>
2018-12-15 16:18:14 +01:00
Willy Tarreau
204e3f1fab BUG/MINOR: log: fix logging to both FD and IP
PiBa-NL reported an issue affecting logs when stdout is enabled at the
same time as an IP address. It does not affect FD and UNIX, but does
still affect multiple FDs. What happens is that the condition to detect
that the initialization was not made relies on the FD being -1, and in
this case the FD points to the *unique* FD used for AF_INET sockets, so
the configured socket used for outgoing logs over UDP gets overwritten
by the last configured FD. This is not appropriate, so instead we rely
on the sin_port part of the IPv4-mapped address to store the
initialization state for each FD.

This part deserves being significantly revamped, as IPv6 is still not
possible due to the way the FDs are managed, and inherited FDs are a
bit hackish.

Note that this patch relies on "MINOR: tools: preset the port of
fd-based "sockets" to zero" in order to operate properly.

No backport is needed.
2018-12-15 15:54:13 +01:00
Willy Tarreau
0205a4e0b5 MINOR: tools: preset the port of fd-based "sockets" to zero
Addresses made of a file descriptor store the file descriptor into the
address part of a sin_addr. Contrary to other address classes, there's
no way to figure later based on the FD if an initialization was done
(which is how logs initialize their FDs). The port part is currently
left with random data, so let's instead specifically set the port part
to zero when creating an FD, and let the code using it set whatever
info it needs there, typically an initialization state.
2018-12-15 15:40:12 +01:00
Willy Tarreau
cc79ed28f6 BUG/MAJOR: backend: only update server's counters when the server exists
PiBa-NL reported that since this commit f157384 ("MINOR: backend: count
the number of connect and reuse per server and per backend"), reg-test
connection/h00001 fails. Indeed it does, the server is not checked for
existing prior to updating its counter. It should also fail with
transparent mode.
2018-12-15 15:13:10 +01:00
Willy Tarreau
37dd54d8d4 BUG/MEDIUM: mux-h1: make sure we always have at least one HTX block to send
Commit 84cca66 ("BUG/MEDIUM: htx: When performing zero-copy, start from
the right offset.") uncovered another issue which is that the send function
may occasionally be called without any block. It's important to check for
this case when computing the zero-copy offsets.

No backport is needed.
2018-12-15 14:48:31 +01:00
Olivier Houchard
f90db445cd BUG/MEDIUM: log: Don't call sample_fetch_as_type if we don't have a stream.
In sess_build_logline(), don't attempt to call sample_fetch_as_type()
if we don't have a stream.

It used never to happen in the past before commit 09bb27c ("MEDIUM: log:
make sess_build_logline() support being called with no stream"). But now
it can happen when sess_log() is called from the lower layers (i.e. the
H2 mux got garbage when it was expecting a preface frame), and it reveals
that some sample fetch functions and some converter fnuctions which rely
on the stream don't test for its existence. For the sample fetch functions,
a durable solution is easy and would consist in adapting sample_process()
to verify the SMP_USE_* bits when the stream is not set. But for the
converters we don't have this option as they don't declare whether or not
they use a stream (which possibly is the real issue).

Thus for now let's disable sample_fetch_as_type() if a stream does not
exist, until it can be more accurately refined later.
2018-12-15 14:34:31 +01:00
William Lallemand
a57b7e33ef MINOR: cli: implements 'reload' on master CLI
The reload command reload the haproxy master like it is done with a kill
-USR2 on the master process.
2018-12-15 13:33:49 +01:00
Willy Tarreau
52880f97b9 MINOR: mworker/cli: indicate in the master prompt when a reload failed
If a reload was issued to the master process and failed, it is critical
that the admin sees it because it means that the saved configuration
does not work anymore and might not be usable after a full restart. For
this reason in this case we modify the "master" prompt to explicitly
indicate that a reload failed.
2018-12-15 13:30:03 +01:00
William Lallemand
6e0d8aee26 BUG/MINOR: mworker: don't use unitialized mworker_proc struct
If the reload fail after the parsing of the configuration, the
mworker_proc structures are created for the processes it tried to
create.

The mworker_proc_list_to_env() function was exporting these unitialized
structures in the "HAPROXY_PROCESSES" environment variable which was
leading to this kind of output in "show proc":

4294967295      worker          [was: 1]        1               17879d 16h26m28s
2018-12-14 19:41:38 +01:00
Olivier Houchard
84cca66ea3 BUG/MEDIUM: htx: When performing zero-copy, start from the right offset.
When using zerocopy, start from the beginning of the data, not from the
beginning of the buffer, it may have contained headers, and so the data
won't start at the beginning of the buffer.
2018-12-14 17:02:11 +01:00
Christopher Faulet
2a454d8c7c MINOR: lua: Remove useless check on the messages state in HTTP functions
The headers parsing is always finished when LUA scripts are evaluated.
2018-12-14 16:04:07 +01:00
Christopher Faulet
9c832fcfb7 MAJOR: lua/htx: Adapt HTTP applets to support HTX messages
This patch is a bit huge but nothing special here. Some functions have been
duplicated to support the HTX, some others have a switch inside to do so. So,
now, it is possible to create HTTP applets from HTX proxies. However, TCP
applets remains unsupported.
2018-12-14 16:04:05 +01:00
Christopher Faulet
a3ceac17e4 MINOR: lua/htx: Adapt the functions get_in_length and is_full to be HTX aware 2018-12-14 16:04:03 +01:00
Christopher Faulet
724a12cc65 MEDIUM: lua/htx: Adapt functions of the HTTP to be compatible with HTX
So, LUA actions, converter and sample fetches are now available from HTX
proxies.
2018-12-14 16:04:02 +01:00
Christopher Faulet
3f829a4b74 MAJOR: lua: Forbid calls to Channel functions for LUA scripts in HTTP proxies
Functions from then Channel class are now forbidden for LUA scripts called from
HTTP proxies. These functions totally hijacked the HTTP parser, leaving it in an
undefined state. This patch is tagged as MAJOR because it could be see as a
compatibility breakage. But a LUA script using one of these functions has a very
low probablity to work correctly except by chance.

So, concretely, following functions are concerned: Channel.get, Channel.dup,
Channel.getline, Channel.set, Channel.append, Channel.send,
Channel.forward. Others remain available.
2018-12-14 16:04:00 +01:00
Christopher Faulet
c16317d1ca MINOR: http_fecth: Implement body_len and body_size sample fetches for the HTX
HTX implementation for these 2 sample fetches was missing. This patch fills this
gap.
2018-12-14 16:03:39 +01:00
Christopher Faulet
f0216dae0c MINOR: payload/htx: Adapt smp_fetch_len to be HTX aware 2018-12-14 16:03:34 +01:00
Christopher Faulet
a361837903 BUG/MINOR: stats: Parse post data for HTX streams
This part was just left out for no reason when the stats applet was adapted to
support the HTX messages.
2018-12-14 16:03:31 +01:00
Christopher Faulet
87a2c0d3f4 BUG/MINOR: proto_htx: Fix htx_res_set_status to also set the reason
Becaue the check on the return value of the function http_replace_res_status was
done upside down, no reason was never set.
2018-12-14 16:03:29 +01:00
William Lallemand
2672eb987a MINOR: mworker: set all_threads_mask and pid_bit to 1
Reinit the all_threads_mask and pid_bit to 1 before the master polling
loop, this process is monothread.
2018-12-14 16:01:37 +01:00
Willy Tarreau
1ee55fddea MEDIUM: tasks: check the global task mask instead of the thread number
When deciding whether to scan the global run queue or not, we currently
check the configured threads number, and if it's 1 we skip the queue
since it's not supposed to be used. However when running with a master
process and multiple threads in the workers, the master will turn this
number back to 1 while some task wakeups might possibly have set bits
in the global tasks mask, thus causing active_tasks_mask to have one
bit permanently set, preventing the process from sleeping.

Instead of checking global.nbthread, let's check for the current
thread's bit in global_tasks_mask. First it will make this part of the
code more consistent, working like a test and set operation, it will
solve the issue with master+nbthread and as a bonus it will save a
lock/unlock for each scheduler call when the thread doesn't have a
task in the global run queue.
2018-12-14 15:49:45 +01:00
Willy Tarreau
a1214a501f MINOR: cache: report the number of cache lookups and cache hits
The cache lookups and hits is now accounted per frontend and per backend,
and reported on the stats page.
2018-12-14 14:00:25 +01:00
Willy Tarreau
59caa3b872 MINOR: tools: increase the number of ITOA strings to 16
It's currently 10 and is too little to extend some tooltips on the stats page.
2018-12-14 13:59:42 +01:00
Willy Tarreau
feead3aff7 BUG/MINOR: stats: fix inversion of failed header rewrites and other statuses
The tooltip in the HTML stats page was damaged by commit 1b0f85e47 ("MINOR:
stats: also report the failed header rewrites warnings on the stats page"),
due to the header rewrites counter being inserted at the wrong place and
taking the place of the other statuses.

This is only for 1.9, no backport is needed.
2018-12-14 13:48:44 +01:00
Willy Tarreau
f157384803 MINOR: backend: count the number of connect and reuse per server and per backend
Sadly we didn't have the cumulated number of connections established to
servers till now, so let's now update it per backend and per-server and
report it in the stats. On the stats page it appears in the tooltip
when hovering over the total sessions count field.
2018-12-14 11:35:36 +01:00
Willy Tarreau
c0960d1185 MINOR: mux_h1/h2: simplify the zero-copy Rx alignment
The transpory layer now respects buffer alignment, so we don't need to
cheat anymore pretending we have some data at the head, adjusting the
buffer's head is enough.
2018-12-14 10:59:15 +01:00
Willy Tarreau
e0f24ee149 MINOR: connection: realign empty buffers in muxes, not transport layers
For a long time we've been realigning empty buffers in the transport
layers, where the I/Os were performed based on callbacks. Doing so is
optimal for higher data throughput but makes it trickier to optimize
unaligned data, where mux_h1/h2 have to claim some data are present
in the buffer to force unaligned accesses to skip the frame's header
or the chunk header.

We don't need to do this anymore since the I/O calls are now always
performed from top to bottom, so it's only the mux's responsibility
to realign an empty buffer if it wants to.

In practice it doesn't change anything, it's just a convention, and
it will allow the code to be simplified in a next patch.
2018-12-14 10:51:23 +01:00
Willy Tarreau
a73da1ed25 BUG/MEDIUM: cache: fix random crash on filter parser's error path
The cconf variable was not initialized before the two first possible
error exits before being freed, resulting in random crashes instead
of displaying an error message if the cache ID was missing from the
filter declaration.

No backport is needed, this is exclusively 1.9.
2018-12-14 10:19:28 +01:00
Willy Tarreau
4a7b5b3fdb REGTEST: http-messaging: add "option http-buffer-request" for H2 tests
These tests upload contents and randomly make the server start to
respond before the client finishes to upload data, making the test
occasionally fail. Waiting for a body in the server doesn't always
work, depending on the method or how the data are advertised. Thus,
let's ask haproxy to wait for the request using the aforementioned
option, it guarantees that the DATA frame is sent before the response
HEADERS frame is delivered.
2018-12-14 09:51:48 +01:00
Willy Tarreau
f3ec86ad89 REGTEST: fix missing space in checks/s00001
I accidently dropped one space when fixing this 3k-long line in the
VTC script, causing the test to fail.
2018-12-14 09:50:38 +01:00
Willy Tarreau
1eb6c55808 MINOR: lb: make the leastconn algorithm more accurate
The leastconn algorithm queues available servers based on their weighted
current load. But this results in an inaccurate load balancing when weights
differ and the load is very low, because what matters is not the load before
picking the server but the load resulting from picking the server. At the
very least, it must be granted that servers with the highest weight are
always picked first when no server has any connection.

This patch addresses this by simply adding one to the current connections
count when queuing the server, since this is the load the server will have
once picked. This finally allows to bridge the gap that existed between
the "leastconn" and the "first" algorithms.
2018-12-14 08:33:28 +01:00