Commit Graph

1561 Commits

Author SHA1 Message Date
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
Emeric Brun
107ca30d54 [MEDIUM] Add pattern fetch management types and functions 2010-01-12 16:01:19 +01:00
Emeric Brun
3bd697e071 [MEDIUM] Add stick table (persistence) management functions and types 2010-01-12 11:23:15 +01:00
Emeric Brun
39132b2165 [MINOR] Add function to parse a size in configuration 2010-01-12 11:23:15 +01:00
Hervé COMMOWICK
698ae00fc2 [MINOR] add option "mysql-check" to use MySQL health checks
This patch adds support for MySQL health checks. Those are
enabled using the new option "mysql-check".
2010-01-12 10:37:39 +01:00
Krzysztof Piotr Oledzki
9f2b9d5bf7 [BUG] checks: fix newline termination
We can't put a newline in server_status_printf() as there might be
something added later.
2010-01-11 21:13:43 +01:00
Krzysztof Piotr Oledzki
5f5b7d2c1d [OPTIM] remove SSP_O_VIA and SSP_O_STATUS
There is a smarter way to do this, so both options are no longer
necessary.
2010-01-11 21:13:12 +01:00
Krzysztof Piotr Oledzki
b16a607997 [BUG] health checks: fix requeued message
Dummy copy&past is not a good idea. :( Also, we shoud
check "s->state & SRV_RUNNING" instead of xferred.
2010-01-11 21:13:12 +01:00
Willy Tarreau
76bfc95aa5 [MINOR] config: remove undocumented and buggy 'timeout appsession'
This one has never really worked and is not documented.
2010-01-10 17:48:11 +01:00
Cyril Bonté
3b7a369baa [MINOR] config: don't accept 'appsession' in defaults section
Maybe appsession should be forbidden in the 'defaults' section as it
will not work in the backends.
2010-01-10 17:47:28 +01:00
Willy Tarreau
b16a5746b7 [MINOR] http: add a separate "http-keep-alive" timeout
This one is used to wait for next request after a response was sent
to the client.
2010-01-10 14:46:16 +01:00
Willy Tarreau
fcffa6911c [MINOR] http: differentiate waiting for new request and waiting for a complete requst
While waiting in a keep-alive state for a request, we want to silently
close if we don't get anything. However if we get a partial request it's
different because that means the client has started to send something.
This requires a new transaction flag. It will be used to implement a
distinct timeout for keep-alive and requests.
2010-01-10 14:24:53 +01:00
Willy Tarreau
a3377eeeff [MINOR] http: move appsession 'sessid' from session to http_txn
This change, suggested by Cyril Bonté, makes a lot of sense and
would have made it obvious that sessid was not properly initialized
while switching to keep-alive. The code is now cleaner.
2010-01-10 10:49:11 +01:00
Willy Tarreau
75661457f7 [MINOR] http redirect: don't explicitly state keep-alive on 1.1
Do not set the "connection: keep-alive" header when the request is in
HTTP 1.1, it's implicit.
2010-01-10 10:35:01 +01:00
Willy Tarreau
148d099406 [BUG] stream_interface: fix retnclose and remove cond_close
The stream_int_cond_close() function was added to preserve the
contents of the response buffer because stream_int_retnclose()
was buggy. It flushed the response instead of flushing the
request. This caused issues with pipelined redirects followed
by error messages which ate the previous response.

This might even have caused object truncation on pipelined
requests followed by an error or by a server redirection.

Now that this is fixed, simply get rid of the now useless
function.
2010-01-10 10:21:21 +01:00
Cyril Bonté
41689c22da [BUG] appsession: possible memory leak in case of out of memory condition
I've tried to follow all the pool_alloc2/pool_free2 calls in the code
to track memory leaks. I've found one which only happens when there's
already no more memory when allocating a new appsession cookie.
2010-01-10 00:50:14 +01:00
Willy Tarreau
81e3b4f48d [MINOR] http redirect: add the ability to append a '/' to the URL
Sometimes it can be desired to return a location which is the same
as the request with a slash appended when there was not one in the
request. A typical use of this is for sending a 301 so that people
don't reference links without the trailing slash. The name of the
new option is "append-slash" and it can be used on "redirect"
statements in prefix mode.
2010-01-10 00:42:19 +01:00
Willy Tarreau
dcb75c4a83 [MINOR] http: fix double slash prefix with server redirect
When using server redirection, it is possible to specify a path
consisting of only one slash. While this is discouraged (risk of
loop) it may sometimes be useful combined with content switching.
The prefixing of a '/' then causes two slashes to be returned in
the response. So we now do as with the other redirects, don't
prepend a slash if it's alone.
2010-01-10 00:24:22 +01:00
Willy Tarreau
962c3f4aab [MEDIUM] http: fix handling of message pointers
Some message pointers were not usable once the message reached the
HTTP_MSG_DONE state. This is the case for ->som which points to the
body because it is needed to parse chunks. There is one case where
we need the beginning of the message : server redirect. We have to
call http_get_path() after the request has been parsed. So we rely
on ->sol without counting on ->som. In order to achieve this, we're
making ->rq.{u,v} relative to the beginning of the message instead
of the buffer. That simplifies the code and makes it cleaner.

Preliminary tests show this is OK.
2010-01-10 00:15:35 +01:00
Willy Tarreau
59e0b0f972 [BUG] server redirection used an uninitialized string.
This might have been introduced with chunk extensions. Note that
the server redirect still does not work because http_get_path()
cannot get the correct path once the request message is in the
HTTP_MSG_DONE state (->som does not point to the start of message
anymore).
2010-01-09 21:29:23 +01:00
Willy Tarreau
1fac75385a [BUILD] appsession did not build anymore under gcc-2.95 2010-01-09 19:23:06 +01:00
Willy Tarreau
762a23618e [BUG] appsession's sessid must be reset at end of transaction
If we don't do that, we may corrupt the pools in keep-alive sessions.
2010-01-09 13:57:26 +01:00
Willy Tarreau
e34070e1be [MEDIUM] session: limit the number of analyser loops
The initial code's intention was to loop on the analysers as long
as an analyser is added by another one. [This code was wrong due to
the while(0) which breaks even on a continue statement, but the
initial intention must be changed too]. In fact we should limit the
number of times we loop on analysers in order to limit latency.
Using maxpollevents as a limit makes sense since this tunable is
used for the exact same purposes. We may add another tunable later
if that ever makes sense, so it's very unlikely.
2010-01-08 00:36:57 +01:00
Willy Tarreau
065e8338e8 [MEDIUM] http: wait for some flush of the response buffer before a new request
If we accept a new request and that request produces an immediate
response (error, redirect, ...), then we may fail to send it in
case of pipelined requests if the response buffer is full. To avoid
this, we check the availability of at least maxrewrite bytes in the
response buffer before accepting a new pipelined request.
2010-01-08 00:36:57 +01:00
Willy Tarreau
ea65e68cc8 [MINOR] http redirect: use proper call to return last response
During a redirect, we used to send the last chunk of response with
stream_int_cond_close(). But this is wrong in case of pipeline,
because if the response already contains something, this function
will refrain from touching the buffer. Use a concatenation function
instead.

Also, this call might still fail when the buffer is full, we need
a second fix to refrain from parsing an HTTP request as long as the
response buffer is full, otherwise we may not even be able to return
a pending redirect or an error code.
2010-01-08 00:36:57 +01:00
Willy Tarreau
4602363f6a [BUG] http: fix for capture memory leak was incorrect
That patch was incorrect because under some circumstances, the
capture memory could be freed by session_free() and then again
by http_end_txn(), causing a double free and an eventual segfault.
The pool use count was also reported wrong due to this bug.

The cleanup code was removed from session_free() to remain only
in http_end_txn().
2010-01-07 22:51:47 +01:00
Willy Tarreau
6fe60182aa [BUG] http: memory leak with captures when using keep-alive
Hank A. Paulson reported a massive memory leak when using keep-alive
mode. The information he provided made it easy to find that captured
request and response headers were erased but not released when renewing
a request.
2010-01-07 13:35:21 +01:00
Krzysztof Piotr Oledzki
260a3bb17b [BUG] cfgparser/stats: fix error message
Fix the error message by unification and goto, previously we had
two independent lists of supported keywords and were raporting 'stats'
instead of a wrong keyword.

Code:
 stats wrong-keyword
 stats

Before:
 [ALERT] 005/163032 (27175) : parsing [haproxy.cfg:248] : unknown stats parameter 'stats' (expects 'hide-version', 'uri', 'realm', 'auth' or 'enable').
 [ALERT] 005/163032 (27175) : parsing [haproxy.cfg:249] : 'stats' expects 'uri', 'realm', 'auth', 'scope' or 'enable', 'hide-version', 'show-node', 'show-desc', 'show-legends'.

After:
 [ALERT] 005/162841 (22710) : parsing [haproxy.cfg:248]: unknown stats parameter 'wrong-keyword', expects 'uri', 'realm', 'auth', 'scope', 'enable', 'hide-version', 'show-node', 'show-desc' or 'show-legends'.
 [ALERT] 005/162841 (22710) : parsing [haproxy.cfg:249]: missing keyword in 'stats', expects 'uri', 'realm', 'auth', 'scope', 'enable', 'hide-version', 'show-node', 'show-desc' or 'show-legends'.
2010-01-07 00:34:27 +01:00
Krzysztof Piotr Oledzki
c0f0c8605b [BUG] stats: cookie should be reported under backend not under proxy 2010-01-07 00:34:27 +01:00
Willy Tarreau
90deb18916 [MEDIUM] http: make safer use of the DONT_READ and AUTO_CLOSE flags
Several HTTP analysers used to set those flags to values that
were useful but without considering the possibility that they
were not called again to clean what they did. First, replace
direct flag manipulation with more explicit macros. Second,
enforce a rule stating that any buffer which changes one of
these flags from the default must restore it after completion,
so that other analysers see correct flags.

With both this fix and the previous one about analyser bits,
we should not see any more stuck sessions.
2010-01-07 00:20:41 +01:00
Willy Tarreau
576507f4c5 [MEDIUM] session: also consider request analysers added during response
A request analyser may very well be added while processing a response
(eg: end of an HTTP keep-alive response). It's very dangerous to only
rely on flags that ought to change in order to loop back, so let's
correctly detect a possible new analyser addition instead of guessing.
2010-01-07 00:09:04 +01:00
Willy Tarreau
1e0bbafcbe [MAJOR] session: fix the order by which the analysers are run
With the introduction of keep-alive, we have created situations
where an analyser can add other analysers to the current list,
which are behind it, which have already been processed once, and
which are needed immediately because without them there will be
no more I/O activity. This is typically the case for enabling
reading of a new request after preparing for a new request.

Instead of creating specific cases for some analysers (there was
already one such before), we now use a little bit of algorithmics
to create an ordered bit chain supporting priorities and fast
operations.

Another advantage of this new construction is that it's not a
real loop anymore, so if an analyser is unknown, it will not
loop but just ignore it.

Note that it is easy to skip multiple analysers at once now in
order to speed up the checking a bit. Some test code has shown
a minor gain though.

This change has been carefully re-read and has no direct reason
of causing a regression. However it has been tagged "major"
because the fact that it runs the analysers correctly might
trigger an old sleeping bug somewhere in one of the analysers.
2010-01-07 00:01:03 +01:00
Krzysztof Piotr Oledzki
034550b742 [BUG] stats: show UP/DOWN status also in tracking servers
It was broken since 0960541e49:
 [MEDIUM] Collect & show information about last health check, v3
2010-01-06 00:28:07 +01:00
Krzysztof Piotr Oledzki
88a14af5d2 [MINOR] stats: add href to tracked server
Each server has now a dedicated "a link" tag, so let's use it.
2010-01-06 00:28:07 +01:00
Krzysztof Piotr Oledzki
a9389b1a37 [BUG]: add 'observer', 'on-error', 'error-limit' to supported options list 2010-01-06 00:28:07 +01:00
Krzysztof Piotr Oledzki
c6df066980 [MEDIUM] default-server support
This patch implements default-server support allowing to change
default server options. It can be used in [defaults] or [backend]/[listen]
sections. Currently the following options are supported:

 - error-limit
 - fall
 - inter
 - fastinter
 - downinter
 - maxconn
 - maxqueue
 - minconn
 - on-error
 - port
 - rise
 - slowstart
 - weight
2010-01-06 00:28:06 +01:00
Krzysztof Piotr Oledzki
15514c21a2 [MINOR]: stats: add show-legends to report additional informations
Supported informations, available via "tr/td title":
  - cap: capabilities (proxy)
  - mode: one of tcp, http or health (proxy)
  - id: SNMP ID (proxy, socket, server)
  - IP (socket, server)
  - cookie (backend, server)
2010-01-06 00:28:06 +01:00
Krzysztof Piotr Oledzki
2ec025d9a5 [MINOR] stats: add "a link" & "a href" for sockets
This patch adds add "a link" & "a href" html tags for sockets.
As sockets may have the same name like servers, I decided to
add "+" char (forbidden in names assigned to servers), as a prefix.
2010-01-06 00:28:06 +01:00
Krzysztof Piotr Oledzki
748196e94b [MINOR] hana: only report stats if it is enabled
It is useless to report statistics if the feature was not enabled.

It also makes possible to distinguish if health analyses is
enabled or not only by looking at the stats page.
2010-01-06 00:28:05 +01:00
Emeric Brun
3a7fce5383 [BUILD] warning ultoa_r returns char *
ultoa_r modifies its output, it returns a char *.
2010-01-05 23:47:00 +01:00
Willy Tarreau
8db1c17634 [BUG] http: check options before the connection header
Commit 0dfdf19b64 introduced a
regression because the connection header is now parsed and checked
depending on the configured options, but the options are set after
calling it instead of being set before.
2010-01-05 23:12:12 +01:00
Willy Tarreau
0dfdf19b64 [MEDIUM] http: restore the original behaviour of option httpclose
Historically, "option httpclose" has always worked the same way. It
only mangles the "Connection" header in the request and the response
if needed, but does not affect the connection by itself, and ignores
any further data. It is dangerous to change this behaviour without
leaving any other alternative. If an active close is desired, it's
better to make use of "option forceclose" which does exactly what
it intends to do.

So as of now, "option httpclose" will only mangle the headers as
before, and will only affect the connection by itself when combined
with another connection-related option (eg: keepalive or server-close).
2010-01-05 11:33:11 +01:00
Willy Tarreau
2832d63874 [BUG] http: don't set no-linger on response in case of forced close
This is a copy-paste error, it must only apply to the request.
2010-01-05 11:06:20 +01:00
Willy Tarreau
9300fb2c01 [BUG] http: redirect needed to be updated after recent changes
The data forwarding fixes broke http redirection which relied on
tricks.
2010-01-05 00:58:24 +01:00
Willy Tarreau
2fa144c66a [BUG] http: some possible missed close remain in the forward chain
We basically have to mimmic the code of process_session() here, so
when the remote output is closed, we must abort otherwise we'll end
up with data which cannot leave the buffer.
2010-01-04 23:16:01 +01:00
Willy Tarreau
e3fa6e5bd7 [BUG] http_process_res_common() must not skip the forward analyser
By default this function returned 0 indicating an end of analysis.
This was not a problem as long as it was the last analyser in the
chain but becomes quite a big one now since it skips the forwarder
with auto_close enabled, causing some data to pass under the nose
of the last one undetected.
2010-01-04 22:57:43 +01:00
Willy Tarreau
610ecceef9 [MAJOR] http: fix again the forward analysers
There were still several situations leading to CLOSE_WAIT sockets
remaining there forever because some complex transitions were
obviously not caught due to the impossibility to resync changes
between the request and response FSMs.

This patch now centralizes the global transaction state and feeds
it from both request and response transitions. That way, whoever
finishes first, there will be no issue for converging to the correct
state.

Some heavy use of the new debugging function has helped a lot. Maybe
those calls could be removed after some time. First tests are very
positive.
2010-01-04 21:15:02 +01:00
Willy Tarreau
e988a79c74 [DEBUG] add an http_silent_debug function to debug HTTP states
This function outputs to fd #-1 the status of request and response
buffers, the transaction states, the stream interface states, etc...
That way, it's easy to find that output in an strace report, correctly
placed WRT the other syscalls.
2010-01-04 21:13:14 +01:00
Willy Tarreau
f5c8bd6a99 [BUG] http: fix hopefully last closing issue on data forwarding
The data forwarders are analysers. As such, the have to check for
various situations on which they have to abort, one of them being
the lack of data with closed input. Now we don't leave the functions
anymore without performing these checks. This has solved the new
CLOSE_WAIT issue that became more noticeable since last patch.
2010-01-04 07:10:34 +01:00
Willy Tarreau
d3347ee227 [BUG] http: disable auto-closing during chunk analysis
It may happen that we forward a close just after we sent the last
chunk, because we forgot to clear the AUTO_CLOSE flag.

This issue caused some pages to be truncated depending on some
timing races. Issue initially reported by Cyril Bonté.
2010-01-04 02:10:45 +01:00
Willy Tarreau
caabe41a15 [OPTIM] http: optimize a bit the construct of the forward loops
By adjusting a few states and direct branches, we can save a few
percents of CPU, increasing by as much the resulting data rate.
2010-01-03 23:08:28 +01:00
Willy Tarreau
bddaa4a2f7 [CLEANUP] http: remove a remaining impossible condition
This test was there before we had the CLOSING and CLOSED states.
It makes no sense now.
2010-01-03 22:13:35 +01:00
Willy Tarreau
477ecd8627 [MEDIUM] config: remove the limitation of 10 config files
Now we use a linked list, there is no limit anymore.
2010-01-03 21:22:14 +01:00
Willy Tarreau
deb9ed8f60 [MEDIUM] config: remove the limitation of 10 reqadd/rspadd statements
Now we use a linked list, there is no limit anymore.
2010-01-03 21:22:14 +01:00
Willy Tarreau
97cb780e81 [MINOR] config: centralize proxy struct initialization 2010-01-03 21:22:14 +01:00
Willy Tarreau
f285f54311 [MINOR] redirect: add support for unconditional rules
Sometimes it's useful to be able to specify an unconditional redirect
rule without adding "if TRUE".
2010-01-03 21:22:08 +01:00
Willy Tarreau
963abc33a2 [MINOR] config: some options were missing for "redirect"
Those options were missing in the parser error message :
  set-cookie, clear-cookie, drop-query
2010-01-03 19:49:34 +01:00
Willy Tarreau
305ae85957 [BUG] http: fix cookie parser to support spaces and commas in values
The cookie parser could be fooled by spaces or commas in cookie names
and values, causing the persistence cookie not to be matched if located
just after such a cookie. Now spaces found in values are considered as
part of the value, and spaces, commas and semi-colons found in values
or names, are skipped till next cookie name.

This fix must be backported to 1.3.
2010-01-03 19:45:54 +01:00
Krzysztof Piotr Oledzki
6492db5453 [BUG] Healthchecks: get a proper error code if connection cannot be completed immediately
In case of a non-blocking socket, used for connecting to a remote
server (not localhost), the error reported by the health check
was most of a time one of EINPROGRESS/EAGAIN/EALREADY.

This patch adds a getsockopt(..., SO_ERROR, ...) call so now
the proper error message is reported.
2010-01-03 19:23:19 +01:00
Willy Tarreau
a9679ac94b [MINOR] http: make the conditional redirect support keep-alive
It makes sense to permit a client to keep its connection when
performing a redirect to the same host. We only detect the fact
that the redirect location begins with a slash to use the keep-alive
(if the client supports it).
2010-01-03 17:32:57 +01:00
Willy Tarreau
2be3939416 [MINOR] http: don't wait for sending requests to the server
By default we automatically wait for enough data to fill large
packets if buf->to_forward is not null. This causes a problem
with POST/Expect requests which have a data size but no data
immediately available. Instead of causing noticeable delays on
such requests, simply add a flag to disable waiting when sending
requests.
2010-01-03 17:24:51 +01:00
Willy Tarreau
6c2cbe14e4 [BUG] http: take care of errors, timeouts and aborts during the data phase
In server-close mode particularly, the response buffer is marked for
no-auto-close after a response passed through. This prevented a POST
request from being aborted on errors, timeouts or anything if the
response was received before the request was complete.
2010-01-03 17:07:49 +01:00
Willy Tarreau
bc5aa19e97 [MINOR] http: move redirect messages to HTTP/1.1 with a content-length
This is cleaner and this tells clients we support 1.1.
2010-01-03 15:12:05 +01:00
Willy Tarreau
5e8949cf84 [OPTIM] http: don't immediately enable reading on request
If we enable reading of a request immediately after completing
another one, we end up performing small reads until the request
buffer is complete. This takes time and makes it harder to realign
the buffer when needed. Just enable reading when we need to.
2010-01-03 14:54:32 +01:00
Willy Tarreau
a95a1f4614 [BUG] http: the request URI pointer is relative to the buffer
The rq.u field is relative to buf->data, not to msg->sol. We have
to subtract msg->som everywhere this error was made. Maybe it will
be simpler to have a pointer to the buffer in the message and find
appropriate data there.
2010-01-03 13:04:35 +01:00
Willy Tarreau
3bb9c23bd6 [BUG] http: redirects were broken by chunk changes
Redirects used to initialize a chunk whose size was not set (0).
Also, the return code of chunk_strcpy() is 1 in case of success.
2010-01-03 12:24:37 +01:00
Willy Tarreau
face839296 [OPTIM] http: set MSG_MORE on response when a pipelined request is pending
Many times we see a lot of short responses in HTTP (typically 304 on a
reload). It is a waste of network bandwidth to send that many small packets
when we know we can merge them. When we know that another HTTP request is
following a response, we set BF_EXPECT_MORE on the response buffer, which
will turn MSG_MORE on exactly once. That way, multiple short responses can
leave pipelined if their corresponding requests were also pipelined.
2010-01-03 11:37:54 +01:00
Willy Tarreau
d38b53b896 [MINOR] stream_sock: enable MSG_MORE when forwarding finite amount of data
While it could be dangerous to enable MSG_MORE on infinite data (eg:
interactive sessions), it makes sense to enable it when we know the
chunk to be sent is just a part of a larger one.
2010-01-03 11:18:34 +01:00
Willy Tarreau
638cd02e9d [BUG] http: fix erroneous trailers size computation
We used to forward more trailers than required, causing a
desynchronization of the output. Now we schedule all for forwarding
as soon as we encounter them.
2010-01-03 07:42:04 +01:00
Willy Tarreau
21c5e4d85b [BUG] last fix was overzealous and disabled server-close
we must not close on remote shutdown but on remote error only.
2010-01-03 00:19:31 +01:00
Willy Tarreau
082b01c541 [BUG] http: ensure we abort data transfer on write error
When a write error is encountered during a data phase, we must
absolutely abort the pending data transfer, otherwise it will
never complete.
2010-01-03 00:00:45 +01:00
Willy Tarreau
b608feb82a [MAJOR] http: add support for option http-server-close
This option enables HTTP keep-alive on the client side and close mode
on the server side. This offers the best latency on the slow client
side, and still saves as many resources as possible on the server side
by actively closing connections. Pipelining is supported on both requests
and responses, though there is currently no reason to get pipelined
responses.
2010-01-02 22:47:18 +01:00
Willy Tarreau
2ab6eb1e24 [MEDIUM] http: make the parsers able to wait for a buffer flush
When too large a message lies in a buffer before parsing a new
request/response, we can now wait for previous outgoing data to
leave the buffer before attempting to parse again. After that
we can consider the opportunity to realign the buffer if needed.
2010-01-02 22:04:45 +01:00
Willy Tarreau
15de77e16e [MEDIUM] http: make the analyser not rely on msg being initialized anymore
The HTTP parser needed the msg structure to hold pre-initialized pointers.
This causes a trouble with keep-alive because if some data is still in the
buffer, the pointers can be anywhere after the data and later become invalid
when the buffer gets realigned.

It was not needed to rely on that since we have two valid information
in the buffer itself :

  - buf->lr : last visited place
  - buf->w + buf->send_max : beginning of next message

So by doing the maths only on those values, we can avoid doing tricks
on msg->som.
2010-01-02 21:59:16 +01:00
Willy Tarreau
a31e5dff36 [MINOR] config: option forceclose is valid in frontends too
This option was disabled for frontends in the configuration because
it was useless in its initial implementation, though it was still
checked in the code. Let's officially enable it now.
2009-12-30 01:10:35 +01:00
Willy Tarreau
c88ea68ef1 [MEDIUM] http: add some SI_FL_NOLINGER around server errors
When we catch an error from the server, speed up the connection
abort since we don't want to remain long with pending data in the
socket, and we want to be able to reuse our source port ASAP.
2009-12-29 14:56:36 +01:00
Willy Tarreau
1464140fce [MEDIUM] session: set SI_FL_NOLINGER when aborting on write timeouts
Doing this helps us flush the system buffers from all unread data. This
avoids having orphans when clients suddenly get off the net without
reading their entire response.
2009-12-29 14:49:56 +01:00
Willy Tarreau
9438c718ce [MEDIUM] http: make forceclose use SI_FL_NOLINGER
Option forceclose is not limited to the shortage of source ports
anymore thanks to this flag.
2009-12-29 14:39:48 +01:00
Willy Tarreau
4c283dce4b [MINOR] stream_sock: add SI_FL_NOLINGER for faster close
This new flag may be set by any user on a stream interface to tell
the underlying protocol that there is no need for lingering on the
socket since we know the other side either received everything or
does not care about what we sent.

This will typically be used with forced server close in HTTP mode,
where we want to quickly close a server connection after receiving
its response. Otherwise the system would prevent us from reusing
the same port for some time.
2009-12-29 14:36:34 +01:00
Willy Tarreau
82eeaf2fae [MEDIUM] http: properly handle "option forceclose"
The "forceclose" option used to close the output channel to the
server once it started to respond. While this happened to work with
most servers, some of them considered this as a connection abort and
immediately stopped responding.

Now that we're aware of the end of a request and response, we're able
to trivially handle this option and properly close both sides when the
server's response is complete.

During this change it appeared that forwarding could be allowed when
the BF_SHUTW_NOW flag was set on a buffer, which obviously is not
acceptable and was causing some trouble. This has been fixed too and
is the reason for the MEDIUM status on this patch.
2009-12-29 14:26:42 +01:00
Willy Tarreau
5523b32cc6 [MEDIUM] http: add two more states for the closing period
HTTP_MSG_CLOSING and HTTP_MSG_CLOSED are needed to know when it
is safe to close a connection without risking to destroy pending
data.
2009-12-29 12:05:52 +01:00
Willy Tarreau
33b2db69a9 [MINOR] stream_sock: prepare for closing when all pending data are sent
Since we'll soon be able to close a connection with remaining data in a
buffer, it becomes obvious that we can prepare to close when we're about
to send the last chunk of data and not the whole buffer.
2009-12-29 08:02:56 +01:00
Willy Tarreau
019fd5bc93 [BUG] buffers: wrong size calculation for displaced data
This error was triggered by requests not starting at the beginning
of the buffer. It cannot happen with earlier versions though it might
be a good idea to fix it anyway.
2009-12-28 18:37:54 +01:00
Willy Tarreau
83e3af0c86 [MEDIUM] http: rework the buffer alignment logic
There were still issues with the buffer alignment. Now we ensure
that we always align it before a request or response is completely
parsed if there is less than maxrewrite bytes free at the end. In
practice, it's not called that often and ensures we can always work
as expected.
2009-12-28 17:39:57 +01:00
Willy Tarreau
864e8256ec [BUG] stream_sock: wrong max computation on recv
Since the introduction of the automatic sizing of buffers during reads,
a bug appeared where the max size could be negative, causing large
chunks of memory to be overwritten during recv() calls if a read pointer
was already past the buffer's limit.
2009-12-28 17:36:37 +01:00
Willy Tarreau
58cc872848 [BUG] http: typos on several unlikely() around header insertion
In many places where we perform header insertion, an error control
is performed but due to a mistake, it cannot match any error :

   if (unlikely(error) < 0)
instead of
   if (unlikely(error < 0))

This prevents error 400 responses from being sent when the buffer is
full due to many header additions. This must be backported to 1.3.
2009-12-28 06:57:33 +01:00
Willy Tarreau
d98cf93395 [MAJOR] http: implement body parser
The body parser will be used in close and keep-alive modes. It follows
the stream to keep in sync with both the request and the response message.
Both chunked transfer-coding and content-length are supported according to
RFC2616.

The multipart/byterange encoding has not yet been implemented and if not
seconded by any of the two other ones, will be forwarded till the close,
as requested by the specification.

Both the request and the response analysers converge into an HTTP_MSG_DONE
state where it will be possible to force a close (option forceclose) or to
restart with a fresh new transaction and maintain keep-alive.

This change is important. All tests are OK but any possible behaviour
change with "option httpclose" might find its root here.
2009-12-27 22:54:55 +01:00
Willy Tarreau
5d881d0f3a [MINOR] new function stream_int_cond_close()
This one will be used to conditionally send a message upon a
close on a stream interface. It will not overwrite any existing
data.
2009-12-27 22:51:06 +01:00
Willy Tarreau
7c96f678fa [BUG] http: body parsing must consider the start of message
When parsing body for URL parameters, we must not consider that
data are available from buf->data but from buf->data + msg->som.
This is not a problem right now but may become with keep-alive.
2009-12-27 22:47:25 +01:00
Willy Tarreau
aec571c2bb [MEDIUM] http: automatically re-aling request buffer
When parsing a request that does not start at the beginning of the
buffer, we may experience a buffer full issue. In order to avoid
this, we try to realign the buffer if it is not really full. That
will be required when we have to deal with pipelined requests.
2009-12-27 17:18:11 +01:00
Willy Tarreau
1d3bcce4dd [BUG] http: offsets are relative to the buffer, not to ->som
Some wrong operations were performed on buffers, assuming the
offsets were relative to the beginning of the request while they
are relative to the beginning of the buffer. In practice this is
not yet an issue since both are the same... until we add support
for keep-alive.
2009-12-27 15:50:06 +01:00
Willy Tarreau
e8e785bb85 [MEDIUM] http: add a new transaction flags indicating if we know the transfer length
It's not enough to know if the connection will be in CLOSE or TUNNEL mode,
we still need to know whether we want to read a full message to a known
length or read it till the end just as in TUNNEL mode. Some updates to the
RFC clarify slightly better the corner cases, in particular for the case
where a non-chunked encoding is used last.

Now we also take care of adding a proper "connection: close" to messages
whose size could not be determined.
2009-12-26 16:29:04 +01:00
Willy Tarreau
115acb9755 [MEDIUM] http: rework chunk-size parser
Chunked encoding can be slightly more complex than what was implemented.
Specifically, it supports some optional extensions that were not parsed
till now if present, and would have caused an error to be returned.

Also, now we enforce check for too large values in chunk sizes in order
to ensure we never overflow.

Last, we're now able to return a request error if we can't read the
chunk size because the buffer is already full.
2009-12-26 13:56:06 +01:00
Willy Tarreau
0394594b06 [MINOR] http: introduce a new synchronisation state : HTTP_MSG_DONE
This state indicates that an HTTP message (request or response) is
complete. This will be used to know when we can re-initialize a
new transaction. Right now we only switch to it after the end of
headers if there is no data. When other analysers are implemented,
we can switch to this state too.

The condition to reuse a connection is when the response finishes
after the request. This will have to be checked when setting the
state.
2009-12-22 16:50:27 +01:00
Willy Tarreau
63c9e5ffa6 [MINOR] http: move 1xx handling earlier to eliminate a lot of ifs
The response 1xx was set too low and required a lot of tests along
the code in order to avoid some processing. We still left the test
after the response rewrite rules so that we can eliminate unwanted
headers if required.
2009-12-22 16:01:27 +01:00
Willy Tarreau
0937bc43cf [MINOR] http: move the http transaction init/cleanup code to proto_http
This code really belongs to the http part since it's transaction-specific.
This will also make it easier to later reinitialize a transaction in order
to support keepalive.
2009-12-22 15:03:09 +01:00
Willy Tarreau
7c3c54177a [MAJOR] buffers: automatically compute the maximum buffer length
We used to apply a limit to each buffer's size in order to leave
some room to rewrite headers, then we used to remove this limit
once the session switched to a data state.

Proceeding that way becomes a problem with keepalive because we
have to know when to stop reading too much data into the buffer
so that we can leave some room again to process next requests.

The principle we adopt here consists in only relying on to_forward+send_max.
Indeed, both of those data define how many bytes will leave the buffer.
So as long as their sum is larger than maxrewrite, we can safely
fill the buffers. If they are smaller, then we refrain from filling
the buffer. This means that we won't risk to fill buffers when
reading last data chunk followed by a POST request and its contents.

The only impact identified so far is that we must ensure that the
BF_FULL flag is correctly dropped when starting to forward. Right
now this is OK because nobody inflates to_forward without using
buffer_forward().
2009-12-22 10:06:34 +01:00
Willy Tarreau
9e13c3c630 [MINOR] http: only consider chunk encoding with HTTP/1.1
This must be ignored in case of HTTP/1.0.
2009-12-22 09:59:58 +01:00
Willy Tarreau
5b15447672 [MAJOR] http: completely process the "connection" header
Up to now, we only had a flag in the session indicating if it had to
work in "connection: close" mode. This is not at all compatible with
keep-alive.

Now we ensure that both sides of a connection act independantly and
only relative to the transaction. The HTTP version of the request
and response is also correctly considered. The connection already
knows several modes :
  - tunnel (CONNECT or no option in the config)
  - keep-alive (when permitted by configuration)
  - server-close (close the server side, not the client)
  - close (close both sides)

This change carefully detects all situations to find whether a request
can be fully processed in its mode according to the configuration. Then
the response is also checked and tested to fix corner cases which can
happen with different HTTP versions on both sides (eg: a 1.0 client
asks for explicit keep-alive, and the server responds with 1.1 without
a header).

The mode is selected by a capability elimination algorithm which
automatically focuses on the least capable agent between the client,
the frontend, the backend and the server. This ensures we won't get
undesired situtations where one of the 4 "agents" is not able to
process a transaction.

No "Connection: close" header will be added anymore to HTTP/1.0 requests
or responses since they're already in close mode.

The server-close mode is still not completely implemented. The response
needs to be rewritten as keep-alive before being sent to the client if
the connection was already in server-close (which implies the request
was in keep-alive) and if the response has a content-length or a
transfer-encoding (but only if client supports 1.1).

A later improvement in server-close mode would probably be to detect
some situations where it's interesting to close the response (eg:
redirections with remote locations). But even then, the client might
close by itself.

It's also worth noting that in tunnel mode, no connection header is
affected in either direction. A tunnelled connection should theorically
be notified at the session level, but this is useless since by definition
there will not be any more requests on it. Thus, we don't need to add a
flag into the session right now.
2009-12-22 09:52:43 +01:00
Willy Tarreau
157dd638e9 [MEDIUM] backend: remove HTTP POST parsing from get_server_ph_post()
Now that the HTTP analyser will already have parsed the beginning
of the request body, we don't have to check for transfer-encoding
anymore since we have the current chunk size in hdr_content_len.
2009-12-22 09:52:42 +01:00
Willy Tarreau
522d6c048f [MEDIUM] http: process request body in a specific analyser
The POST body analysis was split between two analysers for historical
reasons. Now we only have one analyser which checks content length
and waits for enough data to come.

Right now this analyser waits for <url_param_post_limit> bytes of
body to reach the buffer, or the first chunk. But this could be
improved to wait for any other amount of data or any specific
contents.
2009-12-22 09:52:42 +01:00
Willy Tarreau
dc8017ced6 [BUG] check_post: limit analysis to the buffer length
If "balance url_param XXX check_post" is used, we must bound the
number of bytes analysed to the buffer's length.
2009-12-22 09:52:42 +01:00
Krzysztof Piotr Oledzki
1a8bea9390 [BUG] config: fix erroneous check on cookie domain names, again
The previous check was correct: the RFC states that it is required
to have a domain-name which contained a dot AND began with a dot.
However, currently some (all?) browsers do not obey this specification,
so such configuration might work.

This patch reverts 3d8fbb6658 but
changes the check from FATAL to WARNING and extends the message.
2009-12-17 21:14:21 +01:00
Willy Tarreau
3ccf94efd9 [BUG] second fix for the printf format warning
Fix 500b8f0349 fixed the patch for the 64 bit
case but caused the opposite type issue to appear on 32 bit platforms. Cast
the difference and be done with it since gcc does not agree on type carrying
the difference between two pointers on 32 and 64 bit platforms.
2009-12-17 21:14:20 +01:00
Krzysztof Piotr Oledzki
500b8f0349 [BUG] format '%d' expects type 'int', but argument 5 has type 'long int'
src/cfgparse.c: In function 'readcfgfile':
src/cfgparse.c:4087: warning: format '%d' expects type 'int', but argument 5 has type 'long int'
2009-12-16 00:29:41 +01:00
Krzysztof Piotr Oledzki
97f07b832f [MEDIUM] Decrease server health based on http responses / events, version 3
Implement decreasing health based on observing communication between
HAProxy and servers.

Changes in this version 2:
 - documentation
 - close race between a started check and health analysis event
 - don't force fastinter if it is not set
 - better names for options
 - layer4 support

Changes in this version 3:
 - add stats
 - port to the current 1.4 tree
2009-12-16 00:29:27 +01:00
Willy Tarreau
25a67fae3e [MINOR] config: don't report error on all subsequent files on failure
Cyril Bonté found that when an error is detected in one config file, it
is also reported in all other ones, which is wrong. The fix obviously
consists in checking the return code from readcfgfile() and not the
accumulator.
2009-12-15 21:46:25 +01:00
Cyril Bonté
dd1b01d027 [BUG] Configuration parser bug when escaping characters
Today I was testing headers manipulation but I met a bug with my first test.
To reproduce it, add for example this line :

    rspadd Cache-Control:\ max-age=1500

Check the response header, it will provide :

Cache-Control: max-age=15000 <= the last character is duplicated

This only happens when we use backslashes on the last line of the
configuration file, without returning to the line.

Also if the last line is like :
  rspadd Cache-Control:\ max-age=1500\

the last backslash causes a segfault.

This is not due to rspadd but to a more general bug in cfgparse.c :
...
if (skip) {
        memmove(line + 1, line + 1 + skip, end - (line + skip + 1));
        end -= skip;
}
...

should be :
...
if (skip) {
        memmove(line + 1, line + 1 + skip, end - (line + skip));
        end -= skip;
}
...

I've reproduced it with haproxy 1.3.22 and the last 1.4 snapshot.
2009-12-06 13:46:14 +01:00
Willy Tarreau
68a897b2be [MINOR] config: support passing multiple "domain" statements to cookies
In some environments it is not possible to rely on any wildcard for a
domain name (eg: .com, .net, .fr...) so it is required to send multiple
domain extensions. (Un)fortunately the syntax check on the domain name
prevented that from being done the dirty way. So let's just build a
domain list when multiple domains are passed on the same line.
(cherry picked from commit 950245ca2b)
2009-12-06 13:25:23 +01:00
Willy Tarreau
4d187ac350 [BUG] config: cookie domain was ignored in defaults sections
Since cookie can appear in a defaults section, the domain extension
must be supported there as well.

(cherry picked from commit baf78c8e03)
2009-12-06 13:25:05 +01:00
Willy Tarreau
3d8fbb6658 [BUG] config: fix erroneous check on cookie domain names
It was a OR instead of a AND, so it was required to have a cookie
name which contained a dot AND began with a dot.
(cherry picked from commit a1e107fc13)
2009-12-06 13:24:20 +01:00
Willy Tarreau
1780416e33 [BUG] config: disable 'option httplog' on TCP proxies
Gabriel Sosa reported that logs were appearing with BADREQ when
'option httplog' was used with a TCP proxy (eg: inherited via a
default instance). This patch detects it and falls back to tcplog
after emitting a warning.
(cherry picked from commit 5f0bd6537f)
2009-12-06 13:24:11 +01:00
Willy Tarreau
7bb651ec1d [BUG] config: fix wrong handling of too large argument count
Holger Just reported that running ACLs with too many args caused
a segfault during config parsing. This is caused by a wrong test
on argument count. In case of too many arguments on a config line,
the last one was not correctly zeroed. This is now done and we
report the error indicating what part had been truncated.
(cherry picked from commit 3b39c1446b)
2009-12-06 13:23:43 +01:00
Willy Tarreau
c438242878 [BUG] config: fix error message when config file is not found
Cameron Simpson reported an annoying case where haproxy simply reports
"Error(s) found in configuration file" when the file is not found or
not readable.

Fortunately the parsing function still returns -1 in case of open
error, so we're able to detect the issue from the caller and report
the corresponding errno message.
2009-12-06 13:10:44 +01:00
Willy Tarreau
d0f06fc4b2 [MINOR] http: detect tunnel mode and set it in the session
In order to support keepalive, we'll have to differentiate
normal sessions from tunnel sessions, which are the ones we
don't want to analyse further.

Those are typically the CONNECT requests where we don't care
about any form of content-length, as well as the requests
which are forwarded on non-close and non-keepalive proxies.
2009-11-30 12:19:56 +01:00
Willy Tarreau
b86db34fe0 [BUG] x-original-to: name was not set in default instance
This resulted in an empty header name when option originalto
was declared in a default sections.
2009-11-30 11:50:16 +01:00
Cyril Bonté
b21570ae0f [MEDIUM] appsession: add "len", "prefix" and "mode" options
To sum up :
- len : it's now the max number of characters for the value, preventing
  garbaged results.
- a new option "prefix" is added, this allows to use dynamic cookie
  names (e.g. ASPSESSIONIDXXX).

Previously in the thread, I wanted to use the value found with
"capture cookie" but when i started to update the documentation, I
found this solution quite weird. I've made a small rework to not
depend on "capture cookie".

- There's the posssiblity to define the URL parser mode (path parameters
  or query string).
2009-11-30 11:31:53 +01:00
Willy Tarreau
fa355d4a51 [MINOR] http: keep pointer to beginning of data
We now set msg->col and msg->sov to the first byte of non-header.
They will be used later when parsing chunks. A new macro was added
to perform size additions on an http_msg in order to limit the risks
of copy-paste in the long term.

During this operation, it appeared that the http_msg struct was not
optimal on 64-bit, so it was re-ordered to fill the holes.
2009-11-29 18:12:29 +01:00
Willy Tarreau
a9de333aa5 [BUG] stream_sock: BUF_INFINITE_FORWARD broke splice on 64-bit platforms
Yohan Tordjman at Dstorage found that upgrading haproxy to 1.4-dev4
caused truncated objects to be returned. An strace quickly exhibited
the issue which was 100% reproducible :

4297  epoll_wait(0, {}, 10, 0)          = 0
4297  epoll_wait(0, {{EPOLLIN, {u32=7, u64=7}}}, 10, 1000) = 1
4297  splice(0x7, 0, 0x5, 0, 0xffffffffffffffff, 0x3) = -1 EINVAL (Invalid argument)
4297  shutdown(7, 1 /* send */)         = 0
4297  close(7)                          = 0
4297  shutdown(2, 1 /* send */)         = 0
4297  close(2)                          = 0

This is caused by the fact that the forward length is taken from
BUF_INFINITE_FORWARD, which is -1. The problem does not appear
in 32-bit mode because this value is first cast to an unsigned
long, truncating it to 32-bit (4 GB). Setting an upper bound
fixes the issue.

Also, a second error check has been added for splice. If EINVAL
is returned, we fall back to recv().
2009-11-28 07:47:10 +01:00
Willy Tarreau
655dce90d4 [MINOR] http: create new MSG_BODY sub-states
An HTTP message can be decomposed into several sub-states depending
on the transfer-encoding. We'll have to keep these state information
while parsing chunks, so we must extend the values. In order not to
change everything, we'll now consider that anything >= MSG_BODY is
the body, and that the value indicates the precise state. The
MSG_ERROR status which was greater than MSG_BODY was moved for this.
2009-11-08 13:10:58 +01:00
Willy Tarreau
da3b7c31f7 [MINOR] tools: add hex2i() function to convert hex char to int 2009-11-02 20:12:52 +01:00
Alex Williams
96532db923 [MINOR] server tracking: don't care about the tracked server's mode
Right now, an HTTP server cannot track a TCP server and vice-versa.
This patch enables proxy tracking without relying on the proxy's mode
(tcp/http/health). It only requires a matching proxy name to exist. The
original function was renamed to findproxy_mode().
2009-11-02 11:08:00 +01:00
Krzysztof Piotr Oledzki
de71d16ec0 [MINOR] Collect & provide http response codes for frontends, fix backends
This patch extends and corrects the functionality introduced by
"Collect & provide http response codes received from servers":
 - responses are now also accounted for frontends
 - backend's and frontend's counters are incremented based
   on responses sent to client, not received from servers
2009-10-27 21:56:47 +01:00
Krzysztof Piotr Oledzki
1f67285541 [MINOR] add additional "a href"s to stats page
This patch adds <a href> html links for proxies, frontends, servers
and backends. Once located, can be clicked. Users no longer have to
manually add #anchor to stat's url.
2009-10-27 21:56:47 +01:00
Willy Tarreau
3e79479348 [CLEANUP] ebtree: remove old unused files 2009-10-26 21:15:10 +01:00
Willy Tarreau
45cb4fb640 [MEDIUM] build: switch ebtree users to use new ebtree version
All files referencing the previous ebtree code were changed to point
to the new one in the ebtree directory. A makefile variable (EBTREE_DIR)
is also available to use files from another directory.

The ability to build the libebtree library temporarily remains disabled
because it can have an impact on some existing toolchains and does not
appear worth it in the medium term if we add support for multi-criteria
stickiness for instance.
2009-10-26 21:10:04 +01:00
Krzysztof Piotr Oledzki
516ed49964 [MINOR] Add "a name" to stats page
If you have a lot of proxies/servers in your stats page it is
not easy to locate the one you are interested in. You can
of couse use search function from you favorite web browser
but browsers often lost their focus when reloading stats.

This patch adds <a name> html tags for proxies, frontends, servers
and backends. You can use it to access a specific place, for example:

http://(stats_url)#proxy
http://(stats_url)#proxy/Frontend
http://(stats_url)#proxy/server1
http://(stats_url)#proxy/server2
http://(stats_url)#proxy/Backend
2009-10-24 09:54:31 +02:00
Willy Tarreau
8e89b84848 [MINOR] http: remove the last call to stream_int_return
And remove the now unused function itself too.
2009-10-18 23:56:35 +02:00
Willy Tarreau
b50943e717 [MINOR] http response: update the TX_CLI_CONN_KA flag on rewrite
If we modify the "connection" header we send to the client,
update the TX_CLI_CONN_KA flag.
2009-10-18 23:53:19 +02:00
Willy Tarreau
b8c82c295b [MEDIUM] http response: check body length and set transaction flags
We also check the close status and terminate the server persistent
connection if appropriate. Note that since this change, we'll not
get any "Connection: close" headers added to HTTP/1.0 responses
anymore, which is good.
2009-10-18 23:45:12 +02:00
Willy Tarreau
75a5fef4d2 [MINOR] http: pre-set the persistent flags in the transaction
We should pre-set the persistent flags then try to clear them
instead of the opposite.
2009-10-18 23:43:57 +02:00
Willy Tarreau
b37c27e28f [MAJOR] http: create the analyser which waits for a response
The code part which waits for an HTTP response has been extracted
from the old function. We now have two analysers and the second one
may re-enable the first one when an 1xx response is encountered.
This has been tested and works.

The calls to stream_int_return() that were remaining in the wait
analyser have been converted to stream_int_retnclose().
2009-10-18 23:15:41 +02:00
Willy Tarreau
2225dd4421 [MEDIUM] http request: make use of pre-parsed transfer-encoding header
This change should go a bit further. We should have a dedicated analyser
to find and skip chunks.
2009-10-18 21:36:47 +02:00
Willy Tarreau
03a5633299 [MEDIUM] http request: simplify POST length detection
We can now rely on the pre-parsed content-length and transfer-encoding
to find what the supposed body length will be.
2009-10-18 21:28:29 +02:00
Willy Tarreau
349a0f62b5 [MINOR] http request: simplify the test of no-data
Now we can rely on (chunked && !hdr_content_len) to stop forwarding
data. We only do that for known methods that are not CONNECT though.
2009-10-18 21:19:33 +02:00
Willy Tarreau
4273664a1b [MINOR] http request: update the TX_SRV_CONN_KA flag on rewrite
If we modify the "connection" header we send to the server,
update the TX_SRV_CONN_KA flag.
2009-10-18 21:10:21 +02:00
Willy Tarreau
32b47f42a0 [MEDIUM] http request: parse connection, content-length and transfer-encoding
Store those elements in the transaction. RFC2616 is strictly followed.
Note that requests containing two different content-length fields are
discarded as invalid.
2009-10-18 20:59:20 +02:00
Cyril Bonté
bf47aeb946 [MEDIUM] appsession: add the "request-learn" option
This patch has 2 goals :

1. I wanted to test the appsession feature with a small PHP code,
using PHPSESSID. The problem is that when PHP gets an unknown session
id, it creates a new one with this ID. So, when sending an unknown
session to PHP, persistance is broken : haproxy won't see any new
cookie in the response and will never attach this session to a
specific server.

This also happens when you restart haproxy : the internal hash becomes
empty and all sessions loose their persistance (load balancing the
requests on all backend servers, creating a new session on each one).
For a user, it's like the service is unusable.

The patch modifies the code to make haproxy also learn the persistance
from the client : if no session is sent from the server, then the
session id found in the client part (using the URI or the client cookie)
is used to associated the server that gave the response.

As it's probably not a feature usable in all cases, I added an option
to enable it (by default it's disabled). The syntax of appsession becomes :

  appsession <cookie> len <length> timeout <holdtime> [request-learn]

This helps haproxy repair the persistance (with the risk of losing its
session at the next request, as the user will probably not be load
balanced to the same server the first time).

2. This patch also tries to reduce the memory usage.
Here is a little example to explain the current behaviour :
- Take a Tomcat server where /session.jsp is valid.
- Send a request using a cookie with an unknown value AND a path
  parameter with another unknown value :

  curl -b "JSESSIONID=12345678901234567890123456789012" http://<haproxy>/session.jsp;jsessionid=00000000000000000000000000000001

(I know, it's unexpected to have a request like that on a live service)
Here, haproxy finds the URI session ID and stores it in its internal
hash (with no server associated). But it also finds the cookie session
ID and stores it again.

- As a result, session.jsp sends a new session ID also stored in the
  internal hash, with a server associated.

=> For 1 request, haproxy has stored 3 entries, with only 1 which will be usable

The patch modifies the behaviour to store only 1 entry (maximum).
2009-10-18 11:56:26 +02:00
Willy Tarreau
f1ba4b3de5 [MAJOR] buffer: flag BF_DONT_READ to disable reads when not required
When processing a GET or HEAD request in close mode, we know we don't
need to read anything anymore on the socket, so we can disable it.
Doing this can save up to 40% of the recv calls, and half of the
epoll_ctl calls.

For this we need a buffer flag indicating that we're not interesting in
reading anymore. Right now, this flag also disables both polled reads.
We might benefit from disabling only speculative reads, but we will need
at least this flag when we want to support keepalive anyway.

Currently we don't disable the flag on completion, but it does not
matter as we close ASAP when performing the shutw().
2009-10-18 08:52:24 +02:00
Willy Tarreau
b48b323223 [MEDIUM] fd: merge fd_list into fdtab
The fd_list[] used by sepoll was indexed on the fd number and was only
used to store the equivalent of an integer. Changing it to be merged
with fdtab reduces the number of pointer computations, the code size
and some initialization steps. It does not harm other pollers much
either, as only one integer was added to the fdtab array.
2009-10-18 08:20:26 +02:00
Willy Tarreau
8d5d77efc3 [OPTIM] move some rarely used fields out of fdtab
Some rarely information are stored in fdtab, making it larger for no
reason (source port ranges, remote address, ...). Such information
lie there because the checks can't find them anywhere else. The goal
will be to move these information to the stream interface once the
checks make use of it.

For now, we move them to an fdinfo array. This simple change might
have improved the cache hit ratio a little bit because a 0.5% of
performance increase has measured.
2009-10-18 08:17:33 +02:00
Willy Tarreau
ff9d5ba721 [CLEANUP] sepoll: clean up the fd_clr/fd_set functions
This cleanup also slightly reduces code size due to a better
construct and the use of an inlined version of alloc_spec_entry().
2009-10-17 21:43:03 +02:00
Willy Tarreau
7859991dd7 [MINOR] http: detect connection: close earlier
Till now we would only set SN_CONN_CLOSED after rewriting it. Now we
set it just after checking the Connection header so that we can use
the result later if required.
2009-10-17 20:15:29 +02:00
Krzysztof Piotr Oledzki
e5cc072e5d [BUG] Fix silly typo: hspr_other -> hrsp_other
s/hspr_other/hrsp_other/
2009-10-14 22:38:26 +02:00
Krzysztof Piotr Oledzki
5fb1882514 [MINOR] Collect & provide http response codes received from servers
Additional data is provided on both html & csv stats:
 - html: when passing a mouse over Sessions -> Total (servers, backends)
 - cvs: by 6 additional fields (hrsp_1xx, hrsp_2xx, hrsp_3xx, hrsp_4xx, hrsp_5xx, hspr_other)

Patch inspired by:
 http://www.formilux.org/archives/haproxy/0910/2528.html
 http://www.formilux.org/archives/haproxy/0910/2529.html
2009-10-14 21:49:53 +02:00
Willy Tarreau
5d53634f36 [MINOR] unix socket: report the socket path in case of bind error
When an error occurs during binding of the stats unix socket, messages
are far from clear for the user !
2009-10-14 20:37:00 +02:00
Willy Tarreau
cb6cd43725 [MINOR] tcp: add support for the defer_accept bind option
This can ensure that data is readily available on a socket when
we accept it, but a bug in the kernel ignores the timeout so the
socket can remain pending as long as the client does not talk.
Use with care.
2009-10-13 07:34:14 +02:00
Krzysztof Piotr Oledzki
f2d2b1d128 [MINOR] CSS & HTML fun
This patch makes stats page about 30% smaller and
"CSS 2.1" + "HTML 4.01 Transitional" compliant.

There should be no visible differences.

Changes:
 - add DOCTYPE for HTML 4.01 Transitional
 - add missing </ul>
 - remove cols=, AFAIK no modern browser support this property and
   it prevents validation to pass.
 - remove "align: center": there is no such property in css. There is
   however "text-align: center" but it is definitely not what we would
   like to see here.
 - by default align .titre to center
 - by default align .td to right
 - remove all align=right, no longer necessary
 - add class=ac (align center): shorter than "align=center" and use it when
   necessary
 - remove nowrap from td, instead use "white-space: nowrap" in css

Now stats page passes W3C validators for HTML & CSS. We may consider adding
"validated" icons from www.w3.org. ;)
2009-10-13 00:22:01 +02:00
Willy Tarreau
f5bbafe051 [MINOR] config: report all supported options for the "bind" keyword
"mss", "name" and "id" were missing.
2009-10-12 07:19:35 +02:00
Willy Tarreau
4e33d8677a [OPTIM] stats: check free space before trying to print
This alone makes a typical HTML stats dump consume 10% CPU less,
because we avoid doing complex printf calls to drop them later.
Only a few common cases have been checked, those which are very
likely to run for nothing.
2009-10-11 23:35:10 +02:00
Willy Tarreau
ea1f5fe28a [MINOR] stats: use a dedicated state to output static data
It is a bit expensive and complex to use to call buffer_feed()
directly from the request parser, and there are risks that some
output messages are lost in case of buffer full. Since most of
these messages are static, let's have a state dedicated to print
these messages and store them in a specific area shared with the
stats in the session. This both reduces code size and risks of
losing output data.
2009-10-11 23:12:51 +02:00
Willy Tarreau
cfeaa476c6 [MINOR] stats: add support for numeric IDs in set weight/get weight
Krzysztof reported that using names only for get weight/set weight
was not enough because it's still possible to have multiple servers
with the same name (and my test config is one of those). He suggested
to be able to designate them by their unique numeric IDs by prefixing
the ID with a dash.

That way we can have :

     set weight #120/#2

as well as

     get weight static/srv1 10
2009-10-10 22:33:08 +02:00
Krzysztof Piotr Oledzki
f7089f5852 [MINOR] Capture & display more data from health checks, v2
Capture & display more data from health checks, like
strerror(errno) for L4 failed checks or a first line
from a response for L7 successes/failed checks.

Non ascii or control characters are masked with
chunk_htmlencode() (html stats) or chunk_asciiencode() (logs).
2009-10-10 21:51:16 +02:00
Krzysztof Piotr Oledzki
ba8d7d3916 [MINOR] Add chunk_htmlencode and chunk_asciiencode
Add two functions to encode input chunk replacing
non-printable, non ascii or special characters
with:
 "&#%u;"  - chunk_htmlencode
 "<%02X>" - chunk_asciiencode

Above functions should be used when adding strings, received
from possible unsafe sources, to html stats or logs.
2009-10-10 21:51:16 +02:00
Willy Tarreau
4483d43c66 [MEDIUM] stats: add the "set weight" command
It is now possible to change a server's weight from the stats socket.
Just use "set weight <back>/<serv> <weight>".
2009-10-10 20:18:44 +02:00
Willy Tarreau
38338fa0a0 [MEDIUM] stats: add the "get weight" command to report a server's weight
This command is unrestricted and simply reports a server's weight, as
well as the weight initially configured, which at the moment are the
sames.
2009-10-10 19:39:21 +02:00
Willy Tarreau
975c50b838 [MINOR] add the "initial weight" to the server struct.
This one will be used when changing weights.
2009-10-10 19:34:06 +02:00
Willy Tarreau
f395017227 [MINOR] proxy: provide function to retrieve backend/server pointers
int get_backend_server(const char *bk_name, const char *sv_name,
                       struct proxy **bk, struct server **sv);

This function scans the list of backends and servers to retrieve the first
backend and the first server with the given names, and sets them in both
parameters. It returns zero if either is not found, or non-zero and sets
the ones it did not found to NULL. If a NULL pointer is passed for the
backend, only the pointer to the server will be updated.
2009-10-10 18:36:25 +02:00
Willy Tarreau
9bcc91e80e [MINOR] buffers: add buffer_feed2() and make buffer_feed() measure string length
It's inconvenient to always have to compute string lengths when calling
buffer_feed(), so change that.
2009-10-10 18:01:44 +02:00
Willy Tarreau
6162db2a81 [MEDIUM] add access restrictions to the stats socket
The stats socket can now run at 3 different levels :
  - user
  - operator (default one)
  - admin

These levels are used to restrict access to some information
and commands. Only the admin can clear all stats. A user cannot
clear anything nor access sensible data such as sessions or
errors.
2009-10-10 17:13:00 +02:00
Willy Tarreau
2f6bf2b82c [MINOR] stats: use 'clear counters all' to clear all values
The most common use of "clear counters" should be to only clear
max values without affecting cumulated values, for instance,
after an incident. So we change "clear counters" to only clear
max values, and add "clear counters all" to clear all counters.
2009-10-10 15:32:48 +02:00
SaVaGe
1d7a420c84 [BUG] task.c: don't assing last_timer to node-less entries
I noticed that in __eb32_insert , if the tree is empty
(root->b[EB_LEFT] == NULL) , the node.bit is not defined.
However in __task_queue there are checks:

- if (last_timer->node.bit < 0)
- if (task->wq.node.bit < last_timer->node.bit)

which might rely upon an undefined value.

This is how I see it:

1. We insert eb32_node in an empty wait queue tree for a task (called by
process_runnable_tasks() ):
Inserting into empty wait queue  &task->wq = 0x72a87c8, last_timer
pointer: (nil)

2. Then, we set the last timer to the same address:
Setting last_timer: (nil) to: 0x72a87c8

3. We get a new task to be inserted in the queue (again called by
process_runnable_tasks()) , before the __task_unlink_wq() is called for
the previous task.

4. At this point, we still have last_timer set to 0x72a87c8 , but since
it was inserted in an empty tree, it doesn't have node.bit and the
values above get dereferenced with undefined value.

The bug has no effect right now because the check for equality is still
made, so the next timer will still be queued at the right place anyway,
without any possible side-effect. But it's a pending bug waiting for a
small change somewhere to strike.

Iliya Polihronov
2009-10-10 15:15:07 +02:00
Willy Tarreau
a36af91951 [MINOR] acl: add fe_conn, be_conn, queue, avg_queue
These ACLs are used to check the number of active connections on the
frontend, backend or in a backend's queue. The avg_queue returns the
average number of queued connections per server, and for this, divides
the total number of queued connections by the number of alive servers.

The dst_conn ACL has been slightly changed to more reflect its name and
original usage, which is to return the number of connections on the
destination address/port (the socket) and not the whole frontend.
2009-10-10 12:02:45 +02:00
Willy Tarreau
6b2e11be1e [MEDIUM] backend: implement consistent hashing variation
Consistent hashing provides some interesting advantages over common
hashing. It avoids full redistribution in case of a server failure,
or when expanding the farm. This has a cost however, the hashing is
far from being perfect, as we associate a server to a request by
searching the server with the closest key in a tree. Since servers
appear multiple times based on their weights, it is recommended to
use weights larger than approximately 10-20 in order to smoothen
the distribution a bit.

In some cases, playing with weights will be the only solution to
make a server appear more often and increase chances of being picked,
so stats are very important with consistent hashing.

In order to indicate the type of hashing, use :

   hash-type map-based      (default, old one)
   hash-type consistent     (new one)

Consistent hashing can make sense in a cache farm, in order not
to redistribute everyone when a cache changes state. It could also
probably be used for long sessions such as terminal sessions, though
that has not be attempted yet.

More details on this method of hashing here :
  http://www.spiteful.com/2008/03/17/programmers-toolbox-part-3-consistent-hashing/
2009-10-09 07:17:58 +02:00
Krzysztof Piotr Oledzki
4cdd8314e9 [MINOR] acl: don't report valid acls as potential mistakes
Commit 404e8ab461 introduced
smart checking for stupid acl typos. However, now haproxy shows
the warning even for valid acls, like this one:
	acl Cookie-X-NoAccel    hdr_reg(cookie) (^|\ |;)X-NoAccel=1(;|$)
2009-10-08 07:00:07 +02:00
Willy Tarreau
ba255bc3c8 [BUG] counters: fix segfault on missing counters for a listener
If a frontend does not set 'option socket-stats', a 'clear counters'
on the stats socket could segfault because li->counters is NULL. The
correct fix is to check for NULL before as this is a valid situation.
2009-10-05 00:45:38 +02:00
Krzysztof Piotr Oledzki
6f61b21524 [BUG] Fix NULL pointer dereference in stats_check_uri_auth(), v2
Recent "struct chunk rework" introduced a NULL pointer dereference
and now haproxy segfaults if auth is required for stats but not found.

The reason is that size_t cannot store negative values, but current
code assumes that "len < 0" == uninitialized.

This patch fixes it.
2009-10-04 23:44:45 +02:00
Willy Tarreau
ac68c5d92c [OPTIM] counters: move some max numbers to the counters struct
There are a few remaining max values that need to move to counters.
Also, the counters are more often used than some config information,
so get them closer to the other useful struct members for better cache
efficiency.
2009-10-04 23:26:19 +02:00
Willy Tarreau
53fb4ae261 [MEDIUM] config: automatically find unused IDs for proxies, servers and listeners
Until now it was required that every custom ID was above 1000 in order to
avoid conflicts. Now we have the list of all assigned IDs and can automatically
pick the first unused one. This means that it is perfectly possible to interleave
automatic IDs with persistent IDs and the parser will automatically allocate
unused values starting with 1.
2009-10-04 23:04:08 +02:00
Willy Tarreau
482b00d1b4 [MINOR] tools: add a new get_next_id() function
This function returns the next unused key in a tree. This will be
used to find spare IDs.
2009-10-04 22:48:42 +02:00
Willy Tarreau
88922354fb [MINOR] config: add pointer to file name in block/redirect/use_backend/monitor rules
Those conditions already referenced the config line, but not the file.
2009-10-04 22:02:50 +02:00
Willy Tarreau
092549fa85 [MINOR] config: report places of duplicate names or IDs
When a name or ID conflict is detected, it is sometimes useful to know
where the other one was declared. Now that we have this information,
report it in error messages.
2009-10-04 21:16:08 +02:00
Willy Tarreau
90a570f025 [MINOR] config: reference file and line with any listener/proxy/server declaration
Those will be used later for cross-references of conflicts or errors.
2009-10-04 21:14:56 +02:00
Willy Tarreau
9d7e335127 [BUG] config: look for ID conflicts in all sockets, not only last ones.
ID conflicts between 'bind' lines were not detected due to this typo.
2009-10-04 21:13:39 +02:00
Krzysztof Piotr Oledzki
aeebf9ba65 [MEDIUM] Collect & provide separate statistics for sockets, v2
This patch allows to collect & provide separate statistics for each socket.
It can be very useful if you would like to distinguish between traffic
generate by local and remote users or between different types of remote
clients (peerings, domestic, foreign).

Currently no "Session rate" is supported, but adding it should be possible
if we found it useful.
2009-10-04 18:56:02 +02:00
Krzysztof Piotr Oledzki
719e726c97 [MINOR] Add "clear counters" to clear statistics counters
Now, when statistics counters are moved to separate
structures, adding "clear counters" is extremely easy.

[wt: updated the help message]
2009-10-04 18:40:08 +02:00
Krzysztof Piotr Oledzki
052d4fd07d [CLEANUP] Move counters to dedicated structures
Move counters from "struct proxy" and "struct server"
to "struct pxcounters" and "struct svcounters".

This patch should make no functional change.
2009-10-04 18:32:39 +02:00
Willy Tarreau
96fd4b5f09 [MEDIUM] stream_int: adjust WAIT_ROOM handling
When applets write data, they generall cannot fill the buffer, so as
soon as we find a non-empty buffer, we're sure we're missing some room.
2009-10-04 17:35:08 +02:00
Willy Tarreau
b0c9bc4f95 [MEDIUM] stats: make HTTP stats use an I/O handler
Doing this, we can remove the last BF_HIJACK user and remove
produce_content(). s->data_source could also be removed but
it is currently used to detect if the stats or a server was
used.
2009-10-04 15:56:38 +02:00
Willy Tarreau
65671abd32 [MINOR] remove now obsolete ana_state from the session struct
This one is not used anymore.
2009-10-04 14:24:59 +02:00
Willy Tarreau
f5a885fd28 [MEDIUM] stats: don't use s->ana_state anymore
The stats handler used to store internal states in s->ana_state. Now
we only rely on si->st0 in which we can store as many states as we
have possible outputs. This cleans up the stats code a lot and makes
it more maintainable. It has also reduced code size by a few hundred
bytes.
2009-10-04 14:22:18 +02:00
Willy Tarreau
24955a1000 [MINOR] stats: make stats_dump_raw_to_buffer() use buffer_feed_chunk
Same as previous change. A remaining call to stats_dump_proxy()
still prevents us from completing the update.
2009-10-04 12:17:54 +02:00
Willy Tarreau
7e72a8faf2 [MINOR] stats_dump_sess_to_buffer: use buffer_feed_chunk()
same as previous patch for this function.
2009-10-04 11:00:11 +02:00
Willy Tarreau
61b347342c [MINOR] stats_dump_errors_to_buffer: use buffer_feed_chunk()
We can simplify the code in the stats functions using buffer_feed_chunk()
instead of buffer_write_chunk(). Let's start with this function. This
patch also fixed an issue where we could dump past the end of the capture
buffer if it is shorter than the captured request.
2009-10-04 11:00:11 +02:00
Willy Tarreau
fe8903cc76 [BUG] don't refresh timeouts late after detected activity
In old versions, before 1.3.16, we had to refresh the timeouts after
each call to process_session() because the stream socket handler did
not do it. Now that the sockets can exchange data for a long period
without calling process_session(), we can detect an old activity and
refresh a timeout long after the last activity, causing too late a
detection of some timeouts.

The fix simply consists in not checking for activity anymore in
stream_sock_data_finish() but only set a timeout if it was not
previously set.
2009-10-04 10:56:08 +02:00
Willy Tarreau
816fc22a4a [MINOR] stats: strip CR and LF from the input command line
commands sent from certain tools (eg: telnet) will be terminated
by CRLF and not only LF. So we must suppress CR too.
2009-10-04 09:19:42 +02:00
Willy Tarreau
33b230b34a [BUG] stats: don't call buffer_shutw(), but ->shutw() instead
Calling buffer_shutw() marks the buffer as closed but if it was already
closed in the other direction, the stream interface is not marked as
closed, causing infinite loops.

We took this opportunity to completely remove buffer_shutw() and buffer_shutr()
which have no reason to be used at all and which will always cause trouble
when directly called. The stats occurrence was the last one.
2009-10-04 09:19:36 +02:00
Willy Tarreau
f27b5ea8dc [MEDIUM] new option "independant-streams" to stop updating read timeout on writes
By default, when data is sent over a socket, both the write timeout and the
read timeout for that socket are refreshed, because we consider that there is
activity on that socket, and we have no other means of guessing if we should
receive data or not.

While this default behaviour is desirable for almost all applications, there
exists a situation where it is desirable to disable it, and only refresh the
read timeout if there are incoming data. This happens on sessions with large
timeouts and low amounts of exchanged data such as telnet session. If the
server suddenly disappears, the output data accumulates in the system's
socket buffers, both timeouts are correctly refreshed, and there is no way
to know the server does not receive them, so we don't timeout. However, when
the underlying protocol always echoes sent data, it would be enough by itself
to detect the issue using the read timeout. Note that this problem does not
happen with more verbose protocols because data won't accumulate long in the
socket buffers.

When this option is set on the frontend, it will disable read timeout updates
on data sent to the client. There probably is little use of this case. When
the option is set on the backend, it will disable read timeout updates on
data sent to the server. Doing so will typically break large HTTP posts from
slow lines, so use it with caution.
2009-10-03 22:01:18 +02:00
Willy Tarreau
be5b68584e [MINOR] report list of supported pollers with -vv
During troubleshooting, it's often useful to get the list of supported
pollers but until now it was required to have a working configuration
first. Since the pollers are known before main() is called, let's list
them with the build options.
2009-10-03 18:57:08 +02:00
Willy Tarreau
9757a38feb [MEDIUM] backend: introduce the "static-rr" LB algorithm
The "static-rr" is just the old round-robin algorithm. It is still
in use when a hash algorithm is used and the data to hash is not
present, but it was impossible to configure it explicitly. This one
is cheaper in terms of CPU and supports unlimited numbers of servers,
so it makes sense to be able to use it.
2009-10-03 18:41:19 +02:00
Willy Tarreau
da76f4f711 [MINOR] backend: reorganize the LB algorithm selection
We can now factor out some common tests between all map-based
algorithms. This removes some redundancy and makes the code more
logical.
2009-10-03 18:41:18 +02:00
Willy Tarreau
f3e49f9521 [MINOR] backend: separate declarations of LB algos from their lookup method
LB algo macros were composed of the LB algo by itself without any indication
of the method to use to look up a server (the lb function itself). This
method was implied by the LB algo, which was not very convenient to add
more algorithms. Now we have several fields in the LB macros, some to
describe what to look for in the requests, some to describe how to transform
that (kind of algo) and some to describe what lookup function to use.

The next patch will make it possible to factor out some code for all algos
which rely on a map.
2009-10-03 18:41:18 +02:00
Willy Tarreau
5b4c2b58fe [CLEANUP] proxy: move last lb-specific bits to their respective files
The lbprm structure has moved to backend.h, where it should be, and
all algo-specific types and declarations have moved to their specific
files. The proxy struct is now much more readable.
2009-10-03 18:41:18 +02:00
Krzysztof Piotr Oledzki
619caca740 [MINOR] Allow dots in show-node & add "white-space: nowrap" in th.pxname. 2009-10-03 18:37:06 +02:00
Krzysztof Piotr Oledzki
48cb2aed5a [MINOR] add "description", "node" and show-node"/"show-desc", remove "node-name", v2
This patch implements "description" (proxy and global) and "node" (global)
options, removes "node-name" and adds "show-node" & "show-desc" options
for "stats". It also changes the way the header lines (with proxy name) and
the statistics are displayed, so stats no longer look so clumsy with very
long names.

Instead of "node-name" it is possible to use show-node/show-desc with
an optional parameter that overrides a default node/description.

backend cust-0045
        # report specific values for this customer
        stats show-node Europe
        stats show-desc Master node for Europe, Asia, Africa
2009-10-03 07:10:14 +02:00
Willy Tarreau
39c9ba72a7 [MINOR] lb_map: reorder code in order to ease integration of new hash functions
We need to remove hash map accesses out of backend.c if we want to
later support new hash methods. This patch separates the hash computation
method from the server lookup. It leaves the lookup function to lb_map.c
and calls it with the result of the hash.
2009-10-01 21:11:15 +02:00
Willy Tarreau
f89c1873f8 [CLEANUP] backend: move LB algos to individual files
It was becoming painful to have all the LB algos in backend.c.
Let's move them to their own files. A few hashing functions still
need be broken in two parts, one for the contents and one for the
map position.
2009-10-01 11:19:37 +02:00
Krzysztof Piotr Oledzki
99ab5f800c [MINOR] health checks logging unification
The code was duplicated serveral times, let's use
server_status_printf() instead.

   text    data     bss     dec     hex filename
 263504    5800   64224  333528   516d8 haproxy-old
 262944    5800   64224  332968   514a8 haproxy-new

Depends on "struct chunk rework" and
 "Health check reporting code rework + health logging, v3"
2009-10-01 10:17:38 +02:00
Krzysztof Piotr Oledzki
08ff959c3e [BUG] check if rise/fall has an argument and it is > 0
Check if rise/fall has an argument and it is > 0  or bad things may happen
in the health checks. ;)

Now it is verified and the code no longer allows for such condition:

backend bad
	(...)
        server o-f0 192.168.129.27:80 check inter 4000 source 0.0.0.0 rise 0
        server o-r0 192.168.129.27:80 check inter 4000 source 0.0.0.0 fall 0
        server o-f1 192.168.129.27:80 check inter 4000 source 0.0.0.0 rise
        server o-r1 192.168.129.27:80 check inter 4000 source 0.0.0.0 fall

[ALERT] 269/161830 (24136) : parsing [../git/haproxy.cfg:98]: 'rise' has to be > 0.
[ALERT] 269/161830 (24136) : parsing [../git/haproxy.cfg:99]: 'fall' has to be > 0.
[ALERT] 269/161830 (24136) : parsing [../git/haproxy.cfg:100]: 'rise' expects an integer argument.
[ALERT] 269/161830 (24136) : parsing [../git/haproxy.cfg:101]: 'fall' expects an integer argument.

Also add endline in the custom id checking code.
2009-10-01 10:17:38 +02:00
Krzysztof Piotr Oledzki
213014e587 [MEDIUM] Health check reporting code rework + health logging, v3
This patch adds health logging so it possible to check what
was happening before a crash. Failed healt checks are logged if
server is UP and succeeded healt checks if server is DOWN,
so the amount of additional information is limited.

I also reworked the code a little:

 - check_status_description[] and check_status_info[] is now
   joined into check_statuses[]

 - set_server_check_status updates not only s->check_status and
   s->check_duration but also s->result making the code simpler

Changes in v3:
 - for now calculate and use local versions of health/rise/fall/state,
   it is a slow path, no harm should be done. One day we may centralize
   processing of the checks and remove the duplicated code.
 - also log checks that are restoring current state
 - use "conditionally succeeded" for 404 with disable-on-404
2009-10-01 10:17:37 +02:00
Krzysztof Piotr Oledzki
78abe618a8 [MAJOR] struct chunk rework
Add size to struct chunk and simplify the code as there is
no longer required to pass sizeof in chunk_printf().
2009-10-01 10:17:37 +02:00
Willy Tarreau
ca7d4b98d4 [MINOR] backend: uninline some LB functions
There is no reason to inline functions which are used to grab a server
depending on an LB algo. They are large and used at several places.
Uninlining them saves 400 bytes of code.
2009-10-01 09:21:55 +02:00
Willy Tarreau
c5d9c80182 [MINOR] backend: export some functions to recount servers
Those functions will be used by new LB algorithms.
2009-10-01 09:17:05 +02:00
Willy Tarreau
2f9cc8ab52 [BUG] http stats: large outputs sometimes got some parts chopped off
Due to a misplaced call to stream_int_retnclose(), the stats output
buffer was erased before each call to produce_content(), resulting
in missing pieces in the stats output if the connection was not
fast enough between haproxy and the client.
2009-09-24 22:22:18 +02:00
Willy Tarreau
9a42c0d771 [MEDIUM] stats: replace the stats socket analyser with an SI applet
We can get rid of the stats analyser by moving all the stats code
to a stream interface applet. Above being cleaner, it provides new
advantages such as the ability to process requests and responses
from the same function and work only with simple state machines.
There's no need for any hijack hack anymore.

The direct advantage for the user are the interactive mode and the
ability to chain several commands delimited by a semi-colon. Now if
the user types "prompt", he gets a prompt from which he can send
as many requests as he wants. All outputs are terminated by a
blank line followed by a new prompt, so this can be used from
external tools too.

The code is not very clean, it needs some rework, but some part
of the dirty parts are due to the remnants of the hijack mode used
in the old functions we call.

The old AN_REQ_STATS_SOCK analyser flag is now unused and has been
removed.
2009-09-23 23:52:17 +02:00
Willy Tarreau
56a560aef4 [MEDIUM] stats: prepare the connection for closing before dumping
We will need to modify the stats dump functions so that they can
be used in interactive mode. For this, we want their caller to
prepare the connection for a close, not themselves to do it.
Let's simply move the stream_int_retnclose() out.
2009-09-23 23:52:16 +02:00
Willy Tarreau
1accfc0d3a [MEDIUM] session: call iohandler for embedded tasks (applets)
Currently, it's up to process_session() to call the internal tasks
if any are associated to the task being processed. If such a task
is referenced, we don't use ->update() in process_session(), but
only ->iohandler(), which itself is free to use ->update() to
complete its work.

It it also important to understand that an I/O handler may wake the
task up again, for instance because it tries to send data to the
other stream interface, which itself will wake the task up. So
after returning from ->iohandler(), we must check if the task has
been sent back to the runqueue, and if so, immediately return.
2009-09-23 23:52:15 +02:00
Willy Tarreau
fb90d94d7a [MINOR] stream_interface: add functions to support running as internal/external tasks
It will soon be necessary to have stream interfaces running as part of
the current task, or as independant tasks. For instance when we want to
implement compression or SSL. It will also be used for applets running
as stream interfaces.

These new functions are used to perform exactly that. Note that it's
still not easy to write a simple echo applet and more functions will
likely be needed.
2009-09-23 23:52:15 +02:00
Willy Tarreau
b029f8cd7d [MINOR] stream_interface: add iohandler callback
When stream interfaces will embedded applets running as part as their
holding task, we'll need a new callback to process them from the
session processor.
2009-09-23 23:52:15 +02:00
Willy Tarreau
89f7ef295d [MINOR] stream_interface: add SI_FL_DONT_WAKE flag
We had to add a new stream_interface flag : SI_FL_DONT_WAKE. This flag
is used to indicate that a stream interface is being updated and that
no wake up should be sent to its owner. This will be required for tasks
embedded into stream interfaces. Otherwise, we could have the
owner task send wakeups to itself during status updates, thus
preventing the state from converging. As long as a stream_interface's
status is being monitored and adjusted, there is no reason to wake it
up again, as we know its changes will be seen and considered.
2009-09-23 23:52:14 +02:00
Willy Tarreau
2e1dd3d213 [BUG] fix buffer_skip() and buffer_si_getline() to correctly handle wrap-arounds
Those two functions did not correctly deal with full buffers and/or
buffers that wrapped around. Buffer_skip() was even able to incorrectly
set buf->w further than the end of buffer if its len argument was wrong,
and buffer_si_getline() was able to incorrectly return a length larger
than the effective buffer data available.
2009-09-23 23:52:14 +02:00
Willy Tarreau
fb0e9209a9 [MINOR] ensure that buffer_feed() and buffer_skip() set BF_*_PARTIAL
It's important that these functions set these flags themselves, otherwise
the callers will always have to do this, and there is no valid reason for
not doing it.
2009-09-23 23:50:57 +02:00
Willy Tarreau
8280d64961 [BUG] variable buffer size ignored at initialization time
Commit 27a674efb8 introduced the ability
to configure buffer sizes. Unfortunately, the pool was created before
the conf was read, so that is was always set to the default size.

In order to fix that, we delay the call to init_buffer(), which is not
a problem since nothing uses it during the initialization.
2009-09-23 23:50:01 +02:00
Krzysztof Piotr Oledzki
0960541e49 [MEDIUM] Collect & show information about last health check, v3
Collect information about last health check result,
including L7 code if possible (for example http or smtp
return code) and time took to finish last check.

Health check info is provided on both stats pages (html & csv)
and logged when a server is marked UP or DOWN. Currently active
check are marked with an asterisk, but only in html mode.

Currently there are 14 status codes:
  UNK     -> unknown

  INI     -> initializing
  SOCKERR -> socket error

  L4OK    -> check passed on layer 4, no upper layers testing enabled
  L4TOUT  -> layer 1-4 timeout
  L4CON   -> layer 1-4 connection problem, for example "Connection refused"
              (tcp rst) or "No route to host" (icmp)

  L6OK    -> check passed on layer 6
  L6TOUT  -> layer 6 (SSL) timeout
  L6RSP   -> layer 6 invalid response - protocol error

  L7OK    -> check passed on layer 7
  L7OKC   -> check conditionally passed on layer 7, for example
               404 with disable-on-404
  L7TOUT  -> layer 7 (HTTP/SMTP) timeout
  L7RSP   -> layer 7 invalid response - protocol error
  L7STS   -> layer 7 response error, for example HTTP 5xx
2009-09-23 23:15:36 +02:00
Willy Tarreau
269358db93 [BUILD] stream_interface: fix conflicting declaration
stream_int_check_timeouts was declared void while it's an int.
2009-09-21 06:24:42 +02:00
Willy Tarreau
31971e536a [MEDIUM] add support for infinite forwarding
In TCP, we don't want to forward chunks of data, we want to forward
indefinitely. This patch introduces a special value for the amount
of data to be forwarded. When buffer_forward() is called with
BUF_INFINITE_FORWARD, it configures the buffer to never stop
forwarding until the end.
2009-09-20 12:07:52 +02:00
Willy Tarreau
59454bfaa4 [MINOR] stream_sock: don't set SI_FL_WAIT_DATA if BF_SHUTW_NOW is set
Don't ask for more data when we know we're about to close. This is
harmless but better have it cleaned up.
2009-09-20 11:14:27 +02:00
Willy Tarreau
f41ffdc1e9 [BUG] stream_interface: SI_ST_CLO must have buffers SHUT
An abort during a connect would go to the SI_ST_CLO state without
the buffers shut. This was causing some sessions to never end if
they would abort before the connect request was initiated. This
bug has been introduced after 1.4-dev2.

The doc has been extended to reflect that too.
2009-09-20 08:34:41 +02:00
Willy Tarreau
ba0b63d2c7 [MAJOR] buffers: fix the BF_EMPTY flag's meaning
The BF_EMPTY flag was once used to indicate an empty buffer. However,
it was used half the time as meaning the buffer is empty for the reader,
and half the time as meaning there is nothing left to send.

"nothing to send" is only indicated by "->send_max=0 && !pipe". Once
we fix this, we discover that the flag is not used anymore. So the
flags has been renamed BF_OUT_EMPTY and means exactly the condition
above, ie, there is nothing to send.

Doing so has allowed us to remove some unused tests for emptiness,
but also to uncover a certain amount of situations where the flag
was not correctly set or tested.
2009-09-20 08:17:45 +02:00
Willy Tarreau
520d95e42b [MAJOR] buffers: split BF_WRITE_ENA into BF_AUTO_CONNECT and BF_AUTO_CLOSE
The BF_WRITE_ENA buffer flag became very complex to deal with, because
it was used to :
  - enable automatic connection
  - enable close forwarding
  - enable data forwarding

The last point was not very true anymore since we introduced ->send_max,
but still the test remained everywhere. This was causing issues such as
impossibility to connect without forwarding data, impossibility to prevent
closing when data was forwarded, etc...

This patch clarifies the situation by getting rid of this multi-purpose
flag and replacing it with :
  - data forwarding based only on ->send_max || ->pipe ;
  - a new BF_AUTO_CONNECT flag to allow automatic connection and only
    that ;
  - ability to perform an automatic connection when ->send_max or ->pipe
    indicate that data is waiting to leave the buffer ;
  - a new BF_AUTO_CLOSE flag to let the producer automatically set the
    BF_SHUTW_NOW flag when it gets a BF_SHUTR.

During this cleanup, it was discovered that some tests were performed
twice, or that the BF_HIJACK flag was still tested, which is not needed
anymore since ->send_max replcaed it. These places have been fixed too.

These cleanups have also revealed a few areas where the other flags
such as BF_EMPTY are not cleanly used. This will be an opportunity for
a second patch.
2009-09-19 21:14:54 +02:00
Willy Tarreau
c77e761968 [MINOR] buffers: inline buffer_si_putchar()
By inlining this function and slightly reordering it, we can double
the getchar/putchar test throughput, and reduce its footprint by about
40 bytes. Also, it was the only non-inlined char-based function, which
now makes it more consistent this time.
2009-09-19 16:34:18 +02:00
Willy Tarreau
816b979977 [MAJOR] http: add support for HTTP 1xx informational responses
HTTP supports status codes 100 and 101 to report protocol indications,
which are followed by the requests's response. Till now, haproxy would
only see those responses without parsing subsequent ones. That means
that cookie additions were only performed on 1xx messages for instance,
which does not work since headers must be ignored with 1xx messages.
Also, logs were not terribly useful with the common 100 status code
in response to "Expect: 100-continue" during POST some requests.

This change adds support for such messages. Now haproxy sees them,
forwards them and skips them until it finds a correct response, which
it logs and processes. As an exception, header removal/rewriting still
work on 1xx responses in order to be able to strip out sensible
information that may have accidentely been left by another equipment
(possibly an older haproxy itself). But headers addition are disabled
however.

This change brings the ability to loop on response without data, which
is a starting point to support keepalive. The change is marked as major
as a few fixes had to be performed in the HTTP message parser.
2009-09-19 14:53:47 +02:00
Willy Tarreau
cb359e3f3c [MEDIUM] stream_interface: make use of buffer_cut_tail() to report errors
The stream_int_return() function used to call buffer_erase() on the response
buffer, which completely wipes it without taking care about whatever could
have been there. Now we more carefully strip only data not scheduled to be
sent.
2009-09-19 14:53:47 +02:00
Willy Tarreau
36a5c5389d [MINOR] buffers: provide buffer_si_putchar() to send a char from a stream interface
This function works like a traditional putchar() except that it
can return 0 if the output buffer is full.

Now a basic character-based echo function would look like this, from
a stream interface :

	while (1) {
		c = buffer_si_peekchar(req);
		if (c < 0)
			break;
		if (!buffer_si_putchar(res, c)) {
			si->flags |= SI_FL_WAIT_ROOM;
			break;
		}
		buffer_skip(req, 1);
		req->flags |= BF_WRITE_PARTIAL;
		res->flags |= BF_READ_PARTIAL;
	}
2009-09-19 14:53:47 +02:00
Willy Tarreau
4fe7a2ec6c [MINOR] buffers: add peekchar and peekline functions for stream interfaces
The buffer_si_peekline() function is sort of a fgets() to be used from a
stream interface. It returns a complete line whenever possible, and does
not update the buffer's pointer, so that the reader is free to consume
what it wants to.

buffer_si_peekchar() only returns one character, and also needs a call
to buffer_skip() once the character is definitely consumed.
2009-09-19 14:53:47 +02:00
Willy Tarreau
aeac31979e [MEDIUM] buffers: provide new buffer_feed*() function
This functions act like their buffer_write*() counter-parts,
except that they're specifically designed to be used from a
stream interface handler, as they carefully check size limits
and automatically advance the read pointer depending on the
to_forward attribute.

buffer_feed_chunk() is an inline calling buffer_feed() as both
are the sames. For this reason, buffer_write_chunk() has also
been turned into an inline which calls buffer_write().
2009-09-19 14:53:46 +02:00
Willy Tarreau
418fd4722a [MAJOR] buffers: fix misuse of the BF_SHUTW_NOW flag
This flag was incorrectly used as meaning "close immediately",
while it needs to say "close ASAP". ASAP here means when unsent
data pending in the buffer are sent. This helps cleaning up some
dirty tricks where the buffer output was checking the BF_SHUTR
flag combined with EMPTY and other such things. Now we have a
clearly defined semantics :

  - producer sets SHUTR and *may* set SHUTW_NOW if WRITE_ENA is
    set, otherwise leave it to the session processor to set it.
  - consumer only checks SHUTW_NOW to decide whether or not to
    call shutw().

This also induced very minor changes at some locations which were
not protected against buffer changes while the SHUTW_NOW flag was
set. Now we prevent send_max from changing when the flag is set.

Several tests have been run without any unexpected behaviour detected.

Some more cleanups are needed, as it clearly appears that some tests
could be removed with stricter semantics.
2009-09-19 14:53:46 +02:00
Willy Tarreau
106f979bbd [MINOR] acl: add support for hdr_ip to match IP addresses in headers
For x-forwarded-for and such headers, it's sometimes needed to match
based on network addresses. Let's use hdr_ip() for that.
2009-09-19 14:47:49 +02:00
Willy Tarreau
c465fd7836 [BUG] tarpit did not work anymore
Tarpit was broken by recent splitting of analysers. It would still
let the connection go to the server due to a missing buffer_write_dis().
Also, it was performed too late (after content switching rules).
2009-08-31 00:17:18 +02:00
Dmitry Sivachenko
caf58986fb [BUILD] compilation of haproxy-1.4-dev2 on FreeBSD
Please consider the following patches. They are required to
compile haproxy-1.4-dev2 on FreeBSD.

Summary:
1) include <sys/types.h> before <netinet/tcp.h>
2) Use IPPROTO_TCP instead of SOL_TCP
(they are both defined as 6, TCP protocol number)
2009-08-30 14:45:19 +02:00
Willy Tarreau
6db06d3870 [MEDIUM] remove TCP_CORK and make use of MSG_MORE instead
send() supports the MSG_MORE flag on Linux, which does the same
as TCP_CORK except that we don't have to remove TCP_NODELAY before
and we don't need any syscall to set/remove it. This can save up
to 4 syscalls around a send() (two for setting it, two for removing
it), and it's much cleaner since it is not persistent. So make use
of it instead.
2009-08-19 11:29:44 +02:00
Willy Tarreau
d6d06909da [CLEANUP] remove ifdef MSG_NOSIGNAL and define it instead
ifdefs are really annoying in the code. Define MSG_NOSIGNAL to zero
when undefined and remove associated ifdefs.
2009-08-19 11:25:08 +02:00
Willy Tarreau
dc85b39db7 [MEDIUM] stream_interface: add and use ->update function to resync
We used to call stream_sock_data_finish() directly at the end of
a session update, but if we want to support non-socket interfaces,
we need to have this function configurable. Now we access it via
->update().
2009-08-18 07:38:19 +02:00
Willy Tarreau
078e29495a [MEDIUM] report error on buffer writes larger than buffer size
Since it's now possible to change the buffer size by configuration,
we have to take special measures against writes that are larger than
the buffer size. Before this patch, the writers would indefinitely
block, waiting for some space to free up.

With this patch, the functions simply reject the data with an
appropriate code so that the writers can either detect and process
the error or go on, but never remain blocked.

This has been tested on the stats page which does no longer hang
with buffer sizes smaller than 2.5 kB (256 bytes is even OK for
the CSV version).
2009-08-18 07:19:39 +02:00
Willy Tarreau
27a674efb8 [MEDIUM] make it possible to change the buffer size in the configuration
The new tune.bufsize and tune.maxrewrite global directives allow one to
change the buffer size and the maxrewrite size. Right now, setting bufsize
too low will block stats sockets which will not be able to write at all.
An error checking must be added to buffer_write_chunk() so that if it
cannot write its message to an empty buffer, it causes the caller to abort.
2009-08-17 22:56:56 +02:00
Willy Tarreau
a07a34eb24 [MEDIUM] replace BUFSIZE with buf->size in computations
The first step towards dynamic buffer size consists in removing
all static definitions of the buffer size. Instead, we store a
buffer's size in itself. Right now they're all preinitialized
to BUFSIZE, but we will change that.
2009-08-16 23:27:46 +02:00
Willy Tarreau
4e5b8287a6 [MEDIUM] set rep->analysers from fe and be analysers
sess_establish() used to resort to protocol-specific guesses
in order to set rep->analysers. This is no longer needed as it
gets set from the frontend and the backend as a copy of what
was defined in the configuration.
2009-08-16 22:57:50 +02:00
Willy Tarreau
52a0c60845 [MINOR] set s->srv_error according to the analysers
s->srv_error was set depending on the frontend's protocol. Now it is
set by the HTTP analyser, so that even when switching from a TCP
frontend to an HTTP backend, we can have HTTP error messages.
2009-08-16 22:45:38 +02:00
Willy Tarreau
c1a2167e9d [MINOR] cleanup set_session_backend by using pre-computed analysers
Analyser bitmaps are now stored in the frontend and backend, and
combined at configuration time. That way, set_session_backend()
does not need to perform any protocol-specific combinations.
2009-08-16 22:37:44 +02:00
Willy Tarreau
2c9f5b130f [MINOR] move the initial task's nice value to the listener
Since the listener is the one indicating what analyser and session
handlers to call, it makes sense that it also sets the task's nice
value. This also helps getting rid of the last trace of the stats
in the proto_uxst file.
2009-08-16 19:36:56 +02:00
Willy Tarreau
5ca791da8d [CLEANUP] move remaining stats sockets code to dumpstats
The remains of the stats socket code has nothing to do in proto_uxst
anymore and must move to dumpstats. The code is much cleaner and more
structured. It was also an opportunity to rename AN_REQ_UNIX_STATS
as AN_REQ_STATS_SOCK as the stats socket is no longer unix-specific
either.

The last item refering to stats in proto_uxst is the setting of the
task's nice value which should in fact come from the listener.
2009-08-16 19:35:36 +02:00
Willy Tarreau
8e13d7492d [CLEANUP] unix: remove uxst_process_session()
This one is not used anymore.
2009-08-16 19:34:23 +02:00
Willy Tarreau
104eb36f26 [MEDIUM] make the unix stats sockets use the generic session handler
process_session() is now ready to handle unix stats sockets. This
first step works and old code has not been removed. A cleanup is
required. The stats handler is not unix socket-centric anymore and
should move to dumpstats.c.
2009-08-16 19:33:51 +02:00
Willy Tarreau
7320122655 [MINOR] session: switch to established state if no connect function
When a stream interface has no connect() function, it means it is
immediately connected, so we don't need any connection request.
This will be used with unix sockets.
2009-08-16 19:33:29 +02:00
Willy Tarreau
6e6fb2beb9 [MEDIUM] session: account per-listener connections
In order to merge the unix session handling code, we have to maintain
the number of per-listener connections in the session. This was only
performed for unix sockets till now.
2009-08-16 19:32:44 +02:00
Willy Tarreau
89a6313c34 [MEDIUM] make the global stats socket part of a frontend
Creating a frontend for the global stats socket will help merge
unix sockets management with the other socket management. Since
frontends are huge structs, we only allocate it if required.
2009-08-16 19:31:51 +02:00
Willy Tarreau
9650f37628 [MEDIUM] move connection establishment from backend to the SI.
The connection establishment was completely handled by backend.c which
normally just handles LB algos. Since it's purely TCP, it must move to
proto_tcp.c. Also, instead of calling it directly, we now call it via
the stream interface, which will later help us unify session handling.
2009-08-16 17:46:15 +02:00
Willy Tarreau
c9fce2fee8 [BUILD] fix build for systems without SOL_TCP
Andrew Azarov reported that haproxy-1.4-dev1 does not build
under FreeBSD 7.2 because SOL_TCP is not defined. So add a
check for its definition before using it. This only impacts
network optimisations anyway.
2009-08-16 14:13:47 +02:00
Willy Tarreau
b55932ddaf [MEDIUM] remove old experimental tcpsplice option
This Linux-specific option was never really used in production and
has since been superseded by new splicing options brought by recent
Linux kernels.

It caused several particular cases in the code because the kernel
would take care of the session without haproxy being able to do
anything on it, which became hard to handle in the new architecture.

Let's simply get rid of it now that there is a replacement available.
2009-08-16 13:20:32 +02:00
Willy Tarreau
1d45b7cbae [MINOR] stats: add a new node-name setting
The new "node-name" stats setting enables reporting of a node ID on
the stats page. It is possible to return the system's host name as
well as a specific name.
2009-08-16 10:29:18 +02:00
Willy Tarreau
3ad6a7640b [MINOR] export the hostname variable so that all the code can access it
The hostname variable will be used later, export it.
2009-08-16 10:08:02 +02:00
Willy Tarreau
e7ded1f869 [BUG] log: option tcplog would log to global if no logger was defined
Romuald du Song reported a strange bug causing "option tcplog" to
unexpectedly use global log parameters if no log server was declared.

Eventhough it can be useful in some circumstances, it only hides
configuration bugs and can even cause traffic logs to be sent to
the wrong logger, since global settings are just for the process.

This has been fixed and a warning has been added for configurations
where tcplog or httplog are set without any logger. This fix must
be backported to 1.3.20, but not to 1.3.15.X in order not to risk
any regression on old configurations.
2009-08-09 10:11:45 +02:00
Willy Tarreau
34e98ea70d [BUG] task: fix possible crash when some timeouts are not configured
Cristian Ditoiu reported a major regression when testing 1.3.19 at
transfer.ro. It would crash within a few minutes while 1.3.15.10
was OK. He offered to help so we could run gdb and debug the crash
live. We finally found that the crash was the result of a regression
introduced by recent fix 814c978fb6
(task: fix possible timer drift after update) which makes it possible
for a tree walk to start from a detached task if this task has got
its timeout disabled due to a missing timeout.

The trivial fix below has been extensively tested and confirmed not
to crash anymore.

Special thanks to Cristian who spontaneously provided a lot of help
and trust to debug this issue which at first glance looked impossible
after reading the code and traces, but took less than an hour to spot
and fix when caught live in gdb ! That's really appreciated !
2009-08-09 09:09:54 +02:00
Willy Tarreau
c54aef3180 [BUG] fix random pauses on last segment of a series
During a direct data transfer from the server to the client, if the
system did not have enough buffers anymore, haproxy would not enable
write polling again if it could write at least one data chunk. Under
normal conditions, this would remain undetected because the remaining
data would be pushed by next data chunks.

However, when this happens on the last chunk of a session, or the last
in a series in an interactive bidirectional TCP transfer, haproxy would
only start sending again when the read timeout was reached on the side
it stopped writing, causing long pauses on some protocols such as SQL.

This bug was reported by an Exceliance customer who generously offered
to help us by sending large amounts of traces and running various tests
on production systems.

It is quite hard to trigger it but it becomes easier with a ping-pong
TCP service which transfers random data sizes, with a modified version
of send() able to send packets smaller than the average transfer size.

A cleaner fix would imply only updating the write timeout when data
transfers are *attempted*, not succeeded, but that requires more
sensible code changes without fixing the result. It is a candidate
for a later patch though.
2009-07-27 20:08:06 +02:00
Willy Tarreau
bc69d8bbcf [BUILD] fix incorrect printf arg count with tcp_splice
remove an extra arg.
2009-07-26 20:40:05 +02:00
Willy Tarreau
404e8ab461 [MINOR] acl: detect and report potential mistakes in ACLs
I've discovered a configuration with lots of occurrences of the
following :

    acl xxx hdr_beg (host) xxx

The problem is that hdr_beg will match every header against patterns
(host) and xxx due to the space between both, which certainly is not
what the user wanted. Now we detect such ACLs and report a warning
with a suggestion to add "--" between "hdr_beg" and "(host)" if this
is definitely what is wanted.
2009-07-26 19:40:40 +02:00
Willy Tarreau
43e0e39978 [MINOR] print usage on the stats sockets upon invalid commands
When issuing commands on the unix socket, there's no way to
know if the result is empty or if the command is wrong. This
patch makes invalid command return a help message.
2009-07-26 18:16:43 +02:00
Willy Tarreau
b455691af3 [CLEANUP] report 2009 not 2008 in the copyright banner. 2009-07-26 17:33:39 +02:00
Willy Tarreau
be8c736cca [BUILD] fix a minor build warning on AIX
AIX wants string.h in signal.c (and is right to do so) :

gcc -Iinclude -Wall  -O2 -g       -DTPROXY -DENABLE_POLL  -DCONFIG_HAPROXY_VERSION=\"1.3.18\" -DCONFIG_HAPROXY_DATE=\"2009/05/10\" -c -o src/signal.o src/signal.c
src/signal.c: In function 'signal_init':
src/signal.c:32: warning: implicit declaration of function 'memset'
src/signal.c:32: warning: incompatible implicit declaration of built-in function 'memset'
2009-07-26 17:32:11 +02:00
Willy Tarreau
bb9250104f [MINOR] config: improve error reporting when checking configuration
Do not exit early at the first error found while checking configuration
validity. This particularly helps spotting multiple wrong tracked server
names at once.
2009-07-26 17:30:43 +02:00
Willy Tarreau
3b6b1a984d [MINOR] config: the "capture" keyword is not allowed in backends
The "capture" keyword is only supported by frontends, fix the check.
2009-07-26 17:30:30 +02:00
Willy Tarreau
9389379f60 [MINOR] config: improve error reporting in listen sections
Try not to immediately exit on non-fatal errors while parsing a
listen section, so that the user has a chance to get most of the
errors at once, which is quite convenient especially during config
checks with the -c argument.
2009-07-26 17:29:55 +02:00
Willy Tarreau
058e907486 [MINOR] config: improve error reporting in global section
Try not to immediately exit on non-fatal errors while parsing the
global section, so that the user has a chance to get most of the
errors at once, which is quite convenient especially during config
checks with the -c argument. Some other errors such as unresolved
server names also don't make the parser exit too early.
2009-07-26 17:24:11 +02:00
Willy Tarreau
da6721ba28 [MINOR] stats: better displaying in MSIE
MSIE does not correctly display spaced digits. It requires a margin of
at least one pixel. Also, it does not correctly hide empty cells, so we
work around this by setting the background white. Last, the H1 font was
too large, so we reduce it by one size, which is still OK in other
browsers.
2009-07-15 10:07:05 +02:00
Willy Tarreau
1274bc4fa8 [MINOR] apply tcp-smart-connect option for the checks too
We should respect tcp-smart-connect for checks too. First it reduces
the traffic, and second it ensures that the checks see the same thing
as the production traffic, which is better for debugging.
2009-07-15 07:16:31 +02:00
Willy Tarreau
814c978fb6 [BUG] task: fix possible timer drift after update
When the scheduler detected that a task was misplaced in the timer
queue, it used to place it right again. Unfortunately, it did not
check whether it would still call the new task from its new place.
This resulted in some tasks not getting called on timeout once in
a while, causing a minor drift for repetitive timers. This effect
was only observable with slow health checks and without any activity
because no other task would cause the scheduler to be immediately
called again.

In practice, it does not affect any real-world configuration, but
it's still better to fix it.
2009-07-14 23:48:55 +02:00
Willy Tarreau
606ad73e73 [BUG] config: tcp-request content only accepts "if" or "unless"
As reported by Maik Broemme, if something different from "if" or
"unless" was specified after "tcp-request content accept", the
condition would silently remain void. The parser must obviously
complain since this typically corresponds to a forgotten "if".
2009-07-14 21:17:05 +02:00
Willy Tarreau
7154365cc6 [BUG] stream_sock: don't stop reading when the poller reports an error
As reported by Jean-Baptiste Quenot and Robbie Aelter, sometimes a
backend server error is converted to a 502 error if the backend stops
before reading all the request. The reason is that the remote system
sends a TCP RST packet because there are still unread data pending in
the socket buffer. This RST is translated as a socket error on the
local system, and this error is reported by the poller.

However, most of the time, it's a write error, but the system is
still able to read the remaining pending data, such as in the trace
below :

send(7, "GET /aaa HTTP/1.0\r\nUser-Agent: Mo"..., 1123, MSG_DONTWAIT|MSG_NOSIGNAL) = 1123
epoll_ctl(3, EPOLL_CTL_ADD, 7, {EPOLLIN, {u32=7, u64=7}}) = 0
epoll_wait(3, {{EPOLLIN|EPOLLERR|EPOLLHUP, {u32=7, u64=7}}}, 8, 1000) = 1
gettimeofday({1247593958, 643572}, NULL) = 0
recv(7, "HTTP/1.0 400 Bad request\r\nCache-C"..., 7000, MSG_NOSIGNAL) = 187
setsockopt(6, SOL_TCP, TCP_NODELAY, [0], 4) = 0
setsockopt(6, SOL_TCP, TCP_CORK, [1], 4) = 0
send(6, "HTTP/1.0 400 Bad request\r\nCache-C"..., 187, MSG_DONTWAIT|MSG_NOSIGNAL) = 187
shutdown(6, 1 /* send */)               = 0

The recv succeeded while epoll_wait() reported an error.

Note: This case is very hard to reproduce and requires that the backend
server is reached via the loopback in order to minimise latency and
reduce the risk of sent data being ACKed.
2009-07-14 19:55:05 +02:00
Willy Tarreau
720058cdcb [BUG] stream_sock: always shutdown(SHUT_WR) before closing
When we close a socket with unread data in the buffer, or when the
nolinger option is set, we regularly lose the last fragment, which
often contains the error message. This typically occurs when sending
too large a request. Only the RST is seen due to the close() (since
not all data were read) and the output message never reaches the
network.

Doing a shutdown() before the close() solves this annoying issue
because the data are really pushed before the system sends the RST.
2009-07-14 19:21:50 +02:00
Willy Tarreau
1a211943f6 [MINOR] acl: don't complain anymore when using L7 acls in TCP
Since TCP can now check contents using L7 acls, we must not
complain anymore.
2009-07-14 13:53:17 +02:00
Emeric Brun
3a058f3091 [MINOR] add a new CLF log format
Appending the "clf" word after "option httplog" turns the HTTP log
format into a CLF format, more suited for certain tools.
2009-07-14 12:50:40 +02:00
Emeric Brun
647caf1ebc [MEDIUM] add support for RDP cookie persistence
The new statement "persist rdp-cookie" enables RDP cookie
persistence. The RDP cookie is then extracted from the RDP
protocol, and compared against available servers. If a server
matches the RDP cookie, then it gets the connection.
2009-07-14 12:50:40 +02:00
Emeric Brun
736aa238a3 [MEDIUM] add support for RDP cookie load-balancing
This patch adds support for hashing RDP cookies in order to
use them as a load-balancing key. The new "rdp-cookie(name)"
load-balancing metric has to be used for this. It is still
mandatory to wait for an RDP cookie in the frontend, otherwise
it will randomly work.
2009-07-14 12:50:39 +02:00
Emeric Brun
bede3d0ef4 [MINOR] acl: add support for matching of RDP cookies
The RDP protocol is quite simple and documented, which permits
an easy detection and extraction of cookies. It can be useful
to match the MSTS cookie which can contain the username specified
by the client.
2009-07-14 12:50:39 +02:00
Willy Tarreau
51d5dad90a [MINOR] allow TCP inspection rules to make use of HTTP ACLs
Since we can call the HTTP parser from TCP inspection rules, it makes
sense to be able to use the HTTP ACLs with it. That way, we can decide
from a TCP frontend to take a switching decision based on full layer7
decoding. This might be useful to perform layer7 content switching from
a layer4 frontend in fact. For instance, we might want to be able to
detect http/https on a frontend, but still switch to backend X or Y
depending on the Host header. Note that it is mandatory to wait for
an HTTP request otherwise the ACLs will randomly match.
2009-07-12 10:10:05 +02:00
Willy Tarreau
cd7afc0a13 [MINOR] http: take http request timeout from the backend
Since we can now switch from TCP to HTTP, we need to be able to apply
the HTTP request timeout after switching. That means we need to take
it from the backend and not from the frontend. Since the backend points
to the frontend before switching, that changes nothing for the normal
case.
2009-07-12 10:03:17 +02:00
Willy Tarreau
d88bb6f819 [MINOR] ensure we can jump from swiching rules to http without data
In case of switching from TCP to HTTP, we want the HTTP request timeout
to be properly initialized. For this, we have to jump to the analyser
without breaking out of the loop nor waiting for incoming data. The way
it is done right now is not particularly clean but it works.

A cleaner method might involve pushing function pointers into a circular
list.
2009-07-12 09:55:41 +02:00
Willy Tarreau
51aecc76f8 [MEDIUM] allow a TCP frontend to switch to an HTTP backend
This patch allows a TCP frontend to switch to an HTTP backend.
During the switch, missing structures are automatically allocated.
The HTTP parser is enabled so that the backend first waits for a
full HTTP request.
2009-07-12 09:47:04 +02:00
Willy Tarreau
a55b7dc528 [BUG] default ACLs did not properly set the ->requires flag
This bug caused session initialization not to always allocate
the hdr_idx struct for default ACLs involving HTTP content.
2009-07-12 09:21:30 +02:00
Willy Tarreau
bedb9bad67 [MINOR] prepare callers of session_set_backend to handle errors
session_set_backend will soon have to allocate areas for HTTP
headers. We must ensure that the callers can handle an allocation
error.
2009-07-12 08:36:24 +02:00
Willy Tarreau
2492d5b4d6 [MINOR] acl: add HTTP protocol detection (req_proto_http)
Now that we can perform TCP-based content switching, it makes sense
to be able to detect HTTP traffic and act accordingly. We already
have an HTTP decoder, we just have to call it in order to detect HTTP
protocol. Note that since the decoder will automatically fill in the
interesting fields of the HTTP transaction, it would make sense to
use this parsing to extend HTTP matching to TCP.
2009-07-12 08:06:20 +02:00
Willy Tarreau
bf2886274c [MINOR] http: rely on proxy->acl_requires to allocate hdr_idx
Right now only HTTP proxies may use HTTP headers in ACLs, but
when this evolves, we'll need to be able to allocate the hdr_idx
on demand. The solution consists in allocating it only when it is
certain that at least one ACL requires HTTP parsing, regardless
of the mode the proxy is in. This is what is achieved by this
patch.
2009-07-10 23:52:51 +02:00
Willy Tarreau
a9fb08317f [MINOR] report in the proxies the requirements for ACLs
This patch propagates the ACL conditions' "requires" bitfield
to the proxies. This makes it possible to know exactly what a
proxy might have to support for any request, which helps knowing
whether we have to allocate some space for certain types of
structures or not (eg: the hdr_idx struct).

The concept might be extended to a lot more types of information,
such as detecting whether we need to allocate some space for some
request ACLs which need a result in the response, etc...
2009-07-10 23:09:39 +02:00
Willy Tarreau
1d0dfb155d [MAJOR] http: complete splitting of the remaining stages
The HTTP processing has been splitted into 7 steps, one of which
is not anymore HTTP-specific (content-switching). That way, it
becomes possible to use "use_backend" rules in TCP mode. A new
"use_server" directive should follow soon.
2009-07-07 15:10:31 +02:00
Willy Tarreau
3a816293e9 [MEDIUM] session: tell analysers what bit they were called for
Some stream analysers might become generic enough to be called
for several bits. So we cannot have the analyser bit hard coded
into the analyser itself. Let's make the caller inform the callee.
2009-07-07 10:55:49 +02:00
Willy Tarreau
d787e6648c [MEDIUM] http: split request waiter from request processor
We want to split several steps in HTTP processing so that
we can call individual analysers depending on what processing
we want to perform. The first step consists in splitting the
part that waits for a request from the rest.
2009-07-07 10:14:51 +02:00
Willy Tarreau
571ec98baa [CLEANUP] remove unused DEBUG_PARSE_NO_SPEEDUP define
This one has become useless with the new HTTP parser.
2009-07-07 08:56:15 +02:00
Willy Tarreau
06b917c7ab [BUG] http: redirect rules were processed too early
redirect rules are documented as being processed last before
use_backend but were mistakenly processed before block rules.
Fortunately very few people use a mix of block and redirect
rules, so this bug has never been reported yet.
2009-07-06 16:34:52 +02:00
Willy Tarreau
dc340a900d [MEDIUM] splice: set the capability on each stream_interface
The splice code did not consider compatibility between both ends
of the connection. Now we set different capabilities on each
stream interface, depending on what the protocol can splice to/from.
Right now, only TCP is supported. Thanks to this, we're now able to
automatically detect when splice() is not implemented and automatically
disable it on one end instead of reporting errors to the upper layer.
2009-06-28 23:10:19 +02:00
Willy Tarreau
1a52dbda59 [MEDIUM] session: rework buffer analysis to permit permanent analysers
It will soon be necessary to support permanent analysers (eg: HTTP in
keep-alive mode). We first have to slightly rework the call to the
request analysers so that we don't force ->analysers to be 0 before
forwarding data.
2009-06-28 19:37:53 +02:00
Willy Tarreau
5d707e1aaa [MEDIUM] stream_sock: don't close prematurely when nolinger is set
When the nolinger option is used, we must not close too fast because
some data might be left unsent. Instead we must proceed with a normal
shutdown first, then a close. Also, we want to avoid merging FIN with
the last segment if nolinger is set, because if that one gets lost,
there is no chance for it to be retransmitted.
2009-06-28 11:09:07 +02:00
Willy Tarreau
5d01a63b78 [MEDIUM] config: support loading multiple configuration files
We now support up to 10 distinct configuration files. They are
all loaded in the order defined by -f <file1> -f <file2> ...

This can be useful in order to store global, private, public,
etc... configurations in distinct files.
2009-06-23 08:17:17 +02:00
Willy Tarreau
915e1ebe63 [MEDIUM] config: split parser and checker in two functions
This is a first step towards support of multiple configuration files.
Now readcfgfile() only reads a file in memory and performs very minimal
parsing. The checks are performed afterwards.
2009-06-23 08:17:17 +02:00
Willy Tarreau
3deb3d0418 [MAJOR] session: simplify buffer error handling
Buffer errors (timeouts and I/O errors) were handled at two places,
just after the analysers and after again.

Now that the timeout detection has moved, it has become easier to
handle those errors.

This has also made it possible for the request and response analysers
to be processed together as a down-up event, and all the up-down I/O
updates to be processed afterwards, which is exactly what we're looking
for. Interestingly this has reduced the number of iterations of
(stream_int, req_resp) from (5,6,5) to (5,5,4).

Several tests have been run without any issue found.
2009-06-21 23:40:24 +02:00
Willy Tarreau
b67a9b8ca8 [MAJOR] session: only check for timeouts when they have just occurred.
It's useless to check for buffer timeouts every time we call
process_session() because we already control when we set the flag. So
let's check them at the precise moment where the flag is set.
2009-06-21 22:12:49 +02:00
Willy Tarreau
ea38854d34 [MAJOR] session: don't clear buffer status flags anymore
We want to be able to keep information about errors and timeouts
as long as possible in the buffer. Let's not clear these flags
anymore and keep them static. This does not seem to cause any
trouble, though a finer review might be wise.
2009-06-21 21:45:58 +02:00
Willy Tarreau
6704d67d65 [MEDIUM] support setting a server weight to zero
Sometimes it is useful to be able to set a server's weight to zero.
It allows the server to receive only persistent traffic but never
normal traffic.
2009-06-15 10:56:05 +02:00
Willy Tarreau
be1b91842a [MEDIUM] add support for TCP MSS adjustment for listeners
Sometimes it can be useful to limit the advertised TCP MSS on
incoming connections, for instance when requests come through
a VPN or when the system is running with jumbo frames enabled.

Passing the "mss <value>" arguments to a "bind" line will set
the value. This works under Linux >= 2.6.28, and maybe a few
earlier ones, though due to an old kernel bug most of earlier
versions will probably ignore it. It is also possible that some
other OSes will support this.
2009-06-14 18:48:19 +02:00
Willy Tarreau
d88edf2e52 [MEDIUM] implement tcp-smart-connect option at the backend
This new option enables combining of request buffer data with
the initial ACK of an outgoing TCP connection. Doing so saves
one packet per connection which is quite noticeable on workloads
mostly consisting in small objects. The option is not enabled by
default.
2009-06-14 15:48:17 +02:00
Willy Tarreau
fb14edc215 [MEDIUM] stream_sock: implement tcp-cork for use during shutdowns on Linux
Setting TCP_CORK on a socket before sending the last segment enables
automatic merging of this segment with the FIN from the shutdown()
call. Playing with TCP_CORK is not easy though as we have to track
the status of the TCP_NODELAY flag since both are mutually exclusive.
Doing so saves one more packet per session and offers about 5% more
performance.

There is no reason not to do it, so there is no associated option.
2009-06-14 15:24:37 +02:00
Willy Tarreau
9ea05a790f [MEDIUM] implement option tcp-smart-accept at the frontend
This option disables TCP quick ack upon accept. It is also
automatically enabled in HTTP mode, unless the option is
explicitly disabled with "no option tcp-smart-accept".

This saves one packet per connection which can bring reasonable
amounts of bandwidth for servers processing small requests.
2009-06-14 12:07:01 +02:00
Willy Tarreau
3842f00a19 [MINOR] config: support resetting options do default values
A new keyword prefix "default" has been introduced in order to
reset some options to their default values. This can be needed
for instance when an option is forced disabled or enabled in a
defaults section and when later sections want to use automatic
settings regardless of what was specified there. Right now it
is only supported by options, just like the "no" prefix.
2009-06-14 11:39:52 +02:00
Willy Tarreau
84b57dae4a [MINOR] config: track "no option"/"option" changes
Sometimes we would want to implement implicit default options,
but for this we need to be able to disable them, which requires
to keep track of "no option" settings. With this change, an option
explicitly disabled in a defaults section will still be seen as
explicitly disabled. There should be no regression as nothing makes
use of this yet.
2009-06-14 11:10:45 +02:00
Willy Tarreau
c6f4ce8fc4 [MEDIUM] add support for binding to source port ranges during connect
Some users are already hitting the 64k source port limit when
connecting to servers. The system usually maintains a list of
unused source ports, regardless of the source IP they're bound
to. So in order to go beyond the 64k concurrent connections, we
have to manage the source ip:port lists ourselves.

The solution consists in assigning a source port range to each
server and use a free port in that range when connecting to that
server, either for a proxied connection or for a health check.
The port must then be put back into the server's range when the
connection is closed.

This mechanism is used only when a port range is specified on
a server. It makes it possible to reach 64k connections per
server, possibly all from the same IP address. Right now it
should be more than enough even for huge deployments.
2009-06-10 12:23:32 +02:00
Willy Tarreau
f68da4603a [BUG] ensure that we correctly re-start old process in case of error
When a new process fails to grab some ports, it sends a signal to
the old process in order to release them. Then it tries to bind
again. If it still fails (eg: one of the ports is bound to a
completely different process), it must send the continue signal
to the old process so that this one re-binds to the ports. This
is correctly done, but the newly bound ports are not released
first, which sometimes causes the old process to remain running
with no port bound. The fix simply consists in unbinding all
ports before sending the signal to the old process.
2009-06-09 14:36:00 +02:00
Willy Tarreau
6bde87b757 [MINOR] startup: don't imply -q with -D
It is recommended to have -D in init scripts, but -D also implies
quiet mode, which hides warning messages, and both options are now
completely unrelated. Remove the implication to get warnings with
-D.
2009-06-09 12:09:15 +02:00
Willy Tarreau
a94f2d2ef9 [MINOR] stats/html: use the arial font before helvetica
The stats HTML output were barely readable on some browsers such as
firefox on Linux, due to the selected helvetica font which is too
small. Specifying "arial" first fixes the issue without changing the
table size. Also, the default size of 0.8em choosen to get 10px out
of 12px is wrong because it gets 9px when rounded down.
2009-05-10 20:13:32 +02:00
Willy Tarreau
a3e4942ccb [MINOR] stats: report max sessions/s and limit in HTML stats 2009-05-10 19:20:15 +02:00
Willy Tarreau
8f208ecc7b [MINOR] stats: report max sessions/s and limit in CSV export 2009-05-10 19:01:49 +02:00
Willy Tarreau
13a34bd110 [MINOR] compute the max of sessions/s on fe/be/srv
Some users want to keep the max sessions/s seen on servers, frontends
and backends for capacity planning. It's easy to grab it while the
session count is updated, so let's keep it.
2009-05-10 18:52:49 +02:00
Willy Tarreau
f7edefa413 [MINOR] implement per-logger log level limitation
Some people are using haproxy in a shared environment where the
system logger by default sends alert and emerg messages to all
consoles, which happens when all servers go down on a backend for
instance. These people can not always change the system configuration
and would like to limit the outgoing messages level in order not to
disturb the local users.

The addition of an optional 4th field on the "log" line permits
exactly this. The minimal log level ensures that all outgoing logs
will have at least this level. So the logs are not filtered out,
just set to this level.
2009-05-10 17:20:05 +02:00
Benoit
affb481f1a [MEDIUM] add support for "balance hdr(name)"
There is a patch made by me that allow for balancing on any http header
field.

[WT:
  made minor changes:
  - turned 'balance header name' into 'balance hdr(name)' to match more
    closely the ACL syntax for easier future convergence
  - renamed the proxy structure fields header_* => hh_*
  - made it possible to use the domain name reduction to any header, not
    only "host" since it makes sense to do it with other ones.
  Otherwise patch looks good.
/WT]
2009-05-10 15:50:15 +02:00
Willy Tarreau
946ba59190 [MINOR] standard: provide a new 'my_strndup' function
This function is only offered by GNU extensions and is sometimes
useful during configuration parsing.
2009-05-10 15:41:18 +02:00
Willy Tarreau
8e80e0bc4c [BUG] fix parser crash on unconditional tcp content rules
Since 1.3.17, a config containing one of the following lines would
crash the parser :

    tcp content reject
    tcp content accept

This is because a check is performed on the condition which is not
specified. The obvious fix consists in checkinf for a condition
first.
2009-05-10 12:22:39 +02:00
Willy Tarreau
c9bd0cc224 [MINOR] add options dontlog-normal and log-separate-errors
Some big traffic sites have trouble dealing with logs and tend to
disable them. Here are two new options to help cope with massive
logs.

  - dontlog-normal only disables logging for 100% successful
    connections, other ones will still be logged

  - log-separate-errors will cause non-100% successful connections
    to be logged at level "err" instead of level "info" so that a
    properly configured syslog daemon can send them to a different
    file for longer conservation.
2009-05-10 11:57:02 +02:00
Willy Tarreau
1700b9c3d5 [MINOR] don't close stdio fds twice
This minor harmless bug dates back to v1.1. When fclose() was added,
the close() calls were not removed, so the fds 0,1,2 are closed twice.
2009-05-10 10:33:29 +02:00
Willy Tarreau
d79e79b436 [BUG] O(1) pollers should check their FD before closing it
epoll, sepoll and kqueue pollers should check that their fd is not
closed before attempting to close it, otherwise we can end up with
multiple closes of fd #0 upon exit, which is harmless but dirty.
2009-05-10 10:18:54 +02:00
Willy Tarreau
01b3a53f49 [MEDIUM] convert all signals to asynchronous signals
The small list of signals currently handled by haproxy were processed
as soon as they were received. This has caused trouble with calls to
pool_gc2() occuring in the middle of libc's memory management functions
seldom causing deadlocks preventing the old process from leaving.

Now these signals use the new async signal framework and are called
asynchronously, when there is no risk of recursion. This ensures more
reliable operation, especially for sensible processing such as memory
management.
2009-05-10 09:59:50 +02:00
Willy Tarreau
332740dab2 [MEDIUM] pollers: don't wait if a signal is pending
If an asynchronous signal is received outside of the poller, we don't
want the poller to wait for a timeout to occur before processing it,
so we set its timeout to zero, just like we do with pending tasks in
the run queue.
2009-05-10 09:57:21 +02:00
Willy Tarreau
2985794ca9 [MEDIUM] call signal_process_queue from run_poll_loop
Now we check for asynchronous pending signals. There's no user yet
so this cannot cause any trouble.
2009-05-10 09:24:56 +02:00
Willy Tarreau
8f38bd0497 [MINOR] add basic signal handling functions
These functions will be used to deliver asynchronous signals in order
to make the signal handling functions more robust. The goal is to keep
the same interface to signal handlers.
2009-05-10 09:24:23 +02:00
Maik Broemme
36db02e6b1 [BUG] x-original-to: fix missing initialization to default value 2009-05-08 17:02:07 +02:00
Maik Broemme
2850cb42b6 [MINOR] add X-Original-To: header
I have attached a patch which will add on every http request a new
header 'X-Original-To'. If you have HAProxy running in transparent mode
with a big number of SQUID servers behind it, it is very nice to have
the original destination ip as a common header to make decisions based
on it.

The whole thing is configurable with a new option 'originalto'. I have
updated the sourcecode as well as the documentation. The 'haproxy-en.txt'
and 'haproxy-fr.txt' files are untouched, due to lack of my french
language knowledge. ;)

Also the patch adds this header for IPv4 only. I haven't any IPv6 test
environment running here and don't know if getsockopt() with SO_ORIGINAL_DST
will work on IPv6. If someone knows it and wants to test it I can modify
the diff. Feel free to ask me questions or things which should be changed. :)

--Maik
2009-05-01 16:22:33 +02:00
Willy Tarreau
2df8d713b3 [BUG] fix wrong pointer arithmetics in HTTP message captures
The pointer arithmetics was wrong in http_capture_bad_message().
This has no impact right now because the error only msg->som was
affected and right now it's always 0. But this was a bug waiting
for keepalive support to strike.
2009-05-01 11:33:17 +02:00
Willy Tarreau
79e9989196 [CRITICAL] uninitialized response field can sometimes cause crashes
The response message in the transaction structure was not properly
initialised at session initialisation. In theory it cannot cause any
trouble since the affected field os expected to always remain NULL.
However, in some circumstances, such as building on 64-bit platforms
with certain options, the struct session can be exactly 1024 bytes,
the same size of the requri field, so the pools are merged and the
uninitialised field may contain non-null data, causing crashes if
an invalid response is encountered and archived.

The fix simply consists in correctly initialising the missing fields.
This bug cannot affect architectures where the session pool is not
shared (32-bit architectures), but this is only by pure luck.
2009-04-27 08:11:33 +02:00
Willy Tarreau
b7f9d126e2 [MEDIUM] ensure we don't recursively call pool_gc2()
A race condition exists in the hot reconfiguration code. It is
theorically possible that the second signal is sent during a free()
in the first list, which can cause crashes or freezes (the later
have been observed). Just set up a counter to ensure we do not
recurse.
2009-04-21 02:17:45 +02:00
Willy Tarreau
3b88d441e9 [MINOR] switch all stat counters to 64-bit
The byte counters have long been 64-bit to avoid overflows. But with
several sites nowadays, we see session counters wrap around every 10-days
or so. So it was the moment to switch counters to 64-bit, including
error and warning counters which can theorically rise as fast as session
counters even if in practice there is very low risk.

The performance impact should not be noticeable since those counters are
only updated once per session. The stats output have been carefully checked
for proper types on both 32- and 64-bit platforms.
2009-04-11 20:44:08 +02:00
Willy Tarreau
5e4a6f13f4 [MINOR] fix a few remaining printf-like formats on 64-bit platforms
Mainly two sizeof() returning size_t which is not the size of an int
on 64-bit platforms.
2009-04-11 19:42:49 +02:00
Willy Tarreau
0bba5a8f6c [BUG] stats: total and lbtot are unsigned
Some big users are seeing negative numbers in the CSV stats. This patch
needs to be backported to 1.3.15 and extended to the HTML part.
2009-04-07 13:27:40 +02:00
Jeffrey 'jf' Lim
af403fc59d [CLEANUP] give a little bit more information in error message
Indicate the error is about redirection.
2009-04-03 15:01:48 +02:00
Willy Tarreau
1772ece025 [MINOR] fix several printf formats and missing arguments
Last patch revealed a number of mistakes in printf-like calls, mostly int/long
mismatches, and a few missing arguments.
2009-04-03 14:49:12 +02:00
Willy Tarreau
4076a15255 [MEDIUM] http: capture invalid requests/responses even if accepted
It's useful to be able to accept an invalid header name in a request
or response but still be able to monitor further such errors. Now,
when an invalid request/response is received and accepted due to
an "accept-invalid-http-{request|response}" option, the invalid
request will be captured for later analysis with "show errors" on
the stats socket.
2009-04-02 21:36:37 +02:00
Willy Tarreau
32a4ec0ed7 [MEDIUM] http: add options to ignore invalid header names
Sometimes it is required to let invalid requests pass because
applications sometimes take time to be fixed and other servers
do not care. Thus we provide two new options :

     option accept-invalid-http-request  (for the frontend)
     option accept-invalid-http-response (for the backend)

When those options are set, invalid requests or responses do
not cause a 403/502 error to be generated.
2009-04-02 21:36:34 +02:00
Willy Tarreau
61d188920e [MINOR] improve reporting of misplaced acl/reqxxx rules
Now we can detect improper ordering of "block", "reqxxx", "reqadd",
"redirect" and "use_backend", and warn the user accordingly.
2009-03-31 10:49:21 +02:00
Willy Tarreau
0a6d2efc45 [MINOR] stats/html: group digits by 3 to clarify numbers
Large stats numbers are more readable if there is a small space
between groups of 3 digits.
2009-03-29 14:46:01 +02:00
Willy Tarreau
e7239b5152 [MINOR] implement ulltoh() to write HTML-formatted numbers
This function sets CSS letter spacing after each 3rd digit. The page must
create a class "rls" (right letter spacing) with style "letter-spacing: 0.3em"
in order to use it.
2009-03-29 13:41:58 +02:00
Willy Tarreau
2ab85e6fee [BUG] don't set an expiration date directly from now_ms
now_ms can be zero, don't set ->analyse_exp directly from it, we
must use tick_add() instead.
2009-03-29 10:24:15 +02:00
Willy Tarreau
d06e71179a [BUG] stream_sock: check for shut{r,w} before refreshing some timeouts
Under some circumstances, it appears possible to refresh a timeout
just after a side has been shut. For instance, if poll() plans to
call both read and write, and the read side calls chk_snd() which
in turn causes a shutw to occur, then stream_sock_write could update
its write timeout. The same problem happens the other way.

The timeout checks will then not catch these cases because they
ignore timeouts in case of shut{r,w}.

This is very likely to be the major cause of the 100% CPU usages
reported by Bart Bobrowski.

The fix consists in always ensuring that a side is not shut before
updating its timeout.
2009-03-29 10:18:41 +02:00
Willy Tarreau
c6dcad6e74 [MINOR] show sess: report a lot more information about sessions
For complex troubleshooting, it's sometimes useful to be able to
completely dump all the states and flags related to a session.
Now "show sess" will report the stream interfaces and buffers
status for each session.
2009-03-29 10:09:16 +02:00
Willy Tarreau
6574519c23 [MINOR] sepoll: don't count two events on the same FD.
sepoll counts the number of speculative events it has processed in
order to remain fair with epoll_wait(). If a same FD is processed
both for read and for write, it is counted twice. Fix this.
2009-03-28 23:42:55 +01:00
Willy Tarreau
1714e0ffda [BUG] stream_sock: disable I/O on fds reporting an error
Upon read or write error, we cannot immediately close the FD because
we want to first report the error to the upper layer which will do it
itself. However, we want to prevent any further I/O from being performed
on the FD. This is especially important in case of speculative I/O where
nothing else could stop the FD from still being polled until the upper
layer takes care of the condition.
2009-03-28 23:42:30 +01:00
Willy Tarreau
1eead503da [BUG] don't call epoll_ctl() on closed sockets
Some I/O callbacks are able to close their socket themselves. We
want to check this before calling epoll_ctl(EPOLL_CTL_DEL), otherwise
we get a -1 EBADF. Right now is looks like this could not cause any
trouble but the case is racy enough to fix it.
2009-03-28 19:43:06 +01:00
Willy Tarreau
3884cbaae6 [MINOR] show sess: report number of calls to each task
For debugging purposes, it can be useful to know how many times each
task has been called.
2009-03-28 17:54:35 +01:00
Willy Tarreau
2d045597f7 [BUG] reject unix accepts when connection limit is reached
unix sockets are not attached to a real frontend, so there is
no way to disable/enable the listener depending on the global
session count. For this reason, if the global maxconn is reached
and a unix socket comes in, it will just be ignored and remain
in the poll list, which will call again indefinitely.

So we need to accept then drop incoming unix connections when
the table is full.

This should not happen with clean configurations since the global
maxconn should provide enough room for unix sockets.
2009-03-28 11:02:18 +01:00
Willy Tarreau
127334e89b [BUG] reset the stream_interface connect timeout upon connect or error
The stream_interface timeout was not reset upon a connect success or
error, leading to busy loops when requeuing tasks in the past.

Thanks to Bart Bobrowski for reporting the issue.
2009-03-28 11:01:20 +01:00
Willy Tarreau
573fd806ed [OPTIM] sepoll: do not re-check whole list upon accepts
There is already an optimisation in the speculative poller which
causes newly created FDs to be checked immediately after being
created. Unfortunately, this optimisation causes the whole spec
list to be re-checked while we're only interested in the new FDs.

Doing this minor change causes performance gains of up to 6% on
medium-sized objects with a few hundreds concurrent connections.
2009-03-22 19:25:46 +01:00
Willy Tarreau
b00f9c456c [BUG] check for global.maxconn before doing accept()
If the accept() is done before checking for global.maxconn, we can
accept too many connections and encounter a lack of file descriptors
when trying to connect to the server. This is the cause of the
"cannot get a server socket" message  encountered in debug mode
during injections with low timeouts.
2009-03-21 22:43:12 +01:00
Willy Tarreau
06bea94266 [MEDIUM] session: don't resync FSMs on non-interesting changes
While processing the session, we used to resync the FSMs when buffer
flags changed. But since BF_KERN_SPLICING and BF_READ_DONTWAIT were
introduced, sometimes we could resync after they were set, which is
not what we want. This was because there were some old checks left
which did not mask changes with BF_MASK_STATIC before checking.
2009-03-21 22:09:29 +01:00
Willy Tarreau
1b194fe03e [OPTIM] buffer: new BF_READ_DONTWAIT flag reduces EAGAIN rates
When the reader does not expect to read lots of data, it can
set BF_READ_DONTWAIT on the request buffer. When it is set,
the stream_sock_read callback will not try to perform multiple
reads, it will return after only one, and clear the flag.
That way, we can immediately return when waiting for an HTTP
request without trying to read again.

On pure request/responses schemes such as monitor-uri or
redirects, this has completely eliminated the EAGAIN occurrences
and the epoll_ctl() calls, resulting in a performance increase of
about 10%. Similar effects should be observed once we support
HTTP keep-alive since we'll immediately disable reads once we
get a full request.
2009-03-21 21:57:30 +01:00
Willy Tarreau
6f4a82c7af [OPTIM] stream_sock: don't retry to read after a large read
If we get very large data at once, it's almost certain that it's
worthless trying to read again, because we got everything we could
get.

Doing this has made all -EAGAIN disappear from splice reads. The
threshold has been put in the global tunable structures so that if
we one day want to make it accessible from user config, it will be
easy to do so.
2009-03-21 20:43:57 +01:00
Willy Tarreau
e38388033f [BUG] server check intervals must not be null
If server check interval is null, we might end up looping in
process_srv_chk().

Prevent those values from being zero and add some control in
process_srv_chk() against infinite loops.
2009-03-21 18:58:32 +01:00
Willy Tarreau
c7bdf09f9f [MINOR] stats: report number of tasks (active and running)
It may be useful for statistics purposes to report the number of
tasks.
2009-03-21 18:33:52 +01:00
Willy Tarreau
a461318f97 [MINOR] task: keep a task count and clean up task creators
It's sometimes useful at least for statistics to keep a task count.
It's easy to do by forcing the rare task creators to always use the
same functions to create/destroy a task.
2009-03-21 18:13:21 +01:00
Willy Tarreau
135a113e36 [MINOR] sched: permit a task to stay up between calls
If a task wants to stay in the run queue, it is possible. It just
needs to wake itself up. We just want to ensure that a reniced
task will be processed at the right instant.
2009-03-21 13:26:05 +01:00
Willy Tarreau
26ca34e66e [BUG] scheduler: fix improper handling of duplicates __task_queue()
The top of a duplicate tree is not where bit == -1 but at the most
negative bit. This was causing tasks to be queued in reverse order
within duplicates. While this is not dramatic, it's incorrect and
might lead to longer than expected duplicate depths under some
circumstances.
2009-03-21 12:57:06 +01:00
Willy Tarreau
218859ad6c [BUG] sched: don't leave 3 lasts tasks unprocessed when niced tasks are present
When there are niced tasks, we would only process #tasks/4 per
turn, without taking care of running #tasks when #tasks was below
4, leaving those tasks waiting for a few other tasks to push them.

The fix simply consists in checking (#tasks+3)/4.
2009-03-21 11:53:09 +01:00
Willy Tarreau
e35c94a748 [MEDIUM] scheduler: get rid of the 4 trees thanks and use ebtree v4.1
Since we're now able to search from a precise expiration date in
the timer tree using ebtree 4.1, we don't need to maintain 4 trees
anymore. Not only does this simplify the code a lot, but it also
ensures that we can always look 24 days back and ahead, which
doubles the ability of the previous scheduler. Indeed, while based
on absolute values, the timer tree is now relative to <now> as we
can always search from <now>-31 bits.

The run queue uses the exact same principle now, and is now simpler
and a bit faster to process. With these changes alone, an overall
0.5% performance gain was observed.

Tests were performed on the few wrapping cases and everything works
as expected.
2009-03-21 10:25:14 +01:00
Willy Tarreau
5804434a0f [MINOR] update ebtree to version 4.1
Ebtree version 4.1 brings lookup by ranges. This will be useful for
the scheduler.
2009-03-21 10:23:36 +01:00
Willy Tarreau
8365f9335d [CLEANUP] http: remove some commented out obsolete code in process_response 2009-03-15 23:11:49 +01:00
Willy Tarreau
86ef7dc98d [MINOR] tcp_request: let the caller take care of errors and timeouts
tcp_request is not meant to decide how an error or a timeout has to
be handled. It must just apply it rules. Now that the error checks
have been added to the session, we don't need to check them anymore
in tcp_request_inspect(), which will only consider the shutdown which
may be the result of such an error.

That makes a lot more sense since tcp_request is not really waiting
for a request.
2009-03-15 22:55:47 +01:00
Willy Tarreau
844553303d [BUG] session: errors were not reported in termination flags in TCP mode
In order to get termination flags properly updated, the session was
relying a bit too much on http_return_srv_error() which is http-centric.

A generic srv_error function was implemented in the session in order to
catch all connection abort situations. It was then noticed that a request
abort during a connection attempt was not reported, which is now fixed.

Read and write errors/timeouts were not logged either. It was necessary
to add those tests at 4 new locations.

Now it looks like everything is correctly logged. Most likely some error
checking code could now be removed from some analysers.
2009-03-15 22:34:05 +01:00
Willy Tarreau
a3780f2db8 [BUG] connect timeout is in the stream interface, not the buffer
The connect timeout was not properly detected due to the fact that
it was not correctly initialized. It must be set as the stream interface
timeout, not the buffer's write timeout.
2009-03-15 21:49:00 +01:00
Willy Tarreau
5af24efee9 [CLEANUP] config: catch and report some possibly wrong rule ordering
There are some configurations in which redirect rules are declared
after use_backend rules. We can also find "block" rules after any
of these ones. The processing sequence is :
  - block
  - redirect
  - use_backend

So as of now we try to detect wrong ordering to warn the user about
a possibly undesired behaviour.
2009-03-15 15:23:16 +01:00
Willy Tarreau
55bc0f8eb7 [MEDIUM] reverse internal proxy declaration order to match configuration
People are regularly complaining that proxies are linked in reverse
order when reading the stats. This is now definitely fixed because
the proxy order is now fixed to match configuration order.
2009-03-15 14:51:53 +01:00
Willy Tarreau
d869b24119 [MINOR] tcp-inspect: permit the use of no-delay inspection
Sometimes it may make sense to be able to immediately apply a verdict
without waiting at all. It was not possible because no inspect-delay
meant no inspection at all. This is now fixed.
2009-03-15 14:43:58 +01:00
Willy Tarreau
3cd9af228f [MINOR] cfgparse: set backends to "balance roundrobin" by default
When a backend has no LB algo specified and is not in dispatch, proxy
nor transparent mode, use "balance roundrobin" by default instead of
complaining. This will be particularly useful with stats and redirects.
2009-03-15 14:11:27 +01:00
Willy Tarreau
ff01a21ebe [MINOR] cfgparse: some cleanups in the consistency checks
Check for servers in health mode, for health mode in pure-backends.
Some code have been refactored for better organization.
2009-03-15 13:46:16 +01:00
Willy Tarreau
787bbd9b7a [MINOR] show errors: encode backslash as well as non-ascii characters
These ones were not properly encoded, causing confusion on the output.
2009-03-12 08:18:33 +01:00
Willy Tarreau
c9619468ea [BUG] stream_sock: write timeout must be updated when forwarding !
When data are forwarded between socket, we must update the output
socket's write timeout. This was forgotten, causing sessions to
unexpectedly expire during long posts.
2009-03-09 22:40:57 +01:00
Willy Tarreau
6bf1736fb1 [BUILD] proto_http did not build on gcc-2.95 (again)
move the DPRINTF below the local variable declarations.
(cherry picked from commit 7b92db4cd5)

The patch accidently got reverted.
2009-03-08 23:10:34 +01:00
Willy Tarreau
87bed62a92 [BUILD] build fixes for Solaris
One build error in stream_sock.c when MSG_NOSIGNAL is not defined,
and a warning in task.c.
2009-03-08 22:25:28 +01:00
Willy Tarreau
7c84bab879 [MEDIUM] rearrange forwarding condition to enable splice during analysis
The forwarding condition was not very clear. We would only enable
forwarding when send_max is zero, and we would only splice when no
analyser is installed. In fact we want to enable forward when there
is no analyser and we want to splice at soon as there is data to
forward, regardless of the analysers.
2009-03-08 21:38:23 +01:00
Willy Tarreau
6f0aa476bd [CLEANUP] buffer_flush() was misleading, rename it as buffer_erase 2009-03-08 20:33:29 +01:00
Willy Tarreau
ed066fae25 [CLEANUP] don't enable kernel splicing when socket is closed
Splicing will not be used when the source socket is closed. Don't
enable it uselessly.
2009-03-08 19:44:29 +01:00
Willy Tarreau
0be0ef9604 [OPTIM] do not re-check req buffer when only response has changed
In process_session(), we used to re-run through all the evaluation
loop when only the response had changed. Now we carefully check in
this order :
  - changes to the stream interfaces (only SI_ST_DIS)
  - changes to the request buffer flags
  - changes to the response buffer flags

And we branch to the appropriate section. This saves significant
CPU cycles, which is important since process_session() is one of
the major CPU eaters.

The same changes have been applied to uxst_process_session().
2009-03-08 19:20:25 +01:00
Willy Tarreau
531cf0cf8d [OPTIM] task: reduce the number of calls to task_queue()
Most of the time, task_queue() will immediately return. By extracting
the preliminary checks and putting them in an inline function, we can
significantly reduce the number of calls to the function itself, and
most of the tests can be optimized away due to the caller's context.

Another minor improvement in process_runnable_tasks() consisted in
taking benefit from the processor's branch prediction unit by making
a special case of the process_session() callback which is by far the
most common one.

All this improved performance by about 1%, mainly during the call
from process_runnable_tasks().
2009-03-08 16:35:27 +01:00
Willy Tarreau
d0a201b35c [CLEANUP] task: distinguish between clock ticks and timers
Timers are unsigned and used as tree positions. Ticks are signed and
used as absolute date within current time frame. While the two are
normally equal (except zero), it's important not to confuse them in
the code as they are not interchangeable.

We add two inline functions to turn each one into the other.

The comments have also been moved to the proper location, as it was
not easy to understand what was a tick and what was a timer unit.
2009-03-08 15:58:07 +01:00
Willy Tarreau
721fdbc381 [BUG] event_accept() must always wake the task up, even in health mode
event_accept() did not wake the task up in health mode, so that mode was
not working anymore.
2009-03-08 12:25:07 +01:00
Willy Tarreau
26c250683f [MEDIUM] minor update to the task api: let the scheduler queue itself
All the tasks callbacks had to requeue the task themselves, and update
a global timeout. This was not convenient at all. Now the API has been
simplified. The tasks callbacks only have to update their expire timer,
and return either a pointer to the task or NULL if the task has been
deleted. The scheduler will take care of requeuing the task at the
proper place in the wait queue.
2009-03-08 09:38:41 +01:00
Willy Tarreau
4136522527 [OPTIM] displace tasks in the wait queue only if absolutely needed
We don't need to remove then add tasks in the wait queue every time we
update a timeout. We only need to do that when the new timeout is earlier
than previous one. We can rely on wake_expired_tasks() to perform the
proper checks and bounce the misplaced tasks in the rare case where this
happens. The motivation behind this is that we very rarely hit timeouts,
so we save a lot of CPU cycles by moving the tasks very rarely. This now
means we can also find tasks with expiration date set to eternity in the
queue, and that is not a problem.
2009-03-08 07:59:27 +01:00