Commit Graph

1240 Commits

Author SHA1 Message Date
Willy Tarreau
1ba0e5f451 [BUG] debug: wrong pointer was used to report a status line
This would only be wrong when the server has not completely responded yet.
Fix two other occurrences of wrong rsp<->sl associations which were harmless
but wrong anyway.
2010-06-07 22:43:55 +02:00
Willy Tarreau
79ebac602d [BUG] http: report correct flags in case of client aborts during body
Some client abort/timeouts during body transfer were reported as "PR--"
instead of "CD--" or "cD--". This fix has to be ported to 1.5.
2010-06-07 22:43:54 +02:00
Willy Tarreau
d9bbe17b7f [BUG] proxy: connection rate limiting was eating lots of CPU
The rate-limit feature relied on a timer to define how long a frontend
must remain idle. It was not considering the pending connections, so it
was almost always ready to be used again and only the accept's limit was
preventing new connections from coming in. By accounting for the pending
connection, we can compute a correct delay and effectively make the
frontend go idle for that (short) time.
2010-06-07 22:43:54 +02:00
Willy Tarreau
4fe4190278 [BUG] http: automatically close response if req is aborted
Latest BF_READ_ATTACHED fix has unveiled a nice issue with the way
HTTP requests and responses are forwarded. The case where the request
aborts after the response has responded (POST with early response)
forgot to re-enable auto-close on the response. In fact it still
worked thanks to a side effect as long as BF_READ_ATTACHED was there
to force the states to be resynced (and the flags). Since last fix,
the missing auto-close causes CLOSE_WAIT connections when the client
aborts too late during a data transfer.

The right fix consists in considering the situation where the client
experiences an error and to explicitly abort the transfer. There is
no need to wake the response analysers up for that since they'd have
no added value and the analysers flags are cleared. However for a
future usage, that might help (eg: stickiness, ...).

This fix should be backported to 1.4 if the previous one is backported
too. After all the non-reg tests, the risks to see a problem arise
without both patches seems low, and both patches touch sensible areas
of the code. So there's no hurry.
2010-06-07 22:42:44 +02:00
Willy Tarreau
a6eebb372d [BUG] session: clear BF_READ_ATTACHED before next I/O
The BF_READ_ATTACHED flag was created to wake analysers once after
a connection was established. It turns out that this flag is never
cleared once set, so even if there is no event, some analysers are
still evaluated for no reason.

The bug was introduced with commit ea38854d34.
It may cause slightly increased CPU usages during data transfers, maybe
even quite noticeable once when transferring transfer-encoded data,
due to the fact that the request analysers are being checked for every
chunk.

This fix must be backported in 1.4 after all non-reg tests have been
completed.
2010-06-04 14:49:52 +02:00
Willy Tarreau
e29e1c5df4 [BUG] client: always ensure to zero rep->analysers
The response analyser was not emptied upon creation of a new session. In
fact it was always zero just because last session leaved it in a zero state,
but in case of shared pools this cannot be guaranteed. The net effect is
that it was possible to have some HTTP (or any other) analysers on the
response path of a stats unix socket, which would reject the response.

This fix must be backported to 1.4.
2010-06-04 14:49:27 +02:00
Willy Tarreau
39e4f62186 [BUG] http: the transaction must be initialized even in TCP mode (part 2)
Commit 4605e3b641cebbdbb2ee5726e5bbc3c03a2d7b5e was not enough, because
connections passing from a TCP frontend to an HTTP backend without any
ACL and via a "default_backend" statement were still working on non-initialized
data. An initialization was missing in the session_set_backend() function, next
to the initialization of hdr_idx.
2010-06-04 14:37:05 +02:00
Willy Tarreau
dd701651fe [BUG] consistent hash: balance on all servers, not only 2 !
It was once reported at least by Dirk Taggesell that the consistent
hash had a very poor distribution, making use of only two servers.
Jeff Persch analysed the code and found the root cause. Consistent
hash makes use of the server IDs, which are completed after the chash
array initialization. This implies that each server which does not
have an explicit "id" parameter will be merged at the same place in
the chash tree and that in the end, only the first or last servers
may be used.

The now obvious fix (thanks to Jeff) is to assign the missing IDs
earlier. However, it should be clearly understood that changing a
hash algorithm on live systems will rebalance the whole system.
Anyway, the only affected users will be the ones for which the
system is quite unbalanced already. The ones who fix their IDs are
not affected at all.

Kudos to Jeff for spotting that bug which got merged 3 days after
the consistent hashing !
2010-06-04 14:36:39 +02:00
Willy Tarreau
23968d898a [BUG] tcp: dropped connections must be counted as "denied" not "failed"
This probably was a copy-paste typo from the initial tcp-request feature.
This must be backported to 1.4 and possibly 1.3.
2010-05-28 18:10:31 +02:00
Willy Tarreau
a3445fce16 [BUG] http: the transaction must be initialized even in TCP mode
When running in pure TCP mode with a traffic inspection rule to detect
HTTP protocol, we have to initialize the HTTP transaction too. The
effect of not doing this was that some incoming connections could have
been matched as carrying HTTP protocol eventhough this was not the case.
2010-05-23 08:56:02 +02:00
Willy Tarreau
d45b3d5aff [BUG] http: dispatch and http_proxy modes were broken for a long time
Both dispatch and http_proxy modes were broken since 1.4-dev5 when
the adjustment of server health based on response codes was introduced.
In fact, in these modes, s->srv == NULL. The result is a plain segfault.
It should have been noted critical, but the fact that it remained 6
months without being noticed indicates that almost nobody uses these
modes anymore. Also, the crash is immediate upon first request.

Further versions should not be affected anymore since it's planned to
have a dummy server instead of these annoying NULL pointers.
2010-05-23 08:56:02 +02:00
Willy Tarreau
0b1cd94c8b [MINOR] acl: add srv_is_up() to check that a specific server is up or not
This ACL was missing in complex setups where the status of a remote site
has to be considered in switching decisions. Until there, using a server's
status in an ACL required to have a dedicated backend, which is a bit heavy
when multiple servers have to be monitored.
2010-05-16 22:18:27 +02:00
Willy Tarreau
020534d6f7 [CLEANUP] acl: make use of eb_is_empty() instead of open coding the tree's emptiness test
Since ebtree 6.0.1, we now have eb_is_empty() which is cleaner and safer to
use than checking the left pointer of the tree, so let's use that.
2010-05-16 21:45:45 +02:00
Willy Tarreau
4a568976c5 [MINOR] stick-tables: add support for "stick on hdr"
It is now possible to stick on an IP address found in a HTTP header. Right
now only the last occurrence of the header can be used, which is generally
enough for most uses. Also, the header extraction rule only knows how to
convert the header to IP. Later it will be usable as a plain string with
an implicit conversion, and the syntax will not change.
2010-05-13 22:10:02 +02:00
Willy Tarreau
58215a01af [MINOR] acl: ignore empty lines and comments in pattern files
Most often, pattern files used by ACLs will be produced by tools
which emit some comments (eg: geolocation lists). It's very annoying
to have to clean the files before using them, and it does not make
much sense to be able to support patterns we already can't input in
the config file. So this patch makes the pattern file loader skip
lines beginning with a sharp and the empty ones, and strips leading
spaces and tabs.
2010-05-13 22:10:02 +02:00
Willy Tarreau
b337b532de [MEDIUM] acl: add tree-based lookups of networks
Networks patterns loaded from files for longest match ACL testing
will now be arranged into a prefix tree. This is possible thanks to
the new prefix features in ebtree v6.0. Longest match testing is
slightly slower than exact data maching. However, the measured impact
of running at 42000 requests per second and testing whether the IP
address found in a header belongs to a list of 52000 networks or
not is 3% CPU (increase from 66% to 69%). This is low enough to
permit true geolocation based on huge tables.
2010-05-13 21:37:50 +02:00
Willy Tarreau
c4262961f8 [MEDIUM] acl: add tree-based lookups of exact strings
Now if some ACL patterns are loaded from a file and the operation is
an exact string match, the data will be arranged in a tree, yielding
a significant performance boost on large data sets. Note that this
only works when case is sensitive.

A new dedicated function, acl_lookup_str(), has been created for this
matching. It is called for every possible input data to test and it
looks the tree up for the data. Since the keywords are loosely typed,
we would have had to add a new columns to all keywords to adjust the
function depending on the type. Instead, we just compare on the match
function. We call acl_lookup_str() when we could use acl_match_str().
The tree lookup is performed first, then the remaining patterns are
attempted if the tree returned nothing.

A quick test shows that when matching a header against a list of 52000
network names, haproxy uses 68% of one core on a core2-duo 3.2 GHz at
42000 requests per second, versus 66% without any rule, which means
only a 2% CPU increase for 52000 rules. Doing the same test without
the tree leads to 100% CPU at 6900 requests/s. Also it was possible
to run the same test at full speed with about 50 sets of 52000 rules
without any measurable performance drop.
2010-05-13 21:37:45 +02:00
Willy Tarreau
e56cda9a6a [MEDIUM] acl: add ability to insert patterns in trees
The code is now ready to support loading pattern from filesinto trees. For
that, it will be required that the ACL keyword has a flag ACL_MAY_LOOKUP
and that the expr is case sensitive. When that is true, the pattern will
have a flag ACL_PAT_F_TREE_OK to indicate that it is possible to feed the
tree instead of a usual pattern if the parsing function is able to do this.
The tree's root is pre-initialized in the pattern's value so that the
function can easily find it. At that point, if the parsing function decides
to use the tree, it just sets ACL_PAT_F_TREE in the return flags so that
the caller knows the tree has been used and the pattern can be recycled.

That way it will be possible to load some patterns into the tree when it
is compatible, and other ones as linear linked lists. A good example of
this might be IPv4 network entries : right now we support holes in masks,
but this very rare feature is not compatible with binary lookup in trees.
So the parser will be able to decide itself whether the pattern can go to
the tree or not.
2010-05-13 21:37:41 +02:00
Willy Tarreau
2b5285da33 [MINOR] acl: support loading values from files
The "acl XXX -f <file>" syntax was supported but nothing was read from
the file. This is now possible. All lines are merged verbatim, even if
they contain spaces (useful for user-agents). There are shortcomings
though. The worst one is that error reporting is too approximative.
2010-05-09 23:45:24 +02:00
Delta Yeh
af01c7c2a6 [BUG] cttproxy: socket fd leakage in check_cttproxy_version
in cttproxy.c check_cttproxy_version socket is not closed before function
returned. Although it is called only once, I think it is better to close
the socket.
2010-05-09 21:19:08 +02:00
Willy Tarreau
c3bfeebdb4 [MINOR] fix possible crash in debug mode with invalid responses
When trying to display an invalid request or response we received,
we must at least check that we have identified something looking
like a start of message, otherwise we can dereference a NULL pointer.
2010-04-29 07:09:25 +02:00
Willy Tarreau
e52564c4dd [MINOR] option http-pretend-keepalive is both for FEs and BEs
The config parser only accepted it in frontends.
2010-04-27 22:19:14 +02:00
Cyril Bont
47fdd8e993 [MINOR] add the "ignore-persist" option to conditionally ignore persistence
This is used to disable persistence depending on some conditions (for
example using an ACL matching static files or a specific User-Agent).
You can see it as a complement to "force-persist".

In the configuration file, the force-persist/ignore-persist declaration
order define the rules priority.

Used with the "appsesion" keyword, it can also help reducing memory usage,
as the session won't be hashed the persistence is ignored.
2010-04-25 22:37:14 +02:00
Cyril Bont
17530c34e4 [BUG] appsession should match the whole cookie name
I met a strange behaviour with appsession.

I firstly thought this was a regression due to one of my previous patch
but after testing with a 1.3.15.12 version, I also could reproduce it.

To illustrate, the configuration contains :
  appsession PHPSESSID len 32 timeout 1h

Then I call a short PHP script containing :
  setcookie("P", "should not match")

When calling this script thru haproxy, the cookie "P" matches the appsession rule :
Dumping hashtable 0x11f05c8
        table[1572]:    should+not+match

Shouldn't it be ignored ?
If you confirm, I'll send a patch for 1.3 and 1.4 branches to check that the
cookie length is equal to the appsession name length.

This is due to the comparison length, where the cookie length is took into
account instead of the appsession name length. Using the appsession name
length would allow ASPSESSIONIDXXX (+ check that memcmp won't go after the
buffer size).

Also, while testing, I noticed that HEAD requests where not available for
URIs containing the appsession parameter. 1.4.3 patch fixes an horrible
segfault I missed in a previous patch when appsession is not in the
configuration and HAProxy is compiled with DEBUG_HASH.
2010-04-07 21:56:10 +02:00
Willy Tarreau
70160200e0 [MINOR] config: report "default-server" instead of "(null)" in error messages
When an error is reported in a default-server entry, we want to have
that name in the error message instead of "(null)".
2010-04-07 16:06:40 +02:00
Willy Tarreau
8a8e1d99cb [MINOR] http: make it possible to pretend keep-alive when doing close
Some servers do not completely conform with RFC2616 requirements for
keep-alive when they receive a request with "Connection: close". More
specifically, they don't bother using chunked encoding, so the client
never knows whether the response is complete or not. One immediately
visible effect is that haproxy cannot maintain client connections alive.
The second issue is that truncated responses may be cached on clients
in case of network error or timeout.

scar Fras Barranco reported this issue on Tomcat 6.0.20, and
Patrik Nilsson with Jetty 6.1.21.

Cyril Bont proposed this smart idea of pretending we run keep-alive
with the server and closing it at the last moment as is already done
with option forceclose. The advantage is that we only change one
emitted header but not the overall behaviour.

Since some servers such as nginx are able to close the connection
very quickly and save network packets when they're aware of the
close negociation in advance, we don't enable this behaviour by
default.

"option http-pretend-keepalive" will have to be used for that, in
conjunction with "option http-server-close".
2010-04-05 16:26:34 +02:00
Willy Tarreau
efa5f51f00 [BUILD] config: last patch breaks build without CONFIG_HAP_LINUX_TPROXY
A few ifdefs were missing in the config validity check function.
2010-03-30 20:13:29 +02:00
Willy Tarreau
bce7088275 [MEDIUM] add ability to connect to a server from an IP found in a header
Using get_ip_from_hdr2() we can look for occurrence #X or #-X and
extract the IP it contains. This is typically designed for use with
the X-Forwarded-For header.

Using "usesrc hdr_ip(name,occ)", it becomes possible to use the IP address
found in <name>, and possibly specify occurrence number <occ>, as the
source to connect to a server. This is possible both in a server and in
a backend's source statement. This is typically used to use the source
IP previously set by a upstream proxy.
2010-03-30 10:39:43 +02:00
Willy Tarreau
090466c91a [MINOR] add new tproxy flags for dynamic source address binding
This patch adds a new TPROXY bind type, TPROXY_DYN, to indicate to the
TCP connect function that we want to bind to the address passed in
argument.
2010-03-30 09:59:44 +02:00
Willy Tarreau
d54bbdce87 [MINOR] add very fast IP parsing functions
Those functions were previouly used in my firewall log parser,
and are particularly suited for use with http headers.
2010-03-30 09:59:44 +02:00
Willy Tarreau
b1d67749db [MEDIUM] backend: move the transparent proxy address selection to backend
The transparent proxy address selection was set in the TCP connect function
which is not the most appropriate place since this function has limited
access to the amount of parameters which could produce a source address.

Instead, now we determine the source address in backend.c:connect_server(),
right after calling assign_server_address() and we assign this address in
the session and pass it to the TCP connect function. This cannot be performed
in assign_server_address() itself because in some cases (transparent mode,
dispatch mode or http_proxy mode), we assign the address somewhere else.

This change will open the ability to bind to addresses extracted from many
other criteria (eg: from a header).
2010-03-30 09:59:43 +02:00
Willy Tarreau
07a5490881 [CLEANUP] proxy: move PR_O_SSL3_CHK to options2 to release one flag
We'll need another flag in the 'options' member close to PR_O_TPXY_*,
and all are used, so let's move this easy one to options2 (which are
already used for SQL checks).
2010-03-30 09:59:43 +02:00
Willy Tarreau
9683909dce [MINOR] checks: add the ability to disable a server in the config
Adding the "disabled" keyword on a server line disables it. It can
then be enabled again on the unix socket.
2010-03-29 11:50:34 +02:00
Willy Tarreau
4554bc189d [MINOR] config: allow "slowstart 0s"
Sometimes it's useful to be able to disable slowstart by setting "slowstart 0".
2010-03-26 10:40:49 +01:00
Willy Tarreau
e24fdfb8be [MINOR] config: emit warnings when HTTP-only options are used in TCP mode
It's very common to see people getting trapped by HTTP-only options
which don't work in TCP proxies. To help them definitely get rid of
those configs, let's emit warnings for all options and statements
which are not supported in their mode. That includes all HTTP-only
options, the cookies and the stats.

In order to ensure internal config correctness, the options are also
disabled.
2010-03-25 07:26:18 +01:00
Willy Tarreau
3fd6cec5f6 [MINOR] cli: "show errors" should display "backend <NONE>" when backend was not used
It was disturbing to see a backend name associated with a bad request
when this "backend" was in fact the frontend. Instead, we now display
"backend <NONE>" if the "backend" has no backend capability :

> show errors

[25/Mar/2010:06:44:25.394] frontend fe (#1): invalid request
  src 127.0.0.1, session #0, backend <NONE> (#-1), server <NONE> (#-1)
  request length 45 bytes, error at position 0:
2010-03-25 06:45:07 +01:00
Willy Tarreau
eaed5a1d46 [BUG] backend: L7 hashing must not be performed on incomplete requests
Isidore Li reported an occasional segfault when using URL hashing, and
kindly provided backtraces and core files to help debugging.

The problem was triggered by reset connections before the URL was sent,
and was due to the same bug which was fixed by commit e45997661b
(connections were attempted in case of connection abort). While that
bug was already fixed, it appeared that the same segfault could be
triggered when URL hashing is configured in an HTTP backend when the
frontend runs in TCP mode and no URL was seen. It is totally abnormal
to try to hash a null URL, as well as to process any kind of L7 hashing
when a full request was not seen.

This additional fix now ensures that layer7 hashing is not performed on
incomplete requests.
2010-03-25 06:32:52 +01:00
Willy Tarreau
e45997661b [MEDIUM] session: better fix for connection to servers with closed input
The following patch fixed an issue but brought another one :
  296897 [MEDIUM] connect to servers even when the input has already been closed

The new issue is that when a connection is inspected and aborted using
TCP inspect rules, now it is sent to the server before being closed. So
that test is not satisfying. A probably better way is not to prevent a
connection from establishing if only BF_SHUTW_NOW is set but BF_SHUTW
is not. That way, the BF_SHUTW flag is not set if the request has any
data pending, which still fixes the stats issue, but does not let any
empty connection pass through.

Also, as a safety measure, we extend buffer_abort() to automatically
disable the BF_AUTO_CONNECT flag. While it appears to always be OK,
it is by pure luck, so better safe than sorry.
2010-03-21 23:31:42 +01:00
Willy Tarreau
4e1554c295 [CLEANUP] stats: remove printf format warning in stats_dump_full_sess_to_buffer()
This warning was first reported by Ross West on FreeBSD, then by
Holger Just on OpenSolaris. It also happens on 64bit Linux. However,
fixing the format to use long int complains on 32bit Linux where
ptrdiff_t is apparently different. Better cast the pointer difference
to an int then.
2010-03-21 23:21:00 +01:00
Cyril Bont
c9f825f060 [OPTIM] config: only allocate check buffer when checks are enabled
To save a little memory, the check_data buffer is only allocated
for the servers that are checked.

[WT: this patch saves 80 MB of RAM on the test config with 5000 servers]
2010-03-17 22:05:23 +01:00
Willy Tarreau
039381855d [BUG] checks: don't wait for a close to start parsing the response
Cyril Bont reported a regression introduced with very last changes
on the checks code, which causes failed checks on if the server does
not close the connection in time. This happens on HTTP/1.1 checks or
on SMTP checks for instance.

This fix consists in restoring the old behaviour of parsing as soon
as something is available in the response buffer, and waiting for
more data if some are missing. This also helps releasing connections
earlier (eg: a GET check will not have to download the whole object).
2010-03-17 21:52:07 +01:00
Willy Tarreau
e437c44483 [BUG] init: unconditionally catch SIGPIPE
Apparently some systems define MSG_NOSIGNAL but do not necessarily
check it (or maybe binaries are built somewhere and used on older
versions). There were reports of very recent FreeBSD setups causing
SIGPIPEs, while older ones catch the signal. Recent FreeBSD manpages
indeed define MSG_NOSIGNAL.

So let's now unconditionnaly catch the signal. It's useless not to do
it for the rare cases where it's not needed (linux 2.4 and below).
2010-03-17 18:02:46 +01:00
Willy Tarreau
bf3f1de5b5 [BUG] http: fix truncated responses on chunk encoding when size divides buffer size
Bernhard Krieger reported truncated HTTP responses in presence of some
specific chunk-encoded data, and kindly offered complete traces of the
issue which made it easy to reproduce it.

Those traces showed that the chunks were of exactly 8192 bytes, chunk
size and CRLF included, which was exactly half the size of the buffer.
In this situation, the function http_chunk_skip_crlf() could erroneously
try to parse a CRLF after the chunk believing there were more data
pending, because the number of bytes present in the buffer was considered
instead of the number of remaining bytes to be parsed.
2010-03-17 15:54:24 +01:00
Willy Tarreau
6315d914b6 [MINOR] checks: make shutdown() silently fail
Shutdown may fail for instance after an RST. So we must not report
any error for that.
2010-03-16 22:57:27 +01:00
Willy Tarreau
659d7bc4e3 [BUG] checks: don't abort when second poll returns an error
Now that the response may be fragmented, we may receive early notifications
of aborts in return of poll(), as indicated below, which currently cause
an early error detection :

  21:11:21.036600 epoll_wait(3, {{EPOLLIN, {u32=7, u64=7}}}, 8, 993) = 1
  21:11:21.054361 gettimeofday({1268770281, 54467}, NULL) = 0
  21:11:21.054540 recv(7, "H"..., 8030, 0) = 1
  21:11:21.054694 recv(7, 0x967e759, 8029, 0) = -1 EAGAIN (Resource temporarily unavailable)
  21:11:21.054843 epoll_wait(3, {{EPOLLIN|EPOLLERR|EPOLLHUP, {u32=7, u64=7}}}, 8, 975) = 1
  21:11:21.060274 gettimeofday({1268770281, 60386}, NULL) = 0
  21:11:21.060454 close(7)                = 0

Just as in stream_sock, we must not believe poll() without attempting to receive,
which fixes the issue :

  21:11:59.402207 recv(7, "H"..., 8030, 0) = 1
  21:11:59.402362 recv(7, 0x8b5c759, 8029, 0) = -1 EAGAIN (Resource temporarily unavailable)
  21:11:59.402511 epoll_wait(3, {{EPOLLIN|EPOLLERR|EPOLLHUP, {u32=7, u64=7}}}, 8, 974) = 1
  21:11:59.407242 gettimeofday({1268770319, 407353}, NULL) = 0
  21:11:59.407425 recv(7, "TTP/1.0 200 OK\r\n"..., 8029, 0) = 16
  21:11:59.407606 recv(7, 0x8b5c769, 8013, 0) = -1 ECONNRESET (Connection reset by peer)
  21:11:59.407753 shutdown(7, 2 /* send and receive */) = -1 ENOTCONN (Transport endpoint is not connected)
2010-03-16 22:57:27 +01:00
Willy Tarreau
c1a07960a6 [BUG] checks: don't report an error when recv() returns an error after data
This happens when a server immediately closes the connection after
the response without lingering or when we close before the end of
the data. We get an RST which translates into a late error. We must
not declare an error without checking that the contents are OK.
2010-03-16 22:57:27 +01:00
Willy Tarreau
2c7ace07ad [OPTIM] checks: try to detect the end of response without polling again
Since the recv() call returns every time it succeeds, we always need
to calls with one intermediate poll before detecting the end of response :

  20:20:03.958207 recv(7, "HTTP/1.1 200\r\nConnection: close\r\n"..., 8030, 0) = 145
  20:20:03.958365 epoll_wait(3, {{EPOLLIN, {u32=7, u64=7}}}, 8, 1000) = 1
  20:20:03.958543 gettimeofday({1268767203, 958626}, NULL) = 0
  20:20:03.958694 recv(7, ""..., 7885, 0) = 0
  20:20:03.958833 shutdown(7, 2 /* send and receive */) = 0

Let's read as long as we can, that way we can detect end of connections
in the same call, which is much more efficient especially for LBs with
hundreds of servers :

  20:29:58.797019 recv(7, "HTTP/1.1 200\r\nConnection: close\r\n"..., 8030, 0) = 145
  20:29:58.797182 recv(7, ""..., 7885, 0) = 0
  20:29:58.797356 shutdown(7, 2 /* send and receive */) = 0
2010-03-16 22:57:27 +01:00
Nick Chalk
57b1bf7785 [MEDIUM] checks: support multi-packet health check responses
We are seeing both real servers repeatedly going on- and off-line with
a period of tens of seconds. Packet tracing, stracing, and adding
debug code to HAProxy itself has revealed that the real servers are
always responding correctly, but HAProxy is sometimes receiving only
part of the response.

It appears that the real servers are sending the test page as three
separate packets. HAProxy receives the contents of one, two, or three
packets, apparently randomly. Naturally, the health check only
succeeds when all three packets' data are seen by HAProxy. If HAProxy
and the real servers are modified to use a plain HTML page for the
health check, the response is in the form of a single packet and the
checks do not fail.

(...)
I've added buffer and length variables to struct server, and allocated
space with the rest of the server initialisation.

(...)
It seems to be working fine in my tests, and handles check responses
that are bigger than the buffer.
2010-03-16 22:57:26 +01:00
Willy Tarreau
3965040898 [MINOR] http: don't mark a server as failed when it returns 501/505
Those two codes can be triggered on demand by client requests.
We must not fail a server on them.

Ideally we should ignore a certain amount of status codes which do
not indicate life nor death.
2010-03-15 19:44:39 +01:00
Willy Tarreau
f53b25d7c1 [BUG] config: fix endless loop when parsing "on-error"
An arg index increment was missing causing the same arg to be parsed
in an endless loop. Proabably a merge conflict that remained undetected.
2010-03-15 19:40:37 +01:00
Willy Tarreau
2a56c5e1c3 [BUG] don't merge anonymous ACLs !
The new anonymous ACL feature was buggy. If several ones are
declared, the first rule is always matched because all of them
share the same internal name (".noname"). Now we simply declare
them with an empty name and ensure that we disable any merging
when the name is empty.
2010-03-15 16:13:29 +01:00
Cyril Bont
7f2c53938c [BUG] clf logs segfault when capturing a non existant header
Hi Willy,

Please find a small patch to prevent haproxy segfaulting when logging captured headers in CLF format.

Example config to reproduce the bug :
listen test :10080
	log 127.0.0.1 local7 debug err
	mode	http
	option	httplog clf
	capture request header NonExistantHeader len 16

--
Cyril Bont
2010-03-14 20:02:10 +01:00
Willy Tarreau
296897f2c6 [MEDIUM] connect to servers even when the input has already been closed
The BF_AUTO_CLOSE flag prevented a connection from establishing on
a server if the other side's input channel was already closed. This
is wrong because there may be pending data to be sent.

This was causing an issue with stats, as noticed and reported by
Cyril Bont. Since the stats are now handled as a server, sometimes
concurrent accesses were causing one of the connections to send the
shutdown(write) before the connection to the stats function was
established, which aborted it early.

This fix causes the BF_AUTO_CLOSE flag to be checked only when the
connection on the outgoing stream interface has reached an established
state. That way we're still able to connect, send the request then
close.
2010-03-14 19:21:34 +01:00
Willy Tarreau
1d21e0a28e [MINOR] force null-termination of hostname
Marcello Gorlani reported that at least on FreeBSD, a long hostname
was reported with garbage on the stats page. POSIX does not make it
mandatory for gethostname() to NULL-terminate the string in case of
truncation, and at least FreeBSD appears not to do it. So let's
force null-termination to keep safe.
2010-03-12 21:58:54 +01:00
Cyril Bont
78caf8449d [DOC] Some more documentation cleanups
Since the last documentation cleanups, I've found more typos that I kept
in a corner instead of sending you a mail just for one character :)

--
Cyril Bont
2010-03-12 06:46:06 +01:00
Willy Tarreau
4256463b5a [BUG] url_param hash may return a down server
Jozef Hovan reported a bug sometimes causing a down server to be
used in url_param hashing mode.

This happens if the following conditions are met :
  - the backend contains more than one server with at least two
    of different weights
  - all servers but one are down
  - the server which is not down has a weight which does not divide
    all the other ones

Example: 3 servers with 20,20,10, the first one remains up.

The problem is caused by an optimisation in recalc_server_map()
which only fills the first map slot when only one server is up,
because all LB algorithms are optimized to use entry zero when
only one server is up... All but url_param. When doing the modulus,
we can return a position which is greater than zero and use an
entry which still refers to a server which has since been stopped.

One solution could be to optimize the url_param algo to proceed
as the other ones, but the fact that was wrong implies that we
can repeat the same bug later. So let's first correctly initialize
the map in order to avoid that trap.
2010-03-12 06:22:16 +01:00
Willy Tarreau
6a8573ef68 [BUG] stats: connection reset counters must be plain ascii, not HTML
Using U2H*() to put numbers in title tags is a bad idea as those
appear in the HTML itself. Problem reported by Laurent Dolosor.
2010-03-05 18:15:23 +01:00
Willy Tarreau
66dc20a17b [MINOR] stats socket: add show sess <id> to dump details about a session
When trying to spot some complex bugs, it's often needed to access
information on stuck sessions, which is quite difficult. This new
command helps one get detailed information about a session, with
flags, timers, states, etc... The buffer data are not dumped yet.
2010-03-05 17:58:04 +01:00
Willy Tarreau
d426a18a04 [MINOR] stats: make the data dump function reusable for other purposes
The dump_error_line() function was limited to dump error buffers while
it's perfectly suitable to dump anything else.
2010-03-05 17:57:41 +01:00
Willy Tarreau
8811f8e82e [MINOR] stats: don't send empty lines in "show errors"
Empty lines indicate end of dump, so it's important not to do that.
Send a single space instead.
2010-03-05 17:56:56 +01:00
Willy Tarreau
bc77530456 [MINOR] proto_uxst: set accept_date upon accept() to the wall clock time
This accept_date field was not set and will be reported in the stats as
the connection's accept date.
2010-03-05 17:56:31 +01:00
Willy Tarreau
6464841769 [BUG] http: don't wait for response data to leave buffer is client has left
In case of pipelined requests, if the client aborts before reading response
N-1, haproxy waits forever for the data to leave the buffer before parsing
the next response.
2010-03-05 10:57:48 +01:00
Willy Tarreau
15e5554467 [CLEANUP] session: remove duplicate test
This duplicate test should have been removed with the loop rework but was forgotten.
It was harmless, but disassembly shows that it prevents gcc from correctly optimizing
the loop.
2010-03-05 10:12:01 +01:00
William Turner
d986526d98 [BUG] Clear-cookie path issue
We have been using haproxy to balance a not very well written application
(http://www.blackboard.com/). Using the "insert postonly indirect" cookie
method, I was attempting to remove the cookie when users would logout,
allowing the machine to re-balance for the next user (this application is
used in school computer labs, so a computer might stay on the whole day
but be used on and off).

I was having a lot of trouble because when the cookie was set, it was with
"Path=/", but when being cleared there was no "Path" in the set cookie
header, and because the logout page was in a different place of the
website (which I couldn't change), the cookie would not be cleared. I
don't know if this would be a problem for anyone other than me (as our
HTTP application is so un-adjustable), but just in case, I have included
the patch I used. Maybe it will help someone else.

[ WT: this was a correct fix, and I also added the same missing path to
  the set-cookie option ]
2010-03-04 23:16:42 +01:00
Willy Tarreau
1104614b57 [MINOR] report total number of processed connections when stopping a proxy
It's sometimes convenient to know if a proxy has processed any connection
at all when stopping it. Since a soft restart causes the "Proxy stopped"
message to be logged for each proxy, let's add the number of connections
so that it's possible afterwards to check whether a proxy had received
any connection.
2010-03-04 23:07:28 +01:00
Willy Tarreau
3e1b6d1ed0 [STATS] frontend requests were not accounted for failed requests
But failed requests were accounted for, resulting in more failures
than requests.
2010-03-04 23:02:38 +01:00
Willy Tarreau
ae52678444 [STATS] count transfer aborts caused by client and by server
Often we need to understand why some transfers were aborted or what
constitutes server response errors. With those two counters, it is
now possible to detect an unexpected transfer abort during a data
phase (eg: too short HTTP response), and to know what part of the
server response errors may in fact be assigned to aborted transfers.
2010-03-04 20:34:23 +01:00
Willy Tarreau
890a33e41f [BUILD] fix platform-dependant build issues related to crypt()
Holger Just and Ross West reported build issues on FreeBSD and
Solaris that were initially caused by the definition of
_XOPEN_SOURCE at the top of auth.c, which was required on Linux
to avoid a build warning.

Krzysztof Oledzki found that using _GNU_SOURCE instead also worked
on Linux and did not cause any issue on several versions of FreeBSD.
Solaris still reported a warning this time, which was fixed by
including <crypt.h>, which itself is not present on FreeBSD nor on
all Linux toolchains.

So by adding a new build option (NEED_CRYPT_H), we can get Solaris
to get crypt() working and stop complaining at the same time, without
impacting other platforms.

This fix was tested at least on several linux toolchains (at least
uclibc, glibc 2.2.5, 2.3.6 and 2.7), on FreeBSD 4 to 8, Solaris 8
(which needs crypt.h), and AIX 5.3 (without crypt.h).

Every time it builds without a warning.
2010-03-04 19:10:14 +01:00
Willy Tarreau
40dba09343 [BUG] logs: don't report "proxy request" when server closes early
A copy-paste typo and a missing check were causing the logs to
report "PR" instead of "SD" when a server closes before sending
full data. Also, the log would erroneously report 502 while in
fact the correct response will already have been transmitted.
2010-03-04 18:45:47 +01:00
Willy Tarreau
033b2dbeb3 [BUG] logs: don't report "last data" when we have just closed after an error
Some people have reported seeing "SL" flags in their logs quite often while
this should never happen. The reason was that then a server error is detected,
we close the connection to that server and when we decide what state we were
in, we see the connection is closed, and deduce it was the last data transfer,
which is wrong. We should report DATA if the previous state was an established
state, which this patch does.

Now logs correctly report "SD" and not "SL" when a server resets a connection
before the end of the transfer.
2010-03-04 18:45:47 +01:00
Willy Tarreau
88e058164a [BUILD] fix some build warnings on Solaris with is* macros
isalnum, isdigit and friends are really annoying because they take
an int in which we should pass an unsigned char, while strings
everywhere use chars. Solaris uses macros relying on an array for
those functions, which easily triggers some warnings showing where
we have mistakenly passed a char instead of an unsigned char or an
int. Those warnings may indicate real bugs on some platforms
depending on the implementation.
2010-03-03 00:16:00 +01:00
Willy Tarreau
e0454096c0 [MINOR] stats: mark areas with an underline when tooltips are available
There are many information available in the stats page that can only
be seen when the mouse hovers over them. But it's hard to know where
those information are. Now with a discrete dotted underline it's easier
to spot those areas.
2010-02-26 12:29:07 +01:00
Willy Tarreau
b44939a66f [MINOR] stats: report the request rate in frontends as cell titles
The current and max request rates are now reported when the mouse flies
over the session rate cur/max. The total requests is displayed with the
status codes over the total sessions cell.
2010-02-26 11:35:39 +01:00
Willy Tarreau
8096de9a99 [MEDIUM] http: revert to use a swap buffer for realignment
The bounce realign function was algorithmically good but as expected
it was not cache-friendly. Using it with large requests caused so many
cache thrashing that the function itself could drain 70% of the total
CPU time for only 0.5% of the calls !

Revert back to a standard memcpy() using a specially allocated swap
buffer. We're now back to 2M req/s on pipelined requests.
2010-02-26 11:12:27 +01:00
Willy Tarreau
2465779459 [STATS] separate frontend and backend HTTP stats
It is wrong to merge FE and BE stats for a proxy because when we consult a
BE's stats, it reflects the FE's stats eventhough the BE has received no
traffic. The most common example happens with listen instances, where the
backend gets credited for all the trafic even when a use_backend rule makes
use of another backend.
2010-02-26 10:30:28 +01:00
Willy Tarreau
d9b587f260 [STATS] report HTTP requests (total and rate) in frontends
Now that we support keep-alive, it's important to report a separate
counter for requests. Right now it just appears in the CSV output.
2010-02-26 10:05:55 +01:00
Willy Tarreau
b97f199d4b [MEDIUM] http: don't use trash to realign large buffers
The trash buffer may now be smaller than a buffer because we can tune
it at run time. This causes a risk when we're trying to use it as a
temporary buffer to realign unaligned requests, because we may have to
put up to a full buffer into it.

Instead of doing a double copy, we're now relying on an open-coded
bouncing copy algorithm. The principle is that we move one byte at
a time to its final place, and if that place also holds a byte, then
we move it too, and so on. We finish when we've moved all the buffer.
It limits the number of memory accesses, but since it proceeds one
byte at a time and with random walk, it's not cache friendly and
should be slower than a double copy. However, it's only used in
extreme situations and the difference will not be noticeable.

It has been extensively tested and works reliably.
2010-02-25 23:54:31 +01:00
Krzysztof Piotr Oledzki
329f74d463 [BUG] uri_auth: do not attemp to convert uri_auth -> http-request more than once
Bug reported by Laurent Dolosor.
2010-02-23 12:36:10 +01:00
Willy Tarreau
2e2b3eb65a [BUILD] fix build breakage with DEBUG_FULL
Paul Hirose reported a build error when DEBUG_FULL is set.
2010-02-09 20:55:44 +01:00
Willy Tarreau
d5191e7768 [BUG] config: report unresolvable host names as errors
When a host name could not be resolved, an alert was emitted but the
service used to start with 0.0.0.0 for the IP address, because the
address parsing functions could not report an error. This is now
changed. This fix must be backported to 1.3 as it was first discovered
there.
2010-02-09 20:50:45 +01:00
Krzysztof Piotr Oledzki
df5cb9f764 [BUG] pxid/puid/luid: don't shift IDs when some of them are forced
[WT: it was not a bug, I did it on purpose to leave no hole between IDs,
 though it's not very practical when admins want to force some entries
 after they have been used, because they'd rather leave a hole than
 renumber everything ]

Forcing some of IDs should not shift others.

Regression introduced in 53fb4ae261

---cut here---
global
        stats socket /home/ole/haproxy.stat user ole group ole mode 660

frontend F1
        bind 127.0.0.1:9999
        mode http

backend B1
        mode http

backend B2
        mode http
        id 9999

backend B3
        mode http

backend B4
        mode http
---cut here---

Before 53fb4ae261:
$ echo "show stat" | socat unix-connect:/home/ole/haproxy.stat stdio|cut -d , -f 28
iid
1
2
9999
4
5

After 53fb4ae261:
$ echo "show stat" | socat unix-connect:/home/ole/haproxy.stat stdio|cut -d , -f 28
iid
1
2
9999
3
4

With this patch:
$ echo "show stat" | socat unix-connect:/home/ole/haproxy.stat stdio|cut -d , -f 28
iid
1
2
9999
4
5
2010-02-06 09:50:24 +01:00
Krzysztof Piotr Oledzki
aff01ea1dc [BUG] cfgparse memory leak and missing free calls in deinit()
Thich patch fixes cfgparser not to leak memory on each
default server statement and adds several missing free
calls in deinit():
 - free(l->name)
 - free(l->counters)
 - free(p->desc);
 - free(p->fwdfor_hdr_name);

None of them are critical, hopefully.
2010-02-06 09:41:00 +01:00
Cyril Bont
0dae5850f6 [MINOR] stats: report maint state for tracking servers too
This is to avoid confusing a real server failure and a tracking server
which is marked down because the tracked server was switched to MAINT.
2010-02-06 09:36:14 +01:00
Willy Tarreau
b4c06b7be6 [BUILD] auth: don't use unnamed unions
unnamed unions are not compatible with older compilers (eg: gcc 2.95) so
name it "u" instead.
2010-02-02 11:28:20 +01:00
Willy Tarreau
b05613d72b [RELEASE] Released version 1.4-rc1
Released version 1.4-rc1 with the following main changes :
    - [MEDIUM] add a maintenance mode to servers
    - [MINOR] http-auth: last fix was wrong
    - [CONTRIB] add base64rev-gen.c that was used to generate the base64rev table.
    - [MINOR] Base64 decode
    - [MINOR] generic auth support with groups and encrypted passwords
    - [MINOR] add ACL_TEST_F_NULL_MATCH
    - [MINOR] http-request: allow/deny/auth support for frontend/backend/listen
    - [MINOR] acl: add http_auth and http_auth_group
    - [MAJOR] use the new auth framework for http stats
    - [DOC] add info about userlists, http-request and http_auth/http_auth_group acls
    - [STATS] make it possible to change a CLI connection timeout
    - [BUG] patterns: copy-paste typo in type conversion arguments
    - [MINOR] pattern: make the converter more flexible by supporting void* and int args
    - [MINOR] standard: str2mask: string to netmask converter
    - [MINOR] pattern: add support for argument parsers for converters
    - [MINOR] pattern: add the "ipmask()" converting function
    - [MINOR] config: off-by-one in "stick-table" after list of converters
    - [CLEANUP] acl, patterns: make use of my_strndup() instead of malloc+memcpy
    - [BUG] restore accidentely removed line in last patch !
    - [MINOR] checks: make the HTTP check code add the CRLF itself
    - [MINOR] checks: add the server's status in the checks
    - [BUILD] halog: make without arch-specific optimizations
    - [BUG] halog: fix segfault in case of empty log in PCT mode (cherry picked from commit fe362fe476)
    - [MINOR] http: disable keep-alive when process is going down
    - [MINOR] acl: add build_acl_cond() to make it easier to add ACLs in config
    - [CLEANUP] config: use build_acl_cond() instead of parse_acl_cond()
    - [CLEANUP] config: use warnif_cond_requires_resp() to check for bad ACLs
    - [MINOR] prepare req_*/rsp_* to receive a condition
    - [CLEANUP] config: specify correct const char types to warnif_* functions
    - [MEDIUM] config: factor out the parsing of 20 req*/rsp* keywords
    - [MEDIUM] http: make the request filter loop check for optional conditions
    - [MEDIUM] http: add support for conditional request filter execution
    - [DOC] add some build info about the AIX platform (cherry picked from commit e41914c77e)
    - [MEDIUM] http: add support for conditional request header addition
    - [MEDIUM] http: add support for conditional response header rewriting
    - [DOC] add some missing ACLs about response header matching
    - [MEDIUM] http: add support for proxy authentication
    - [MINOR] http-auth: make the 'unless' keyword work as expected
    - [CLEANUP] config: use build_acl_cond() to simplify http-request ACL parsing
    - [MEDIUM] add support for anonymous ACLs
    - [MEDIUM] http: switch to tunnel mode after status 101 responses
    - [MEDIUM] http: stricter processing of the CONNECT method
    - [BUG] config: reset check request to avoid double free when switching to ssl/sql
    - [MINOR] config: fix too large ssl-hello-check message.
    - [BUG] fix error response in case of server error
2010-02-02 10:18:28 +01:00
Willy Tarreau
0b89fbb076 [BUG] fix error response in case of server error
The fix below was incomplete :
    commit d5fd51c75b

    [BUG] http_server_error() must not purge a previous pending response

    This can cause parts of responses to be truncated in case of
    pipelined requests if the second request generates an error
    before the first request is completely flushed.

Pending response data being rejected was still sent, causing inappropriate
error responses in case of error while parsing a response header. We must
purge pending data from the response buffer that were not scheduled to be
sent (l - send_max).
2010-02-02 10:04:19 +01:00
Willy Tarreau
137325dc71 [MINOR] config: fix too large ssl-hello-check message.
As reported by Cyril Bont and Herv Commowick, the ssl-hello-check
should use sizeof()-1 and not sizeof() for the message length.
2010-02-01 16:38:17 +01:00
Willy Tarreau
54f6a586cd [BUG] config: reset check request to avoid double free when switching to ssl/sql
SSL and SQL checks did only perform a free() of the request without replacing
it, so having multiple SSL/SQL check declarations after another check type
causes a double free condition during config parsing. This should be backported
although it's harmless.
2010-02-01 16:32:37 +01:00
Willy Tarreau
dc008c57a4 [MEDIUM] http: stricter processing of the CONNECT method
Now we establish the tunnel only once the status 200 reponse is
received. That way we can still support an authentication request
in response to a CONNECT, then a client's authentication response.
2010-02-01 16:20:08 +01:00
Willy Tarreau
5843d1a894 [MEDIUM] http: switch to tunnel mode after status 101 responses
A 101 response is accompanied with an Upgrade header indicating
a new protocol that is spoken on the connection after the exchange
completes. At least we should switch to tunnel mode after such a
response.
2010-02-01 15:13:32 +01:00
Willy Tarreau
95fa4698f1 [MEDIUM] add support for anonymous ACLs
Anonymous ACLs allow the declaration of rules which rely directly on
ACL expressions without passing via the declaration of an ACL. Example :

   With named ACLs :

        acl site_dead nbsrv(dynamic) lt 2
        acl site_dead nbsrv(static)  lt 2
        monitor fail  if site_dead

   With anonymous ACLs :

        monitor fail if { nbsrv(dynamic) lt 2 } || { nbsrv(static) lt 2 }
2010-02-01 13:05:50 +01:00
Krzysztof Olędzki
711ad9eb27 [MINOR] http-auth: last fix was wrong
I'm not sure if the fix is correct:

- if (req_acl->cond)
-         ret = acl_exec_cond(req_acl->cond, px, s, txn, ACL_DIR_REQ);
+ if (!req_acl->cond)
+         continue;

Doesn't it ignore rules with no condition attached? I think that the
proper solution would be the following.
2010-02-01 12:54:32 +01:00
Willy Tarreau
9cc670f7d9 [CLEANUP] config: use build_acl_cond() to simplify http-request ACL parsing
Now that we have this new function to make your life better, use it.
2010-02-01 10:43:44 +01:00
Willy Tarreau
5142594dea [MINOR] http-auth: make the 'unless' keyword work as expected
One check was missing for the 'polarity' of the test. Now 'unless'
works. BTW, 'unless' provides a nice way to perform one-line auth :

    acl valid-user http_auth(user-list)
    http-request auth unless valid-user
2010-02-01 10:40:19 +01:00
Cyril Bont
cd19e51b05 [MEDIUM] add a maintenance mode to servers
This is a first attempt to add a maintenance mode on servers, using
the stat socket (in admin level).

It can be done with the following command :
   - disable server <backend>/<server>
   - enable  server <backend>/<server>

In this mode, no more checks will be performed on the server and it
will be marked as a special DOWN state (MAINT).

If some servers were tracking it, they'll go DOWN until the server
leaves the maintenance mode. The stats page and the CSV export also
display this special state.

This can be used to disable the server in haproxy before doing some
operations on this server itself. This is a good complement to the
"http-check disable-on-404" keyword and works in TCP mode.
2010-01-31 23:33:18 +01:00
Willy Tarreau
844a7e76d2 [MEDIUM] http: add support for proxy authentication
We're already able to know if a request is a proxy request or a
normal one, and we have an option "http-use-proxy-header" which states
that proxy headers must be checked. So let's switch to use the proxy
authentication headers and responses when this option is set and we're
facing a proxy request. That allows haproxy to enforce auth in front
of a proxy.
2010-01-31 21:46:18 +01:00
Krzysztof Piotr Oledzki
8c8bd4593c [MAJOR] use the new auth framework for http stats
Support the new syntax (http-request allow/deny/auth) in
http stats.

Now it is possible to use the same syntax is the same like in
the frontend/backend http-request access control:
 acl src_nagios src 192.168.66.66
 acl stats_auth_ok http_auth(L1)

 stats http-request allow if src_nagios
 stats http-request allow if stats_auth_ok
 stats http-request auth realm LB

The old syntax is still supported, but now it is emulated
via private acls and an aditional userlist.
2010-01-31 19:14:09 +01:00
Krzysztof Piotr Oledzki
f9423ae43a [MINOR] acl: add http_auth and http_auth_group
Add two acls to match http auth data:
 acl <name> http_auth(userlist)
 acl <name> http_auth_hroup(userlist) group1 group2 (...)
2010-01-31 19:14:09 +01:00
Krzysztof Piotr Oledzki
59bb218b86 [MINOR] http-request: allow/deny/auth support for frontend/backend/listen
Use the generic auth framework to control access to frontends/backends/listens
2010-01-31 19:14:08 +01:00
Krzysztof Piotr Oledzki
d7528e5a60 [MINOR] add ACL_TEST_F_NULL_MATCH
Add ACL_TEST_F_NULL_MATCH so expr->kw->match can be called
even if expr->patterns is empty.
2010-01-31 19:14:07 +01:00
Krzysztof Piotr Oledzki
961050465e [MINOR] generic auth support with groups and encrypted passwords
Add generic authentication & authorization support.

Groups are implemented as bitmaps so the count is limited to
sizeof(int)*8 == 32.

Encrypted passwords are supported with libcrypt and crypt(3), so it is
possible to use any method supported by your system. For example modern
Linux/glibc instalations support MD5/SHA-256/SHA-512 and of course classic,
DES-based encryption.
2010-01-31 19:14:07 +01:00
Krzysztof Piotr Oledzki
fccbdc8421 [MINOR] Base64 decode
Implement Base64 decoding with a reverse table.

The function accepts and decodes classic base64 strings, which
can be composed from many streams as long each one is properly
padded, for example: SGVsbG8=IEhBUHJveHk=IQ==
2010-01-31 19:14:07 +01:00
Willy Tarreau
fdb563c06f [MEDIUM] http: add support for conditional response header rewriting
Just as for the req* rules, we can now condition rsp* rules with ACLs.
ACLs match on response, so volatile request information cannot be used.
A warning is emitted if a configuration contains such an anomaly.
2010-01-31 15:43:27 +01:00
Willy Tarreau
8abd4cd526 [MEDIUM] http: add support for conditional request header addition
Now the reqadd rules also support ACLs. All req* rules are converted
now.
2010-01-31 15:12:45 +01:00
Willy Tarreau
5321c42722 [MEDIUM] http: add support for conditional request filter execution
All the req* rules except the reqadd rules can now be specified with
an if/unless condition. If a condition is specified and does not match,
the filter is ignored. This is particularly useful with reqidel, reqirep
and reqtarpit.
2010-01-28 20:35:13 +01:00
Willy Tarreau
6c123b15cb [MEDIUM] http: make the request filter loop check for optional conditions
From now on, if request filters have ACLs defined, these ACLs will be
evaluated to condition the filter. This will be used to conditionally
remove/rewrite headers based on ACLs.
2010-01-28 20:22:06 +01:00
Willy Tarreau
ade5ec430d [MEDIUM] config: factor out the parsing of 20 req*/rsp* keywords
A new function was added to take care of the common code between
all those keywords. This has saved 8 kB of object code and about
500 lines of source code. This has also permitted to spot and fix
minor bugs (allocated args that were never used).

The code could be factored even more but that would make it a bit
more complex which is not interesting at this stage.

Various tests have been performed, and the warnings and errors are
still correctly reported and everything seems to work as expected.
2010-01-28 19:42:59 +01:00
Willy Tarreau
3ec18a0eee [CLEANUP] config: specify correct const char types to warnif_* functions
Also factor out a few declarations of acl_cond everywhere.
2010-01-28 19:01:34 +01:00
Willy Tarreau
f4f04125d4 [MINOR] prepare req_*/rsp_* to receive a condition
It will be very handy to be able to pass conditions to req_* and rsp_*.
For now, we just add the pointer to the condition in the affected
structs.
2010-01-28 18:10:50 +01:00
Willy Tarreau
f1e98b8628 [CLEANUP] config: use warnif_cond_requires_resp() to check for bad ACLs
Factor out some repetitive copy-pasted code to check for request ACLs
validity.
2010-01-28 17:59:39 +01:00
Willy Tarreau
ef6494cb8c [CLEANUP] config: use build_acl_cond() instead of parse_acl_cond()
This allows to clean up the code a little bit by moving some of the
ACL internals out of the config parser.
2010-01-28 17:12:36 +01:00
Willy Tarreau
2bbba415d7 [MINOR] acl: add build_acl_cond() to make it easier to add ACLs in config
This function automatically builds a rule, considering the if/unless
statements, and automatically updates the proxy's acl_requires, the
condition's file and line.
2010-01-28 16:48:33 +01:00
Willy Tarreau
c3e8b25c79 [MINOR] http: disable keep-alive when process is going down
Krzysztof Oledzki suggested to disable keep-alive when a process
is going down due to a reload, in order to avoid ever-lasting
sessions. This is a simple and very efficient solution as it
ensures that at most one more request will be handled on a
keep-alive connection after the process has received a SIGUSR1
signal.
2010-01-28 15:01:20 +01:00
Willy Tarreau
ef78104947 [MINOR] checks: add the server's status in the checks
Now a server can check the contents of the header X-Haproxy-Server-State
to know how haproxy sees it. The same values as those reported in the stats
are provided :
  - up/down status + check counts
  - throttle
  - weight vs backend weight
  - active sessions vs backend sessions
  - queue length
  - haproxy node name
2010-01-27 20:16:12 +01:00
Willy Tarreau
e9d8788fdd [MINOR] checks: make the HTTP check code add the CRLF itself
Currently we cannot easily add headers nor anything to HTTP checks
because the requests are pre-formatted with the last CRLF. Make the
check code add the CRLF itself so that we can later add useful info.
2010-01-27 20:16:12 +01:00
Willy Tarreau
1edb144b8d [BUG] restore accidentely removed line in last patch !
The test condition for the acl expression validity got dropped, and
only the error remained. Error reported by Krzysztof Oledzki.
2010-01-27 20:13:38 +01:00
Willy Tarreau
ac778f5ade [CLEANUP] acl, patterns: make use of my_strndup() instead of malloc+memcpy
This is simpler and more readable.
2010-01-26 19:02:46 +01:00
Willy Tarreau
0c55931696 [MINOR] config: off-by-one in "stick-table" after list of converters 2010-01-26 18:36:26 +01:00
Willy Tarreau
d31d6eb89a [MINOR] pattern: add the "ipmask()" converting function
This converter can be applied on top of an IPv4-type pattern. It
applies a netmask which is suited for IP address storage and matching.
This can be used to make all hosts within a certain mask to share the
same table entries and as such use the same server.

The mask can be passed in dotted form (eg: 255.255.255.0) or in CIDR
form (eg: 24).
2010-01-26 18:05:48 +01:00
Willy Tarreau
9e92d327f7 [MINOR] pattern: add support for argument parsers for converters
Some converters will need one or several arguments. It's not possible
to write a simple generic parser for that, so let's add the ability
for each converter to support its own argument parser, and call it
to get the arguments when it's specified. If unspecified, the arguments
are passed unmodified as string+len.
2010-01-26 18:01:35 +01:00
Willy Tarreau
2937c0dd20 [MINOR] standard: str2mask: string to netmask converter
This function converts a dotted or CIDR value to a netmask.
2010-01-26 17:36:17 +01:00
Willy Tarreau
1a51b6342e [MINOR] pattern: make the converter more flexible by supporting void* and int args
The pattern type converters currently support a string arg and a length.
Sometimes we'll prefer to pass them a list or a structure. So let's convert
the string and length into a generic void* and int that each converter may
use as it likes.
2010-01-26 17:17:56 +01:00
Willy Tarreau
a724d49b6e [BUG] patterns: copy-paste typo in type conversion arguments 2010-01-26 16:48:20 +01:00
Willy Tarreau
7aabd11cec [STATS] make it possible to change a CLI connection timeout
Sometimes it helps to be able to change an interactive CLI connection
timeout. Now we just have to enter "set timeout cli <value>" to do that.
2010-01-26 11:11:42 +01:00
Cyril Bont
99ed327d62 [CLEANUP] Keep in sync "defaults" support between documentation and code
Hi Willy,

I've made a quick pass on the "defaults" column in the Proxy keywords matrix (chapter 4.1. in the documentation).
This patch resyncs the code and the documentation. I let you decide if some keywords that still work in the "defaults" section should be forbidden.

- default_backend : in the matrix, "defaults" was not supported but the keyword details say it is.
Tests also shows it works, then I've updated the matrix.

- capture cookie : in the keyword details, we can read `It is not possible to specify a capture in a "defaults" section.'.
Ok, even if the tests worked, I've added an alert in the configuration parser (as it is for capture request/response header).

- description : not supported in "defaults", I added an alert in the parser.
I've also noticed that this keyword doesn't appear in the documentation.
There's one "description" entry, but for the "global" section, which is for a different use (the patch doesn't update the documentation).

- grace : even if this is maybe useless, it works in "defaults". Documentation is updated.
- redirect : alert is added in the parser.
- rsprep : alert added in the parser.

--
Cyril Bont
2010-01-25 23:20:35 +01:00
Willy Tarreau
739cfbab6a [BUG] http: trim any excess buffer data when recycling a connection
We must trim any excess data from the response buffer when recycling
a keep-alive connection, because we may have blocked an invalid response
from a server that we don't want to accidentely forward once we disable
the analysers, nor do we want those data to come along with next response.
A typical example of such data would be from a buggy server responding to
a HEAD with some data, or sending more than the advertised content-length.
2010-01-25 23:11:14 +01:00
Willy Tarreau
d08f82ebe2 [MINOR] http: remove a copy-paste typo in transaction cleaning
For deciding to set the BF_EXPECT_MORE, we reused the same code as in
http_wait_for_request(), but here we must ignore buf->lr which is not
yet set and useless. This might only have caused random sub-optimal
behaviours.
2010-01-25 22:46:30 +01:00
Willy Tarreau
c5bbe53f6f [CRITICAL] buffers: buffer_insert_line2 must not change the ->w entry
Krzysztof Oledzki reported that 1.4-dev7 would regularly crash
on an apparently very common workload. The cores he provided
showed some inter-buffer data corruption, exactly similar to
what was fixed by the following recent commit :

bbfa7938bd [BUG] buffer_replace2 must never change the ->w entry

In fact, it was buffer_insert_line2() which was still modifying the
->w pointer, causing issues with pipelined responses in keep-alive
mode if some headers were to be added.

The bug requires a remote client, a near server, large server buffers
and small client buffers to be reproduced, with response header
insertion. Still, it's surprizing that it did not trigger earlier.

Now after 100k pipelined requests it did not trigger anymore.
2010-01-25 20:46:42 +01:00
Willy Tarreau
88d349d25d [MEDIUM] http: add support for Proxy-Connection header
Despite what is explicitly stated in HTTP specifications,
browsers still use the undocumented Proxy-Connection header
instead of the Connection header when they connect through
a proxy. As such, proxies generally implement support for
this stupid header name, breaking the standards and making
it harder to support keep-alive between clients and proxies.

Thus, we add a new "option http-use-proxy-header" to tell
haproxy that if it sees requests which look like proxy
requests, it should use the Proxy-Connection header instead
of the Connection header.
2010-01-25 12:48:26 +01:00
Willy Tarreau
bbfa7938bd [BUG] buffer_replace2 must never change the ->w entry
This function is used to move data which is located between ->w and ->r,
so it must not touch ->w, otherwise it will displace pending data which
is before the one we're actually overwriting. The issue arises with
some pipelined responses which cause some part of the previous one to
be chopped off when removing the connection: close header, thus
corrupting last response and shifting next one. Those are detected
in the logs because the next response will be a 502 with flags PH.
2010-01-25 01:53:38 +01:00
Willy Tarreau
2a6d88dafe [MINOR] http: logs must report persistent connections to down servers
When using "option persist" or "force-persist", we want to know from the
logs if the cookie referenced a valid server or a down server. Till here
the flag reported a valid server even if the server was down, which is
misleading. Now we correctly report that the requested server was down.
We can typically see "--DI" when using "option persist" with redispatch,
ad "SCDN" when using force-persist on a down server.
2010-01-24 13:10:43 +01:00
Willy Tarreau
4de9149f87 [MINOR] add the "force-persist" statement to force persistence on down servers
This is used to force access to down servers for some requests. This
is useful when validating that a change on a server correctly works
before enabling the server again.
2010-01-22 19:10:05 +01:00
Willy Tarreau
ff7b5883c0 [OPTIM] http: don't delay response if next request is incomplete
We use to delay the response if there is a new request in the buffer.
However, if the pending request is incomplete, we should not delay the
pending responses.
2010-01-22 14:43:47 +01:00
Willy Tarreau
d5fd51c75b [BUG] http_server_error() must not purge a previous pending response
This can cause parts of responses to be truncated in case of
pipelined requests if the second request generates an error
before the first request is completely flushed.
2010-01-22 14:20:17 +01:00
Willy Tarreau
e803de2c6b [MINOR] add the ability to force kernel socket buffer size.
Sometimes we need to be able to change the default kernel socket
buffer size (recv and send). Four new global settings have been
added for this :
   - tune.rcvbuf.client
   - tune.rcvbuf.server
   - tune.sndbuf.client
   - tune.sndbuf.server

Those can be used to reduce kernel memory footprint with large numbers
of concurrent connections, and to reduce risks of write timeouts with
very slow clients due to excessive kernel buffering.
2010-01-22 11:49:41 +01:00
Willy Tarreau
6046652253 [MAJOR] http: rework response Connection header handling
This one is the next step of previous patch. It correctly computes
the response mode and the Connection flag transformations depending
on the request mode and version, and the response version and headers.

We're now also able to add "Connection: keep-alive", and to convert
server's close during a keep-alive connection to a server-close
connection.
2010-01-22 11:49:41 +01:00
Willy Tarreau
bbf0b37f6c [MAJOR] http: rework request Connection header handling
We need to improve Connection header handling in the request for it
to support the upcoming keep-alive mode. Now we have two flags which
keep in the session the information about the presence of a
Connection: close and a Connection: keep-alive headers in the initial
request, as well as two others which keep the current state of those
headers so that we don't have to parse them again. Knowing the initial
value is essential to know when the client asked for keep-alive while
we're forcing a close (eg in server-close mode). Also the Connection
request parser is now able to automatically remove single header values
at the same time they are parsed. This provides greater flexibility and
reliability.

All combinations of listen/front/back in all modes and with both
1.0 and 1.1 have been tested.
2010-01-22 11:49:35 +01:00
Willy Tarreau
348238b3a9 [MINOR] tools: add a "word_match()" function to match words and ignore spaces
Some header values might be delimited with spaces, so it's not enough to
compare "close" or "keep-alive" with strncasecmp(). Use word_match() for
that.
2010-01-18 19:51:39 +01:00
Willy Tarreau
68085d8cfb [MINOR] http: add http_remove_header2() to remove a header value.
Calling this function after http_find_header2() automatically deletes
the current value of the header, and removes the header itself if the
value is the only one. The context is automatically adjusted for a
next call to http_find_header2() to return the next header. No other
change nor test should be made on the transient context though.
2010-01-18 19:51:33 +01:00
Willy Tarreau
cce7fa4c81 [MEDIUM] http: don't switch to tunnel mode upon close
The close mode of a transaction would be switched to tunnel mode
at the end of the processing, letting a lot of pending data pass
in the other direction if any. Let's fix that by checking for the
close mode during state resync too.
2010-01-17 11:38:34 +01:00
Willy Tarreau
d3c343f8aa [BUG] http: don't count req errors on client resets or t/o during keep-alive
We must set the error flags when detecting that a client has reset
a connection or timed out while waiting for a new request on a keep-alive
connection, otherwise process_session() sets it itself and counts one
request error.

That explains why some sites were showing an increase in request errors
with the keep-alive.
2010-01-16 10:26:19 +01:00
Willy Tarreau
7340ca5a54 [OPTIM] stream_sock: don't shutdown(write) when the socket is in error
We get a lot of those, especially with web crawlers :

recv(2, 0x810b610, 7000, 0)             = -1 ECONNRESET (Connection reset by peer)
shutdown(2, 1 /* send */)               = -1 ENOTCONN (Transport endpoint is not connected)
close(2)                                = 0

There's no need to perform the shutdown() here, the socket is already
in error so it is down.
2010-01-16 10:03:45 +01:00
Willy Tarreau
43a7e6620b [BUG] buffers: remove remains of wrong obsolete length check
A check was performed in buffer_replace2() to compare buffer
length with its read pointer. This has been wrong for a long
time, though it only has an impact when dealing with keep-alive
requests/responses. In theory this should be backported but
the check has no impact without keep-alive.
2010-01-15 23:38:27 +01:00
Willy Tarreau
a5aa1c86a5 [BUG] check: we must not check for error before reading a response
We can receive data with a notification of socket error. But we
must not check for the error before reading the data, because it
may be an asynchronous error notification that we check too early
while the response we're waiting for is available. If there is an
error, recv() will get it.

This should help with servers that close very fast after the response
and should also slightly lower the CPU usage during very fast checks
on massive amounts of servers since we eliminate one system call.

This should probably be backported to 1.3.
2010-01-15 10:48:04 +01:00
Willy Tarreau
fc1daaf497 [CLEANUP] stream_sock: MSG_NOSIGNAL is only for send(), not recv()
We must not set this flag on recv(), it's not used, it's just for
send().
2010-01-15 10:26:13 +01:00
Willy Tarreau
2a3a51752b [BUG] checks: chars are unsigned on AIX, check was always true
Use '\xff' instead of -1 for a character test.
2010-01-14 11:41:31 +01:00
Krzysztof Piotr Oledzki
346f76ddbd [MINOR] acl: add fe_id/so_id to match frontend's and socket's id 2010-01-12 23:00:51 +01:00
Emeric Brun
1d33b2965e [MEDIUM] Add stick and store rules analysers. 2010-01-12 16:01:24 +01:00
Emeric Brun
b982a3d23a [MEDIUM] Add stick table configuration and init. 2010-01-12 16:01:24 +01:00
Emeric Brun
5d16eda210 [MEDIUM] Add src dst and dport pattern fetches. 2010-01-12 16:01:23 +01:00