Commit Graph

6447 Commits

Author SHA1 Message Date
David Carlier
80ebd30c96 BUG/MINOR: contrib/mod_defender: build fix
In similar manner than modsecurity, making the build possible under *BSD flavors, the -lm for ceilf function.
2017-07-19 14:35:24 +02:00
David Carlier
0f4df640d2 BUG/MINOR: contrib/modsecurity: BSD build fix
previous version introduced in the last commit was not the correct one.
2017-07-19 14:34:31 +02:00
Christopher Faulet
a81ff60454 BUG/MINOR: http: Fix bug introduced in previous patch in http_resync_states
The previous patch ("MINOR: http: Rely on analyzers mask to end processing in
forward_body functions") contains a bug for keep-alive transactions.

For these transactions, AN_REQ_FLT_END and AN_RES_FLT_END analyzers must be
removed only when all outgoing data was forwarded.
2017-07-19 10:57:53 +02:00
Christopher Faulet
894da4c8ea MINOR: http: Rely on analyzers mask to end processing in forward_body functions
Instead of relying on request or response state, we use "chn->analysers" mask as
all other analyzers. So now, http_resync_states does not return anything
anymore.

The debug message in http_resync_states has been improved.
2017-07-18 15:24:05 +02:00
Christopher Faulet
1486b0ab6d BUG/MEDIUM: http: Switch HTTP responses in TUNNEL mode when body length is undefined
When the body length of a HTTP response is undefined, the HTTP parser is blocked
in the body parsing. Before HAProxy 1.7, in this case, because
AN_RES_HTTP_XFER_BODY is never set, there is no visible effect. When the server
closes its connection to terminate the response, HAProxy catches it as a normal
closure. Since 1.7, we always set this analyzer to enter at least once in
http_response_forward_body. But, in the present case, when the server connection
is closed, http_response_forward_body is called one time too many. The response
is correctly sent to the client, but an error is catched and logged with "SD--"
flags.

To reproduce the bug, you can use the configuration "tests/test-fsm.cfg". The
tests 3 and 21 hit the bug.

Idea to fix the bug is to switch the response in TUNNEL mode without switching
the request. This is possible because of previous patches.

First, we need to detect responses with undefined body length during states
synchronization. Excluding tunnelled transactions, when the response length is
undefined, TX_CON_WANT_CLO is always set on the transaction. So, when states are
synchronized, if TX_CON_WANT_CLO is set, the response is switched in TUNNEL mode
and the request remains unchanged.

Then, in http_msg_forward_body, we add a specific check to switch the response
in DONE mode if the body length is undefined and if there is no data filter.

This patch depends on following previous commits:

  * MINOR: http: Switch requests/responses in TUNNEL mode only by checking txn flags
  * MINOR: http: Reorder/rewrite checks in http_resync_states

This patch must be backported in 1.7 with 2 previous ones.
2017-07-18 15:22:26 +02:00
Christopher Faulet
4be9803914 MINOR: http: Switch requests/responses in TUNNEL mode only by checking txn flags
Today, the only way to have a request or a response in HTTP_MSG_TUNNEL state is
to have the flag TX_CON_WANT_TUN set on the transaction. So this is a symmetric
state. Both the request and the response are switch in same time in this
state. This can be done only by checking transaction flags instead of relying on
the other side state. This is the purpose of this patch.

This way, if for any reason we need to switch only one side in TUNNEL mode, it
will be possible. And to prepare asymmetric cases, we check channel flags in
DONE _AND_ TUNNEL states.

WARNING: This patch will be used to fix a bug. The fix will be commited in a
very next commit. So if the fix is backported, this one must be backported too.
2017-07-18 15:15:12 +02:00
Christopher Faulet
f77bb539d4 MINOR: http: Reorder/rewrite checks in http_resync_states
The previous patch removed the forced symmetry of the TUNNEL mode during the
state synchronization. Here, we take care to remove body analyzer only on the
channel in TUNNEL mode. In fact, today, this change has no effect because both
sides are switched in same time. But this way, with some changes, it will be
possible to keep body analyzer on a side (to finish the states synchronization)
with the other one in TUNNEL mode.

WARNING: This patch will be used to fix a bug. The fix will be commited in a
very next commit. So if the fix is backported, this one must be backported too.
2017-07-18 15:09:54 +02:00
Christopher Faulet
a3992e06a6 BUG/MINOR: http: Set the response error state in http_sync_res_state
This is just typo. It may only report a wrong response message state in
"show errors" on the CLI.

This patch must be backported in 1.7.
2017-07-18 15:09:10 +02:00
Willy Tarreau
7ab16868bc DOC: update the list of OpenSSL versions in the README
1.1.0 is also supported nowadays. Also mention the best effort support
for derivatives.
2017-07-18 07:01:26 +02:00
Willy Tarreau
9d84cd602f DOC: update CONTRIBUTING regarding optional parts and message format
Make it clear that optional components must not break when disabled,
that openssl is the only officially supported library and its support
must not be broken, and that bug fixes must always be detailed.
2017-07-18 06:56:40 +02:00
Thierry FOURNIER
6b546a6048 BUG/MINOR: Lua: variable already initialized
The variable strm->hlua is already initilized by the function stream_new().
2017-07-18 06:41:58 +02:00
Thierry FOURNIER
7bd10d58d3 BUG/MEDIUM: lua: bad memory access
We cannot perform garbage collection on unreferenced thread.
This memory is now free and another Lua process can use it for
other things.

HAProxy is monothread, so this bug doesn't cause crash.

This patch must be backported in 1.6 and 1.7
2017-07-18 06:41:38 +02:00
Thierry FOURNIER
b13b20a19a BUG/MAJOR: lua/socket: resources not detroyed when the socket is aborted
In some cases, the socket is misused. The user can open socket and never
close it, or open the socket and close it without sending data. This
causes resources leak on all resources associated to the stream (buffer,
spoe, ...)

This is caused by the stream_shutdown function which is called outside
of the stream execution process. Sometimes, the shtudown is required
while the stream is not started, so the cleanup is ignored.

This patch change the shutdown mode of the session. Now if the session is
no longer used and the Lua want to destroy it, it just set a destroy flag
and the session kill itself.

This patch should be backported in 1.6 and 1.7
2017-07-18 06:41:33 +02:00
Thierry FOURNIER
75d0208009 BUG/MINOR: lua: executes the function destroying the Lua session in safe mode
When we destroy the Lua session, we manipulates Lua stack,
so errors can raises. It will be better to catch these errors.

This patch should be backported in 1.6 and 1.7
2017-07-18 06:41:28 +02:00
Thierry FOURNIER
0a97620c08 BUG/MINOR: lua: In error case, the safe mode is not removed
Just forgot of reset the safe mode. This have not consequences
the safe mode just set a pointer on fucntion which is called only
and initialises a longjmp.

Out of lua execution, this longjmp is never executed and the
function is never called.

This patch should be backported in 1.6 and 1.7
2017-07-18 06:41:19 +02:00
Olivier Houchard
be7b1ce4c1 BUG/MINOR: Prevent a use-after-free on error scenario on option "-x".
This was introduced with recent commit f73629d ("MINOR: global: Add an
option to get the old listening sockets."). No backport is needed.
2017-07-18 04:22:32 +02:00
Willy Tarreau
106f631280 CLEANUP: hdr_idx: make some function arguments const where possible
Functions hdr_idx_first_idx() and hdr_idx_first_pos() were missing a
"const" qualifier on their arguments which are not modified, causing
a warning in some experimental H2 code.
2017-07-17 21:11:30 +02:00
Frdric Lcaille
ed2b4a6b79 BUG/MINOR: peers: peer synchronization issue (with several peers sections).
When several stick-tables were configured with several peers sections,
only a part of them could be synchronized: the ones attached to the last
parsed 'peers' section. This was due to the fact that, at least, the peer I/O handler
refered to the wrong peer section list, in fact always the same: the last one parsed.

The fact that the global peer section list was named "struct peers *peers"
lead to this issue. This variable name is dangerous ;).

So this patch renames global 'peers' variable to 'cfg_peers' to ensure that
no such wrong references are still in use, then all the functions wich used
old 'peers' variable have been modified to refer to the correct peer list.

Must be backported to 1.6 and 1.7.
2017-07-13 09:39:29 +02:00
Willy Tarreau
7784f1739c OPTIM: ssl: don't consider a small ssl_read() as an indication of end of buffer
In ssl_sock_to_buf(), when we face a small read, we used to consider it
as an indication for the end of incoming data, as is the case with plain
text. The problem is that here it's quite different, SSL records are
returned at once so doing so make us wake all the upper layers for each
and every record. Given that SSL records are 16kB by default, this is
rarely observed unless the protocol employs small records or the buffers
are increased. But with 64kB buffers while trying to deal with HTTP/2
frames, the exchanges are obviously suboptimal as there are two messages
per frame (one for the frame header and another one for the frame payload),
causing the H2 parser to be woken up half of the times without being able
to proceed :

   try=65536 ret=45
   try=65536 ret=16384
   try=49152 ret=9
   try=49143 ret=16384
   try=32759 ret=9
   try=32750 ret=16384
   try=16366 ret=9
   try=32795 ret=27
   try=49161 ret=9
   try=49152 ret=16384
   try=49116 ret=9
   try=49107 ret=16384
   try=32723 ret=9
   try=32714 ret=16384
   try=16330 ret=9
   try=32831 ret=63
   try=49161 ret=9
   try=49152 ret=16384
   try=49080 ret=9
   try=49071 ret=2181

With this change, the buffer can safely be filled with all pending frames
at once when they are available.
2017-07-11 17:22:12 +02:00
Willy Tarreau
a14ad72d30 BUG/MINOR: http: properly handle all 1xx informational responses
Only 100 was considered informational instead of all 1xx. This can be
a problem when facing a 102 ("progress") or with the upcoming 103 for
early hints. Let's properly handle all 1xx now, leaving a special case
for 101 which is used for the upgrade.

This fix should be backported to 1.7, 1.6 and 1.5. In 1.4 the code is
different but the backport should be made there as well.
2017-07-07 11:36:32 +02:00
Frdric Lcaille
37a72546f6 MINOR: peers: Add additional information to stick-table definition messages.
With this patch additional information are added to stick-table definition
messages so that to make external application capable of learning peer
stick-table configurations. First stick-table entries duration is added
followed by the frequency counters type IDs and values.

May be backported to 1.7 and 1.6.
2017-07-07 10:24:44 +02:00
Christopher Faulet
570f799877 BUG/MEDIUM: filters: Be sure to call flt_end_analyze for both channels
In the commit 2b553de5 ("BUG/MINOR: filters: Don't force the stream's wakeup
when we wait in flt_end_analyze"), we removed a task_wakeup in flt_end_analyze
to no consume too much CPU by looping in certain circumstances.

But this fix was too drastic. For Keep-Alive transactions, flt_end_analyze is
often called only for the response. Then the stream is paused until a timeout is
hitted or the next request is received. We need first let a chance to both
channels to call flt_end_analyze function. Then if a filter need to wait here,
it is its responsibility to wake up the stream when needed. To fix the bug, and
thanks to previous commits, we set the flag CF_WAKE_ONCE on channels to pretend
there is an activity. On the current channel, the flag will be removed without
any effect, but for the other side the analyzer will be called immediatly.

Thanks for Lukas Tribus for his detailed analysis of the bug.

This patch must be backported in 1.7 with the 2 previous ones:

  * a94fda3 ("BUG/MINOR: http: Don't reset the transaction if there are still data to send")
  * cdaea89 ("BUG/MINOR: stream: Don't forget to remove CF_WAKE_ONCE flag on response channel")
2017-07-06 23:07:36 +02:00
Christopher Faulet
a94fda30bd BUG/MINOR: http: Don't reset the transaction if there are still data to send
To reset an HTTP transaction, we need to be sure all data were sent, for the
request and the response. There are tests on request and response buffers for
that in http_resync_states function. But the return code was wrong. We must
return 0 to wait.

This patch must be backported in 1.7
2017-07-06 23:06:57 +02:00
Christopher Faulet
cdaea89a0c BUG/MINOR: stream: Don't forget to remove CF_WAKE_ONCE flag on response channel
This flag can be set on a channel to pretend there is activity on it. This is a
way to wake-up the corresponding stream and evaluate stream analyzers on the
channel. It is correctly handled on both channels but removed only on the
request channel.

This patch is flagged as a bug but for now, CF_WAKE_ONCE is never set on the
response channel.
2017-07-06 23:06:47 +02:00
Willy Tarreau
2ab88675ec MINOR: ssl: compare server certificate names to the SNI on outgoing connections
When support for passing SNI to the server was added in 1.6-dev3, there
was no way to validate that the certificate presented by the server would
really match the name requested in the SNI, which is quite a problem as
it allows other (valid) certificates to be presented instead (when hitting
the wrong server or due to a man in the middle).

This patch adds the missing check against the value passed in the SNI.
The "verifyhost" value keeps precedence if set. If no SNI is used and
no verifyhost directive is specified, then the certificate name is not
checked (this is unchanged).

In order to extract the SNI value, it was necessary to make use of
SSL_SESSION_get0_hostname(), which appeared in openssl 1.1.0. This is
a trivial function which returns the value of s->tlsext_hostname, so
it was provided in the compat layer for older versions. After some
refinements from Emmanuel, it now builds with openssl 1.0.2, openssl
1.1.0 and boringssl. A test file was provided to ease testing all cases.

After some careful observation period it may make sense to backport
this to 1.7 and 1.6 as some users rightfully consider this limitation
as a bug.

Cc: Emmanuel Hocdet <manu@gandi.net>
Signed-off-by: Willy Tarreau <w@1wt.eu>
2017-07-06 15:15:28 +02:00
Emeric Brun
96fd926ccc BUG/MAJOR: http: fix buffer overflow on loguri buffer.
The pool used to log the uri was created with a size of 0 because the
configuration and 'tune.http.logurilen' were parsed too earlier.

The fix consist to postpone the pool_create as it is done for
cookie captures.

Regression introduced with 'MINOR: log: Add logurilen tunable'
2017-07-05 13:59:29 +02:00
Emeric Brun
7d27f3c12d BUG/MEDIUM: map/acl: fix unwanted flags inheritance.
The bug: Maps/ACLs using the same file/id can mistakenly inherit
their flags from the last declared one.

i.e.

    $ cat haproxy.conf
    listen mylistener
	mode http
	bind 0.0.0.0:8080

	acl myacl1 url -i -f mine.acl
	acl myacl2 url -f mine.acl
	acl myacl3 url -i -f mine.acl
	redirect location / if myacl2
    $ cat mine.acl
    foobar

Shows an unexpected redirect for request 'GET /FOObAR HTTP/1.0\n\n'.

This fix should be backported on mainline branches v1.6 and v1.7.
2017-07-04 10:45:53 +02:00
Jarno Huuskonen
e0ee0be4e7 DOC: fix references to the section about time format.
Time format is documented in section 2.4, not 2.2.
2017-07-04 10:05:21 +02:00
Emeric Brun
2802b07d97 BUG/MAJOR: applet: fix a freeze if data is immedately forwarded.
Introduced regression with 'MAJOR: applet scheduler rework' (1.8-dev only).

The fix consist to re-enable the appctx immediatly from the
applet wake cb if the process_stream is not pending in runqueue
and the applet want perform a put or a get and the WAIT_ROOM
flag was removed by stream_int_notify.
2017-06-30 14:57:24 +02:00
Christopher Faulet
a03d4ada26 MINOR: compression: Use a memory pool to allocate compression states
Instead of doing a malloc/free to each HTTP transaction to allocate the
compression state (when the HTTP compression is enabled), we use a memory pool.
2017-06-30 14:05:29 +02:00
Christopher Faulet
d60b3cf431 BUG/MAJOR: compression: Be sure to release the compression state in all cases
This patch fixes an obvious memory leak in the compression filter. The
compression state (comp_state) is allocated when a HTTP transaction starts, in
channel_start_analyze callback, Whether we are able to compression the response
or not. So it must be released when the transaction ends, in channel_end_analyze
callback.

But there is a bug here. The state is released on the response side only. So, if
a transaction ends before the response is started, it is never released. This
happens when a connection is closed before the response is started.

To fix the bug, statistics about the HTTP compression are now updated in
http_end callback, when the response parsing ends.  It happens only if no error
is encountered and when the response is compressed. So, it is safe to release
the compression state in channel_end_analyze callback, regardless the
channel's type.

This patch must be backported in 1.7.
2017-06-30 14:05:29 +02:00
Emeric Brun
8d85aa44da BUG/MAJOR: map: fix segfault during 'show map/acl' on cli.
The reference of the current map/acl element to dump could
be destroyed if map is updated from an 'http-request del-map'
configuration rule or throught a 'del map/acl' on CLI.

We use a 'back_refs' chaining element to fix this. As it
is done to dump sessions.

This patch needs also fix:
'BUG/MAJOR: cli: fix custom io_release was crushed by NULL.'

To clean the back_ref and avoid a crash on a further
del/clear map operation.

Those fixes should be backported on mainline branches 1.7 and 1.6.

This patch wont directly apply on 1.6.
2017-06-30 06:49:42 +02:00
Emeric Brun
d6871f785f BUG/MAJOR: cli: fix custom io_release was crushed by NULL.
The io_release could be set into the parsing request handler
and must not be crushed.

This patch should be backported on mainline branches 1.7 and 1.6
2017-06-30 06:49:31 +02:00
Willy Tarreau
27f2dbbdfd BUG/MAJOR: frontend: don't dereference a null conn on outgoing connections
Recently merged commit 0cfe388 ("MINOR: frontend: retrieve the ALPN name when
available") assumed that the connection is always known in frontend_accept()
which is not true for outgoing peers connections for example.

No backport needed.
2017-06-27 15:47:56 +02:00
Emeric Brun
c730606879 MAJOR: applet: applet scheduler rework.
In order to authorize call of appctx_wakeup on running task:
- from within the task handler itself.
- in futur, from another thread.

The appctx is considered paused as default after running the handler.

The handler should explicitly call appctx_wakeup to be re-called.

When the appctx_free is called on a running handler. The real
free is postponed at the end of the handler process.
2017-06-27 14:38:02 +02:00
Willy Tarreau
57ec32fb99 MINOR: connection: send data before receiving
It's more efficient this way, as it allows to flush a send buffer before
receiving data in the other one. This can lead to a slightly faster buffer
recycling, thus slightly less memory and a small performance increase by
using a hotter cache.
2017-06-27 14:38:02 +02:00
Willy Tarreau
d62b98c6e8 MINOR: stream: don't set backend's nor response analysers on SF_TUNNEL
In order to implement hot-pluggable applets like we'll need for HTTP/2
which will speak a different protocol than the expected one, it will be
mandatory to be able to clear all analysers from the request and response
channel and/or to keep only the ones the applet initializer installed.

Unfortunately for now in sess_establish() we systematically place a number
of analysers inherited from the frontend, backend and some hard-coded ones.

This patch reuses the now unused SF_TUNNEL flag on the stream to indicate
we're dealing with a tunnel and don't want to add more analysers anymore.
It will be usable to install such a specific applet.

Ideally over the long term it might be nice to be able to set the mode on
the stream instead of the proxy so that we can decide to change a stream's
mode (eg: TCP, HTTP, HTTP/2) at run time. But it would require many more
changes for a gain which is not yet obvious.
2017-06-27 14:38:02 +02:00
Willy Tarreau
9c26680eb9 MINOR: frontend: report the connection's ALPN in the debug output
Now the incoming connection will also report the ALPN field, truncated
to 15 characters.
2017-06-27 14:38:02 +02:00
Willy Tarreau
0cfe3887de MINOR: frontend: retrieve the ALPN name when available
Here we try to retrieve the negociated ALPN on the front connection.
This will be used to decide whether or not we want to switch to H2.
2017-06-27 14:38:02 +02:00
Willy Tarreau
8743f7e567 MINOR: ssl: add a get_alpn() method to ssl_sock
This is used to retrieve the TLS ALPN information from a connection. We
also support a fallback to NPN if ALPN doesn't find anything or is not
available on the existing implementation. It happens that depending on
the library version, either one or the other is available. NPN was
present in openssl 1.0.1 (very common) while ALPN is in 1.0.2 and onwards
(still uncommon at the time of writing). Clients are used to send either
one or the other to ensure a smooth transition.
2017-06-27 14:38:02 +02:00
Willy Tarreau
a9c1741820 MINOR: connection: add a .get_alpn() method to xprt_ops
This will be used to retrieve the ALPN negociated over SSL (or possibly
via the proxy protocol later). It's likely that this information should
be stored in the connection itself, but it requires adding an extra
pointer and an extra integer. Thus better rely on the transport layer
to pass this info for now.
2017-06-27 14:38:02 +02:00
Willy Tarreau
0a6bed2394 MINOR: frontend: initialize HTTP layer after the debugging code
For HTTP/2 we'll have to choose the upper layer based on the
advertised protocol name here and we want to keep debugging,
so let's move debugging earlier.
2017-06-27 14:38:02 +02:00
Willy Tarreau
9b82d941c5 MEDIUM: stream: make stream_new() always set the target and analysers
It doesn't make sense that stream_new() doesn't sets the target nor
analysers and that the caller has to do it even if it doesn't know
about streams (eg: in session_accept_fd()). This causes trouble for
H2 where the applet handling the protocol cannot properly change
these information during its init phase.

Let's ensure it's always set and that the callers don't set it anymore.

Note: peers and lua don't use analysers and that's properly handled.
2017-06-27 14:38:02 +02:00
Christopher Faulet
f3a55dbd22 MINOR: queue: Change pendconn_from_srv/pendconn_from_px into private functions 2017-06-27 14:38:02 +02:00
Christopher Faulet
f0614e8111 MINOR: backends: Change get_server_sh/get_server_uh into private function 2017-06-27 14:38:02 +02:00
Christopher Faulet
87566c923b MINOR: queue: Change pendconn_get_next_strm into private function 2017-06-27 14:38:02 +02:00
Emeric Brun
5f77fef34e MINOR: task/stream: tasks related to a stream must be init by the caller.
The task_wakeup was called on stream_new, but the task/stream
wasn't fully initialized yet. The task_wakeup must be called
explicitly by the caller once the task/stream is initialized.
2017-06-27 14:38:02 +02:00
Emeric Brun
0194897e54 MAJOR: task: task scheduler rework.
In order to authorize call of task_wakeup on running task:
- from within the task handler itself.
- in futur, from another thread.

The lookups on runqueue and waitqueue are re-worked
to prepare multithread stuff.

If task_wakeup is called on a running task, the woken
message flags are savec in the 'pending_state' attribute of
the state. The real wakeup is postponed at the end of the handler
process and the woken messages are copied from pending_state
to the state attribute of the task.

It's important to note that this change will cause a very minor
(though measurable) performance loss but it is necessary to make
forward progress on a multi-threaded scheduler. Most users won't
ever notice.
2017-06-27 14:38:02 +02:00
Emeric Brun
ff4491726f BUG/MINOR: stream: flag TASK_WOKEN_RES not set if task in runqueue
Under certain circumstances, if a stream's task is first woken up
(eg: I/O event) then notified of the availability of a buffer it
was waiting for via stream_res_wakeup(), this second event is lost
because the flags are only merged after seeing that the task is
running. At the moment it seems that the TASK_WOKEN_RES event is
not explicitly checked for, but better fix this before getting
reports of lost events.

This fix removes this "task running" test which is properly
performed in task_wakeup(), while the flags are properly merged.

It must be backported to 1.7 and 1.6.
2017-06-27 14:37:52 +02:00
Willy Tarreau
1af20c7161 DOC: fix references to the section about the unix socket
The unix socket is documented in 9.3, not 9.2 of the management guide.

This should be backported to 1.7.
2017-06-23 16:04:12 +02:00