Commit Graph

6804 Commits

Author SHA1 Message Date
Christopher Faulet
7ff4f14204 BUG/MINOR: config: Be aware of the HTX during the check of mux protocols
Because the HTX is still experimental, we must add special cases during the
configuration check to be sure it is not enabled on a proxy with incompatible
options. Here, for HTX proxies, when a mux protocol is specified on a bind line
or a server line, we must force the HTX mode (PROTO_MODE_HTX).

Concretely, H2 is the only mux protocol that can be forced. And it doesn't yet
support the HTX. So forcing the H2 on an HTX proxy will always fail.
2018-11-20 14:31:44 +01:00
Christopher Faulet
55dec0dca4 MINOR: stream-int: remove useless checks on CS and conn flags in si_cs_send()
In si_cs_send(), some checks are done the CS flags en the connection flags
before calling snd_buf(). But these checks are useless because they have already
been done earlier in the function. The harder to figure out is the flag
CO_FL_SOCK_WR_SH. So it is now tested with CF_SHUTW at the beginning.
2018-11-20 14:31:44 +01:00
Christopher Faulet
3f76f4ccf7 BUG/MINOR: stream-int: Don't call snd_buf() if there are still data in the pipe
In si_cs_send, as said in comments, snd_buf() should only be called if there is
no data in the pipe anymore. But actually, this condition was not respected.
2018-11-20 14:31:44 +01:00
Christopher Faulet
e4acd5e471 MINOR: stream-int: Notify caller when an error is reported after a rcv_buf()
For the same reason than for the commit b46784b1c ("MINOR: stream-int: Notify
caller when an error is reported after a rcv_pipe()"), we return 1 after the
call to rcv_buf() in si_cs_send() to notify the caller some processing may be
triggered.

This patch is not flagged as a bug because no strange behaviour was yet observed
without it. It is just a proactive fix to be consistent.
2018-11-20 14:31:44 +01:00
Christopher Faulet
5ed7aab68a MINOR: stream-int: Notify caller when an error is reported after a rcv_pipe()
In si_cs_send(), when an error is found on the CS or the connection at the
beginning of the function, we return 1 to notify the caller some processing may
be triggered. So, it seems logical to do the same after the call to rcv_pipe().

This patch is not flagged as a bug because no strange behaviour was yet observed
without it. It is just a proactive fix to be consistent.
2018-11-20 14:31:44 +01:00
Christopher Faulet
b42a8b6c61 BUG/MINOR: proto_htx: Fix request/response synchronisation on error
The HTTP transaction must be aborted if an error is detected on any one
side.
2018-11-20 14:31:44 +01:00
Christopher Faulet
9b95d31122 BUG/MINOR: stats/htx: Remove channel's output when the request is eaten
The request is eaten when the stats applet have finished to send its
response. It was removed from the channel's buffer, removing all HTX blocks till
the EOM. But the channel's output was not reset, leaving the request channel in
an undefined state.
2018-11-20 14:31:44 +01:00
Christopher Faulet
9c38840055 BUG/MEDIUM: mux-h1: Don't set the flag CS_FL_RCV_MORE when nothing was parsed
When we start to parse a new message, if all headers have not been received,
nothing is copied in the channel's buffer. In this situation, we must not set
the flag CS_FL_RCV_MORE on the conn-stream. If we do so, the connection freezes
because there is no data to send that can reenable the reads
2018-11-20 14:31:44 +01:00
Christopher Faulet
d44ad5b8bd BUG/MEDIUM: mux-h1: Fix freeze when the kernel splicing is used
First of all, we need to be sure to keep the flag H1S_F_BUF_FLUSH on the H1S
reading data until all data was flushed from the buffer. Then we need to know
when the kernel splicing is in use and when it ends. This is handled with the
new flag H1S_F_SPLICED_DATA.

Then, we must subscribe to send when some data remain in the pipe after a
snd_pipe(). It is mandatory to wakeup the stream and avoid a freeze.

Finally, we must be sure to update the message state when we restart to use the
channel's buffer. Among other things, it is mandatory to swith the message from
DATA to DONE state when all data were sent using the kernel splicing.
2018-11-20 14:31:44 +01:00
Christopher Faulet
81d484326b BUG/MINOR: mux-h1: Enable keep-alive on server side
Don't force the close on server side anymore. Since commit 7c6f8b146 ("MAJOR:
connections: Detach connections from streams"), it is possible to release a
stream without the underlying connection.

Because of this change, we must be sure to create a new stream to handle the
next HTTP transaction only on the client side. And we must be sure to correctly
handle the read0 event in h1_recv, to be sure to call h1_process().
2018-11-20 14:31:44 +01:00
Christopher Faulet
539e029cc5 MAJOR: mux-h1: Remove the rxbuf and decode HTTP messages in channel's buffer
It avoids a copy between the rxbuf and the channel's buffer. It means the
parsing is done in h1_rcv_buf(). So we need to have a stream to start the
parsing. This change should improve the overall performances. It also implies a
better split between the connection layer and the applicative layer. Now, on the
connection layer, only raw data are manipulated. Raw data received from the
socket are stored in ibuf and those sent are get from obuf. On the applicative
layer, data in ibuf are parsed and copied into the channel's buffer. And on the
other side, those structured data are formatted and copied into obuf.
2018-11-20 14:31:44 +01:00
Willy Tarreau
4bf194cbdb BUG/MEDIUM: hpack: fix encoding of "accept-ranges" field
James Brown reported that when an "accept-ranges" header field is sent
through haproxy and converted from HTTP/1.1 to H2, it's mis-encoded as
"accept-language". It happens that it's one of the few very common header
fields encoded using its index value and that this index value was misread
in the spec as 17 instead of 18, resulting in the wrong name being sent.
Thanks to Lukas for spotting the issue in the HPACK encoder itself.

This fix must be backported to 1.8.
2018-11-20 04:47:38 +01:00
William Lallemand
16dd1b3ead MINOR: cli: show master information in 'show proc'
Displays the master information in show proc.
2018-11-20 04:43:54 +01:00
William Lallemand
e368330128 MINOR: cli: displays uptime in show proc
Displays the uptime of the workers in `show proc`
2018-11-20 04:43:54 +01:00
William Lallemand
e09cdc6d48 MINOR: cli: format show proc to be more readable
Add more space on the output to be more readable and separate old
processes from current ones.
2018-11-20 04:43:54 +01:00
Willy Tarreau
3a1f5fda10 REORG: config: extract the proxy parser into cfgparse-listen.c
This was the largest function of the whole file, taking a rough second
to build alone. Let's move it to a distinct file along with a few
dependencies. Doing so saved about 2 seconds on the total build time.
2018-11-19 06:47:09 +01:00
Willy Tarreau
36b9e222bb REORG: config: extract the global section parser into cfgparse-global
The config parser is the largest file to build and its build dominates
the total project's build time. Let's start to split it into multiple
smaller pieces by extracting the "global" section parser into a new
file called "cfgparse-global.c". This removes 1/4th of the file's build
time.
2018-11-19 06:41:57 +01:00
Joseph Herlant
f1da69d9ea MINOR: Fix a typo in a warning message in the spoe subsystem
Fix a typo in a user-facing message of the spoe subsystem.
2018-11-18 22:29:19 +01:00
Joseph Herlant
7fe1577cc7 MINOR: Fix typo in the error 500 output of hlua
Fixes a common typo in the output generated by the hlua subsystem when
emitting an error 500 page.
2018-11-18 22:28:09 +01:00
Joseph Herlant
b8f9c5e634 CLEANUP: fix typos in the comments of hlua
Fix typos in the code comments of the hlua subsystem.
2018-11-18 22:28:09 +01:00
Joseph Herlant
76dbe785b5 MINOR: Fix typo in error message in the standard subsystem
Fix a typo in an error message that could be user-visible when running
out of memory in the parse_binary function.
2018-11-18 22:26:42 +01:00
Joseph Herlant
cf92b6d332 CLEANUP: Fix typos in the task subsystem
Fix typos in the code comments of the task subsystem.
2018-11-18 22:26:42 +01:00
Joseph Herlant
5662fa4707 CLEANUP: Fix typos in the stick_table subsystem
Fix some typos in the code comments of the stick_table subsystem.
2018-11-18 22:26:42 +01:00
Joseph Herlant
32b8327266 CLEANUP: Fix typos in the standard subsystem
Fix typos in the code comments of the standard subsystem.
2018-11-18 22:26:42 +01:00
Joseph Herlant
f7f6031184 CLEANUP: Fix typos in the spoe subsystem
Fix typos in the code comments of the spoe subsystem.
2018-11-18 22:26:42 +01:00
Joseph Herlant
757f5ad73a CLEANUP: Fix typos in the sample subsystem
Fix some typos in the code comment of the sample subsystem.
2018-11-18 22:26:42 +01:00
Joseph Herlant
eda75484a8 CLEANUP: Fix typos in the regex subsystem
Fix typos in the code comment of the regex subsystem.
2018-11-18 22:26:42 +01:00
Joseph Herlant
82b2f54d4c CLEANUP: Fix typos in the peers subsystem
Fix some typos in the code comments of the peers subsystem.
2018-11-18 22:26:42 +01:00
Joseph Herlant
85b4059b82 CLEANUP: Fix typos in the log subsystem
Fix some misspells in the code comments of the log subsystem.
2018-11-18 22:26:42 +01:00
Joseph Herlant
942eea3f5c CLEANUP: Fix typos in the http subsystem
Fix typos in code comment of the http subsystem.
2018-11-18 22:26:42 +01:00
Joseph Herlant
b35ea68081 CLEANUP: Fix typos in the filters subsystem
Fix typos in the code comments of the filters subsystems.
2018-11-18 22:26:42 +01:00
Joseph Herlant
a14c03ef43 CLEANUP: Fix typos in the cfgparse subsystem
Fix typos in the code comments of the cfgpase subsystem.
2018-11-18 22:26:42 +01:00
Joseph Herlant
8dae5b38b8 CLEANUP: Fix typos in the cache subsystem
Fix common misspells in the code comments of the cache subsystem.
2018-11-18 22:26:42 +01:00
Joseph Herlant
6808279b2a CLEANUP: Fix typos in the acl subsystem
Fix typos in the code comments of the acl subsystem.
2018-11-18 22:26:26 +01:00
Joseph Herlant
29023ec5d9 CLEANUP: Fix a typo in the stats subsystem
Fix a typo in a code comment of the stats subsystem.
2018-11-18 22:26:26 +01:00
Joseph Herlant
9edebb8568 MINOR: Fix typos in error messages in the proxy subsystem
Fix typos in error messages that will be user-visible in the proxy
subsystem.
2018-11-18 22:23:15 +01:00
Joseph Herlant
07a0834635 MINOR: Fix an error message thrown when we run out of memory
Fixes a typo in an error message that can be seen by the end user when
the haproxy subsystem runs out of memory.
2018-11-18 22:23:15 +01:00
Joseph Herlant
017b3da94e CLEANUP: fix typos in the ssl_sock subsystem
Fix some typos found in the code comments of the ssl_sock subsystem.
2018-11-18 22:23:15 +01:00
Joseph Herlant
59dd295926 CLEANUP: fix typos in the proxy subsystem
Fix typos in the code comments of the proxy subsystem.
2018-11-18 22:23:15 +01:00
Joseph Herlant
5ba8025976 CLEANUP: fix typos in the proto_http subsystem
Fixes typos in the code comments of the proto_http subsystem.
2018-11-18 22:23:15 +01:00
Joseph Herlant
b3d92e3b9f CLEANUP: fix typos in the hlua_fcn subsystem
Fixes typos detected in the code comments of the hlua_fcn subsystem using
the misspell tool and other ones detected manually.
2018-11-18 22:23:15 +01:00
Joseph Herlant
0767689e93 CLEANUP: fix typos in the comments of the vars subsystem
Those are mostly misspells of the words available and variable.
2018-11-18 22:23:15 +01:00
Joseph Herlant
4cc8d0d60c CLEANUP: fix a typo found in the stream subsystem
This typo is in a code comment so not end-user visible.
2018-11-18 22:23:15 +01:00
Joseph Herlant
44466826b1 CLEANUP: fix a few typos in the comments of the server subsystem
A few misspells where detected in the server subsystem. This commit
fixes them.
2018-11-18 22:23:15 +01:00
Joseph Herlant
b2db6a00f9 CLEANUP: fix 2 typos in the xxhash subsystem
Fixes 2 typos in the comments of the xxhash subsystem.
2018-11-18 22:23:15 +01:00
Joseph Herlant
4189d671b7 CLEANUP: Fix typos in the pattern subsystem
Fixes typos in the code comments of the pattern subsystem.
2018-11-18 22:23:15 +01:00
Joseph Herlant
42cf6395c4 CLEANUP: Fix typos in the dns subsystem
Fix misspells in the code comments of the dns subsystem.
2018-11-18 22:23:15 +01:00
Joseph Herlant
0342090ed7 CLEANUP: Fix some typos in the haproxy subsystem
Fix some typos in the code comments of the haproxy subsystem.
2018-11-18 22:23:15 +01:00
Christopher Faulet
afd8f10be9 MINOR: lua/htx: Forbid lua usage when the HTX is enabled on a proxy
For now, the lua scripts are not compatible with the new HTX internal
representation of HTTP messages. Thus, for a given proxy, when the option
"http-use-htx" is enabled, an error is triggered if any lua's
action/service/sample-fetch/converter is also configured.
2018-11-18 22:10:09 +01:00
Christopher Faulet
0c859127f1 MINOR: filters/htx: Forbid filters when the HTX is enabled on a proxy
For now, the filters are not compatible with the new HTX internal representation
of HTTP messages. Thus, for a given proxy, when the option "http-use-htx" is
enabled, an error is triggered if any filter is also configured.
2018-11-18 22:10:09 +01:00
Christopher Faulet
473652733a MEDIUM: mux-h1: Handle errors and timeouts in the stream
To do so, the stream is created as earlier as possible. It means, during the mux
creation for the first request, and for others, just at the end of the previous
transaction. Because all timeouts are handled by the strream, the mux's task is
now useless, so it is removed. Finally, to report errors, flags are set on the
HTX message. The HTX message is passed to the stream if there is some content to
analyse or if there is some error to handle.

All of this will probably be reworked later to handle errors and timeouts
directly in the mux. For now, it is the simpler way to handle all of this.
2018-11-18 22:10:08 +01:00
Christopher Faulet
ed28da534a MINOR: stream: Don't reset sov value with HTX messages 2018-11-18 22:10:08 +01:00
Christopher Faulet
ef77922776 MINOR: stats/htx: Adapt the stats applet to handle HTX messages
Switches between the HTX version of the code and the legacy one have been added
to let the stats applet work with both.
2018-11-18 22:10:08 +01:00
Christopher Faulet
3b88b8d02e MEDIUM: mux-h1: Wait for connection establishment before consuming channel's data
When a server is down, the channel's data must not be consumed. This is
required to allow redispatch and connection retry. So now, we wait for
the connection to be marked as connected, with the flag CO_FL_CONNECTED,
before starting to consume channel's data. In the mux, this event is
tracked with the flag H1C_F_CS_WAIT_CONN.
2018-11-18 22:10:04 +01:00
Christopher Faulet
311c7eaad0 MEDIUM: http_fetch: Adapt all fetches to handle HTX messages
For HTTP proxies, when the HTX internal representation is used, or for all TCP
proxies, we use the HTX version of sample fetches.
2018-11-18 22:09:01 +01:00
Christopher Faulet
ef453ed9b0 MINOR: http_fetch: Add smp_prefetch_htx
It does the same than smp_prefetch_http but for HTX messages. It can be called
from an HTTP proxy or a TCP proxy. For HTTP proxies, the parsing is handled by
the mux, so it does nothing but wait. For TCP proxies, it tries to parse an HTTP
message and to convert it in a temporary HTX message. Sample fetches will use
this temporary variable to do their job.
2018-11-18 22:09:00 +01:00
Christopher Faulet
fec7bd16de MEDIUM: proto_htx: Adapt htx_process_res_common to handle HTX messages 2018-11-18 22:09:00 +01:00
Christopher Faulet
f76ebe8bc7 MEDIUM: proto_htx: Adapt htx_wait_for_request_body to handle HTX messages
This version is simpler than the legacy one because the parsing is no more
handled by the analyzer. So now we just need to wait to have more data to move
on.
2018-11-18 22:09:00 +01:00
Christopher Faulet
8137c27094 MINOR: proto_htx: Adapt htx_process_tarpit to handle HTX messages 2018-11-18 22:09:00 +01:00
Christopher Faulet
d7bdfb1e7b MEDIUM: proto_htx: Adapt htx_process_request to handle HTX messages 2018-11-18 22:08:59 +01:00
Christopher Faulet
ff2759febd MEDIUM: proto_htx: Adapt htx_process_req_common to handle HTX messages
Here, the only real change is that the stats and cache applets are disabled.
2018-11-18 22:08:59 +01:00
Christopher Faulet
377c5a508c MINOR: proto_htx: Add functions to handle the stats applet
For now, the call to the stats applet is disabled for HTX messages. But HTX
versions of the function to check the request URI against the stats URI and the
fnuction to prepare the call to the stats applet have been added.
2018-11-18 22:08:59 +01:00
Christopher Faulet
fefc73da34 MINOR: proto_htx: Add functions htx_perform_server_redirect
It is more or less the same than legacy version but adapted to be called from
HTX analyzers. In the legacy version of this function, we switch on the HTX code
when applicable.
2018-11-18 22:08:58 +01:00
Christopher Faulet
64159df1fb MINOR: proto_htx: Add functions htx_send_name_header
It is more or less the same than legacy version but adapted to be called from
HTX analyzers. In the legacy version of this function, we switch on the HTX code
when applicable.
2018-11-18 22:08:58 +01:00
Christopher Faulet
25a02f65b1 MINOR: proto_htx: Add functions to check the cacheability of HTX messages
It is more or less the same than legacy versions but adapted to be called from
HTX analyzers. In the legacy versions of these functions, we switch on the HTX
code when applicable.
2018-11-18 22:08:58 +01:00
Christopher Faulet
fcda7c6850 MINOR: proto_htx: Add functions to manage cookies on HTX messages
It is more or less the same than legacy versions but adapted to be called from
HTX analyzers.
2018-11-18 22:08:57 +01:00
Christopher Faulet
336400861e MINOR: proto_htx: Add functions to apply req* and rsp* rules on HTX messages
It is more or less the same than legacy versions but adapted to be called from
HTX analyzers.
2018-11-18 22:08:57 +01:00
Christopher Faulet
3e9641951f MINOR: proto_htx: Add functions htx_req_get_intercept_rule and htx_res_get_intercept_rule
It is more or less the same than legacy versions but adapted to be called from
HTX analyzers.
2018-11-18 22:08:57 +01:00
Christopher Faulet
6eb92897f7 MINOR: proto_htx: Add function to build and send HTTP 103 responses
It is more or less the same than legacy versions but adapted to be called from
HTX analyzers.
2018-11-18 22:08:56 +01:00
Christopher Faulet
8d8ac191a7 MINOR: proto_htx: Add functions htx_req_replace_stline and htx_res_set_status
It is more or less the same than legacy versions but adapted to be called from
HTX analyzers. In the legacy versions of these functions, we switch on the HTX
code when applicable.
2018-11-18 22:08:56 +01:00
Christopher Faulet
7233352fe4 MINOR: proto_htx: Add functions htx_transform_header and htx_transform_header_str
It is more or less the same than legacy versions but adapted to be called from
HTX analyzers.
2018-11-18 22:08:56 +01:00
Christopher Faulet
f052354892 MINOR: proto_htx: Add the internal function htx_fmt_res_line 2018-11-18 22:08:55 +01:00
Christopher Faulet
0b6bdc55af MINOR: proto_htx: Add the internal function htx_del_hdr_value
It is more or less the same than del_hdr_value but adapted to be called from HTX
analyzers. The main changes is that it takes pointers on the start and the end
of the header value.
2018-11-18 22:08:55 +01:00
Christopher Faulet
80f14bffc7 MINOR: proto_htx: Rewrite htx_apply_redirect_rule to handle HTX messages 2018-11-18 22:08:55 +01:00
Christopher Faulet
7ff1ceaa5e MINOR: http_htx: Add functions to retrieve a specific occurrence of a header
There are 2 functions. The first one considers any comma as a delimiter for
distinct values. The second one considers full-line headers.
2018-11-18 22:08:55 +01:00
Christopher Faulet
e010c80753 MINOR: http_htx: Add functions to replace part of the start-line 2018-11-18 22:08:54 +01:00
Christopher Faulet
9768c2660e MAJOR: mux-h1/proto_htx: Switch mux-h1 and HTX analyzers on the HTX representation
The mux-h1 now parses and formats HTTP/1 messages using the HTX
representation. The HTX analyzers have been updated too. For now, only
htx_wait_for_{request/response} and http_{request/response}_forward_body have
been adapted. Others are disabled for now.

Now, the HTTP messages are parsed by the mux on a side and then, after analysis,
formatted on the other side. In the middle, in the stream, there is no more
parsing. Among other things, the version parsing is now handled by the
mux. During the data forwarding, depending the value of the "extra" field, we
are able to know if the body length is known or not and if yes, how many bytes
are still expected.
2018-11-18 22:08:54 +01:00
Christopher Faulet
0f226958b7 MINOR: proto_htx: Add some functions to handle HTX messages
More functions will come, but it is the minimum to switch HTX analyzers on the
HTX internal representation.
2018-11-18 22:08:54 +01:00
Christopher Faulet
47596d3787 MINOR: http_htx: Add functions to manipulate HTX messages in http_htx.c
This file will host all functions to manipulate HTTP messages using the HTX
representation. Functions in this file will be able to be called from anywhere
and are mainly related to the HTTP semantics.
2018-11-18 22:08:53 +01:00
Christopher Faulet
a3d2a16fad MEDIUM: htx: Add API to deal with the internal representation of HTTP messages
The internal representation of an HTTP message, called HTX, is a structured
representation, unlike the old one which is a raw representation of
messages. Idea is to have a version-agnostic representation of the HTTP
messages, which can be easily used by to handle HTTP/1, HTTP/2 and hopefully
QUIC messages, and communication from one of them to another.

In this patch, we add types to define the internal representation itself and the
main functions to manipulate them.
2018-11-18 22:08:53 +01:00
Christopher Faulet
1be55f9eb2 MEDIUM: mux-h1: Add support of the kernel TCP splicing to forward data
The mux relies on the flag CO_RFL_BUF_FLUSH during a call to h1_rcv_buf to know
if it needs to stop reads and to flush its internal buffers to use kernel tcp
splicing. It is the caller responsibility (here the SI) to know when it must
come back on buffered exchanges.
2018-11-18 22:08:53 +01:00
Christopher Faulet
f2824e6e10 MAJOR: mux-h1/proto_htx: Handle keep-alive connections in the mux
Now, the connection mode is detected in the mux and not in HTX analyzers
anymore. Keep-alive connections are now managed by the mux. A new stream is
created for each transaction. This removes the most important part of the
synchronization between channels and the HTTP transaction cleanup. These changes
only affect the HTX part (proto_htx.c). Legacy HTTP analyzers remain untouched
for now.

On the client-side, the mux is responsible to create new streams when a new
request starts. It is also responsible to parse and update the "Connection:"
header of the response. On the server-side, the mux is responsible to parse and
update the "Connection:" header of the request. Muxes on each side are
independent. For now, there is no connection pool on the server-side, so it
always close the server connection.
2018-11-18 22:02:42 +01:00
Christopher Faulet
129817b394 MEDIUM: mux-h1: Add parsing of incoming and ougoing HTTP messages
For now, it only parses and transfers data. There is no internal representation
yet. It means the stream still need to parse it too. So a message is parsed 3
times today: one time by each muxes (the client one and the server one) and
another time by the stream. This is of course inefficient. But don't worry, it
is only a transitionnal state. And this mux is optional for now.

BTW, headers and body parsing are now handled using same functions than the mux
H2. Request/Response synchronization is also handled. The mux's task is now used
to catch client/http-request timeouts. Others timeouts are still handled by the
stream. On the clien-side, the stream is created once headers are fully parsed
and body parsing starts only when heeaders are transferred to the stream (ie,
copied into channel buffer).

There is still some known limitations here and there. But, it works in the
common cases. Bad message are not captured and some logs are emitted when errors
occur, only if no stream are attached to the mux. Otherwise, data are
transferred and we let the stream handles errors itself.
2018-11-18 22:02:41 +01:00
Christopher Faulet
51dbc94d48 MEDIUM: mux-h1: Add dummy mux to handle HTTP/1.1 connections
For now, it is just an other kind of passthrough multiplexer, but with internal
buffers to be prepared to parse incoming messages and to format outgoing
ones. There is also a task attached to it to handle timeouts. However, because
it does not handle any timeout for now, this task is unused. And finally,
because it handles internal buffers, it also handles retries on recv/send. To
use this multiplexer, you must use the option "http-use-htx" both on the
frontend and the backend.

It does not support keep-alive and will freeze connections after the first
request/response.
2018-11-18 22:02:11 +01:00
Christopher Faulet
e0768ebabc MEDIUM: proto_htx: Add HTX analyzers and use it when the mux H1 is used
For now, these analyzers are just copies of the legacy HTTP analyzers. But,
during the HTTP refactoring, it will be the main place where it will be
visible. And in legacy analyzers, the macro IS_HTX_STRM is used to know if the
HTX version should be called or not.

Note: the following commits were applied to proto_http.c after this patch
      was developed and need to be studied to see if an adaptation to htx
      is required :

  fd9b68c BUG/MINOR: only mark connections private if NTLM is detected
2018-11-18 21:45:50 +01:00
Christopher Faulet
effc3750cc MINOR: conn_stream: Add a flag to notify the SI some data were received
The flag CS_FL_READ_PARTIAL can be set by the mux on the conn_stream to notify
the stream interface that some data were received. Is is used in si_cs_recv to
re-arm read timeout on the channel.
2018-11-18 21:45:49 +01:00
Christopher Faulet
27a3dc8fb2 MINOR: http: Call http_send_name_header with the stream instead of the txn
This is just a minor change to ease integrartion of the HTX.
2018-11-18 21:45:49 +01:00
Christopher Faulet
8277ca72b1 MINOR: http: Add standalone functions to parse a start-line or a header
These 2 functions are pretty naive. They only split a start-line into its 3
substrings or a header line into its name and value. Spaces before and after
each part are skipped. No CRLF at the end are expected.
2018-11-18 21:45:49 +01:00
Christopher Faulet
72d9125efb MINOR: conn_stream: Add a flag to notify the mux it must respect the reserve
By setting the flag CO_RFL_KEEP_RSV when calling mux->rcv_buf, the
stream-interface notifies the mux it must keep some space to preserve the
buffer's reserve. This flag is only useful for multiplexers handling structured
data, because in such case, the stream-interface cannot know the real amount of
free space in the channel's buffer.
2018-11-18 21:45:48 +01:00
Christopher Faulet
f4eb75d177 MINOR: htx: Add proto_htx.c file
This file is empty for now. But it will be used to add new versions of the HTTP
analyzers based on the internal representation of HTTP messages (not implemented
yet but called HTX).
2018-11-18 21:45:48 +01:00
Christopher Faulet
c6618d6835 MINOR: conn_stream: Add a flag to notify the mux it should flush its buffers
By setting the flag CO_RFL_BUF_FLUSH when calling mux->rcv_buf, the
stream-interface notifies the mux it should flush its buffers without reading
more data. This flag is set when the SI want to use the kernel TCP splicing to
forward data. Of course, the mux can respect it or not, depending on its
state. It's just an information.
2018-11-18 21:45:48 +01:00
Olivier Houchard
7c6f8b146d MAJOR: connections: Detach connections from streams.
Do not destroy the connection when we're about to destroy a stream. This
prevents us from doing keepalive on server connections when the client is
using HTTP/2, as a new stream is created for each request.
Instead, the session is now responsible for destroying connections.
When reusing connections, the attach() mux method is now used to create a new
conn_stream.
2018-11-18 21:45:45 +01:00
Olivier Houchard
131fd89d5a MINOR: sessions: Start to store the outgoing connection in sessions.
Introduce a new field in session, "srv_conn", and a linked list of sessions
in the connection. It will be used later when we'll switch connections
from being managed by the stream, to being managed by the session.
2018-11-18 21:44:56 +01:00
Olivier Houchard
060ed43361 MINOR: mux: Add a destroy() method.
Add a new method to muxes, destroy(), that is responsible for destroying
the mux and the associated connection, to be used for server connections.
2018-11-18 21:44:53 +01:00
Olivier Houchard
d540b36e8a MINOR: mux: Add a new "avail_streams" method.
Add a new method for mux, avail_streams, that returns the number of streams
still available for a mux.
For the mux_pt, it'll return 1 if the connection is in idle, or 0. For
the H2 mux, it'll return the max number of streams allowed, minus the number
of streams currently in use.
2018-11-18 21:44:06 +01:00
Olivier Houchard
b6c32ee4c2 MEDIUM: mux: Teach the mux_pt how to deal with idle connections.
In order to make the mux_pt able to handle idle connections, give it its
own context, where it'll stores the connection, the current conn_stream if
any, and a wait_event, so that it can subscribe to I/O events.
Add a new parameter to the detach() method, that gives the mux a hint
if it should destroy the connection or not when detaching a conn_stream.
If 1, then the mux_pt immediately destroys the connecion, if 0, then it
just subscribes to any read event. If a read happens, it will call
conn_sock_drain(), and if there's a connection error, it'll free the
connection, after removing it from the idle list.
2018-11-18 21:44:03 +01:00
Olivier Houchard
47e9a1ad4e MEDIUM: connections: Wait until the connection is established to try to recv.
Instead of trying to receive as soon as the connection is created, and to
eventually have to transfer subscription if we move connections, wait
until the connection is established before attempting to recv.
2018-11-18 21:41:50 +01:00
Willy Tarreau
db398435aa MINOR: stream-int: replace si_cant_put() with si_rx_room_{blk,rdy}()
Remaining calls to si_cant_put() were all for lack of room and were
turned to si_rx_room_blk(). A few places where SI_FL_RXBLK_ROOM was
cleared by hand were converted to si_rx_room_rdy().

The now unused si_cant_put() function was removed.
2018-11-18 21:41:50 +01:00
Willy Tarreau
b26a6f9708 MEDIUM: stream-int: make use of si_rx_chan_{rdy,blk} to control the stream-int from the channel
The channel can disable reading from the stream-interface using various
methods, such as :
  - CF_DONT_READ
  - !channel_may_recv()
  - and possibly others

Till now this was done by mangling SI_FL_RX_WAIT_EP which is not
appropriate at all since it's not the stream interface which decides
whether it wants to deliver data or not. Some places were also wrongly
relying on SI_FL_RXBLK_ROOM since it was the only other alternative,
but it's not suitable for CF_DONT_READ.

Let's use the SI_FL_RXBLK_CHAN flag for this instead. It will properly
prevent the stream interface from being woken up and reads from
subscribing to more receipt without being accidently removed. It is
automatically reset if CF_DONT_READ is not set in stream_int_notify().

The code is not trivial because it splits the logic between everything
related to buffer contents (channel_is_empty(), CF_WRITE_PARTIAL, etc)
and buffer policy (CF_DONT_READ). Also it now needs to decide timeouts
based on any blocking flag and not just SI_FL_RXBLK_ROOM anymore.

It looks like this patch has caused a minor performance degradation on
connection rate, which possibly deserves being investigated deeper as
the test conditions are uncertain (e.g. slightly more subscribe calls?).
2018-11-18 21:41:49 +01:00
Willy Tarreau
47baeb85d4 MEDIUM: stream-int: unconditionally call si_chk_rcv() in update and notify
For a long time, stream_int_update() and stream_int_notify() used to only
conditionally call si_chk_rcv() based on state change detection. This
detection is not reliable and quite complex. With the new blocked flags
that si_chk_rcv() checks, it's much more reliable to always call the
function to take into account recent changes,and let it decide if it needs
to wake something up or not.

This also removes the calls to si_chk_rcv() that were performed in
si_update_both() since these ones are systematically performed in
stream_int_update() after updating the Rx flags.
2018-11-18 21:41:49 +01:00
Willy Tarreau
abb5d4202f MEDIUM: stream-int: use si_rx_shut_blk() to indicate the SI is closed
Till now we were using si_done_put() upon shutr, but these flags could
be reset upon next activity. Now let's switch to SI_FL_RXBLK_SHUT which
doesn't go away. It's also set in stream_int_update() in case a shutr
condition is detected.

The now unused si_done_put() was removed.
2018-11-18 21:41:49 +01:00
Willy Tarreau
4b962a4179 MEDIUM: stream-int: fix the si_cant_put() calls used for buffer readiness
A number of calls to si_cant_put() were used in fact to request being
called back once a buffer is available. These ones are not needed anymore
since si_alloc_ibuf() already sets the SI_FL_RXBLK_BUFF flag when called
in appctx context. Those called with a foreign stream-int are simply turned
to si_rx_buff_blk().
2018-11-18 21:41:48 +01:00
Willy Tarreau
3367d4156d MEDIUM: stream-int: fix the si_cant_put() calls used for end point readiness
A number of si_cant_put() calls were still present to in fact indicate
that the end point is ready (thus should be turned to si_rx_endp_more()).

One other call in the Lua handler indicates that the endpoint wanted to
be blocked until some room is made in the Rx buffer in order to detect
that the connection happened, which is in fact an indication that it
wants to be called once the endpoint is ready, this is the default case
for an applet so this call was removed.

A useless call to si_cant_put() before appctx_wakeup() in the Lua
applet wakeup call was removed as well since the first thing that will
be done there will be to set end ENDP blocking flag.
2018-11-18 21:41:48 +01:00
Willy Tarreau
186dcdd128 MINOR: stream-int: automatically mark applets as ready if they block on the channel
If an applet reports being blocked due to any of the channel-side flags,
it's reportedly ready to deliver incoming data. It's better to do this
after the return from the applet handler so that applet developers don't
have to worry about details related to flags ordering.
2018-11-18 21:41:48 +01:00
Willy Tarreau
dd5621ab80 MEDIUM: stream-int: update the endp polling status only at the end of si_cs_recv()
Instead of first indicating that there's more data to read from the
conn_stream then re-adjusting this info along the function, we now
instead set the status according to the subscription status at the
end. It's easier, more accurate, and less sensitive to intermediary
changes.

This will soon allow to remove all the si_cant_put() calls that were
placed in the middle to force a subsequent callback and prevent the
function from subscribing to the mux layer.
2018-11-18 21:41:47 +01:00
Willy Tarreau
8bb2ffb831 MINOR: stream-int: replace si_{want,stop}_put() with si_rx_endp_{more,done}()
Here it's only a 1-to-1 replacement.
2018-11-18 21:41:47 +01:00
Willy Tarreau
8be7cd7b92 MEDIUM: stream-int: use si_rx_buff_{rdy,blk} to report buffer readiness
The stream interface used to conflate a missing buffer and lack of
buffer space into SI_FL_WAIT_ROOM but this causes difficulties as
these cannot be checked at the same moment and are not resolved at
the same moment either. Now we instead mark the buffer as presumably
available using si_rx_buff_rdy() and mark it as unavailable+requested
using si_rx_buff_blk().

The call to si_alloc_buf() was moved after si_stop_put(). This makes
sure that the SI_FL_RX_WAIT_EP flag is cleared on allocation failure so
that the function is called again if the callee fails to do its work.
2018-11-18 21:41:47 +01:00
Willy Tarreau
32742fdf45 MINOR: stream-int: use si_rx_blocked()/si_tx_blocked() to check readiness
This way we don't limit ourselves to random flags only and the code
is more readable and safer for the long term.
2018-11-18 21:41:46 +01:00
Willy Tarreau
05b9b64afb MINOR: stream-int: replace SI_FL_WANT_PUT with !SI_FL_RX_WAIT_EP
The SI_FL_WANT_PUT flag is used in an awkward way, sometimes it's
set by the stream-interface to mean "I have something to deliver",
sometimes it's cleared by the channel to say "I don't want you to
send what you have", and it has to be set back once CF_DONT_READ
is cleared. This will have to be split between SI_FL_RX_WAIT_EP
and SI_FL_RXBLK_CHAN. This patch only replaces all uses of the
flag with its natural (but negated) replacement SI_FL_RX_WAIT_EP.
The code is expected to be strictly equivalent. The now unused flag
was completely removed.
2018-11-18 21:41:46 +01:00
Willy Tarreau
d0f5bbcd64 MINOR: stream-int: rename SI_FL_WAIT_ROOM to SI_FL_RXBLK_ROOM
This flag is not enough to describe all blocking situations, as can be
seen in each case we remove it. The muxes has taught us that using multiple
blocking flags in parallel will be much easier, so let's start to do this
now. This patch only renames this flags in order to make next changes more
readable.
2018-11-18 21:41:45 +01:00
Willy Tarreau
89b6a2b4fd MINOR: stream-int: relax the forwarding rules in stream_int_notify()
There currently is an optimization in stream_int_notify() consisting
in not trying to forward small bits of data if extra data remain to be
processed. The purpose is to avoid forwarding one chunk at a time if
multiple chunks are available to be parsed at once. It consists in
avoiding sending pending output data if there are still data to be
parsed in the channel's buffer, since process_stream() will have the
opportunity to deal with them all at once.

Not only this optimization is less useful with the new way the connections
work, but it even causes problems like lost events since WAIT_ROOM will
not be removed. And with HTX, it will never be able to update the input
buffer after the first read.

Let's relax the rules now, by always sending if we don't have the
CF_EXPECT_MORE flag (used to group writes), or if the buffer is
already full.
2018-11-18 21:41:44 +01:00
Willy Tarreau
6b1379fb8a MINOR: stream-int: make conn_si_send_proxy() use cs_get_first()
The function used to abuse the internals of mux_pt to retrieve a
conn_stream, which will not work anymore after the idle connection
changes. Let's make it rely on the more reliable cs_get_first()
instead.
2018-11-18 21:38:19 +01:00
Willy Tarreau
fafd3984b9 MINOR: mux: implement a get_first_cs() method
This method is used to retrieve the first known good conn_stream from
the mux. It will be used to find the other end of a connection when
dealing with the proxy protocol for example.
2018-11-18 21:29:20 +01:00
Willy Tarreau
479998adbf CLEANUP: h2: minimum documentation for recent API changes
Commit d4dd22d ("MINOR: h2: Let user of h2_recv() and h2_send() know xfer
has been done") changed the API without documenting the expected returned
values which appear to come out of nowhere in the code :-(  Please don't
do that anymore! The description was recovered from the commit message.
2018-11-18 06:35:29 +01:00
Christopher Faulet
6b44975fbd BUG/MINOR: config: Copy default error messages when parsing of a backend starts
To be used, error messages declared in a default section must be copied when the
parsing of a proxy section starts. But this was only done for frontends.

This patch may be backported to older versions.
2018-11-18 06:17:03 +01:00
Willy Tarreau
ade6478a8c MINOR: stream: move the conn_stream specific calls to the stream-int
There are still some unwelcome synchronous calls to si_cs_recv() in
process_stream(). Let's have a new function si_sync_recv() to perform
a synchronous receive call on a stream interface regardless of the type
of its endpoint, and move these calls there. For now it only implements
conn_streams since it doesn't seem useful to support applets there. The
function implements an extra check for the stream interface to be in an
established state before attempting anything.
2018-11-17 19:53:45 +01:00
Willy Tarreau
00b3b8c361 BUG/MINOR: stream-int: set SI_FL_WANT_PUT in sess_establish()
In commit f26c26c ("BUG/MEDIUM: stream-int: change the way buffer room
is requested by a stream-int") we used to call si_want_put() at the
end of sess_update_st_con_tcp(), when switching to SI_ST_EST state.
But this is incorrect as there are a few other situations where we
can switch to this state, such as in si_connect() where a connection
reuse is detected, or when directly calling an applet (in which case
that was already covered anyway). For now it doesn't have any side
effect but it could impact connection reuse after the stream-int
changes by stalling an immediately reused connection.

Let's move this flag change to sess_establish() instead, which is the
only place which is always called exactly once on connection setup.

No backport is needed, this is purely 1.9.
2018-11-17 19:20:01 +01:00
William Lallemand
a337229ac2 MEDIUM: cli: worker socketpair is unstoppable
In master-worker mode, the socketpair CLI listener of the worker is now
marked unstoppable, which allows to connect to the CLI of an old process
which is in a leaving state, allowing to debug it.
2018-11-16 17:05:40 +01:00
William Lallemand
c59f9884d7 MEDIUM: listeners: support unstoppable listener
An unstoppable listener is a listener which won't be stop during a soft
stop. The unstoppable_jobs variable is incremented and the listener
won't prevent the process to leave properly.

It is not a good idea to use this feature (the LI_O_NOSTOP flag) with a
listener that need to be bind again on another process during a soft
reload.
2018-11-16 17:05:40 +01:00
William Lallemand
a719926cf8 MEDIUM: jobs: support unstoppable jobs for soft stop
This patch allows a process to properly quit when some jobs are still
active, this feature is handled by the unstoppable_jobs variable, which
must be atomically incremented.

During each new iteration of run_poll_loop() the break condition of the
loop is now (jobs - unstoppable_jobs) == 0.

The unique usage of this at the moment is to handle the socketpair CLI
of a the worker during the stopping of the process.  During the soft
stop, we could mark the CLI listener as an unstoppable job and still
handle new connections till every other jobs are stopped.
2018-11-16 17:05:40 +01:00
Christopher Faulet
3c0544efbf BUG/MINOR: http: Be sure to sent fully formed HTTP 103 responses
The previous commit fedceaf33 ("MINOR: http: Regroup return statements of
http_req_get_intercept_rule at the end") partly fixes the problem. But not
entierly. Because HTTP 103 reponses were sent line by line it is possible to mix
them with others. For instance, an early-hint rule followed by a redirect rule
leaving the response buffer totally messed up. Furthermore, if we fail to add
the last CRLF to finish the HTTP 103 response because there is no more space in
the buffer, it leave the buffer with an unfinished and invalid message.

This patch fixes the bug by creating a fully formed HTTP 103 response before
trying to push it in the response buffer. If an error occurred during the copy
or if another response was already sent, the HTTP 103 response is
ignored. However, the last point should never happened because, for redirects
and authentication errors, we first try to copy any pending HTTP 103 response.
2018-11-16 16:05:51 +01:00
Christopher Faulet
6c243ebb9f MINOR: http: Regroup return statements of http_res_get_intercept_rule at the end
Instead of having multiple return statements spreaded here and there in middle
of the function, we just exit from the loop setting the right return code. It
let a chance to do some work before leaving the function. It is also less error
prone.
2018-11-16 16:05:51 +01:00
Christopher Faulet
ea827bdcbc MINOR: http: Regroup return statements of http_req_get_intercept_rule at the end
Instead of having multiple return statements spreaded here and there in middle
of the function, we just exit from the loop setting the right return code. It
let a chance to do some work before leaving the function. It is also less error
prone.
2018-11-16 16:05:51 +01:00
Christopher Faulet
78337bbbaa BUG/MINOR: http_fetch: Remove the version part when capturing the request uri
This patch fixes a bug introduced in the commit 6b952c810 ("REORG: http: move
http_get_path() to http.c"). In the reorg, the code responsible to skip the
version to only extract the path in the HTTP request was dropped.

No backport is needed, this only affects 1.9.
2018-11-16 16:05:51 +01:00
Willy Tarreau
ffb1205a47 BUG/MINOR: stream-int: make sure not to go through the rcv_buf path after splice()
When splice() reports a pipe full condition, we go through the common
code used to release a possibly empty pipe (which we don't have) and which
immediately tries to allocate a buffer that will never be used. Further,
it may even subscribe to get this buffer if the resources are low. Let's
simply get out of this way if the pipe is full.

This fix could be backported to 1.8 though the code is a bit different
overthere.
2018-11-15 17:00:08 +01:00
Willy Tarreau
81464b4e4d BUG/MEDIUM: stream-int: clear CO_FL_WAIT_ROOM after splicing data in
Since we don't necessarily pass through conn_fd_handler() when reading,
conn_refresh_polling_flags() is not necessarily called when performing
a recv() operation, thus flags like CO_FL_WAIT_ROOM are not cleared.

It happens that si_cs_recv() checks CO_FL_WAIT_ROOM before deciding to
receive into a buffer, to see if the previous rcv_pipe() call failed by
lack of pipe room. The combined effect of these two statements is that
at the end of a file transmission, when there's too little data to
warrant the use of a pipe and the pipe is empty, we refrain from using
rcv_pipe() for the last few bytes, but since CO_FL_WAIT_ROOM is still
present, we don't use rcv_buf() either, and the connection remains
frozen in this state with si_cs_recv() called in loops.

In order to fix this we can simply manually clear CO_FL_WAIT_ROOM when
not using pipe so that the next check sees the result of the previous
operation and not an old one. We could equally call
cond_refresh_polling_flags() but that would be overkill and dangerous
given that it would manipulate the connection's flags under the mux.
By the way ideally the mux should report this flag into the connstream
for cleaner manipulation.

No backport is needed as this is only post 1.9-dev2.
2018-11-15 17:00:08 +01:00
Willy Tarreau
f6975aa920 BUG/MEDIUM: stream-int: make failed splice_in always subscribe to recv
As part of the changes that went into 1.9-dev2 regarding the polling
modifications, the changes consecutive to the removal of the wait_list
from the conn_streams (commit 71384551a) made si_cs_recv() occasionally
return without subscribing to receive events, causing spliced transfers
to randomly fail if the client was at least as fast as the server. This
may remain unnoticed on most deployments since servers are usually close
to haproxy with higher bandwidth than clients have, resulting in buffers
always being full.

In order to reproduce his effect, it is better to do it on the local
machine and to transfer very large objects (hundreds of gigs) over a
single connection, to see it suddenly stall after a few tens of gigs.
Now with this fix it's fine even after 3 TB over a single connection.

No backport is needed.
2018-11-15 14:39:03 +01:00
Olivier Houchard
52dabbc4fa BUG/MEDIUM: Make sure stksess is properly aligned.
When we allocate struct stksess, we also allocate memory to store the
associated data before the struct itself.
As the data can be of different types, they can have different size. However,
we need the struct stksess to be properly aligned, as it can do 64bits
load/store (including atomic load/stores) on 64bits platforms, and some of
them doesn't support unaligned access.
So, when allocating the struct stksess, round the size up to the next
multiple of sizeof(void *), and make sure the struct stksess itself is
properly aligned.
Many thanks to Paul Martin for investigating and reporting that bug.

This should be backported to earlier releases.
2018-11-15 14:24:05 +01:00
William Lallemand
a8b2671cf6 BUG/MEDIUM: log: don't CLOEXEC the inherited FDs
When configuring the logs with a FD and using the master worker, the FD
was closed upon a reload because it was configured with CLOEXEC. It
leads to using the wrong FD for the logs and to close them. Which is
unfortunate since the master rely on the FD left opened during a reload.

The fix is to stop doing a CLOEXEC when the FD is inherited.
No backport needed.
2018-11-13 19:32:45 +01:00
William Lallemand
2e8fad9c30 MINOR: mworker: only close std{in,out,err} in daemon mode
This allows to output messages when we are not in daemon mode which is
useful to use log stdout in master worker mode.
2018-11-13 16:21:15 +01:00
Frdric Lcaille
9ca51aa288 MINOR: http: Implement "early-hint" http request rules.
This patch implements http_apply_early_hint_rule() function is responsible of
building HTTP 103 Early Hint responses each time a "early-hint" rule is matched.
2018-11-12 21:08:55 +01:00
Frdric Lcaille
0ebbcb663c MINOR: http: Make new "early-hint" http-request action really be parsed.
This patch adds a "early_hint" struct to "arg" union of "act_rule" struct
and parse "early-hint" http-request keyword with it using the same
code as for "(add|set)-header" parser.
2018-11-12 21:08:55 +01:00
Frdric Lcaille
a985e3875b MINOR: http: Add new "early-hint" http-request action.
This patch adds the new "early-hint" action to "http-request" rules parser.
This action should be parsed the same way as "(add|set)-header" actions.
2018-11-12 21:08:55 +01:00
David Carlier
42d9e5ae68 BUILD/MEDIUM: threads/affinity: DragonFly build fix
DragonFlyBSD does not have a build on its own, it has always
used the FreeBSD's. To be able to support the cpu affinity,
it needs few more headers.
2018-11-12 19:16:00 +01:00
Willy Tarreau
7520e4ff57 MINOR: namespaces: don't build namespace.c if disabled
When namespaces are disabled, support is still reported because the file
is built with almost nothing in it but built anyway. Instead of extending
the scope of the numerous ifdefs in this file, better avoid building it
when namespaces are diabled. In this case we define my_socketat() as an
inline function mapping directly to socket(). The struct netns_entry
still needs to be defined because it's used by various other functions
in the code.
2018-11-12 19:15:15 +01:00
Willy Tarreau
691fe39284 BUG/MEDIUM: stream-int: convert some co_data() checks to channel_is_empty()
Splicing was in great part broken over the last few development version
due to the use of co_data() to detect if data are available in the channel.
But co_data() only looks at buffered data, not spliced data.

Channel_is_empty() takes care of both and should be used. With this,
splicing restarts to work but there are still a few cases where transfers
may stall.

No backport is needed.
2018-11-12 19:00:22 +01:00
Willy Tarreau
f26c26cca2 BUG/MEDIUM: stream-int: change the way buffer room is requested by a stream-int
Subsequent to the recent stream-int updates, we started to consider that
SI_FL_WANT_PUT needs to be set when receipt is enabled, but this is wrong
and results in 100% CPU when an HTTP client stays idle after a keep-alive
request because the stream-int has nothing to provide and nothing to send.

In fact just like for applets this flag should reflect the continuation
of an attempt. So it's si_cs_recv() which should set the flag, and clear
it if it has nothing more to provide. This function is called the first
time in process_stream()), and called again during transfers, so it will
always be up to date during stream_int_update() and stream_int_notify().

As a special case, it should also be set when a connection switches to
the established state. And we should absolutely refrain from calling
si_cs_recv() to re-enable reading, normally just setting this flag
(from within the stream-int's handler or prior to calling si_chk_rcv())
is expected to be OK.

A corner case remains where it was observed that in stream_int_notify() we
can sometimes be called with an empty output channel with SI_FL_WAIT_ROOM
and no CF_WRITE_PARTIAL, so there's no way to detect that we should
re-enable receiving. It's easy to also take care of this condition
there for the time it takes to figure if this situation is expected
or not.

Now it becomes more obvious that relying on a single flag to request
room (or on two flags to arbiter activity) is not workable given the
autonomy of both sides. The mux_h2 has taught us that blocking flags
are much more reliable, require much less condition and are much easier
to deal with. That's probably something to consider quickly in this
area.

No backport is needed.
2018-11-12 18:58:45 +01:00
Willy Tarreau
c1b0645dac MEDIUM: log: add a new "raw" format
This format is pretty similar to the previous "short" format except
that it also removes the severity level. Thus only the raw message is
sent. This is suitable for use in containers, where only the raw
information is expected and where the severity is supposed to come
from the file descriptor used.
2018-11-12 18:37:55 +01:00
Willy Tarreau
e8746a08b2 MEDIUM: log: support a new "short" format
This format is meant to be used with local file descriptors. It emits
messages only prefixed with a level, removing all the process name,
system name, date and so on. It is similar to the printk() format used
on Linux. It's suitable to be sent to a local logger compatible with
systemd's output format.

Note that the facility is still required but not used, hence it is
suggested to use "daemon" to remind that it's a local logger.
Example :

    log stdout format short daemon          # send everything to stdout
    log stderr format short daemon notice   # send important events to stderr
2018-11-12 18:37:55 +01:00
Willy Tarreau
5a32ecc6cf MEDIUM: log: add support for logging to existing file descriptors
In certain situations it would be desirable to log to an existing file
descriptor, the most common case being a pipe between containers or
processes. The main issue with pipes is that using write() on them will
randomly truncate messages. But there is a trick. By using writev(), we
can atomically deliver or drop a message, which perfectly fits the
purpose. The only caveat is that large messages (4096 bytes on modern
operating systems) may be interleaved with messages from other processes
if using nbproc for example. In practice such messages are rare and most
of the time when users need such type of logging, the load is low enough
for a single process to be running so this is not really a problem.

This logging method thus uses unbuffered writev() calls and is uses more
CPU than if it used its own buffer with large writes at once, though this
is not a problem for moderate loads.

Logging to a file descriptor attached to a file also works with the side
effect that the process is significantly slowed down during disk accesses
and that it's not possible to rotate the file without restarting the
process. For this reason this option is not offered as a configuration
option, since it would confuse most users, but one could decide to
redirect haproxy's output to a file during debugging sessions. Two aliases
"stdout" and "stderr" are provided, but keep in mind that these are closed
by default in daemon mode.

When logging to a pipe or socket at a high enough rate, some logs will be
dropped and the number of dropped messages is reported in "show info".
2018-11-12 18:37:55 +01:00
Willy Tarreau
13ef773722 MINOR: log: report the number of dropped logs in the stats
It's easy to detect when logs on some paths are lost as sendmsg() will
return EAGAIN. This is particularly true when sending to /dev/log, which
often doesn't support a big logging capacity. Let's keep track of these
and report the total number of dropped messages in "show info".
2018-11-12 18:37:55 +01:00
Willy Tarreau
251fe34ca2 MINOR: log: slightly improve error message syntax on log failure
The error messages used to say something along "socket logger 2 failed"
or "sendmsg logger 2 failed" which are confusing. Let's rephrase this
"sendmsg() failed for logger 2".
2018-11-12 18:37:55 +01:00
Willy Tarreau
96062a181d BUILD: cache: fix a build warning regarding too large an integer for the age
Building on 32 bit gives this :

  src/cache.c: In function 'http_action_store_cache':
  src/cache.c:466:4: warning: this decimal constant is unsigned only in ISO C90 [enabled by default]
  src/cache.c:467:5: warning: this decimal constant is unsigned only in ISO C90 [enabled by default]
  src/cache.c: In function 'cache_channel_append_age_header':
  src/cache.c:578:2: warning: this decimal constant is unsigned only in ISO C90 [enabled by default]
  src/cache.c:579:3: warning: this decimal constant is unsigned only in ISO C90 [enabled by default]

It's because of the definition below added in commit e7a770c ("MINOR:
cache: Add "Age" header.") :

  #define CACHE_ENTRY_MAX_AGE 2147483648

Just appending "U" to mark it unsigned is enough to fix it. This only
affects 1.9, no backport is needed.
2018-11-11 14:03:02 +01:00
Willy Tarreau
4db49c0704 BUG/MINOR: config: better detect the presence of the h2 pattern in npn/alpn
In 1.8, commit 45a66cc ("MEDIUM: config: ensure that tune.bufsize is at
least 16384 when using HTTP/2") tried to avoid an annoying issue making
H2 fail when haproxy is built with default buffer sizes smaller than 16kB,
which used to be the case for a very long time. Sadly, the test only sees
when NPN/ALPN exactly match "h2" and not when it's combined like
"h2,http/1.1" nor "http/1.1,h2". We can safely use strstr() there because
the string is prefixed by the token's length (0x02) which is unambiguous
as it cannot be part of any other token.

This fix should be backported to 1.8 as a safety guard against bad
configurations.
2018-11-11 10:42:37 +01:00
Christopher Faulet
4eb7d745e2 MEDIUM: stream-int: Try to read data even if channel's buffer seems to be full
Before calling the mux to get incoming data, we get the amount of space
available at the input of the buffer. If there is no space, we don't try to read
more data. This is good enough when raw data are stored in the buffer. But this
info has no meaning when structured data are stored. Because with the HTTP
refactoring, such kind of data will be stored in buffers, it is a bit annoying.

So, to avoid any problems, we always call the mux. It is the mux's responsiblity
to notify the stream interface it needs more space to store more data. This must
be done by setting the flag CS_FL_RCV_MORE on the conn_stream.

This is exactly what we do in the pass-through mux when <count> is null.
2018-11-11 10:18:37 +01:00
Christopher Faulet
b3e0de46ce MEDIUM: stream-int: Rely only on SI_FL_WAIT_ROOM to stop data receipt
This flag is set on the stream interface when we should wait for more space in
the channel's buffer to store more incoming data. This means we should wait some
outgoing data are sent before retrying to receive more data.

But in stream interface functions, at many places, instead of checking this
flag, we use the function channel_may_recv to know if we can (re)start
reading. This currently works but it is not really consistent. And, it works
because only raw data are stored in buffers. But it will be a problem when we
start to store structured data in buffers.

So to avoid any problems with futur implementations, we now rely only on
SI_FL_WAIT_ROOM. The function channel_may_recv can still be called, but only
when we are sure to handle raw data (for instance in functions ci_put*). To do
so, among other things, we must be sure to unset SI_FL_WAIT_ROOM and offer an
opportunity to call chk_rcv() on a stream interface when some data are sent
on the other end, which is now granted by the previous patch series.
2018-11-11 10:18:37 +01:00
Willy Tarreau
d0d40ebf5e CLEANUP: stream-int: remove the now unused si->update() function
We exclusively use stream_int_update() now, the lower layers are not
called anymore so let's remove them, as well as si_update() which used
to be their wrapper.
2018-11-11 10:18:37 +01:00
Willy Tarreau
bf89ff3db8 MEDIUM: stream-int: make stream_int_update() aware of the lower layers
It's far from being clean, but at least it allows to resync both CS and
applets from the same place, taking into account the fact that CS are
processed synchronously for the send side while appletx are processed
outside of the process_stream() loop. The arrangement is optimised to
minimize the amount of iteration by handling send first, then updating
the SI_FL_WAIT_ROOM flags and only then dealing with si_chk_rcv() on
both sides. The SI_FL_WANT_PUT flag is set if needed before calling
si_chk_rcv() since this is done prior to calling stream_int_update().

Now there's no risk that stream_int_notify() is called anymore during
such operations, thus we cannot have any spurious wake-up anymore. The
case where a successful send() could complete a pending connect() is
handled by taking any stream-int state changes into account at the
call place, which is normal since process_stream() is designed to
iterate till stabilisation.

Doing this solves most of the remaining inconsistencies between CS and
applets.
2018-11-11 10:18:37 +01:00
Willy Tarreau
d14844a734 MINOR: stream-int: replace si_update() with si_update_both()
The function used to be called in turn for each side of the stream, but
since it's called exclusively from process_stream(), it prevents us from
making use of the knowledge we have of the operations in progress for
each side, resulting in having to go all the way through functions like
stream_int_notify() which are not appropriate there.

That patch creates a new function, si_update_both() which takes two
stream interfaces expected to belong to the same stream, and processes
their flags in a more suitable order, but for now doesn't change the
logic at all.

The next step will consist in trying to reinsert the rest of the socket
layer-specific update code to ultimately update the flags correctly at
the end of the operation.
2018-11-11 10:18:37 +01:00
Willy Tarreau
abf531caa0 MEDIUM: stream-int: always call si_chk_rcv() when we make room in the buffer
Instead of clearing the SI_FL_WAIT_ROOM flag and losing the information
about the need from the producer to be woken up, we now call si_chk_rcv()
immediately. This is cheap to do and it could possibly be further improved
by only doing it when SI_FL_WAIT_ROOM was still set, though this will
require some extra auditing of the code paths.

The only remaining place where the flag was cleared without a call to
si_chk_rcv() is si_alloc_ibuf(), but since this one is called from a
receive path woken up from si_chk_rcv() or not having failed, the
clearing was not necessary anymore either.

And there was one place in stream_int_notify() where si_chk_rcv() was
called with SI_FL_WAIT_ROOM still explicitly set so this place was
adjusted in order to clear the flag prior to calling si_chk_rcv().

Now we don't have any situation where we randomly clear SI_FL_WAIT_ROOM
without trying to wake the other side up, nor where we call si_chk_rcv()
with the flag set, so this flag should accurately represent a failed
attempt at putting data into the buffer.
2018-11-11 10:18:37 +01:00
Willy Tarreau
1f9de21c38 MEDIUM: stream-int: make SI_FL_WANT_PUT reflect CF_DONT_READ
When CF_DONT_READ is set, till now we used to set SI_FL_WAIT_ROOM, which
is not appropriate since it would lose the subscribe status. Instead let's
clear SI_FL_WANT_PUT (just like applets do), and set the flag only when
CF_DONT_READ is cleared.

We have to do this in stream_int_update(), and in si_cs_io_cb() after
returning from si_cs_recv() since it would be a bit invasive to hack
this one for now. It must not be done in stream_int_notify() otherwise
it would re-enable blocked applets.

Last, when si_chk_rcv() is called, it immediately clears the flag before
calling ->chk_rcv() so that we are not tempted to uselessly loop on the
same call until the receive function is called. This is the same principle
as what is done with the applet scheduler.
2018-11-11 10:18:37 +01:00
Willy Tarreau
1bdb598a55 MINOR: stream-int: factor the SI_ST_EST state test into si_chk_rcv()
This test is made in each implementation of the function, better to
merge it.
2018-11-11 10:18:37 +01:00
Willy Tarreau
96aadd5c55 MEDIUM: stream-int: temporarily make si_chk_rcv() take care of SI_FL_WAIT_ROOM
This flag should already be cleared before calling the *chk_rcv() functions.
Before adapting all call places, let's first make sure si_chk_rcv() clears
it before calling them so that these functions do not have to check it again
and so that they do not adjust it. This function will only call the lower
layers if the SI_FL_WANT_PUT flag is present so that the endpoint can decide
not to be called (as done with applets).
2018-11-11 10:18:37 +01:00
Willy Tarreau
43e69dc1eb MINOR: stream-int: make use of si_done_{get,put}() in shut{w,r}
It's cleaner to use these functions there to properly clear the flags.
2018-11-11 10:18:37 +01:00
Willy Tarreau
af4f6f6d2f MINOR: stream-int: use si_cant_put() instead of setting SI_FL_WAIT_ROOM
We now do this on the si_cs_recv() path so that we always have
SI_FL_WANT_PUT properly set when there's a need to receive and
SI_FL_WAIT_ROOM upon failure.
2018-11-11 10:18:37 +01:00
Willy Tarreau
0cd3bd628a MINOR: stream-int: rename si_applet_{want|stop|cant}_{get|put}
It doesn't make sense to limit this code to applets, as any stream
interface can use it. Let's rename it by simply dropping the "applet_"
part of the name. No other change was made except updating the comments.
2018-11-11 10:18:37 +01:00
Willy Tarreau
21028b5e7f MEDIUM: appctx: check for allocation attempts in buffer allocation callbacks
The buffer allocation callback appctx_res_wakeup() used to rely on old
tricks to detect if a buffer was already granted to an appctx, namely
by checking the task's state. Not only this test is not valid anymore,
but it's inaccurate.

Let's solely on SI_FL_WAIT_ROOM that is now set on allocation failure by
the functions trying to allocate a buffer. The buffer is now allocated on
the fly and the flag removed so that the consistency between the two
remains granted. The patch also fixes minor issues such as the function
being improperly declared inline(!) and the fact that using appctx_wakeup()
sets the wakeup reason to TASK_WOKEN_OTHER while we try to use TASK_WOKEN_RES
when waking up consecutive to a ressource allocation such as a buffer.
2018-11-11 10:18:37 +01:00
Willy Tarreau
b882dd88cc MEDIUM: stream: implement stream_buf_available()
This function replaces stream_res_available(), which is used as a callback
for the buffer allocator. It now carefully checks which stream interface
was blocked on a buffer allocation, tries to allocate the input buffer to
this stream interface, and wakes the task up once such a buffer was found.
It will automatically remove the SI_FL_WAIT_ROOM flag upon success since
the info this flag indicates becomes wrong as soon as the buffer is
allocated.

The code is still far from being perfect because if a call to si_cs_recv()
fails to allocate a buffer, we'll still end up passing via process_stream()
again, but this could be improved in the future by using finer-grained
wake-up notifications.
2018-11-11 10:18:37 +01:00
William Lallemand
e260e0df44 BUG/MEDIUM: cli: crash when trying to access a worker
When using the CLI proxy of the master and trying to access a worker
with the @ prefix, the worker just crash.

The commit 7216032 ("MEDIUM: mworker: leave when the master die")
reintroduced the old code of the pipe, which was not trying to access
the pointers before. The owner of the FD was modified to a different
value, this is a problem since we call listener_accept() in most cases
now from the mworker_accept_wrapper() and it casts the owner variable to
get the listener.

This patch fix the issue by setting back the previous owner of the FD.
2018-11-08 14:48:06 +01:00
Willy Tarreau
b69f1713af BUG/MEDIUM: stream-int: don't wake up for nothing during SI_ST_CON
Commit eafd8ebcf ("MEDIUM: stream-int: call si_cs_process() in
stream_int_update_conn") uncovered a sleeping bug. By calling
si_cs_process() within si_update(), we end up calling stream_int_notify().
We rely on it to update the stream-int before quitting as a hack, but
it happens to immediately wake the task up while the stream int's
state is still SI_ST_CON (during the connection establishment). The
observable effect is that an unreachable server causes haproxy to
use 100% CPU until the connection timeout strikes.

This patch fixes this by not causing the wake up for the SI_ST_CON
state. It would equally be possible to check for states higher than
SI_ST_EST as is done in other places, but for now better stay on the
safe side by covering the only issue that can be triggered. It's
suspected that this issue slightly affects older versions by causing
one extra call to process_stream() during the connection setup for
each activity change on the other side, but this should not have
any observable effect.

No backport is needed.
2018-11-08 14:47:24 +01:00
William Lallemand
a90cacfd70 BUG/MEDIUM: mworker: does not abort() in mworker_pipe_register()
The process was aborting with nbthread > 1.

The mworker_pipe_register() could be called several time in multithread
mode, we don't want to abort() there.
2018-11-07 09:26:36 +01:00
Willy Tarreau
8ccd2081f5 CLEANUP: stream-int: retro-document si_cs_io_cb()
It took me 17 minutes this morning to figure where si->wait_event was
set (it's in si_reset() which should now probably be renamed since it
doesn't just perform a reset anymore but also an allocation) and what
its task was assigned to (si_cs_io_cb() even for applets and empty SI).

This is too confusing and not intuitive enough, let's at least add a
few comments for now to help figure how this stuff works next time.
2018-11-07 07:54:26 +01:00
William Lallemand
7216032e6f MEDIUM: mworker: leave when the master die
When the master die, the worker should exit too, this is achieved by
checking if the FD of the socketpair/pipe was closed between the master
and the worker.

In the former architecture of the master-worker, there was only a pipe
between the master and the workers, and it was easy to check an EOF on
the pipe FD to exit() the worker.

With the new architecture, we use a socketpair by process, and this
socketpair is also used to accept new connections with the
listener_accept() callback.

This accept callback can't handle the EOF and the exit of the process,
because it's very specific to the master worker. This is why we
transformed the mworker_pipe_handler() function in a wrapper which check
if there is an EOF and exit the process, and if not call
listener_accept() to achieve the accept.
2018-11-06 18:30:57 +01:00
William Lallemand
5d05db8ce1 MINOR: mworker: displays a message when a worker is forked
Displays the PID and the relative PID when we fork a new worker.
2018-11-06 18:30:50 +01:00
William Lallemand
91723745c6 MEDIUM: mworker: exit with the incriminated exit code
The former behavior was to exit() the master process with the latest
status code known, which was the one of the last process to exit.

The problem is that the master process was not exiting with the status
code which provoked the exit-on-failure.
2018-11-06 18:28:33 +01:00
William Lallemand
18e52a8834 MINOR: mworker: displays more information when leaving
When a worker is leaving, we display the relative PID and the result of
the strsignal() function if it was killed by a signal.
2018-11-06 18:28:33 +01:00
William Lallemand
550db6d188 MEDIUM: mworker: does not create the CLI proxy when no listener
Does not create the CLI proxy if no -S argument was specified. It
prevents a warning that says that the MASTER proxy does not have any
bind option.
2018-11-06 18:28:33 +01:00
William Lallemand
6b7cd0a72b MINOR: cli: can't connect to the target CLI
Return an error and quit if the CLI proxy is not able to connect to a
target.
2018-11-06 18:28:33 +01:00
William Lallemand
adbce8e0dd MINOR: cli: show the number of reload in 'show proc'
Displays the number of reload in the life of each worker.
2018-11-06 18:28:33 +01:00
Willy Tarreau
2d372c2aa1 MINOR: stats: report the number of currently connected peers
The active peers output indicates both the number of established peers
connections and the number of peers connection attempts. The new counter
"ConnectedPeers" also indicates the number of currently connected peers.
This helps detect that some peers cannot be reached for example. It's
worth mentioning that this value changes over time because unused peers
are often disconnected and reconnected. Most of the time it should be
equal to ActivePeers.
2018-11-05 17:15:21 +01:00
Willy Tarreau
199ad24661 MINOR: stats: report the number of active peers in "show info"
Peers are the last type of activity which can maintain a job present, so
it's important to report that such an entity is still active to explain
why the job count may be higher than zero. Here by "ActivePeers" we report
peers sessions, which include both established connections and outgoing
connection attempts.
2018-11-05 17:15:21 +01:00
Willy Tarreau
00098ea034 MINOR: stats: report the number of active jobs and listeners in "show info"
When an haproxy process doesn't stop after a reload, it's because it
still has some active "jobs", which mainly are active sessions, listeners,
peers or other specific activities. Sometimes it's difficult to troubleshoot
the cause of these issues (which generally are the result of a bug) only
because some indicators are missing.

This patch add the number of listeners, the number of jobs, and the stopping
status to the output of "show info". This way it becomes a bit easier to try
to narrow down the cause of such an issue should it happen. A typical use
case is to connect to the CLI before reloading, then issuing the "show info"
command to see what happens. In the normal situation, stopping should equal
1, jobs should equal 1 (meaning only the CLI is still active) and listeners
should equal zero.

The patch is so trivial that it could make sense to backport it to 1.8 in
order to help with troubleshooting.
2018-11-05 17:15:21 +01:00
Willy Tarreau
086735a688 BUG/MINOR: tasks: make sure wakeup events are properly reported to subscribers
The tasks API was changed in 1.9-dev1 with commit 9f6af3322 ("MINOR: tasks:
Change the task API so that the callback takes 3 arguments."), causing the
task's state not to be usable anymore and to have been replaced with an
explicit argument in the callee. The task's state doesn't contain any trace
of the wakeup cause anymore. But there were two places where the old task's
state remained in use :
  - sessions, used to more accurately report timeouts in logs when seeing
    TASK_WOKEN_TIMEOUT ;
  - peers, used to finish resynchronization when seeing TASK_WOKEN_SIGNAL

This commit fixes both occurrences by making sure we don't access task->state
directly (should we rename it by the way ?).

No backport is needed.
2018-11-05 17:15:21 +01:00
Willy Tarreau
1d0b7069f2 BUG/MAJOR: stream-int: don't call si_cs_recv() in stream_int_chk_rcv_conn()
This one causes some events to be lost. It has already been tested in
an experimental branch but was not merged until being certain it was
needed. Fred figured that requesting /?k=1&s=447392 from httpterm through
haproxy-master was enough to stall the transfer.

No backport is needed, this only affects 1.9-dev5.
2018-10-30 11:05:24 +01:00
Willy Tarreau
943e7ec025 MEDIUM: auth/threads: make use of crypt_r() on systems supporting it
On systems where crypt_r() is available, prefer it over a locked crypt().
This improves performance especially on very slow crypto algorithms.
2018-10-29 19:17:39 +01:00
Willy Tarreau
34d4b525a1 BUG/MEDIUM: auth/threads: use of crypt() is not thread-safe
It was reported here that authentication may fail when threads are
enabled :

    https://bugzilla.redhat.com/show_bug.cgi?id=1643941

While I couldn't reproduce the issue, it's obvious that there is a
problem with the use of the non-reentrant crypt() function there.
On Linux systems there's crypt_r() but not on the vast majority of
other ones. Thus a first approach consists in placing a lock around
this crypt() call. Another patch may relax it when crypt_r() is
available.

This fix must be backported to 1.8. Thanks to Ryan O'Hara for the
quick notification.
2018-10-29 18:06:02 +01:00
William Lallemand
744de5b52a BUG/MINOR: cli: forward the whole command on master CLI
A bug occurs when the CLI proxy of the master received a command which
is prefixed by some spaces but without a routing prefix (@).
In this case the pcli_parse_request() was returning a wrong number of
data to forward.

The response analyzer was called twice and the prompt displayed twice.
2018-10-29 17:23:27 +01:00
Willy Tarreau
cde1bc64cb BUG/MINOR: backend: assign the wait list after the error check
Commit 85b73e9 ("BUG/MEDIUM: stream: Make sure polling is right on retry.")
introduced a possible null dereference on the error path detected by gcc-7.
Let's simply assign srv_conn after checking the error and not before.

No backport is needed.
2018-10-28 20:36:00 +01:00
Willy Tarreau
9d9ccdbf8b BUG/MAJOR: http: http_txn_get_path() may deference an inexisting buffer
When the "path" sample fetch function is called without any path, the
function doesn't check that the request buffer is allocated. While this
doesn't happen with the request during processing, it can definitely
happen when mistakenly trying to reference a path from the response
since the request channel is not allocated anymore.

It's certain that this bug was emphasized by the buffer changes that
went in 1.9 and the HTTP refactoring, but at first glance, 1.8 doesn't
seem 100% safe either so it's possible that older version are affected
as well.

Thanks to PiBa-NL for reporting this bug with a reproducer.
2018-10-28 20:16:12 +01:00
Frdric Lcaille
e7a770ce80 MINOR: cache: Add "Age" header.
This patch makes the cache capable of adding an "Age" header as defined by
rfc7234.

During the storage of new HTTP objects we memorize ->eoh value and
the value of the "Age" header coming from the origin server.
These information may then be reused to return the cached HTTP objects
with a new "Age" header.

May be backported to 1.8.
2018-10-28 19:06:59 +01:00
William Lallemand
deeaa593f3 MINOR: cli: helper to write an response message and close
pcli_reply_and_close() writes a message to the client and close the
connection. To be used only in the CLI proxy.
2018-10-28 14:13:35 +01:00
William Lallemand
2f4ce202d7 MEDIUM: cli: write a prompt for the CLI proxy of the master
Write a prompt with the PID of the target or master.
It's always activated for now.

Example:
    1234>
    master>
2018-10-28 14:13:34 +01:00
William Lallemand
309dc9adec MEDIUM: mworker: stop the master proxy in the workers
The master proxy which handles the CLI should not be used or shown in
the stats of the workers. This proxy is now disabled after the fork.
2018-10-28 14:03:31 +01:00
William Lallemand
0b3e849a48 MEDIUM: listeners: set O_CLOEXEC on the accepted FDs
Set the O_CLOEXEC flag on the accept, useful to avoid an FD leak in the
master process, since it reexecutes itself during a reload
2018-10-28 14:03:31 +01:00
William Lallemand
4e8450b7d6 MINOR: cli: put @master @<relative pid> @!<pid> in the help
Add help for the prefix command of the CLI. These help only displays
from the CLI of the master.
2018-10-28 14:03:30 +01:00
William Lallemand
35851fbaf4 MEDIUM: cli: enable "show cli sockets" for the master
Enable the keyword on the master CLI.
2018-10-28 14:03:30 +01:00
William Lallemand
2631434b4b MINOR: cli: displays sockpair@ in "show cli sockets"
The 'show cli sockets' was not handling the sockpairs, it now displays
the fd of the socket and also show the unknown protocols.
2018-10-28 14:03:30 +01:00
William Lallemand
cf62f7e3cb MEDIUM: cli: implement 'mode cli' proxy analyzers
This patch implements analysers for parsing the CLI and extra features
for the master's CLI.

For each command (sent alone, or separated by ; or \n) the request
analyser will determine to which server it should send the request.

The 'mode cli' proxy is able to parse a prefix for each command which is
used to select the apropriate server. The prefix start by @ and is
followed by "master", the PID preceded by ! or the relative PID. (e.g.
@master, @1, @!1234). The servers are not round-robined anymore.

The command is sent with a SHUTW which force the server to close the
connection after sending its response. However the proxy allows a
keepalive connection on the client side and does not close.

The response analyser does not do much stuff, it only reinits the
connection when it received a close from the server, and forward the
response. It does not analyze the response data.
The only guarantee of the end of the response is the close of the
server, we can't rely on the double \n since it's not send by every
command.

This could be reimplemented later as a filter.
2018-10-28 14:03:06 +01:00
William Lallemand
b9f9e3bc17 MEDIUM: cli: 'show proc' displays processus
This patch implements a command which displays the current processes.

It only works in the CLI of the master.
2018-10-28 13:51:39 +01:00
William Lallemand
291810d8f8 MEDIUM: mworker: find the server ptr using a CLI prefix
Add a struct server pointer in the mworker_proc struct so we can easily
use it as a target for the mworker proxy.

pcli_prefix_to_pid() is used to find the right PID of the worker
when using a prefix in the CLI. (@master, @#<relative pid> , @<pid>)

pcli_pid_to_server() is used to find the right target server for the
CLI proxy.
2018-10-28 13:51:39 +01:00
William Lallemand
14721be11f MEDIUM: cli: disable some keywords in the master
The master process does not need all the keywords of the cli, add 2
flags to chose which keyword to use.

It might be useful to activate some of them in a debug mode later...
2018-10-28 13:51:39 +01:00
William Lallemand
e736115d3a MEDIUM: mworker: create CLI listeners from argv[]
This patch introduces mworker_cli_proxy_new_listener() which allows the
creation of new listeners for the CLI proxy.

Using this function it is possible to create new listeners from the
program arguments with -Sa <unix_socket>. It is allowed to create
multiple listeners with several -Sa.
2018-10-28 13:51:39 +01:00
William Lallemand
8a02257d88 MEDIUM: mworker: proxy for the master CLI
This patch implements a listen proxy within the master. It uses the
sockpair of all the workers as servers.

In the current state of the code, the proxy is only doing round robin on
the CLI of the workers. A CLI mode will be needed to know to which CLI
send the requests.
2018-10-28 13:51:39 +01:00
William Lallemand
1b66361f8d MEDIUM: mworker: move proc_list gen before proxies startup
We need to generate the process list before starting the proxies,
because it will be used to create a proxy in the master
2018-10-28 13:51:38 +01:00
William Lallemand
313bfd18c1 MINOR: server: export new_server() function
The new_server() function will be useful to create a proxy for the
master-worker.
2018-10-28 13:51:38 +01:00
William Lallemand
7e1299bb3a REORG: mworker: move struct mworker_proc to global.h
Move the definition of the mworker_proc structure in types/global.h.
2018-10-28 13:51:38 +01:00
William Lallemand
ce83b4a5dd MEDIUM: mworker: each worker socketpair is a CLI listener
The init code of the mworker_proc structs has been moved before the
init of the listeners.

Each socketpair is now connected to a CLI within the workers, which
allows the master to access their CLI.

The inherited flag of the worker side socketpair is removed so the
socket can be closed in the master.
2018-10-28 13:51:38 +01:00
William Lallemand
f1a62860c8 MINOR: mworker: number of reload in the life of a worker
This patch adds a field in the mworker_proc structure which contains how
much time the master reloaded during the life of a worker.
2018-10-28 13:51:38 +01:00
Willy Tarreau
908d26fd03 MINOR: stream-int: don't needlessly call si_cs_send() in si_cs_process()
There's a call there to si_cs_send() while we're supposed to come from
si_cs_io_cb() which has just done it. But in fact we can also come here
as a lower layer callback from ->wake() after a connection is established.
Since most of the time we'll end up here with either no data in the buffer
or a blocked output, let's simply check if we're already susbcribed to send
events before calling si_cs_send().
2018-10-28 13:50:02 +01:00
Willy Tarreau
0dfccb20f5 MINOR: stream-int: make stream_int_notify() not wake the tasklet up
stream_int_notify() is I/O agnostic and should not wake up the tasklet,
it's up to si_cs_process() to do that, just like si_applet_wake_cb()
does it for the applet.
2018-10-28 13:50:01 +01:00