]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
16 years ago[MINOR] add an expiration flag to the stream_sock_interface
Willy Tarreau [Thu, 4 Sep 2008 09:51:16 +0000 (11:51 +0200)] 
[MINOR] add an expiration flag to the stream_sock_interface

This expiration flag is used to indicate that the timer has
expired without having to check it everywhere.

16 years ago[MEDIUM] use buffer_check_timeouts instead of stream_sock_check_timeouts()
Willy Tarreau [Thu, 4 Sep 2008 09:19:41 +0000 (11:19 +0200)] 
[MEDIUM] use buffer_check_timeouts instead of stream_sock_check_timeouts()

It's more appropriate to use buffer_check_timeouts() to check for buffer
timeouts and si->shutw/shutr to shutdown the stream interfaces.

16 years ago[MINOR] add buffer_check_timeouts() to check what timeouts have fired.
Willy Tarreau [Thu, 4 Sep 2008 07:14:08 +0000 (09:14 +0200)] 
[MINOR] add buffer_check_timeouts() to check what timeouts have fired.

This new function sets the BF_*_TIMEOUT flags when a buffer timeout
has expired.

16 years ago[OPTIM] add compiler hints in tick_is_expired()
Willy Tarreau [Thu, 4 Sep 2008 07:00:24 +0000 (09:00 +0200)] 
[OPTIM] add compiler hints in tick_is_expired()

adding those two unlikely() reduces the number of branches taken in
the common path and the size of the code.

16 years ago[MEDIUM] move QUEUE and TAR timers to stream interfaces
Willy Tarreau [Wed, 3 Sep 2008 16:11:02 +0000 (18:11 +0200)] 
[MEDIUM] move QUEUE and TAR timers to stream interfaces

It was not practical to have QUEUE and TAR timers in buffers, as they caused
triggering of the timeout flags. Move them to the stream interface where they
belong.

16 years ago[CLEANUP] process_session: move debug outputs out of the critical loop
Willy Tarreau [Wed, 3 Sep 2008 09:37:47 +0000 (11:37 +0200)] 
[CLEANUP] process_session: move debug outputs out of the critical loop

The if(debug&closed) printfs have moved outside of the loop. It also
permitted to merge several of them.

16 years ago[MEDIUM] process_session: make use of the new buffer flags
Willy Tarreau [Sat, 30 Aug 2008 11:36:43 +0000 (13:36 +0200)] 
[MEDIUM] process_session: make use of the new buffer flags

Now we have almost two distinct parts between tcp and http.
Only the connection establishment code still requires some
resynchronization, the rest does not.

16 years ago[MEDIUM] buffers: add BF_READ_ATTACHED and BF_ANA_TIMEOUT
Willy Tarreau [Sat, 30 Aug 2008 10:31:07 +0000 (12:31 +0200)] 
[MEDIUM] buffers: add BF_READ_ATTACHED and BF_ANA_TIMEOUT

Those two flags will be used to wake up analysers only when
needed.

16 years ago[MEDIUM] stream interface: add the ->shutw method as well as in and out buffers
Willy Tarreau [Sat, 30 Aug 2008 02:58:38 +0000 (04:58 +0200)] 
[MEDIUM] stream interface: add the ->shutw method as well as in and out buffers

Those entries were really needed for cleaner and better code. Using them
has permitted to automatically close a file descriptor during a shut write,
reducing by 20% the number of calls to process_session() and derived
functions.

Process_session() does not need to know the file descriptor anymore, though
it still remains very complicated due to the special case for the connect
mode.

16 years ago[MAJOR] make stream sockets aware of the stream interface
Willy Tarreau [Sat, 30 Aug 2008 01:17:31 +0000 (03:17 +0200)] 
[MAJOR] make stream sockets aware of the stream interface

As of now, a stream socket does not directly wake up the task
but it does contact the stream interface which itself knows the
task. This allows us to perform a few cleanups upon errors and
shutdowns, which reduces the number of calls to data_update()
from 8 per session to 2 per session, and make all the functions
called in the process_session() loop completely swappable.

Some improvements are required. We need to provide a shutw()
function on stream interfaces so that one side which closes
its read part on an empty buffer can propagate the close to
the remote side.

16 years ago[MINOR] change type of fdtab[]->owner to void*
Willy Tarreau [Fri, 29 Aug 2008 21:36:51 +0000 (23:36 +0200)] 
[MINOR] change type of fdtab[]->owner to void*

The owner of an fd was initially a task but this was sometimes
casted to a (struct listener *). We'll soon need more types,
so void* is more appropriate.

16 years ago[MEDIUM] indicate a reason for a task wakeup
Willy Tarreau [Fri, 29 Aug 2008 16:19:04 +0000 (18:19 +0200)] 
[MEDIUM] indicate a reason for a task wakeup

It's very frequent to require some information about the
reason why a task is running. Some flags have been added
so that a task now knows if it got woken up due to I/O
completion, timeout, etc...

16 years ago[OPTIM] force inlining of large functions with gcc >= 3
Willy Tarreau [Fri, 29 Aug 2008 13:48:49 +0000 (15:48 +0200)] 
[OPTIM] force inlining of large functions with gcc >= 3

GCC 3 and above do not inline large functions, which is a problem
with ebtree where most core functions are inlined.

This simple patch has both reduced code size and increased speed.
It should be back-ported to ebtree.

16 years ago[OPTIM] reduce the number of calls to task_wakeup()
Willy Tarreau [Fri, 29 Aug 2008 13:26:14 +0000 (15:26 +0200)] 
[OPTIM] reduce the number of calls to task_wakeup()

A test has shown that more than 16% of the calls to task_wakeup()
could be avoided because the task is already woken up. So make it
inline and move the test to the inline part.

16 years ago[OPTIM] ev_sepoll: detect newly created FDs and check them once
Willy Tarreau [Fri, 29 Aug 2008 11:57:30 +0000 (13:57 +0200)] 
[OPTIM] ev_sepoll: detect newly created FDs and check them once

When an accept() creates a new FD, it is already marked as set for
reads. But the task will be woken up without first checking if the
socket could be read.

The speculative I/O gives us a chance to either read the FD if there
are data pending on it, or immediately mark it for poll mode if
nothing is pending.

Simply doing this reduces the number of calls to process_session
from 6 to 5 per session, 2 to 1 calls to process_request, 10% less
calls to epoll_ctl, fd_clr, fd_set, stream_sock_data_update, 20%
less eb32_insert/eb_delete, etc... General performance increase
seems to be around 3%.

16 years ago[MINOR] do not check for BF_SHUTR when computing write timeout
Willy Tarreau [Fri, 29 Aug 2008 09:30:14 +0000 (11:30 +0200)] 
[MINOR] do not check for BF_SHUTR when computing write timeout

This check was useless as !BF_SHUTR is already implied by tick_isset(rex).

16 years ago[MINOR] re-arrange buffer flags and rename some of them
Willy Tarreau [Fri, 29 Aug 2008 07:58:42 +0000 (09:58 +0200)] 
[MINOR] re-arrange buffer flags and rename some of them

The buffer flags became a big bazaar. Re-arrange them
so that their names are more explicit and so that they
are more easily readable in hex form. Some aggregates
have also been adjusted.

16 years ago[MEDIUM] reintroduce BF_HIJACK with produce_content
Willy Tarreau [Thu, 28 Aug 2008 14:01:32 +0000 (16:01 +0200)] 
[MEDIUM] reintroduce BF_HIJACK with produce_content

The stats dump are back. Even very large config files with
5000 servers work fast and well. The SN_SELF_GEN flag has
completely been removed.

16 years ago[MINOR] only call flow analysers when their read side is connected.
Willy Tarreau [Thu, 28 Aug 2008 09:07:58 +0000 (11:07 +0200)] 
[MINOR] only call flow analysers when their read side is connected.

It's useless to call flow analysers when their read side has not
seen a connection yet.

16 years ago[OPTIM] stream_sock_read must check for null-reads more often
Willy Tarreau [Thu, 28 Aug 2008 07:47:43 +0000 (09:47 +0200)] 
[OPTIM] stream_sock_read must check for null-reads more often

With small HTTP messages, stream_sock_read() tends to wake the
task up for a message read without indicating that it may be
the last one. The reason is that level-triggered pollers generally
don't report HUP with data, but only afterwards, so stream_sock_read
has no chance to detect this condition and needs a respin.

So now we return on incomplete buffers only when the buffer is known
as a streamer, because here it generally makes sense. The net result
is that the number of calls in a single HTTP session has dropped
from 5 to 3, with one less wake up and several less calls to
stream_sock_data_update().

16 years ago[MEDIUM] split stream_sock_process_data
Willy Tarreau [Thu, 28 Aug 2008 06:54:27 +0000 (08:54 +0200)] 
[MEDIUM] split stream_sock_process_data

It was a waste to constantly update the file descriptor's status
and timeouts during a flags update. So stream_sock_process_data
has been slit in two parts :
  stream_sock_data_update()  => computes updated flags
  stream_sock_data_finish()  => computes timeouts

Only the first one is called during flag updates. The second one
is only called upon completion. The number of calls to fd_set/fd_clr
has now significantly dropped.

Also, it's useless to check for errors and timeouts in the
process_session() loop, it's enough to check for them at the
beginning.

16 years ago[MAJOR] make the client side use stream_sock_process_data()
Willy Tarreau [Wed, 27 Aug 2008 21:57:16 +0000 (23:57 +0200)] 
[MAJOR] make the client side use stream_sock_process_data()

The client side now relies on stream_sock_process_data(). One
part has not yet been re-implemented, it concerns the calls
to produce_content().

process_session() has been adjusted to correctly check for
changing bits in order not to call useless functions too many
times.

It already appears that stream_sock_process_data() should be
split so that the timeout computations are only performed at
the exit of process_session().

16 years ago[MEDIUM] stream_sock_process_data moved to stream_sock.c
Willy Tarreau [Wed, 27 Aug 2008 19:41:35 +0000 (21:41 +0200)] 
[MEDIUM] stream_sock_process_data moved to stream_sock.c

The old temporary process_srv_data function moved to stream_sock.c.

16 years ago[MEDIUM] process_srv_data: ensure that we always correctly re-arm timeouts
Willy Tarreau [Wed, 27 Aug 2008 19:10:25 +0000 (21:10 +0200)] 
[MEDIUM] process_srv_data: ensure that we always correctly re-arm timeouts

We really want to ensure that we don't miss a timeout update and do not
update them for nothing. So the code takes care of updating the timeout
in the two following circumstances :
  - it was not set
  - some I/O has been performed

Maybe we'll be able to remove that from stream_sock_{read|write}, or
we'll find a way to ensure that we never have to re-enable this.

16 years ago[MEDIUM] third cleanup and optimization of process_srv_data()
Willy Tarreau [Wed, 27 Aug 2008 18:35:41 +0000 (20:35 +0200)] 
[MEDIUM] third cleanup and optimization of process_srv_data()

Some repeated tests were factored out.
Now the code makes sense and is fully understandable.

16 years ago[MEDIUM] second level of code cleanup for process_srv_data
Willy Tarreau [Wed, 27 Aug 2008 18:09:19 +0000 (20:09 +0200)] 
[MEDIUM] second level of code cleanup for process_srv_data

Now the function is 100% server-independant. Next step will
consist in using the same function for the client side too.

16 years ago[MEDIUM] massive cleanup of process_srv()
Willy Tarreau [Wed, 27 Aug 2008 16:52:22 +0000 (18:52 +0200)] 
[MEDIUM] massive cleanup of process_srv()

Server-specific calls were extracted and moved to the caller.
The function is now nearly server-agnostic.

16 years ago[OPTIM] remove useless fd_set(read) upon shutdown(write)
Willy Tarreau [Wed, 27 Aug 2008 13:19:25 +0000 (15:19 +0200)] 
[OPTIM] remove useless fd_set(read) upon shutdown(write)

Those old tricks are no longer needed and are overwritten
anyway. Remove them.

16 years ago[MAJOR] rework of the server FSM
Willy Tarreau [Sun, 19 Oct 2008 05:30:41 +0000 (07:30 +0200)] 
[MAJOR] rework of the server FSM

srv_state has been removed from HTTP state machines, and states
have been split in either TCP states or analyzers. For instance,
the TARPIT state has just become a simple analyzer.

New flags have been added to the struct buffer to compensate this.
The high-level stream processors sometimes need to force a disconnection
without touching a file-descriptor (eg: report an error). But if
they touched BF_SHUTW or BF_SHUTR, the file descriptor would not
be closed. Thus, the two SHUT?_NOW flags have been added so that
an application can request a forced close which the stream interface
will be forced to obey.

During this change, a new BF_HIJACK flag was added. It will
be used for data generation, eg during a stats dump. It
prevents the producer on a buffer from sending data into it.

  BF_SHUTR_NOW  /* the producer must shut down for reads ASAP  */
  BF_SHUTW_NOW  /* the consumer must shut down for writes ASAP */
  BF_HIJACK     /* the producer is temporarily replaced        */

BF_SHUTW_NOW has precedence over BF_HIJACK. BF_HIJACK has
precedence over BF_MAY_FORWARD (so that it does not need it).

New functions buffer_shutr_now(), buffer_shutw_now(), buffer_abort()
are provided to manipulate BF_SHUT* flags.

A new type "stream_interface" has been added to describe both
sides of a buffer. A stream interface has states and error
reporting. The session now has two stream interfaces (one per
side). Each buffer has stream_interface pointers to both
consumer and producer sides.

The server-side file descriptor has moved to its stream interface,
so that even the buffer has access to it.

process_srv() has been split into three parts :
  - tcp_get_connection() obtains a connection to the server
  - tcp_connection_failed() tests if a previously attempted
    connection has succeeded or not.
  - process_srv_data() only manages the data phase, and in
    this sense should be roughly equivalent to process_cli.

Little code has been removed, and a lot of old code has been
left in comments for now.

16 years ago[MEDIUM] make it possible for analysers to follow the whole session
Willy Tarreau [Thu, 21 Aug 2008 08:05:00 +0000 (10:05 +0200)] 
[MEDIUM] make it possible for analysers to follow the whole session

Some analysers will need to remain present after connection is
established. Change the way BF_MAY_FORWARD is set to allow this.

16 years ago[BUG] fix harmless but wrong fd insertion sequence
Willy Tarreau [Tue, 26 Aug 2008 11:25:39 +0000 (13:25 +0200)] 
[BUG] fix harmless but wrong fd insertion sequence

In backend.c, we had an EV_FD_SET() called before fd_insert().
This is wrong because fd_insert updates maxfd which might be
used by some of the pollers during EV_FD_SET(), although this
is not currently the case.

16 years ago[BUG] Fix empty X-Forwarded-For header name when set in defaults section
Willy Tarreau [Sat, 23 Aug 2008 06:18:21 +0000 (08:18 +0200)] 
[BUG] Fix empty X-Forwarded-For header name when set in defaults section

The following patch introduced a minor bug :
   [MINOR] permit renaming of x-forwarded-for header

If "option forwardfor" is declared in a defaults section, the header name
is never set and we see an empty header name before the value. Also, the
header name was not reset between two defaults sections.

16 years ago[TESTS] test-fsm: 22 regression tests for state machines
Willy Tarreau [Sun, 17 Aug 2008 17:30:03 +0000 (19:30 +0200)] 
[TESTS] test-fsm: 22 regression tests for state machines

22 regression tests for state machines are managed by the new
file tests/test-fsm.cfg. Check it, they are all documented
inside. Most of the bugs introduced during the FSM extraction
have been found with these tests.

16 years ago[BUG] process_request: HTTP body analysis must return zero if missing data
Willy Tarreau [Sun, 17 Aug 2008 17:17:57 +0000 (19:17 +0200)] 
[BUG] process_request: HTTP body analysis must return zero if missing data

This missing return and timeout check caused an infinite loop too.

16 years ago[BUG] process_cli/process_srv: don't call shutdown when already done
Willy Tarreau [Sun, 17 Aug 2008 16:16:38 +0000 (18:16 +0200)] 
[BUG] process_cli/process_srv: don't call shutdown when already done

A few missing checks of BF_SHUTR and BF_SHUTW caused busy loops upon
some error paths.

16 years ago[MEDIUM] merge inspect_exp and txn->exp into request buffer
Willy Tarreau [Sun, 17 Aug 2008 16:03:28 +0000 (18:03 +0200)] 
[MEDIUM] merge inspect_exp and txn->exp into request buffer

Since we may have several analysers on a buffer, it's more
convenient to have the analyser timeout attached to the
buffer itself.

16 years ago[BUILD] fix warning in proto_tcp.c with gcc >= 4
Willy Tarreau [Sun, 17 Aug 2008 15:13:47 +0000 (17:13 +0200)] 
[BUILD] fix warning in proto_tcp.c with gcc >= 4

signedness issues.

16 years ago[BUG] regparm is broken on gcc < 3
Willy Tarreau [Sun, 17 Aug 2008 15:06:37 +0000 (17:06 +0200)] 
[BUG] regparm is broken on gcc < 3

Gcc < 3 does not consider regparm declarations for function pointers.
This causes big trouble at least with pollers (and with any function
pointer after all). Disable CONFIG_HAP_USE_REGPARM for gcc < 3.

16 years ago[OPTIM] process_cli/process_srv: reduce the number of tests
Willy Tarreau [Sun, 17 Aug 2008 14:23:10 +0000 (16:23 +0200)] 
[OPTIM] process_cli/process_srv:  reduce the number of tests

We can skip a number of tests by simply checking a few flags,
it saves a few CPU cycles in the fast path.

16 years ago[MEDIUM] session: move the analysis bit field to the buffer
Willy Tarreau [Sun, 17 Aug 2008 13:20:19 +0000 (15:20 +0200)] 
[MEDIUM] session: move the analysis bit field to the buffer

It makes more sense to store the list of analysers in the buffer
than in the session since they are precisely plugged onto one
buffer.

16 years ago[MINOR] ensure the termination flags are set by process_xxx
Willy Tarreau [Sun, 17 Aug 2008 12:38:41 +0000 (14:38 +0200)] 
[MINOR] ensure the termination flags are set by process_xxx

When any processing remains on a buffer, it must be up to the
processing functions to set the termination flags, because they
are the only ones who know about higher levels.

16 years ago[MEDIUM] centralize buffer timeout checks at the top of process_session
Willy Tarreau [Sun, 17 Aug 2008 11:04:25 +0000 (13:04 +0200)] 
[MEDIUM] centralize buffer timeout checks at the top of process_session

it's more efficient and easier to check all the timeouts at once and
always rely on the buffer flags than to check them everywhere.

16 years ago[MEDIUM] use buffer->wex instead of buffer->cex for connect timeout
Willy Tarreau [Sun, 17 Aug 2008 10:11:14 +0000 (12:11 +0200)] 
[MEDIUM] use buffer->wex instead of buffer->cex for connect timeout

It's a shame not to use buffer->wex for connection timeouts since by
definition it cannot be used till the connection is not established.
Using it instead of ->cex also makes the buffer processing more
symmetric.

16 years ago[MAJOR] process_session: rely only on buffer flags
Willy Tarreau [Sat, 16 Aug 2008 23:00:46 +0000 (01:00 +0200)] 
[MAJOR] process_session: rely only on buffer flags

Instead of calling all functions in a loop, process_session now
calls them according to buffer flags changes. This ensures that
we almost never call functions for nothing. The flags settings
are still quite coarse, but the number of average functions
calls per session has dropped from 31 to 18 (the calls to
process_srv dropped from 13 to 7 and the calls to process_cli
dropped from 13 to 8).

This could still be improved by memorizing which flags each
function uses, but that would add a level of complexity which
is not desirable and maybe even not worth the small gain.

16 years ago[MEDIUM] buffers: add BF_EMPTY and BF_FULL to remove dependency on req/rep->l
Willy Tarreau [Sat, 16 Aug 2008 20:18:07 +0000 (22:18 +0200)] 
[MEDIUM] buffers: add BF_EMPTY and BF_FULL to remove dependency on req/rep->l

It is not always convenient to run checks on req->l in functions to
check if a buffer is empty or full. Now the stream_sock functions
set flags BF_EMPTY and BF_FULL according to the buffer contents. Of
course, functions which touch the buffer contents adjust the flags
too.

16 years ago[CLEANUP] get rid of BF_SHUT*_PENDING
Willy Tarreau [Sat, 16 Aug 2008 19:13:23 +0000 (21:13 +0200)] 
[CLEANUP] get rid of BF_SHUT*_PENDING

BF_SHUTR_PENDING and BF_SHUTW_PENDING were poor ideas because
BF_SHUTR is the pending of BF_SHUTW_DONE and BF_SHUTW is the
pending of BF_SHUTR_DONE. Remove those two useless and confusing
"pending" versions and rename buffer_shut{r,w}_* functions.

16 years ago[BUG] maintain_proxies must not disable backends
Willy Tarreau [Sat, 16 Aug 2008 16:41:13 +0000 (18:41 +0200)] 
[BUG] maintain_proxies must not disable backends

maintain_proxies could disable backends (p->maxconn == 0) which is
wrong (but apparently harmless). Add a check for p->maxconn == 0.

16 years ago[BUG] process_response: do not touch srv_state
Willy Tarreau [Sat, 16 Aug 2008 16:40:18 +0000 (18:40 +0200)] 
[BUG] process_response: do not touch srv_state

process_response is not allowed to touch srv_state (this is an
incident which has survived the code migration). This bug was
causing connection exhaustion on frontend due to some closed
sockets marked SV_STDATA again.

16 years ago[BUG] buffers: remove BF_MAY_CONNECT and fix forwarding issue
Willy Tarreau [Sat, 16 Aug 2008 14:39:26 +0000 (16:39 +0200)] 
[BUG] buffers: remove BF_MAY_CONNECT and fix forwarding issue

It wasn't really wise to separate BF_MAY_CONNECT and BF_MAY_FORWARD,
as it caused trouble in TCP mode because the connection was allowed
but not the forwarding. Remove BF_MAY_CONNECT.

16 years ago[BUG] process_response must not enable the read FD
Willy Tarreau [Sat, 16 Aug 2008 14:11:07 +0000 (16:11 +0200)] 
[BUG] process_response must not enable the read FD

Since the separation of TCP and HTTP state machines, the HTTP
code must not play anymore with the file descriptor status
without checking if they are closed. Remains of such practice
have caused busy loops under some circumstances (mainly when
client closed during headers response).

16 years ago[BUG] ev_sepoll: closed file descriptors could persist in the spec list
Willy Tarreau [Sat, 16 Aug 2008 14:06:02 +0000 (16:06 +0200)] 
[BUG] ev_sepoll: closed file descriptors could persist in the spec list

If __fd_clo() was called on a file descriptor which was previously
disabled, it was not removed from the spec list. This apparently
could not happen on previous code because the TCP states prevented
this, but now it happens regularly. The effects are spec entries
stuck populated, leading to busy loops.

16 years ago[MINOR] term_trace: add better instrumentations to trace the code
Willy Tarreau [Sat, 16 Aug 2008 12:55:08 +0000 (14:55 +0200)] 
[MINOR] term_trace: add better instrumentations to trace the code

A new member has been added to the struct session. It keeps a trace
of what block of code performs a close or a shutdown on a socket, and
in what sequence. This is extremely convenient for post-mortem analysis
where flag combinations and states seem impossible. A new ABORT_NOW()
macro has also been added to make the code immediately segfault where
called.

16 years ago[MEDIUM] remove unused references to {CL|SV}_STSHUT*
Willy Tarreau [Sat, 16 Aug 2008 08:56:30 +0000 (10:56 +0200)] 
[MEDIUM] remove unused references to {CL|SV}_STSHUT*

All references to CL_STSHUT* and SV_STSHUT* were removed where
possible. Some of them could not be removed because they are
still in use by the unix sockets.

A bug remains at this stage. Injecting with a very short timeout
sometimes leads to a client in close state and a server in data
state with all buffer flags indicating a shutdown but the server
fd still enable, thus causing a busy loop.

16 years ago[MAJOR] clearly separate HTTP response processing from TCP server state
Willy Tarreau [Fri, 15 Aug 2008 21:43:19 +0000 (23:43 +0200)] 
[MAJOR] clearly separate HTTP response processing from TCP server state

The HTTP response is now processed in its own function, regardless of
the TCP state. All FSMs have become fairly simpler and must still be
improved by removing useless CL_STSHUT* and SV_STSHUT* (still used by
proto_uxst). The number of calls to process_* is still huge though.

Next steps consist in :
  - removing useless assignments of CL_STSHUT* and SV_STSHUT*
  - add a BF_EMPTY flag to buffers to indicate an empty buffer
  - returning smarter values in process_* so that each callee
    may explicitly indicate whom needs to be called after it.
  - unify read and write timeouts for a same side. The way it
    is now is too complicated and error-prone
  - auditing code for regression testing

We're close to getting something which works fairly better now.

16 years ago[MAJOR] better separation of response processing and server state
Willy Tarreau [Fri, 15 Aug 2008 16:16:37 +0000 (18:16 +0200)] 
[MAJOR] better separation of response processing and server state

TCP timeouts are not managed anymore by the response FSM. Warning,
the FORCE_CLOSE state does not work anymore for now. All remaining
bugs causing stale connections have been swept.

16 years ago[MAJOR] get rid of the SV_STHEADERS state
Willy Tarreau [Thu, 14 Aug 2008 16:35:40 +0000 (18:35 +0200)] 
[MAJOR] get rid of the SV_STHEADERS state

The HTTP response code has been moved to a specific function
called "process_response" and the SV_STHEADERS state has been
removed and replaced with the flag AN_RTR_HTTP_HDR.

16 years ago[BUG] fix recently introduced loop when client closes early
Willy Tarreau [Wed, 13 Aug 2008 17:19:37 +0000 (19:19 +0200)] 
[BUG] fix recently introduced loop when client closes early

Due to a recent change in the FSMs, if the client closes with buffer
full, then the server loops waiting for headers. We can safely ignore
this case since the server FSM will have to be reworked too. Let's
fix the root cause for now.

16 years ago[MAJOR] completely separate HTTP and TCP states on the request path
Willy Tarreau [Mon, 11 Aug 2008 21:42:50 +0000 (23:42 +0200)] 
[MAJOR] completely separate HTTP and TCP states on the request path

For the first time, HTTP and TCP are not merged anymore. All request
processing has moved to process_request while the TCP processing of
the frontend remains in process_cli. The code is a lot cleaner,
simpler, smaller (1%) and slightly faster (1% too).

Right now, the HTTP state machine cannot easily command the TCP
state machine, but it does not cause that many difficulties.

The response processing has not yet been extracted, and the unix-stream
state machines have to be broken down that way too.

The CL_STDATA, CL_STSHUTR and CL_STSHUTW states still exist and are
exactly the sames. They will have to be all merged into CL_STDATA
once the work has stabilized. It is also possible that this single
state will disappear in favor of just buffer flags.

16 years ago[MEDIUM] simplify and centralize request timeout cancellation and request forwarding
Willy Tarreau [Mon, 11 Aug 2008 15:35:01 +0000 (17:35 +0200)] 
[MEDIUM] simplify and centralize request timeout cancellation and request forwarding

Instead of playing with req->flags and request timeout everywhere,
tweak them only at precise locations.

16 years ago[MAJOR] get rid of SV_STANALYZE (step 2)
Willy Tarreau [Mon, 11 Aug 2008 13:24:42 +0000 (15:24 +0200)] 
[MAJOR] get rid of SV_STANALYZE (step 2)

The SV_STANALYZE state was installed on the server side but was really
meant to be processed with the rest of the request on the client side.
It suffered from several issues, mostly related to the way timeouts were
handled while waiting for data.

All known issues related to timeouts during a request - and specifically
a request involving body processing - have been raised and fixed. At this
point, the code is a bit dirty but works fine, so next steps might be
cleanups with an ability to come back to the current state in case of
trouble.

16 years ago[MAJOR] kill CL_STINSPECT and CL_STHEADERS (step 1)
Willy Tarreau [Sun, 10 Aug 2008 20:55:22 +0000 (22:55 +0200)] 
[MAJOR] kill CL_STINSPECT and CL_STHEADERS (step 1)

This is a first attempt at separating data processing from the
TCP state machine. Those two states have been replaced with flags
in the session indicating what needs to be analyzed. The corresponding
code is still called before and in lieu of TCP states.

Next change should get rid of the specific SV_STANALYZE which is in
fact a client state.

Then next change should consist in making it possible to analyze
TCP contents while being in CL_STDATA (or CL_STSHUT*).

16 years ago[PATCH] appsessions: cleanup DEBUG_HASH and initialize request_counter
Aleksandar Lazic [Wed, 13 Aug 2008 17:57:02 +0000 (19:57 +0200)] 
[PATCH] appsessions: cleanup DEBUG_HASH and initialize request_counter

This patch cleanup the -DDEBUG=DEBUG_HASH output setting and initialize
the request_counter for the appsessions.

16 years ago[BUG] client timeout incorrectly rearmed while waiting for server
Willy Tarreau [Mon, 11 Aug 2008 09:20:03 +0000 (11:20 +0200)] 
[BUG] client timeout incorrectly rearmed while waiting for server

Client timeout could be refreshed in stream_sock_*, but this is
undesired when the timeout is already set to eternity. The effect
is that a session could still be aborted if client timeout was
smaller than server timeout. A second effect is that sessions
expired on the server side would expire with "cD" flags.

The fix consists in not updating it if it was not previously set.
A cleaner method might consist in updating the buffer timeout. This
is probably what will be done later when the state machines only
deal with the buffers.

16 years ago[BUG] server timeout was not considered in some circumstances
Willy Tarreau [Mon, 11 Aug 2008 08:35:07 +0000 (10:35 +0200)] 
[BUG] server timeout was not considered in some circumstances

Due to a copy-paste typo, the client timeout was refreshed instead
of the server's when waiting for server response. This means that
the server's timeout remained eternity.

16 years ago[BUG] fix segfault with url_param + check_post
Willy Tarreau [Sun, 10 Aug 2008 22:21:56 +0000 (00:21 +0200)] 
[BUG] fix segfault with url_param + check_post

If an HTTP/0.9-like POST request is sent to haproxy while
configured with url_param + check_post, it will crash. The
reason is that the total buffer length was computed based
on req->total (which equals the number of bytes read) and
not req->l (number of bytes in the buffer), thus leading
to wrong size calculations when calling memchr().

The affected code does not look like it could have been
exploited to run arbitrary code, only reads were performed
at wrong locations.

16 years ago[MEDIUM] process_cli: don't rely at all on server state
Willy Tarreau [Sun, 10 Aug 2008 14:21:32 +0000 (16:21 +0200)] 
[MEDIUM] process_cli: don't rely at all on server state

A new buffer flag BF_MAY_FORWARD has been added so that the client
FSM can check whether it is allowed to forward the response to the
client. The client FSM does not have to monitor the server state
anymore.

16 years ago[MEDIUM] process_srv: don't rely at all on client state
Willy Tarreau [Sun, 3 Aug 2008 18:38:13 +0000 (20:38 +0200)] 
[MEDIUM] process_srv: don't rely at all on client state

A new buffer flag BF_MAY_CONNECT has been added so that the server
FSM can check whether it is allowed to establish a connection or
not. That way, the client FSM only has to move this flag and the
server side does not need to monitor client state anymore.

16 years ago[MEDIUM] process_srv: rely on buffer flags for client shutdown
Willy Tarreau [Sun, 3 Aug 2008 17:15:35 +0000 (19:15 +0200)] 
[MEDIUM] process_srv: rely on buffer flags for client shutdown

The open/close nature of each half of the client side is known
to the buffer, so let the server state machine rely on this
instead of checking the client state for CL_STSHUT* or
CL_STCLOSE.

16 years ago[MEDIUM] buffers: ensure buffer_shut* are properly called upon shutdowns
Willy Tarreau [Sun, 3 Aug 2008 15:25:14 +0000 (17:25 +0200)] 
[MEDIUM] buffers: ensure buffer_shut* are properly called upon shutdowns

It is important that buffer states reflect the state of both sides so
that we can remove client and server state inter-dependencies.

16 years ago[MEDIUM] memory: update pool_free2() to support NULL pointers
Willy Tarreau [Sun, 3 Aug 2008 15:41:33 +0000 (17:41 +0200)] 
[MEDIUM] memory: update pool_free2() to support NULL pointers

In order to make pool usage more convenient, let pool_free2()
support NULL pointers by doing nothing, just like the standard
free(3) call does.

The various call places have been updated to remove the now
useless checks.

16 years ago[CLEANUP] remove 65 useless NULL checks before free
Willy Tarreau [Sun, 3 Aug 2008 10:19:50 +0000 (12:19 +0200)] 
[CLEANUP] remove 65 useless NULL checks before free

C specification clearly states that free(NULL) is a no-op.
So remove useless checks before calling free.

16 years ago[MINOR] permit renaming of x-forwarded-for header
Ross West [Sun, 3 Aug 2008 08:51:45 +0000 (10:51 +0200)] 
[MINOR] permit renaming of x-forwarded-for header

Because I needed it in my situation - here's a quick patch to
allow changing of the "x-forwarded-for" header by using a suboption to
"option forwardfor".

Suboption "header XYZ" will set the header from "x-forwarded-for" to "XYZ".

Default is still "x-forwarded-for" if the header value isn't defined.
Also the suboption 'except a.b.c.d/z' still works on the same line.

So it's now: option forwardfor [except a.b.c.d[/z]] [header XYZ]

16 years ago[MEDIUM] acl: when possible, report the name and requirements of ACLs in warnings
Willy Tarreau [Sun, 27 Jul 2008 20:02:32 +0000 (22:02 +0200)] 
[MEDIUM] acl: when possible, report the name and requirements of ACLs in warnings

When an ACL is referenced at a wrong place (eg: response during request, layer7
during layer4), try to indicate precisely the name and requirements of this ACL.

Only the first faulty ACL is returned. A small change consisting in iterating
that way may improve reports :
   cap = ACL_USE_any_unexpected
   while ((acl=cond_find_require(cond, cap))) {
     warning()
     cap &= ~acl->requires;
   }

This will report the first ACL of each unsupported type. But doing so will
mangle the error reporting a lot, so we need to rework error reports first.

16 years ago[MEDIUM] acl: set types on all currently known ACL verbs
Willy Tarreau [Fri, 25 Jul 2008 17:31:03 +0000 (19:31 +0200)] 
[MEDIUM] acl: set types on all currently known ACL verbs

All currently known ACL verbs have been assigned a type which makes
it possible to detect inconsistencies, such as response values used
in request rules.

16 years ago[MEDIUM] acl: enforce ACL type checking
Willy Tarreau [Fri, 25 Jul 2008 17:13:19 +0000 (19:13 +0200)] 
[MEDIUM] acl: enforce ACL type checking

ACL now hold information on the availability of the data they rely
on. They can indicate which parts of the requests/responses they
require, and the rules parser may now report inconsistencies.

As an example, switching rules are now checked for response-specific
ACLs, though those are not still set. A warning is reported in case
of mismatch. ACLs keyword restrictions will now have to be specifically
set wherever a better control is expected.

The line number where an ACL condition is declared has been added to
the conditions in order to be able to report the faulty line number
during post-loading checks.

17 years ago[MINOR] acl: add the "wait_end" acl verb
Willy Tarreau [Sun, 20 Jul 2008 09:18:28 +0000 (11:18 +0200)] 
[MINOR] acl: add the "wait_end" acl verb

The new "wait_end" acl delays evaluation of the rule (and the next ones)
to the end of the analysis period. This is intented to be used with TCP
content analysis. A rule referencing such an ACL will not match until
the delay is over. An equivalent default ACL "WAIT_END" has been created.

17 years ago[MEDIUM] acl: get rid of dummy values in always_true/always_false
Willy Tarreau [Sun, 20 Jul 2008 08:39:22 +0000 (10:39 +0200)] 
[MEDIUM] acl: get rid of dummy values in always_true/always_false

make use of last change in order to get rid of dummy values in
always_true/always_false.

17 years ago[MEDIUM] acl: permit fetch() functions to set the result themselves
Willy Tarreau [Sun, 20 Jul 2008 08:13:37 +0000 (10:13 +0200)] 
[MEDIUM] acl: permit fetch() functions to set the result themselves

For protocol analysis, it's not always convenient to have to run through
a fetch then a match against dummy values. It's easier to let the fetch()
function set the result itself. This obviously works only for boolean
values.

17 years ago[MINOR] acl: add REQ_CONTENT to the list of default acls
Willy Tarreau [Sun, 20 Jul 2008 07:29:50 +0000 (09:29 +0200)] 
[MINOR] acl: add REQ_CONTENT to the list of default acls

With content inspection, checking the presence of data in the
request buffer is very important. It's getting boring to always
add such an ACL, so let's add it by default.

17 years ago[DOC] document the new "tcp-request" keyword and associated ACLs
Willy Tarreau [Wed, 16 Jul 2008 16:36:06 +0000 (18:36 +0200)] 
[DOC] document the new "tcp-request" keyword and associated ACLs

The update concerns :
  - tcp-request inspect-delay
  - tcp-request accept
  - tcp-request reject
  - acl ... req_len
  - acl ... req_ssl_ver

17 years ago[CLEANUP] remove dependency on obsolete INTBITS macro
Willy Tarreau [Mon, 14 Jul 2008 22:36:31 +0000 (00:36 +0200)] 
[CLEANUP] remove dependency on obsolete INTBITS macro

The INTBITS macro was found to be already defined on some platforms,
and to equal 32 (while INTBITS was 5 here). Due to pure luck, there
was no declaration conflict, but it's nonetheless a problem to fix.

Looking at the code showed that this macro was only used for left
shifts and nothing else anymore. So the replacement is obvious. The
new macro, BITS_PER_INT is more obviously correct.

17 years ago[CLEANUP] remove many #include <types/xxx> from C files
Willy Tarreau [Mon, 14 Jul 2008 22:22:45 +0000 (00:22 +0200)] 
[CLEANUP] remove many #include <types/xxx> from C files

It should be stated as a rule that a C file should never
include types/xxx.h when proto/xxx.h exists, as it gives
less exposure to declaration conflicts (one of which was
caught and fixed here) and it complicates the file headers
for nothing.

Only types/global.h, types/capture.h and types/polling.h
have been found to be valid includes from C files.

17 years ago[CLEANUP] remove unused include/types/client.h
Willy Tarreau [Mon, 14 Jul 2008 21:57:33 +0000 (23:57 +0200)] 
[CLEANUP] remove unused include/types/client.h

This file is not used anymore.

17 years ago[MINOR] acl: add req_ssl_ver in TCP, to match an SSL version
Willy Tarreau [Tue, 15 Jul 2008 16:58:05 +0000 (18:58 +0200)] 
[MINOR] acl: add req_ssl_ver in TCP, to match an SSL version

This new keyword matches an dotted version mapped into an integer.
It permits to match an SSL message protocol version just as if it
was an integer, so that it is easy to map ranges, like this :

acl obsolete_ssl  req_ssl_ver   lt 3
acl correct_ssl   req_ssl_ver   3.0-3.1
acl invalid_ssl   req_ssl_ver   gt 3.1

Both SSLv2 hello messages and SSLv3 messages are supported. The
test tries to be strict enough to avoid being easily fooled. In
particular, it waits for as many bytes as announced in the message
header if this header looks valid (bound to the buffer size).

The same decoder will be usable with minor changes to check the
response messages.

17 years ago[MINOR] acl: add a new parsing function: parse_dotted_ver
Willy Tarreau [Tue, 15 Jul 2008 14:05:33 +0000 (16:05 +0200)] 
[MINOR] acl: add a new parsing function: parse_dotted_ver

This new function supports one major and one minor and makes an int of them.
It is very convenient to compare versions (eg: SSL) just as if they were plain
integers, as the comparison functions will still be based on integers.

17 years ago[MAJOR] implement tcp request content inspection
Willy Tarreau [Mon, 14 Jul 2008 21:54:42 +0000 (23:54 +0200)] 
[MAJOR] implement tcp request content inspection

Some people need to inspect contents of TCP requests before
deciding to forward a connection or not. A future extension
of this demand might consist in selecting a server farm
depending on the protocol detected in the request.

For this reason, a new state CL_STINSPECT has been added on
the client side. It is immediately entered upon accept() if
the statement "tcp-request inspect-delay <xxx>" is found in
the frontend configuration. Haproxy will then wait up to
this amount of time trying to find a matching ACL, and will
either accept or reject the connection depending on the
"tcp-request content <action> {if|unless}" rules, where
<action> is either "accept" or "reject".

Note that it only waits that long if no definitive verdict
can be found earlier. That generally implies calling a fetch()
function which does not have enough information to decode
some contents, or a match() function which only finds the
beginning of what it's looking for.

It is only at the ACL level that partial data may be processed
as such, because we need to distinguish between MISS and FAIL
*before* applying the term negation.

Thus it is enough to add "| ACL_PARTIAL" to the last argument
when calling acl_exec_cond() to indicate that we expect
ACL_PAT_MISS to be returned if some data is missing (for
fetch() or match()). This is the only case we may return
this value. For this reason, the ACL check in process_cli()
has become a lot simpler.

A new ACL "req_len" of type "int" has been added. Right now
it is already possible to drop requests which talk too early
(eg: for SMTP) or which don't talk at all (eg: HTTP/SSL).

Also, the acl fetch() functions have been extended in order
to permit reporting of missing data in case of fetch failure,
using the ACL_TEST_F_MAY_CHANGE flag.

The default behaviour is unchanged, and if no rule matches,
the request is accepted.

As a side effect, all layer 7 fetching functions have been
cleaned up so that they now check for the validity of the
layer 7 pointer before dereferencing it.

17 years ago[MEDIUM] modularize the "timeout" keyword configuration parser
Willy Tarreau [Wed, 9 Jul 2008 18:34:27 +0000 (20:34 +0200)] 
[MEDIUM] modularize the "timeout" keyword configuration parser

The "timeout" keyword already relied on an external parser, let's
make use of the new keyword registration mechanism.

17 years ago[MINOR] cfgparse: add support for warnings in external functions
Willy Tarreau [Wed, 9 Jul 2008 18:22:56 +0000 (20:22 +0200)] 
[MINOR] cfgparse: add support for warnings in external functions

Some parsers will need to report warnings in some cases. Let's
use positive values for that.

17 years ago[MEDIUM] modularize the global "stats" keyword configuration parser
Willy Tarreau [Wed, 9 Jul 2008 18:12:41 +0000 (20:12 +0200)] 
[MEDIUM] modularize the global "stats" keyword configuration parser

The "stats" keyword already relied on an external parser, let's
make use of the new keyword registration mechanism.

17 years ago[MEDIUM] add support for configuration keyword registration
Willy Tarreau [Wed, 9 Jul 2008 17:39:06 +0000 (19:39 +0200)] 
[MEDIUM] add support for configuration keyword registration

Any module which needs configuration keywords may now dynamically
register a keyword in a given section, and associate it with a
configuration parsing function using cfg_register_keywords() from
a constructor function. This makes the configuration parser more
modular because it is not required anymore to touch cfg_parse.c.
Example :

static int parse_global_blah(char **args, int section_type, struct proxy *curpx,
                             struct proxy *defpx, char *err, int errlen)
{
printf("parsing blah in global section\n");
return 0;
}

static int parse_listen_blah(char **args, int section_type, struct proxy *curpx,
      struct proxy *defpx, char *err, int errlen)
{
printf("parsing blah in listen section\n");
if (*args[1]) {
snprintf(err, errlen, "missing arg for listen_blah!!!");
return -1;
}
return 0;
}

static struct cfg_kw_list cfg_kws = {{ },{
{ CFG_GLOBAL, "blah", parse_global_blah },
{ CFG_LISTEN, "blah", parse_listen_blah },
{ 0, NULL, NULL },
}};

__attribute__((constructor))
static void __module_init(void)
{
cfg_register_keywords(&cfg_kws);
}

17 years ago[TESTS] added test-acl.cfg to test some ACL combinations
Willy Tarreau [Wed, 9 Jul 2008 14:18:21 +0000 (16:18 +0200)] 
[TESTS] added test-acl.cfg to test some ACL combinations

various rules constructions can be tested with this test case.

17 years ago[BUG] use_backend would not correctly consider "unless"
Willy Tarreau [Wed, 9 Jul 2008 09:23:31 +0000 (11:23 +0200)] 
[BUG] use_backend would not correctly consider "unless"

A copy-paste typo made use_backend not correctly consider the "unless"
case, depending on the previous "block" rule.

17 years ago[MAJOR] convert all expiration timers from timeval to ticks
Willy Tarreau [Sun, 6 Jul 2008 22:09:58 +0000 (00:09 +0200)] 
[MAJOR] convert all expiration timers from timeval to ticks

This is the first attempt at moving all internal parts from
using struct timeval to integer ticks. Those provides simpler
and faster code due to simplified operations, and this change
also saved about 64 bytes per session.

A new header file has been added : include/common/ticks.h.

It is possible that some functions should finally not be inlined
because they're used quite a lot (eg: tick_first, tick_add_ifset
and tick_is_expired). More measurements are required in order to
decide whether this is interesting or not.

Some function and variable names are still subject to change for
a better overall logics.

17 years ago[BUILD] silent a warning in unlikely() with gcc 4.x
Willy Tarreau [Sun, 6 Jul 2008 13:18:50 +0000 (15:18 +0200)] 
[BUILD] silent a warning in unlikely() with gcc 4.x

The unlikely() implementation for gcc 4.x spits out a warning
when a pointer is passed. Add a cast to unsigned long.

17 years ago[OPTIM] task_queue: assume most consecutive timers are equal
Willy Tarreau [Sat, 5 Jul 2008 16:16:19 +0000 (18:16 +0200)] 
[OPTIM] task_queue: assume most consecutive timers are equal

When queuing a timer, it's very likely that an expiration date is
equal to that of the previously queued timer, due to time rounding
to the millisecond. Optimizing for this case provides a noticeable
1% performance boost.

17 years ago[MEDIUM] introduce task->nice and boot access to statistics
Willy Tarreau [Mon, 30 Jun 2008 05:51:00 +0000 (07:51 +0200)] 
[MEDIUM] introduce task->nice and boot access to statistics

The run queue scheduler now considers task->nice to queue a task and
to pick a task out of the queue. This makes it possible to boost the
access to statistics (both via HTTP and UNIX socket). The UNIX socket
receives twice as much a boost as the HTTP socket because it is more
sensible.

17 years ago[MAJOR] use an ebtree instead of a list for the run queue
Willy Tarreau [Sun, 29 Jun 2008 20:40:23 +0000 (22:40 +0200)] 
[MAJOR] use an ebtree instead of a list for the run queue

We now insert tasks in a certain sequence in the run queue.
The sorting key currently is the arrival order. It will now
be possible to apply a "nice" value to any task so that it
goes forwards or backwards in the run queue.

The calls to wake_expired_tasks() and maintain_proxies()
have been moved to the main run_poll_loop(), because they
had nothing to do in process_runnable_tasks().

The task_wakeup() function is not inlined anymore, as it was
only used at one place.

The qlist member of the task structure has been removed now.
The run_queue list has been replaced for an integer indicating
the number of tasks in the run queue.

17 years ago[OPTIM] shrink wake_expired_tasks() by using task_wakeup()
Willy Tarreau [Sun, 29 Jun 2008 17:25:52 +0000 (19:25 +0200)] 
[OPTIM] shrink wake_expired_tasks() by using task_wakeup()

It's not worth duplicating task_wakeup() in wake_expired_tasks().
Calling it reduces code size and slightly improves performance.

17 years ago[BUILD] change declaration of base64tab to fix build with Intel C++
Willy Tarreau [Sun, 29 Jun 2008 15:17:38 +0000 (17:17 +0200)] 
[BUILD] change declaration of base64tab to fix build with Intel C++

I got a report that Intel C++ complains about the size of the
base64tab in base64.c. Setting it to 65 chars to allow for the
trailing zero fixes the problem.

17 years ago[MEDIUM] rework the wait queue mechanism
Willy Tarreau [Sun, 29 Jun 2008 15:00:59 +0000 (17:00 +0200)] 
[MEDIUM] rework the wait queue mechanism

The wait queues now rely on 4 trees for past, present and future
timers. The computations are cleaner and more reliable. The
wake_expired_tasks function has become simpler. Also, a bug
previously introduced in task_queue() by the first introduction
of eb_trees has been fixed (the eb->key was never updated).