Commit Graph

8730 Commits

Author SHA1 Message Date
Joseph Herlant
f43b88bc09 CLEANUP: Fix typos in the map management functions
Fixes typos in the code comments of the MAP management functions.
2018-12-02 18:40:38 +01:00
Joseph Herlant
8bb32ae8c6 CLEANUP: Fix typos in the socket pair protocol subsystem
Fixes typos in the code comments of the socket pair protocol subsystem.
2018-12-02 18:40:33 +01:00
Joseph Herlant
3952643b35 CLEANUP: Fix typos in the shctx subsystem
Fixes typos in the code comments of the shctx subsystem.
2018-12-02 18:40:29 +01:00
Joseph Herlant
d8499ecb6e CLEANUP: Fix a typo in the queue subsystem
Fixes a typo in the code comments of the queue subsystem.
2018-12-02 18:40:11 +01:00
Joseph Herlant
d091bfbc6f CLEANUP: Fix a typo in the session subsystem
Fixes a typo in the code comments of the session subsystem.
2018-12-02 18:39:57 +01:00
Joseph Herlant
f6989ca056 CLEANUP: Fix a typo in the signal subsystem
Fixes a typo in the code comments of the signal subsystem.
2018-12-02 18:39:52 +01:00
Joseph Herlant
a6331475e0 CLEANUP: Fix typos in the proto_tcp subsystem
Fixes typos in the code comments of the proto_tcp subsystem.
2018-12-02 18:39:05 +01:00
Joseph Herlant
e9d5c727c1 CLEANUP: Fix a typo in the proto_htx subsystem
Fixes a typo in the code comments of the proto_htx subsystem.
2018-12-02 18:38:48 +01:00
Joseph Herlant
41abef77cb CLEANUP: Fix a typo in the mini-clist header
Fixes a typo in the code comments of the mini-clist header.
2018-12-02 18:38:15 +01:00
Joseph Herlant
d77575d03e CLEANUP: Fix typos in the h2 subsystem
Fixes typos in the code comments of the h2 subsystem.
2018-12-02 18:38:08 +01:00
Joseph Herlant
30bc509c40 CLEANUP: Fix typos in the h1 subsystem
Fixes typos in the code comments of the h1 subsystem.
2018-12-02 18:38:02 +01:00
Joseph Herlant
be7619aaca CLEANUP: Fix typo in the chunk headers file
Fix a typo detected in the chunk.h header file's code comments.
2018-12-02 18:37:56 +01:00
Joseph Herlant
c42c0e9969 CLEANUP: fix typos in the htx subsystem
Fix typos detected in the code comments of the htx subsystem.
2018-12-02 18:37:50 +01:00
Olivier Houchard
0c18a6fe34 MEDIUM: servers: Add a way to keep idle connections alive.
Add a new keyword for servers, "idle-timeout". If set, unused connections are
kept alive until the timeout happens, and will be picked for reuse if no
other connection is available.
2018-12-02 18:16:53 +01:00
Olivier Houchard
8defe4b51a MINOR: mux: add a "max_streams" method.
Add a new method to muxes, "max_streams", that returns the max number of
streams the mux can handle. This will be used to know if a mux is in use
or not.
2018-12-02 17:48:32 +01:00
Olivier Houchard
f3e65b086d MINOR: connection: Fix a comment.
Connections can now have an owner for outgoing connections, so update
the comment tu reflect that.
2018-12-02 17:48:28 +01:00
Frdric Lcaille
d92ae75a90 REGTEST: Fix LEVEL 4 script 0 of "connection" module.
Prevent this script from creating a UNIX socket in ${testdir} which
is the parent directory of the script. Prefer use ${tmpdir} which
is the temporary working directory for the script.
2018-12-02 13:35:31 +01:00
Olivier Houchard
a6cf7112bb MEDIUM: mux-h2: Don't bother flagging outgoing connections as TOOMANY.
When creating a new stream, don't bother flagging a connection with
H2_CF_DEM_TOOMANY if we created the last available stream. We won't create
any other anyway, because h2_avail_streams() would return 0 available streams,
and has it is a blocking flag, it prevents us from reading data after.
2018-12-02 13:31:53 +01:00
Olivier Houchard
7a57e8a67a MEDIUM: mux-h2: Implement h2_attach().
Implement h2_attach(), so that we can have multiple streams in one outgoin
h2 connection.
2018-12-02 13:31:53 +01:00
Willy Tarreau
c12f38fe32 MEDIUM: mux-h2: make h2_process_demux() capable of processing responses as well
The function now calls h2c_bck_handle_headers() or h2c_frt_handle_headers()
depending on the connection's side. The former doesn't create a new stream
but feeds an existing one. At this point it's possible to forward an H2
request to a backend server and retrieve the response headers.
2018-12-02 13:31:52 +01:00
Willy Tarreau
c3e18f3448 MEDIUM: mux-h2: make h2_frt_decode_headers() direction-agnostic
This function does not really depend on the request, all it does is
also valid for H2 responses found on the backend side, so this patch
renames it and makes it call the appropriate decoder based on the
direction.
2018-12-02 13:31:52 +01:00
Willy Tarreau
8073969376 MEDIUM: mux-h2: implement encoding of H2 request on the backend side
This creates an H2 HEADERS frame from an HTX request. The code is
very similar to the response encoding, so probably that in the future
we'll have to factor these functions differently. The HTX's start line
type is used to decide on the direction. We also purposely error out
when trying to encode an H2 request from an H1 message since it's not
implemented.
2018-12-02 13:31:52 +01:00
Willy Tarreau
01b4482b46 MEDIUM: mux-h2: start to create the outgoing mux
For now it reports an immediate error when trying to encode the request
since it doesn't parse as a response. We take care of sending the preface
and settings frame with the outgoing connection, and not to wait for a
preface during the H2_CS_PREFACE phase for outgoing connections.
2018-12-02 13:31:51 +01:00
Willy Tarreau
751f2d0ddf MINOR: mux-h2: implement an outgoing stream allocator : h2c_bck_stream_new()
For the backend we'll need to allocate streams as well. Let's do this
with h2c_bck_stream_new(). The stream ID allocator was split from it
so that the caller can decide whether or not to stay on the same
connection or create a new one. It possibly isn't the best way to do
this as once we're on the mux it's too late to give up creation of a
new stream. Another approach would possibly consist in detaching muxes
that reached their connection count limit before they can be reused.

Instead of choosing the stream id as soon as the stream is created, wait
until data is about to be sent. If we don't do that, the stream may send
data out of order, and so the stream 3 may send data before the stream 1,
and then when the stream 1 will try to send data, the other end will
consider that an error, as stream ids should always be increased.

Cc: Olivier Houchard <ohouchard@haproxy.com>
2018-12-02 13:31:51 +01:00
Willy Tarreau
f8957277ff MINOR: mux-h2: mention that the mux is compatible with both sides
We declare two configurations for the H2 mux. One supporting only
the frontend in HTTP mode and one supporting both sides in HTX mode.

This is only to ease development at this point. Trying to assign an h2
mux on the server side will still fail during h2_init() anyway instead
of at config parsing time.
2018-12-02 13:31:03 +01:00
Willy Tarreau
1329b5be71 MINOR: h2: add new functions to produce an HTX message from an H2 response
The new function h2_prepare_htx_stsline() produces an HTX response message
from an H2 response presented as a list of header fields.
2018-12-02 13:30:17 +01:00
Willy Tarreau
a40782bb24 MINOR: hpack: add ":path" to the list of common header fields
The ":path" header field will be used a lot with outgoing requests,
let's encode it with its index.
2018-12-02 13:30:17 +01:00
Willy Tarreau
76a551de2e MINOR: config: make sure to associate the proper mux to bind and servers
Currently a mux may be forced on a bind or server line by specifying the
"proto" keyword. The problem is that the mux may depend on the proxy's
mode, which is not known when parsing this keyword, so a wrong mux could
be picked.

Let's simply update the mux entry while checking its validity. We do have
the name and the side, we only need to see if a better mux fits based on
the proxy's mode. It also requires to remove the side check while parsing
the "proto" keyword since a wrong mux could be picked.

This way it becomes possible to declare multiple muxes with the same
protocol names and different sides or modes.
2018-12-02 13:29:35 +01:00
Willy Tarreau
3fbea1d8d0 MINOR: server: the mux_proto entry in the server is const
Same as previous commit. We'll have to update this one soon, let's
avoid any cast and mark it const as it really is.
2018-12-02 13:12:16 +01:00
Willy Tarreau
5fc311c001 MINOR: connection: create conn_get_best_mux_entry()
We currently have conn_get_best_mux() to return the best mux for a
given protocol name, side and proxy mode. But we need the mux entry
as well in order to fix the bind_conf and servers at the end of the
config parsing. Let's split the function in two parts. It's worth
noting that the <conn> argument is never used anymore so this part
is eligible to some cleanup.
2018-12-02 13:12:16 +01:00
Willy Tarreau
a004ae3e66 MINOR: listener: the mux_proto entry in the bind_conf is const
We'll have to update this one soon, let's avoid any cast and mark it
const as it really is.
2018-12-02 13:12:15 +01:00
Willy Tarreau
c5753aedf7 BUG/MEDIUM: mux-h2: remove the HTX EOM block on H2 response headers
If we decided to emit the end of stream flag on the H2 response headers
frame, we must remove the EOM block from the HTX stream, otherwise it
will lead to an extra DATA frame being sent with the ES flag and will
violate the protocol.
2018-12-02 12:31:51 +01:00
Willy Tarreau
fab9bb08fc BUG/MEDIUM: mux-h2: don't lose the first response header in HTX mode
When converting response headers from HTX to H2, we accidently skipped
the first header block.
2018-12-02 12:31:20 +01:00
Christopher Faulet
bf7a9597e2 BUG/MINOR: cfgparse: Fix the call to post parser of the last sections parsed
Wrong variable was used to know if we need to call the callback
post_section_parser() or not. We must use 'cs' and not 'pcs'.

This patch must be backported in 1.8 with the commit 7805e2b ("BUG/MINOR:
cfgparse: Fix transition between 2 sections with the same name").
2018-12-02 10:21:47 +01:00
Willy Tarreau
61ea7dc005 MEDIUM: mux-h2: support passing H2 DATA frames to HTX blocks
This is used for uploads, we can now convert H2 DATA frames to HTX
DATA blocks. It's uncertain whether it's better to reuse the same
function or to split it in two at this point. For now the same
function was added with some paths specific to HTX. In this mode
we loop back to the same or next frame in order to try to complete
DATA blocks.
2018-12-01 23:31:13 +01:00
Willy Tarreau
0c535fd1b5 MEDIUM: mux-h2: implement the emission of DATA frames from HTX DATA blocks
At the moment the way it's done is not optimal. We should aggregate multiple
blocks into a single DATA frame, and we should merge the ES flag with the
last one when we already know we've reached the end. For now and for an
easier tracking of the HTX stream, an individual empty DATA frame is sent
with the ES bit when EOM is met.

The DATA function is called for DATA, EOD and EOM since these stats indicate
that a previous frame was already produced without the ES flag (typically a
headers frame or another DATA frame). Thus it makes sense to handle all these
blocks there.

There's still an uncertainty on the way the EOD and EOM HTX blocks must be
accounted for, as they're counted as one byte in the HTX stream, but if we
count that byte off when parsing these blocks, we end up sending too much
and desynchronizing the HTX stream. Maybe it hides an issue somewhere else.

At least it's possible to reliably retrieve payloads up to 1 GB over H2/HTX
now. It's still unclear why larger ones are interrupted at 1 GB.
2018-12-01 23:27:08 +01:00
Willy Tarreau
115e83b071 MEDIUM: mux-h2: implement emission of H2 headers frames from HTX blocks
When using HTX, we need a separate function to emit a headers frame.
The code is significantly different from the H1 to H2 conversion, though
it borrows some parts there. It looks like the part building the H2 frame
from the headers list could be factored out, however some of the logic
around dealing with end of stream or block sizes remains different.

With this patch it becomes possible to retrieve bodyless HTTP responses
using H2 over HTX.
2018-12-01 23:27:08 +01:00
Willy Tarreau
bd4a6b675c MEDIUM: mux-h2: add basic H2->HTX transcoding support for headers
When the proxy is configured to use HTX mode, the headers frames
will be converted to HTX header blocks instead of HTTP/1 messages.
This requires very little modifications to the existing function
so it appeared better to do it this way than to duplicate it.

Only the request headers are handled, responses are not processed
yet and data frames are not processed yet either. The return value
is inaccurate but this is not an issue since we're using it as a
boolean : data received or not.
2018-12-01 23:27:08 +01:00
Willy Tarreau
bcd3bb3ca2 MEDIUM: mux-h2: make h2_snd_buf() HTX-aware
Now h2_snd_buf() will check the proxy's mode to decide whether to use
HTX-specific send functions or legacy functions. In HTX mode, the HTX
blocks of the output buffer will be parsed and the related functions
will be called accordingly based on the block type, and unimplemented
blocks will be skipped. For now all blocks are skipped, this is only
helpful for debugging.
2018-12-01 23:27:07 +01:00
Willy Tarreau
86724e2e8a MEDIUM: mux-h2: make h2_rcv_buf() support HTX transfers
The function needs to be slightly adapted to transfer HTX blocks, since
it may face a full buffer on the receive path, thus it needs to transfer
HTX blocks between the two sides ignoring the <count> argument in this
mode.
2018-12-01 23:25:55 +01:00
Willy Tarreau
5ae9600950 MEDIUM: mux-h2: register mux for both HTTP and HTX modes
The H2 mux will now be called for both HTTP and HTX modes. For now the
data transferr functions are not HTX-aware so this will lead to problems
if used as-is but it's convenient for development and debugging.
2018-12-01 19:03:20 +01:00
Willy Tarreau
6deb4129de MINOR: h2: implement H2->HTX request header frame transcoding
Till now we could only produce an HTTP/1 request from a list of H2
request headers. Now the new function h2_make_htx_request() does the
same but using the HTX encoding instead, while respecting the H2
semantics. The code is not much different from the first version,
only the encoding differs.

For now it's not used.
2018-12-01 17:38:32 +01:00
Christopher Faulet
e6902cd57c MEDIUM: compression: Adapt to be compatible with the HTX representation
Functions analyzing request and response headers have been duplicated and
adapted to support HTX messages. The callback http_payload have been implemented
to handle the data compression itself. It loops on HTX blocks and replace
uncompressed value of DATA block by compressed one. Unlike the HTTP legacy
version, there is no chunk at all. So HTX version is significantly easier.
2018-12-01 17:37:27 +01:00
Christopher Faulet
e0aa6f7a9a MINOR: flt_trace: Adapt to be compatible with the HTX representation
The callback http_headers has been updated to dump HTX headers when the HTX
internal representation is in use. And the callback http_payload has been
implemented with its hexdump function.
2018-12-01 17:37:27 +01:00
Christopher Faulet
aed82cfb04 MEDIUM: proto_htx/filters: Add data filtering during the forwarding
If there is data filters registered on the stream, the function
flt_http_payload() is called before forwarding any data. And the function
flt_http_end() is called when all data are forwarded. While at least one data
filter reamins registered on the stream, no fast forwarding is used.
2018-12-01 17:37:27 +01:00
Christopher Faulet
75bc913d23 MAJOR: filters: Adapt filters API to be compatible with the HTX represenation
First, to be called on HTX streams, a filter must explicitly be declared as
compatible by setting the flag STRM_FLT_FL_HAS_FILTERS on the filter's config at
HAProxy startup. This flag is checked when a filter implementation is attached
to a stream.

Then, some changes have been made on HTTP callbacks. The callback http_payload
has been added to filter HTX data. It will be called on HTX streams only. It
replaces the callbacks http_data, http_chunk_trailers and http_forward_data,
called on legacy HTTP streams only and marked as deprecated. The documention
(once updated)) will give all information to implement this new callback. Other
HTTP callbacks will be called for HTX and HTTP legacy streams. So it is the
filter's responsibility to known which kind of data it handles. The macro
IS_HTX_STRM should be used in such cases.

There is at least a noticeable changes in the way data are forwarded. In HTX,
after the call to the callback http_headers, all the headers are considered as
forwarded. So, in http_payload, only the body and eventually the trailers will
be filtered.
2018-12-01 17:37:27 +01:00
Christopher Faulet
e44769b4fa MINOR: mux-h1: Capture bad H1 messages
First of all, an dedicated error snapshot, h1_snapshot, has been added. It
contains more or less the some info than http_snapshot but adapted for H1
messages. Then, the function h1_capture_bad_message() has been added to capture
bad H1 messages. And finally, the function h1_show_error_snapshot() is used to
dump these errors. Only Headers or data parsing are captured.
2018-12-01 17:37:27 +01:00
Christopher Faulet
bd44ca6ede MINOR: mux-h1: Change client conn_mode on an explicit close for the response
in h1_set_cli_conn_mode(), on the response path, If the response's connection
header is explicitly set to close and if the request is unfinished (state !=
DONE), then the client connection is marked as WANT_CLO.
2018-12-01 17:37:27 +01:00
Christopher Faulet
d1ebb1eeb5 MINOR: mux-h1: Process conn_mode on the EOH when no connection header is found
Instead of looking for a connection header just after the start line to know if
we must process the conn_mode by hand or if we wait to parse the connection
header, we now delay this processing when the end of headers is reached. A flag
is used to know if it was already done (or skipped) or not. This save a lookup
on headers.
2018-12-01 17:37:27 +01:00
Christopher Faulet
a7b677cd0d MEDIUM: proto_htx: Convert all HTTP error messages into HTX
During startup, after the configuration parsing, all HTTP error messages
(errorloc, errorfile or default messages) are converted into HTX messages and
stored in dedicated buffers. We use it to return errors in the HTX analyzers
instead of using ugly OOB blocks.
2018-12-01 17:37:27 +01:00