Commit Graph

72 Commits

Author SHA1 Message Date
Willy Tarreau
48d63db7a8 [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.
2008-08-03 20:48:50 +02:00
Willy Tarreau
0ceba5af74 [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.
2008-07-25 19:31:03 +02:00
Willy Tarreau
ec6c5df018 [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.
2008-07-16 10:30:42 +02:00
Willy Tarreau
b686644ad8 [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.
2008-07-16 10:29:07 +02:00
Willy Tarreau
0c303eec87 [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.
2008-07-07 00:09:58 +02:00
Willy Tarreau
9789f7bd68 [MAJOR] replace ultree with ebtree in wait-queues
The ultree code has been removed in favor of a simpler and
cleaner ebtree implementation. The eternity queue does not
need to exist anymore, and the pool_tree64 has been removed.

The ebtree node is stored in the task itself. The qlist list
header is still used by the run-queue, but will be able to
disappear once the run-queue uses ebtree too.
2008-06-24 08:17:16 +02:00
Willy Tarreau
b7f694f20e [MEDIUM] implement a monotonic internal clock
If the system date is set backwards while haproxy is running,
some scheduled events are delayed by the amount of time the
clock went backwards. This is particularly problematic on
systems where the date is set at boot, because it seldom
happens that health-checks do not get sent for a few hours.

Before switching to use clock_gettime() on systems which
provide it, we can at least ensure that the clock is not
going backwards and maintain two clocks : the "date" which
represents what the user wants to see (mostly for logs),
and an internal date stored in "now", used for scheduled
events.
2008-06-22 17:18:02 +02:00
Willy Tarreau
7c669d7e0f [BUG] fix the dequeuing logic to ensure that all requests get served
The dequeuing logic was completely wrong. First, a task was assigned
to all servers to process the queue, but this task was never scheduled
and was only woken up on session free. Second, there was no reservation
of server entries when a task was assigned a server. This means that
as long as the task was not connected to the server, its presence was
not accounted for. This was causing trouble when detecting whether or
not a server had reached maxconn. Third, during a redispatch, a session
could lose its place at the server's and get blocked because another
session at the same moment would have stolen the entry. Fourth, the
redispatch option did not work when maxqueue was reached for a server,
and it was not possible to do so without indefinitely hanging a session.

The root cause of all those problems was the lack of pre-reservation of
connections at the server's, and the lack of tracking of servers during
a redispatch. Everything relied on combinations of flags which could
appear similarly in quite distinct situations.

This patch is a major rework but there was no other solution, as the
internal logic was deeply flawed. The resulting code is cleaner, more
understandable, uses less magics and is overall more robust.

As an added bonus, "option redispatch" now works when maxqueue has
been reached on a server.
2008-06-20 15:08:06 +02:00
Willy Tarreau
7008987813 [BUG] queue management: wake oldest request in queues
When a server terminates a connection, the next session in its
own queue was immediately processed. Because of this, if all
server queues are always filled, then no new anonymous request
will be processed. Consider oldest request between global and
server queues to choose from which to pick the request.

An improvement over this will consist in adding a configurable
offset when comparing expiration dates, so that cookie-less
requests can get either less or more priority.
2008-06-20 15:07:40 +02:00
matt.farnsworth@nokia.com
1c2ab96be5 [MAJOR] implement parameter hashing for POST requests
This patch extends the "url_param" load balancing method by introducing
the "check_post" option. Using this option enables analysis of the beginning
of POST requests to search for the specified URL parameter.

The patch also fixes a few minor typos in comments that were discovered
during code review.
2008-04-15 15:30:41 +02:00
Willy Tarreau
d6f087ea1c [BUG] fix truncated responses with sepoll
Due to the way Linux delivers EPOLLIN and EPOLLHUP, a closed connection
received after some server data sometimes results in truncated responses
if the client disconnects before server starts to respond. The reason
is that the EPOLLHUP flag is processed as an indication of end of
transfer while some data may remain in the system's socket buffers.

This problem could only be triggered with sepoll, although nothing should
prevent it from happening with normal epoll. In fact, the work factoring
performed by sepoll increases the risk that this bug appears.

The fix consists in making FD_POLL_HUP and FD_POLL_ERR sticky and that
they are only checked if FD_POLL_IN is not set, meaning that we have
read all pending data.

That way, the problem is definitely fixed and sepoll still remains about
17% faster than epoll since it can take into account all information
returned by the kernel.
2008-01-18 17:20:13 +01:00
Willy Tarreau
036fae0ec9 [MEDIUM] introduce "timeout http-request" in frontends
In order to offer DoS protection, it may be required to lower the maximum
accepted time to receive a complete HTTP request without affecting the client
timeout. This helps protecting against established connections on which
nothing is sent. The client timeout cannot offer a good protection against
this abuse because it is an inactivity timeout, which means that if the
attacker sends one character every now and then, the timeout will not
trigger. With the HTTP request timeout, no matter what speed the client
types, the request will be aborted if it does not complete in time.
2008-01-06 13:24:40 +01:00
Willy Tarreau
a0250ba38d [OPTIM] introduce global parameter "tune.maxaccept"
This new parameter makes it possible to override the default
number of consecutive incoming connections which can be
accepted on a socket. By default it is not limited on single
process mode, and limited to 8 in multi-process mode.
2008-01-06 11:22:57 +01:00
Willy Tarreau
d7c30f9a8c [CLEANUP] grouped all timeouts in one structure
All known timeouts in a proxy have been grouped into a
"timeout" sub-structure.
2007-12-03 01:38:36 +01:00
Alexandre Cassen
5eb1a9033a [MEDIUM] New option http_proxy
Hello,

You will find attached an updated release of previously submitted patch.
It polish some part and extend ACL engine to match IP and PORT parsed in
HTTP request. (and take care of comments made by Willy ! ;))

Best regards,
Alexandre
2007-11-29 15:43:32 +01:00
Willy Tarreau
e6b989479c [MAJOR] create proto_tcp and move initialization of proxy listeners
Proxy listeners were very special and not very easy to manipulate.
A proto_tcp file has been created with all that is required to
manage TCPv4/TCPv6 as raw protocols, and provide generic listeners.

The code of start_proxies() and maintain_proxies() now looks less
like spaghetti. Also, event_accept will need a serious lifting in
order to use more of the information provided by the listener.
2007-11-04 22:42:49 +01:00
Willy Tarreau
8ced9a4b91 [MEDIUM] simplify error path in event_accept()
The error path in event_accept() was complicated by many code
duplications. Use the classical unrolling with the gotos. This
fix alone reduced the code by 2.5 kB.
2007-11-04 22:41:52 +01:00
Willy Tarreau
a7e76142a1 [MEDIUM] make default_backend work in TCP mode too
The default_backend did not work in TCP mode since there was no
header state to assign the backend. This causes much trouble when
configs are created by copy-paste.

The solution was to fix the way the backend is assigned upon accept().
A wrong contimeout assignment was fixed too.
2007-11-03 14:28:39 +01:00
Willy Tarreau
d95dcb51a8 [BUG] fix wrong timeout computation in event_accept()
In case the incoming socket is set for write and not for read (very
unlikely, except in HEALTH mode), the timeout may remain eternity due
to a copy-paste typo.
2007-10-16 07:41:52 +02:00
Willy Tarreau
e94ebd0e37 [MEDIUM] moved the sockaddr pointer to the fdtab structure
The stream_sock_* functions had to know about sessions just in
order to get the server's address for a connect() operation. This
is not desirable, particularly for non-IP protocols (eg: PF_UNIX).

Put a pointer to the peer's sockaddr_storage or sockaddr address
in the fdtab structure so that we never need to look further.

With this small change, the stream_sock.c file is now 100% protocol
independant.
2007-10-15 17:14:01 +02:00
Alexandre Cassen
87ea548313 [MINOR] add the "nolinger" option to disable data lingering
The following patch will give the ability to tweak socket linger mode.
You can use this option with "option nolinger" inside fronted or backend
configuration declaration.

This will help in environments where lots of FIN_WAIT sockets are
encountered.
2007-10-15 09:33:06 +02:00
Willy Tarreau
c11416f22f [MEDIUM] acl: distinguish between request and response headers
hdr(x) will now still be used for request headers, and shdr(x) for
server headers (response).
2007-06-17 16:58:38 +02:00
Willy Tarreau
97be145991 [MINOR] acl: provide a reference to the expr to fetch()
The fetch() functions may need to access the full expr to get
their args. Turn the void *arg into a struct acl_expr *expr.
2007-06-10 11:47:14 +02:00
Willy Tarreau
d41f8d85e8 [MINOR] acl: specify the direction during fetches
Some fetches such as 'line' or 'hdr' need to know the direction of
the test (request or response). A new 'dir' parameter is now
propagated from the caller to achieve this.
2007-06-10 10:06:18 +02:00
Willy Tarreau
ae8b796722 [MEDIUM] smarter integer comparison support in ACLs
ACLs now support operators such as 'eq', 'le', 'lt', 'ge' and 'gt'
in order to give more flexibility to the language. Because of this
change, the 'dst_limit' keyword changed to 'dst_conn' and now requires
either a range or a test such as 'dst_conn lt 1000' which is more
understandable.
2007-06-09 23:10:04 +02:00
Willy Tarreau
ee99136992 [BUG] pre-initialize timeouts with tv_eternity during parsing
ETERNITY is not 0 anymore, so all timeouts will not be initialized
to ETERNITY by a simple calloc(). We have to explictly assign them.

This bug caused random session aborts.
2007-05-14 14:37:50 +02:00
Willy Tarreau
1d4154a7c0 [MAJOR] convert the header indexes to use mempool v2 2007-05-13 22:57:02 +02:00
Willy Tarreau
cf7f320f9d [MAJOR] last bunch of capture changes for mempool v2
The header captures had lots of pools. They have all been transformed.
2007-05-13 22:46:04 +02:00
Willy Tarreau
7341d94c5d [MAJOR] switched buffers to mempools v2 2007-05-13 19:56:02 +02:00
Willy Tarreau
c6ca1a02aa [MAJOR] migrated task, tree64 and session to pool2
task and tree64 are already very close in size and are merged together.
Overall performance gained slightly by this simple change.
2007-05-13 19:43:47 +02:00
Willy Tarreau
d825eef9c5 [MAJOR] replaced all timeouts with struct timeval
The timeout functions were difficult to manipulate because they were
rounding results to the millisecond. Thus, it was difficult to compare
and to check what expired and what did not. Also, the comparison
functions were heavy with multiplies and divides by 1000. Now, all
timeouts are stored in timevals, reducing the number of operations
for updates and leading to cleaner and more efficient code.
2007-05-12 22:35:00 +02:00
Willy Tarreau
662b2d8d18 [MINOR] implement the ACL keywords 'dst' and 'dport'
The file client.c now provides acl_fetch_dip and acl_fetch_dport
to be able to check the client's destination address and port. The
corresponding ACL keywords 'dst' and 'dport' have been added.
2007-05-08 23:24:51 +02:00
Willy Tarreau
a67fad9d68 [MINOR] implement acl_parse_ip and acl_match_ip
The ACL can now compare IP addresses. The client's IP address
can be checked.
2007-05-08 23:24:51 +02:00
Willy Tarreau
8797c06327 [MEDIUM] added several ACL criteria and matches
Many ACL criteria have been added. Some others are still commented out
because some functions are still missing.
2007-05-08 23:24:50 +02:00
Willy Tarreau
14c8aac63b [MEDIUM] store the original destination address in the session
There are multiple places where the client's destination address is
required. Let's store it in the session when needed, and add a flag
to inform that it has been retrieved.
2007-05-08 23:24:20 +02:00
Willy Tarreau
5465e111fd [MINOR] pre-compute t->expire in event_accept
At the end of event_accept(), t->expire is computed with tv_min
between two exclusive values. Let's simply assign it at the same
time.
2007-04-29 19:09:47 +02:00
Willy Tarreau
42aae5c7cf [MEDIUM] many cleanups in the time functions
Now, functions whose name begins with '__tv_' are inlined. Also,
'tv_ms' is used as a prefix for functions using milliseconds.
2007-04-29 17:43:56 +02:00
Willy Tarreau
96bcfd75aa [MAJOR] replaced rbtree with ul2tree.
The rbtree-based wait queue consumes a lot of CPU. Use the ul2tree
instead. Lots of cleanups and code reorganizations made it possible
to reduce the task struct and simplify the code a bit.
2007-04-29 13:43:53 +02:00
Willy Tarreau
3d32d3a849 [MINOR] add support for the polling results in fdtab
Now fdtab can contain the FD_POLL_* events so that the pollers
which can fill them can give userful information to readers and
writers about the precise condition of wakeup.
2007-04-15 11:31:05 +02:00
Willy Tarreau
7a9664872e [MINOR] recompute maxfd before touching fdtab
It may be dangerous to play with fdtab before doing fd_insert()
because this last one is responsible for growing maxfd as needed.
Call fd_insert() before instead.
2007-04-15 10:58:02 +02:00
Willy Tarreau
f161a34fb3 [MEDIUM] updated all files to use EV_FD_*
Removed the temporary dirty hack.
2007-04-08 16:59:42 +02:00
Willy Tarreau
422505801f [MEDIUM] splitted logs into two versions : TCP and HTTP
logs are handled better with dedicated functions. The HTTP implementation
moved to proto_http.c. It has been cleaned up a bit. Now a frontend with
option httplog and no log will not call the function anymore.
2007-04-01 01:30:43 +02:00
Willy Tarreau
e2e27a5c8d [MEDIUM] removed now unused fiprm and beprm from proxies
The fiprm and beprm were added to ease the transition between
a single listener mode to frontends+backends. They are no longer
needed and make the code a bit more complicated. Remove them.
2007-04-01 00:01:37 +02:00
Willy Tarreau
042cc79e59 [BUG] fix pointer initializations for TCP connections.
Very recent changes consisting in moving some pointers to the
transaction instead of the session have lead to a bug because
those pointers were only initialized if the protocol was HTTP,
but they were freed based on their value. In some cases, it
was possible to cause double frees.
2007-03-19 16:20:06 +01:00
Willy Tarreau
3d300596bb [MINOR] move some flags from session.h to proto_http.h
Some session flags were clearly related to HTTP transactions.
A new 'flags' field has been added to http_txn, and the
associated flags moved to proto_http.h.
2007-03-18 18:34:41 +01:00
Willy Tarreau
3bac9ffe20 [CLEANUP] move http_txn out of session.h
The http_txn structure definitions moved to proto_http.h
2007-03-18 17:31:28 +01:00
Willy Tarreau
c2168d3ccb [CLEANUP] replaced occurrences of 'hreq' with 'txn' (bis)
Did the same in client.c
2007-03-03 20:53:23 +01:00
Willy Tarreau
b326fcc46a [CLEANUP] renamed several HTTP structures
Some parts of HTTP processing were incorrectly called "request" while
they are messages or transactions. The following structure members
have changed :

  http_msg.hdr_state => msg_state
  http_msg.sor => som
  http_req.req_state => removed
  http_req => http_txn
2007-03-03 13:54:32 +01:00
Willy Tarreau
f0d058e8ab [BUG] hdr_idx might be left uninitialized in some cases
When a request is invalid during RQ_BEFORE AND the debug mode is active,
the hdr_idx might be used uninitialized. Let's initialize it right after
the accept() for now.
2007-01-25 12:03:42 +01:00
Willy Tarreau
8973c70f7d [MEDIUM] implemented the status-line parser in http_msg_analyzer().
The status line parser has been written. With it, it should not
be too hard to replace the response parser to benefit from the
new header facilities.
2007-01-21 23:58:29 +01:00