Commit Graph

10109 Commits

Author SHA1 Message Date
William Lallemand
4d03e431b3 DOC: add some environment variables in section 2.3
Add the missing environment variable in the 2.3 section.
2019-06-14 15:38:05 +02:00
Olivier Houchard
fe4abe62c7 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.
2019-06-14 15:33:41 +02:00
Willy Tarreau
86eded6c69 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.
2019-06-14 14:57:03 +02:00
Willy Tarreau
3c39a7d889 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.
2019-06-14 14:42:29 +02:00
Baptiste Assmann
95c2c01ced 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.
2019-06-14 14:18:55 +02:00
Christopher Faulet
3b44c54129 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.
2019-06-14 11:13:32 +02:00
Christopher Faulet
42993a86c9 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.
2019-06-14 11:13:32 +02:00
Christopher Faulet
a9a5c04c23 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".
2019-06-14 11:13:32 +02:00
Christopher Faulet
e21c01637a 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.
2019-06-14 11:13:32 +02:00
Christopher Faulet
d20fdb0454 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.
2019-06-14 11:13:32 +02:00
Christopher Faulet
36a7702b03 CLEANUP: channel: Remove channel_htx_fwd_payload() and channel_htx_fwd_all()
These functions are unused now. No backport needed.
2019-06-14 11:13:32 +02:00
Christopher Faulet
421e769783 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.
2019-06-14 11:13:32 +02:00
Christopher Faulet
8c65486081 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>.
2019-06-14 11:13:32 +02:00
Christopher Faulet
e4ab11bb88 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.
2019-06-14 11:13:32 +02:00
Christopher Faulet
87ebe944d6 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.
2019-06-14 11:13:32 +02:00
Christopher Faulet
647fe1d9e1 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.
2019-06-14 11:13:32 +02:00
Willy Tarreau
3cec0f94f3 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.
2019-06-14 09:16:51 +02:00
Olivier Houchard
985234d0cb 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.
2019-06-13 19:14:45 +02:00
Olivier Houchard
6063003c96 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.
2019-06-13 19:14:45 +02:00
Ben51Degrees
f4a82fb26b 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.
2019-06-13 18:00:54 +02:00
William Lallemand
63329e36ab 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.
2019-06-13 17:09:27 +02:00
Ilya Shipitsin
b41adedaf7 BUILD: travis-ci: add 51Degree device detection, update openssl to 1.1.1c 2019-06-13 17:02:23 +02:00
Willy Tarreau
5e4c5003c5 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.
2019-06-13 15:56:10 +02:00
Tim Duesterhus
dda1155ed7 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);
>    ^
2019-06-13 15:47:41 +02:00
William Lallemand
c5473e507e 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.
2019-06-13 15:39:48 +02:00
William Lallemand
95635ddac8 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.
2019-06-13 15:32:39 +02:00
Kazuo Yagi
971c3943be MINOR: doc: Remove -Ds option in man page
Remove -Ds option in man page.

Should be backported in every version since 1.8.
2019-06-13 11:22:08 +02:00
William Lallemand
1dc6963086 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.
2019-06-12 19:19:57 +02:00
William Lallemand
e8669fc9db 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.
2019-06-12 19:19:57 +02:00
Ben51Degrees
31c3d51a18 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.
2019-06-12 18:06:59 +02:00
Ben51Degrees
31a51f25d6 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.
2019-06-12 18:06:59 +02:00
Willy Tarreau
3381022d88 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.
2019-06-12 18:06:59 +02:00
William Lallemand
c9515529a0 DOC: mworker-prog: documentation for the program section
This patch documents the program feature.
2019-06-12 18:06:59 +02:00
Olivier Houchard
a0fdce3950 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.
2019-06-12 14:36:24 +02:00
Willy Tarreau
ca3551f005 [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
2019-06-11 19:28:00 +02:00
Daniel Corbett
c802921721 DOC/MINOR: contrib/spoa_server: Fix typo in README
Fix typo in README ps_pyhton.py -> ps_python.py
2019-06-11 19:27:42 +02:00
Daniel Corbett
061766859c 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.
2019-06-11 19:27:42 +02:00
Daniel Corbett
4e0fa55dcd 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.
2019-06-11 19:27:41 +02:00
Daniel Corbett
5897867ac5 MINOR: contrib/spoa_server: Upgrade SPOP to 2.0
Upgrade SPOP version to 2.0
2019-06-11 19:27:41 +02:00
Olivier Houchard
690e0f07f5 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.
2019-06-11 16:41:36 +02:00
Olivier Houchard
92d093d641 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.
2019-06-11 16:41:24 +02:00
Willy Tarreau
b5ba2b0177 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.
2019-06-11 16:37:13 +02:00
Willy Tarreau
5abdc760c9 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.
2019-06-11 16:37:13 +02:00
Olivier Houchard
45c4437b4a Revert "BUG/MEDIUM: H1: When upgrading, make sure we don't free the buffer too early."
This reverts commit 6c7fe5c370.

This patch was harmless, but not needed, conn_upgrade_mux_fe() already takes
care of setting the buffer to BUF_NULL.
2019-06-11 14:07:53 +02:00
Christopher Faulet
86fcf6d6cd 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.
2019-06-11 14:05:25 +02:00
Christopher Faulet
d7884d3449 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.
2019-06-11 14:05:25 +02:00
Christopher Faulet
50fe9fba4b 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.
2019-06-11 14:05:25 +02:00
Christopher Faulet
86bc8df955 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.
2019-06-11 14:05:25 +02:00
Christopher Faulet
bda8397fba 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.
2019-06-11 14:05:25 +02:00
Willy Tarreau
34a150ccf5 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
2019-06-11 11:30:26 +02:00