]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
11 years agoMEDIUM: proxy: make findproxy() use trees to look up proxies
Willy Tarreau [Sat, 15 Mar 2014 06:43:51 +0000 (07:43 +0100)] 
MEDIUM: proxy: make findproxy() use trees to look up proxies

Both proxy IDs and names are now looked up from the trees.

11 years agoMEDIUM: proxy: create a tree to store proxies by name
Willy Tarreau [Sat, 15 Mar 2014 06:22:35 +0000 (07:22 +0100)] 
MEDIUM: proxy: create a tree to store proxies by name

Large configurations can take time to parse when thousands of backends
are in use. Let's store all the proxies in trees.

findproxy_mode() has been modified to use the tree for lookups, which
has divided the parsing time by about 2.5. But many lookups are still
present at many places and need to be dealt with.

11 years agoMINOR: protect ebimtree/ebistree against multiple inclusions
Willy Tarreau [Sat, 15 Mar 2014 06:43:05 +0000 (07:43 +0100)] 
MINOR: protect ebimtree/ebistree against multiple inclusions

These two files were missing the usual #ifndef around the code.
(cherry picked from commit f2873b23705ff08ca3ab4f1a6b27050e572e1d9e)

11 years agoMINOR: http: release compression context only in http_end_txn()
Willy Tarreau [Tue, 11 Mar 2014 14:48:55 +0000 (15:48 +0100)] 
MINOR: http: release compression context only in http_end_txn()

Currently there are two places where the compression context is released,
one in session_free() and another one in http_end_txn_clean_session().
Both of them call http_end_txn(), either directly or via http_reset_txn(),
and this function is made for this exact purpose. So let's centralize the
call there instead.

11 years agoBUG/MEDIUM: http: don't start to forward request data before the connect
Willy Tarreau [Wed, 12 Mar 2014 09:41:13 +0000 (10:41 +0100)] 
BUG/MEDIUM: http: don't start to forward request data before the connect

Currently, "balance url_param check_post" randomly works. If the client
sends chunked data and there's another chunk after the one containing the
data, http_request_forward_body() will advance msg->sov and move the start
of data to the beginning of the last chunk, and get_server_ph_post() will
not find the data.

In order to avoid this, we add an HTTP_MSGF_WAIT_CONN flag whose goal is
to prevent the forwarding code from parsing until the connection is
confirmed, so that we're certain not to fail on a redispatch. Note that
we need to force channel_auto_connect() since the output buffer is empty
and a previous analyser might have stopped auto-connect.

The flag is currently set whenever some L7 POST analysis is needed for a
connect() so that it correctly addresses all corner cases involving a
possible rewind of the buffer, waiting for a better fix.

Note that this has been broken for a very long time. Even all 1.4 versions
seem broken but differently, with ->sov pointing to the end of the arguments.
So the fix should be considered for backporting to all stable releases,
possibly including 1.3 which works differently.

11 years agoBUG/MINOR: log: The log of quotted capture header has been terminated by 2 quotes.
Thierry FOURNIER [Thu, 13 Mar 2014 15:55:01 +0000 (16:55 +0100)] 
BUG/MINOR: log: The log of quotted capture header has been terminated by 2 quotes.

Julien Vehent repport that the log format '%{+Q}hr' display the value
termnated by two chars '"' like this: '"value""'. This patch just remove
the second quote.

This bug is old but 1.5-specific but users of older 1.5 versions may be
interested in a backport.

11 years agoBUG/MEDIUM: map: The map parser includes blank lines.
Thierry FOURNIER [Wed, 26 Feb 2014 17:30:13 +0000 (18:30 +0100)] 
BUG/MEDIUM: map: The map parser includes blank lines.

The parser check the end line comparing to the null character.
In fact, the end of line can be also '\r' or '\n'.

The effect is that empty lines are loaded and indexed in maps.

The bug was introduced by commit d5f624dd ("MEDIUM: sample:
add the "map" converter") in 1.5-dev20. No backport is needed.

11 years agoBUG/MEDIUM: compression: fix the output type of the compressor name
Willy Tarreau [Tue, 11 Mar 2014 15:23:05 +0000 (16:23 +0100)] 
BUG/MEDIUM: compression: fix the output type of the compressor name

smp_fetch_res_comp_algo() returns the name of the compression algorithm
in use. The output type is set to SMP_T_STR instead of SMP_T_CSTR, which
causes any transformation to be operated without a cast. Fortunately,
the current converters do not overwrite a zero-sized area, so the result
is an empty string. Fix this to have SMP_T_CSTR instead so that the cast
is always performed using a copy before any transformation is done.

11 years agoBUG/MINOR: raw_sock: also consider ENOTCONN in addition to EAGAIN for recv()
Joshua M. Clulow [Mon, 3 Mar 2014 21:48:42 +0000 (13:48 -0800)] 
BUG/MINOR: raw_sock: also consider ENOTCONN in addition to EAGAIN for recv()

I was testing haproxy-1.5-dev22 on SmartOS (an illumos-based system)
and ran into a problem.  There's a small window after non-blocking
connect() is called, but before the TCP connection is established,
where recv() may return ENOTCONN.  On Linux, the behaviour here seems
to be always to return EAGAIN.  The fix is relatively trivial, and
appears to make haproxy work reliably on current SmartOS (see patch
below).  It's possible that other UNIX platforms exhibit this
behaviour as well.

Note: the equivalent was already done for send() in commit 0ea0cf6
("BUG: raw_sock: also consider ENOTCONN in addition to EAGAIN").
Both patches should be backported to 1.4.

11 years agoMINOR: set IP_FREEBIND on IPv6 sockets in transparent mode
Lukas Tribus [Mon, 3 Mar 2014 20:10:51 +0000 (21:10 +0100)] 
MINOR: set IP_FREEBIND on IPv6 sockets in transparent mode

Lets set IP_FREEBIND on IPv6 sockets as well, this works since Linux 3.3
and doesn't require CAP_NET_ADMIN privileges (IPV6_TRANSPARENT does).

This allows unprivileged users to bind to non-local IPv6 addresses, which
can be useful when setting up the listening sockets or when connecting
to backend servers with a specific, non-local source IPv6 address (at that
point we usually dropped root privileges already).

11 years agoBUG/MINOR: config: fix a crash on startup when a disabled backend references a peer
Willy Tarreau [Mon, 24 Feb 2014 19:59:47 +0000 (20:59 +0100)] 
BUG/MINOR: config: fix a crash on startup when a disabled backend references a peer

Disabled backends don't have their symbols resolved. We must not initialize
their peers section since they're not valid and instead still contain the
section's name.

There are other places where such unions are still in use, and other similar
errors might still happen. Ideally we should get rid of all of them in the
quite sensible config stage.

11 years agoMEDIUM: acl: fix pattern type for payload / payload_lv
Willy Tarreau [Mon, 24 Feb 2014 17:55:33 +0000 (18:55 +0100)] 
MEDIUM: acl: fix pattern type for payload / payload_lv

Since commit 0ce3aa0c ("MEDIUM: acl: implement payload and payload_lv"),
the payload and payload_lv ACL patterns were declared as strings because
at this date there was no support for binary patterns. At this time, these
ACLs were not reliably usable due to the binary-to-string cast involved,
and because it was not possible to specify the direction of the match.

Since recent evolutions, the new fetch methods "req.payload" and
"res.payload" have leveraged the ambiguity and were of type "binary",
with an implicit ACL mapping of the same type. The doc also states
that "payload" is an alias for "req.payload" etc... while these two
don't share the same type.

Better fix this mess before it's too late. "payload" and "payload_lv"
return a binary content, so their ACLs must by default use a binary
pattern. That way they behave like their "req." and "res." sisters.

This change might break some configs making use of these, but there's
almost a zero probability that anyone managed to use them to match
exact strings, so in practice the change should be safe.

11 years agoBUG/MEDIUM: http: continue to emit 503 on keep-alive to different server
Willy Tarreau [Mon, 24 Feb 2014 17:26:30 +0000 (18:26 +0100)] 
BUG/MEDIUM: http: continue to emit 503 on keep-alive to different server

Finn Arne Gangstad reported that commit 6b726adb35 ("MEDIUM: http: do
not report connection errors for second and further requests") breaks
support for serving static files by abusing the errorfile 503 statement.

Indeed, a second request over a connection sent to any server or backend
returning 503 would silently be dropped.

The proper solution consists in adding a flag on the session indicating
that the server connection was reused, and to only avoid the error code
in this case.

11 years agoBUG/MEDIUM: backend: prefer-last-server breaks redispatch
Willy Tarreau [Wed, 19 Feb 2014 17:40:43 +0000 (18:40 +0100)] 
BUG/MEDIUM: backend: prefer-last-server breaks redispatch

Since 1.5-dev20, we have a working server-side keep-alive and an option
"prefer-last-server" to indicate that we explicitly want to reuse the
same server as the last one. Unfortunately this breaks the redispatch
feature because assign_server() insists on reusing the same server as
the first one attempted even if the connection failed to establish.

A simple solution consists in only considering the last connection if
it was connected. Otherwise there is no reason for being interested in
reusing the same server.

11 years agoDOC: fix a typo on http-server-close and encapsulate options with double-quotes
Cyril Bonté [Wed, 19 Feb 2014 23:13:15 +0000 (00:13 +0100)] 
DOC: fix a typo on http-server-close and encapsulate options with double-quotes

Add a missing "r" on "option http-server-close" and put double-quotes
everywhere to ease keywords parsing.

11 years agoBUG/MINOR: config: server on-marked-* statement is ignored in default-server
Willy Tarreau [Tue, 18 Feb 2014 09:36:15 +0000 (10:36 +0100)] 
BUG/MINOR: config: server on-marked-* statement is ignored in default-server

Commits e0d1bfb ("[MINOR] Allow shutdown of sessions when a server
becomes unavailable") and eb2c24a ("MINOR: checks: add on-marked-up
option") mentionned that the directive was supported in default-server
but while it can be stated there, it's ignored because the config value
is not copied from the default server upon creation of a new server.
Moving the statement to the "server" lines works fine though. Thanks
to Baptiste Assmann for reporting and diagnosing this bug.

These features were introduced in 1.5-dev6 and 1.5-dev10 respectively,
so no backport is needed.

11 years agoBUG/MEDIUM: ssl: always send a full buffer after EAGAIN
Willy Tarreau [Mon, 17 Feb 2014 14:43:01 +0000 (15:43 +0100)] 
BUG/MEDIUM: ssl: always send a full buffer after EAGAIN

Igor Chan reported a very interesting bug which was triggered by the
recent dynamic size change in SSL.

The OpenSSL API refuses to send less data than any failed previous
attempt. So what's happening is that if an SSL_write() in streaming
mode sends 5kB of data and the openssl layer cannot send them all,
it returns SSL_ERROR_WANT_WRITE, which haproxy reacts to by enabling
polling on the file descriptor. In the mean time, haproxy may detect
that the buffer was almost full and will disable streaming mode. Upon
write notification, it will try to send again, but less data this
time (limited to tune.ssl_max_record). OpenSSL disagrees with this
and returns a generic error SSL_ERROR_SSL.

The solution which was found consists in adding a flag to the SSL
context to remind that we must not shrink writes after a failed
attempt. Thus, if EAGAIN is encountered, the next send() will not
be limited in order to retry the same size as before.

11 years agoMEDIUM: ssl: Use ALPN support as it will be available in OpenSSL 1.0.2
Dirkjan Bussink [Thu, 13 Feb 2014 11:29:42 +0000 (12:29 +0100)] 
MEDIUM: ssl: Use ALPN support as it will be available in OpenSSL 1.0.2

The current ALPN support is based on custom OpenSSL patches. These are
however not the same as what has landed on OpenSSL:

http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=6f017a8f9db3a79f3a3406cf8d493ccd346db691

This patch change the code so it supports ALPN as it will be part of
OpenSSL.

11 years agoBUG/MINOR: ssl: fix syntax in config error message
Willy Tarreau [Sun, 16 Feb 2014 18:22:08 +0000 (19:22 +0100)] 
BUG/MINOR: ssl: fix syntax in config error message

Some error messages about server lines had a confusing '|' instead
of '[' to delimit the config file name.

11 years agoBUG/MEDIUM: config: immediately abort if peers section has no name
Willy Tarreau [Sun, 16 Feb 2014 07:20:13 +0000 (08:20 +0100)] 
BUG/MEDIUM: config: immediately abort if peers section has no name

Cyril Bonté reported that despite commit 0dbbf317 which attempted
to fix the crash when a peers section has no name, we still get a
segfault after the error message when parsing the peers. The reason
is that the returned error code is ERR_FATAL and not ERR_ABORT, so
the parsing continues while the section was not initialized.

This is 1.5-specific, no backport is needed.

11 years agoBUG/MEDIUM: peers: fix key consistency for integer stick tables
Cyril Bonté [Sun, 16 Feb 2014 00:07:07 +0000 (01:07 +0100)] 
BUG/MEDIUM: peers: fix key consistency for integer stick tables

Peers with integer stick tables are breaking the keys received. This is due to
the fact that the sender converts the key with htonl() but the receiver doesn't
convert the value back to its original format.

Peers appeared in haproxy-1.5, no backport is needed.

11 years agoMINOR: sample: add a rand() sample fetch to return a sample.
Willy Tarreau [Fri, 14 Feb 2014 10:59:04 +0000 (11:59 +0100)] 
MINOR: sample: add a rand() sample fetch to return a sample.

Sometimes it can be useful to generate a random value, at least
for debugging purposes, but also to take routing decisions or to
pass such a value to a backend server.

11 years agoMINOR: config: add global directives to set default SSL ciphers
Willy Tarreau [Thu, 13 Feb 2014 10:36:41 +0000 (11:36 +0100)] 
MINOR: config: add global directives to set default SSL ciphers

The ability to globally override the default client and server cipher
suites has been requested multiple times since the introduction of SSL.
This commit adds two new keywords to the global section for this :
  - ssl-default-bind-ciphers
  - ssl-default-server-ciphers

It is still possible to preset them at build time by setting the macros
LISTEN_DEFAULT_CIPHERS and CONNECT_DEFAULT_CIPHERS.

11 years agoMINOR: config: make the stream interface idle timer user-configurable
Willy Tarreau [Wed, 12 Feb 2014 15:35:14 +0000 (16:35 +0100)] 
MINOR: config: make the stream interface idle timer user-configurable

The new tune.idletimer value allows one to set a different value for
idle stream detection. The default value remains set to one second.
It is possible to disable it using zero, and to change the default
value at build time using DEFAULT_IDLE_TIMER.

11 years agoMINOR: ssl: add DEFAULT_SSL_MAX_RECORD to set the record size at build time
Willy Tarreau [Wed, 12 Feb 2014 13:55:41 +0000 (14:55 +0100)] 
MINOR: ssl: add DEFAULT_SSL_MAX_RECORD to set the record size at build time

For some deployments it may help to have tune.ssl.maxrecord set to a
more efficient one at build time. This build setting allows this.

11 years agoMEDIUM: stream-int: automatically disable CF_STREAMER flags after idle
Willy Tarreau [Sun, 9 Feb 2014 16:47:01 +0000 (17:47 +0100)] 
MEDIUM: stream-int: automatically disable CF_STREAMER flags after idle

Disabling the streamer flags after an idle period will help TCP proxies
to better adapt to the streams they're forwarding, especially with SSL
where this will allow the SSL sender to use smaller records. This is
typically used to optimally relay HTTP and derivatives such as SPDY or
HTTP/2 in pure TCP mode when haproxy is used as an SSL offloader.

This idea was first proposed by Ilya Grigorik on the haproxy mailing
list, and his tests seem to confirm the improvement :

  https://www.mail-archive.com/haproxy@formilux.org/msg12576.html

11 years agoMINOR: channel: add the date of last read in the channel
Willy Tarreau [Sun, 9 Feb 2014 16:45:16 +0000 (17:45 +0100)] 
MINOR: channel: add the date of last read in the channel

We store the time stamp of last read in the channel in order to
be able to measure some bit rate and pause lengths. We only use
16 bits which were unused for this. We don't need more, as it
allows us to measure with a millisecond precision for up to 65s.

11 years agoBUG/MINOR: channel: initialize xfer_small/xfer_large on new buffers
Willy Tarreau [Sun, 9 Feb 2014 07:31:49 +0000 (08:31 +0100)] 
BUG/MINOR: channel: initialize xfer_small/xfer_large on new buffers

These ones are only reset during transfers. There is a low but non-null
risk that a first full read causes the previous value to be reused and
immediately to immediately set the CF_STREAMER flag. The impact is only
to increase earlier than expected the SSL record size and to use splice().

This bug was already present in 1.4, so a backport is possible.

11 years agoBUG/MAJOR: check: fix memory leak in "tcp-check connect" over SSL
Willy Tarreau [Tue, 11 Feb 2014 16:53:37 +0000 (17:53 +0100)] 
BUG/MAJOR: check: fix memory leak in "tcp-check connect" over SSL

tcp-check must not reinitialize the SSL stack upon each check!
It's done once after the config parsing and leaks memory and eats
performance when done upon every check.

This bug was introduced in 1.5-dev22, no backport is needed.

11 years agoBUG/MEDIUM: stats: the "lastsess" field must appear last in the CSV.
Willy Tarreau [Mon, 10 Feb 2014 21:22:49 +0000 (22:22 +0100)] 
BUG/MEDIUM: stats: the "lastsess" field must appear last in the CSV.

It happens that latest change broke some monitoring tools which expect the
field to be found at the same position as indicated in the doc. Let's move
it to the last column instead.

11 years agoMINOR: stats: report exact last session time in backend too
Willy Tarreau [Sat, 8 Feb 2014 23:50:01 +0000 (00:50 +0100)] 
MINOR: stats: report exact last session time in backend too

I forgot to remove one human_time() in the CSV output for the backend's
lastsess entry in previous patch, which caused the value to be reported
as "1m18s" for example instead of 78.

11 years agoMINOR: stats: Enhancement to stats page to provide information of last session time.
Bhaskar Maddala [Mon, 3 Feb 2014 21:26:46 +0000 (16:26 -0500)] 
MINOR: stats: Enhancement to stats page to provide information of last session time.

Summary:
Track and report last session time on the stats page for each server
in every backend, as well as the backend.

This attempts to address the requirement in the ROADMAP

  - add a last activity date for each server (req/resp) that will be
    displayed in the stats. It will be useful with soft stop.

The stats page reports this as time elapsed since last session. This
change does not adequately address the requirement for long running
session (websocket, RDP... etc).

11 years agoOPTIM: ssl: implement dynamic record size adjustment
Willy Tarreau [Sun, 2 Feb 2014 01:00:24 +0000 (02:00 +0100)] 
OPTIM: ssl: implement dynamic record size adjustment

By having the stream interface pass the CF_STREAMER flag to the
snd_buf() primitive, we're able to tell the send layer whether
we're sending large chunks or small ones.

We use this information in SSL to adjust the max record dynamically.
This results in small chunks respecting tune.ssl.maxrecord at the
beginning of a transfer or for small transfers, with an automatic
switch to full records if the exchanges last long. This allows the
receiver to parse HTML contents on the fly without having to retrieve
16kB of data, which is even more important with small initcwnd since
the receiver does not need to wait for round trips to start fetching
new objects. However, sending large files still produces large chunks.

For example, with tune.ssl.maxrecord = 2859, we see 5 write(2885)
sent in two segments each and 6 write(16421).

This idea was first proposed on the haproxy mailing list by Ilya Grigorik.

11 years agoMEDIUM: connection: don't use real send() flags in snd_buf()
Willy Tarreau [Sun, 2 Feb 2014 00:51:17 +0000 (01:51 +0100)] 
MEDIUM: connection: don't use real send() flags in snd_buf()

This prevents us from passing other useful info and requires the
upper levels to know these flags. Let's use a new flags category
instead : CO_SFL_*. For now, only MSG_MORE has been remapped.

11 years agoBUG/MEDIUM: checks: immediately report a connection success
Willy Tarreau [Wed, 5 Feb 2014 17:31:24 +0000 (18:31 +0100)] 
BUG/MEDIUM: checks: immediately report a connection success

When no check type is configured (so the basic connection check), we
want the connection success to be immediately reported. Unfortunately,
it did not happen because in this case the connection is not registered
for read nor for write, and the wake_srv() callback does not handle this
case where no data transfer was requested. However, having option tcp-check
hides this problem because the check type follows a different setup mode,
by having check->type != 0 and the connection believing it must try to
send data.

The effect was that without any option, checks would succeed only at the
end of the check interval. So let's just add the wake-up condition.

This bug appeared with the recent polling changes, no backport is needed.
As a workaround, using "option tcp-check" fixes the problem.

11 years agoMINOR: http: optimize capture.req.method and capture.req.uri
William Lallemand [Tue, 4 Feb 2014 23:30:02 +0000 (00:30 +0100)] 
MINOR: http: optimize capture.req.method and capture.req.uri

Useless strncpy were done in those two sample fetches, the
"struct chunk" allows us to dump the specified len.

The encode_string() in capture.req.uri was judged inappropriate and was
deleted.

The return type was fixed to SMP_T_CSTR.

11 years agoMINOR: session: clean up the connection free code
Willy Tarreau [Tue, 4 Feb 2014 23:18:47 +0000 (00:18 +0100)] 
MINOR: session: clean up the connection free code

Use conn_free() instead of pool_free2(conn...). This makes the code more
auditable.

11 years agoBUG/MINOR: tcpcheck connect wrong behavior
Baptiste Assmann [Mon, 3 Feb 2014 21:38:15 +0000 (22:38 +0100)] 
BUG/MINOR: tcpcheck connect wrong behavior

A typo made first step of a tcpcheck to be a connect step. This patch
prevents this behavior. The bug was introduced in 1.5-dev22 with
"tcp-check connect" and only affects these directives. No backport is
needed.

11 years agoMINOR: http: capture.req.method and capture.req.uri
William Lallemand [Fri, 31 Jan 2014 14:08:02 +0000 (15:08 +0100)] 
MINOR: http: capture.req.method and capture.req.uri

Add 2 sample fetchs allowing to extract the method and the uri of an
HTTP request.

FIXME: the sample fetches parser can't add the LW_REQ requirement, at
the moment this flag is used automatically when you use sample fetches.

Note: also fixed the alphabetical order of other capture.req.* keywords
in the doc.

11 years agoDOC: add some information on capture.(req|res).hdr
William Lallemand [Tue, 4 Feb 2014 20:04:21 +0000 (21:04 +0100)] 
DOC: add some information on capture.(req|res).hdr

Clarify the beginning of the index.

11 years ago[RELEASE] Released version 1.5-dev22 v1.5-dev22
Willy Tarreau [Sun, 2 Feb 2014 23:41:29 +0000 (00:41 +0100)] 
[RELEASE] Released version 1.5-dev22

Released version 1.5-dev22 with the following main changes :
    - MEDIUM: tcp-check new feature: connect
    - MEDIUM: ssl: Set verify 'required' as global default for servers side.
    - MINOR: ssl: handshake optim for long certificate chains.
    - BUG/MINOR: pattern: pattern comparison executed twice
    - BUG/MEDIUM: map: segmentation fault with the stats's socket command "set map ..."
    - BUG/MEDIUM: pattern: Segfault in binary parser
    - MINOR: pattern: move functions for grouping pat_match_* and pat_parse_* and add documentation.
    - MINOR: standard: The parse_binary() returns the length consumed and his documentation is updated
    - BUG/MINOR: payload: the patterns of the acl "req.ssl_ver" are no parsed with the good function.
    - BUG/MEDIUM: pattern: "pat_parse_dotted_ver()" set bad expect_type.
    - BUG/MINOR: sample: The c_str2int converter does not fail if the entry is not an integer
    - BUG/MEDIUM: http/auth: Sometimes the authentication credentials can be mix between two requests
    - MINOR: doc: Bad cli function name.
    - MINOR: http: smp_fetch_capture_header_* fetch captured headers
    - BUILD: last release inadvertently prepended a "+" in front of the date
    - BUG/MEDIUM: stream-int: fix the keep-alive idle connection handler
    - BUG/MEDIUM: backend: do not re-initialize the connection's context upon reuse
    - BUG: Revert "OPTIM/MEDIUM: epoll: fuse active events into polled ones during polling changes"
    - BUG/MINOR: checks: successful check completion must not re-enable MAINT servers
    - MINOR: http: try to stick to same server after status 401/407
    - BUG/MINOR: http: always disable compression on HTTP/1.0
    - OPTIM: poll: restore polling after a poll/stop/want sequence
    - OPTIM: http: don't stop polling for read on the client side after a request
    - BUG/MEDIUM: checks: unchecked servers could not be enabled anymore
    - BUG/MEDIUM: stats: the web interface must check the tracked servers before enabling
    - BUG/MINOR: channel: CHN_INFINITE_FORWARD must be unsigned
    - BUG/MINOR: stream-int: do not clear the owner upon unregister
    - MEDIUM: stats: add support for HTTP keep-alive on the stats page
    - BUG/MEDIUM: stats: fix HTTP/1.0 breakage introduced in previous patch
    - Revert "MEDIUM: stats: add support for HTTP keep-alive on the stats page"
    - MAJOR: channel: add a new flag CF_WAKE_WRITE to notify the task of writes
    - OPTIM: session: set the READ_DONTWAIT flag when connecting
    - BUG/MINOR: http: don't clear the SI_FL_DONT_WAKE flag between requests
    - MINOR: session: factor out the connect time measurement
    - MEDIUM: session: prepare to support earlier transitions to the established state
    - MEDIUM: stream-int: make si_connect() return an established state when possible
    - MINOR: checks: use an inline function for health_adjust()
    - OPTIM: session: put unlikely() around the freewheeling code
    - MEDIUM: config: report a warning when multiple servers have the same name
    - BUG: Revert "OPTIM: poll: restore polling after a poll/stop/want sequence"
    - BUILD/MINOR: listener: remove a glibc warning on accept4()
    - BUG/MAJOR: connection: fix mismatch between rcv_buf's API and usage
    - BUILD: listener: fix recent accept4() again
    - BUG/MAJOR: ssl: fix breakage caused by recent fix abf08d9
    - BUG/MEDIUM: polling: ensure we update FD status when there's no more activity
    - MEDIUM: listener: fix polling management in the accept loop
    - MINOR: protocol: improve the proto->drain() API
    - MINOR: connection: add a new conn_drain() function
    - MEDIUM: tcp: report in tcp_drain() that lingering is already disabled on close
    - MEDIUM: connection: update callers of ctrl->drain() to use conn_drain()
    - MINOR: connection: add more error codes to report connection errors
    - MEDIUM: tcp: report connection error at the connection level
    - MEDIUM: checks: make use of chk_report_conn_err() for connection errors
    - BUG/MEDIUM: unique_id: HTTP request counter is not stable
    - DOC: fix misleading information about SIGQUIT
    - BUG/MAJOR: fix freezes during compression
    - BUG/MEDIUM: stream-interface: don't wake the task up before end of transfer
    - BUILD: fix VERDATE exclusion regex
    - CLEANUP: polling: rename "spec_e" to "state"
    - DOC: add a diagram showing polling state transitions
    - REORG: polling: rename "spec_e" to "state" and "spec_p" to "cache"
    - REORG: polling: rename "fd_spec" to "fd_cache"
    - REORG: polling: rename the cache allocation functions
    - REORG: polling: rename "fd_process_spec_events()" to "fd_process_cached_events()"
    - MAJOR: polling: rework the whole polling system
    - MAJOR: connection: remove the CO_FL_WAIT_{RD,WR} flags
    - MEDIUM: connection: remove conn_{data,sock}_poll_{recv,send}
    - MEDIUM: connection: add check for readiness in I/O handlers
    - MEDIUM: stream-interface: the polling flags must always be updated in chk_snd_conn
    - MINOR: stream-interface: no need to call fd_stop_both() on error
    - MEDIUM: connection: no need to recheck FD state
    - CLEANUP: connection: use conn_ctrl_ready() instead of checking the flag
    - CLEANUP: connection: use conn_xprt_ready() instead of checking the flag
    - CLEANUP: connection: fix comments in connection.h to reflect new behaviour.
    - OPTIM: raw-sock: don't speculate after a short read if polling is enabled
    - MEDIUM: polling: centralize polled events processing
    - MINOR: polling: create function fd_compute_new_polled_status()
    - MINOR: cli: add more information to the "show info" output
    - MEDIUM: listener: add support for limiting the session rate in addition to the connection rate
    - MEDIUM: listener: apply a limit on the session rate submitted to SSL
    - REORG: stats: move the stats socket states to dumpstats.c
    - MINOR: cli: add the new "show pools" command
    - BUG/MEDIUM: counters: flush content counters after each request
    - BUG/MEDIUM: counters: fix stick-table entry leak when using track-sc2 in connection
    - MINOR: tools: add very basic support for composite pointers
    - MEDIUM: counters: stop relying on session flags at all
    - BUG/MINOR: cli: fix missing break in command line parser
    - BUG/MINOR: config: correctly report when log-format headers require HTTP mode
    - MAJOR: http: update connection mode configuration
    - MEDIUM: http: make keep-alive + httpclose be passive mode
    - MAJOR: http: switch to keep-alive mode by default
    - BUG/MEDIUM: http: fix regression caused by recent switch to keep-alive by default
    - BUG/MEDIUM: listener: improve detection of non-working accept4()
    - BUILD: listener: add fcntl.h and unistd.h
    - BUG/MINOR: raw_sock: correctly set the MSG_MORE flag

11 years agoMEDIUM: tcp-check new feature: connect
Baptiste Assmann [Tue, 10 Dec 2013 23:52:19 +0000 (00:52 +0100)] 
MEDIUM: tcp-check new feature: connect

A new tcp-check rule type: connect.
It allows HAProxy to test applications which stand on multiple ports or
multiple applications load-balanced through the same backend.

11 years agoBUG/MINOR: raw_sock: correctly set the MSG_MORE flag
Willy Tarreau [Sun, 2 Feb 2014 00:44:13 +0000 (01:44 +0100)] 
BUG/MINOR: raw_sock: correctly set the MSG_MORE flag

Due to a typo, the MSG_MORE flag used to replace MSG_NOSIGNAL and
MSG_DONTWAIT. Fortunately, sockets are always marked non-blocking,
so the loss of MSG_DONTWAIT is harmless, and the NOSIGNAL is covered
by the interception of the SIGPIPE. So no issue could have been
caused by this bug.

11 years agoMINOR: ssl: handshake optim for long certificate chains.
Emeric Brun [Tue, 28 Jan 2014 14:43:53 +0000 (15:43 +0100)] 
MINOR: ssl: handshake optim for long certificate chains.

Suggested on the mailing list by Ilya Grigorik and greatly inspired
from Nginx code: we try to dynamicaly rise the output buffer size from
4k to 16k during the handshake to reduce the number of round trips.
This is mostly beneficial when initcwnd==10.

Ilya's tests confirm the gain and show a handshake time divided by 3 :

before:
   http://www.webpagetest.org/result/140116_VW_3bd95a5cfb7e667498ef13b59639b9bf/2/details/
after:
   http://www.webpagetest.org/result/140201_2X_03511ec63344f442b81c24d2bf39f59d/3/details/

11 years agoBUILD: listener: add fcntl.h and unistd.h
Willy Tarreau [Sat, 1 Feb 2014 08:28:36 +0000 (09:28 +0100)] 
BUILD: listener: add fcntl.h and unistd.h

Otherwise it fails to build on some platforms.

11 years agoBUG/MEDIUM: listener: improve detection of non-working accept4()
Willy Tarreau [Fri, 31 Jan 2014 18:40:19 +0000 (19:40 +0100)] 
BUG/MEDIUM: listener: improve detection of non-working accept4()

On ARM, glibc does not implement accept4() and simply returns ENOSYS
which was not caught as a reason to fall back to accept(), resulting
in a spinning process since poll() would call again.

Let's change the error detection mechanism to save the broken status
of the syscall into a local variable that is used to fall back to the
legacy accept().

In addition to this, since the code was becoming a bit messy, the
accept4() was removed, so now the fallback code and the legacy code
are the same. This will also increase bug report accuracy if needed.

This is 1.5-specific, no backport is needed.

11 years agoBUG/MEDIUM: http: fix regression caused by recent switch to keep-alive by default
Willy Tarreau [Fri, 31 Jan 2014 14:45:34 +0000 (15:45 +0100)] 
BUG/MEDIUM: http: fix regression caused by recent switch to keep-alive by default

Yesterday's commit 70dffda ("MAJOR: http: switch to keep-alive mode by default")
broke HTTP/1.0 handling without keep-alive when keep-alive is enabled both in
the frontend and in the backend.

Before this patch, it used to work because tunnel mode was the default one,
so if no mode was present in the frontend and a mode was set in the backend,
the backend was the first one to parse the header. This is what the original
patch tried to do with keep-alive by default, causing the version and the
connection header to be ignored if both the frontend and the backend were
running in keep-alive mode.

The fix consists in always parsing the header in non-tunnel mode, and
processing the rest of the logic in at least once, and again if the
backend works in a different mode than the frontend.

This is 1.5-specific, no backport is needed.

11 years agoMINOR: doc: Bad cli function name.
Thierry FOURNIER [Wed, 29 Jan 2014 19:40:18 +0000 (20:40 +0100)] 
MINOR: doc: Bad cli function name.

The documentation describe a "disable" function,  but "enable" is
writed.

11 years agoBUG/MEDIUM: http/auth: Sometimes the authentication credentials can be mix between...
Thierry FOURNIER [Thu, 23 Jan 2014 11:13:02 +0000 (12:13 +0100)] 
BUG/MEDIUM: http/auth: Sometimes the authentication credentials can be mix between two requests

The authentication function "get_http_auth()" extract credentials from
the request and keep it this values in shared cache. This function set
a flag in the session indicating that the authentication is already
parsed and the value stored in the cache are avalaible. If this flag is
set the authorization header is not re-parsed and the shared cache is
used.

If two request are simultaneous processsed, the first one check the
credentials. After this, the second request check also it's credentials
and change the data stored in the shared cache. When the first request
re-check credentials (for many reasons), they are changed. The change
can introduce a segfault.

This patch deactivate the cache upon success. When we need
authentication information from one request, they are re-parsed and
re-decoded. However, a failure to retrieve credentials is still
cached to avoid useless lookups.

This fix needs to be backported to 1.4 as well.

11 years agoMAJOR: http: switch to keep-alive mode by default
Willy Tarreau [Thu, 30 Jan 2014 02:07:23 +0000 (03:07 +0100)] 
MAJOR: http: switch to keep-alive mode by default

Since we support HTTP keep-alive, there is no more reason for staying
in tunnel mode by default. It is confusing for new users and creates
more issues than it solves. Option "http-tunnel" is available to force
to use it if really desired.

Switching to KA by default has implied to change the value of some
option flags and some transaction flags so that value zero (default)
matches keep-alive. That explains why more code has been changed than
expected. Tests have been run on the 25 combinations of frontend and
backend options, plus a few with option http-pretend-keepalive, and
no anomaly was found.

The relation between frontend and backends remains the same. Options
have been updated to take precedence over http-keep-alive which is now
implicit.

All references in the doc to haproxy not supporting keep-alive have
been fixed, and the doc for config options has been updated.

11 years agoMEDIUM: http: make keep-alive + httpclose be passive mode
Willy Tarreau [Wed, 29 Jan 2014 23:51:42 +0000 (00:51 +0100)] 
MEDIUM: http: make keep-alive + httpclose be passive mode

There's no particular reason for having keep-alive + httpclose combine
into forceclose when set in different frontend/backend sections, since
keep-alive does not close anything by default. Let's have this still
combination remain httpclose only.

11 years agoMAJOR: http: update connection mode configuration
Willy Tarreau [Wed, 29 Jan 2014 23:15:28 +0000 (00:15 +0100)] 
MAJOR: http: update connection mode configuration

At the very beginning of haproxy, there was "option httpclose" to make
haproxy add a "Connection: close" header in both directions to invite
both sides to agree on closing the connection. It did not work with some
rare products, so "option forceclose" was added to do the same and actively
close the connection. Then client-side keep-alive was supported, so option
http-server-close was introduced. Now we have keep-alive with a fourth
option, not to mention the implicit tunnel mode.

The connection configuration has become a total mess because all the
options above may be combined together, despite almost everyone thinking
they cancel each other, as judging from the common problem reports on the
mailing list. Unfortunately, re-reading the doc shows that it's not clear
at all that options may be combined, and the opposite seems more obvious
since they're compared. The most common issue is options being set in the
defaults section that are not negated in other sections, but are just
combined when the user expects them to be overloaded. The migration to
keep-alive by default will only make things worse.

So let's start to address the first problem. A transaction can only work in
5 modes today :
  - tunnel : haproxy doesn't bother with what follows the first req/resp
  - passive close : option http-close
  - forced close : option forceclose
  - server close : option http-server-close with keep-alive on the client side
  - keep-alive   : option http-keep-alive, end to end

All 16 combination for each section fall into one of these cases. Same for
the 256 combinations resulting from frontend+backend different modes.

With this patch, we're doing something slightly different, which will not
change anything for users with valid configs, and will only change the
behaviour for users with unsafe configs. The principle is that these options
may not combined anymore, and that the latest one always overrides all the
other ones, including those inherited from the defaults section. The "no
option xxx" statement is still supported to cancel one option and fall back
to the default one. It is mainly needed to ignore defaults sections (eg:
force the tunnel mode). The frontend+backend combinations have not changed.

So for examplen the following configuration used to put the connection
into forceclose :

    defaults http
        mode http
        option httpclose

    frontend foo.
        option http-server-close

  => http-server-close+httpclose = forceclose before this patch! Now
     the frontend's config replaces the defaults config and results in
     the more expected http-server-close.

All 25 combinations of the 5 modes in (frontend,backend) have been
successfully tested.

In order to prepare for upcoming changes, a new "option http-tunnel" was
added. It currently only voids all other options, and has the lowest
precedence when mixed with another option in another frontend/backend.

11 years agoMEDIUM: ssl: Set verify 'required' as global default for servers side.
Emeric Brun [Wed, 29 Jan 2014 11:24:34 +0000 (12:24 +0100)] 
MEDIUM: ssl: Set verify 'required' as global default for servers side.

If no CA file specified on a server line, the config parser will show an error.

Adds an cmdline option '-dV' to re-set verify 'none' as global default on
servers side (previous behavior).

Also adds 'ssl-server-verify' global statement to set global default to
'none' or 'required'.

WARNING: this changes the default verify mode from "none" to "required" on
the server side, and it *will* break insecure setups.

11 years agoBUG/MINOR: config: correctly report when log-format headers require HTTP mode
Willy Tarreau [Wed, 29 Jan 2014 13:39:58 +0000 (14:39 +0100)] 
BUG/MINOR: config: correctly report when log-format headers require HTTP mode

When using some log-format directives in header insertion without HTTP mode,
the config parser used to report a cryptic message about option httplog being
downgraded to tcplog and with "(null):0" as the file name and line number.

This is because the lfs_file and lfs_line were not properly set for some valid
use cases of log-format directives. Now we cover http-request and http-response
as well.

11 years agoBUG/MINOR: cli: fix missing break in command line parser
Willy Tarreau [Wed, 29 Jan 2014 11:13:39 +0000 (12:13 +0100)] 
BUG/MINOR: cli: fix missing break in command line parser

Yesterday's commit 12833bb ("MINOR: cli: add the new "show pools" command")
missed a "break" statement causing trouble to the "show map" command. Spotted
by Thierry Fournier.

11 years agoMEDIUM: counters: stop relying on session flags at all
Willy Tarreau [Tue, 28 Jan 2014 22:18:23 +0000 (23:18 +0100)] 
MEDIUM: counters: stop relying on session flags at all

Till now, we had one flag per stick counter to indicate if it was
tracked in a backend or in a frontend. We just had to add another
flag per stick-counter to indicate if it relies on contents or just
connection. These flags are quite painful to maintain and tend to
easily conflict with other flags if their number is changed.

The correct solution consists in moving the flags to the stkctr struct
itself, but currently this struct is made of 2 pointers, so adding a
new entry there to store only two bits will cause at least 16 more bytes
to be eaten per counter due to alignment issues, and we definitely don't
want to waste tens to hundreds of bytes per session just for things that
most users don't use.

Since we only need to store two bits per counter, an intermediate
solution consists in replacing the entry pointer with a composite
value made of the original entry pointer and the two flags in the
2 unused lower bits. If later a need for other flags arises, we'll
have to store them in the struct.

A few inline functions have been added to abstract the retrieval
and assignment of the pointers and flags, resulting in very few
changes. That way there is no more dependence on the number of
stick-counters and their position in the session flags.

11 years agoMINOR: tools: add very basic support for composite pointers
Willy Tarreau [Tue, 28 Jan 2014 22:04:39 +0000 (23:04 +0100)] 
MINOR: tools: add very basic support for composite pointers

Very often we want to associate one or two flags to a pointer, to
put a type on it or whatever. This patch provides this in standard.h
in the form of a few inline functions which combine a void * pointer
with an int and return an unsigned long called a composite address.
The functions allow to individuall set, retrieve both the pointer and
the flags. This is very similar to what is used in ebtree in fact.

11 years agoBUG/MEDIUM: counters: fix stick-table entry leak when using track-sc2 in connection
Willy Tarreau [Tue, 28 Jan 2014 21:48:24 +0000 (22:48 +0100)] 
BUG/MEDIUM: counters: fix stick-table entry leak when using track-sc2 in connection

In 1.5-dev19, commit e25c917 ("MEDIUM: counters: add support for tracking
a third counter") introduced the third track counter. However, there was
a hard-coded test in the accept() error path to release only sc0 and sc1.
So it seems that if tracking sc2 at the connection level and deciding to
reject once the track-sc2 has been done, there could be some leaking of
stick-table entries which remain marked used forever, thus which can never
be purged nor expired. There's no memory leak though, it's just that
entries are unexpirable forever.

The simple solution consists in removing the test and always calling
the inline function which iterates over all entries.

11 years agoBUG/MEDIUM: counters: flush content counters after each request
Willy Tarreau [Tue, 28 Jan 2014 20:40:28 +0000 (21:40 +0100)] 
BUG/MEDIUM: counters: flush content counters after each request

One year ago, commit 5d5b5d8 ("MEDIUM: proto_tcp: add support for tracking
L7 information") brought support for tracking L7 information in tcp-request
content rules. Two years earlier, commit 0a4838c ("[MEDIUM] session-counters:
correctly unbind the counters tracked by the backend") used to flush the
backend counters after processing a request.

While that earliest patch was correct at the time, it became wrong after
the second patch was merged. The code does what it says, but the concept
is flawed. "TCP request content" rules are evaluated for each HTTP request
over a single connection. So if such a rule in the frontend decides to
track any L7 information or to track L4 information when an L7 condition
matches, then it is applied to all requests over the same connection even
if they don't match. This means that a rule such as :

     tcp-request content track-sc0 src if { path /index.html }

will count one request for index.html, and another one for each of the
objects present on this page that are fetched over the same connection
which sent the initial matching request.

Worse, it is possible to make the code do stupid things by using multiple
counters:

     tcp-request content track-sc0 src if { path /foo }
     tcp-request content track-sc1 src if { path /bar }

Just sending two requests first, one with /foo, one with /bar, shows
twice the number of requests for all subsequent requests. Just because
both of them persist after the end of the request.

So the decision to flush backend-tracked counters was not the correct
one. In practice, what is important is to flush countent-based rules
since they are the ones evaluated for each request.

Doing so requires new flags in the session however, to keep track of
which stick-counter was tracked by what ruleset. A later change might
make this easier to maintain over time.

This bug is 1.5-specific, no backport to stable is needed.

11 years agoMINOR: http: smp_fetch_capture_header_* fetch captured headers
William Lallemand [Tue, 28 Jan 2014 17:14:25 +0000 (18:14 +0100)] 
MINOR: http: smp_fetch_capture_header_* fetch captured headers

Allows you to fetch a captured header content with capture.res.hdr()
and capture.req.hdr().

11 years agoMINOR: cli: add the new "show pools" command
Willy Tarreau [Tue, 28 Jan 2014 15:49:56 +0000 (16:49 +0100)] 
MINOR: cli: add the new "show pools" command

show pools
  Dump the status of internal memory pools. This is useful to track memory
  usage when suspecting a memory leak for example. It does exactly the same
  as the SIGQUIT when running in foreground except that it does not flush
  the pools.

11 years agoREORG: stats: move the stats socket states to dumpstats.c
Willy Tarreau [Tue, 28 Jan 2014 15:27:17 +0000 (16:27 +0100)] 
REORG: stats: move the stats socket states to dumpstats.c

There is no more usage of these values outside of dumpstats.c, and
they're easier to maintain there. Also replace the #defines with an
enum.

11 years agoMEDIUM: listener: apply a limit on the session rate submitted to SSL
Willy Tarreau [Mon, 7 Oct 2013 18:01:52 +0000 (20:01 +0200)] 
MEDIUM: listener: apply a limit on the session rate submitted to SSL

Just like the previous commit, we sometimes want to limit the rate of
incoming SSL connections. While it can be done for a frontend, it was
not possible for a whole process, which makes sense when multiple
processes are running on a system to server multiple customers.

The new global "maxsslrate" setting is usable to fix a limit on the
session rate going to the SSL frontends. The limits applies before
the SSL handshake and not after, so that it saves the SSL stack from
expensive key computations that would finally be aborted before being
accounted for.

The same setting may be changed at run time on the CLI using
"set rate-limit ssl-session global".

11 years agoMEDIUM: listener: add support for limiting the session rate in addition to the connec...
Willy Tarreau [Mon, 7 Oct 2013 16:51:07 +0000 (18:51 +0200)] 
MEDIUM: listener: add support for limiting the session rate in addition to the connection rate

It's sometimes useful to be able to limit the connection rate on a machine
running many haproxy instances (eg: per customer) but it removes the ability
for that machine to defend itself against a DoS. Thus, better also provide a
limit on the session rate, which does not include the connections rejected by
"tcp-request connection" rules. This permits to have much higher limits on
the connection rate without having to raise the session rate limit to insane
values.

The limit can be changed on the CLI using "set rate-limit sessions global",
or in the global section using "maxsessrate".

11 years agoMINOR: cli: add more information to the "show info" output
Willy Tarreau [Tue, 28 Jan 2014 14:19:44 +0000 (15:19 +0100)] 
MINOR: cli: add more information to the "show info" output

In addition to previous outputs, we also emit the cumulated number of
connections, the cumulated number of requests, the maximum allowed
SSL connection concurrency, the current number of SSL connections and
the cumulated number of SSL connections. This will help troubleshoot
systems which experience memory shortage due to SSL.

11 years agoBUG/MINOR: sample: The c_str2int converter does not fail if the entry is not an integer
Thierry FOURNIER [Mon, 27 Jan 2014 17:20:48 +0000 (18:20 +0100)] 
BUG/MINOR: sample: The c_str2int converter does not fail if the entry is not an integer

If the string not start with a number, the converter fails. In other, it
converts a maximum of characters to a number and stop to the first
character that not match a number.

11 years agoBUG/MEDIUM: pattern: "pat_parse_dotted_ver()" set bad expect_type.
Thierry FOURNIER [Mon, 27 Jan 2014 15:04:43 +0000 (16:04 +0100)] 
BUG/MEDIUM: pattern: "pat_parse_dotted_ver()" set bad expect_type.

This is a regression introducted by the patches "MINOR: pattern: Each
pattern sets the expected input type" and "MEDIUM: acl: Last patch
change the output type". The expected value is SMP_T_CSTR in place of
SMP_T_UINT.

This bug impact all the acl using the parser "pat_parse_dotted_ver()".
The two acl are "req_ssl_ver()" and "req.ssl_ver()".

This is a recent bug, no backport is needed.

11 years agoMINOR: polling: create function fd_compute_new_polled_status()
Willy Tarreau [Sat, 25 Jan 2014 09:32:56 +0000 (10:32 +0100)] 
MINOR: polling: create function fd_compute_new_polled_status()

This function is used to compute the new polling state based on
the previous state. All pollers have to do this in their update
loop, so better centralize the logic for it.

11 years agoMEDIUM: polling: centralize polled events processing
Willy Tarreau [Sat, 25 Jan 2014 08:58:06 +0000 (09:58 +0100)] 
MEDIUM: polling: centralize polled events processing

Currently, each poll loop handles the polled events the same way,
resulting in a lot of duplicated, complex code. Additionally, epoll
was the only one to handle newly created FDs immediately.

So instead, let's move that code to fd.c in a new function dedicated
to this task : fd_process_polled_events(). All pollers now use this
function.

11 years agoOPTIM: raw-sock: don't speculate after a short read if polling is enabled
Willy Tarreau [Thu, 23 Jan 2014 23:54:27 +0000 (00:54 +0100)] 
OPTIM: raw-sock: don't speculate after a short read if polling is enabled

This is the reimplementation of the "done" action : when we experience
a short read, we're almost certain that we've exhausted the system's
buffers and that we'll meet an EAGAIN if we attempt to read again. If
the FD is not yet polled, the stream interface already takes care of
stopping the speculative read. When the FD is already being polled, we
have two options :
  - either we're running from a level-triggered poller, in which case
    we'd rather report that we've reached the end so that we don't
    speculate over the poller and let it report next time data are
    available ;

  - or we're running from an edge-triggered poller in which case we
    have no choice and have to see the EAGAIN to re-enable events.

At the moment we don't have any edge-triggered poller, so it's desirable
to avoid speculative I/O that we know will fail.

Note that this must not be ported to SSL since SSL hides the real
readiness of the file descriptor.

Thanks to this change, we observe no EAGAIN anymore during keep-alive
transfers, and failed recvfrom() are reduced by half in http-server-close
mode (the client-facing side is always being polled and the second recv
can be avoided). Doing so results in about 5% performance increase in
keep-alive mode. Similarly, we used to have up to about 1.6% of EAGAIN
on accept() (1/maxaccept), and these have completely disappeared under
high loads.

11 years agoCLEANUP: connection: fix comments in connection.h to reflect new behaviour.
Willy Tarreau [Thu, 23 Jan 2014 14:26:18 +0000 (15:26 +0100)] 
CLEANUP: connection: fix comments in connection.h to reflect new behaviour.

The polling has substantially changed, better fix the comments.

11 years agoCLEANUP: connection: use conn_xprt_ready() instead of checking the flag
Willy Tarreau [Thu, 23 Jan 2014 13:21:42 +0000 (14:21 +0100)] 
CLEANUP: connection: use conn_xprt_ready() instead of checking the flag

It's easier and safer to rely on conn_xprt_ready() everywhere than to
check the flag itself. It will also simplify adding extra checks later
if needed. Some useless controls for !xprt have been removed, as the
XPRT_READY flag itself guarantees xprt is set.

11 years agoCLEANUP: connection: use conn_ctrl_ready() instead of checking the flag
Willy Tarreau [Thu, 23 Jan 2014 12:50:42 +0000 (13:50 +0100)] 
CLEANUP: connection: use conn_ctrl_ready() instead of checking the flag

It's easier and safer to rely on conn_ctrl_ready() everywhere than to
check the flag itself. It will also simplify adding extra checks later
if needed. Some useless controls for !ctrl have been removed, as the
CTRL_READY flag itself guarantees ctrl is set.

11 years agoMEDIUM: connection: no need to recheck FD state
Willy Tarreau [Tue, 21 Jan 2014 10:01:08 +0000 (11:01 +0100)] 
MEDIUM: connection: no need to recheck FD state

We already have everything in the connection flags using the
CO_FL_DATA_*_ENA bits combined with the fd's ready state, so
we do not need to check fdtab[fd].ev anymore. This considerably
simplifies the connection handling logic since it doesn't
have to mix connection flags with past polling states.

11 years agoMINOR: stream-interface: no need to call fd_stop_both() on error
Willy Tarreau [Tue, 21 Jan 2014 09:30:08 +0000 (10:30 +0100)] 
MINOR: stream-interface: no need to call fd_stop_both() on error

We don't need to call fd_stop_both() since we already call
conn_cond_update_polling() which will do it. This call was introduced by
commit d29a066 ("BUG/MAJOR: connection: always recompute polling status
upon I/O").

11 years agoMEDIUM: stream-interface: the polling flags must always be updated in chk_snd_conn
Willy Tarreau [Tue, 21 Jan 2014 09:27:49 +0000 (10:27 +0100)] 
MEDIUM: stream-interface: the polling flags must always be updated in chk_snd_conn

We used to only update the polling flags in data phase, but after that
we could update other flags. It does not seem possible to trigger a
bug here but it's not very safe either. Better always keep them up to
date.

11 years agoMEDIUM: connection: add check for readiness in I/O handlers
Willy Tarreau [Mon, 20 Jan 2014 14:13:07 +0000 (15:13 +0100)] 
MEDIUM: connection: add check for readiness in I/O handlers

The recv/send callbacks must check for readiness themselves instead of
having their callers do it. This will strengthen the test and will also
ensure we never refrain from calling a handshake handler because a
direction is being polled while the other one is ready.

11 years agoMEDIUM: connection: remove conn_{data,sock}_poll_{recv,send}
Willy Tarreau [Wed, 22 Jan 2014 19:02:06 +0000 (20:02 +0100)] 
MEDIUM: connection: remove conn_{data,sock}_poll_{recv,send}

We simply remove these functions and replace their calls with the
appropriate ones :

  - if we're in the data phase, we can simply report wait on the FD
  - if we're in the socket phase, we may also have to signal the
    desire to read/write on the socket because it might not be
    active yet.

11 years agoMAJOR: connection: remove the CO_FL_WAIT_{RD,WR} flags
Willy Tarreau [Wed, 22 Jan 2014 18:46:33 +0000 (19:46 +0100)] 
MAJOR: connection: remove the CO_FL_WAIT_{RD,WR} flags

These flags were used to report the readiness of the file descriptor.
Now this readiness is directly checked at the file descriptor itself.
This removes the need for constantly synchronizing updates between the
file descriptor and the connection and ensures that all layers share
the same level of information.

For now, the readiness is updated in conn_{sock,data}_poll_* by directly
touching the file descriptor. This must move to the lower layers instead
so that these functions can disappear as well. In this state, the change
works but is incomplete. It's sensible enough to avoid making it more
complex.

Now the sock/data updates become much simpler because they just have to
enable/disable access to a file descriptor and not to care anymore about
its readiness.

11 years agoMAJOR: polling: rework the whole polling system
Willy Tarreau [Fri, 10 Jan 2014 15:58:45 +0000 (16:58 +0100)] 
MAJOR: polling: rework the whole polling system

This commit heavily changes the polling system in order to definitely
fix the frequent breakage of SSL which needs to remember the last
EAGAIN before deciding whether to poll or not. Now we have a state per
direction for each FD, as opposed to a previous and current state
previously. An FD can have up to 8 different states for each direction,
each of which being the result of a 3-bit combination. These 3 bits
indicate a wish to access the FD, the readiness of the FD and the
subscription of the FD to the polling system.

This means that it will now be possible to remember the state of a
file descriptor across disable/enable sequences that generally happen
during forwarding, where enabling reading on a previously disabled FD
would result in forgetting the EAGAIN flag it met last time.

Several new state manipulation functions have been introduced or
adapted :
  - fd_want_{recv,send} : enable receiving/sending on the FD regardless
    of its state (sets the ACTIVE flag) ;

  - fd_stop_{recv,send} : stop receiving/sending on the FD regardless
    of its state (clears the ACTIVE flag) ;

  - fd_cant_{recv,send} : report a failure to receive/send on the FD
    corresponding to EAGAIN (clears the READY flag) ;

  - fd_may_{recv,send}  : report the ability to receive/send on the FD
    as reported by poll() (sets the READY flag) ;

Some functions are used to report the current FD status :

  - fd_{recv,send}_active
  - fd_{recv,send}_ready
  - fd_{recv,send}_polled

Some functions were removed :
  - fd_ev_clr(), fd_ev_set(), fd_ev_rem(), fd_ev_wai()

The POLLHUP/POLLERR flags are now reported as ready so that the I/O layers
knows it can try to access the file descriptor to get this information.

In order to simplify the conditions to add/remove cache entries, a new
function fd_alloc_or_release_cache_entry() was created to be used from
pollers while scanning for updates.

The following pollers have been updated :

   ev_select() : done, built, tested on Linux 3.10
   ev_poll()   : done, built, tested on Linux 3.10
   ev_epoll()  : done, built, tested on Linux 3.10 & 3.13
   ev_kqueue() : done, built, tested on OpenBSD 5.2

11 years agoREORG: polling: rename "fd_process_spec_events()" to "fd_process_cached_events()"
Willy Tarreau [Sat, 25 Jan 2014 18:24:15 +0000 (19:24 +0100)] 
REORG: polling: rename "fd_process_spec_events()" to "fd_process_cached_events()"

This is in order to be coherent with the rest.

11 years agoREORG: polling: rename the cache allocation functions
Willy Tarreau [Sat, 25 Jan 2014 18:20:35 +0000 (19:20 +0100)] 
REORG: polling: rename the cache allocation functions

- alloc_spec_entry() becomes fd_alloc_cache_entry()
- release_spec_entry() becomes fd_release_cache_entry()

11 years agoREORG: polling: rename "fd_spec" to "fd_cache"
Willy Tarreau [Sat, 25 Jan 2014 18:10:48 +0000 (19:10 +0100)] 
REORG: polling: rename "fd_spec" to "fd_cache"

So fd_spec was renamed "fd_cache" as it's becoming an event cache, and
fd_nbspec becomes fd_cache_num.

11 years agoREORG: polling: rename "spec_e" to "state" and "spec_p" to "cache"
Willy Tarreau [Mon, 20 Jan 2014 10:09:39 +0000 (11:09 +0100)] 
REORG: polling: rename "spec_e" to "state" and "spec_p" to "cache"

We're completely changing the way FDs will be polled. There will be no
more speculative I/O since we'll know the exact FD state, so these will
only be cached events.

First, let's fix a few field names which become confusing. "spec_e" was
used to store a speculative I/O event state. Now we'll store the whole
R/W states for the FD there. "spec_p" was used to store a speculative
I/O cache position. Now let's clearly call it "cache".

11 years agoDOC: add a diagram showing polling state transitions
Willy Tarreau [Fri, 17 Jan 2014 18:40:43 +0000 (19:40 +0100)] 
DOC: add a diagram showing polling state transitions

This is internal stuff.

11 years agoCLEANUP: polling: rename "spec_e" to "state"
Willy Tarreau [Mon, 20 Jan 2014 10:02:59 +0000 (11:02 +0100)] 
CLEANUP: polling: rename "spec_e" to "state"

We're completely changing the way FDs will be polled. First, let's fix
a few field names which become confusing. "spec_e" was used to store a
speculative I/O event state. Now we'll store the whole R/W states for
the FD there.

11 years agoBUILD: fix VERDATE exclusion regex
Willy Tarreau [Sat, 25 Jan 2014 23:39:22 +0000 (00:39 +0100)] 
BUILD: fix VERDATE exclusion regex

A backslash was missing. It used to work well with GNU grep anyway but
better fix it.

11 years agoBUG/MEDIUM: stream-interface: don't wake the task up before end of transfer
Willy Tarreau [Sat, 25 Jan 2014 01:33:21 +0000 (02:33 +0100)] 
BUG/MEDIUM: stream-interface: don't wake the task up before end of transfer

Recent commit d7ad9f5 ("MAJOR: channel: add a new flag CF_WAKE_WRITE to
notify the task of writes") was not correct. It used to wake up the task
as soon as there was some write activity and the flag was set, even if there
were still some data to be forwarded. This resulted in process_session()
being called a lot when transfering chunk-encoded HTTP responses made of
very large chunks.

The purpose of the flag is to wake up only a task waiting for some
room and not the other ones, so it's totally counter-productive to
wake it up as long as there are data to forward because the task
will not be allowed to write anyway.

Also, the commit above was taking some risks by not considering
certain events anymore (eg: state != SI_ST_EST). While such events
are not used at the moment, if some new features were developped
in the future relying on these, it would be better that they could
be notified when subscribing to the WAKE_WRITE event, so let's
restore the condition.

11 years agoBUG/MAJOR: fix freezes during compression
Willy Tarreau [Sat, 25 Jan 2014 01:26:39 +0000 (02:26 +0100)] 
BUG/MAJOR: fix freezes during compression

Recent commit d7ad9f5 ("MAJOR: channel: add a new flag CF_WAKE_WRITE to
notify the task of writes") introduced this new CF_WAKE_WRITE flag that
an analyser which requires some free space to write must set if it wants
to be notified.

Unfortunately, some places were missing. More specifically, the
compression engine can rarely be stuck by a lack of output space,
especially when dealing with non-compressible data. It then has to
stop until some pending data are flushed and for this it must set
the CF_WAKE_WRITE flag. But these cases were missed by the commit
above.

Fortunately, this change was introduced very recently and never
released, so the impact was limited.

Huge thanks to Sander Klein who first reported this issue and who kindly
and patiently provided lots of traces and test data that made it possible
to reproduce, analyze, then fix this issue.

11 years agoDOC: fix misleading information about SIGQUIT
Willy Tarreau [Sat, 25 Jan 2014 17:19:32 +0000 (18:19 +0100)] 
DOC: fix misleading information about SIGQUIT

SIGQUIT dumps the pools state to stderr, not to the logs. Thanks to
Jim Freeman for reporting this.

11 years agoBUG/MEDIUM: unique_id: HTTP request counter is not stable
Willy Tarreau [Sat, 25 Jan 2014 10:01:50 +0000 (11:01 +0100)] 
BUG/MEDIUM: unique_id: HTTP request counter is not stable

Patrick Hemmer reported that using unique_id_format and logs did not
report the same unique ID counter since commit 9f09521 ("BUG/MEDIUM:
unique_id: HTTP request counter must be unique!"). This is because
the increment was done while producing the log message, so it was
performed twice.

A better solution consists in fetching a new value once per request
and saving it in the request or session context for all of this
request's life.

It happens that sessions already have a unique ID field which is used
for debugging and reporting errors, and which differs from the one
sent in logs and unique_id header.

So let's change this to reuse this field to have coherent IDs everywhere.
As of now, a session gets a new unique ID once it is instanciated. This
means that TCP sessions will also benefit from a unique ID that can be
logged. And this ID is renewed for each extra HTTP request received on
an existing session. Thus, all TCP sessions and HTTP requests will have
distinct IDs that will be stable along all their life, and coherent
between all places where they're used (logs, unique_id header,
"show sess", "show errors").

This feature is 1.5-specific, no backport to 1.4 is needed.

11 years agoBUG/MINOR: payload: the patterns of the acl "req.ssl_ver" are no parsed with the...
Thierry FOURNIER [Fri, 24 Jan 2014 11:41:51 +0000 (12:41 +0100)] 
BUG/MINOR: payload: the patterns of the acl "req.ssl_ver" are no parsed with the good function.

The fetch "req.ssl_ver" is not declared as explicit acl. If it is used
as implicit ACL, the acl engine detect SMP_T_UINT output type and choose
to use the default interger parser: pat_parse_int(). This fetch needs the
parser pat_parse_dotted_ver().

This patch declare explicit ACL named "req.ssl_ver" that use the good
parser function pat_parse_dotted_ver().

11 years agoMEDIUM: checks: make use of chk_report_conn_err() for connection errors
Willy Tarreau [Fri, 24 Jan 2014 15:10:57 +0000 (16:10 +0100)] 
MEDIUM: checks: make use of chk_report_conn_err() for connection errors

Checks used not to precisely report the errors that were detected at the
connection layer (eg: too many SSL connections). Using chk_report_conn_err()
makes this possible.

11 years agoMEDIUM: tcp: report connection error at the connection level
Willy Tarreau [Fri, 24 Jan 2014 15:08:19 +0000 (16:08 +0100)] 
MEDIUM: tcp: report connection error at the connection level

Now when a connection error happens, it is reported in the connection
so that upper layers know exactly what happened. This is particularly
useful with health checks and resources exhaustion.

11 years agoMINOR: connection: add more error codes to report connection errors
Willy Tarreau [Fri, 24 Jan 2014 15:06:50 +0000 (16:06 +0100)] 
MINOR: connection: add more error codes to report connection errors

It is quite often that an connection error only reports "socket error" with
no more information. This is especially problematic with health checks where
many causes are possible, including resource exhaustion which do not lead to
a valid errno code. So let's add explicit codes to cover these cases.

11 years agoMINOR: standard: The parse_binary() returns the length consumed and his documentation...
Thierry FOURNIER [Tue, 21 Jan 2014 10:36:14 +0000 (11:36 +0100)] 
MINOR: standard: The parse_binary() returns the length consumed and his documentation is updated

Actually the values returned by this function is never used. All the
callers just check if the resultat is non-zero. Before this patch, the
function returns the length of the produced content. This value is not
useful because is returned twice: the first time in the return value and
the second time in the <binstrlen> argument. Now the function returns
the number of bytes consumed from <source>.

11 years agoMINOR: pattern: move functions for grouping pat_match_* and pat_parse_* and add docum...
Thierry FOURNIER [Tue, 21 Jan 2014 10:25:41 +0000 (11:25 +0100)] 
MINOR: pattern: move functions for grouping pat_match_* and pat_parse_* and add documentation.

11 years agoBUG/MEDIUM: pattern: Segfault in binary parser
Thierry FOURNIER [Tue, 21 Jan 2014 09:59:24 +0000 (10:59 +0100)] 
BUG/MEDIUM: pattern: Segfault in binary parser

The functions pat_parse_* must return 0 if fail and the number of
elements eated from **text if not fail. The function pat_parse_bin()
returns 0 or the length parsed. This causes a segfault. I just apply the
double operator "!" on the result of the function pat_parse_bin() and
the return value value match the expected value.

11 years agoMEDIUM: connection: update callers of ctrl->drain() to use conn_drain()
Willy Tarreau [Mon, 20 Jan 2014 11:10:52 +0000 (12:10 +0100)] 
MEDIUM: connection: update callers of ctrl->drain() to use conn_drain()

Now we can more safely rely on the connection state to decide how to
drain and what to do when data are drained. Callers don't need to
manipulate the file descriptor's state anymore.

Note that it also removes the need for the fix ea90063 ("BUG/MEDIUM:
stream-int: fix the keep-alive idle connection handler") since conn_drain()
correctly sets the polling flags.

11 years agoMEDIUM: tcp: report in tcp_drain() that lingering is already disabled on close
Willy Tarreau [Mon, 20 Jan 2014 10:56:37 +0000 (11:56 +0100)] 
MEDIUM: tcp: report in tcp_drain() that lingering is already disabled on close

When an incoming shutdown or error is detected, we know that we
can safely close without disabling lingering. Do it in tcp_drain()
so that we don't have to do it from each and every caller.