Commit Graph

1163 Commits

Author SHA1 Message Date
Willy Tarreau
8b117082bc REORG: connection: replace si_data_close() with conn_data_close()
This close function only applies to connection-specific parts and
the stream-interface entry may soon disappear. Move this to the
connection instead.
2012-09-02 21:53:10 +02:00
Willy Tarreau
3788e4c874 MEDIUM: fd: remove the EV_FD_COND_* primitives
These primitives were initially introduced so that callers were able to
conditionally set/disable polling on a file descriptor and check in return
what the state was. It's been long since we last had an "if" on this, and
all pollers' functions were the same for cond_* and their systematic
counter parts, except that this required a check and a specific return
value that are not always necessary.

So let's simplify the FD API by removing this now unused distinction and
by making all specific functions return void.
2012-09-02 21:53:10 +02:00
Willy Tarreau
c76ae33bfc MAJOR: connection: call data layer handshakes from the handler
Handshakes is not called anymore from the data handlers, they're only
called from the connection handler when their flag is set.

Also, this move has uncovered an issue with the stream interface notifier :
it doesn't consider the FD_WAIT_* flags possibly set by the handshake
handlers. This will result in a stuck handshake when no data is in the
output buffer. In order to cover this, for now we'll perform the EV_FD_SET
in the SSL handshake function, but this needs to be addressed separately
from the stream interface operations.
2012-09-02 21:53:09 +02:00
Willy Tarreau
8f8c92fe93 MAJOR: connection: add a new CO_FL_CONNECTED flag
This new flag is used to indicate that the connection was already
connected. It can be used by I/O handlers to know that a connection
has just completed. It is used by stream_sock_update_conn(), allowing
the sock_opt handlers not to manipulate the SI timeout nor the
BF_WRITE_NULL flag anymore.
2012-09-02 21:53:09 +02:00
Willy Tarreau
239d7189fc MEDIUM: stream_interface: pass connection instead of fd in sock_ops
The sock_ops I/O callbacks made use of an FD till now. This has become
inappropriate and the struct connection is much more useful. It also
fixes the race condition introduced by previous change.
2012-09-02 21:53:08 +02:00
Willy Tarreau
fd31e53139 MAJOR: remove the stream interface and task management code from sock_*
The socket data layer code must only focus on moving data between a
socket and a buffer. We need a special stream interface handler to
update the stream interface and the file descriptor status.

At the moment the code works but suffers from a race condition caused
by its API : the read/write callbacks still make use of the fd instead
of using the connection. And when a double shutdown is performed, a call
to ->write() after ->read() processed an error results in dereferencing
a NULL fdtab[]->owner. This is only a temporary issue which doesn't need
to be fixed now since this will automatically go away when the functions
change to use the connection instead.
2012-09-02 21:53:08 +02:00
Willy Tarreau
076be25ab8 CLEANUP: remove the now unused fdtab direct I/O callbacks
They were all left to NULL since last commit so we can safely remove them
all now and remove the temporary dual polling logic in pollers.
2012-09-02 21:51:29 +02:00
Willy Tarreau
2da156fe5e MAJOR: tcp: remove the specific I/O callbacks for TCP connection probes
Use a single tcp_connect_probe() instead of tcp_connect_write() and
tcp_connect_read(). We call this one only when no data layer function
have been processed, so this is a fallback to test for completion of
a connection attempt.

With this done, we don't have the need for any direct I/O callback
anymore.

The function still relies on ->write() to wake the stream interface up,
so it's not finished.
2012-09-02 21:51:29 +02:00
Willy Tarreau
2c6be84b3a MEDIUM: connection: extract the send_proxy callback from proto_tcp
This handshake handler must be independant, so move it away from
proto_tcp. It has a dedicated connection flag. It is tested before
I/O handlers and automatically removes the CO_FL_WAIT_L4_CONN flag
upon success.

It also sets the BF_WRITE_NULL flag on the stream interface and
stops the SI timeout. However it does not perform the task_wakeup(),
and relies on the data handler to do so for now. The SI wakeup will
have to be moved elsewhere anyway.
2012-09-02 21:51:28 +02:00
Willy Tarreau
8018471f44 MINOR: fd: make fdtab->owner a connection and not a stream_interface anymore
It is more convenient with a connection here and will abstract stream_interface
more easily.
2012-09-02 21:51:28 +02:00
Willy Tarreau
59f98393bb MINOR: connection: add a handler for fd-based connections
This connection handler will be used as an I/O handler for events
detected on a file descriptor. It is not used yet.
2012-09-02 21:51:28 +02:00
Willy Tarreau
4e6049e553 MINOR: fd: add a new I/O handler to fdtab
This one will eventually replace both cb[] handlers. At the moment it
is not used yet.
2012-09-02 21:51:27 +02:00
Willy Tarreau
505e34a36d MAJOR: get rid of fdtab[].state and use connection->flags instead
fdtab[].state was only used to know whether a connection was in progress
or an error was encountered. Instead we now use connection->flags to store
a flag for both. This way, connection management will be able to update the
connection status on I/O.
2012-09-02 21:51:26 +02:00
Willy Tarreau
900bc93e24 MINOR: connection: add flags to the connection struct
We're doing this to take over fdtab[].state.
2012-09-02 21:51:26 +02:00
Willy Tarreau
da92e2fb61 REORG/MINOR: checks: put a struct connection into the server
This will be used to handle the connection state once it goes away from fdtab.
There is no functional change at the moment.
2012-09-02 21:51:26 +02:00
Willy Tarreau
56e9c5e963 REORG/MINOR: connection: move declaration to its own include file
This way we don't depend on stream_interface anymore.
2012-09-02 21:51:26 +02:00
Willy Tarreau
ed8f614078 REORG/MEDIUM: fd: get rid of FD_STLISTEN
This state was only used so that ev_sepoll did not match FD_STERROR, which
changed in previous patch. We can now safely remove this state.
2012-09-02 21:51:25 +02:00
Willy Tarreau
db3b32610f REORG/MEDIUM: fd: remove FD_STCLOSE from struct fdtab
In an attempt to get rid of fdtab[].state, and to move the relevant
parts to the connection struct, we remove the FD_STCLOSE state which
can easily be deduced from the <owner> pointer as there is a 1:1 match.
2012-09-02 21:51:25 +02:00
Jamie Gloudon
801a0a353a DOC: fix name for "option independant-streams"
The correct spelling is "independent", not "independant". This patch
fixes the doc and the configuration parser to accept the correct form.
The config parser still allows the old naming for backwards compatibility.
2012-09-02 21:51:07 +02:00
Willy Tarreau
654694e189 MEDIUM: stats/cli: add support for "set table key" to enter values
This is used to enter values for stick tables. The most likely usage
is to set gpc0 for a specific IP address in order to block traffic
for abusers without having to reload. Since all data types are
supported, other usages are possible (eg: replace a users's assigned
server).
2012-09-02 21:51:07 +02:00
Willy Tarreau
c3a08a136b BUG: stktable: tcp_src_to_stktable_key() must return NULL on invalid families
Source addresses of non-TCP families were not correctly handled by
tcp_src_to_stktable_key() as it forgot to return NULL and instead left
the previous value in the stick-table buffer.

This bug is 1.5-specific and was introduced by commit 4f92d320 in 1.5-dev6
so it does not need any backport.
2012-08-31 11:03:30 +02:00
David du Colombier
65c1796c4a MINOR: IPv6 support for transparent proxy
Set socket option IPV6_TRANSPARENT on binding
to enable transparent proxy on IPv6.
This option is available from Linux 2.6.37.
2012-07-31 07:53:42 +02:00
Willy Tarreau
96596aeead MEDIUM: fd/si: move peeraddr from struct fdinfo to struct connection
The destination address is purely a connection thing and not an fd thing.
It's also likely that later the address will be stored into the connection
and linked to by the SI.

struct fdinfo only keeps the pointer to the port range and the local port
for now. All of this also needs to move to the connection but before this
the release of the port range must move from fd_delete() to a new function
dedicated to the connection.
2012-06-08 22:59:52 +02:00
Willy Tarreau
4f8a83cb6e MEDIUM: stats: add the ability to kill sessions from the admin interface
It was not possible to kill remaining sessions from the admin interface,
which is annoying especially when switching to maintenance mode. Now it's
possible.
2012-06-04 00:26:23 +02:00
Willy Tarreau
d72822442d MEDIUM: stats: add support for soft stop/soft start in the admin interface
One important missing feature on the web interface is the ability to perform
a soft stop/soft start. This is now possible.
2012-06-04 00:22:44 +02:00
Justin Karneges
eb2c24ae2a MINOR: checks: add on-marked-up option
This implements the feature discussed in the earlier thread of killing
connections on backup servers when a non-backup server comes back up. For
example, you can use this to route to a mysql master & slave and ensure
clients don't stay on the slave after the master goes from down->up. I've done
some minimal testing and it seems to work.

[WT: added session flag & doc, moved the killing after logging the server UP,
 and ensured that the new server is really usable]
2012-06-03 23:48:42 +02:00
Willy Tarreau
496aa0111e BUG/MEDIUM: ensure that unresolved arguments are freed exactly once
When passing arguments to ACLs and samples, some types are stored as
strings then resolved later after config parsing is done. Upon exit,
the arguments need to be freed only if the string was not resolved
yet. At the moment we can encounter double free during deinit()
because some arguments (eg: userlists) are freed once as their own
type and once as a string.

The solution consists in adding an "unresolved" flag to the args to
say whether the value is still held in the <str> part or is final.

This could be debugged thanks to a useful bug report from Sander Klein.
2012-06-01 10:40:52 +02:00
Willy Tarreau
4992dd2d30 MINOR: http: add support for "httponly" and "secure" cookie attributes
httponly  This option tells haproxy to add an "HttpOnly" cookie attribute
             when a cookie is inserted. This attribute is used so that a
             user agent doesn't share the cookie with non-HTTP components.
             Please check RFC6265 for more information on this attribute.

   secure    This option tells haproxy to add a "Secure" cookie attribute when
             a cookie is inserted. This attribute is used so that a user agent
             never emits this cookie over non-secure channels, which means
             that a cookie learned with this flag will be presented only over
             SSL/TLS connections. Please check RFC6265 for more information on
             this attribute.
2012-05-31 21:02:17 +02:00
Willy Tarreau
b5ba17e3a9 BUG/MINOR: config: do not report twice the incompatibility between cookie and non-http
This one was already taken care of in proxy_cfg_ensure_no_http(), so if a
cookie is presented in a TCP backend, we got two warnings.

This can be backported to 1.4 since it's been this way for 2 years (although not dramatic).
2012-05-31 20:47:00 +02:00
Willy Tarreau
674021329c REORG/MINOR: use dedicated proxy flags for the cookie handling
Cookies were mixed with many other options while they're not used as options.
Move them to a dedicated bitmask (ck_opts). This has released 7 flags in the
proxy options and leaves some room for new proxy flags.
2012-05-31 20:40:20 +02:00
Willy Tarreau
196729eff8 BUG/MINOR: fix option httplog validation with TCP frontends
Option httplog needs to be checked only once the proxy has been validated,
so that its final mode (tcp/http) can be used. Also we need to check for
httplog before checking the log format, so that we can report a warning
about this specific option and not about the format it implies.
2012-05-31 19:30:26 +02:00
Willy Tarreau
ab152a7eda BUG/MAJOR: b_rew() must pass a signed offset to b_ptr()
Commit 13e66da introduced b_rew() but passes -adv which is an unsigned
quantity on 64-bit platforms, causing the buffer to advance in the wrong
direction.

No backport is needed.
2012-05-31 11:33:42 +02:00
Oskar Stolc
8dc4184c57 MINOR: balance uri: added 'whole' parameter to include query string in hash calculation
This patch brings a new "whole" parameter to "balance uri" which makes
the hash work over the whole uri, not just the part before the query
string. Len and depth parameter are still honnored.

The reason for this new feature is explained below.

I have 3 backend servers, each accepting different form of HTTP queries:

http://backend1.server.tld/service1.php?q=...
http://backend1.server.tld/service2.php?q=...

http://backend2.server.tld/index.php?query=...&subquery=...

http://backend3.server.tld/image/49b8c0d9ff

Each backend server returns a different response based on either:
- the URI path (the left part of the URI before the question mark)
- the query string (the right part of the URI after the question mark)
- or the combination of both

I wanted to set up a common caching cluster (using 6 Squid servers, each
configured as reverse proxy for those 3 backends) and have HAProxy balance
the queries among the Squid servers based on URL. I also wanted to achieve
hight cache hit ration on each Squid server and send the same queries to
the same Squid servers. Initially I was considering using the 'balance uri'
algorithm, but that would not work as in case of backend2 all queries would
go to only one Squid server. The 'balance url_param' would not work either
as it would send the backend3 queries to only one Squid server.

So I thought the simplest solution would be to use 'balance uri', but to
calculate the hash based on the whole URI (URI path + query string),
instead of just the URI path.
2012-05-22 07:56:54 +02:00
Emeric Brun
d88fd824b7 MEDIUM: protocol: add a pointer to struct sock_ops to the listener struct
The listener struct is now aware of the socket layer to use upon accept().
At the moment, only sock_raw is supported so this patch should not change
anything.
2012-05-21 22:22:39 +02:00
Emeric Brun
21adb02d19 MINOR: stream_interface: add a pointer to the listener for TARG_TYPE_CLIENT
When the target is a client, it will be convenient to have a pointer to the
original listener so that we can retrieve some configuration information at
the stream interface level.
2012-05-21 22:22:39 +02:00
Willy Tarreau
24208275d5 MINOR: stream_interface: add a data channel close function
This function will be called later when splitting the shutdown in two
steps. It will be needed by SSL and for remote socket operations to
release unused contexts.
2012-05-21 17:59:53 +02:00
Willy Tarreau
949811319b REORG/MEDIUM: stream_interface: move applet->state and private to connection
The state and the private pointer are not specific to the applets, since SSL
will require exactly both of them. Move them to the connection layer now and
rename them. We also now ensure that both are NULL on first call.
2012-05-21 17:09:48 +02:00
Willy Tarreau
fb7508aefb REORG/MINOR: stream_interface: move si->fd to struct connection
The socket fd is used only when in socket mode and with a connection.
2012-05-21 16:47:54 +02:00
Willy Tarreau
73b013b070 MINOR: stream_interface: introduce a new "struct connection" type
We start to move everything needed to manage a connection to a special
entity "struct connection". We have the data layer operations and the
control operations there. We'll also have more info in the future such
as file descriptors and applet contexts, so that in the end it becomes
detachable from the stream interface, which will allow connections to
be reused between sessions.

For now on, we start with minimal changes.
2012-05-21 16:31:45 +02:00
Willy Tarreau
9580d16e40 BUG/MAJOR: checks: don't call set_server_status_* when no LB algo is set
David Touzeau reported that haproxy dies when a server is checked and is
used in a farm with only "option transparent" and no LB algo. This is
because the LB params are NULL, the functions should be checked before
being called.

The same bug is present in 1.4 so this patch must be backported.
2012-05-19 19:09:46 +02:00
Willy Tarreau
2692736aa3 MEDIUM: http: get rid of msg->som which is not used anymore
msg->som was zero before the body and was used to carry the beginning
of a chunk size for chunked-encoded messages, at a moment when msg->sol
is always zero.

Remove msg->som and replace it with msg->sol where needed.
2012-05-18 23:50:43 +02:00
Willy Tarreau
09d1e254c9 MAJOR: http: stop using msg->sol outside the parsers
This is a left-over from the buffer changes. Msg->sol is always null at the
end of the parsing, so we must not use it anymore to read headers or find
the beginning of a message. As a side effect, the dump of the request in
debug mode is working again because it was relying on msg->sol not being
null.

Maybe it will even be mergeable with another of the message pointers.
2012-05-18 22:43:55 +02:00
Willy Tarreau
13e66dad26 MINOR: buffers: add a rewind function
b_rew() will be used to rewind a buffer for certain specific operations
such as header inspection on data already in the output queue.
2012-05-18 22:11:27 +02:00
Willy Tarreau
be0688c64d MEDIUM: stream_interface: remove the si->init
Calling the init() function in sess_establish was a bad idea, it is
too late to allow it to fail on lack of resource and does not help at
all. Remove it for now before it's used.
2012-05-18 15:15:26 +02:00
David du Colombier
7af4605ef7 BUG/MAJOR: trash must always be the size of a buffer
Before it was possible to resize the buffers using global.tune.bufsize,
the trash has always been the size of a buffer by design. Unfortunately,
the recent buffer sizing at runtime forgot to adjust the trash, resulting
in it being too short for content rewriting if buffers were enlarged from
the default value.

The bug was encountered in 1.4 so the fix must be backported there.
2012-05-16 14:21:55 +02:00
Willy Tarreau
7bb68abb9f OPTIM/MEDIUM: stream_interface: add a new SI_FL_NOHALF flag
This flag indicates that we're not interested in keeping half-open
connections on a stream interface. It has the benefit of allowing
the socket layer to cause an immediate write close when detecting
an incoming read close. This releases resources much faster and
saves one syscall (either a shutdown or setsockopt).

This flag is only set by HTTP on the interface going to the server
since we don't want to continue pushing data there when it has
closed.

Another benefit is that it responds with a FIN to a server's FIN
instead of responding with an RST as it used to, which is much
cleaner.

Performance gains of 7.5% have been measured on HTTP connection
rate on empty objects.
2012-05-13 14:52:22 +02:00
Willy Tarreau
b147a8382a CLEANUP: fd: remove unused cb->b pointers in the struct fdtab
These pointers were used to hold pointers to buffers in the past, but
since we introduced the stream interface, they're no longer used but
they were still sometimes set.

Removing them shrink the struct fdtab from 32 to 24 bytes on 32-bit machines,
and from 52 to 36 bytes on 64-bit machines, which is a significant saving. A
quick tests shows a steady 0.5% performance gain, probably due to the better
cache efficiency.
2012-05-13 00:35:44 +02:00
Willy Tarreau
3d2f16f3c3 MINOR: standard: add a new debug macro : fddebug()
This macro is usable like printf but sends messages to fd #-1, which has no
visible effect but is easy to spot in strace. This is very useful to put
tracers at many points during debugging sessions.
2012-05-13 00:21:17 +02:00
Willy Tarreau
ce887fd3b2 MEDIUM: session: add support for tunnel timeouts
Tunnel timeouts are used when TCP connections are forwarded, or
when forwarding upgraded HTTP connections (WebSocket) as well as
CONNECT requests to proxies.

This timeout allows long-lived sessions to be supported without
having to set large timeouts to normal requests.
2012-05-12 12:50:00 +02:00
Willy Tarreau
d02394b5a1 MEDIUM: stream_interface: derive the socket operations from the target
Instead of hard-coding sock_raw in connect_server(), we set this socket
operation at config parsing time. Right now, only servers and peers have
it. Proxies are still hard-coded as sock_raw. This will be needed for
future work on SSL which requires a different socket layer.
2012-05-11 18:52:14 +02:00
Willy Tarreau
64798bd720 MINOR: stream_interface: add an init callback to sock_ops
This will be needed for some socket layers such as SSL. It's not used
at the moment.
2012-05-11 18:39:26 +02:00
Willy Tarreau
f873d754f8 CLEANUP: stream_interface: stop exporting socket layer functions
Similarly to the previous patch, we don't need the socket-layer functions
outside of stream_interface. They could even move to a file dedicated to
applets, though that does not seem particularly useful at the moment.
2012-05-11 17:47:17 +02:00
Willy Tarreau
b277d6e568 CLEANUP: sock_raw: remove last references to stream_sock
We also stop exporting all functions since they're not needed anymore outside
of sock_raw.c.
2012-05-11 17:03:42 +02:00
Willy Tarreau
59b9479667 BUG/MEDIUM: stream_interface: restore get_src/get_dst
Commit e164e7a removed get_src/get_dst setting in the stream interfaces but
forgot to set it in proto_tcp. Get the feature back because we need it for
logging, transparent mode, ACLs etc... We now rely on the stream interface
direction to know what syscall to use.

One benefit of doing it this way is that we don't use getsockopt() anymore
on outgoing stream interfaces nor on UNIX sockets.
2012-05-11 16:48:10 +02:00
Willy Tarreau
1539a01645 MINOR: stream_interface: add a client target : TARG_TYPE_CLIENT
This one will be used to identify the direction the SI is being used. All
incoming connections have a target of type TARG_TYPE_CLIENT.
2012-05-11 14:47:34 +02:00
Willy Tarreau
c63190d429 REORG: use the name sock_raw instead of stream_sock
We'll soon have an SSL socket layer, and in order to ease the difference
between the two, we use the name "sock_raw" to designate the one which
directly talks to the sockets without any conversion.
2012-05-11 14:23:52 +02:00
Willy Tarreau
a7fe8e527c MINOR: http: replace http_message_realign() with buffer_slow_realign()
There is no more reason for the realign function being HTTP specific,
it only operates on a buffer now. Let's move it to buffers.c instead.

It's likely that buffer_bounce_realign is broken (not used), this will
have to be inspected. The function is worth rewriting as it can be
cheaper than buffer_slow_realign() to realign large wrapping buffers.
2012-05-08 21:28:17 +02:00
Willy Tarreau
0a3dd74c9c MEDIUM: cfgparse: use the new error reporting framework for remaining cfg_keywords
All keywords registered using a cfg_kw_list now make use of the new error reporting
framework. This allows easier and more precise error reporting without having to
deal with complex buffer allocation issues.
2012-05-08 21:28:17 +02:00
Willy Tarreau
a93c74be5c MEDIUM: cfgparse: make backend_parse_balance() use memprintf to report errors
Using the new error reporting framework makes it easier to report complex
errors.
2012-05-08 21:28:17 +02:00
Willy Tarreau
6e0644339f MEDIUM: memory: add the ability to poison memory at run time
From time to time, some bugs are discovered that are caused by non-initialized
memory areas. It happens that most platforms return a zero-filled area upon
first malloc() thus hiding potential bugs. This patch also replaces malloc()
in pools with calloc() to ensure that all platforms exhibit the same behaviour
upon startup. In order to catch these bugs more easily, add a -dM command line
flag to enable memory poisonning. Optionally, passing -dM<byte> forces the
poisonning byte to <byte>.
2012-05-08 21:28:16 +02:00
Willy Tarreau
d04b1bce69 MEDIUM: http: improve error capture reports
A number of important information were missing from the error captures, so
let's improve them. Now we also log source port, session flags, transaction
flags, message flags, pending output bytes, expected buffer wrapping position,
total bytes transferred, message chunk length, and message body length.

As such, the output format has slightly evolved and the source address moved
to the third line :

[08/May/2012:11:14:36.341] frontend echo (#1): invalid request
  backend echo (#1), server <NONE> (#-1), event #1
  src 127.0.0.1:40616, session #4, session flags 0x00000000
  HTTP msg state 26, msg flags 0x00000000, tx flags 0x00000000
  HTTP chunk len 0 bytes, HTTP body len 0 bytes
  buffer flags 0x00909002, out 0 bytes, total 28 bytes
  pending 28 bytes, wrapping at 8030, error at position 7:

  00000  GET / /?t=20000 HTTP/1.1\r\n
  00026  \r\n

[08/May/2012:11:13:13.426] backend echo (#1) : invalid response
  frontend echo (#1), server local (#1), event #0
  src 127.0.0.1:40615, session #1, session flags 0x0000044e
  HTTP msg state 32, msg flags 0x0000000e, tx flags 0x08200000
  HTTP chunk len 0 bytes, HTTP body len 20 bytes
  buffer flags 0x00008002, out 81 bytes, total 92 bytes
  pending 11 bytes, wrapping at 7949, error at position 9:

  00000  Foo: bar\r\r\n
2012-05-08 21:28:16 +02:00
Willy Tarreau
bbebbbff83 REORG/MEDIUM: move the default accept function from sockstream to protocols.c
The previous sockstream_accept() function uses nothing from sockstream, and
is totally irrelevant to stream interfaces. Move this to the protocols.c
file which handles listeners and protocols, and call it listener_accept().

It now makes much more sense that the code dealing with listen() also handles
accept() and passes it to upper layers.
2012-05-08 21:28:15 +02:00
Willy Tarreau
26d8c59f0b REORG/MEDIUM: replace stream interface protocol functions by a proto pointer
The stream interface now makes use of the socket protocol pointer instead
of the direct functions.
2012-05-08 21:28:15 +02:00
Willy Tarreau
5c979a9c71 REORG/MEDIUM: stream_interface: initialize socket ops from descriptors 2012-05-08 21:28:14 +02:00
Willy Tarreau
1b79bdee26 REORG/MEDIUM: move protocol->{read,write} to sock_ops
The protocol must not set the read and write callbacks, they're specific
to the socket layer. Move them to sock_ops instead.
2012-05-08 21:28:14 +02:00
Willy Tarreau
060781fb4a REORG: stream_interface: create a struct sock_ops to hold socket operations
These operators are used regardless of the socket protocol family. Move
them to a "sock_ops" struct. ->read and ->write have been moved there too
as they have no reason to remain at the protocol level.
2012-05-08 21:28:14 +02:00
Willy Tarreau
ceb4ac9c34 MEDIUM: acl: support IPv6 address matching
Make use of the new IPv6 pattern type so that acl_match_ip() knows how to
compare pattern and sample.

IPv6 may be entered in their usual form, with or without a netmask appended.
Only bit counts are accepted for IPv6 netmasks. In order to avoid any risk of
trouble with randomly resolved IP addresses, host names are never allowed in
IPv6 patterns.

HAProxy is also able to match IPv4 addresses with IPv6 addresses in the
following situations :
  - tested address is IPv4, pattern address is IPv4, the match applies
    in IPv4 using the supplied mask if any.
  - tested address is IPv6, pattern address is IPv6, the match applies
    in IPv6 using the supplied mask if any.
  - tested address is IPv6, pattern address is IPv4, the match applies in IPv4
    using the pattern's mask if the IPv6 address matches with 2002:IPV4::,
    ::IPV4 or ::ffff:IPV4, otherwise it fails.
  - tested address is IPv4, pattern address is IPv6, the IPv4 address is first
    converted to IPv6 by prefixing ::ffff: in front of it, then the match is
    applied in IPv6 using the supplied IPv6 mask.
2012-05-08 21:28:14 +02:00
Willy Tarreau
6d20e28556 MINOR: standard: add an IPv6 parsing function (str62net)
str62net returns an address and a netmask in number of bits.
2012-05-08 20:57:21 +02:00
Willy Tarreau
c92ddbc37d MINOR: acl: add types to ACL patterns
We cannot currently match IPv6 addresses in ACL simply because we don't
support types on the patterns. Let's introduce this notion. For now, we
rely on the SMP_TYPES though it doesn't seem like it will last forever
given that some types are not present there (eg: regex, meth). Still it
should be enough to support mixed matchings for most types.

We use the special impossible value SMP_TYPES for types that don't exist
in the SMP_T_* space.
2012-05-08 20:57:21 +02:00
Willy Tarreau
cd3b094618 REORG: rename "pattern" files
They're now called "sample" everywhere to match their description.
2012-05-08 20:57:21 +02:00
Willy Tarreau
1278578487 REORG: use the name "sample" instead of "pattern" to designate extracted data
This is mainly a massive renaming in the code to get it in line with the
calling convention. Next patch will rename a few files to complete this
operation.
2012-05-08 20:57:20 +02:00
Willy Tarreau
7dcb6480db MEDIUM: acl: extend the pattern parsers to report meaningful errors
By passing the error pointer to all ACL parsers, we can make them report
useful errors and not simply fail.
2012-05-08 20:57:20 +02:00
Willy Tarreau
b7451bb660 MEDIUM: acl: report parsing errors to the caller
All parsing errors were known but impossible to return. Now by making use
of memprintf(), we're able to build meaningful error messages that the
caller can display.
2012-05-08 20:57:20 +02:00
Willy Tarreau
185b5c4a7b MEDIUM: http: merge acl and pattern header fetch functions
HTTP header fetch is now done using smp_fetch_hdr() for both ACLs and
patterns. This one also supports an occurrence number, making it possible
to specify explicit occurrences for ACLs and patterns.
2012-05-08 20:57:19 +02:00
Willy Tarreau
ae52f06da3 MINOR: acl: add a val_args field to keywords
This will make it possible to delegate argument validating to functions
shared with smp_fetch_*.
2012-05-08 20:57:19 +02:00
Willy Tarreau
7a777edbdf MINOR: acl: set SMP_OPT_ITERATE on fetch functions
This way, fetch functions will be able to tell if they're called for a single
request or as part of a loop. This is important for instance when we use
hdr(foo), because in an ACL this means that all hdr(foo) occurrences must
be checked while in a pattern it means only one of them (eg: last one).
2012-05-08 20:57:18 +02:00
Willy Tarreau
32a6f2e572 MEDIUM: acl/pattern: use the same direction scheme
Patterns were using a bitmask to indicate if request or response was desired
in fetch functions and keywords. ACLs were using a bitmask in fetch keywords
and a single bit in fetch functions. ACLs were also using an ACL_PARTIAL bit
in fetch functions indicating that a non-final fetch was performed, which was
an abuse of the existing direction flag.

The change now consists in using :
  - a capabilities field for fetch keywords => SMP_CAP_REQ/RES to indicate
    if a keyword supports requests, responses, both, etc...
  - an option field for fetch functions to indicate what the caller expects
    (request/response, final/non-final)

The ACL_PARTIAL bit was reversed to get SMP_OPT_FINAL as it's more explicit
to know we're working on a final buffer than on a non-final one.

ACL_DIR_* were removed, as well as PATTERN_FETCH_*. L4 fetches were improved
to support being called on responses too since they're still available.

The <dir> field of all fetch functions was changed to <opt> which is now
unsigned.

The patch is large but mostly made of cosmetic changes to accomodate this, as
almost no logic change happened.
2012-05-08 20:57:17 +02:00
Willy Tarreau
24e32d8c6b MEDIUM: acl: replace acl_expr with args in acl fetch_* functions
Having the args everywhere will make it easier to share fetch functions
between patterns and ACLs. The only place where we could have needed
the expr was in the http_prefetch function which can do well without.
2012-05-08 20:57:16 +02:00
Willy Tarreau
32389b7d04 MEDIUM: acl/pattern: switch rdp_cookie functions stack up-down
Previously, both pattern, backend and persist_rdp_cookie would build fake
ACL expressions to fetch an RDP cookie by calling acl_fetch_rdp_cookie().

Now we switch roles. The RDP cookie fetch function is provided as a sample
fetch function that all others rely on, including ACL. The code is exactly
the same, only the args handling moved from expr->args to args. The code
was moved to proto_tcp.c, but probably that a dedicated file would be more
suited to content handling.
2012-05-08 20:57:16 +02:00
Willy Tarreau
342acb4775 MEDIUM: pattern: integrate pattern_data into sample and use sample everywhere
Now there is no more reference to union pattern_data. All pattern fetch and
conversion functions now make use of the common sample type. Note: none of
them adjust the type right now so it's important to do it next otherwise
we would risk sharing such functions with ACLs and seeing them fail.
2012-05-08 20:57:15 +02:00
Willy Tarreau
b4a88f0672 MINOR: pattern: replace struct pattern with struct sample
This change is pretty minor. Struct pattern is only used for
pattern_process() now so changing it to use the common type is
quite obvious. It's worth noting that the last argument of
pattern_process() is never used so the function is self-sufficient.

Note that pattern_process() does not initialize the pattern at all
before calling fetch->process(), and that minimal initialization
will be required when we later change the argument for the sample.
2012-05-08 20:57:15 +02:00
Willy Tarreau
21e5b0e3cb MEDIUM: get rid of SMP_F_READ_ONLY and SMP_F_MUST_FREE
These ones were either unused or improperly used. Some integers were marked
read-only, which does not make much sense. Buffers are not read-only, they're
"constant" in that they must be kept intact after any possible change.
2012-05-08 20:57:15 +02:00
Willy Tarreau
197e10aaae MEDIUM: acl: get rid of the SET_RES flags
We now simply rely on a boolean result from a fetch to declare a match.
Booleans are not compared against patterns, they fix the result.
2012-05-08 20:57:15 +02:00
Willy Tarreau
f853c46bc3 MEDIUM: pattern/acl: get rid of temp_pattern in ACLs
This one is not needed anymore as we can return the data and its type in the
sample provided by the caller. ACLs now always return the proper type. BOOL
is already returned when the result is expected to be processed as a boolean.

temp_pattern has been unexported now.
2012-05-08 20:57:14 +02:00
Willy Tarreau
3740635b88 MAJOR: acl: make use of the new sample struct and get rid of acl_test
This change is invasive in lines of code but not much in terms of
functionalities as it's mainly a replacement of struct acl_test
with struct sample.
2012-05-08 20:57:14 +02:00
Willy Tarreau
422aa0792d MEDIUM: pattern: add new sample types to replace pattern types
The new sample types are necessary for the acl-pattern convergence.
These types are boolean and signed int. Some types were renamed for
less ambiguity (ip->ipv4, integer->uint).
2012-05-08 20:57:14 +02:00
Willy Tarreau
16c31b00dc MINOR: pattern: add a new 'sample' type to store fetched data
The pattern type is ambiguous because a pattern is only a type and a data
part, and is normally used to match against samples. Currently, patterns
cannot hold information related to the life of the data which was extracted.
We don't want to overload patterns either, so let's add a new "sample" type
which will progressively supersede the acl_test and maybe the pattern at most
places. The sample shares similar information with patterns and also has flags
describing the data volatility and protection.
2012-05-08 20:57:13 +02:00
Willy Tarreau
8f7406e9b4 MEDIUM: acl: remove the ACL_TEST_F_NULL_MATCH flag
This flag was used to force a boolean match even if there was no pattern
to match. It was used only by http_auth() and designed only for this one.
It's easier and cleaner to make the fetch function perform the test and
report the boolean result as a few other functions already do. It simplifies
the acl_exec_cond() logic and will help merging ACLs and patterns.
2012-05-08 20:57:13 +02:00
Willy Tarreau
21d68a6895 MEDIUM: pattern: add an argument validation callback to pattern descriptors
This is used to validate that arguments are coherent. For instance,
payload_lv expects that the last arg (if any) is not more negative
than the sum of the first two. The error is reported if any.
2012-05-08 20:57:13 +02:00
Willy Tarreau
9fcb984b17 MEDIUM: pattern: use the standard arg parser
We don't need the pattern-specific args parsers anymore, make use of the
common parser instead. We still need to improve this by adding a validation
function to report abnormal argument values or combinations. We don't report
precise parsing errors yet but this was not previously done either.
2012-05-08 20:57:13 +02:00
Willy Tarreau
f995410355 MEDIUM: pattern: get rid of arg_i in all functions making use of arguments
arg_i was almost unused, and since we migrated to use struct arg everywhere,
the rare cases where arg_i was needed could be replaced by switching to
arg->type = ARGT_STOP.
2012-05-08 20:57:12 +02:00
Willy Tarreau
ecfb8e8ff9 MEDIUM: pattern: replace type pattern_arg with type arg
arg is more complete than pattern_arg since it also covers ACL args,
so let's use this one instead.
2012-05-08 20:57:12 +02:00
Willy Tarreau
61612d49a7 MAJOR: acl: store the ACL argument types in the ACL keyword declaration
The types and minimal number of ACL keyword arguments are now stored in
their declaration. This will allow many more fantasies if some ACL use
several arguments or types.

Doing so required to rework all ACL keyword declarations to add two
parameters. So this was a good opportunity for a general cleanup and
to sort all entries in alphabetical order.

We still have two pending issues :
  - parse_acl_expr() checks for errors but has no way to report them to
    the user ;
  - the types of some arguments are still not resolved and kept as strings
    (eg: ARGT_FE/BE/TAB) for compatibility reasons, which must be resolved
    in acl_find_targets()
2012-05-08 20:57:11 +02:00
Willy Tarreau
34db108423 MAJOR: acl: make use of the new argument parsing framework
The ACL parser now uses the argument parser to build a typed argument list.
Right now arguments are all strings and only one argument is supported since
this is what ACLs currently support.
2012-05-08 20:57:11 +02:00
Willy Tarreau
2ac5718dbd MEDIUM: add a new typed argument list parsing framework
make_arg_list() builds an array of typed arguments with their values,
that the caller describes how to parse. This will be used to support
multiple arguments for ACLs and patterns, which is currently problematic
and prevents ACLs and patterns from being merged. Up to 7 arguments types
may be enumerated in a single 32-bit word, including their number of
mandatory parts.

At the moment, these files are not used yet, they're only built. Note that
the 4-bit encoding for the type has left only one unused type!
2012-05-08 20:57:10 +02:00
Willy Tarreau
9dab5fc4d4 MEDIUM: buffers: rename a number of buffer management functions
The following renaming took place :
1) buffer input functions
  buffer_put_block => bi_putblk
  buffer_put_char => bi_putchr
  buffer_put_string => bi_putstr
  buffer_put_chunk => bi_putchk
  buffer_feed => bi_putstr
  buffer_feed_chunk => bi_putchk
  buffer_cut_tail => bi_erase
  buffer_ignore => bi_fast_delete

2) buffer output functions
  buffer_get_char => bo_getchr
  buffer_get_line => bo_getline
  buffer_get_block => bo_getblk
  buffer_skip => bo_skip
  buffer_write => bo_inject

3) buffer input avail/full functions were introduced :
  bi_avail
  bi_full
2012-05-08 20:56:56 +02:00
Willy Tarreau
328582c3f9 MEDIUM: buffers: implement b_adv() to advance a buffer's pointer
This is more convenient and efficient than buf->p = b_ptr(buf, n);
It simply advances the buffer's pointer by <n> and trasfers that
amount of bytes from <in> to <out>. The BF_OUT_EMPTY flag is updated
accordingly.

A few occurrences of such computations in buffers.c and stream_sock.c
were updated to use b_adv(), which resulted in a small code shrink.
2012-05-08 12:28:14 +02:00
Willy Tarreau
cc5cfcbcce MEDIUM: buffers: add new pointer wrappers and get rid of almost all buffer_wrap_add calls
buffer_wrap_add was convenient for the migration but is not handy at all.
Let's have new wrappers that report input begin/end and output begin/end
instead.

It looks like we'll also need a b_adv(ofs) to advance a buffer's pointer.
2012-05-08 12:28:14 +02:00
Willy Tarreau
ec1bc82a1d MEDIUM: buffers: fix unsafe use of buffer_ignore at some places
buffer_ignore may only be used when the output of a buffer is empty,
but it's not granted it is always the case when sending HTTP error
responses. Better use buffer_cut_tail() instead, and use buffer_ignore
only on non-wrapping data.
2012-05-08 12:28:14 +02:00
Willy Tarreau
8a0cef2dad MEDIUM: http: remove buffer arg in http_capture_bad_message
The buffer pointer is now taken from the http_msg.
2012-05-08 12:28:13 +02:00
Willy Tarreau
45c0d98769 MEDIUM: http: http_send_name_header: remove references to msg and buffer
They can be deduced from txn.
2012-05-08 12:28:12 +02:00
Willy Tarreau
3a215bedba MAJOR: http: make http_msg->sol relative to buffer's origin
msg->sol is now a relative pointer just like all other ones. There is no
more absolute references to the buffer outside the struct buffer itself.

Next two cleanups should include removing buffer references to functions
which already have an msg, and removal of wrapping detection in request
and response parsing which cannot wrap by definition.
2012-05-08 12:28:12 +02:00
Willy Tarreau
62f791ea6f MEDIUM: http: add a pointer to the buffer in http_msg
ACLs and patterns only rely on a struct http_msg and don't know the pointer
to the actual data. struct http_msg will soon only hold relative references
so that's not possible. We need http_msg to hold a reference to the struct
buffer before having relative pointers everywhere.

It is likely that doing so will also result in opportunities to simplify
a number of functions arguments. The following functions are already
candidate :

	http_buffer_heavy_realign
	http_capture_bad_message
	http_change_connection_header
	http_forward_trailers
	http_header_add_tail
	http_header_add_tail2
	http_msg_analyzer
	http_parse_chunk_size
	http_parse_connection_header
	http_remove_header2
	http_send_name_header
	http_skip_chunk_crlf
	http_upgrade_v09_to_v10
2012-05-08 12:28:12 +02:00
Willy Tarreau
12e48b36dd MAJOR: http: turn http_msg->eol to a buffer-relative offset
It was an absolute pointer to the buffer's data, now it's a pointer relative
to the buffer's origin.
2012-05-08 12:28:12 +02:00
Willy Tarreau
fa4a03ca08 CLEANUP: http: remove unused http_msg->col
The <col> element of the struct http_msg has not been used for a long
time now, remove it.
2012-05-08 12:28:11 +02:00
Willy Tarreau
ea1175a687 MAJOR: http: change msg->{som,col,sov,eoh} to be relative to buffer origin
These offsets were relative to the buffer itself. Now they're relative to
the buffer's origin (buf->p) which normally corresponds to the start of
current message.

This saves a big dependency between the HTTP message struct and the buffers.
It appeared during this change that ->col is not used anymore (it will have
to be removed). Next step is to turn ->eol and ->sol from absolute to relative.
2012-05-08 12:28:11 +02:00
Willy Tarreau
a458b67965 MAJOR: http: move buffer->lr to http_msg->next
The buffer's pointer <lr> was only used by HTTP parsers which also use a
struct http_msg to keep track of the parser's state. We've reached a point
where it makes no sense to keep ->lr in the buffer, as the split between
buffer and msg is only arbitrary for historical reasons.

This change ensures that touching buffers will not impact HTTP messages
anymore, making the buffers more content-agnostic. However, it becomes
very important not to forget to update msg->next when some data get
forwarded or moved (and in general each time buf->p is updated).

The new pointer in http_msg becomes relative to buffer->p so that
parsing multiple messages becomes easier. It is possible that at one
point ->som and ->next will be merged.

Note: http_parse_reqline() and http_parse_stsline() have been temporarily
modified to know the message starting point in the buffer (->p).
2012-05-08 12:28:11 +02:00
Willy Tarreau
363a5bb152 MAJOR: buffers: replace buf->r with buf->p + buf->i
This change gets rid of buf->r which is always equal to buf->p + buf->i.
It removed some wrapping detection at a number of places, but required addition
of new relative offset computations at other locations. A large number of places
can be simplified now with extreme care, since most of the time, either the
pointer has to be computed once or we need a difference between the old ->w and
old ->r to compute free space. The cleanup will probably happen with the rewrite
of the buffer_input_* and buffer_output_* functions anyway.

buf->lr still has to move to the struct http_msg and be relative to buf->p
for the rework to be complete.
2012-05-08 12:28:11 +02:00
Willy Tarreau
89fa706d39 MAJOR: buffers: replace buf->w with buf->p - buf->o
This change introduces the buffer's base pointer, which is the limit between
incoming and outgoing data. It's the point where the parsing should start
from. A number of computations have already been greatly simplified, but
more simplifications are expected to come from the removal of buf->r.

The changes appear good and have revealed occasional improper use of some
pointers. It is possible that this patch has introduced bugs or revealed
some, although preliminary testings tend to indicate that everything still
works as it should.
2012-05-08 12:28:10 +02:00
Willy Tarreau
3f7ff1406c MINOR: buffers: remove unused function buffer_contig_data()
This one was never used and is buggy. It will be easier to rewrite
it when the buffer rework is complete.
2012-05-08 12:28:10 +02:00
Willy Tarreau
7fd758bbcf MINOR: buffers: provide simple pointer normalization functions
Add buffer_wrap_sub() and buffer_wrap_add() to normalize buffer pointers
after an addition or subtract.
2012-05-08 12:28:10 +02:00
Willy Tarreau
02d6cfc1d7 MAJOR: buffer: replace buf->l with buf->{o+i}
We don't have buf->l anymore. We have buf->i for pending data and
the total length is retrieved by adding buf->o. Some computation
already become simpler.

Despite extreme care, bugs are not excluded.

It's worth noting that msg->err_pos as set by HTTP request/response
analysers becomes relative to pending data and not to the beginning
of the buffer. This has not been completed yet so differences might
occur when outgoing data are left in the buffer.
2012-05-08 12:28:10 +02:00
Willy Tarreau
2e046c6017 MAJOR: buffer rework: replace ->send_max with ->o
This is the first minor step of the buffer rework. It's only renaming,
it should have no impact.
2012-04-30 11:57:00 +02:00
Willy Tarreau
a36fc4d7ed MEDIUM: move message-related flags from transaction to message
Too many flags are stored in the transaction structure. Some flags are
clearly message-specific and exist in two versions (request and response).
Move them to a new "flags" field in the http_message struct instead.
2012-04-30 11:57:00 +02:00
Willy Tarreau
9a7bea52b1 MINOR: standard: add a memprintf() function to build formatted error messages
memprintf() is just like snprintf() except that it always returns a properly
sized allocated string that the caller is responsible for freeing. NULL is
returned on serious errors. It also supports stackable calls over the same
pointer since it offers support for automatically freeing a previous one :

     memprintf(&err, "invalid argument: '%s'", arg);
     ...
     memprintf(&err, "keyword parser said: <%s>", *err);
     ...
     memprintf(&err, "line parser said: %s\n", *err);
     ...
     free(*err);
2012-04-30 11:55:35 +02:00
Willy Tarreau
3fb818c014 BUILD: http: make extract_cookie_value() return an int not size_t
It's very annoying that we have to deal with the crappy size_t and with ints
at some places because these ones don't mix well. Patch 6f61b2 changed the
chunk len to int but its size remains size_t and some functions are having
trouble being used by several callers depending on the type of their arguments.

Let's turn extract_cookie_value() to int for now on, and plan a massive cleanup
later to remove all size_t.
2012-04-30 00:19:28 +02:00
Willy Tarreau
9b061e3320 MEDIUM: stream_sock: add a get_src and get_dst callback and remove SN_FRT_ADDR_SET
These callbacks are used to retrieve the source and destination address
of a socket. The address flags are not hold on the stream interface and
not on the session anymore. The addresses are collected when needed.

This still needs to be improved to store the IP and port separately so
that it is not needed to perform a getsockname() when only the IP address
is desired for outgoing traffic.
2012-04-07 18:03:52 +02:00
William Lallemand
5e19a2866f MINOR: log: log-format: usable without httplog and tcplog
Options httplog and tcplog aren't mandatory anymore for the log-format.
The LW_ flags are now set during the log-format string parsing.
2012-04-07 16:25:26 +02:00
William Lallemand
a73203e3dc MEDIUM: log: Unique ID
The Unique ID, is an ID generated with several informations. You can use
a log-format string to customize it, with the "unique-id-format" keyword,
and insert it in the request header, with the "unique-id-header" keyword.
2012-04-07 16:25:26 +02:00
William Lallemand
5f2324019d MEDIUM: log: New format-log flags: %Fi %Fp %Si %Sp %Ts %rt %H %pid
%Fi: Frontend IP
%Fp: Frontend Port
%Si: Server IP
%Sp: Server Port
%Ts: Timestamp
%rt: HTTP request counter
%H: hostname
%pid: PID

+X: Hexadecimal represenation

The +X mode in logformat displays hexadecimal for the following flags
%Ci %Cp %Fi %Fp %Bi %Bp %Si %Sp %Ts %ct %pid

rename logformat_write_string() to lf_text()

Optimize size computation
2012-04-07 16:05:39 +02:00
William Lallemand
1d7055675e MEDIUM: log: split of log_format generation
* logformat functions now take a format linked list as argument
* build_logline() build a logline using a format linked list
* rename LOG_* by LOG_FMT_* in enum
* improve error management in build_logline()
2012-04-07 16:05:02 +02:00
Aman Gupta
0bc0c2426c MINOR: Add TO/FROM_SET flags to struct stream_interface
[WT: it will make sense to remove SN_FRT_ADDR_SET and to use these
  flags everywhere instead ]
2012-04-07 09:17:26 +02:00
Willy Tarreau
c89ccb6221 MEDIUM: log: add a new cookie flag 'U' to report situations where cookie is not used
This happens when a "use-server" rule sets the server instead.
2012-04-05 21:18:22 +02:00
Willy Tarreau
4a5cadea40 MEDIUM: session: implement the "use-server" directive
Sometimes it is desirable to forward a particular request to a specific
server without having to declare a dedicated backend for this server. This
can be achieved using the "use-server" rules. These rules are evaluated after
the "redirect" rules and before evaluating cookies, and they have precedence
on them. There may be as many "use-server" rules as desired. All of these
rules are evaluated in their declaration order, and the first one which
matches will assign the server.
2012-04-05 21:14:10 +02:00
Aman Gupta
9a13e84cc2 MINOR: Add release callback to si_applet 2012-04-05 10:39:20 +02:00
Cyril Bonté
19979e176e MINOR: stats admin: reduce memcmp()/strcmp() calls on status codes
memcmp()/strcmp() calls were needed in different parts of code to determine
the status code. Each new status code introduces new calls, which can become
inefficient and source of bugs.
This patch reorganizes the code to rely on a numeric status code internally
and to be hopefully more generic.
2012-04-05 09:58:27 +02:00
Cyril Bonté
cf8d9ae3cd MINOR: stats admin: allow unordered parameters in POST requests
Previously, the stats admin page required POST parameters to be provided
exactly in the same order as the HTML form.
This patch allows to handle those parameters in any orders.

Also, note that haproxy won't alter server states anymore if backend or server
names are ambiguous (duplicated names in the configuration) to prevent
unexpected results (the same should probably be applied to the stats socket).
2012-04-05 09:58:25 +02:00
Simon Horman
b7cd8f9a3a CLEANUP: Fix HCHK spelling errors 2012-03-24 21:54:25 +01:00
Simon Horman
63a4a822c1 CLEANUP: Make check_statuses, analyze_statuses and process_chk static
These symbols are only used inside src/checks.c
2012-03-24 21:54:19 +01:00
Willy Tarreau
b1a2faf7c9 BUG/CRITICAL: log: fix risk of crash in development snapshot
Commit a1cc38 introduced a regression which was easy to trigger till ad4cd58
(snapshots 20120222 to 20120311 included). The bug was still present after
that but harder to trigger.

The bug is caused by the use of two distinct log buffers due to intermediary
changes. The issue happens when an HTTP request is logged just after a TCP
request during the same second and the HTTP request is too large for the buffer.
In this case, it happens that the HTTP request is logged into the TCP buffer
instead and that length controls can't detect anything.

Starting with bddd4f, the issue is still possible when logging too large an
HTTP request just after a send_log() call (typically a server status change).

We owe a big thanks to Sander Klein for testing several snapshots and more
specifically for taking significant risks in production by letting the buggy
version crash several times in order to provide an exploitable core ! The bug
could not have been found without this precious help. Thank you Sander !

This fix does not need to be backported, it did not affect any released version.
2012-03-19 17:09:30 +01:00
Willy Tarreau
6580c06ba3 MINOR: log: use "%ts" to log term status only and "%tsc" to log with cookie
The difference could be seen when logging a request in HTTP mode with option
tcplog, as it would keep emitting 4 chars. Better use two distinct flags to
clear the confusion.
2012-03-12 15:50:53 +01:00
William Lallemand
81f5117a24 BUG/MINOR: log-format: fix %o flag
The %o flag was not working at all.
2012-03-12 15:50:53 +01:00
William Lallemand
b7ff6a3a36 MEDIUM: log-format: backend source address %Bi %Bp
%Bi return the backend source IP
%Bp return the backend source port

Add a function pointer in logformat_type to do additional configuration
during the log-format variable parsing.
2012-03-12 15:50:52 +01:00
William Lallemand
bddd4fd93b MEDIUM: log: use log_format for mode tcplog
Merge http_sess_log() and tcp_sess_log() to sess_log() and move it to
log.c

A new field in logformat_type define if you can use a logformat
variable in TCP or HTTP mode.

doc: log-format in tcp mode

Note that due to the way log buffer allocation currently works, trying to
log an HTTP request without "option httplog" is still not possible. This
will change in the near future.
2012-03-12 15:47:13 +01:00
Willy Tarreau
18dd41dc46 MINOR: buffer: switch a number of buffer args to const
A number of offset computation functions use struct buffer* arguments
and return integers without modifying the input. Using consts helps
simplifying some operations in callers.
2012-03-10 08:55:07 +01:00
Willy Tarreau
f09c6603d3 MEDIUM: backend: add the 'first' balancing algorithm
The principle behind this load balancing algorithm was first imagined
and modeled by Steen Larsen then iteratively refined through several
work sessions until it would totally address its original goal.

The purpose of this algorithm is to always use the smallest number of
servers so that extra servers can be powered off during non-intensive
hours. Additional tools may be used to do that work, possibly by
locally monitoring the servers' activity.

The first server with available connection slots receives the connection.
The servers are choosen from the lowest numeric identifier to the highest
(see server parameter "id"), which defaults to the server's position in
the farm. Once a server reaches its maxconn value, the next server is used.
It does not make sense to use this algorithm without setting maxconn. Note
that it can however make sense to use minconn so that servers are not used
at full load before starting new servers, and so that introduction of new
servers requires a progressively increasing load (the number of servers
would more or less follow the square root of the load until maxconn is
reached). This algorithm ignores the server weight, and is more beneficial
to long sessions such as RDP or IMAP than HTTP, though it can be useful
there too.
2012-02-21 22:27:27 +01:00
Willy Tarreau
3ebb1163ba MINOR: backend: rework the LC definition to support other connection-based algos
The leastconn algorithm should be of kind "connection-based", not "leastconn"
if we want to later support other connection-based LB algos.
2012-02-13 17:02:31 +01:00
William Lallemand
a1cc381151 MEDIUM: log: make http_sess_log use log_format
http_sess_log now use the logformat linked list to make the log
string, snprintf is not used for speed issue.

CLF mode also uses logformat.

NOTE: as of now, empty fields in CLF now are "" not "-" anymore.
2012-02-09 17:03:28 +01:00
William Lallemand
421f5b5882 MINOR: Date and time fonctions that don't use snprintf
Also move human_time() to standard.c since it's not related to
timeval calculations.
2012-02-09 17:03:28 +01:00
William Lallemand
e7340ec111 MINOR: add ultoa, ulltoa, ltoa, lltoa implementations
Implementations that write result from left to right
2012-02-09 17:03:28 +01:00
William Lallemand
723b73ad75 MINOR: config: Parse the string of the log-format config keyword
parse_logformat_string: parse the string, detect the type: text,
        separator or variable

parse_logformat_var: dectect variable name

parse_logformat_var_args: parse arguments and flags

add_to_logformat_list: add to the logformat linked list
2012-02-09 17:03:24 +01:00
William Lallemand
2a4a44f0f9 REORG: log: split send_log function
send_log function is now splited in 3 functions
* hdr_log: generate the syslog header
* send_log: send a syslog message with a printf format string
* __send_log: send a syslog message
2012-02-09 15:54:43 +01:00
Willy Tarreau
f8e8b76ed3 BUG/MEDIUM: zero-weight servers must not dequeue requests from the backend
It was reported that a server configured with a zero weight would
sometimes still take connections from the backend queue. This issue is
real, it happens this way :
  1) the disabled server accepts a request with a cookie
  2) many cookie-less requests accumulate in the backend queue
  3) when the disabled server completes its request, it checks its own
     queue and the backend's queue
  4) the server takes a pending request from the backend queue and
     processes it. In response, the server's cookie is assigned to
     the client, which ensures that some requests will continue to
     be served by this server, leading back to point 1 above.

The fix consists in preventing a zero-weight server from dequeuing pending
requests from the backend. Making use of srv_is_usable() in such tests makes
the tests more robust against future changes.

This fix must be backported to 1.4 and 1.3.
2012-01-20 16:18:53 +01:00
Willy Tarreau
62c3be28ed BUG/MEDIUM: correctly disable servers tracking another disabled servers.
In a config where server "s1" is marked disabled and "s2" tracks "s1",
s2 appears disabled on the stats but is still inserted into the LB farm
because the tracking is resolved too late in the configuration process.

We now resolve tracked servers before building LB maps and we also mark
the tracking server in maintenance mode, which previously was not done,
causing half of the issue.

Last point is that we also protect srv_is_usable() against electing a
server marked for maintenance. This is not absolutely needed but is a
safe choice and makes a lot of sense.

This fix must be backported to 1.4.
2012-01-20 16:18:30 +01:00
Mark Lamourine
c2247f0b8d MEDIUM: http: add support for sending the server's name in the outgoing request
New option "http-send-name-header" specifies the name of a header which
will hold the server name in outgoing requests. This is the name of the
server the connection is really sent to, which means that upon redispatches,
the header's value is updated so that it always matches the server's name.
2012-01-05 15:17:31 +01:00
Willy Tarreau
294c473756 MEDIUM: http: replace get_ip_from_hdr2() with http_get_hdr()
The new function does not return IP addresses but header values instead,
so that the caller is free to make what it want of them. The conversion
is not quite clean yet, as the previous test which considered that address
0.0.0.0 meant "no address" is still used. A different IP parsing function
should be used to take this into account.
2011-12-30 17:33:26 +01:00
Willy Tarreau
aff79da207 CLEANUP: acl: remove last data fields from the acl_test struct
acl_test doesn't hold ptr nor len anymore, since everything has moved to
the temporary pattern.
2011-12-30 17:33:26 +01:00
Willy Tarreau
31d1b01211 CLEANUP: acl: integer part of acl_test is not used anymore 2011-12-30 17:33:26 +01:00
Willy Tarreau
b666bc7d51 MEDIUM: pattern: change the pattern data integer from unsigned to signed
Till now the pattern data integer type was unsigned without any
particular reason. In order to make ACLs use it, we must switch it
to signed int instead.
2011-12-30 17:33:25 +01:00
Willy Tarreau
918458439e MINOR: acl: include pattern.h to make pattern migration more transparent 2011-12-30 17:33:25 +01:00
Willy Tarreau
5e6cc4aad8 MINOR: pattern: export the global temporary pattern
The global pattern is used for pattern conversions. Export it under the
name "temp_pattern" so that it can later be used by ACLs.
2011-12-30 17:33:25 +01:00
Willy Tarreau
f3bfede52e CLEANUP: ebtree: clarify licence and update to 6.0.6
(from ebtree 6.0.6)

This version is mainly aimed at clarifying the fact that the ebtree license
is LGPL. Some files used to indicate LGPL and other ones GPL, while the goal
clearly is to have it LGPL. A LICENSE file has also been added.

No code is affected, but it's better to have the local tree in sync anyway.

(cherry picked from commit 24dc7cca051f081600fe8232f33e55ed30e88425)
2011-12-02 17:09:49 +01:00
Willy Tarreau
19ae56b2b6 CLEANUP: kill buffer_replace() and use an inline instead
This function is never used, only its buffer_replace2() alternative
is used. Replace the former with an inline which calls the later.
2011-11-28 21:01:28 +01:00
Willy Tarreau
71730256a3 MINOR: buffers: make buffer_pointer() support negative pointers too
It's more handy if the buffer_pointer() function also handles negative pointers.
2011-11-28 21:00:46 +01:00
Willy Tarreau
fe4b1f9dc0 BUG: buffers: don't return a negative value on buffer_total_space_res()
In commit 4b517ca93a (MEDIUM: buffers:
add some new primitives and rework existing ones), we forgot to check
if buffer_max_len() < l.

No backport is needed.
2011-11-28 21:00:46 +01:00
Willy Tarreau
4b517ca93a MEDIUM: buffers: add some new primitives and rework existing ones
A number of primitives were missing for buffer management, and some
of them were particularly awkward to use. Specifically, the functions
used to compute free space could not always be used depending what was
wrapping in the buffers. Some documentation has been added about how
the buffers work and their properties. Some functions are still missing
such as a buffer replacement which would support wrapping buffers.
2011-11-25 21:57:29 +01:00
William Lallemand
0f99e34978 MEDIUM: log: Use linked lists for loggers
This patch settles the 2 loggers limitation.
Loggers are now stored in linked lists.

Using "global log", the global loggers list content is added at the end
of the current proxy list. Each "log" entries are added at the end of
the proxy list.

"no log" flush a logger list.
2011-10-31 14:09:19 +01:00
Willy Tarreau
2e99390faf BUG/MEDIUM: checks: fix slowstart behaviour when server tracking is in use
Ludovic Levesque reported and diagnosed an annoying bug. When a server is
configured to track another one and has a slowstart interval set, it's
assigned a minimal weight when the tracked server goes back up but keeps
this weight forever.

This is because the throttling during the warmup phase is only computed
in the health checking function.

After several attempts to resolve the issue, the only real solution is to
split the check processing task in two tasks, one for the checks and one
for the warmup. Each server with a slowstart setting has a warmum task
which is responsible for updating the server's weight after a down to up
transition. The task does not run in othe situations.

In the end, the fix is neither complex nor long and should be backported
to 1.4 since the issue was detected there first.
2011-10-31 11:53:20 +01:00
Willy Tarreau
4426770013 CLEANUP: rename possibly confusing struct field "tracked"
When reading the code, the "tracked" member of a server makes one
think the server is tracked while it's the opposite, it's a pointer
to the server being tracked. This is particularly true in constructs
such as :

	if (srv->tracked) {

Since it's the second time I get caught misunderstanding it, let's
rename it to "track" to avoid the confusion.
2011-10-28 15:35:33 +02:00
Willy Tarreau
ac1932da3e MEDIUM: tune.http.maxhdr makes it possible to configure the maximum number of HTTP headers
For a long time, the max number of headers was taken as a part of the buffer
size. Since the header size can be configured at runtime, it does not make
much sense anymore.

Nothing was making it necessary to have a static value, so let's turn this into
a tunable with a default value of 101 which equals what was previously used.
2011-10-24 19:14:41 +02:00
Willy Tarreau
34eb671f24 OPTIM/MINOR: move the hdr_idx pools out of the proxy struct
It makes no sense to have one pointer to the hdr_idx pool in each proxy
struct since these pools do not depend on the proxy. Let's have a common
pool instead as it is already the case for other types.
2011-10-24 18:15:04 +02:00
Willy Tarreau
bd9a0a7781 OPTIM/MINOR: make it possible to change pipe size (tune.pipesize)
By default, pipes are the default size for the system. But sometimes when
using TCP splicing, it can improve performance to increase pipe sizes,
especially if it is suspected that pipes are not filled and that many
calls to splice() are performed. This has an impact on the kernel's
memory footprint, so this must not be changed if impacts are not understood.
2011-10-23 21:15:38 +02:00
Willy Tarreau
7b81563443 OPTIM/MINOR: move struct sockaddr_storage to the tail of structs
Struct sockaddr_storage is huge (128 bytes) and severely impacts the
cache. It also displaces other struct members, causing them to have
larger relative offsets. By moving these few occurrences to the end
of the structs which host them, we can reduce the code size by no less
than 2 kB !
2011-10-23 19:08:46 +02:00
Willy Tarreau
6471afb43d MINOR: remove the client/server side distinction in SI addresses
Stream interfaces used to distinguish between client and server addresses
because they were previously of different types (sockaddr_storage for the
client, sockaddr_in for the server). This is not the case anymore, and this
distinction is confusing at best and has caused a number of regressions to
be introduced in the process of converting everything to full-ipv6. We can
now remove this and have a much cleaner code.
2011-09-23 10:54:59 +02:00
Willy Tarreau
0e69854ed4 MINOR: acl: add new matches for header/path/url length
This patch introduces hdr_len, path_len and url_len for matching these
respective parts lengths against integers. This can be used to detect
abuse or empty headers.
2011-09-16 08:32:32 +02:00
Willy Tarreau
eabea0763b [MINOR] stats: report the number of requests intercepted by the frontend
These requests are mainly monitor requests, as well as stats requests when
the stats are processed by the frontend. Having this counter helps explain
the difference in number of sessions that is sometimes observed between a
frontend and a backend.
2011-09-10 23:32:41 +02:00
Willy Tarreau
45a1251515 [MEDIUM] poll: add a measurement of idle vs work time
We now measure the work and idle times in order to report the idle
time in the stats. It's expected that we'll be able to use it at
other places later.
2011-09-10 18:01:41 +02:00
Willy Tarreau
a2a64e9689 [MEDIUM] session: make session_shutdown() an independant function
We already had the ability to kill a connection, but it was only
for the checks. Now we can do this for any session, and for this we
add a specific flag "K" to the logs.
2011-09-07 23:01:56 +02:00
Willy Tarreau
532a450ebc [MEDIUM] stats: add the ability to enable/disable/shutdown a frontend at runtime
The stats socket now allows the admin to disable, enable or shutdown a frontend.
This can be used when a bug is discovered in a configuration and it's desirable
to fix it but the rules in place don't allow to change a running config. Thus it
becomes possible to kill the frontend to release the port and start a new one in
a separate process.

This can also be used to temporarily make haproxy return TCP resets to incoming
requests to pretend the service is not bound. For instance, this may be useful
to quickly flush a very deep SYN backlog.

The frontend check and lookup code was factored with the "set maxconn" usage.
2011-09-07 22:50:52 +02:00
Willy Tarreau
ce8fe259b5 [CLEANUP] proxy: make pause_proxy() perform the required controls and emit the logs
It avoids duplicated code in the caller.
2011-09-07 22:47:43 +02:00
Willy Tarreau
3c63fd828a [MEDIUM] don't limit peers nor stats socket to maxconn nor maxconnrate
The peers and the stats socket are control sockets, they must not be
limited by traffic rules.
2011-09-07 22:47:42 +02:00
Willy Tarreau
81c25d0ee6 [MEDIUM] add support for global.maxconnrate to limit the per-process conn rate.
This one enforces a per-process connection rate limit, regardless of what
may be set per frontend. It can be a way to limit the CPU usage of a process
being severely attacked.

The side effect is that the global process connection rate is now measured
for each incoming connection, so it will be possible to report it.
2011-09-07 22:47:42 +02:00
Willy Tarreau
91886b692a [MEDIUM] stats: add the "set maxconn" setting to the command line interface
This option permits to change the global maxconn setting within the
limit that was set by the initial value, which is now reported as the
hard maxconn value. This allows to immediately accept more concurrent
connections or to stop accepting new ones until the value passes below
the indicated setting.

The main use of this option is on systems where many haproxy instances
are loaded and admins need to re-adjust resource sharing at run time
to regain a bit of fairness between processes.
2011-09-07 22:47:41 +02:00
Willy Tarreau
588bd4f813 [BUG] http: trailing white spaces must also be trimmed after headers
Trailing spaces after headers were not trimmed, only the leading ones
were. An issue was detected today with a content-length value which
was padded with spaces and which was rejected. Recent updates to the
http-bis draft made it a lot more clear that such spaces must be ignored,
so this is what this patch does.

It should be backported to 1.4.
2011-09-05 00:54:56 +02:00
Willy Tarreau
631f01c2f1 [MINOR] make use of addr_to_str() and get_host_port() to replace many inet_ntop()
Many inet_ntop calls were partially right, which was hard to detect given
the complex combinations. Some of them were relying on the listener's proto
instead of the address itself, which could have been different when dealing
with an accept-proxy connection.

The new addr_to_str() function does the dirty job and returns the family, which
makes it particularly suited to calls from switch/case statements. A large number
of if/else statements were removed and the stats output could even be cleaned up
in the case of session dump.

As a side effect of doing this, the resulting code is smaller by almost 1kB.
All changed parts have been tested and provided expected output.
2011-09-05 00:54:36 +02:00
Willy Tarreau
43d8fb2d3a [REORG] build: move syscall redefinition to specific places
Some older libc don't define splice() and and don't define _syscall*()
either, which causes build errors if splicing is enabled.

To solve this, we now split the syscall redefinition into two layers :
  - one file per syscall (epoll, splice)
  - one common file to declare the _syscall*() macros

The code is cleaner because files using the syscalls just have to include
their respective file. It's not adviced to merge multiple syscall families
into a same file if all are not intended to be used simultaneously, because
defining unused static functions causes warnings to be emitted during build.

As a result, the new USE_MY_SPLICE parameter was added in order to be able
to define the splice() syscall separately.
2011-08-23 00:11:25 +02:00
Willy Tarreau
87cf51406c [MEDIUM] http: make x-forwarded-for addition conditional
If "option forwardfor" has the "if-none" argument, then the header is
only added when the request did not already have one. This option has
security implications, and should not be set blindly.
2011-08-19 22:57:24 +02:00
Willy Tarreau
1ee51a6581 [BUG] check: http-check expect + regex would crash in defaults section
Manoj Kumar reported a case where haproxy would crash upon start-up. The
cause was an "http-check expect" statement declared in the defaults section,
which caused a NULL regex to be used during the check. This statement is not
allowed in defaults sections precisely because this requires saving a copy
of the regex in the default proxy. But the check was not made to prevent it
from being declared there, hence the issue.

Instead of adding code to detect its abnormal use, we decided to implement
it. It was not that much complex because the expect_str part was not used
with regexes, so it could hold the string form of the regex in order to
compile it again for every backend (there's no way to clone regexes).

This patch has been tested and works. So it's both a bugfix and a minor
feature enhancement.

It should be backported to 1.4 though it's not critical since the config
was not supposed to be supported.
2011-08-19 20:14:01 +02:00
Willy Tarreau
1620ec39a7 [MEDIUM] checks: group health checks methods by values and save option bits
Adding health checks has become a real pain, with cross-references to all
checks everywhere because they're all a single bit. Since they're all
exclusive, let's change this to have a check number only. We reserve 4
bits allowing up to 16 checks (15+tcp), only 7 of which are currently
used. The code has shrunk by almost 1kB and we saved a few option bits.

The "dispatch" option has been moved to px->options, making a few tests
a bit cleaner.
2011-08-06 17:08:40 +02:00
Herv COMMOWICK
ec032d63a6 [MINOR] check: add redis check support
This patch provides a new "option redis-check" statement to enable server health checks based on redis PING request (http://www.redis.io/commands/ping).
2011-08-06 15:52:47 +02:00
Herv COMMOWICK
daa824e513 [MINOR] acl: add srv_conn acl to count connections on a
specific backend server

These ACLs are used to check the number of active connections on the specified server in the specified backend.
2011-08-06 15:52:27 +02:00
Willy Tarreau
e9b2602ac5 [MEDIUM] listeners: add a global listener management task
This global task is used to periodically check for end of resource shortage
and to try to enable queued listeners again. This is important in case some
temporary system-wide shortage is encountered, so that we don't have to wait
for an existing connection to be released before checking the queue again.

For situations where listeners are queued due to the global maxconn being
reached, the task is woken up at least every second. For situations where
a system resource shortage is detected (memory, sockets, ...) the task is
woken up at least every 100 ms. That way, recovery from severe events can
still be achieved under acceptable conditions.
2011-08-01 20:57:55 +02:00
Willy Tarreau
237250cc0d [BUG] proxy: stats frontend and peers were missing many initializers
This was revealed with one of the very latest patches which caused
the listener_queue not to be initialized on the stats socket frontend.
And in fact a number of other ones were missing too. This is getting so
boring that now we'll always make use of the same function to initialize
any proxy. Doing so has even saved about 500 bytes on the binary due to
the avoided code redundancy.

No backport is needed.
2011-07-29 02:00:19 +02:00
Willy Tarreau
918ff608f8 [MAJOR] proxy: finally get rid of maintain_proxies()
This function is finally not needed anymore, as it has been replaced with
a per-proxy task that is scheduled when some limits are encountered on
incoming connections or when the process is stopping. The savings should
be noticeable on configs with a large number of proxies. The most important
point is that the rate limiting is now enforced in a clean and solid way.
2011-07-25 16:33:49 +02:00
Willy Tarreau
26e4881a2d [MINOR] task: new function task_schedule() to schedule a wake up
This function is used when a task should be woken up at most at a given
date. This will be used with rate shapers.
2011-07-25 15:30:39 +02:00
Willy Tarreau
562515cac1 [CLEANUP] proxy: rename a few proxy states (PR_STIDLE and PR_STRUN)
Those states have been replaced with PR_STFULL and PR_STREADY respectively,
as it is what matches them the best now. Also, two occurrences of PR_STIDLE
in peers.c have been removed as this did not provide any form of error recovery
anyway.
2011-07-25 08:11:52 +02:00
Willy Tarreau
07687c171e [MEDIUM] listeners: queue proxy-bound listeners at the proxy's
All listeners that are limited by a proxy-specific resource are now
queued at the proxy's and not globally. This allows finer-grained
wakeups when releasing resource.
2011-07-24 23:55:06 +02:00
Willy Tarreau
08ceb1012b [MEDIUM] listeners: put listeners in queue upon resource shortage
When an accept() fails because of a connection limit or a memory shortage,
we now disable it and queue it so that it's dequeued only when a connection
is released. This has improved the behaviour of the process near the fd limit
as now a listener with a no connection (eg: stats) will not loop forever
trying to get its connection accepted.

The solution is still not 100% perfect, as we'd like to have this used when
proxy limits are reached (use a per-proxy list) and for safety, we'd need
to have dedicated tasks to periodically re-enable them (eg: to overcome
temporary system-wide resource limitations when no connection is released).
2011-07-24 22:58:00 +02:00
Willy Tarreau
e6ca1fcd84 [MINOR] listeners: add support for queueing resource limited listeners
When a listeners encounters a resource shortage, it currently stops until
one re-enables it. This is far from being perfect as it does not yet handle
the case where the single connection from the listener is rejected (eg: the
stats page).

Now we'll have a special status for resource limited listeners and we'll
queue them into one or multiple lists. That way, each time we have to stop
a listener because of a resource shortage, we can enqueue it and change its
state, so that it is dequeued once more resources are available.

This patch currently does not change any existing behaviour, it only adds
the basic building blocks for doing that.
2011-07-24 22:03:52 +02:00
Willy Tarreau
627937158f [MINOR] listeners: add listen_full() to mark a listener full
This is just a cleanup which removes calls to EV_FD_CLR() and state
setting everywhere in the code.
2011-07-24 19:25:28 +02:00
Willy Tarreau
be58c38264 [MEDIUM] proxy: add a PAUSED state to listeners and move socket tricks out of proxy.c
Managing listeners state is difficult because they have their own state
and can at the same time have theirs dictated by their proxy. The pause
is not done properly, as the proxy code is fiddling with sockets. By
introducing new functions such as pause_listener()/resume_listener(), we
make it a bit more obvious how/when they're supposed to be used. The
listen_proxies() function was also renamed to resume_proxies() since
it's only used for pause/resume.

This patch is the first in a series aiming at getting rid of the maintain_proxies
mess. In the end, proxies should not call enable_listener()/disable_listener()
anymore.
2011-07-24 19:09:37 +02:00
Willy Tarreau
9bd0d744ef [BUG] session: risk of crash on out of memory (1.5-dev regression)
Patch af5149 introduced an issue which can be detected only on out of
memory conditions : a LIST_DEL() may be performed on an uninitialized
struct member instead of a LIST_INIT() during the accept() phase,
causing crashes and memory corruption to occur.

This issue was detected and diagnosed by the Exceliance R&D team.

This is 1.5-specific and very recent, so no existing deployment should
be impacted.
2011-07-20 00:22:54 +02:00
Simon Horman
fa46168c8f [MINOR] Add non-stick server option
Never add connections allocated to this sever to a stick-table.
This may be used in conjunction with backup to ensure that
stick-table persistence is disabled for backup servers.
2011-06-25 21:14:17 +02:00
Simon Horman
e869176486 [MINOR] Make appsess{,ion}_refresh static
apsession_refresh() and apsess_refressh are only used inside apsession.c
and thus can be made static.

The only use of apsession_refresh() is appsession_task_init().
These functions have been re-ordered to avoid the need for
a forward-declaration of apsession_refresh().
2011-06-25 21:07:01 +02:00
Simon Horman
752dc4ab2d [MINOR] Add down termination condition
If a connection is closed by because the backend became unavailable
then log 'D' as the termination condition.

Signed-off-by: Simon Horman <horms@verge.net.au>
2011-06-21 22:10:56 +02:00
Simon Horman
e0d1bfb4c1 [MINOR] Allow shutdown of sessions when a server becomes unavailable
This adds the "on-marked-down shutdown-sessions" statement on "server" lines,
which causes all sessions established on a server to be killed at once when
the server goes down. The task's priority is reniced to the highest value
(1024) so that servers holding many tasks don't cause a massive slowdown due
to the wakeup storm.
2011-06-21 22:00:21 +02:00
Simon Horman
af51495397 [MINOR] Add active connection list to server
The motivation for this is to allow iteration of all the connections
of a server without the expense of iterating over the global list
of connections.

The first use of this will be to implement an option to close connections
associated with a server when is is marked as being down or in maintenance
mode.
2011-06-21 22:00:12 +02:00
Simon Horman
dec5be4ed4 [CLEANUP] session.c: Make functions static where possible 2011-06-18 20:27:19 +02:00
Simon Horman
96553775a0 [CLEANUP] peers.h: fix declarations
* The declaration of peer_session_create() does
  not match its definition. As it is only
  used inside of peers.c make it static.

* Make the declaration of peers_register_table()
  match its definition.

* Also, make all functions in peers.c that
  are not also in peers.h static
2011-06-18 20:27:19 +02:00
Simon Horman
c88b887d8d [MINOR] More flexible clearing of stick table
* Allow clearing of all entries of a table
* Allow clearing of all entries of a table
  that match a data filter
2011-06-17 11:39:29 +02:00
Simon Horman
9bd2c73916 [CLEANUP] dumpstats: make symbols static where possible 2011-06-17 11:39:28 +02:00
Willy Tarreau
bf9c2fcd93 [BUG] stats: support url-encoded forms
Bashkim Kasa reported that the stats admin page did not work when colons
were used in server or backend names. This was caused by url-encoding
resulting in ':' being sent as '%3A'. Now we systematically decode the
field names and values to fix this issue.
2011-05-31 22:44:28 +02:00
Willy Tarreau
14acc7072e [OPTIM] stream_sock: don't use splice on too small payloads
It's more expensive to call splice() on short payloads than to use
recv()+send(). One of the reasons is that doing a splice() involves
allocating a pipe. One other reason is that the kernel will have to
copy itself if we try to splice less than a page. So let's fix a
short offset of 4kB below which we don't splice.

A quick test shows that on chunked encoded data, with splice we had
6826 syscalls (1715 splice, 3461 recv, 1650 send) while with this
patch, the same transfer resulted in 5793 syscalls (3896 recv, 1897
send).
2011-05-30 18:42:41 +02:00
Willy Tarreau
96e312139a [MEDIUM] http: add support for "http-no-delay"
There are some very rare server-to-server applications that abuse the HTTP
protocol and expect the payload phase to be highly interactive, with many
interleaved data chunks in both directions within a single request. This is
absolutely not supported by the HTTP specification and will not work across
most proxies or servers. When such applications attempt to do this through
haproxy, it works but they will experience high delays due to the network
optimizations which favor performance by instructing the system to wait for
enough data to be available in order to only send full packets. Typical
delays are around 200 ms per round trip. Note that this only happens with
abnormal uses. Normal uses such as CONNECT requests nor WebSockets are not
affected.

When "option http-no-delay" is present in either the frontend or the backend
used by a connection, all such optimizations will be disabled in order to
make the exchanges as fast as possible. Of course this offers no guarantee on
the functionality, as it may break at any other place. But if it works via
HAProxy, it will work as fast as possible. This option should never be used
by default, and should never be used at all unless such a buggy application
is discovered. The impact of using this option is an increase of bandwidth
usage and CPU usage, which may significantly lower performance in high
latency environments.

This change should be backported to 1.4 since the first report of such a
misuse was in 1.4. Next patch will also be needed.
2011-05-30 18:42:41 +02:00
Willy Tarreau
ae94d4df8f [MINOR] http: make the "HTTP 200" status code configurable.
This status code is used in response to requests matching "monitor-uri".
Some users need to adjust it to fit their needs (eg: make some strings
appear there). As it's already defined as a chunked string and used
exactly like other status codes, it makes sense to make it configurable
with the usual "errorfile", "errorloc", ...
2011-05-11 16:31:43 +02:00
Willy Tarreau
436d9ed808 [REORG] http: move HTTP error codes back to proto_http.h
This one was left isolated in its own file. It probably is a leftover
from the 1.2->1.3 split.
2011-05-11 16:31:43 +02:00
Willy Tarreau
c9f6011760 [BUG] TCP source tracking was broken with IPv6 changes
John Helliwell reported a bug when using TCP source address
tracking on Solaris. The bug was introduced in haproxy 1.5-dev5.
2011-04-07 10:53:25 +02:00
Willy Tarreau
1b4b7ce6dd [BUG] stream_sock: use get_addr_len() instead of sizeof() on sockaddr_storage
John Helliwell reported a runtime issue on Solaris since 1.5-dev5. Traces
show that connect() returns EINVAL, which means the socket length is not
appropriate for the family. Solaris does not like being called with sizeof
and needs the address family's size on sockaddr_storage.

The fix consists in adding a get_addr_len() function which returns the
socket's address length based on its family. Tests show that this works
for both IPv4 and IPv6 addresses.
2011-04-05 16:56:50 +02:00
David du Colombier
4f92d32004 [MEDIUM] IPv6 support for stick-tables
Since IPv6 is a different type than IPv4, the pattern fetch functions
src6 and dst6 were added. IPv6 stick-tables can also fetch IPv4 addresses
with src and dst. In this case, the IPv4 addresses are mapped to their
IPv6 counterpart, according to RFC 4291.
2011-03-29 01:09:14 +02:00
David du Colombier
11bcb6c4f5 [MEDIUM] IPv6 support for syslog 2011-03-28 18:45:15 +02:00
Willy Tarreau
0bc3493d2c [OPTIM] buffers: uninline buffer_forward()
Since the latest additions to buffer_forward(), it became too large for
inlining, so let's uninline it. The code size drops by 3kB. Should be
backported to 1.4 too.
2011-03-28 16:25:58 +02:00
Willy Tarreau
d8ee85a0a3 [BUG] http: fix content-length handling on 32-bit platforms
Despite much care around handling the content-length as a 64-bit integer,
forwarding was broken on 32-bit platforms due to the 32-bit nature of
the ->to_forward member of the "buffer" struct. The issue is that this
member is declared as a long, so while it works OK on 64-bit platforms,
32-bit truncate the content-length to the lower 32-bits.

One solution could consist in turning to_forward to a long long, but it
is used a lot in the critical path, so it's not acceptable to perform
all buffer size computations on 64-bit there.

The fix consists in changing the to_forward member to a strict 32-bit
integer and ensure in buffer_forward() that only the amount of bytes
that can fit into it is considered. Callers of buffer_forward() are
responsible for checking that their data were taken into account. We
arbitrarily ensure we never consider more than 2G at once.

That's the way it was intended to work on 32-bit platforms except that
it did not.

This issue was tracked down hard at Exosec with Bertrand Jacquin,
Thierry Fournier and Julien Thomas. It remained undetected for a long
time because files larger than 4G are almost always transferred in
chunked-encoded format, and most platforms dealing with huge contents
these days run on 64-bit.

The bug affects all 1.5 and 1.4 versions, and must be backported.
2011-03-28 16:25:16 +02:00
Willy Tarreau
d3db94399f [MINOR] tools: add two macros MID_RANGE and MAX_RANGE
Those will be used later, they return the largest and middle integer
possible for a given variable or type.
2011-03-28 15:55:43 +02:00
Willy Tarreau
fab5a43726 [MEDIUM] config: rework the IPv4/IPv6 address parser to support host-only addresses
The parser now distinguishes between pure addresses and address:port. This
is useful for some config items where only an address is required.

Raw IPv6 addresses are now parsed, but IPv6 host name resolution is still not
handled (gethostbyname does not resolve IPv6 names to addresses).
2011-03-23 19:01:18 +01:00
David du Colombier
64e9c90e69 [BUG] standard: is_addr return value for IPv4 was inverted 2011-03-22 14:39:16 +01:00
Willy Tarreau
5ab04ec47c [MEDIUM] server: add support for the "send-proxy" option
This option enables use of the PROXY protocol with the server, which
allows haproxy to transport original client's address across multiple
architecture layers.
2011-03-20 11:53:50 +01:00
Willy Tarreau
b22e55bc8f [MEDIUM] stream_sock: add support for sending the proxy protocol header line
Upon connection establishment, stream_sock is now able to send a PROXY
line before sending any data. Since it's possible that the buffer is
already full, and we don't want to allocate a block for that line, we
compute it on-the-fly when we need it. We just store the offset from
which to (re-)send from the end of the line, since it's assumed that
multiple outputs of the same proxy line will be strictly equivalent. In
practice, one call is enough. We just make sure to handle the case where
the first send() would indicate an incomplete output, eventhough it's
very unlikely to ever happen.
2011-03-20 10:16:46 +01:00
Willy Tarreau
a73fcaf424 [MINOR] frontend: add a make_proxy_line function
This function will build a PROXY protocol line header from two addresses
(IPv4 or IPv6). AF_UNIX family will be reported as UNKNOWN.
2011-03-20 10:15:22 +01:00
Willy Tarreau
ff011f26e9 [REORG] http: move the http-request rules to proto_http
And also rename "req_acl_rule" "http_req_rule". At the beginning that
was a bit confusing to me, especially the "req_acl" list which in fact
holds what we call rules. After some digging, it appeared that some
part of the code is 100% HTTP and not just related to authentication
anymore, so let's move that part to HTTP and keep the auth-only code
in auth.c.
2011-03-13 22:00:24 +01:00
Willy Tarreau
7d0aaf39d1 [MEDIUM] stats: split frontend and backend stats
It's very annoying that frontend and backend stats are merged because we
don't know what we're observing. For instance, if a "listen" instance
makes use of a distinct backend, it's impossible to know what the bytes_out
means.

Some points take care of not updating counters twice if the backend points
to the frontend, indicating a "listen" instance. The thing becomes more
complex when we try to add support for server side keep-alive, because we
have to maintain a pointer to the backend used for last request, and to
update its stats. But we can't perform such comparisons anymore because
the counters will not match anymore.

So in order to get rid of this situation, let's have both frontend AND
backend stats in the "struct proxy". We simply update the relevant ones
during activity. Some of them are only accounted for in the backend,
while others are just for frontend. Maybe we can improve a bit on that
later, but the essential part is that those counters now reflect what
they really mean.
2011-03-13 22:00:23 +01:00
David du Colombier
6f5ccb1589 [MEDIUM] add internal support for IPv6 server addresses
This patch turns internal server addresses to sockaddr_storage to
store IPv6 addresses, and makes the connect() function use it. This
code already works but some caveats with getaddrinfo/gethostbyname
still need to be sorted out while the changes had to be merged at
this stage of internal architecture changes. So for now the config
parser will not emit an IPv6 address yet so that user experience
remains unchanged.

This change should have absolutely zero user-visible effect, otherwise
it's a bug introduced during the merge, that should be reported ASAP.
2011-03-13 22:00:12 +01:00
Willy Tarreau
827aee913f [MAJOR] session: remove the ->srv pointer from struct session
This one has been removed and is now totally superseded by ->target.
To get the server, one must use target_srv(&s->target) instead of
s->srv now.

The function ensures that non-server targets still return NULL.
2011-03-10 23:32:17 +01:00
Willy Tarreau
9e000c6ec8 [CLEANUP] stream_interface: use inline functions to manipulate targets
The connection target involves a type and a union of pointers, let's
make the code cleaner using simple wrappers.
2011-03-10 23:32:17 +01:00
Willy Tarreau
3d80d911aa [MEDIUM] session: remove s->prev_srv which is not needed anymore
s->prev_srv is used by assign_server() only, but all code paths leading
to it now take s->prev_srv from the existing s->srv. So assign_server()
can do that copy into its own stack.

If at one point a different srv is needed, we still have a copy of the
last server on which we failed a connection attempt in s->target.
2011-03-10 23:32:16 +01:00
Willy Tarreau
664beb8610 [MINOR] session: add a pointer to the new target into the session
When dealing with HTTP keep-alive, we'll have to know if we can reuse
an existing connection. For that, we'll have to check if the current
connection was made on the exact same target (referenced in the stream
interface).

Thus, we need to first assign the next target to the session, then
copy it to the stream interface upon connect(). Later we'll check for
equivalence between those two operations.
2011-03-10 23:32:16 +01:00
Willy Tarreau
f5ab69aad9 [MINOR] proxy: add PR_O2_DISPATCH to detect dispatch mode
Till now we used the fact that the dispatch address was not null to use
the dispatch mode. This is very unconvenient, so let's have a dedicated
option.
2011-03-10 23:32:16 +01:00
Willy Tarreau
295a837726 [REORG] session: move the data_ctx struct to the stream interface's applet
This is in fact where those parts belong to. The old data_state was replaced
by applet.state and is now initialized when the applet is registered. It's
worth noting that the applet does not need to know the session nor the
buffer anymore since everything is brought by the stream interface.

It is possible that having a separate applet struct would simplify the
code but that's not a big deal.
2011-03-10 23:32:16 +01:00
Willy Tarreau
5ec29ffa42 [CLEANUP] stats: make all dump functions only rely on the stream interface
This will be needed to move the applet-specific data out of the session.
2011-03-10 23:32:16 +01:00
Willy Tarreau
75581aebb0 [CLEANUP] session: remove data_source from struct session
This one was only used for logging purposes, it's not needed
anymore.
2011-03-10 23:32:15 +01:00
Willy Tarreau
7c0a151a2e [CLEANUP] stream_interface: remove the applet.handler pointer
Now that we have the target pointer and type in the stream interface,
we don't need the applet.handler pointer anymore. That makes the code
somewhat cleaner because we know we're dealing with an applet by checking
its type instead of checking the pointer is not null.
2011-03-10 23:32:15 +01:00
Willy Tarreau
ac82540c35 [MEDIUM] stream_interface: store the target pointer and type
When doing a connect() on a stream interface, some information is needed
from the server and from the backend. In some situations, we don't have
a server and only a backend (eg: peers). In other cases, we know we have
an applet and we don't want to connect to anything, but we'd still like
to have the info about the applet being used.

For this, we now store a pointer to the "target" into the stream interface.
The target describes what's on the other side before trying to connect. It
can be a server, a proxy or an applet for now. Later we'll probably have
descriptors for multiple-stage chains so that the final information may
still be found.

This will help removing many specific cases in the code. It already made
it possible to remove the "srv" and "be" parameters to tcpv4_connect_server().
2011-03-10 23:32:15 +01:00
Willy Tarreau
f153686a71 [REORG] tcp: make tcpv4_connect_server() take the target address from the SI
The address is now available in the stream interface, no need to pass it by
argument.
2011-03-10 23:32:15 +01:00
Willy Tarreau
957c0a5845 [REORG] session: move client and server address to the stream interface
This will be needed very soon for the keep-alive.
2011-03-10 23:32:14 +01:00
Willy Tarreau
be5ea19188 [REORG] stream_interface: split the struct members in 3 parts
Those 3 parts are the buffer side, the remote side and the communication
functions. This change has no functional effect but is needed to proceed
further.
2011-03-10 23:32:14 +01:00
Willy Tarreau
bc4af0573c [REORG] stream_interface: move the st0, st1 and private members to the applet
Those fields are only used by the applets, so let's move them to the
struct.
2011-03-10 23:32:14 +01:00
Willy Tarreau
b24281b0ff [MINOR] stream_interface: make use of an applet descriptor for IO handlers
I/O handlers are still delicate to manipulate. They have no type, they're
just raw functions which have no knowledge of themselves. Let's have them
declared as applets once for all. That way we can have multiple applets
share the same handler functions and we can store their names there. When
we later need to add more parameters (eg: usage stats), we'll be able to
do so in the applets themselves.

The CLI functions has been prefixed with "cli" instead of "stats" as it's
clearly what is going on there.

The applet descriptor in the stream interface should get all the applet
specific data (st0, ...) but this will be done in the next patch so that
we don't pollute this one too much.
2011-03-10 23:32:14 +01:00
Willy Tarreau
124d99181c [BUG] http: fix computation of message body length after forwarding has started
Till now, the forwarding code was making use of the hdr_content_len member
to hold the size of the last chunk parsed. As such, it was reset after being
scheduled for forwarding. The issue is that this entry was reset before the
data could be viewed by backend.c in order to parse a POST body, so the
"balance url_param check_post" did not work anymore.

In order to fix this, we need two things :
  - the chunk size (reset upon every forward)
  - the total body size (not reset)

hdr_content_len was thus replaced by the former (hence the size of the patch)
as it makes more sense to have it stored that way than the way around.

This patch should be backported to 1.4 with care, considering that it affects
the forwarding code.
2011-03-01 20:30:48 +01:00
Willy Tarreau
930bd6b763 [MINOR] acl: add ability to check for internal response-only parameters
Some parameters are known to the response only (eg: the server which processed
it). Let's have a flag for that.
2011-02-23 15:32:20 +01:00
Rauf Kuliyev
38b4156a69 [MINOR] checks: add PostgreSQL health check
I have written a small patch to enable a correct PostgreSQL health check
It works similar to mysql-check with the very same parameters.

E.g.:
listen pgsql 127.0.0.1:5432
   mode tcp
   option pgsql-check user pgsql
   server masterdb pgsql.server.com:5432 check inter 10000
2011-01-04 15:14:13 +01:00
Kevinm
48936af9a2 [MINOR] log: ability to override the syslog tag
One of the requirements we have is to run multiple instances of haproxy on a
single host; this is so that we can split the responsibilities (and change
permissions) between product teams. An issue we ran up against is how we
would distinguish between the logs generated by each instance. The solution
we came up with (please let me know if there is a better way) is to override
the application tag written to syslog. We can then configure syslog to write
these to different files.

I have attached a patch adding a global option 'log-tag' to override the
default syslog tag 'haproxy' (actually defaults to argv[0]).
2010-12-30 11:43:36 +01:00
Joe Williams
df5b38fac1 [MINOR] log: add support for passing the forwarded hostname
Haproxy does not include the hostname rather the IP of the machine in
the syslog headers it sends. Unfortunately this means that for each log
line rsyslog does a reverse dns on the client IP and in the case of
non-routable IPs one gets the public hostname not the internal one.

While this is valid according to RFC3164 as one might imagine this is
troublsome if you have some machines with public IPs, internal IPs, no
reverse DNS entries, etc and you want a standardized hostname based log
directory structure. The rfc says the preferred value is the hostname.

This patch adds a global "log-send-hostname" statement which accepts an
optional string to force the host name. If unset, the local host name
is used.
2010-12-29 17:05:48 +01:00
Willy Tarreau
0499e3575c [BUG] http: analyser optimizations broke pipelining
HTTP pipelining currently needs to monitor the response buffer to wait
for some free space to be able to send a response. It was not possible
for the HTTP analyser to be called based on response buffer activity.
Now we introduce a new buffer flag BF_WAKE_ONCE which is set when the
HTTP request analyser is set on the response buffer and some activity
is detected. This is not clean at all but once of the only ways to fix
the issue before we make it possible to register events for analysers.

Also it appeared that one realign condition did not cover all cases.
2010-12-17 07:15:57 +01:00
Willy Tarreau
10479e4bac [MINOR] stats: add global event ID and count
This counter will help quickly spot whether there are new errors or not.
It is also assigned to each capture so that a script can keep trace of
which capture was taken when.
2010-12-12 14:00:34 +01:00
Willy Tarreau
078272e115 [MINOR] stats: report HTTP message state and buffer flags in error dumps
Debugging parsing errors can be greatly improved if we know what the parser
state was and what the buffer flags were (especially for closed inputs/outputs
and full buffers). Let's add that to the error snapshots.
2010-12-12 12:46:33 +01:00
Willy Tarreau
798a39cdc9 [MEDIUM] hash: add support for an 'avalanche' hash-type
When the number of servers is a multiple of the size of the input set,
map-based hash can be inefficient. This typically happens with 64
servers when doing URI hashing. The "avalanche" hash-type applies an
avalanche hash before performing a map lookup in order to smooth the
distribution. The result is slightly less smooth than the map for small
numbers of servers, but still better than the consistent hashing.
2010-11-29 07:28:16 +01:00
Willy Tarreau
4c14eaa0d4 [CLEANUP] hash: move the avalanche hash code globally available
We'll use this hash at other places, let's make it globally available.
The function has also been renamed because its "chash_hash" name was
not appropriate.
2010-11-29 07:28:16 +01:00
Willy Tarreau
b695a6e5fa [BUILD] pattern: use 'int' instead of 'int32_t'
Ross West reported that int32_t breaks compilation on FreeBSD. Since an
int is 32-bit on all supported platforms and we already rely on that,
change the type.
2010-11-14 14:24:27 +01:00
Emeric Brun
32da3c40db [MEDIUM] Manage peers section parsing and stick table registration on peers. 2010-11-11 09:29:08 +01:00
Emeric Brun
2b920a1af1 [MAJOR] Add new files src/peer.c, include/proto/peers.h and include/types/peers.h for sync stick table management
Add cmdline option -L to configure local peer name
2010-11-11 09:29:08 +01:00
Emeric Brun
85e77c7f0d [MEDIUM] Create updates tree on stick table to manage sync. 2010-11-11 09:29:08 +01:00