]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
12 years agoOPTIM: splice: assume by default that splice is working correctly
Willy Tarreau [Mon, 7 Jan 2013 15:57:09 +0000 (16:57 +0100)] 
OPTIM: splice: assume by default that splice is working correctly

Versions of splice between 2.6.25 and 2.6.27.12 were bogus and would return EAGAIN
on incoming shutdowns. On these versions, we have to call recv() after such a return
in order to find whether splice is OK or not. Since 2.6.27.13 we don't need to do
this anymore, saving one useless recv() call after each splice() returning EAGAIN,
and we can avoid this logic by defining ASSUME_SPLICE_WORKS.

Building with linux2628 automatically enables splice and the flag above since the
kernel is safe. People enabling splice for custom kernels will be able to disable
this logic by hand too.

12 years agoOPTIM: splice: detect shutdowns and avoid splice() == 0
Willy Tarreau [Mon, 7 Jan 2013 15:38:26 +0000 (16:38 +0100)] 
OPTIM: splice: detect shutdowns and avoid splice() == 0

Since last commit introducing EPOLLRDHUP, the splicing code is able to
detect an incoming shutdown without calling splice() == 0. This avoids
one useless syscall.

12 years agoOPTIM: epoll: make use of EPOLLRDHUP
Willy Tarreau [Mon, 7 Jan 2013 15:19:18 +0000 (16:19 +0100)] 
OPTIM: epoll: make use of EPOLLRDHUP

epoll may report pending shutdowns using EPOLLRDHUP. Since this
flag is missing from a number of libcs despite being available
since kernel 2.6.17, let's define it ourselves.

Doing so saves one syscall by allow us to avoid the read()==0 when
the server closes with the respose.

12 years agoMINOR: signal: don't block SIGPROF by default
Willy Tarreau [Fri, 4 Jan 2013 15:20:20 +0000 (16:20 +0100)] 
MINOR: signal: don't block SIGPROF by default

SIGPROF is blocked then restored to default settings, which sometimes
makes profiling harder. Let's not block it by default nor restore it,
it doesn't serve any purpose anyway.

12 years agoMINOR: config: http-request configuration error message misses new keywords
Baptiste Assmann [Sat, 5 Jan 2013 15:02:07 +0000 (16:02 +0100)] 
MINOR: config: http-request configuration error message misses new keywords

"redirect" and "tarpit" keywords were missing from http-request configuration
error message.

12 years agoDOC: typo and minor fixes in compression paragraph
Baptiste Assmann [Sat, 5 Jan 2013 14:44:44 +0000 (15:44 +0100)] 
DOC: typo and minor fixes in compression paragraph

12 years agoBUG/MINOR: http-compression: lookup Cache-Control in the response, not the request
Willy Tarreau [Sat, 5 Jan 2013 15:20:35 +0000 (16:20 +0100)] 
BUG/MINOR: http-compression: lookup Cache-Control in the response, not the request

As stated in both RFC2616 and the http-bis drafts, Cache-Control:
no-transform must be looked up in the response since we're modifying
the response. However, its presence in the request is irrelevant to
any changes in the response :

  7.2.1.6. no-transform
   The "no-transform" request directive indicates that an intermediary
   (whether or not it implements a cache) MUST NOT change the Content-
   Encoding, Content-Range or Content-Type request header fields, nor
   the request representation.

  7.2.2.9. no-transform
   The "no-transform" response directive indicates that an intermediary
   (regardless of whether it implements a cache) MUST NOT change the
   Content-Encoding, Content-Range or Content-Type response header
   fields, nor the response representation.

Note: according to the specs, we're supposed to emit the following
response header :

  Warning: 214 transformation applied

However no other product seems to do it, so the effect on user agents
is unclear.

12 years agoDOC: fix bogus recommendation on usage of gpc0 counter
Willy Tarreau [Fri, 4 Jan 2013 13:14:57 +0000 (14:14 +0100)] 
DOC: fix bogus recommendation on usage of gpc0 counter

The doc pretends that src_inc_gpc0 may be used alone without an integer
match, but this is false and has always been since its introduction in
1.5-dev1. If the ACL is called, the increment will be used, the value
returned, but it will be matched against no value so the resulting ACL
will never be true and the condition will not be met.

This means that the following config :

     acl abuser src -f abusers.lst
     acl blacklist src_inc_gpc0
     tcp-request connection reject if abuser blacklist

Will never reject the connection and must be fixed this way :

     acl abuser src -f abusers.lst
     acl blacklist src_inc_gpc0 gt 0
     tcp-request connection reject if abuser blacklist

Note that clr_gpc0 is trickier, as it returns the previous value which
might also be zero. Thus it's suggested to compare it against any positive
value including zero :

     tcp-request connection accept if { src_clr_gpc0 ge 0 }

Some arguments were missing on the sc1/sc2 forms of most ACLs including
gpc0, so this has been fixed too.

12 years agoBUG/MEDIUM: checks: ignore late resets after valid responses
Willy Tarreau [Sun, 30 Dec 2012 00:44:24 +0000 (01:44 +0100)] 
BUG/MEDIUM: checks: ignore late resets after valid responses

Reinout Verkerk from Trilex reported an issue with servers recently
flapping after an haproxy upgrade. Haproxy checks a simple agent
returning an HTTP response. The issue is that if the request packet
is lost but the simple agent responds before reading the HTTP request
and closes, the server will emit a TCP RST once the request finally
reaches it.

The way checks have been ported to use connections makes the error
flag show up as a failure after the success, reporting a stupid case
where the server is said to be down with a correct response.

In order to fix this, let's ignore the connection's error flag if a
successful check has already been reported. Reinout could verify that
a patched server did not exhibit the problem anymore.

12 years agoBUG/MEDIUM: stream_interface: don't close outgoing connections on shutw()
Willy Tarreau [Sun, 30 Dec 2012 00:39:37 +0000 (01:39 +0100)] 
BUG/MEDIUM: stream_interface: don't close outgoing connections on shutw()

Commit 7bb68abb introduced the SI_FL_NOHALF flag in dev10. It is used
to automatically close the write side of a connection whose read side
is closed. But the patch also caused the opposite to happen, which is
that a simple shutw() call would immediately close the connection. This
is not desired because when using option abortonclose, we want to pass
the client's shutdown to the server which will decide what to do with
it. So let's avoid the close when SHUTR is not set.

12 years agoBUG/MINOR: http: don't process abortonclose when request was sent
Willy Tarreau [Sat, 29 Dec 2012 23:50:35 +0000 (00:50 +0100)] 
BUG/MINOR: http: don't process abortonclose when request was sent

option abortonclose may cause a valid connection to be aborted just
after the request has been sent. This is because we check for it
during the session establishment sequence before checking for write
activity. So if the abort and the connect complete at the same time,
the abort is still considered. Let's check for an explicity partial
write before aborting.

This fix should be backported to 1.4 too.

12 years agoBUG/MINOR: time: frequency counters are not totally accurate
Willy Tarreau [Sat, 29 Dec 2012 20:50:07 +0000 (21:50 +0100)] 
BUG/MINOR: time: frequency counters are not totally accurate

When a frontend is rate-limited to 1000 connections per second, the
effective rate measured from the client is 999/s, and connections
experience an average response time of 99.5 ms with a standard
deviation of 2 ms.

The reason for this inaccuracy is that when computing frequency
counters, we use one part of the previous value proportional to the
number of milliseconds remaining in the current second. But even the
last millisecond still uses a part of the past value, which is wrong :
since we have a 1ms resolution, the last millisecond must be dedicated
only to filling the current second.

So we slightly adjust the algorithm to use 999/1000 of the past value
during the first millisecond, and 0/1000 of the past value during the
last millisecond.  We also slightly improve the computation by computing
the remaining time instead of the current time in tv_update_date(), so
that we don't have to negate the value in each frequency counter.

Now with the fix, the connection rate measured by both the client and
haproxy is a steady 1000/s, the average response time measured is 99.2ms
and more importantly, the standard deviation has been divided by 3 to
0.6 millisecond.

This fix should also be backported to 1.4 which has the same issue.

12 years ago[RELEASE] Released version 1.5-dev17 v1.5-dev17
Willy Tarreau [Fri, 28 Dec 2012 14:04:05 +0000 (15:04 +0100)] 
[RELEASE] Released version 1.5-dev17

Released version 1.5-dev17 with the following main changes :
    - MINOR: ssl: Setting global tune.ssl.cachesize value to 0 disables SSL session cache.
    - BUG/MEDIUM: stats: fix stats page regression introduced by commit 20b0de5
    - BUG/MINOR: stats: last fix was still wrong
    - BUG/MINOR: stats: http-request rules still don't cope with stats
    - BUG/MINOR: http: http-request add-header emits a corrupted header
    - BUG/MEDIUM: stats: disable request analyser when processing POST or HEAD
    - BUG/MINOR: log: make log-format, unique-id-format and add-header more independant
    - BUILD: log: unused variable svid
    - CLEANUP: http: rename the misleading http_check_access_rule
    - MINOR: http: move redirect rule processing to its own function
    - REORG: config: move the http redirect rule parser to proto_http.c
    - MEDIUM: http: add support for "http-request redirect" rules
    - MEDIUM: http: add support for "http-request tarpit" rule

12 years agoMINOR: ssl: Setting global tune.ssl.cachesize value to 0 disables SSL session cache.
Emeric Brun [Fri, 28 Dec 2012 13:41:32 +0000 (14:41 +0100)] 
MINOR: ssl: Setting global tune.ssl.cachesize value to 0 disables SSL session cache.

12 years agoMEDIUM: http: add support for "http-request tarpit" rule
Willy Tarreau [Thu, 27 Dec 2012 11:37:57 +0000 (12:37 +0100)] 
MEDIUM: http: add support for "http-request tarpit" rule

The "reqtarpit" rule is not very handy to use. Now that we have more
flexibility with "http-request", let's finally make the tarpit rules
usable there.

There are still semantical differences between apply_filters_to_request()
and http_req_get_intercept_rule() because the former updates the counters
while the latter does not. So we currently have almost similar code leafs
for similar conditions, but this should be cleaned up later.

12 years agoMEDIUM: http: add support for "http-request redirect" rules
Willy Tarreau [Thu, 27 Dec 2012 11:19:02 +0000 (12:19 +0100)] 
MEDIUM: http: add support for "http-request redirect" rules

These are exactly the same as the classic redirect rules except
that they can be interleaved with other http-request rules for
more flexibility.

The redirect parser should probably be changed to stop at the condition
so that the caller puts its own condition pointer. At the moment, the
redirect rule and condition are parsed at once by build_redirect_rule()
and the condition is assigned to the http_req_rule.

12 years agoREORG: config: move the http redirect rule parser to proto_http.c
Willy Tarreau [Thu, 27 Dec 2012 11:00:31 +0000 (12:00 +0100)] 
REORG: config: move the http redirect rule parser to proto_http.c

We'll have to use this elsewhere soon, let's move it to the proper
place.

12 years agoMINOR: http: move redirect rule processing to its own function
Willy Tarreau [Thu, 27 Dec 2012 10:30:54 +0000 (11:30 +0100)] 
MINOR: http: move redirect rule processing to its own function

We now have http_apply_redirect_rule() which does all the redirect-specific
job instead of having this inside http_process_req_common().

Also one of the benefit gained from uniformizing this code is that both
keep-alive and close response do emit the PR-- flags. The fix for the
flags could probably be backported to 1.4 though it's very minor.

The previous function http_perform_redirect() was becoming confusing
so it was renamed http_perform_server_redirect() since it only applies
to server-based redirection.

12 years agoCLEANUP: http: rename the misleading http_check_access_rule
Willy Tarreau [Thu, 27 Dec 2012 09:46:37 +0000 (10:46 +0100)] 
CLEANUP: http: rename the misleading http_check_access_rule

Several bugs were introduced recently due to a misunderstanding of how
this function works and what it was supposed to do. Since it's supposed
to only return the pointer to a rule which aborts further processing of
the request, let's rename it to avoid further issues.

The function was also slightly cleaned up without any functional change.

12 years agoBUILD: log: unused variable svid
Willy Tarreau [Fri, 28 Dec 2012 13:46:45 +0000 (14:46 +0100)] 
BUILD: log: unused variable svid

This results from previous fix.

12 years agoBUG/MINOR: log: make log-format, unique-id-format and add-header more independant
Willy Tarreau [Fri, 28 Dec 2012 08:40:16 +0000 (09:40 +0100)] 
BUG/MINOR: log: make log-format, unique-id-format and add-header more independant

It happens that all of them call parse_logformat_line() which sets
proxy->to_log with a number of flags affecting the line format for
all three users. For example, having a unique-id specified disables
the default log-format since fe->to_log is tested when the session
is established.

Similarly, having "option logasap" will cause "+" to be inserted in
unique-id or headers referencing some of the fields depending on
LW_BYTES.

This patch first removes most of the dependency on fe->to_log whenever
possible. The first possible cleanup is to stop checking fe->to_log
for being null, considering that it always contains at least LW_INIT
when any such usage is made of the log-format!

Also, some checks are wrong. s->logs.logwait cannot be nulled by
"logwait &= ~LW_*" since LW_INIT is always there. This results in
getting the wrong log at the end of a request or session when a
unique-id or add-header is set, because logwait is still not null
but the log-format is not checked.

Further cleanups are required. Most LW_* flags should be removed or at
least replaced with what they really mean (eg: depend on client-side
connection, depend on server-side connection, etc...) and this should
only affect logging, not other mechanisms.

This patch fixes the default log-format and tries to limit interferences
between the log formats, but does not pretend to do more for the moment,
since it's the most visible breakage.

12 years agoBUG/MEDIUM: stats: disable request analyser when processing POST or HEAD
Willy Tarreau [Fri, 28 Dec 2012 07:36:50 +0000 (08:36 +0100)] 
BUG/MEDIUM: stats: disable request analyser when processing POST or HEAD

After the response headers are sent and the request processing is done,
the buffers are wiped out and the stream interface is closed. We must
then disable the request analysers, otherwise some processing will
happen on a closed stream interface and empty buffers which do not
match, causing all sort of crashes. This issue was introduced with
recent work on the stats, and was reported by Seri.

12 years agoBUG/MINOR: http: http-request add-header emits a corrupted header
Willy Tarreau [Fri, 28 Dec 2012 01:44:01 +0000 (02:44 +0100)] 
BUG/MINOR: http: http-request add-header emits a corrupted header

David BERARD reported that http-request add-header passes a \0 along
with the header field, which of course is not appropriate. This is
caused by build_logline() which sometimes returns the size with the
trailing zero and sometimes can return an empty string. Let's fix
this function instead of fixing the places where it's used.

12 years agoBUG/MINOR: stats: http-request rules still don't cope with stats
Willy Tarreau [Thu, 27 Dec 2012 09:34:21 +0000 (10:34 +0100)] 
BUG/MINOR: stats: http-request rules still don't cope with stats

Since commit 20b0de5, we also had another remaining issue : an
"http-request allow" rule would prevent a stats rule from being
processed.

12 years agoBUG/MINOR: stats: last fix was still wrong
Willy Tarreau [Tue, 25 Dec 2012 20:53:25 +0000 (21:53 +0100)] 
BUG/MINOR: stats: last fix was still wrong

Previous commit was still wrong, it broke add-header and set-header
because we don't want to leave on these actions.

The http_check_access_rule() function should be redesigned, it was
initially thought for allow/deny rules but now it is executing other
non-final rules and at the same time returning a pointer to the last
final rule. That becomes a bit confusing and will need to be addressed
before we implement redirect and return.

12 years agoBUG/MEDIUM: stats: fix stats page regression introduced by commit 20b0de5
Willy Tarreau [Tue, 25 Dec 2012 19:52:58 +0000 (20:52 +0100)] 
BUG/MEDIUM: stats: fix stats page regression introduced by commit 20b0de5

This commit adding http-request add-header/set-header unfortunately introduced
a regression to the handling of the stats page which is not matched anymore.

Thanks to Dmitry Sivachenko for reporting this.

12 years ago[RELEASE] Released version 1.5-dev16 v1.5-dev16
Willy Tarreau [Mon, 24 Dec 2012 15:48:14 +0000 (16:48 +0100)] 
[RELEASE] Released version 1.5-dev16

Released version 1.5-dev16 with the following main changes :
    - BUG/MEDIUM: ssl: Prevent ssl error from affecting other connections.
    - BUG/MINOR: ssl: error is not reported if it occurs simultaneously with peer close detection.
    - MINOR: ssl: add fetch and acl "ssl_c_used" to check if current SSL session uses a client certificate.
    - MINOR: contrib: make the iprange tool grep for addresses
    - CLEANUP: polling: gcc doesn't always optimize constants away
    - OPTIM: poll: optimize fd management functions for low register count CPUs
    - CLEANUP: poll: remove a useless double-check on fdtab[fd].owner
    - OPTIM: epoll: use a temp variable for intermediary flag computations
    - OPTIM: epoll: current fd does not count as a new one
    - BUG/MINOR: poll: the I/O handler was called twice for polled I/Os
    - MINOR: http: make resp_ver and status ACLs check for the presence of a response
    - BUG/MEDIUM: stream-interface: fix possible stalls during transfers
    - BUG/MINOR: stream_interface: don't return when the fd is already set
    - BUG/MEDIUM: connection: always update connection flags prior to computing polling
    - CLEANUP: buffer: use buffer_empty() instead of buffer_len()==0
    - BUG/MAJOR: stream_interface: fix occasional data transfer freezes
    - BUG/MEDIUM: stream_interface: fix another case where the reader might not be woken up
    - BUG/MINOR: http: don't abort client connection on premature responses
    - BUILD: no need to clean up when making git-tar
    - MINOR: log: add a tag for amount of bytes uploaded from client to server
    - BUG/MEDIUM: log: fix possible segfault during config parsing
    - MEDIUM: log: change a few log tokens to make them easier to remember
    - BUG/MINOR: log: add_to_logformat_list() used the wrong constants
    - MEDIUM: log-format: make the format parser more robust and more extensible
    - MINOR: sample: support cast from bool to string
    - MINOR: samples: add a function to fetch and convert any sample to a string
    - MINOR: log: add lf_text_len
    - MEDIUM: log: add the ability to include samples in logs
    - REORG: stats: massive code reorg and cleanup
    - REORG: stats: move the HTTP header injection to proto_http
    - REORG: stats: functions are now HTTP/CLI agnostic
    - BUG/MINOR: log: fix regression introduced by commit 8a3f52
    - MINOR: chunks: centralize the trash chunk allocation
    - MEDIUM: stats: use hover boxes instead of title to report details
    - MEDIUM: stats: use multi-line tips to display detailed counters
    - MINOR: tools: simplify the use of the int to ascii macros
    - MINOR: stats: replace STAT_FMT_CSV with STAT_FMT_HTML
    - MINOR: http: prepare to support more http-request actions
    - MINOR: log: make parse_logformat_string() take a const char *
    - MEDIUM: http: add http-request 'add-header' and 'set-header' to build headers

12 years agoMEDIUM: http: add http-request 'add-header' and 'set-header' to build headers
Willy Tarreau [Mon, 24 Dec 2012 14:45:22 +0000 (15:45 +0100)] 
MEDIUM: http: add http-request 'add-header' and 'set-header' to build headers

These two new statements allow to pass information extracted from the request
to the server. It's particularly useful for passing SSL information to the
server, but may be used for various other purposes such as combining headers
together to emulate internal variables.

12 years agoMINOR: log: make parse_logformat_string() take a const char *
Willy Tarreau [Mon, 24 Dec 2012 11:36:33 +0000 (12:36 +0100)] 
MINOR: log: make parse_logformat_string() take a const char *

Sometimes we can't pass a char *, and there is no need for this since we strdup() it.

12 years agoMINOR: http: prepare to support more http-request actions
Willy Tarreau [Mon, 24 Dec 2012 11:00:25 +0000 (12:00 +0100)] 
MINOR: http: prepare to support more http-request actions

We'll need to support per-action arguments, so we need to have an
"arg" union in http_req_rule.

12 years agoMINOR: stats: replace STAT_FMT_CSV with STAT_FMT_HTML
Willy Tarreau [Sun, 23 Dec 2012 17:15:23 +0000 (18:15 +0100)] 
MINOR: stats: replace STAT_FMT_CSV with STAT_FMT_HTML

We need to switch the default mode if we want to add new output formats
later. Let CSV be the default and HTML be an option.

12 years agoMINOR: tools: simplify the use of the int to ascii macros
Willy Tarreau [Sun, 23 Dec 2012 17:00:29 +0000 (18:00 +0100)] 
MINOR: tools: simplify the use of the int to ascii macros

These macros (U2H, U2A, LIM2A, ...) have been used with an explicit
index for the local storage variable, making it difficult to change
log formats and causing a few issues from time to time. Let's have
a single macro with a rotating index so that up to 10 conversions
may be used in a single call.

12 years agoMEDIUM: stats: use multi-line tips to display detailed counters
Willy Tarreau [Sun, 23 Dec 2012 01:25:03 +0000 (02:25 +0100)] 
MEDIUM: stats: use multi-line tips to display detailed counters

Frontend, listener, server and backend detailed counters are now spread
over several lines in a table when the pointer hovers over the <u> area.

The values are much more readble, and the extra space gained this way
allowed to report some percentages.

Note: some incoherencies still exist between some counters. For example,
the backend's cum_conn is increased when a session is assigned instead
of increasing cum_sess.

12 years agoMEDIUM: stats: use hover boxes instead of title to report details
Willy Tarreau [Sun, 23 Dec 2012 00:59:23 +0000 (01:59 +0100)] 
MEDIUM: stats: use hover boxes instead of title to report details

Using titles to report detailed information is not convenient. The
browser decides to wrap the line where it wants, generally the box
quickly fades away, and it's not possible to copy-paste the text
from the box.

By using two levels, we can make a block appear/disappear depending
on whether its parent it being hovered or not, for example :

    .tip { display: none; }
    u:hover .tip { display: block; }

  or better:

    .tip { display: block; visibility: hidden; }
    u:hover .tip { visibility: visible; }

Toggling visibility ensures that the place required to display the block
is always reserved. This is important to display boxes that are close to
the edges.

Then using <span class="tip">this is a box</span> will make the text
appear only when the upper <u> is hovered.

But this still adds much text. So instead we use a generic <div> tag
which we don't use anywhere else. That way we don't have to specify a
class :

    div { display: block; visibility: hidden; }
    u:hover div { visibility: hidden; }

This works pretty well, even in old browsers from 2005.

This commit does not change the display format, it only replaces the
title attribute with the div tag. Later commits will adjust the layout.

12 years agoMINOR: chunks: centralize the trash chunk allocation
Willy Tarreau [Sun, 23 Dec 2012 19:22:19 +0000 (20:22 +0100)] 
MINOR: chunks: centralize the trash chunk allocation

At the moment, we need trash chunks almost everywhere and the only
correctly implemented one is in the sample code. Let's move this to
the chunks so that all other places can use this allocator.

Additionally, the get_trash_chunk() function now really returns two
different chunks. Previously it used to always overwrite the same
chunk and point it to a different buffer, which was a bit tricky
because it's not obvious that two consecutive results do alias each
other.

12 years agoBUG/MINOR: log: fix regression introduced by commit 8a3f52
Willy Tarreau [Sun, 23 Dec 2012 16:29:07 +0000 (17:29 +0100)] 
BUG/MINOR: log: fix regression introduced by commit 8a3f52

The commit above improved error reporting during log parsing, but as
a result, some shared strings such as httplog_format are truncated
during parsing. This is observable upon startup because the second
proxy to use httplog emits a warning.

Let's have the logformat parser duplicate the string while parsing it.

12 years agoREORG: stats: functions are now HTTP/CLI agnostic
Willy Tarreau [Sat, 22 Dec 2012 22:20:30 +0000 (23:20 +0100)] 
REORG: stats: functions are now HTTP/CLI agnostic

All the functions that were called "http" or "raw" have been cleaned up
to support either only HTML and use that word in their name, or support
both HTML and CSV and be usable both from the HTTP and the CLI entry
points.

stats_http_dump() now explicitly checks for HTML mode before adding
HTML-specific headers/trailers, and has been renamed since it's now
used by both entry points.

Some more duplicated code could be removed. The patch looks big but it's
mostly due to re-indents resulting from the moves or comments updates.

The calling sequences now look like this :

   cli_io_handler()
       -> stats_dump_sess_to_buffer()      // "show sess"
       -> stats_dump_errors_to_buffer()    // "show errors"
       -> stats_dump_info_to_buffer()      // "show info"
       -> stats_dump_stat_to_buffer()      // "show stat"
          -> stats_dump_csv_header()
          -> stats_dump_proxy_to_buffer()
             -> stats_dump_fe_stats()
             -> stats_dump_li_stats()
             -> stats_dump_sv_stats()
             -> stats_dump_be_stats()

   http_stats_io_handler()
       -> stats_dump_stat_to_buffer()      // same as above, but used for CSV or HTML
          -> stats_dump_csv_header()       // emits the CSV headers (same as above)
          -> stats_dump_html_head()        // emits the HTML headers
          -> stats_dump_html_info()        // emits the equivalent of "show info" at the top
          -> stats_dump_proxy_to_buffer()  // same as above, valid for CSV and HTML
             -> stats_dump_html_px_hdr()
             -> stats_dump_fe_stats()
             -> stats_dump_li_stats()
             -> stats_dump_sv_stats()
             -> stats_dump_be_stats()
             -> stats_dump_html_px_end()
          -> stats_dump_html_end()         // emits HTML trailer

12 years agoREORG: stats: move the HTTP header injection to proto_http
Willy Tarreau [Sat, 22 Dec 2012 21:03:39 +0000 (22:03 +0100)] 
REORG: stats: move the HTTP header injection to proto_http

The HTTP header injection that are performed in dumpstats when responding
or when redirecting a POST request have nothing to do in dumpstats. They
do not use any state from the stats, and are 100% HTTP. Let's make the
headers there in the HTTP core, and have dumpstats only produce stats.

12 years agoREORG: stats: massive code reorg and cleanup
Willy Tarreau [Sat, 22 Dec 2012 19:31:10 +0000 (20:31 +0100)] 
REORG: stats: massive code reorg and cleanup

The dumpstats code looks like a spaghetti plate. Several functions are
supposed to be able to do several things but rely on complex states to
dispatch the work to independant functions. Most of the HTML output is
performed within the switch/case statements of the whole state machine.

Let's clean this up by adding new functions to emit the data and have
a few more iterators to avoid relying on so complex states.

The new stats dump sequence looks like this for CLI and for HTTP :

  cli_io_handler()
      -> stats_dump_sess_to_buffer()      // "show sess"
      -> stats_dump_errors_to_buffer()    // "show errors"
      -> stats_dump_raw_info_to_buffer()  // "show info"
         -> stats_dump_raw_info()
      -> stats_dump_raw_stat_to_buffer()  // "show stat"
         -> stats_dump_csv_header()
         -> stats_dump_proxy()
            -> stats_dump_px_hdr()
            -> stats_dump_fe_stats()
            -> stats_dump_li_stats()
            -> stats_dump_sv_stats()
            -> stats_dump_be_stats()
            -> stats_dump_px_end()

  http_stats_io_handler()
      -> stats_http_redir()
      -> stats_dump_http()              // also emits the HTTP headers
         -> stats_dump_html_head()      // emits the HTML headers
         -> stats_dump_csv_header()     // emits the CSV headers (same as above)
         -> stats_dump_http_info()      // note: ignores non-HTML output
         -> stats_dump_proxy()          // same as above
         -> stats_dump_http_end()       // emits HTML trailer

12 years agoMEDIUM: log: add the ability to include samples in logs
Willy Tarreau [Thu, 20 Dec 2012 23:09:23 +0000 (00:09 +0100)] 
MEDIUM: log: add the ability to include samples in logs

Using %[expression] it becomes possible to make the log engine fetch
some samples from the request or the response and provide them in the
logs. Note that this feature is still limited, it does not yet allow
to apply converters, to limit the output length, nor to specify the
direction which should be fetched when a fetch function works in both
directions.

However it's quite convenient to log SSL information or to include some
information that are used in stick tables.

It is worth noting that this has been done in the generic log format
handler, which means that the same information may be used to build the
unique-id header and to pass the information to a backend server.

12 years agoMINOR: log: add lf_text_len
Willy Tarreau [Fri, 21 Dec 2012 18:23:44 +0000 (19:23 +0100)] 
MINOR: log: add lf_text_len

This function allows to log a text of a specific length.

12 years agoMINOR: samples: add a function to fetch and convert any sample to a string
Willy Tarreau [Thu, 20 Dec 2012 23:02:32 +0000 (00:02 +0100)] 
MINOR: samples: add a function to fetch and convert any sample to a string

Any sample type can now easily be converted to a string that can be used
anywhere. This will be used for logging and passing information in headers.

12 years agoMINOR: sample: support cast from bool to string
Willy Tarreau [Fri, 21 Dec 2012 16:38:05 +0000 (17:38 +0100)] 
MINOR: sample: support cast from bool to string

Samples could be converted from bool to int and from int to string but
not from bool to string. Let's add this.

12 years agoMEDIUM: log-format: make the format parser more robust and more extensible
Willy Tarreau [Thu, 20 Dec 2012 20:23:42 +0000 (21:23 +0100)] 
MEDIUM: log-format: make the format parser more robust and more extensible

The log-format parser reached a limit making it hard to add new features.
It also suffers from a weak handling of certain incorrect corner cases,
for example "%{foo}" is emitted as a litteral while syntactically it's an
argument to no variable. Also the argument parser had to redo some of the
job with some cases causing minor memory leaks (eg: ignored args).

This work aims at improving the situation so that slightly better reporting
is possible and that it becomes possible to extend the log format. The code
has a few more states but looks significantly simpler. The parser is now
capable of reporting ignored arguments and truncated lines.

12 years agoBUG/MINOR: log: add_to_logformat_list() used the wrong constants
Willy Tarreau [Thu, 20 Dec 2012 20:59:12 +0000 (21:59 +0100)] 
BUG/MINOR: log: add_to_logformat_list() used the wrong constants

The <type> argument was checked against LOG_FMT_* but it was passed as
LF_* which are two independant enums. It happens that the 3 first entries
in these enums do match, but this broke some experimental changes which
required another state, so let's fix this now.

12 years agoMEDIUM: log: change a few log tokens to make them easier to remember
Willy Tarreau [Thu, 20 Dec 2012 16:22:52 +0000 (17:22 +0100)] 
MEDIUM: log: change a few log tokens to make them easier to remember

Some log tokens have evolved in a way that is not completely logical.
For example, frontend tokens sometimes begin with an 'f' and sometimes
with an 'F'. Same for backend and server.

So let's change a few cases without disrupting compatibility with existing
setups :

  Bi => bi
  Bp => bp
  Ci => ci
  Cp => cp
  Fi => fi
  Fp => fp
  Si => si
  Sp => sp
  cc => CC
  cs => CS
  st => ST

The old ones are still supported but deprecated and will be unsupported by
the 1.5 release. However, a warning message is emitted when they're encounterd
and it indicates what token should be used to replace them.

12 years agoBUG/MEDIUM: log: fix possible segfault during config parsing
Willy Tarreau [Thu, 20 Dec 2012 17:19:26 +0000 (18:19 +0100)] 
BUG/MEDIUM: log: fix possible segfault during config parsing

When log format arguments are specified within braces with no '+' nor '-'
prefix, the NULL string is compared with known keywords causing a crash.
This only happens during parsing so it does not affect runtime processing.

12 years agoMINOR: ssl: add fetch and acl "ssl_c_used" to check if current SSL session uses a...
Emeric Brun [Thu, 20 Dec 2012 14:44:16 +0000 (15:44 +0100)] 
MINOR: ssl: add fetch and acl "ssl_c_used" to check if current SSL session uses a client certificate.

12 years agoMINOR: log: add a tag for amount of bytes uploaded from client to server
Willy Tarreau [Thu, 20 Dec 2012 14:38:04 +0000 (15:38 +0100)] 
MINOR: log: add a tag for amount of bytes uploaded from client to server

For POST, PUT, CONNECT or tunnelled connections, it's annoying not to have
the amount of uploaded bytes in the logs. %U now reports this value.

12 years agoBUILD: no need to clean up when making git-tar
Willy Tarreau [Thu, 20 Dec 2012 14:00:44 +0000 (15:00 +0100)] 
BUILD: no need to clean up when making git-tar

git-tar uses the repository, not the working dir, so it's useless to
run "make clean" first.

12 years agoBUG/MINOR: http: don't abort client connection on premature responses
Willy Tarreau [Thu, 20 Dec 2012 11:10:09 +0000 (12:10 +0100)] 
BUG/MINOR: http: don't abort client connection on premature responses

When a server responds prematurely to a POST request, haproxy used to
cause the transfer to be aborted before the end. This is problematic
because this causes the client to receive a TCP reset when it tries to
push more data, generally preventing it from receiving the response
which contain the reason for the premature reponse (eg: "entity too
large" or an authentication request).

From now on we take care of allowing the upload traffic to flow to the
server even when the response has been received, since the server is
supposed to drain it. That way the client receives the server response.

This bug has been present since 1.4 and the fix should probably be
backported there.

12 years agoBUG/MEDIUM: stream_interface: fix another case where the reader might not be woken up
Willy Tarreau [Wed, 19 Dec 2012 17:01:02 +0000 (18:01 +0100)] 
BUG/MEDIUM: stream_interface: fix another case where the reader might not be woken up

The code review during the chase for the POST freeze uncovered another possible
issue which might appear when we perform an incomplete read and want to stop because
of READ_DONTWAIT or because we reached the maximum read_poll limit. Reading is
disabled but SI_FL_WAIT_ROOM was not set, possibly causing some cases where a
send() on the other side would not wake the reader up until another activity
on the same side calls the update function which fixes its status.

12 years agoBUG/MAJOR: stream_interface: fix occasional data transfer freezes
Willy Tarreau [Wed, 19 Dec 2012 16:34:17 +0000 (17:34 +0100)] 
BUG/MAJOR: stream_interface: fix occasional data transfer freezes

Since the changes in connection management, it became necessary to re-enable
polling after a fast-forward transfer would complete.

One such issue was addressed after dev12 by commit 9f7c6a18 (BUG/MAJOR:
stream_interface: certain workloads could cause get stuck) but unfortunately,
it was incomplete as very subtle cases would occasionally remain unaddressed
when a buffer was marked with the NOEXP flag, which is used during POST
uploads. The wake up must be performed even when the flag is there, the
flag is used only to refresh the timeout.

Too many conditions need to be hit together for the situation to be
reproducible, but it systematically appears for some users.

It is particularly important to credit Sander Klein and John Rood from
Picturae ICT ( http://picturae.com/ ) for reporting this bug on the mailing
list, providing configs and countless traces showing the bug in action, and
for their patience testing litteraly tens of snapshots and versions of
supposed fixes during a full week to narrow the commit range until the bug
was really knocked down! As a side effect of their numerous tests, several
other bugs were fixed.

12 years agoCLEANUP: buffer: use buffer_empty() instead of buffer_len()==0
Willy Tarreau [Sun, 16 Dec 2012 18:39:09 +0000 (19:39 +0100)] 
CLEANUP: buffer: use buffer_empty() instead of buffer_len()==0

A few places still made use of buffer_len()==0 to detect an empty
buffer. Use the cleaner and more efficient buffer_empty() instead.

12 years agoBUG/MEDIUM: connection: always update connection flags prior to computing polling
Willy Tarreau [Sun, 16 Dec 2012 18:19:13 +0000 (19:19 +0100)] 
BUG/MEDIUM: connection: always update connection flags prior to computing polling

stream_int_chk_rcv_conn() did not clear connection flags before updating them. It
is unsure whether this could have caused the stalled transfers that have been
reported since dev15.

In order to avoid such further issues, we now use a simple inline function to do
all the job.

12 years agoBUG/MINOR: stream_interface: don't return when the fd is already set
Willy Tarreau [Sat, 15 Dec 2012 09:12:39 +0000 (10:12 +0100)] 
BUG/MINOR: stream_interface: don't return when the fd is already set

Back in the days where polling was made with select() where all FDs
were checked at once, stream_int_chk_snd_conn() used to check whether
the file descriptor it was passed was ready or not, so that it did
not perform the work for nothing.

Right now FDs are checked just before calling the I/O handler so this
test never matches at best, or may return false information at worst.

Since conn_fd_handler() always clears the flags upon exit, it looks
like a missed event cannot happen right now. Still, better remove
this outdated check than wait for it to cause issues.

12 years agoBUG/MEDIUM: stream-interface: fix possible stalls during transfers
Willy Tarreau [Sat, 15 Dec 2012 08:18:05 +0000 (09:18 +0100)] 
BUG/MEDIUM: stream-interface: fix possible stalls during transfers

Sander Klein reported a rare case of POST transfers being stalled
after a few megabytes since dev15. One possible culprit is the fix
for the CPU spinning issues which is not totally correct, because
stream_int_chk_snd_conn() would inconditionally enable the
CO_FL_CURR_WR_ENA flag.

What could theorically happen is the following sequence :
  1) send buffer is empty, server-side polling is disabled
  2) client sends some data
  3) such data are forwarded to the server using
     stream_int_chk_snd_conn()
  4) conn->flags |= CO_FL_CURR_WR_ENA
  5) si_conn_send_loop() is called
  6) raw_sock_from_buf() does a partial write due to full kernel buffers
  7) stream_int_chk_snd_conn() detects this and requests to be called
     to send the remaining data using __conn_data_want_send(), and clears
     the SI_FL_WAIT_DATA flag on the stream interface, indicating that it
     is already congestionned.
  8) conn_cond_update_polling() calls conn_data_update_polling() which
     sees that both CO_FL_DATA_WR_ENA and CO_FL_CURR_WR_ENA are set, so
     it does not enable polling on the output fd.
  9) the next chunk from the client fills the buffer
  10) stream_int_chk_snd_conn() is called again
  11) SI_FL_WAIT_DATA is already cleared, so the function immediately
      returns without doing anything.
  12) the buffer is now full with the FD write polling disabled and
      everything deadlocks.

Not that there is no reason for such an issue not to happen the other
way around, from server to client, except maybe that due to the speed
difference between the client and the server, client-side polling is
always enabled and the buffer is never empty.

All this shows that the new polling still looks fragile, in part due
to the double information on the FD status, being both in fdtab[] and
in the connection, which looks unavoidable. We should probably have
some functions to tighten the relation between such flags and avoid
manipulating them by hand.

Also, the effects of chk_snd() on the polling are still under-estimated,
while the relation between the stream_int and the FD is still too much
present. Maybe the function should be rethought to only call the connection's
fd handler.  The connection model probably needs two calling conventions
for bottom half and upper half.

12 years agoBUG/MINOR: ssl: error is not reported if it occurs simultaneously with peer close...
Emeric Brun [Fri, 14 Dec 2012 11:33:41 +0000 (12:33 +0100)] 
BUG/MINOR: ssl: error is not reported if it occurs simultaneously with peer close detection.

12 years agoBUG/MEDIUM: ssl: Prevent ssl error from affecting other connections.
Emeric Brun [Fri, 14 Dec 2012 10:21:13 +0000 (11:21 +0100)] 
BUG/MEDIUM: ssl: Prevent ssl error from affecting other connections.

J. Maurice reported that ssllabs.com test affects unrelated
legitimate traffic and cause SSL errors and broken connections.

Sometimes openssl store read/write/handshake errors in a global stack. This
stack is not specific to the current session. Openssl API does not clean the
stack at the beginning of a new read/write. And the function used to retrieve
error ID after read/write, returns the generic error SSL_ERROR_SSL if the
global stack is not empty.

The fix consists in cleaning the errors stack after read/write/handshake
errors.

12 years agoMINOR: http: make resp_ver and status ACLs check for the presence of a response
Willy Tarreau [Fri, 14 Dec 2012 07:33:14 +0000 (08:33 +0100)] 
MINOR: http: make resp_ver and status ACLs check for the presence of a response

The two ACL fetches "resp_ver" and "status", if used in a request despite
the warning, would return a match of zero length. This is inappropriate,
better return a non-match to be more consistent with other ACL processing.

12 years agoBUG/MINOR: poll: the I/O handler was called twice for polled I/Os
Willy Tarreau [Thu, 13 Dec 2012 23:17:03 +0000 (00:17 +0100)] 
BUG/MINOR: poll: the I/O handler was called twice for polled I/Os

When a polled I/O event is detected, the event is added to the updates
list and the I/O handler is called. Upon return, if the event handler
did not experience an EAGAIN, the event remains in the updates list so
that it will be processed later. But if the event was already in the
spec list, its state is updated and it will be called again immediately
upon exit, by fd_process_spec_events(), so this creates unfairness
between speculative events and polled events.

So don't call the I/O handler upon I/O detection when the FD already is
in the spec list. The fd events are still updated so that the spec list
is up to date with the possible I/O change.

12 years agoOPTIM: epoll: current fd does not count as a new one
Willy Tarreau [Thu, 13 Dec 2012 23:02:33 +0000 (00:02 +0100)] 
OPTIM: epoll: current fd does not count as a new one

The epoll loop checks for newly appeared FDs in order to process them early
if they're accepted sockets. Since the introduction of the fd_ev_set()
calls before the iocb(), the current FD is always in the update list,
and we don't want to check it again, so we must assign the old_updt
index just before calling the I/O handler.

12 years agoOPTIM: epoll: use a temp variable for intermediary flag computations
Willy Tarreau [Thu, 13 Dec 2012 22:52:58 +0000 (23:52 +0100)] 
OPTIM: epoll: use a temp variable for intermediary flag computations

Playing with fdtab[fd].ev makes gcc constantly reload the pointers
because it does not know they don't alias. Use a temporary variable
instead. This saves a few operations in the fast path.

12 years agoCLEANUP: poll: remove a useless double-check on fdtab[fd].owner
Willy Tarreau [Thu, 13 Dec 2012 22:41:12 +0000 (23:41 +0100)] 
CLEANUP: poll: remove a useless double-check on fdtab[fd].owner

This check is already performed a few lines above in the same loop,
remove it from the condition.

12 years agoOPTIM: poll: optimize fd management functions for low register count CPUs
Willy Tarreau [Thu, 13 Dec 2012 22:34:18 +0000 (23:34 +0100)] 
OPTIM: poll: optimize fd management functions for low register count CPUs

Looking at the assembly code that updt_fd() and alloc/release_spec_entry
produce in the polling loops, it's clear that gcc has to recompute pointers
several times in a row because of limited spare registers. By better
grouping adjacent structure updates, we improve the code size by around
60 bytes in the fast path on x86.

12 years agoCLEANUP: polling: gcc doesn't always optimize constants away
Willy Tarreau [Thu, 13 Dec 2012 21:26:37 +0000 (22:26 +0100)] 
CLEANUP: polling: gcc doesn't always optimize constants away

In ev_poll and ev_epoll, we have a bit-to-bit mapping between the POLL_
constants and the FD_POLL_ constants. A comment said that gcc was able
to detect this and to automatically apply a mask. Things have possibly
changed since the output assembly doesn't always reflect this. So let's
perform an explicit assignment when bits are equal.

12 years agoMINOR: contrib: make the iprange tool grep for addresses
Willy Tarreau [Wed, 12 Dec 2012 23:11:02 +0000 (00:11 +0100)] 
MINOR: contrib: make the iprange tool grep for addresses

The iprange tool is handy for transforming network range formats, but
it's common to need a tool for running quick checks on the output.
The tool now supports a list of addresses on the command line, and it
will only output those which match. It's absolutely inefficient but is
handy for debugging.

12 years ago[RELEASE] Released version 1.5-dev15 v1.5-dev15
Willy Tarreau [Tue, 11 Dec 2012 23:39:52 +0000 (00:39 +0100)] 
[RELEASE] Released version 1.5-dev15

Released version 1.5-dev15 with the following main changes :
    - DOC: add a few precisions on compression
    - BUG/MEDIUM: ssl: Fix handshake failure on session resumption with client cert.
    - BUG/MINOR: ssl: One free session in cache remains unused.
    - BUG/MEDIUM: ssl: first outgoing connection would fail with {ca,crt}-ignore-err
    - MEDIUM: ssl: manage shared cache by blocks for huge sessions.
    - MINOR: acl: add fetch for server session rate
    - BUG/MINOR: compression: Content-Type is case insensitive
    - MINOR: compression: disable on multipart or status != 200
    - BUG/MINOR: http: don't report client aborts as server errors
    - MINOR: stats: compute the ratio of compressed response based on 2xx responses
    - MINOR: http: factor out the content-type checks
    - BUG/MAJOR: stats: correctly check for a possible divide error when showing compression ratios
    - BUILD: ssl: OpenSSL 0.9.6 has no renegociation
    - BUG/MINOR: http: disable compression when message has no body
    - MINOR: compression: make the stats a bit more robust
    - BUG/MEDIUM: comp: DEFAULT_MAXZLIBMEM was expressed in bytes and not megabytes
    - MINOR: connection: don't remove failed handshake flags
    - MEDIUM: connection: add an error code in connections
    - MEDIUM: connection: add minimal error reporting in logs for incomplete connections
    - MEDIUM: connection: add error reporting for the PROXY protocol header
    - MEDIUM: connection: add error reporting for the SSL
    - DOC: document the connection error format in logs
    - BUG/MINOR: http: don't log a 503 on client errors while waiting for requests
    - BUILD: stdbool is not portable
    - BUILD: ssl: NAME_MAX is not portable, use MAXPATHLEN instead
    - BUG/MAJOR: raw_sock: must check error code on hangup
    - BUG/MAJOR: polling: do not set speculative events on ERR nor HUP
    - BUG/MEDIUM: session: fix FD leak when transport layer logging is enabled
    - MINOR: stats: add a few more information on session dump
    - BUG/MINOR: tcp: set the ADDR_TO_SET flag on outgoing connections
    - CLEANUP: connection: remove unused server/proxy/task/si_applet declarations
    - BUG/MEDIUM: tcp: process could theorically crash on lack of source ports
    - MINOR: cfgparse: mention "interface" in the list of allowed "source" options
    - MEDIUM: connection: introduce "struct conn_src" for servers and proxies
    - CLEANUP: proto_tcp: use the same code to bind servers and backends
    - CLEANUP: backend: use the same tproxy address selection code for servers and backends
    - BUG/MEDIUM: stick-tables: conversions to strings were broken in dev13
    - MEDIUM: proto_tcp: add support for tracking L7 information
    - MEDIUM: counters: add sc1_trackers/sc2_trackers
    - MINOR: http: add the "base32" pattern fetch function
    - MINOR: http: add the "base32+src" fetch method.
    - CLEANUP: session: use an array for the stick counters
    - BUG/MINOR: proto_tcp: fix parsing of "table" in track-sc1/2
    - BUG/MINOR: proto_tcp: bidirectional fetches not supported anymore in track-sc1/2
    - BUG/MAJOR: connection: always recompute polling status upon I/O
    - BUG/MINOR: connection: remove a few synchronous calls to polling updates
    - MINOR: config: improve error checking on TCP stick-table tracking
    - DOC: add some clarifications to the readme

12 years agoDOC: add some clarifications to the readme
Willy Tarreau [Tue, 11 Dec 2012 23:38:22 +0000 (00:38 +0100)] 
DOC: add some clarifications to the readme

Typos, repositories and build options.

12 years agoMINOR: config: improve error checking on TCP stick-table tracking
Willy Tarreau [Tue, 11 Dec 2012 23:25:44 +0000 (00:25 +0100)] 
MINOR: config: improve error checking on TCP stick-table tracking

Commit 5d5b5d added support for multiple types to track-sc* but
forgot to check that the types are compatible with the stick-tables.

12 years agoBUG/MINOR: connection: remove a few synchronous calls to polling updates
Willy Tarreau [Mon, 10 Dec 2012 16:03:52 +0000 (17:03 +0100)] 
BUG/MINOR: connection: remove a few synchronous calls to polling updates

There were a few synchronous calls to polling updates in some functions
called from the connection handler. These ones are not needed and should
be replaced by more efficient and more debugable asynchronous calls.

12 years agoBUG/MAJOR: connection: always recompute polling status upon I/O
Willy Tarreau [Mon, 10 Dec 2012 15:33:38 +0000 (16:33 +0100)] 
BUG/MAJOR: connection: always recompute polling status upon I/O

Bryan Berry and Baptiste Assmann both reported some occasional CPU
spinning loops where haproxy was still processing I/O but burning
CPU for apparently uncaught events.

What happens is the following sequence :
  - proxy is in TCP mode
  - a connection from a client initiates a connection to a server
  - the connection to the server does not immediately happen and is
    polled for
  - in the mean time, the client speaks and the stream interface
    calls ->chk_snd() on the peer connection to send the new data
  - chk_snd() calls send_loop() to send the data. This last one
    makes the connection succeed and empties the buffer, so it
    disables polling on the connection and on the FD by creating
    an update entry.
  - before the update is processed, poll() succeeds and reports
    a write event for this fd. The poller does fd_ev_set() on the
    FD to switch it to speculative mode
  - the IO handler is called with a connection which has no write
    flag but an FD which is enabled in speculative mode.
  - the connection does nothing useful.
  - conn_update_polling() at the end of conn_fd_handler() cannot
    disable the FD because there were no changes on this FD.
  - the handler is left with speculative polling still enabled on
    the FD, and will be called over and over until a poll event is
    needed to transfer data.

There is no perfectly elegant solution to this. At least we should
update the flags indicating the current polling status to reflect
what is being done at the FD level. This will allow to detect that
the FD needs to be disabled upon exit.

chk_snd() also needs minor changes to correctly switch to speculative
polling before calling send_loop(), and to reflect this in the connection
flags. This is needed so that no event remains stuck there without any
polling. In fact, chk_snd() and chk_rcv() should perform the same number
of preparations and cleanups as conn_fd_handler().

12 years agoBUG/MINOR: proto_tcp: bidirectional fetches not supported anymore in track-sc1/2
Willy Tarreau [Sun, 9 Dec 2012 16:04:41 +0000 (17:04 +0100)] 
BUG/MINOR: proto_tcp: bidirectional fetches not supported anymore in track-sc1/2

Sample fetch capabilities indicate when the fetch may be used and not
what it requires, so we need to check if a fetch is compatible with
the direction we want and not if it works backwards.

12 years agoBUG/MINOR: proto_tcp: fix parsing of "table" in track-sc1/2
Willy Tarreau [Sun, 9 Dec 2012 15:57:27 +0000 (16:57 +0100)] 
BUG/MINOR: proto_tcp: fix parsing of "table" in track-sc1/2

Recent commit 5d5b5d8e left the "table" argument in the list of
arguments to parse.

12 years agoCLEANUP: session: use an array for the stick counters
Willy Tarreau [Sun, 9 Dec 2012 14:55:40 +0000 (15:55 +0100)] 
CLEANUP: session: use an array for the stick counters

The stick counters were in two distinct sets of struct members,
causing some code to be duplicated. Now we use an array, which
enables some processing to be performed in loops. This allowed
the code to be shrunk by 700 bytes.

12 years agoMINOR: http: add the "base32+src" fetch method.
Willy Tarreau [Sun, 9 Dec 2012 13:53:32 +0000 (14:53 +0100)] 
MINOR: http: add the "base32+src" fetch method.

This returns the concatenation of the base32 fetch and the src fetch.
The resulting type is of type binary, with a size of 8 or 20 bytes
depending on the source address family. This can be used to track
per-IP, per-URL counters.

12 years agoMINOR: http: add the "base32" pattern fetch function
Willy Tarreau [Sun, 9 Dec 2012 12:38:54 +0000 (13:38 +0100)] 
MINOR: http: add the "base32" pattern fetch function

This returns a 32-bit hash of the value returned by the "base"
fetch method above. This is useful to track per-URL activity on
high traffic sites without having to store all URLs. Instead a
shorter hash is stored, saving a lot of memory. The output type
is an unsigned integer.

12 years agoMEDIUM: counters: add sc1_trackers/sc2_trackers
Willy Tarreau [Sun, 9 Dec 2012 11:16:43 +0000 (12:16 +0100)] 
MEDIUM: counters: add sc1_trackers/sc2_trackers

Returns the current amount of concurrent connections tracking the same
tracked counters. This number is automatically incremented when tracking
begins and decremented when tracking stops. It differs from sc1_conn_cur in
that it does not rely on any stored information but on the table's reference
count (the "use" value which is returned by "show table" on the CLI). This
may sometimes be more suited for layer7 tracking.

12 years agoMEDIUM: proto_tcp: add support for tracking L7 information
Willy Tarreau [Sun, 9 Dec 2012 11:00:04 +0000 (12:00 +0100)] 
MEDIUM: proto_tcp: add support for tracking L7 information

Until now it was only possible to use track-sc1/sc2 with "src" which
is the IPv4 source address. Now we can use track-sc1/sc2 with any fetch
as well as any transformation type. It works just like the "stick"
directive.

Samples are automatically converted to the correct types for the table.

Only "tcp-request content" rules may use L7 information, and such information
must already be present when the tracking is set up. For example it becomes
possible to track the IP address passed in the X-Forwarded-For header.

HTTP request processing now also considers tracking from backend rules
because we want to be able to update the counters even when the request
was already parsed and tracked.

Some more controls need to be performed (eg: samples do not distinguish
between L4 and L6).

12 years agoBUG/MEDIUM: stick-tables: conversions to strings were broken in dev13
Willy Tarreau [Sun, 9 Dec 2012 10:08:14 +0000 (11:08 +0100)] 
BUG/MEDIUM: stick-tables: conversions to strings were broken in dev13

Commit 07115412 (MEDIUM: stick-table: allocate the table key...) broke
conversion of samples to strings for stick tables, because if replaced
char buf[BUFSIZE] with char buf[0] and the string converters use sizeof
on this part. Note that sizeof was wrong as well but at least it used
to work.

Fix this by making use of the len parameter instead of sizeof.

12 years agoCLEANUP: backend: use the same tproxy address selection code for servers and backends
Willy Tarreau [Sat, 8 Dec 2012 22:13:33 +0000 (23:13 +0100)] 
CLEANUP: backend: use the same tproxy address selection code for servers and backends

This is just like previous commit, but for the backend this time. All this
code did not need to remain duplicated. These are 500 more bytes shaved off.

12 years agoCLEANUP: proto_tcp: use the same code to bind servers and backends
Willy Tarreau [Sat, 8 Dec 2012 21:49:11 +0000 (22:49 +0100)] 
CLEANUP: proto_tcp: use the same code to bind servers and backends

The tproxy and source binding code has now be factored out for
servers and backends. A nice effect is that the code now supports
having backends use source port ranges, though the config does not
support it yet. This change has reduced the executable by around
700 bytes.

12 years agoMEDIUM: connection: introduce "struct conn_src" for servers and proxies
Willy Tarreau [Sat, 8 Dec 2012 21:29:20 +0000 (22:29 +0100)] 
MEDIUM: connection: introduce "struct conn_src" for servers and proxies

Both servers and proxies share a common set of parameters for outgoing
connections, and since they're not stored in a similar structure, a lot
of code is duplicated in the connection setup, which is one sensible
area.

Let's first define a common struct for these settings and make use of it.
Next patches will de-duplicate code.

This change also fixes a build breakage that happens when USE_LINUX_TPROXY
is not set but USE_CTTPROXY is set, which seem to be very unlikely
considering that the issue was introduced almost 2 years ago an never
reported.

12 years agoMINOR: cfgparse: mention "interface" in the list of allowed "source" options
Willy Tarreau [Sat, 8 Dec 2012 22:21:19 +0000 (23:21 +0100)] 
MINOR: cfgparse: mention "interface" in the list of allowed "source" options

"interface" was only mentionned for the proxy source address but not
for the server's.

12 years agoBUG/MEDIUM: tcp: process could theorically crash on lack of source ports
Willy Tarreau [Sat, 8 Dec 2012 22:03:28 +0000 (23:03 +0100)] 
BUG/MEDIUM: tcp: process could theorically crash on lack of source ports

When connect() fails with EAGAIN or EADDRINUSE, an error message is
sent to logs and uses srv->id to indicate the server name (this is
very old code). Since version 1.4, it is possible to have srv == NULL,
so the message could cause a crash when connect() returns EAGAIN or
EADDRINUSE. However in practice this does not happen because on lack
of source ports, EADDRNOTAVAIL is returned instead, so this code is
never called.

This fix consists in not displaying the server name anymore, and in
adding the test for EADDRNOTAVAIL.

Also, the log level was lowered from LOG_EMERG to LOG_ERR in order
not to spam all consoles when source ports are missing for a given
target.

This fix should be backported to 1.4.

12 years agoCLEANUP: connection: remove unused server/proxy/task/si_applet declarations
Willy Tarreau [Sat, 8 Dec 2012 20:43:36 +0000 (21:43 +0100)] 
CLEANUP: connection: remove unused server/proxy/task/si_applet declarations

These ones are left-overs from the code before the introduction of
obj_type.

12 years agoBUG/MINOR: tcp: set the ADDR_TO_SET flag on outgoing connections
Willy Tarreau [Sat, 8 Dec 2012 17:53:44 +0000 (18:53 +0100)] 
BUG/MINOR: tcp: set the ADDR_TO_SET flag on outgoing connections

tcp_connect_server() resets all of the connection's flags. This means
that an outgoing connection does not have the ADDR_TO_SET flag
eventhough the address is set.

The first impact is that logging the outgoing address or displaying
it on the CLI while dumping sessions will result in an extra call to
getpeername().

But there is a nastier impact. If such a lookup happens *after* the
first connect() attempt and this one fails, the destination address
is corrupted by the call to getsockname(), and subsequent connection
retries will fail with socket errors.

For now we fix this by making tcp_connect_server() set the flag. But
we'll soon need a function to initialize an outgoing connection with
appropriate address and flags before calling the connect() function.

12 years agoMINOR: stats: add a few more information on session dump
Willy Tarreau [Sat, 8 Dec 2012 16:48:47 +0000 (17:48 +0100)] 
MINOR: stats: add a few more information on session dump

We also report fd.spec_p, fd.updt and a few names instead of the values.

12 years agoBUG/MEDIUM: session: fix FD leak when transport layer logging is enabled
Willy Tarreau [Sat, 8 Dec 2012 07:44:02 +0000 (08:44 +0100)] 
BUG/MEDIUM: session: fix FD leak when transport layer logging is enabled

Commit 2b199c9a attempted to fix all places where the transport layer
is improperly closed, but it missed one place in session_free(). If
SSL ciphers are logged, the close() is delayed post-log and performed
in session_free(). However, conn_xprt_close() only closes the transport
layer but not the file descriptor, resulting in a slow FD leak which is
hardly noticeable until the process cannot accept any new connection.

A workaround consisted in disabling %sslv/%sslc in log-format.

So use conn_full_close() instead of conn_xprt_close() to fix this there
too.

A similar pending issue existed in the close during outgoing connection
failure, though on this side, the transport layer is never tracked at the
moment.

12 years agoBUG/MAJOR: polling: do not set speculative events on ERR nor HUP
Willy Tarreau [Thu, 6 Dec 2012 23:09:43 +0000 (00:09 +0100)] 
BUG/MAJOR: polling: do not set speculative events on ERR nor HUP

Errors and Hangups are sticky events, which means that once they're
detected, we never clear them, allowing them to be handled later if
needed.

Till now when an error was reported, it used to register a speculative
I/O event for both recv and send. Since the connection had not requested
such events, it was not able to detect a change and did not clear them,
so the events were called in loops until a timeout caused their owner
task to die.

So this patch does two things :
  - stop registering spec events when no I/O activity was requested,
    so that we don't end up with non-disablable polling state ;

  - keep the sticky polling flags (ERR and HUP) when leaving the
    connection handler so that an error notification doesn't
    magically become a normal recv() or send() report once the
    event is converted to a spec event.

It is normally not needed to make the connection handler emit an
error when it detects POLL_ERR because either a registered data
handler will have done it, or the event will be disabled by the
wake() callback.

12 years agoBUG/MAJOR: raw_sock: must check error code on hangup
Willy Tarreau [Thu, 6 Dec 2012 23:01:33 +0000 (00:01 +0100)] 
BUG/MAJOR: raw_sock: must check error code on hangup

In raw_sock, we already check for FD_POLL_HUP after a short recv()
to avoid a useless syscall and detect the end of stream. However,
we fail to check for FD_POLL_ERR here, which causes major issues
as some errors might be delivered and ignored if they are delivered
at the same time as a HUP, and there is no data to send to detect
them on the other direction.

Since the connections flags do not have the CO_FL_ERROR flag, the
polling is not disabled on the socket and the pollers immediately
call the conn_fd_handler() again, resulting in CPU spikes for as
long as the timeouts allow them.

Note that this patch alone fixes the issue but a few patches will
follow to strengthen this fragile area.

Big thanks to Bryan Berry who reported the issue with significant
amounts of detailed traces that helped rule out many other initially
suspected causes and to finally reproduce the issue in the lab.

12 years agoBUILD: ssl: NAME_MAX is not portable, use MAXPATHLEN instead
Willy Tarreau [Thu, 6 Dec 2012 10:36:59 +0000 (11:36 +0100)] 
BUILD: ssl: NAME_MAX is not portable, use MAXPATHLEN instead

At least Solaris doesn't know about NAME_MAX, so let's use the more portable
MAXPATHLEN instead. This issue was reported by Benjamin Polidore.

12 years agoMINOR: acl: add fetch for server session rate
Tait Clarridge [Thu, 6 Dec 2012 02:39:31 +0000 (21:39 -0500)] 
MINOR: acl: add fetch for server session rate

Considering there is no option yet for maxconnrate for servers, I wrote
an ACL to check a backend server session rate which we use to send to an
"overflow" backend to prevent latency responses to our clients (very
sensitive latency requirements).

12 years agoBUILD: stdbool is not portable
Willy Tarreau [Wed, 5 Dec 2012 22:01:12 +0000 (23:01 +0100)] 
BUILD: stdbool is not portable

Benjamin Polidore reported a build issue on Solaris with gcc 4.2.4 where
stdbool is not usable without c99. It only appeared at one location in
dumpstats and is totally useless, let's use the more common and portable
int as everywhere else.

12 years agoMEDIUM: ssl: manage shared cache by blocks for huge sessions.
Emeric Brun [Wed, 28 Nov 2012 17:47:52 +0000 (18:47 +0100)] 
MEDIUM: ssl: manage shared cache by blocks for huge sessions.

Sessions using client certs are huge (more than 1 kB) and do not fit
in session cache, or require a huge cache.

In this new implementation sshcachesize set a number of available blocks
instead a number of available sessions.

Each block is large enough (128 bytes) to store a simple session (without
client certs).

Huge sessions will take multiple blocks depending on client certificate size.

Note: some unused code for session sync with remote peers was temporarily
      removed.

12 years agoBUG/MINOR: http: don't log a 503 on client errors while waiting for requests
Willy Tarreau [Tue, 4 Dec 2012 09:39:01 +0000 (10:39 +0100)] 
BUG/MINOR: http: don't log a 503 on client errors while waiting for requests

If a client aborts a request with an error (typically a TCP reset), we must
log a 400. Till now we did not set the status nor close the stream interface,
causing the request to attempt to be forwarded and logging a 503.

Should be backported to 1.4 which is affected as well.

12 years agoBUG/MEDIUM: ssl: first outgoing connection would fail with {ca,crt}-ignore-err
Emeric Brun [Mon, 3 Dec 2012 12:24:29 +0000 (13:24 +0100)] 
BUG/MEDIUM: ssl: first outgoing connection would fail with {ca,crt}-ignore-err

When using ca_ignore_err/crt_ignore_err, a connection to an untrusted
server raises an error which is ignored. But the next SSL_read() that
encounters EAGAIN raises the error again, breaking the connection.

Subsequent connections don't have this problem because the session has
been stored and is correctly reused without performing a verify again.

The solution consists in correctly flushing the SSL error stack when
ignoring the crt/ca error.

12 years agoBUG/MINOR: ssl: One free session in cache remains unused.
Emeric Brun [Wed, 28 Nov 2012 10:41:01 +0000 (11:41 +0100)] 
BUG/MINOR: ssl: One free session in cache remains unused.

12 years agoDOC: document the connection error format in logs
Willy Tarreau [Mon, 3 Dec 2012 17:40:10 +0000 (18:40 +0100)] 
DOC: document the connection error format in logs

This is for failed connection handshakes that are now logged.

12 years agoMEDIUM: connection: add error reporting for the SSL
Willy Tarreau [Mon, 3 Dec 2012 15:32:10 +0000 (16:32 +0100)] 
MEDIUM: connection: add error reporting for the SSL

Get a bit more info in the logs when client-side SSL handshakes fail.