Commit Graph

2725 Commits

Author SHA1 Message Date
Willy Tarreau
16a2147dfe MEDIUM: adjust the maxaccept per listener depending on the number of processes
global.tune.maxaccept was used for all listeners. This becomes really not
convenient when some listeners are bound to a single process and other ones
are bound to many processes.

Now we change the principle : we count the number of processes a listener
is bound to, and apply the maxaccept either entirely if there is a single
process, or divided by twice the number of processes in order to maintain
fairness.

The default limit has also been increased from 32 to 64 as it appeared that
on small machines, 32 was too low to achieve high connection rates.
2012-11-19 12:39:59 +01:00
Emeric Brun
4f65bff1a5 MINOR: ssl: Add tune.ssl.lifetime statement in global.
Sets the ssl session <lifetime> in seconds. Openssl default is 300 seconds.
2012-11-16 16:47:20 +01:00
Willy Tarreau
6ec58dbacc MINOR: ssl: rename and document the tune.ssl.cachesize option
Its was initially called "tune.sslcachesize" but not documented, let's
rename it and document it.
2012-11-16 16:47:10 +01:00
Willy Tarreau
fc6c032d8d MEDIUM: global: add support for CPU binding on Linux ("cpu-map")
The new "cpu-map" directive allows one to assign the CPU sets that
a process is allowed to bind to. This is useful in combination with
the "nbproc" and "bind-process" directives.

The support is implicit on Linux 2.6.28 and above.
2012-11-16 16:16:53 +01:00
Emeric Brun
c52962f292 MINOR: conf: add warning if ssl is not enabled and a certificate is present on bind. 2012-11-15 18:46:03 +01:00
Willy Tarreau
110ecc1acd MINOR: config: support process ranges for "bind-process"
Several users have already been caught by "bind-process" which does not
support ranges, so let's support them now.
2012-11-15 17:50:01 +01:00
Willy Tarreau
247a13a315 MINOR: global: don't prevent nbproc from being redefined
Having nbproc preinitialized to zero is really annoying as it prevents
some checks from being correctly performed. Also the check to prevent
nbproc from being redefined is totally useless, so let's preset it to
1 and remove the test.
2012-11-15 17:38:15 +01:00
Willy Tarreau
543db62e1f BUG/MEDIUM: compression: release the zlib pools between keep-alive requests
There was a possible memory leak in the zlib code when the first response of
a keep-alive session was compressed, because the next request would reset the
compression algo, preventing a later call to session_free() from releasing it.
The reason is that it is necessary to release the assigned resources in
http_end_txn_clean_session().
2012-11-15 16:41:22 +01:00
William Lallemand
ec3e3890f0 BUG/MINOR: compression: deinit zlib only when required
The zlib stream was deinitialized even when the init failed.
2012-11-15 15:42:17 +01:00
William Lallemand
c04ca58222 BUG/MEDIUM: compression: no Content-Type header but type in configuration
HAProxy was compressing data when there was no Content-Type header in
the response but a compression type specified in the configuration.
2012-11-15 15:42:11 +01:00
Willy Tarreau
4690985fca BUG: compression: do not always increment the round counter on allocation failure
Zlib (at least 1.2 and 1.3) aborts when it fails to allocate the state, so we
must not count a round on this event. If the state succeeds, then it allocates
all the 4 remaining counters at once.
2012-11-15 15:00:55 +01:00
Emeric Brun
4663577e24 MINOR: build: allow packagers to specify the ssl cache size
This is done by passing the default value to SSLCACHESIZE in sessions.
User can use tune.sslcachesize to change this value.
By default, it is set to 20000 sessions as openssl internal cache size.
Currently, a session entry size is between 592 and 616 bytes depending on the arch.
2012-11-15 10:52:19 +01:00
Willy Tarreau
4055a107a7 BUG: proxy: fix server name lookup in get_backend_server()
The lookup was broken by commit 050536d5. The server ID is
initialized to a negative value but unfortunately not all the
tests were converted. Thanks to Igor at owind for reporting it.
2012-11-15 00:15:18 +01:00
Willy Tarreau
96aa6b32d7 MINOR: build: allow packagers to specify the default maxzlibmem
This is done by passing the default value to DEFAULT_MAXZLIBMEM in megs.
2012-11-12 15:52:53 +01:00
Willy Tarreau
45b8893966 MINOR: splice: disable it when the system returns EBADF
At least on a heavily patched 2.6.35.9, we can see splice() fail
with EBADF :

  recv(6, "789.123456789.123456789.12345678"..., 1049, 0) = 1049
  send(5, "HTTP/1.1 200\r\nContent-length: 10"..., 8030, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_MORE) = 8030
  gettimeofday({1352717854, 515601}, NULL) = 0
  epoll_wait(0x3, 0x40221008, 0x7, 0)     = 0
  gettimeofday({1352717854, 515793}, NULL) = 0
  pipe([7, 8])                            = 0
  splice(0x6, 0, 0x8, 0, 0xfe12c, 0x3)    = -1 EBADF (Bad file descriptor)
  close(6)                                = 0

This clearly is a kernel issue since all FDs are valid here, so let's
simply disable splice() on the connection when this happens so that
the session correctly recovers from that issue using recv().
2012-11-12 12:02:20 +01:00
Emeric Brun
674b743067 BUG/MEDIUM: ssl: Fix sometimes reneg fails if requested by server.
SSL_do_handshake is not appropriate for reneg, it's only appropriate at the
beginning of a connection. OpenSSL correctly handles renegs using the data
functions, so we use SSL_peek() here to make its state machine progress if
SSL_renegotiate_pending() says a reneg is pending.
2012-11-12 11:46:08 +01:00
Emeric Brun
282a76acc1 BUG/MEDIUM: ssl: Fix some reneg cases not correctly handled.
SSL may decide to switch to a handshake in the middle of a transfer due to
a reneg. In this case we don't want to re-enable polling because data might
have been left pending in the buffer. We just want to switch immediately to
the handshake mode.
2012-11-12 11:43:05 +01:00
Emeric Brun
8af8dd1a9a BUG/MEDIUM: ssl: review polling on reneg.
SSL may return SSL_ERROR_WANT_WRITE or SSL_ERROR_WANT_READ when switching
from data to handshake even if it does not need to poll first.
2012-11-12 11:41:16 +01:00
Willy Tarreau
70d0ad560c BUG: polling: don't skip polled events in the spec list
Commit 09f245 came with a bug : if we don't process events from the
spec list that are also being polled, we can end up with some stuck
events that nobody processes.

We must process all events from the spec list even if they're being
polled in parallel.
2012-11-12 01:57:14 +01:00
Willy Tarreau
54a08d3e08 BUG: connection: fix typo in previous commit
A typo broke the logs (obj_type() instead of objt_server()).
2012-11-12 01:14:56 +01:00
Willy Tarreau
3fdb366885 MAJOR: connection: replace struct target with a pointer to an enum
Instead of storing a couple of (int, ptr) in the struct connection
and the struct session, we use a different method : we only store a
pointer to an integer which is stored inside the target object and
which contains a unique type identifier. That way, the pointer allows
us to retrieve the object type (by dereferencing it) and the object's
address (by computing the displacement in the target structure). The
NULL pointer always corresponds to OBJ_TYPE_NONE.

This reduces the size of the connection and session structs. It also
simplifies target assignment and compare.

In order to improve the generated code, we try to put the obj_type
element at the beginning of all the structs (listener, server, proxy,
si_applet), so that the original and target pointers are always equal.

A lot of code was touched by massive replaces, but the changes are not
that important.
2012-11-12 00:42:33 +01:00
Willy Tarreau
128b03c9ab CLEANUP: stream_interface: remove the external task type target
Before connections were introduced, it was possible to connect an
external task to a stream interface. However it was left as an
exercise for the brave implementer to find how that ought to be
done.

The feature was broken since the introduction of connections and
was never fixed since due to lack of users. Better remove this dead
code now.
2012-11-11 23:14:16 +01:00
Willy Tarreau
b31c971bef CLEANUP: channel: remove any reference of the hijackers
Hijackers were functions designed to inject data into channels in the
distant past. They became unused around 1.3.16, and since there has
not been any user of this mechanism to date, it's uncertain whether
the mechanism still works (and it's not really useful anymore). So
better remove it as well as the pointer it uses in the channel struct.
2012-11-11 23:05:39 +01:00
Willy Tarreau
50fc7777c6 MEDIUM: http: refrain from sending "Connection: close" when Upgrade is present
Some servers are not totally HTTP-compliant when it comes to parsing the
Connection header. This is particularly true with WebSocket where it happens
from time to time that a server doesn't support having a "close" token along
with the "Upgrade" token in the Connection header. This broken behaviour has
also been noticed on some clients though the problem is less frequent on the
response path.

Sometimes the workaround consists in enabling "option http-pretend-keepalive"
to leave the request Connection header untouched, but this is not always the
most convenient solution. This patch introduces a new solution : haproxy now
also looks for the "Upgrade" token in the Connection header and if it finds
it, then it refrains from adding any other token to the Connection header
(though "keep-alive" and "close" may still be removed if found). The same is
done for the response headers.

This way, WebSocket much with less changes even when facing non-compliant
clients or servers. At least it fixes the DISCONNECT issue that was seen
on the websocket.org test.

Note that haproxy does not change its internal mode, it just refrains from
adding new tokens to the connection header.
2012-11-11 22:40:00 +01:00
Willy Tarreau
70c6fd82c3 MAJOR: polling: remove unused callbacks from the poller struct
Since no poller uses poller->{set,clr,wai,is_set,rem} anymore, let's
remove them and remove the associated pointer tests in proto/fd.h.
2012-11-11 21:02:34 +01:00
Willy Tarreau
e9f49e78fe MAJOR: polling: replace epoll with sepoll and remove sepoll
Now that all pollers make use of speculative I/O, there is no point
having two epoll implementations, so replace epoll with the sepoll code
and remove sepoll which has just become the standard epoll method.
2012-11-11 20:53:30 +01:00
Willy Tarreau
4a22627672 MAJOR: ev_kqueue: make the poller support speculative events
The poller was updated to support speculative events. We'll need this
to fully support SSL.

As an a side effect, the code has become much simpler and much more
efficient, by taking advantage of the nice kqueue API which supports
batched updates. All references to fd_sets have disappeared, and only
the fdtab[].spec_e fields are used to decide about file descriptor
state.
2012-11-11 20:53:29 +01:00
Willy Tarreau
cc7e3f7c3f MAJOR: ev_poll: make the poller support speculative events
The poller was updated to support speculative events. We'll need this
to fully support SSL.
2012-11-11 20:53:29 +01:00
Willy Tarreau
4d31fb2643 MAJOR: ev_select: make the poller support speculative events
The poller was updated to support speculative events. We'll need this
to fully support SSL.
2012-11-11 20:53:29 +01:00
Willy Tarreau
7f7ad91056 BUILD: stream_interface: remove si_fd() and its references
si_fd() is not used a lot, and breaks builds on OpenBSD 5.2 which
defines this name for its own purpose. It's easy enough to remove
this one-liner function, so let's do it.
2012-11-11 20:53:29 +01:00
Willy Tarreau
0ea0cf606e BUG: raw_sock: also consider ENOTCONN in addition to EAGAIN
A failed send() may return ENOTCONN when the connection is not yet established.
On Linux, we generally see EAGAIN but on OpenBSD we clearly have ENOTCONN, so
let's ensure we poll for write when we encounter this error.
2012-11-11 20:53:28 +01:00
Willy Tarreau
09f24569d4 REORG: fd: centralize the processing of speculative events
Speculative events are independant on the poller, so they can be
centralized in fd.c.
2012-11-11 17:45:39 +01:00
Willy Tarreau
6ea20b1acb REORG: fd: move the fd state management from ev_sepoll
ev_sepoll already provides everything needed to manage FD events
by only manipulating the speculative I/O list. Nothing there is
sepoll-specific so move all this to fd.
2012-11-11 17:45:39 +01:00
Willy Tarreau
7be79a41e1 REORG: fd: move the speculative I/O management from ev_sepoll
The speculative I/O will need to be ported to all pollers, so move
this to fd.c.
2012-11-11 17:45:39 +01:00
Willy Tarreau
1720abd727 MEDIUM: fd: don't unset fdtab[].updated upon delete
We must not remove the .updated flag otherwise we risk having to
reallocate a new updt entry if the same fd is reused.
2012-11-11 17:45:39 +01:00
William Lallemand
3203ff4617 MINOR: log-format: check number of arguments in cfgparse.c
Exit with error if there is a second argument in the 'log-format' and
'unique-id-format' options. It is convenient when we forgot to escape
spaces.
2012-11-11 17:45:39 +01:00
Cyril Bonté
6162c43a0a BUILD: report zlib support in haproxy -vv
Compression algorithms are not always supported depending on build options.
"haproxy -vv" now reports if zlib is supported and lists compression algorithms
also supported.
2012-11-10 20:36:46 +01:00
Willy Tarreau
b1fbd050ec BUILD: compression: remove a build warning
gcc emits this warning while building free_zlib() :
  src/compression.c: In function `free_zlib':
  src/compression.c:403: warning: 'pool' might be used uninitialized in this function

This is not a bug as the pool cannot take other values, but let's
pre-initialize is to null to fix the warning.
2012-11-10 17:49:37 +01:00
William Lallemand
d85f917daf MINOR: compression: maximum compression rate limit
This patch adds input and output rate calcutation on the HTTP compresion
feature.

Compression can be limited with a maximum rate value in kilobytes per
second. The rate is set with the global 'maxcomprate' option. You can
change this value dynamicaly with 'set rate-limit http-compression
global' on the UNIX socket.
2012-11-10 17:47:27 +01:00
William Lallemand
f3747837e5 MINOR: compression: tune.comp.maxlevel
This option allows you to set the maximum compression level usable by
the compression algorithm. It affects CPU usage.
2012-11-10 17:47:07 +01:00
Finn Arne Gangstad
0a410e81fb BUG: http: revert broken optimisation from 82fe75c1a7
This optimisation causes haproxy to time out requests that result
in two TCP packets, one packet containing the header, and one
packet containing the actual data. This is a very typical type
of response from a lot of servers.

[Willy: I suspect the fix might have an impact on the compression code
 which I'm not sure completely handles calls with 0 bytes to forward]
2012-11-10 17:38:36 +01:00
Willy Tarreau
5fddab0a56 OPTIM: stream_interface: disable reading when CF_READ_DONTWAIT is set
CF_READ_DONTWAIT was designed to avoid getting an EAGAIN upon recv() when
very few data are expected. It prevents the reader from looping over
recv(). Unfortunately with speculative I/O, it is very common that the
same event has the time to be called twice before the task handles the
data and disables the recv(). This is because not all tasks are always
processed at once.

Instead of leaving the buffer free-wheeling and doing an EAGAIN, we
disable reading as soon as the first recv() succeeds. This way we're
sure that only the next wakeup of the task will re-enable it if needed.

Doing so has totally removed the EAGAIN we were seeing till now (30% of
recv).
2012-11-10 00:23:38 +01:00
Willy Tarreau
037d2c1f8f MAJOR: sepoll: make the poller totally event-driven
At the moment sepoll is not 100% event-driven, because a call to fd_set()
on an event which is already being polled will not change its state.

This causes issues with OpenSSL because if some I/O processing is interrupted
after clearing the I/O event (eg: read all data from a socket, can't put it
all into the buffer), then there is no way to call the SSL_read() again once
the buffer releases some space.

The only real solution is to go 100% event-driven. The principle is to use
the spec list as an event cache and that each time an I/O event is reported
by epoll_wait(), this event is automatically scheduled for addition to the
spec list for future calls until the consumer explicitly asks for polling
or stopping.

Doing this is a bit tricky because sepoll used to provide a substantial
number of optimizations such as event merging. These optimizations have
been maintained : a dedicated update list is affected when events change,
but not the event list, so that updates may cancel themselves without any
side effect such as displacing events. A specific case was considered for
handling newly created FDs as soon as they are detected from within the
poll loop. This ensures that their read or write operation will always be
attempted as soon as possible, thus reducing the number of poll loops and
process_session wakeups. This is especially true for newly accepted fds
which immediately perform their first recv() call.

Two new flags were added to the fdtab[] struct to tag the fact that a file
descriptor already exists in the update list. One flag indicates that a
file descriptor is new and has just been created (fdtab[].new) and the other
one indicates that a file descriptor is already referenced by the update list
(fdtab[].updated). Even if the FD state changes during operations or if the
fd is closed and replaced, it's not an issue because the update flag remains
and is easily spotted during list walks. The flag must absolutely reflect the
presence of the fd in the update list in order to avoid overflowing the update
list with more events than there are distinct fds.

Note that this change also recovers the small performance loss introduced
by its connection counter-part and goes even beyond.
2012-11-10 00:17:27 +01:00
Willy Tarreau
c9f7804aad BUG/MAJOR: always clear the CO_FL_WAIT_* flags after updating polling flags
The CO_FL_WAIT_* flags were not cleared after updating polling flags.
This means that any caller of these functions that did not clear it
would enable polling instead of speculative I/O. This happens during
the stream interface update call which is performed from the session
handler for example.

As of now it's not a problem yet because speculative I/O and polling
are handled the same way. However with upcoming changes it does cause
some deadlocks because enabling read processing on a file descriptor
where everything was already read will do nothing until something new
happens on this FD.

The correct fix consists in clearing the flags while leaving the update
functions.

This fix does not need any backport as it was introduced with recent
connection changes (dev12) and not triggered until last commit.
2012-11-09 22:09:33 +01:00
Willy Tarreau
c8dd77fddf MAJOR: connection: remove the CO_FL_CURR_*_POL flag
This is the first step of a series of changes aiming at making the
polling totally event-driven. This first change consists in only
remembering at the connection level whether an FD was enabled or not,
regardless of the fact it was being polled or cached. From now on, an
EAGAIN will always be considered as a change so that the pollers are
able to manage a cache and to flush it based on such events. One of
the noticeable effect is that conn_fd_handler() is called once more
per session (6 instead of 5 min) but other update functions are less
called.

Note that the performance loss caused by this change at the moment is
quite significant, around 2.5%, but the change is needed to have SSL
working correctly in all situations, even when data were read from the
socket and stored in the invisible cache, waiting for some room in the
channel's buffer.
2012-11-09 22:09:33 +01:00
Willy Tarreau
815f5ecffa BUG/MINOR: session: mark the handshake as complete earlier
There is a small waste of CPU cycles when no handshake is required on an
accepted connection, because we had to perform one call to conn_fd_handler()
to mark the connection CONNECTED and to call process_session() again to say
that nothing happened.

By marking the connection CONNECTED when there is no pending handshake, we
avoid this extra call to process_session().
2012-11-09 22:09:08 +01:00
Willy Tarreau
798f4325fa OPTIM: session: don't process the whole session when only timers need a refresh
Having a global expiration timer for a task means that the tasks are regularly
woken up (at least after each expiration timer). It's totally useless and counter
productive to process the whole session upon each such wakeup, and it's fairly
easy to detect such wakeups, so let's just update the task's timer and return
to sleep when this happens.

For 100k concurrent connections with 10s of timeouts, this can save 10k wakeups
per second, which is not bad.
2012-11-08 16:55:07 +01:00
William Lallemand
9d5f5480fd MEDIUM: compression: limit RAM usage
With the global maxzlibmem option, you are able ton control the maximum
amount of RAM usable for HTTP compression.

A test is done before each zlib allocation, if the there isn't available
memory, the test fail and so the zlib initialization, so data won't be
compressed.
2012-11-08 15:23:30 +01:00
William Lallemand
4c49fae985 MINOR: compression: init before deleting headers
Init the compression algorithm before modifying the response headers. So
if the compression init fail, the headers won't be modified.
2012-11-08 15:23:30 +01:00
William Lallemand
552df67100 MINOR: compression: try init in cfgparse.c
Try to init and deinit the algorithm in the configuration parser and
exit with error if it doesn't work.
2012-11-08 15:23:30 +01:00
William Lallemand
2b50247695 MEDIUM: use pool for zlib
Don't use the zlib allocator anymore, 5 pools are used for the zlib
compression. Their sizes depends of the window size and the memLevel in
deflateInit2.
2012-11-08 15:23:29 +01:00
William Lallemand
a509e4c332 MINOR: compression: memlevel and windowsize
The window size and the memlevel of the zlib are now configurable using
global options tune.zlib.memlevel and tune.zlib.windowsize.

It affects the memory consumption of the zlib.
2012-11-08 15:23:29 +01:00
William Lallemand
08289f12f9 BUILD: remove dependency to zlib.h
The build was dependent of the zlib.h header, regardless of the USE_ZLIB
option. The fix consists of several #ifdef in the source code.

It removes the overhead of the zstream structure in the session when you
don't use the option.
2012-11-05 10:23:16 +01:00
William Lallemand
1c2d622d82 CLEANUP: use struct comp_ctx instead of union
Replace union comp_ctx by struct comp_ctx.

Use struct comp_ctx * in the init/add_data/flush/reset/end prototypes of
compression.h functions.
2012-11-05 10:23:16 +01:00
Willy Tarreau
e3224e870f BUG/MINOR: session: ensure that we don't retry connection if some data were sent
With extra-large buffers, it is possible that a lot of data are sent upon
connection establishment before the session is notified. The issue is how
to handle a send() error after some data were actually sent.

At the moment, only a connection error is reported, causing a new connection
attempt and send() to restart after the last data. We absolutely don't want
to retry the connect() if at least one byte was sent, because those data are
lost.

The solution consists in reporting exactly what happens, which is :
  - a successful connection attempt
  - a read/write error on the channel

That way we go on with sess_establish(), the response analysers are called
and report the appropriate connection state for the error (typically a server
abort while waiting for a response). This mechanism also guarantees that we
won't retry since it's a success. The logs also report the correct connect
time.

Note that 1.4 is not directly affected because it only attempts one send(),
so it cannot detect a send() failure here and distinguish it form a failed
connection attempt. So no backport is needed. Also, this is just a safe belt
we're taking, since this issue should not happen anymore since previous commit.
2012-10-29 23:31:04 +01:00
Willy Tarreau
ed7f836f07 BUG/MINOR: stream_interface: don't loop over ->snd_buf()
It is stupid to loop over ->snd_buf() because the snd_buf() itself already
loops and stops when system buffers are full. But looping again onto it,
we lose the information of the full buffers and perform one useless syscall.

Furthermore, this causes issues when dealing with large uploads while waiting
for a connection to establish, as it can report a server reject of some data
as a connection abort, which is wrong.

1.4 does not have this issue as it loops maximum twice (once for each buffer
half) and exists as soon as system buffers are full. So no backport is needed.
2012-10-29 23:30:33 +01:00
Finn Arne Gangstad
cbb9a4b128 MINOR: compression: Enable compression for IE6 w/SP2, IE7 and IE8
Some old browsers that have a user-agent starting with "Mozilla/4" do
not support compressison correctly, so disable compression for those.

Internet explorer 6 after Windows XP service pack 2, IE 7, and IE 8,
do however support compression and still have a user agent starting
with Mozilla/4, so we try to enable compression for those.

MSIE has a user-agent on this form:
Mozilla/4.0 (compatible; MSIE <version>; ...)

98% of MSIE 6 SP2 user agents start with
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1
The remaining 2% have additional flags before "SV1".

This simplified matching looking for MSIE at exactly position 25
and SV1 at exacly position 51 gives a few false negatives, so sometimes
a compression opportunity is lost.

A test against 3 hours of traffic to around 3000 news sites worldwide
gives less than 0.007% (70ppm) missed compression opportunities.
2012-10-29 22:03:14 +01:00
Willy Tarreau
07115412d3 MEDIUM: stick-table: allocate the table key of size buffer size
Keys are copied from samples to stick_table_key. If a key is larger
than the stick_table_key, we have an overflow. In pratice it does not
happen because it requires :
   1) a configuration with tune.bufsize larger than BUFSIZE (common)
   2) a stick-table configured with keys strictly larger than buffers
   3) extraction of data larger than BUFSIZE (eg: using payload())

Points 2 and 3 don't make any sense for a real world configuration. That
said the issue needs be fixed. The solution consists in allocating it the
same size as the global buffer size, just like the samples. This fixes the
issue.
2012-10-29 21:56:59 +01:00
Willy Tarreau
7e2c647ee7 MEDIUM: remove remains of BUFSIZE in HTTP auth and sample conversions
Sample conversions rely on two alternative buffers which were previously
allocated as static bufs of size BUFSIZE. Now they're initialized to the
global buffer size. It was the same for HTTP authentication. Note that it
seems that none of them was prone to any mistake when dealing with the
buffer size, but better stay on the safe side by maintaining the old
assumption that a trash buffer is always "large enough".
2012-10-29 20:44:36 +01:00
Willy Tarreau
19d14ef104 MEDIUM: make the trash be a chunk instead of a char *
The trash is used everywhere to store the results of temporary strings
built out of s(n)printf, or as a storage for a chunk when chunks are
needed.

Using global.tune.bufsize is not the most convenient thing either.

So let's replace trash with a chunk and directly use it as such. We can
then use trash.size as the natural way to get its size, and get rid of
many intermediary chunks that were previously used.

The patch is huge because it touches many areas but it makes the code
a lot more clear and even outlines places where trash was used without
being that obvious.
2012-10-29 16:57:30 +01:00
Willy Tarreau
7780473c3b CLEANUP: replace chunk_printf() with chunk_appendf()
This function's naming was misleading as it is used to append data
at the end of a string, causing some surprizes when used for the
first time!

Add a chunk_printf() function which does what its name suggests.
2012-10-29 16:14:26 +01:00
Willy Tarreau
acbbe900e2 CLEANUP: completely remove trashlen
Commit c919dc66 did not remove the trashlen assigment.
2012-10-29 13:29:39 +01:00
Yuxans Yao
4e25b015a7 MINOR: log: add '%Tl' to log-format
The '%Tl' is similar to '%T', but using local timezone.
2012-10-29 11:55:26 +01:00
Willy Tarreau
08b4d79d31 BUG: compression: disable auto-close and enable MSG_MORE during transfer
We don't want the lower layer to forward a close while we're compressing,
and we want the system to fuse outgoing TCP segments using MSG_MORE as
much as possible to save round trips that can emerge from sending short
packets with a PUSH flag.

A test on a remote busy DSL line consisting in compressing a 100MB file
on the fly full of zeroes only showed a transfer rate of a few kB/s due
to these round trips.
2012-10-27 01:36:34 +02:00
Willy Tarreau
70737d142f MINOR: compression: add an offload option to remove the Accept-Encoding header
This is used when it is desired that backend servers don't compress
(eg: because of buggy implementations).
2012-10-27 01:13:24 +02:00
Willy Tarreau
f2943dccd0 MAJOR: session: detach the connections from the stream interfaces
We will need to be able to switch server connections on a session and
to keep idle connections. In order to achieve this, the preliminary
requirement is that the connections can survive the session and be
detached from them.

Right now they're still allocated at exactly the same place, so when
there is a session, there are always 2 connections. We could soon
improve on this by allocating the outgoing connection only during a
connect().

This current patch touches a lot of code and intentionally does not
change any functionnality. Performance tests show no regression (even
a very minor improvement). The doc has not yet been updated.
2012-10-26 20:15:20 +02:00
Willy Tarreau
c919dc66a3 CLEANUP: remove trashlen
trashlen is a copy of global.tune.bufsize, so let's stop using it as
a duplicate, fall back to the original bufsize, it's less confusing
this way.
2012-10-26 20:04:27 +02:00
Willy Tarreau
5f2877a7dd BUG/MEDIUM: tcp: transparent bind to the source only when address is set
Thomas Heil reported that health checks did not work anymore when a backend
or server has "usesrc clientip". This is because the source address is not
set and tcp_bind_socket() tries to bind to that address anyway.

The solution consists in explicitly clearing the source address in the checks
and to make tcp_bind_socket() avoid binding when the address is not set. This
also has an indirect benefit that a useless bind() syscall will be avoided
when using "source 0.0.0.0 usesrc clientip" in health checks.
2012-10-26 20:04:27 +02:00
Willy Tarreau
772f0dd545 BUG/MEDIUM: command-line option -D must have precedence over "debug"
From the beginning it has been said that -D must always be used on the
command line from startup scripts so that haproxy does not accidentally
stay in foreground when loaded from init script... Except that this has
not been true for a long time now.

The fix is easy and must be backported to 1.4 too which is affected.
2012-10-26 16:04:28 +02:00
Emeric Brun
61694ab373 MINOR: ssl: checks the consistency of a private key with the corresponding certificate 2012-10-26 15:10:32 +02:00
Emeric Brun
a7aa309c44 MINOR: ssl: add 'crt' statement on server.
crt: client certificate to send
2012-10-26 15:10:10 +02:00
Emeric Brun
ce5ad80c34 MINOR: ssl: add pattern and ACLs fetches 'ssl_c_notbefore', 'ssl_c_notafter', 'ssl_f_notbefore' and 'ssl_f_notafter'
ssl_c_notbefore: start date of client cert (string, eg: "121022182230Z" for YYMMDDhhmmss[Z])
ssl_c_notafter: end date of client cert (string, eg: "121022182230Z" for YYMMDDhhmmss[Z])
ssl_f_notbefore: start date of frontend cert (string, eg: "121022182230Z" for YYMMDDhhmmss[Z])
ssl_f_notafter: end date of frontend cert (string, eg: "121022182230Z" for YYMMDDhhmmss[Z])
2012-10-26 15:08:00 +02:00
Emeric Brun
521a011999 MINOR: ssl: add pattern and ACLs fetches 'ssl_c_key_alg' and 'ssl_f_key_alg'
ssl_c_key_alg: algo used to encrypt the client's cert key (ex: rsaEncryption)
ssl_f_key_alg: algo used to encrypt the frontend's cert key (ex: rsaEncryption)
2012-10-26 15:08:00 +02:00
Emeric Brun
7f56e74841 MINOR: ssl: add pattern and ACLs 'ssl_c_sig_alg' and 'ssl_f_sig_alg'
ssl_c_sig_alg: client cert signature algo (string). Ex: "RSA-SHA1"
ssl_f_sig_alg: frontend cert signature algo (string). Ex: "RSA-SHA1"
2012-10-26 15:08:00 +02:00
Emeric Brun
8785589ba3 MINOR: ssl: add pattern and ACLs fetches 'ssl_c_s_dn', 'ssl_c_i_dn', 'ssl_f_s_dn' and 'ssl_c_i_dn'
ssl_c_s_dn : client cert subject DN (string)
ssl_c_i_dn : client cert issuer DN (string)
ssl_f_s_dn : frontend cert subject DN (string)
ssl_f_i_dn : frontend cert issuer DN (string)

Return either the full DN without params, or just the DN entry (first param) or
its specific occurrence (second param).
2012-10-26 15:08:00 +02:00
Emeric Brun
a7359fd6dd MINOR: ssl: add pattern and ACLs fetches 'ssl_c_version' and 'ssl_f_version'
ssl_c_version : version of the cert presented by the client  (integer)
ssl_f_version : version of the cert presented by the frontend  (integer)
2012-10-26 15:08:00 +02:00
Willy Tarreau
8d5984010e MINOR: ssl: add pattern and ACLs fetches 'ssl_c_serial' and 'ssl_f_serial'
ssl_c_serial: serial of the certificate presented by the client.
ssl_f_serial: serial of the certificate presentend by the frontend.
2012-10-26 15:08:00 +02:00
Emeric Brun
fe68f682b1 MINOR: ssl: add pattern fetch 'ssl_fc_session_id'
This fetch returns the SSL ID of the front connection. Useful to stick
on a given client.
2012-10-26 15:07:59 +02:00
Emeric Brun
589fcadbd9 MINOR: ssl: add pattern and ACLs fetches 'ssl_fc_protocol', 'ssl_fc_cipher', 'ssl_fc_use_keysize' and 'ssl_fc_alg_keysize'
Some front connection fetches :
- ssl_fc_protocol = protocol name (string)
- ssl_fc_cipher = cipher name (string)
- ssl_fc_use_keysize = symmetric cipher key size used in bits (integer)
- ssl_fc_alg_keysize = symmetric cipher key size supported in bits (integer)
2012-10-26 15:07:59 +02:00
Emeric Brun
2525b6bb92 MINOR: conf: rename all ssl modules fetches using prefix 'ssl_fc' and 'ssl_c'
SSL fetches were renamed :
  ssl_fc_* = Front Connection (attributes of the connection itself)
  ssl_c_*  = Client side certificate
2012-10-26 15:07:59 +02:00
Willy Tarreau
3476364ce9 BUILD: fix coexistence of openssl and zlib
The crappy zlib and openssl libs both define a free_func as a different typedef.
That's a very clever idea to use such a generic name in general purpose libraries,
really... The zlib one is easier to redefine than openssl's, so let's only fix this
one.
2012-10-26 15:07:59 +02:00
Willy Tarreau
3c7b97b9f9 BUG/MINOR: http: compression should consider all Accept-Encoding header values
Right now commit 82fe75c1 came with a minor bug limiting the check to the first
accept-encoding header value only.
2012-10-26 14:52:02 +02:00
Willy Tarreau
7e488d781c MINOR: compression: optimize memLevel to improve byte rate
Decreasing the deflateInit2's memLevel parameter from 9 to 8 does not
affect the compression ratio and increases the compression speed by 12%.
Lower values do not increase transfer speed but decrease the compression
ratio so it looks like 8 is optimal.
2012-10-26 11:36:40 +02:00
Willy Tarreau
05d846092f MINOR: compression: automatically disable compression for older browsers
A number of older browsers have many issues with compressed contents. It
happens that all these older browsers announce themselves as "Mozilla/4"
and that despite not being all broken, the amount of working browsers
announcing themselves this way compared to all other ones is so tiny
that it's not worth wasting cycles trying to adapt to every specific
one.

So let's simply disable compression for these older browsers.

More information on this very detailed article :

   http://zoompf.com/2012/02/lose-the-wait-http-compression
2012-10-26 02:54:31 +02:00
William Lallemand
82fe75c1a7 MEDIUM: HTTP compression (zlib library support)
This commit introduces HTTP compression using the zlib library.

http_response_forward_body has been modified to call the compression
functions.

This feature includes 3 algorithms: identity, gzip and deflate:

  * identity: this is mostly for debugging, and it was useful for
  developping the compression feature. With Content-Length in input, it
  is making each chunk with the data available in the current buffer.
  With chunks in input, it is rechunking, the output chunks will be
  bigger or smaller depending of the size of the input chunk and the
  size of the buffer. Identity does not apply any change on data.

  * gzip: same as identity, but applying a gzip compression. The data
  are deflated using the Z_NO_FLUSH flag in zlib. When there is no more
  data in the input buffer, it flushes the data in the output buffer
  (Z_SYNC_FLUSH). At the end of data, when it receives the last chunk in
  input, or when there is no more data to read, it writes the end of
  data with Z_FINISH and the ending chunk.

  * deflate: same as gzip, but with deflate algorithm and zlib format.
  Note that this algorithm has ambiguous support on many browsers and
  no support at all from recent ones. It is strongly recommended not
  to use it for anything else than experimentation.

You can't choose the compression ratio at the moment, it will be set to
Z_BEST_SPEED (1), as tests have shown very little benefit in terms of
compression ration when going above for HTML contents, at the cost of
a massive CPU impact.

Compression will be activated depending of the Accept-Encoding request
header. With identity, it does not take care of that header.

To build HAProxy with zlib support, use USE_ZLIB=1 in the make
parameters.

This work was initially started by David Du Colombier at Exceliance.
2012-10-26 02:30:48 +02:00
Willy Tarreau
54d23dfc07 CLEANUP: http: rename HTTP_MSG_DATA_CRLF state
This state's name is confusing as it is only used with chunked encoding
and makes newcomers think it's also related to the content-length. Let's
call it CHUNK_CRLF to clear any doubt on this.
2012-10-26 01:13:52 +02:00
Willy Tarreau
3dd0c4e20e OPTIM: tools: inline hex2i()
This tiny function was not inlined because initially not much used.
However it's been used un the chunk parser for a while and it became
one of the most CPU-cycle eater there. By inlining it, the chunk parser
speed was increased by 74 %. We're almost 3 times faster than original
with just the last 4 commits.
2012-10-26 01:13:24 +02:00
Willy Tarreau
24e6d972aa OPTIM: http: inline http_parse_chunk_size() and http_skip_chunk_crlf()
These functions are not that long and the compiler inlines them well. Doing
so has sped up the chunked encoding parser by 41% !

Note that http_forward_trailers was also declared static because it's not
exported.
2012-10-26 01:12:40 +02:00
Willy Tarreau
55a6906125 OPTIM: channel: inline channel_forward's fast path
Most calls to channel_forward() are performed with short byte counts and
are already optimized in channel_forward() taking just a few instructions.
Thus it's a waste of CPU cycles to call a function for this, let's just
inline the short byte count case and fall back to the common one for
remaining situations.

Doing so has increased the chunked encoding parser's performance by 12% !
2012-10-26 01:08:01 +02:00
Cyril Bonté
69fa99292e MEDIUM: http: accept IPv6 values with (s)hdr_ip acl
Commit ceb4ac9c states that IPv6 values are accepted by "hdr_ip" acl,
but the code didn't allow it. This patch provides the ability to accept IPv6
values.
2012-10-25 14:41:33 +02:00
Cyril Bonté
9ccf661225 BUG/MAJOR: fix a segfault on option http_proxy and url_ip acl
url2sa() mistakenly uses "addr" as a reference. This causes a segfault when
option http_proxy or url_ip are used.

This bug was introduced in haproxy 1.5 and doesn't need to be backported.
2012-10-25 08:31:57 +02:00
Cyril Bonté
4c01beb64b BUG/MEDIUM: acls using IPv6 subnets patterns incorrectly match IPs
Some tests revealed that IPs not in the range of IPv6 subnets incorrectly
matched (for example "acl BUG src 2804::/16" applied to a src IP "127.0.0.1").

This is caused by the acl_match_ip() function applies a mask in host byte
order, whereas it should be in network byte order.
2012-10-24 01:00:53 +02:00
Willy Tarreau
35b7b16818 MEDIUM: cli: allow the stats socket to be bound to a specific set of processes
Using "stats bind-process", it becomes possible to indicate to haproxy which
process will get the incoming connections to the stats socket. It will also
shut down the warning when nbproc > 1.
2012-10-22 23:17:18 +02:00
Willy Tarreau
153c3cafd7 BUG/MAJOR: connection: risk of crash on certain tricky close scenario
In some circumstances, if the connection to the server is aborted while
some data were planned to be sent and the poller reported an ability to
send, then conn_fd_handler() would still call conn->data->send(), causing
the data layer to dereference the now NULL conn->xprt and crash.

So we have to check for conn->xprt validity before calling the data
layer.

This issue was introduced after 1.5-dev12 so it does not need any backport
and does not affect any released version.

Special thanks go to Cristian Ditoiu who once again provided amazing help
to troubleshoot this bug !
2012-10-22 22:47:55 +02:00
Willy Tarreau
6b3b0d4736 MEDIUM: listener: provide a fallback for accept4() when not supported
It happens that on some systems, the libc is recent enough to permit
building with accept4() but the kernel does not support it. The result
is then a disaster since no connection is accepted. We now detect this
and automatically fall back to accept() and fcntl() when this happens.
2012-10-22 19:32:55 +02:00
Emeric Brun
a068a2951d MINOR: sample: export 'sample_get_trash_chunk(void)'
This will be used on external fetch modules.
2012-10-22 18:54:24 +02:00
Emeric Brun
07ca496ea9 MINOR: acl: add parse and match primitives to use binary type on ACLs
Binary ACL match patterns can now be entered as hex digit strings.
2012-10-22 18:54:24 +02:00
Emeric Brun
8ac33d99f2 MINOR: sample: manage binary to string type convertion in stick-table and samples.
Binary type is converted to a null terminated hexa string.
2012-10-22 18:54:15 +02:00
Willy Tarreau
fc47f91c9c BUG/MEDIUM: http: set DONTWAIT on data when switching to tunnel mode
Jaroslaw Bojar diagnosed an issue when haproxy switches to tunnel mode
after a transfer. The response data are sent with the MSG_MORE flag,
causing them to be needlessly queued in the kernel. In order to fix this,
we set the CF_NEVER_WAIT flag on the channels when switching to tunnel
mode.

One issue remained with client-side keep-alive : if the response is sent
before the end of the request, it suffers the same issue for the same
reason. This is easily addressed by setting the CF_SEND_DONTWAIT flag
on the channel when the response has been parsed and we're waiting for
the other side.

The same issue is present in 1.4 so the fix must be backported.
2012-10-20 10:41:37 +02:00
Willy Tarreau
566dc5545b MINOR: ssl: improve socket behaviour upon handshake abort.
While checking haproxy's SSL stack with www.ssllabs.com, it appeared that
immediately closing upon a failed handshake caused a TCP reset to be emitted.
This is because OpenSSL does not consume pending data in the socket buffers.
One side effect is that if the reset packet is lost, the client might not get
it. So now when a handshake fails, we try to clean the socket buffers before
closing, resulting in a clean FIN instead of an RST.
2012-10-19 20:56:59 +02:00
Willy Tarreau
2e845be249 MEDIUM: sample: pass an empty list instead of a null for fetch args
ACL and sample fetches use args list and it is really not convenient to
check for null args everywhere. Now for empty args we pass a constant
list of end of lists. It will allow us to remove many useless checks.
2012-10-19 19:49:09 +02:00
Willy Tarreau
f22a50836d MINOR: sample: accept fetch keywords without parenthesis
fetch keywords which support arguments do not support being called
without parenthesis even if all arguments are optional. Let's fix
this to allow fetch keywords without parenthesis as is already done
in ACLs.
2012-10-19 16:47:23 +02:00
Willy Tarreau
ad8f8e8ffb MINOR: chunk: provide string compare functions
It's sometimes needed to be able to compare a zero-terminated string with a
chunk, so we now have two functions to do that, one strcmp() equivalent and
one strcasecmp() equivalent.
2012-10-19 15:18:06 +02:00
Willy Tarreau
8c866a3858 BUG: ssl: fix ssl_sni ACLs to correctly process regular expressions
ssl_sni_reg was using acl_parse_str which is wrong since we're parsing
a regex. Additionally, neither _end nor _reg may be looked up.
2012-10-19 14:34:30 +02:00
Willy Tarreau
6c9a3d5585 MEDIUM: ssl: add support for the "npn" bind keyword
The ssl_npn match could not work by itself because clients do not use
the NPN extension unless the server advertises the protocols it supports.
Thanks to Simone Bordet for the explanations on how to get it right.
2012-10-18 19:03:00 +02:00
Willy Tarreau
338a4fc2a8 BUILD: ssl: fix shctx build on older compilers
gcc < 3 breaks on shctx because of the missing arg in the lock macros.
We don't need the arg at all, it's not used.
2012-10-18 19:03:00 +02:00
Willy Tarreau
a33c654cb1 MINOR: ssl: add 'ssl_npn' sample/acl to extract TLS/NPN information
This may be used to distinguish between SPDY versions for example.
2012-10-15 13:19:06 +02:00
Willy Tarreau
c93f7959e5 CLEANUP: session: remove term_trace which is not used anymore
This field was used to trace precisely where a session was terminated
but it did not survive code rearchitecture and was not used at all
anymore. Let's get rid of it.
2012-10-13 11:10:30 +02:00
Willy Tarreau
9b28e03b66 MAJOR: channel: replace the struct buffer with a pointer to a buffer
With this commit, we now separate the channel from the buffer. This will
allow us to replace buffers on the fly without touching the channel. Since
nobody is supposed to keep a reference to a buffer anymore, doing so is not
a problem and will also permit some copy-less data manipulation.

Interestingly, these changes have shown a 2% performance increase on some
workloads, probably due to a better cache placement of data.
2012-10-13 09:07:52 +02:00
Willy Tarreau
f332af7715 CLEANUP: acl: use 'chn' instead of 'b' to name channel pointers
As with previous patches, this naming is confusing.
2012-10-12 23:58:13 +02:00
Willy Tarreau
cb76e5978c CLEANUP: stream_interface: use 'chn' instead of 'b' to name channel pointers
As with previous patches, this naming is confusing.
2012-10-12 23:56:57 +02:00
Willy Tarreau
697d85045a CLEANUP: tcp: use 'chn' instead of 'buf' or 'b' for channel pointer names
Same as previous patches, avoid confusion in local variable names.
2012-10-12 23:53:39 +02:00
Willy Tarreau
974ced6305 CLEANUP: channel: use 'chn' instead of 'buf' as local variable names
It's too confusing to see buf->buf everywhere where the first buf is
a channel. Let's fix this now.
2012-10-12 23:11:02 +02:00
Willy Tarreau
cdbdd52a38 CLEANUP: http: use 'chn' to name channel variables, not 'buf'
These "buf" were confusing as they were really refering to channels. At
most places, a buffer was really all what was needed, so a struct buffer
was used instead. It is possible that the performance has slightly increased
by the removal of pointer offset in many pointer operations by directly
using the buffer pointer instead of the channel pointer.
2012-10-12 23:02:51 +02:00
Willy Tarreau
394db379eb REORG: http: rename msg->buf to msg->chn since it's a channel
It's extremely confusing to have all those msg->buf->buf everywhere after
the extraction of the buffer from the channel. Let's clean this up.
2012-10-12 22:40:39 +02:00
Willy Tarreau
ffc3fcd6da MEDIUM: log: report SSL ciphers and version in logs using logformat %sslc/%sslv
These two new log-format tags report the SSL protocol version (%sslv) and the
SSL ciphers (%sslc) used for the connection with the client. For instance, to
append these information just after the client's IP/port address information
on an HTTP log line, use the following configuration :

    log-format %Ci:%Cp\ %sslv:%sslc\ [%t]\ %ft\ %b/%s\ %Tq/%Tw/%Tc/%Tr/%Tt\ %st\ %B\ %cc\ \ %cs\ %tsc\ %ac/%fc/%bc/%sc/%rc\ %sq/%bq\ %hr\ %hs\ %{+Q}r

It will report a line such as the following one :

    Oct 12 20:47:30 haproxy[9643]: 127.0.0.1:43602 TLSv1:AES-SHA [12/Oct/2012:20:47:30.303] stick2~ stick2/s1 7/0/12/0/19 200 145 - - ---- 0/0/0/0/0 0/0 "GET /?t=0 HTTP/1.0"
2012-10-12 20:48:51 +02:00
Willy Tarreau
4f65356a22 MINOR: log: make lf_text use a const char *
lf_text() should use a const char * otherwise it makes it more complex
to use data coming from const strings.
2012-10-12 20:30:51 +02:00
Willy Tarreau
93dbc2bc0e MEDIUM: log: add a new LW_XPRT flag to pin the transport layer
This flag will have to be set on log tags which require transport layer
information. They will prevent the conn_xprt_close() call from releasing
the transport layer too early.
2012-10-12 20:30:51 +02:00
Willy Tarreau
1e954913de MEDIUM: connection: add a flag to hold the transport layer
When we start logging SSL information, we need the SSL struct to be
present even past the conn_xprt_close() call. In order to achieve this,
we should use refcounting on the connection and the transport layer. At
the moment it's not worth using plain refcounting as only the logs require
this, so instead of real refcounting we just use a flag which will be set
by the log subsystem when SSL data need to be logged.

What happens then is that the xprt->close() call is ignored and the
transport layer is closed again during session_free(), after the log
line is emitted.
2012-10-12 20:30:50 +02:00
Willy Tarreau
91083f5c8f BUG/MEDIUM: session: enable the conn_session_update() callback
This callback was introduced by commit 9683e9a0 but never enabled because
the CO_FL_WAKE_DATA flag was not set. The result is that this function is
never called when an SSL handshake fails, so the connection is only closed
on timeout.
2012-10-12 20:30:38 +02:00
Willy Tarreau
e9909f4e50 BUG/MINOR: session: fix some leftover from debug code
Commit 82569f91 moved the health and monitor-net checks to session.c
but a debug test introduced 0& to disable MSG_DONTWAIT in the recv()
call and this debug code remained there. Since the socket is marked
non-blocking, there should be no effect but it's dangerous to keep
such a thing here.
2012-10-12 17:36:40 +02:00
Willy Tarreau
773d65f413 MEDIUM: log: suffix the frontend's name with '~' when using SSL
Until now it was not possible to know from the logs whether the incoming
connection was made over SSL or not. In order to address this in the existing
log formats, a new log format %ft was introduced, to log the frontend's name
suffixed with its transport layer. The only transport layer in use right now
is '~' for SSL, so that existing log formats for non-SSL traffic are not
affected at all, and SSL log formats have the frontend's name suffixed with
'~'.

The TCP, HTTP and CLF log format now use %ft instead of %f. This does not
affect existing log formats which still make use of %f however.
2012-10-12 14:56:11 +02:00
Emeric Brun
ef42d9219d MINOR: ssl: add statements 'verify', 'ca-file' and 'crl-file' on servers.
It now becomes possible to verify the server's certificate using the "verify"
directive. This one only supports "none" and "required", as it does not make
much sense to also support "optional" here.
2012-10-12 12:05:15 +02:00
Emeric Brun
f9c5c4701c MINOR: ssl: add statement 'no-tls-tickets' on server side. 2012-10-12 11:48:55 +02:00
Emeric Brun
ecc91fea7b MEDIUM: ssl: reject ssl server keywords in default-server statement
At the moment they are ignored, but they were not rejected so they could
cause confusion in some configurations.
2012-10-12 11:47:06 +02:00
Emeric Brun
94324a4c87 MINOR: ssl: move ssl context init for servers from cfgparse.c to ssl_sock.c 2012-10-12 11:37:36 +02:00
Willy Tarreau
92faadff78 MEDIUM: ssl: move "server" keyword SSL options parsing to ssl_sock.c
All SSL-specific "server" keywords are now processed in ssl_sock.c. At
the moment, there is no more "not implemented" hint when SSL is disabled,
but keywords could be added in server.c if needed.
2012-10-10 23:09:23 +02:00
Willy Tarreau
7151633945 BUG/MEDIUM: config: check-send-proxy was ignored if SSL was not builtin
Improper insertion within #if/#endif SSL causes the check-send-proxy state
not to be automatically enabled if SSL is disabled at build time.
2012-10-10 23:01:14 +02:00
Willy Tarreau
dff5543618 MEDIUM: server: move parsing of keyword "id" to server.c
This is the first keyword to be moved to server.c.
2012-10-10 17:51:05 +02:00
Willy Tarreau
d0d6059630 MEDIUM: server: check for registered keywords when parsing unknown keywords
At this point, no server keyword is registered yet. The help line does
not report supported keywords anymore since it lists the registered ones
only.
2012-10-10 17:50:42 +02:00
Willy Tarreau
70eec3832f MINOR: standard: make indent_msg() support empty messages
indent_msg() is called with dynamically generated messages, so these
may be empty (NULL) when an empty list is being dumped. Support this
and return a NULL too.
2012-10-10 17:42:39 +02:00
Willy Tarreau
21faa91be6 MINOR: server: add minimal infrastructure to parse keywords
Just like with the "bind" lines, we'll switch the "server" line
parsing to keyword registration. The code is essentially the same
as for bind keywords, with minor changes such as support for the
default-server keywords and support for variable argument count.
2012-10-10 17:42:39 +02:00
Willy Tarreau
1bc4aab290 MEDIUM: listener: add support for linux's accept4() syscall
On Linux, accept4() does the same as accept() except that it allows
the caller to specify some flags to set on the resulting socket. We
use this to set the O_NONBLOCK flag and thus to save one fcntl()
call in each connection. The effect is a small performance gain of
around 1%.

The option is automatically enabled when target linux2628 is set, or
when the USE_ACCEPT4 Makefile variable is set. If the libc is too old
to provide the equivalent function, this is automatically detected and
our own function is used instead. In any case it is possible to force
the use of our implementation with USE_MY_ACCEPT4.
2012-10-08 20:11:03 +02:00
Willy Tarreau
1b6c00cb99 BUG/MAJOR: ensure that hdr_idx is always reserved when L7 fetches are used
Baptiste Assmann reported a bug causing a crash on recent versions when
sticking rules were set on layer 7 in a TCP proxy. The bug is easier to
reproduce with the "defer-accept" option on the "bind" line in order to
have some contents to parse when the connection is accepted. The issue
is that the acl_prefetch_http() function called from HTTP fetches relies
on hdr_idx to be preinitialized, which is not the case if there is no L7
ACL.

The solution consists in adding a new SMP_CAP_L7 flag to fetches to indicate
that they are expected to work on L7 data, so that the proxy knows that the
hdr_idx has to be initialized. This is already how ACL and HTTP mode are
handled.

The bug was present since 1.5-dev9.
2012-10-05 22:46:09 +02:00
Willy Tarreau
71e451c74c CLEANUP: cttproxy: remove a warning on undeclared close()
This one is harmless and only happens on old systems anyway.
2012-10-05 22:18:07 +02:00
Emeric Brun
76d8895c49 MINOR: ssl: add defines LISTEN_DEFAULT_CIPHERS and CONNECT_DEFAULT_CIPHERS.
These ones are used to set the default ciphers suite on "bind" lines and
"server" lines respectively, instead of using OpenSSL's defaults. These
are probably mainly useful for distro packagers.
2012-10-05 22:11:15 +02:00
Emeric Brun
8694b9a682 MINOR: ssl: add 'force-sslv3' and 'force-tlsvXX' statements on server
These options force the SSL lib to use the specified protocol when
connecting to a server. They are complentary to no-tlsv*/no-sslv3.
2012-10-05 22:05:04 +02:00
Emeric Brun
2cb7ae5302 MINOR: ssl: add 'force-sslv3' and 'force-tlsvXX' statements on bind.
These options force the SSL lib to use the specified protocol. They
are complentary to no-tlsv*/no-sslv3.
2012-10-05 22:02:42 +02:00
Emeric Brun
8967549d52 MINOR: ssl: use bit fields to store ssl options instead of one int each
Too many SSL options already and some still to come, use a bit field
and get rid of all the integers. No functional change here.
2012-10-05 21:53:59 +02:00
Emeric Brun
fb510ea2b9 MEDIUM: conf: rename 'cafile' and 'crlfile' statements 'ca-file' and 'crl-file'
These names were not really handy.
2012-10-05 21:50:43 +02:00
Emeric Brun
9b3009b440 MEDIUM: conf: rename 'nosslv3' and 'notlsvXX' statements 'no-sslv3' and 'no-tlsvXX'.
These ones were really not easy to read nor write, and become confusing
with the next ones to be added.
2012-10-05 21:47:42 +02:00
Emeric Brun
c8e8d12257 MINOR: ssl: add 'crt-base' and 'ca-base' global statements.
'crt-base' sets root directory used for relative certificates paths.
'ca-base' sets root directory used for relative CAs and CRLs paths.
2012-10-05 21:46:52 +02:00
Emeric Brun
9fa8973abb BUG/MEDIUM: ssl: subsequent handshakes fail after server configuration changes
On server's configuration change, if the previously used
cipher is disabled, all subsequent connect attempts fail.

Fix consists in freeing cached session on handshake failure.
2012-10-05 21:46:52 +02:00
Willy Tarreau
3b5bc66554 BUG: connection: fix regression from commit 9e272bf9
Commit 9e272bf9 broke connection setup in TCP mode, the comment was
misleading and obviously wrong, as after a connection is established,
we *do* have none of the CONNECT* flags. However we can never have
them all at the same time, so let's use this to trigger a detection.
2012-10-05 21:29:37 +02:00
Emeric Brun
3c4bc6e10a MINOR: ssl: remove prefer-server-ciphers statement and set it as the default on ssl listeners. 2012-10-05 20:02:06 +02:00
Emeric Brun
ce08baa36d BUG/MINOR: build: Fix failure with USE_OPENSSL=1 and USE_FUTEX=1 on archs i486 and i686. 2012-10-05 20:00:03 +02:00
Emeric Brun
0914df894f BUG/MINOR: conf: Fix 'maxsslconn' statement error if built without OPENSSL. 2012-10-05 19:59:55 +02:00
Willy Tarreau
1c862c5920 MEDIUM: tcp: enable TCP Fast Open on systems which support it
If TCP_FASTOPEN is defined, then the "tfo" option is supported on
"bind" lines to enable TCP Fast Open (linux >= 3.6).
2012-10-05 16:22:35 +02:00
bedis
4c75cca8ba MINOR: samples: update the url_param fetch to match parameters in the path
It now supports an optional delimiter to allow to look for the parameter before
the query string.
2012-10-05 15:17:23 +02:00
Willy Tarreau
392e9390e6 CLEANUP: checks: remove minor warnings for assigned but not used variables
We don't use the return value from snd_buf/rcv_buf anymore since we only
rely on the connection flags.
2012-10-05 14:54:30 +02:00
Baptiste Assmann
e6baecfe23 BUILD: fix build issue without USE_OPENSSL
The SSL check referenced use_ssl which only exists when USE_OPENSSL is set.
2012-10-05 11:48:04 +02:00
Willy Tarreau
6c16adc661 MEDIUM: checks: enable the PROXY protocol with health checks
When health checks are configured on a server which has the send-proxy
directive and no "port" nor "addr" settings, the health check connections
will automatically use the PROXY protocol. If "port" or "addr" are set,
the "check-send-proxy" directive may be used to force the protocol.
2012-10-05 00:33:14 +02:00
Willy Tarreau
763a95bfde MEDIUM: checks: add the "check-ssl" server option
This option forces health checks to be sent over SSL even if the
address or port are not the standard ones.
2012-10-05 00:33:14 +02:00
Willy Tarreau
f150317671 MAJOR: checks: completely use the connection transport layer
With this change, we now use the connection's transport layer to receive
and send data during health checks. It even becomes possible to send data
in multiple times, which was not possible before.

The transport layer used is the same as the one used for the traffic, unless
a specific address and/or port is specified for the checks using "port" or
"addr", in which case the transport layer defaults to raw_sock. An option
will be provided to force SSL checks on different IP/ports later.

Connection errors and timeouts are still reported.

Some situations where strerror() was able to report a precise error after
a failed connect() in the past might not be reported with as much precision
anymore, but the error message was already meaningless. During the tests,
no situation was found where a message became less precise.
2012-10-05 00:33:14 +02:00
Willy Tarreau
f4288ee4ba MEDIUM: check: add the ctrl and transport layers in the server check structure
Since it's possible for the checks to use a different protocol or transport layer
than the prod traffic, we need to have them referenced in the server. The
SSL checks are not enabled yet, but the transport layers are completely used.
2012-10-05 00:33:14 +02:00
Willy Tarreau
1ae1b7b53c MEDIUM: checks: use real buffers to store requests and responses
Till now the request was made in the trash and sent to the network at
once, and the response was read into a preallocated char[]. Now we
allocate a full buffer for both the request and the response, and make
use of it.

Some of the operations will probably be replaced later with buffer macros
but the point was to ensure we could migrate to use the data layers soon.

One nice improvement caused by this change is that requests are now formed
at the beginning of the check and may safely be sent in multiple chunks if
needed.
2012-10-05 00:33:14 +02:00
Willy Tarreau
5b3a202f78 REORG: server: move the check-specific parts into a check subsection
The health checks in the servers are becoming a real mess, move them
into their own subsection. We'll soon need to have a struct buffer to
replace the char * as well as check-specific protocol and transport
layers.
2012-10-05 00:33:14 +02:00
Willy Tarreau
fb56aab443 MAJOR: checks: make use of the connection layer to send checks
This is a first step, we now use the connection layer without the data
layers (send/recv are still used by hand). The connection is established
using tcp_connect_server() and raw_sock is assumed and forced for now.

fdtab is not manipulated anymore and polling is managed via the connection
layer.

It becomes quite clear that the server needs a second ->ctrl and ->xprt
dedicated to the checks.
2012-10-05 00:33:14 +02:00
Willy Tarreau
5f1504f524 MEDIUM: connection: add a new local send-proxy transport callback
This callback sends a PROXY protocol line on the outgoing connection,
with the local and remote endpoint information. This is used for local
connections (eg: health checks) where the other end needs to have a
valid address and no connection is relayed.
2012-10-05 00:32:35 +02:00
Willy Tarreau
e1e4a61e7a REORG: connection: move the PROXY protocol management to connection.c
It was previously in frontend.c but there is no reason for this anymore
considering that all the information involved is in the connection itself
only. Theorically this should be in the socket layer but we don't have
this yet.
2012-10-05 00:32:33 +02:00
Willy Tarreau
0ffde2cc3f MEDIUM: connection: automatically disable polling on error
We absolutely want to disable FD polling after an error is detected,
otherwise the data layer has to do it and it's far from being obvious
at these layers.

The way we did it was a bit tricky in conn_update_*_polling and
conn_*_polling_changes. However it has almost no impact on performance
and code size both for the fast and slow path.

We'll now be able to remove some flag updates in the stream interface.
2012-10-04 22:26:11 +02:00
Willy Tarreau
665e6ee7aa MEDIUM: connection: it's not the data layer's role to validate the connection
Till now we used to perform the L4_CONN check in the data layer
(eg: stream interface) but that does not make sense, because some transport
layers will imply that the connection is opened (eg: SSL), and also because
the complexity to check for this is higher in the data layer than in the
transport layer. This is so much true that some read0 cases did not validate
the connection.

So as of now, the transport layer is responsible for clearing L4_CONN when
it detects an activity, and the data layer may safely rely on this flag. This
only impacts a minor change in raw_sock and stream_interface for now.
2012-10-04 22:26:11 +02:00
Willy Tarreau
78eaebed13 MEDIUM: connection: don't call the data->init callback upon error
We don't call ->init() anymore upon error since we already call ->wake().
2012-10-04 22:26:10 +02:00
Willy Tarreau
9683e9a05f MEDIUM: session: register a data->wake callback to process errors
The connection layer will soon call ->wake() only when errors happen, and
not ->init(). So make the session layer use this callback to detect errors
and abort connections.
2012-10-04 22:26:10 +02:00
Willy Tarreau
2396c1c4a2 MEDIUM: connection: make it possible for data->wake to return an error
Just like ->init(), ->wake() may now be used to return an error and
abort the connection. Currently this is not used but will be with
embryonic sessions.
2012-10-04 22:26:10 +02:00
Willy Tarreau
9e272bf95d MEDIUM: connection: only call the data->wake callback on activity
We now check the connection flags for changes in order not to call the
data->wake callback when there is no activity. Activity means a change
on any of the CO_FL_*_SH, CO_FL_ERROR, CO_FL_CONNECTED, CO_FL_WAIT_CONN*
flags, as well as a call to data->recv or data->send.
2012-10-04 22:26:10 +02:00
Willy Tarreau
071e137ec2 MEDIUM: connection: use a generic data-layer init() callback
The generic data-layer init callback is now used after the transport
layer is complete and before calling the data layer recv/send callbacks.

This allows the session to switch from the embryonic session data layer
to the complete stream interface data layer, by making conn_session_complete()
the data layer's init callback.

It sill looks awkwards that the init() callback must be used opon error,
but except by adding yet another one, it does not seem to be mergeable
into another function (eg: it should probably not be merged with ->wake
to avoid unneeded calls during the handshake, though semantically that
would make sense).
2012-10-04 22:26:10 +02:00
Willy Tarreau
5e75e2755e MEDIUM: session: use a specific data_cb for embryonic sessions
We don't want to have the recv or send callbacks in embryonic
sessions, and we want the stream interface to be referenced as
the connection owner only once the session is instanciated. So
let's first have the embryonic session be the owner, then replaced
later by the stream interface once the transport layer is ready.
2012-10-04 22:26:10 +02:00
Willy Tarreau
4aa3683b2d MINOR: connection: provide a generic data layer wakeup callback
Instead of calling conn_notify_si() from the connection handler, we
now call data->wake(), which will allow us to use a different callback
with health checks.

Note that we still rely on a flag in order to decide whether or not
to call this function. The reason is that with embryonic sessions,
the callback is already initialized to si_conn_cb without the flag,
and we can't call the SI notify function in the leave path before
the stream interface is initialized.

This issue should be addressed by involving a different data_cb for
embryonic sessions and for stream interfaces, that would be changed
during session_complete() for the final data_cb.
2012-10-04 22:26:10 +02:00
Willy Tarreau
74beec32a5 REORG: connection: rename app_cb "data"
Now conn->data will designate the data layer which is the client for
the transport layer. In practice it's the stream interface and will
soon also be the health checks.
2012-10-04 22:26:10 +02:00
Willy Tarreau
f7bc57ca6e REORG: connection: rename the data layer the "transport layer"
While working on the changes required to make the health checks use the
new connections, it started to become obvious that some naming was not
logical at all in the connections. Specifically, it is not logical to
call the "data layer" the layer which is in charge for all the handshake
and which does not yet provide a data layer once established until a
session has allocated all the required buffers.

In fact, it's more a transport layer, which makes much more sense. The
transport layer offers a medium on which data can transit, and it offers
the functions to move these data when the upper layer requests this. And
it is the upper layer which iterates over the transport layer's functions
to move data which should be called the data layer.

The use case where it's obvious is with embryonic sessions : an incoming
SSL connection is accepted. Only the connection is allocated, not the
buffers nor stream interface, etc... The connection handles the SSL
handshake by itself. Once this handshake is complete, we can't use the
data functions because the buffers and stream interface are not there
yet. Hence we have to first call a specific function to complete the
session initialization, after which we'll be able to use the data
functions. This clearly proves that SSL here is only a transport layer
and that the stream interface constitutes the data layer.

A similar change will be performed to rename app_cb => data, but the
two could not be in the same commit for obvious reasons.
2012-10-04 22:26:09 +02:00
Willy Tarreau
6f5d141149 MEDIUM: raw_sock: improve connection error reporting
When a connection setup is pending and we receive an error without a
POLL_IN flag, we're certain there will be nothing to read from it and
we can safely report an error without attempting a recv() call. This
will be significantly better for health checks which will avoid a useless
recv() on all failed checks.
2012-10-04 22:26:09 +02:00
Willy Tarreau
c0e98868fe MINOR: raw_sock: always report asynchronous connection errors
Depending on the pollers used, a connection error may be notified
with POLLOUT|POLLERR|POLLHUP. POLLHUP by itself is enough for the
connection handler to call the read actor, which would only consider
this flag as a good indication of a hangup, without considering the
POLLERR flag.

In order to address this, we directly jump to the read0 label if
POLLERR was not set.

This will be important with health checks as we don't want to believe
a connection was properly established when it's not the case !
2012-10-04 22:26:09 +02:00
Willy Tarreau
c39b0d17f2 MINOR: signal: really ignore signals configured with no handler
Until now, signals configured with no handler were still enabled and
ignored upon signal reception. Until now it was not an issue but with
SSL causing many EPIPE all the time, it becomes obvious that signal
processing comes with a cost. So set the handler to SIG_IGN when the
function is NULL.
2012-10-04 22:26:09 +02:00
Willy Tarreau
f8cfa447c6 BUG/MINOR: epoll: correctly disable FD polling in fd_rem()
When calling fd_rem(), the polling was not correctly disabled because the
->prev state was set to zero instead of the previous value. fd_rem() is
very rarely used, only just before closing a socket.

The effect is that upon an error reported at the connection level, if the
task assigned to the connection was too slow to be woken up because of too
many other tasks in the run queue, the FD was still not disabled and caused
the connection handler to be called again with the same event until the task
was finally executed to close the fd.

This issue only affects the epoll poller, not the sepoll variant nor any of
the other ones.

It was already present in 1.4 and even 1.3 with the same almost unnoticeable
effects. The bug can in fact only be discovered during development where it
emphasizes other bugs.

It should be backported anyway.
2012-10-04 22:26:09 +02:00
Willy Tarreau
050536d582 MEDIUM: proxy: add the global frontend to the list of normal proxies
Since recent changes on the global frontend, it was not possible anymore
to soft-reload a process which had a stats socket because the socket would
not be disabled upon reload. The only solution to this endless madness is
to have the global frontend part of normal proxies.

Since we don't want to get an ID that shifts all other proxies and causes
trouble in deployed environments, we assign it ID #0 which other proxies
can't grab, and we don't report it in the stats pages.
2012-10-04 08:58:23 +02:00
Willy Tarreau
b3fb60bdcd BUG/MEDIUM: listener: don't pause protocols that do not support it
Pausing a UNIX_STREAM socket results in a major pain because the socket
does not correctly resume, it wakes poll() but return EAGAIN on accept(),
resulting in a busy loop. So let's only pause protocols that support it.

This issues has existed since UNIX sockets were introduced on bind lines.
2012-10-04 08:58:21 +02:00
Willy Tarreau
8113a5d78f BUG/MINOR: config: use a copy of the file name in proxy configurations
Each proxy contains a reference to the original config file and line
number where it was declared. The pointer used is just a reference to
the one passed to the function instead of being duplicated. The effect
is that it is not valid anymore at the end of the parsing and that all
proxies will be enumerated as coming from the same file on some late
configuration errors. This may happen for exmaple when reporting SSL
certificate issues.

By copying using strdup(), we avoid this issue.

1.4 has the same issue, though no report of the proxy file name is done
out of the config section. Anyway a backport is recommended to ease
post-mortem analysis.
2012-10-04 08:13:32 +02:00
Willy Tarreau
d1a33e35fb BUG/MEDIUM: proxy: must not try to stop disabled proxies upon reload
Hervé Commowick reported an issue : haproxy dies in a segfault during a
soft restart if it tries to pause a disabled proxy. This is because disabled
proxies have no management task so we must not wake the task up. This could
easily remain unnoticed since the old process was expected to go away, so
having it go away faster was not really troubling. However, with sync peers,
it is obvious that there is no peer sync during this reload.

This issue has been introduced in 1.5-dev7 with the removal of the
maintain_proxies() function. No backport is needed.
2012-10-04 00:20:55 +02:00
Willy Tarreau
8923019a1d BUG/MINOR: ssl: report the L4 connection as established when possible
If we get an SSL error during the handshake, we at least try to see
if a syscall reported an error or not. In case of an error, it generally
means that the connection failed. If there is no error, then the connection
established successfully.

The difference is important for health checks which report the precise cause
to the logs and to the stats.
2012-10-02 19:54:38 +02:00
Emeric Brun
051cdab68b BUG/MINOR: build: Fix compilation issue on openssl 0.9.6 due to missing CRL feature. 2012-10-02 19:54:38 +02:00
Emeric Brun
561e574e2f BUG/MINOR: ssl: Fix CRL check was not enabled when crlfile was specified. 2012-10-02 16:05:51 +02:00
Emeric Brun
2d0c482682 MINOR: ssl: add statement 'no-tls-tickets' on bind to disable stateless session resumption
Disables the stateless session resumption (RFC 5077 TLS Ticket extension)
and force to use stateful session resumption.
Stateless session resumption is more expensive in CPU usage.
2012-10-02 16:05:33 +02:00
Emeric Brun
c6678e21bb MEDIUM: config: authorize frontend and listen without bind.
This allows to easily add/remove "bind" entries to a frontend without
being forced to remove it when the last entry is temporarily removed.
While "disabled" may sometimes work in a frontend, it becomes trickier
on "listen" sections which can also hold servers and be referenced by
other frontends.

Note that a "listen" section with no "bind" is equivalent to a "backend"
section.

Configs without any listeners are still reported as invalid and refuse
to load.
2012-10-02 08:34:39 +02:00
Emeric Brun
c0ff4924c0 MINOR: ssl : add statements 'notlsv11' and 'notlsv12' and rename 'notlsv1' to 'notlsv10'.
This is because "notlsv1" used to disable TLSv1.0 only and had no effect
on v1.1/v1.2. so better have an option for each version. This applies both
to "bind" and "server" statements.
2012-10-02 08:34:38 +02:00
Emeric Brun
9faf071acb MINOR: ssl: add build param USE_PRIVATE_CACHE to build cache without shared memory
It removes dependencies with futex or mutex but ssl performances decrease
using nbproc > 1 because switching process force session renegotiation.

This can be useful on small systems which never intend to run in multi-process
mode.
2012-10-02 08:34:38 +02:00
Emeric Brun
4b3091e54e MINOR: ssl: disable shared memory and locks on session cache if nbproc == 1
We don't needa to lock the memory when there is a single process. This can
make a difference on small systems where locking is much more expensive than
just a test.
2012-10-02 08:34:38 +02:00
Emeric Brun
f282a810b7 MINOR: ssl: add fetches and ACLs to return verify errors
Add fetch 'ssl_verify_caerr':
returns the first ssl verify error at depth > 0 (CA chain).

Add fetch 'ssl_verify_caerr_depth':
returns the first ssl verify error depth (max returns is 15 if depth > 15).

Add fetch 'ssl_verify_crterr':
returns the fist ssl verify error at depth == 0.
2012-10-02 08:34:37 +02:00
Emeric Brun
baf8ffb673 MINOR: ssl: add fetch and ACL 'ssl_verify_result'
This fetch returns the final ssl verify error.
2012-10-02 08:34:37 +02:00
Emeric Brun
81c00f0a7a MINOR: ssl: add ignore verify errors options
Allow to ignore some verify errors and to let them pass the handshake.

Add option 'crt-ignore-err <list>'
Ignore verify errors at depth == 0 (client certificate)
<list> is string 'all' or a comma separated list of verify error IDs
(see http://www.openssl.org/docs/apps/verify.html)

Add option 'ca-ignore-err <list>'
Same as 'crt-ignore-err' for all depths > 0 (CA chain certs)

Ex ignore all errors on CA and expired or not-yet-valid errors
on client certificate:

bind 0.0.0.0:443 ssl crt crt.pem verify required
 cafile ca.pem ca-ignore-err all crt-ignore-err 10,9
2012-10-02 08:32:50 +02:00
Emeric Brun
e64aef124a MINOR: ssl: add fetch and ACL 'client_crt' to test a client cert is present
Useful in case of 'verify optional' to know if the client sent a certificate.
2012-10-02 08:32:50 +02:00
Emeric Brun
d94b3fe98f MEDIUM: ssl: add client certificate authentication support
Add keyword 'verify' on bind:
'verify none': authentication disabled (default)
'verify optional': accept connection without certificate
                   and process a verify if the client sent a certificate
'verify required': reject connection without certificate
                   and process a verify if the client send a certificate

Add keyword 'cafile' on bind:
'cafile <path>' path to a client CA file used to verify.
'crlfile <path>' path to a client CRL file used to verify.
2012-10-02 08:04:49 +02:00
Emeric Brun
2b58d040b6 MINOR: ssl: add elliptic curve Diffie-Hellman support for ssl key generation
Add 'ecdhe' on 'bind' statement: to set named curve used to generate ECDHE keys
(ex: ecdhe secp521r1)
2012-10-02 08:03:21 +02:00
Emeric Brun
a4bcd9a5a8 MINOR: ssl: try to load Diffie-Hellman parameters from cert file
Feature is disabled if openssl compiled with OPENSSL_NO_DH.
2012-10-02 08:01:42 +02:00
Willy Tarreau
e603e69d18 MEDIUM: connection: make use of the owner instead of container_of
This way the connection can become independant on the stream interface.
2012-09-28 00:01:23 +02:00
Willy Tarreau
82569f9158 MEDIUM: monitor: simplify handling of monitor-net and mode health
We were having several different behaviours with monitor-net and
"mode health" :
  - monitor-net on TCP connections was evaluated just after accept(),
    did not count a connection on the frontend and were not subject
    to tcp-request connection rules, and caused an immediate close().

  - monitor-net in HTTP mode was evaluated once the session was
    accepted (eg: on top of SSL), returned "HTTP/1.0 200 OK\r\n\r\n"
    over the connection's data layer and instanciated a session which
    was responsible for closing this connection. A connection AND a
    session were counted for the frontend ;

  - "mode health" with "option httpchk" would do exactly the same as
    monitor-net in HTTP mode ;

  - "mode health" without "option httpchk" would do the same as above
    except that "OK" was returned instead of "HTTP/1.0 200 OK\r\n\r\n".

None of them took care of cleaning the input buffer, sometimes resulting
in a TCP reset to be emitted after the last packet if a request was received
over the connection.

Given the inconsistencies and the complexity in keeping all these features
handled at the right position, we now slightly changed the way they are
handled :

  - all of them are handled just after the "tcp-request connection" rules,
    so that all of them may be blocked using such rules, offering more
    flexibility and consistency ;

  - no connection handshake is performed anymore for non-TCP modes

  - all of them send the response as raw data over the socket, there is no
    more difference between TCP and HTTP mode for example (these rules were
    never meant to be served over SSL connections and were never documented
    as able to do that).

  - any possible pending data on the incoming socket is drained before the
    response is sent, in order to avoid the risk of a reset.

  - none of them exactly did what was documented !

This results in more consistent, more flexible and more accurate handling of
monitor rules, with smaller and more robust code.
2012-09-28 00:01:22 +02:00
Willy Tarreau
b8ffd378f0 BUG/MAJOR: http: chunk parser was broken with buffer changes
Since at least commit a458b679, msg->sov could become negative in
http_parse_chunk_size() if a chunk size wrapped around the buffer.
The effect is that at some point channel_forward() was called with
a negative size, causing all data to be transferred without being
analyzed anymore.

Since haproxy does not support keep-alive with the server yet, this
issue is not really noticeable, as the server closes the connection
in response. Still, when tunnel mode is used or when pretent-keepalive
is used, it is possible to see the problem.

This issue was reported and diagnosed by William Lallemand at
Exceliance.
2012-09-27 15:08:56 +02:00
Willy Tarreau
3c7a79dbb1 MINOR: cli: allow to set frontend maxconn to zero
It is sometimes useful to completely disable accepting new connections
on a frontend during maintenance operations. By setting a frontend's
maxconn to zero, connections are not accepted anymore until the limit
is increased again.
2012-09-26 21:07:15 +02:00
Willy Tarreau
a7944ad9ef BUG: stats: fix regression introduced by commit 4348fad1
Recent commit 4348fad1 (listeners: use dual-linked lists to chain listeners
with frontends) broke frontend lookup in stats sockets by using the wrong
iterator in the listeners.
2012-09-26 21:03:11 +02:00
Willy Tarreau
3631d41778 CLEANUP: config: fix typo inteface => interface
This was in an error message.
2012-09-25 16:31:00 +02:00
Willy Tarreau
173e7fbd94 BUG/MINOR: config: check the proper pointer to report unknown protocol
Check the protocol pointer and not the socket to report an unknown family
in servers or peers. This can never happen anyway, it's just to be completely
clean.
2012-09-24 22:49:06 +02:00
Willy Tarreau
e92693af26 BUG: http: do not print garbage on invalid requests in debug mode
Cyril Bonté reported a mangled debug output when an invalid request
was sent with a faulty request line. The reason was the use of the
msg->sl.rq.l offset which was not yet initialized in this case. So
we change the way to report such an error so that first we initialize
it to zero before parsing a message, then we use that to know whether
we can trust it or not. If it's still zero, then we display the whole
buffer, truncated by debug_hdr() to the first CR or LF character, which
results in the first line only.

The same operation was performed for the response, which was wrong too.
2012-09-24 21:16:42 +02:00
Cyril Bonté
3aaba440a2 BUILD: fix compilation error with DEBUG_FULL
Recent changes in structures broke the compilation when using DEBUG_FULL.
Let's update apply the changes also to the variables used in DPRINTF calls.
2012-09-24 20:36:39 +02:00
Willy Tarreau
d578120a3e MEDIUM: stats: make use of the standard "bind" parsers to parse global socket
The global stats socket statement now makes use of the standard bind parsers.
This results in all UNIX socket options being set by proto_uxst and in all
TCP and SSL options being inherited and usable. For example it is now possible
to enable a stats socket over SSL/TCP by appending the "ssl" keyword and a
certificate after "crt".

The code is simplified since we don't have a special case to parse this config
keyword anymore.
2012-09-24 10:53:17 +02:00
Willy Tarreau
81796be87c MINOR: ssl: set the listeners' data layer to ssl during parsing
It's better to set all listeners to ssl_sock when seeing the "ssl"
keyword that to loop on all of them afterwards just for this. This
also removes some #ifdefs.
2012-09-24 10:53:17 +02:00
Willy Tarreau
c53d42256d MEDIUM: stats: remove the stats_sock struct from the global struct
Now the stats socket is allocated when the 'stats socket' line is parsed,
and assigned using the standard str2listener(). This has two effects :
  - more than one stats socket can now be declared
  - stats socket now support protocols other than UNIX

The next step is to remove the duplicate bind config parsing.
2012-09-24 10:53:16 +02:00
Willy Tarreau
4fbb2285e2 MINOR: config: make str2listener() use memprintf() to report errors.
This will make it possible to use the function for other listening
sockets.
2012-09-24 10:53:16 +02:00
Willy Tarreau
eb6cead1de MINOR: standard: make memprintf() support a NULL destination
Doing so removes many checks that were systematically made because
the callees don't know if the caller passed a valid pointer.
2012-09-24 10:53:16 +02:00
Willy Tarreau
ce39bfb7c4 BUG: backend: balance hdr was broken since 1.5-dev11
Alex Markham reported and diagnosed a bug appearing on 1.5-dev11,
causing a crash on x86_64 when header hashing is used. The cause is
a missing (int) cast causing a negative offset to appear positive
and the resulting pointer to go out of bounds.

The crash is not possible anymore since 1.5-dev12 because a second
bug caused the negative sign to disappear so the pointer is always
within range but always wrong, so balance hdr() never works anymore.

This fix restores the correct behaviour and ensures the sign is
correct.
2012-09-22 18:36:29 +02:00
Willy Tarreau
290e63aa87 REORG: listener: move unix perms from the listener to the bind_conf
Unix permissions are per-bind configuration line and not per listener,
so let's concretize this in the way the config is stored. This avoids
some unneeded loops to set permissions on all listeners.

The access level is not part of the unix perms so it has been moved
away. Once we can use str2listener() to set all listener addresses,
we'll have a bind keyword parser for this one.
2012-09-20 18:07:14 +02:00
Willy Tarreau
4348fad1c1 MAJOR: listeners: use dual-linked lists to chain listeners with frontends
Navigating through listeners was very inconvenient and error-prone. Not to
mention that listeners were linked in reverse order and reverted afterwards.
In order to definitely get rid of these issues, we now do the following :
  - frontends have a dual-linked list of bind_conf
  - frontends have a dual-linked list of listeners
  - bind_conf have a dual-linked list of listeners
  - listeners have a pointer to their bind_conf

This way we can now navigate from anywhere to anywhere and always find the
proper bind_conf for a given listener, as well as find the list of listeners
for a current bind_conf.
2012-09-20 16:48:07 +02:00
Willy Tarreau
81a8117b41 MINOR: config: set the bind_conf entry on listeners created from a "listen" line.
Otherwise we would risk a segfault when checking the config's validity
(eg: when looking for conflicts on ID assignments).

Note that the same issue exists with peers_fe and the global stats_fe. All
listeners should be reviewed and simplified to use a compatible declaration
mode.
2012-09-18 20:56:12 +02:00
Willy Tarreau
a020fbd593 MINOR: stats: fill the file and line numbers in the stats frontend
The stats frontend struct has config file and line which were not set.
They're not used right now but better fill them correctly anyway.
2012-09-18 20:05:00 +02:00
Willy Tarreau
28a47d6408 MINOR: config: pass the file and line to config keyword parsers
This will be needed when we need to create bind config settings.
2012-09-18 20:02:48 +02:00
Willy Tarreau
51fb7651c4 MINOR: listener: add a scope field in the bind keyword lists
This scope is used to report what the keywords are used for (eg: TCP,
UNIX, ...). It is now reported by bind_dump_kws().
2012-09-18 18:27:14 +02:00
Willy Tarreau
8638f4850f MEDIUM: config: enumerate full list of registered "bind" keywords upon error
When an unknown "bind" keyword is detected, dump the list of all
registered keywords. Unsupported default alternatives are also reported
as "not supported".
2012-09-18 18:27:14 +02:00
Willy Tarreau
d0a895d25f MEDIUM: config: move all unix-specific bind keywords to proto_uxst.c
The "mode", "uid", "gid", "user" and "group" bind options were moved to
proto_uxst as they are unix-specific.

Note that previous versions had a bug here, only the last listener was
updated with the specified settings. However, it almost never happens
that bind lines contain multiple UNIX socket paths so this is not that
much of a problem anyway.
2012-09-18 18:26:08 +02:00
Willy Tarreau
3dcc341720 MEDIUM: config: move the common "bind" settings to listener.c
These ones are better placed in listener.c than in cfgparse.c, by relying
on the bind keyword registration subsystem.
2012-09-18 17:17:28 +02:00
Willy Tarreau
dda322dec0 MINOR: config: improve error reporting for "bind" lines
We now report the bind argument, which was missing in all error reports. It
is now much more convenient to spot configuration mistakes.
2012-09-18 16:34:09 +02:00
Willy Tarreau
79eeafacb4 MEDIUM: move bind SSL parsing to ssl_sock
Registering new SSL bind keywords was not particularly handy as it required
many #ifdef in cfgparse.c. Now the code has moved to ssl_sock.c which calls
a register function for all the keywords.

Error reporting was also improved by this move, because the called functions
build an error message using memprintf(), which can span multiple lines if
needed, and each of these errors will be displayed indented in the context of
the bind line being processed. This is important when dealing with certificate
directories which can report multiple errors.
2012-09-18 16:20:01 +02:00
Willy Tarreau
4479124cda MEDIUM: config: move the "bind" TCP parameters to proto_tcp
Now proto_tcp.c is responsible for the 4 settings it handles :
  - defer-accept
  - interface
  - mss
  - transparent

These ones do not need to be handled in cfgparse anymore. If support for a
setting is disabled by a missing build option, then cfgparse correctly
reports :

  [ALERT] 255/232700 (2701) : parsing [echo.cfg:114] : 'bind' : 'transparent' option is not implemented in this version (check build options).
2012-09-15 22:33:16 +02:00
Willy Tarreau
269826659d MEDIUM: listener: add a minimal framework to register "bind" keyword options
With the arrival of SSL, the "bind" keyword has received even more options,
all of which are processed in cfgparse in a cumbersome way. So it's time to
let modules register their own bind options. This is done very similarly to
the ACLs with a small difference in that we make the difference between an
unknown option and a known, unimplemented option.
2012-09-15 22:33:08 +02:00
Willy Tarreau
88500de69e CLEANUP: listener: remove unused conf->file and conf->line
These ones are already in bind_conf.
2012-09-15 22:29:33 +02:00
Willy Tarreau
2a65ff014e MEDIUM: config: replace ssl_conf by bind_conf
Some settings need to be merged per-bind config line and are not necessarily
SSL-specific. It becomes quite inconvenient to have this ssl_conf SSL-specific,
so let's replace it with something more generic.
2012-09-15 22:29:33 +02:00
Willy Tarreau
d1d5454180 REORG: split "protocols" files into protocol and listener
It was becoming confusing to have protocols and listeners in the same
files, split them.
2012-09-15 22:29:32 +02:00
Willy Tarreau
21c705b0f8 MINOR: config: add a function to indent error messages
Bind parsers may return multiple errors, so let's make use of a new function
to re-indent multi-line error messages so that they're all reported in their
context.
2012-09-15 22:29:27 +02:00
Willy Tarreau
3e394c903f BUG/MAJOR: ssl: missing tests in ACL fetch functions
Baptiste Assmann observed a crash of 1.5-dev12 occuring when the ssl_sni
fetch was used with no SNI on the input connection and without a prior
has_sni check. A code review revealed several issues :
   1) it was possible to call the has_sni and ssl_sni fetch functions with
      a NULL data_ctx if the handshake fails or if the connection is aborted
      during the handshake.
   2) when no SNI is present, strlen() was called with a NULL parameter in
      smp_fetch_ssl_sni().
2012-09-15 08:57:46 +02:00
Willy Tarreau
2e1dca8f52 MEDIUM: http: add "redirect scheme" to ease HTTP to HTTPS redirection
For instance :

   redirect scheme https if !{ is_ssl }
2012-09-12 08:43:15 +02:00
Willy Tarreau
69845dfcf3 DOC: add a special acknowledgement for the stud project
Really, the quality of their code deserves it, it would have been much
harder to figure how to get all the things right at once without looking
there from time to time !
2012-09-10 09:44:59 +02:00
Willy Tarreau
7875d0967f MEDIUM: ssl: add sample fetches for is_ssl, ssl_has_sni, ssl_sni_*
This allows SNI presence and value to be checked on incoming SSL connections.
It is usable both for ACLs and stick tables.
2012-09-10 09:27:02 +02:00
Willy Tarreau
1ee0e302a1 BUILD: report openssl build settings in haproxy -vv
Since it's common enough to discover that some config options are not
supported due to some openssl version or build options, we report the
relevant ones in "haproxy -vv".
2012-09-10 09:27:02 +02:00
Emeric Brun
fc0421fde9 MEDIUM: ssl: add support for SNI and wildcard certificates
A side effect of this change is that the "ssl" keyword on "bind" lines is now
just a boolean and that "crt" is needed to designate certificate files or
directories.

Note that much refcounting was needed to have the free() work correctly due to
the number of cert aliases which can make a context be shared by multiple names.
2012-09-10 09:27:02 +02:00
Willy Tarreau
f5ae8f7637 MEDIUM: config: centralize handling of SSL config per bind line
SSL config holds many parameters which are per bind line and not per
listener. Let's use a per-bind line config instead of having it
replicated for each listener.

At the moment we only do this for the SSL part but this should probably
evolved to handle more of the configuration and maybe even the state per
bind line.
2012-09-08 08:31:50 +02:00
Willy Tarreau
aa52bef622 BUILD: shut a gcc warning introduced by commit 269ab31
Usual warning on unchecked write() on which no operation is possible.
2012-09-08 08:24:51 +02:00
Willy Tarreau
50acaaae5e MINOR: config: make the tasks "nice" value configurable on "bind" lines.
This is very convenient to reduce SSL processing priority compared to
other traffic. This applies to CPU usage only, but has a direct impact
on latency under congestion.
2012-09-06 14:28:58 +02:00
Willy Tarreau
58363cf193 MEDIUM: connection: improve error handling around the data layer
Better avoid calling the data functions upon error or handshake than
having to put conditions everywhere, which are too easy to forget (one
check for CO_FL_ERROR was missing, but this was harmless).
2012-09-06 14:12:03 +02:00
Willy Tarreau
184636e3e7 BUG: tcp: close socket fd upon connect error
When the data layer fails to initialize (eg: out of memory for SSL), we
must close the socket fd we just allocated.
2012-09-06 14:04:41 +02:00
Willy Tarreau
403edff4b8 MEDIUM: config: implement maxsslconn in the global section
SSL connections take a huge amount of memory, and unfortunately openssl
does not check malloc() returns and easily segfaults when too many
connections are used.

The only solution against this is to provide a global maxsslconn setting
to reject SSL connections above the limit in order to avoid reaching
unsafe limits.
2012-09-06 12:10:43 +02:00
Willy Tarreau
cbaaec475c MINOR: session: do not send an HTTP/500 error on SSL sockets
If a session fails its initialization, we don't want to send HTTP/500
over the socket if it's not a raw data layer.
2012-09-06 11:32:07 +02:00
Willy Tarreau
32368ceba4 MEDIUM: config: support per-listener backlog and maxconn
With SSL, connections are much more expensive, so it is important to be
able to limit concurrent connections per listener in order to limit the
memory usage.
2012-09-06 11:10:55 +02:00
Willy Tarreau
269ab318ef BUG/MEDIUM: workaround an eglibc bug which truncates the pidfiles when nbproc > 1
Thomas Heil reported that when using nbproc > 1, his pidfiles were
regularly truncated. The issue could be tracked down to the presence
of a call to lseek(pidfile, 0, SEEK_SET) just before the close() call
in the children, resulting in the file being truncated by the children
while the parent was feeding it. This unexpected lseek() is transparently
performed by fclose().

Since there is no way to have the file automatically closed during the
fork, the only solution is to bypass the libc and use open/write/close
instead of fprintf() and fclose().

The issue was observed on eglibc 2.15.
2012-09-05 15:04:20 +02:00
Willy Tarreau
ee2e3a4027 BUILD: ssl: use MAP_ANON instead of MAP_ANONYMOUS
FreeBSD uses the former, Linux uses the latter but generally also
defines the former as an alias of the latter. Just checked on other
OSes and AIX defines both. So better use MAP_ANON which seems to be
more commonly defined.
2012-09-04 15:45:21 +02:00
David BERARD
e566ecbea8 MEDIUM: ssl: add support for prefer-server-ciphers option
I wrote a small path to add the SSL_OP_CIPHER_SERVER_PREFERENCE OpenSSL option
to frontend, if the 'prefer-server-ciphers' keyword is set.

Example :
	bind 10.11.12.13 ssl /etc/haproxy/ssl/cert.pem ciphers RC4:HIGH:!aNULL:!MD5 prefer-server-ciphers

This option mitigate the effect of the BEAST Attack (as I understand), and it
equivalent to :
	- Apache HTTPd SSLHonorCipherOrder option.
	- Nginx ssl_prefer_server_ciphers option.

[WT: added a test for the support of the option]
2012-09-04 15:35:32 +02:00
Willy Tarreau
ff9f7698fc BUILD: fix build error without SSL (ssl_cert)
One last-minute optimization broke the build without SSL support.
Move ssl_cert out of the #ifdef/#endif and it's OK.
2012-09-04 15:13:20 +02:00
Willy Tarreau
18b2059a75 BUILD: ssl: fix shctx build on RHEL with futex
On RHEL/CentOS, linux/futex.h uses an u32 type which is never declared
anywhere. Let's set it with a #define in order to fix the issue without
causing conflicts with possible typedefs on other platforms.
2012-09-04 12:26:26 +02:00
Willy Tarreau
783f25800c BUILD: http: rename error_message http_error_message to fix conflicts on RHEL
Duncan Hall reported a build issue on CentOS where error_message conflicts
with another system declaration when SSL is enabled. Rename the function.
2012-09-04 12:19:04 +02:00
Willy Tarreau
0573747da0 BUG: ssl: mark the connection as waiting for an SSL connection during the handshake
The WAIT_L6_CONN was designed especially to ensure that the connection
was not marked ready before the SSL layer was OK, but we forgot to set
the flag, resulting in a rejected handshake when ssl was combined with
accept-proxy because accept-proxy would validate the connection alone
and the SSL handshake would then believe in a client-initiated reneg
and kill it.
2012-09-04 08:03:39 +02:00
Willy Tarreau
c230b8bfb6 MEDIUM: config: add "nosslv3" and "notlsv1" on bind and server lines
This is aimed at disabling SSLv3 and TLSv1 respectively. SSLv2 is always
disabled. This can be used in some situations where one version looks more
suitable than the other.
2012-09-03 23:55:16 +02:00
Willy Tarreau
d7aacbffcb MEDIUM: config: add a "ciphers" keyword to set SSL cipher suites
This is supported for both servers and listeners. The cipher suite
simply follows the "ciphers" keyword.
2012-09-03 23:43:25 +02:00
Emeric Brun
fc32acafcd MINOR: ssl add global setting tune.sslcachesize to set SSL session cache size.
This new global setting allows the user to change the SSL cache size in
number of sessions. It defaults to 20000.
2012-09-03 22:36:33 +02:00
Emeric Brun
aa35f1fad7 MEDIUM: ssl: replace OpenSSL's session cache with the shared cache
OpenSSL's session cache is now totally disabled and we use our own
implementation instead.
2012-09-03 22:36:33 +02:00
Emeric Brun
3e541d1c03 MEDIUM: ssl: add shared memory session cache implementation.
This SSL session cache was developped at Exceliance and is the same that
was proposed for stunnel and stud. It makes use of a shared memory area
between the processes so that sessions can be handled by any process. It
is only useful when haproxy runs with nbproc > 1, but it does not hurt
performance at all with nbproc = 1. The aim is to totally replace OpenSSL's
internal cache.

The cache is optimized for Linux >= 2.6 and specifically for x86 platforms.
On Linux/x86, it makes use of futexes for inter-process locking, with some
x86 assembly for the locked instructions. On other architectures, GCC
builtins are used instead, which are available starting from gcc 4.1.

On other operating systems, the locks fall back to pthread mutexes so
libpthread is automatically linked. It is not recommended since pthreads
are much slower than futexes. The lib is only linked if SSL is enabled.
2012-09-03 22:36:33 +02:00
Willy Tarreau
fbac6638c1 MINOR: ssl: disable TCP quick-ack by default on SSL listeners
Since the SSL handshake involves an immediate reply from the server
to the client, there's no point responding with a quick-ack before
sending the data, so disable quick-ack by default, just as it is done
for HTTP.

This shows a 2-2.5% transaction rate increase on a dual-core atom.
2012-09-03 22:36:27 +02:00
Emeric Brun
e1f38dbb44 MEDIUM: ssl: protect against client-initiated renegociation
CVE-2009-3555 suggests that client-initiated renegociation should be
prevented in the middle of data. The workaround here consists in having
the SSL layer notify our callback about a handshake occurring, which in
turn causes the connection to be marked in the error state if it was
already considered established (which means if a previous handshake was
completed). The result is that the connection with the client is immediately
aborted and any pending data are dropped.
2012-09-03 22:03:17 +02:00
Emeric Brun
01f8e2f61b MEDIUM: config: add support for the 'ssl' option on 'server' lines
This option currently takes no option and simply turns SSL on for all
connections going to the server. It is likely that more options will
be needed in the future.
2012-09-03 22:02:21 +02:00
Emeric Brun
6e159299f1 MEDIUM: config: add the 'ssl' keyword on 'bind' lines
"bind" now supports "ssl" followed by a PEM cert+key file name.
2012-09-03 20:49:14 +02:00
Emeric Brun
4659195e31 MEDIUM: ssl: add new files ssl_sock.[ch] to provide the SSL data layer
This data layer supports socket-to-buffer and buffer-to-socket operations.
No sock-to-pipe nor pipe-to-sock functions are provided, since splicing does
not provide any benefit with data transformation. At best it could save a
memcpy() and avoid keeping a buffer allocated but that does not seem very
useful.

An init function and a close function are provided because the SSL context
needs to be allocated/freed.

A data-layer shutw() function is also provided because upon successful
shutdown, we want to store the SSL context in the cache in order to reuse
it for future connections and avoid a new key generation.

The handshake function is directly called from the connection handler.
At this point it is not certain whether this will remain this way or
if a new ->handshake callback will be added to the data layer so that
the connection handler doesn't care about SSL.

The sock-to-buf and buf-to-sock functions are all capable of enabling
the SSL handshake at any time. This also implies polling in the opposite
direction to what was expected. The upper layers must take that into
account (it is OK right now with the stream interface).
2012-09-03 20:49:14 +02:00
Willy Tarreau
dd2f85eb3b CLEANUP: includes: fix includes for a number of users of fd.h
It appears that fd.h includes a number of unneeded files and was
included from standard.h, and as such served as an intermediary
to provide almost everything to everyone.

By removing its useless includes, a long dependency chain broke
but could easily be fixed.
2012-09-03 20:49:14 +02:00
Willy Tarreau
45dab73788 CLEANUP: fdtab: flatten the struct and merge the spec struct with the rest
The "spec" sub-struct was using 8 bytes for only 5 needed. There is no
reason to keep it as a struct, it doesn't bring any value. By flattening
it, we can merge the single byte with the next single byte, resulting in
an immediate saving of 4 bytes (20%). Interestingly, tests have shown a
steady performance gain of 0.6% after this change, which can possibly be
attributed to a more cache-line friendly struct.
2012-09-03 20:49:14 +02:00
Willy Tarreau
40ff59d820 CLEANUP: fd: remove fdtab->flags
These flags were added for TCP_CORK. They were only set at various places
but never checked by any user since TCP_CORK was replaced with MSG_MORE.
Simply get rid of this now.
2012-09-03 20:49:14 +02:00
Willy Tarreau
34ffd77648 MAJOR: stream_interface: continue to update data polling flags during handshakes
Since data and socket polling flags were split, it became possible to update
data flags even during handshakes. In fact this is very important otherwise
it is not possible to poll for writes if some data are to be forwarded during
a handshake (eg: data received during an SSL connect).
2012-09-03 20:49:13 +02:00
Willy Tarreau
d9de7ca3d0 MEDIUM: connection: avoid calling handshakes when polling is required
If a data handler suddenly switches to a handshake mode and detects the
need for polling in either direction, we don't want to loop again through
the handshake handlers because we know we won't be able to do anything.

Similarly, we don't want to call again the data handlers after a loop
through the handshake handlers if polling is required.

No performance change was observed, it might only be observed during
high rate SSL renegociation.
2012-09-03 20:47:35 +02:00
Willy Tarreau
56a77e5933 MEDIUM: connection: complete the polling cleanups
I/O handlers now all use __conn_{sock,data}_{stop,poll,want}_* instead
of returning dummy flags. The code has become slightly simpler because
some tricks such as the MIN_RET_FOR_READ_LOOP are not needed anymore,
and the data handlers which switch to a handshake handler do not need
to disable themselves anymore.
2012-09-03 20:47:35 +02:00
Willy Tarreau
f8deb0cfa8 MEDIUM: connection: only call tcp_connect_probe when nothing was attempted yet
It was observed that after a failed send() on EAGAIN, a second connect()
would still be attempted in tcp_connect_probe() because there was no way
to know that a send() had failed.

By checking the WANT_WR status flag, we know if a previous write attempt
failed on EAGAIN, so we don't try to connect again if we know this has
already failed.

With this simple change, the second connect() has disappeared.
2012-09-03 20:47:35 +02:00
Willy Tarreau
e9dfa79a75 MAJOR: connection: rearrange the polling flags.
Polling flags were set for data and sock layer, but while this does make
sense for the ENA flag, it does not for the POL flag which translates the
detection of an EAGAIN condition. So now we remove the {DATA,SOCK}_POL*
flags and instead introduce two new layer-independant flags (WANT_RD and
WANT_WR). These flags are only set when an EAGAIN is encountered so that
polling can be enabled.

In order for these flags to have any meaning they are not persistent and
have to be cleared by the connection handler before calling the I/O and
data callbacks. For this reason, changes detection has been slightly
improved. Instead of comparing the WANT_* flags with CURR_*_POL, we only
check if the ENA status changes, or if the polling appears, since we don't
want to detect the useless poll to ena transition. Tests show that this
has eliminated one useless call to __fd_clr().

Finally the conn_set_polling() function which was becoming complex and
required complex operations from the caller was split in two and replaced
its two only callers (conn_update_data_polling and conn_update_sock_polling).
The two functions are now much smaller due to the less complex conditions.
Note that it would be possible to re-merge them and only pass a mask but
this does not appear much interesting.
2012-09-03 20:47:35 +02:00
Willy Tarreau
74172ff9c3 CLEANUP: frontend: remove the old proxy protocol decoder
This one used to rely on a stream analyser which was inappropriate.
It's not used anymore.
2012-09-03 20:47:35 +02:00
Willy Tarreau
22cda21ad5 MAJOR: connection: make the PROXY decoder a handshake handler
The PROXY protocol is now decoded in the connection before other
handshakes. This means that it may be extracted from a TCP stream
before SSL is decoded from this stream.
2012-09-03 20:47:35 +02:00
Willy Tarreau
2542b53b19 MAJOR: session: introduce embryonic sessions
When an incoming connection request is accepted, a connection
structure is needed to store its state. However we don't want to
fully initialize a session until the data layer is about to be
ready.

As long as the connection is physically stored into the session,
it's not easy to split both allocations.

As such, we only initialize the minimum requirements of a session,
which results in what we call an embryonic session. Then once the
data layer is ready, we can complete the function's initialization.

Doing so avoids buffers allocation and ensures that a session only
sees ready connections.

The frontend's client timeout is used as the handshake timeout. It
is likely that another timeout will be used in the future.
2012-09-03 20:47:35 +02:00
Willy Tarreau
15678efc45 MEDIUM: connection: add an ->init function to data layer
SSL need to initialize the data layer before proceeding with data. At
the moment, this data layer is automatically initialized from itself,
which will not be possible once we extract connection from sessions
since we'll only create the data layer once the handshake is finished.

So let's have the application layer initialize the data layer before
using it.
2012-09-03 20:47:34 +02:00
Willy Tarreau
64ee491309 MINOR: tcp: replace tcp_src_to_stktable_key with addr_to_stktable_key
Make it more obvious that this function does not depend on any knowledge
of the session. This is important to plan for TCP rules that can run on
connection without any initialized session yet.
2012-09-03 20:47:34 +02:00
Willy Tarreau
14f8e86da5 MEDIUM: proto_tcp: remove any dependence on stream_interface
The last uses of the stream interfaces were in tcp_connect_server() and
could easily and more appropriately be moved to its callers, si_connect()
and connect_server(), making a lot more sense.

Now the function should theorically be usable for health checks.

It also appears more obvious that the file is split into two distinct
parts :
  - the protocol layer used at the connection level
  - the tcp analysers executing tcp-* rules and their samples/acls.
2012-09-03 20:47:34 +02:00
Willy Tarreau
93b0f4f6c6 MEDIUM: stream_interface: remove CAP_SPLTCP/CAP_SPLICE flags
These ones are implicitly handled by the connection's data layer, no need
to rely on them anymore and reaching them maintains undesired dependences
on stream-interface.
2012-09-03 20:47:34 +02:00
Willy Tarreau
986a9d2d12 MAJOR: connection: move the addr field from the stream_interface
We need to have the source and destination addresses in the connection.
They were lying in the stream interface so let's move them. The flags
SI_FL_FROM_SET and SI_FL_TO_SET have been moved as well.

It's worth noting that tcp_connect_server() almost does not use the
stream interface anymore except for a few flags.

It has been identified that once we detach the connection from the SI,
it will probably be needed to keep a copy of the server-side addresses
in the SI just for logging purposes. This has not been implemented right
now though.
2012-09-03 20:47:34 +02:00
Willy Tarreau
3cefd521fa REORG: connection: move the target pointer from si to connection
The target is per connection and is directly used by the connection, so
we need it there. It's not needed anymore in the SI however.
2012-09-03 20:47:34 +02:00
Willy Tarreau
8263d2b259 CLEANUP: channel: use "channel" instead of "buffer" in function names
This is a massive rename of most functions which should make use of the
word "channel" instead of the word "buffer" in their names.

In concerns the following ones (new names) :

unsigned long long channel_forward(struct channel *buf, unsigned long long bytes);
static inline void channel_init(struct channel *buf)
static inline int channel_input_closed(struct channel *buf)
static inline int channel_output_closed(struct channel *buf)
static inline void channel_check_timeouts(struct channel *b)
static inline void channel_erase(struct channel *buf)
static inline void channel_shutr_now(struct channel *buf)
static inline void channel_shutw_now(struct channel *buf)
static inline void channel_abort(struct channel *buf)
static inline void channel_stop_hijacker(struct channel *buf)
static inline void channel_auto_connect(struct channel *buf)
static inline void channel_dont_connect(struct channel *buf)
static inline void channel_auto_close(struct channel *buf)
static inline void channel_dont_close(struct channel *buf)
static inline void channel_auto_read(struct channel *buf)
static inline void channel_dont_read(struct channel *buf)
unsigned long long channel_forward(struct channel *buf, unsigned long long bytes)

Some functions provided by channel.[ch] have kept their "buffer" name because
they are really designed to act on the buffer according to some information
gathered from the channel. They have been moved together to the same place in
the file for better readability but they were not changed at all.

The "buffer" memory pool was also renamed "channel".
2012-09-03 20:47:33 +02:00
Willy Tarreau
03cdb7c678 CLEANUP: channel: usr CF_/CHN_ prefixes instead of BF_/BUF_
Get rid of these confusing BF_* flags. Now channel naming should clearly
be used everywhere appropriate.

No code was changed, only a renaming was performed. The comments about
channel operations was updated.
2012-09-03 20:47:33 +02:00
Willy Tarreau
af81935b82 REORG: channel: move buffer_{replace,insert_line}* to buffer.{c,h}
These functions do not depend on the channel flags anymore thus they're
much better suited to be used on plain buffers. Move them from channel
to buffer.
2012-09-03 20:47:33 +02:00
Willy Tarreau
f941cf2ef2 MAJOR: channel: remove the BF_FULL flag
This is similar to the recent removal of BF_OUT_EMPTY. This flag was very
problematic because it relies on permanently changing information such as the
to_forward value, so it had to be updated upon every change to the buffers.
Previous patch already got rid of its users.

One part of the change is sensible : the flag was also part of BF_MASK_STATIC,
which is used by process_session() to rescan all analysers in case the flag's
status changes. At first glance, none of the analysers seems to change its
mind base on this flag when it is subject to change, so it seems fine not to
add variation checks here. Otherwise it's possible that checking the buffer's
input and output is more reliable than checking the flag's replacement.
2012-09-03 20:47:33 +02:00
Willy Tarreau
3bf1b2b816 MAJOR: channel: stop relying on BF_FULL to take action
This flag is quite complex to get right and updating it everywhere is a
major pain, especially since the buffer/channel split. This is the first
step of getting rid of it. Instead now it's dynamically computed whenever
needed.
2012-09-03 20:47:33 +02:00
Willy Tarreau
ad1cc3df9c MINOR: channel: rename bi_full to channel_full as it checks the whole channel
Since the function takes care of the forward count and involves more than
buffer knowledge, rename it.
2012-09-03 20:47:32 +02:00
Willy Tarreau
a75bcef867 REORG: buffer: move buffer_flush, b_adv and b_rew to buffer.h
These one now operate over real buffers, not channels anymore.
2012-09-03 20:47:32 +02:00
Willy Tarreau
8e21bb9e52 MAJOR: channel: remove the BF_OUT_EMPTY flag
This flag was very problematic because it was composite in that both changes
to the pipe or to the buffer had to cause this flag to be updated, which is
not always simple (eg: there may not even be a channel attached to a buffer
at all).

There were not that many users of this flags, mostly setters. So the flag got
replaced with a macro which reports whether the channel is empty or not, by
checking both the pipe and the buffer.

One part of the change is sensible : the flag was also part of BF_MASK_STATIC,
which is used by process_session() to rescan all analysers in case the flag's
status changes. At first glance, none of the analysers seems to change its
mind base on this flag when it is subject to change, so it seems fine not to
add variation checks here. Otherwise it's possible that checking the buffer's
output size is more useful than checking the flag's replacement.
2012-09-03 20:47:32 +02:00
Willy Tarreau
c7e4238df0 REORG: buffers: split buffers into chunk,buffer,channel
Many parts of the channel definition still make use of the "buffer" word.
2012-09-03 20:47:32 +02:00
Willy Tarreau
c578891112 CLEANUP: connection: split sock_ops into data_ops, app_cp and si_ops
Some parts of the sock_ops structure were only used by the stream
interface and have been moved into si_ops. Some of them were callbacks
to the stream interface from the connection and have been moved into
app_cp as they're the application seen from the connection (later,
health-checks will need to use them). The rest has moved to data_ops.

Normally at this point the connection could live without knowing about
stream interfaces at all.
2012-09-03 20:47:31 +02:00
Willy Tarreau
62266dba88 MEDIUM: stream-interface: don't remove WAIT_DATA when a handshake is in progress
This doesn't make sense and will only require that it's enabled again.
2012-09-03 20:47:31 +02:00
Willy Tarreau
2c052083e6 MAJOR: stream-interface: fix splice not to call chk_snd by itself
In recent splice fixes we made splice call chk_snd, but this was due
to inappropriate checks in conn_notify_si() which prevented the chk_snd()
call from being performed. Now that this has been fixed, remove this
duplicate code.
2012-09-03 20:47:31 +02:00
Willy Tarreau
f16723e4ca MAJOR: stream-interface: don't commit polling changes in every callback
It's more efficient to centralize polling changes, which is already done
in the connection handler. So now all I/O callbacks just change flags and
rely on the connection handler for the commit. The special case of the
send loop is handled by the chk_snd() function which does an update at
the end.
2012-09-03 20:47:31 +02:00
Willy Tarreau
a1a74744a4 MEDIUM: proxy-proto: don't use buffer flags in conn_si_send_proxy()
These ones should only be handled by the stream interface at the end
of the handshake now. Similarly a number of information are now taken
at the connection level rather than at the data level (eg: shutdown).

Fast polling updates have been used instead of slow ones since the
function is only called by the connection handler.
2012-09-03 20:47:31 +02:00
Willy Tarreau
44b5dc6f85 MAJOR: stream-interface: make conn_notify_si() more robust
This function was relying on the result of file descriptor polling
which is inappropriate as it may be subject to race conditions during
handshakes. Make it more robust by relying solely on buffer activity.
2012-09-03 20:47:31 +02:00
Willy Tarreau
96199b1016 MAJOR: stream-interface: restore splicing mechanism
The splicing is now provided by the data-layer rcv_pipe/snd_pipe functions
which in turn are called by the stream interface's recv and send callbacks.

The presence of the rcv_pipe/snd_pipe functions is used to attest support
for splicing at the data layer. It looks like the stream-interface's
SI_FL_CAP_SPLICE flag does not make sense anymore as it's used as a proxy
for the pointers above.

It also appears that we call chk_snd() from the recv callback and then
try to call it again in update_conn(). It is very likely that this last
function will progressively slip into the recv/send callbacks in order
to avoid duplicate check code.

The code works right now with and without splicing. Only raw_sock provides
support for it and it is automatically selected when the various splice
options are set. However it looks like splice-auto doesn't enable it, which
possibly means that the streamer detection code does not work anymore, or
that it's only called at a time where it's too late to enable splicing (in
process_session).
2012-09-03 20:47:31 +02:00
Willy Tarreau
5368d80ede MAJOR: connection: split the send call into connection and stream interface
Similar to what was done on the receive path, the data layer now provides
only an snd_buf() callback that is iterated over by the stream interface's
si_conn_send_loop() function.

The data layer now has no knowledge about channels nor stream interfaces.

The splice() code still need to be ported as it currently is disabled.
2012-09-03 20:47:31 +02:00
Willy Tarreau
ce323dea14 REORG: stream-interface: move sock_raw_read() to si_conn_recv_cb()
The recv function is now generic and is usable to iterate any connection-to-buf
reading function from a stream interface. So let's move it to stream-interface.
2012-09-03 20:47:30 +02:00
Willy Tarreau
1fe6bc335a MINOR: stream-interface: add an rcv_buf callback to sock_ops
This one is to be used by the read I/O handlers.
2012-09-03 20:47:30 +02:00
Willy Tarreau
af978c4170 MAJOR: raw_sock: temporarily disable splicing
It's too hard to convert splicing to connection+buf for now, so let's disable
it in order to make progress.
2012-09-03 20:47:30 +02:00
Willy Tarreau
2ba4465086 MAJOR: raw_sock: extract raw_sock_to_buf() from raw_sock_read()
This is the start of the stream connection iterator which calls the
data-layer reader. This still looks a bit tricky but is OK. Splicing
is not handled at all at the moment.
2012-09-03 20:47:30 +02:00
Willy Tarreau
75bf2c925f REORG: sock_raw: rename the files raw_sock*
The "raw_sock" prefix will be more convenient for naming functions as
it will be prefixed with the data layer and suffixed with the data
direction. So let's rename the files now to avoid any further confusion.

The #include directive was also removed from a number of files which do
not need it anymore.
2012-09-02 21:54:56 +02:00
Willy Tarreau
572bf9095d REORG/MAJOR: extract "struct buffer" from "struct channel"
At the moment, the struct is still embedded into the struct channel, but
all the functions have been updated to use struct buffer only when possible,
otherwise struct channel. Some functions would likely need to be splitted
between a buffer-layer primitive and a channel-layer function.

Later the buffer should become a pointer in the struct buffer, but doing so
requires a few changes to the buffer allocation calls.
2012-09-02 21:54:56 +02:00
Willy Tarreau
7421efb85f REORG/MAJOR: use "struct channel" instead of "struct buffer"
This is a massive rename. We'll then split channel and buffer.

This change needs a lot of cleanups. At many locations, the parameter
or variable is still called "buf" which will become ambiguous. Also,
the "struct channel" is still defined in buffers.h.
2012-09-02 21:54:55 +02:00
Willy Tarreau
9bf9c14c12 MEDIUM: stream-interface: provide a generic stream_sock_read0() function
This function is used by the data layer when a zero has been read over a
connection. At the moment it only handles sockets and nothing else. Once
the complete split is done between buffers and stream interfaces, it should
become possible to work regardless on the connection type.
2012-09-02 21:54:55 +02:00
Willy Tarreau
eecf6ca68a MEDIUM: stream-interface: provide a generic si_conn_send_cb callback
The connection send() callback is supposed to be generic for a
stream-interface, and consists in calling the lower layer snd_buf
function. Move this function to the stream interface and remove
the sock-raw and sock-ssl clones.
2012-09-02 21:54:55 +02:00
Willy Tarreau
de5722c302 MEDIUM: stream-interface: provide a generic stream_int_chk_snd_conn() function
This one can be used by both sock_raw and sock_ssl instead of each having their own.
2012-09-02 21:54:55 +02:00
Willy Tarreau
fae4499e36 MEDIUM: stream-interface: add a snd_buf() callback to sock_ops
This callback is used to send data from the buffer to the socket. It is
the old write_loop() call of the data layer which is used both by the
->write() callback and the ->chk_snd() function. The reason for having
it as a pointer is that it's the only remaining part which causes the
write and chk_snd() functions to be different between raw and ssl.
2012-09-02 21:54:18 +02:00
Willy Tarreau
46a8d925c2 MEDIUM: stream-interface: offer a generic chk_rcv function for connections
sock_raw and sock_ssl use a pretty generic chk_rcv function, so let's move
this function to the stream_interface and remove specific functions. Later
we might have a single chk_rcv function.
2012-09-02 21:54:18 +02:00
Willy Tarreau
100c467120 MEDIUM: stream_interface: offer a generic function for connection updates
We need to have a generic function to be called by upper layers when buffer
flags have been updated (the si->update function). At the moment, both sock_raw
and sock_ssl had their own which basically was a copy-paste. Since these
functions are only used to update stream interface flags, it is logical to
have them handled by the stream interface code.

This allowed us to remove the stream_interface-specific update function from
sock_raw and sock_ssl which now use the generic code.

The stream_sock_update_conn callback has also been more appropriately renamed
conn_notify_si() since it's meant to be called by lower layers to notify the
SI and possibly upper layers about incoming changes.
2012-09-02 21:54:18 +02:00
Willy Tarreau
26f44d1e91 MINOR: fd: get rid of FD_WAIT_*
These flags were used to ease a transition which has been completed,
so they're not needed anymore. Get rid of them.
2012-09-02 21:53:12 +02:00
Willy Tarreau
3267d36c84 MEDIUM: checks: don't use FD_WAIT_* anymore
make use of fd_poll_* instead in preparation for a later adoption by the
connection subsystem.
2012-09-02 21:53:12 +02:00
Willy Tarreau
afad0e0f80 MAJOR: make use of conn_{data|sock}_{poll|stop|want}* in connection handlers
This is a second attempt at getting rid of FD_WAIT_*. Now the situation is
much better since native I/O handlers can directly manipulate the FD using
fd_{poll|want|stop}_* and the connection handlers manipulate connection-level
flags using the conn_{data|sock}_* equivalent.

Proceeding this way ensures that the connection flags always reflect the
reality even after data<->handshake switches.
2012-09-02 21:53:12 +02:00
Willy Tarreau
f9dabecd03 MEDIUM: connection: make use of the new polling functions
Now the connection handler, the handshake callbacks and the I/O callbacks
make use of the connection-layer polling functions to enable or disable
polling on a file descriptor.

Some changes still need to be done to avoid using the FD_WAIT_* constants.
2012-09-02 21:53:11 +02:00
Willy Tarreau
b5e2cbdcc8 MEDIUM: connection: add definitions for dual polling mechanisms
The conflicts we're facing with polling is that handshake handlers have
precedence over data handlers and may change the polling requirements
regardless of what is expected by the data layer. This causes issues
such as missed events.

The real need is to have three polling levels :
  - the "current" one, which is effective at any moment
  - the data one, which reflects what the data layer asks for
  - the sock one, which reflects what the socket layer asks for

Depending on whether a handshake is in progress or not, either one of the
last two will replace the current one, and the change will be propagated
to the lower layers.

At the moment, the shutdown status is not considered, and only handshakes
are used to decide which layer to chose. This will probably change.
2012-09-02 21:53:11 +02:00
Willy Tarreau
babd05a6c6 MEDIUM: fd: add fd_poll_{recv,send} for use when explicit polling is required
The old EV_FD_SET() macro was confusing, as it would enable receipt but there
was no way to indicate that EAGAIN was received, hence the recently added
FD_WAIT_* flags. They're not enough as we're still facing a conflict between
EV_FD_* and FD_WAIT_*. So let's offer I/O functions what they need to explicitly
request polling.
2012-09-02 21:53:11 +02:00
Willy Tarreau
49b046dddf MAJOR: fd: replace all EV_FD_* macros with new fd_*_* inline calls
These functions have a more explicity meaning and will offer provisions
for explicit polling.

EV_FD_ISSET() has been left for now as it is still in use in checks.
2012-09-02 21:53:11 +02:00
Willy Tarreau
4a36b56909 MAJOR: stream_int: use a common stream_int_shut*() functions regardless of the data layer
Up to now, we had to use a shutr/shutw interface per data layer, which
basically means 3 distinct functions when we include SSL :
  - generic stream_interface
  - sock_raw
  - sock_ssl

With this change, the code located in the stream_interface manages all the
stream_interface and buffer updates, and calls the data layer hooks when
needed.

At the moment, the socket layer hook had been implicitly considered as
being a regular socket, so the si_shut*() functions call the normal
shutdown() and EV_FD_CLR() functions on the fd if a socket layer is
defined. This may change in the future. The stream_int_shut*()
functions don't call EV_FD_CLR() so that they can later be embedded
in lower layers.

Thus, the si->data->shutr() is not called anymore and si->data->shutw()
is called to close the data layer only (eg: only for SSL).

Proceeding like this is very important because it's the only way to be
able not to rely on these functions when called from the connection
handlers, and call the data layers' instead.
2012-09-02 21:53:10 +02:00
Willy Tarreau
3d8903fae0 MEDIUM: sock_raw: introduce a read0 callback that is different from shutr
This one is supposed to be called by the lower layer upon receiving a shutr
notification, which is different from the call performed by the upper layer.
Specifically, this function will ultimately not call EV_FD_* but will just
manipulate event flags instead. The function also does not call shutw anymore
and instead performs the necessary work.

Splitting it into si-specific part and data-specific parts will not be easy.
2012-09-02 21:53:10 +02:00
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
3438f5dce1 MINOR: sock_raw: move calls to si_data_close upper
Some users of si_data_close() need to have the fd still open,
so we must move the call before fd_delete().
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
0b0c097a3a MINOR: rearrange tcp_connect_probe() and fix wrong return codes
Sometimes we returned the need for polling while it was not needed. Remove
some of the spaghetti in the function.
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
3c55ec2020 MEDIUM: stream_interface: centralize the SI_FL_ERR management
It's better to have only stream_sock_update_conn() handle the conversion
of the CO_FL_ERROR flag to SI_FL_ERR than having it in each and every I/O
callback.
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
61ace1b2ca MEDIUM: connection: remove the FD_POLL_* flags only once
It's inappropriate to remove FD_POLL_IN and FD_POLL_OUT in the IO callback
handlers, first because they shouldn't care about this, and second because
it will make it harder to chain multiple callers.

So let's flush these flags only once for all in the connection handler.
Right now, the HUP and ERR flags are still flushed in each IO handler to
avoid multiple calls. This will probably have to be fixed later.
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
d2274c6536 MAJOR: connection: replace direct I/O callbacks with the connection callback
Almost all direct I/O callbacks have been changed to use the connection
callback instead. Only the TCP connection validation remains.
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
aece46a44d MEDIUM: protocols: use the generic I/O callback for accept callbacks
This one is used only on read events, and it was easy to convert to
use the new I/O callback.
2012-09-02 21:51:27 +02:00
Willy Tarreau
20bea42a95 MEDIUM: checks: make use of fdtab->iocb instead of cb[]
Use the single I/O callback to handle the checks. This should soon be
replaced by the common connection handler.
2012-09-02 21:51:27 +02:00
Willy Tarreau
9845e75d23 MEDIUM: polling: prepare to call the iocb() function when defined.
We will need this to centralize I/O callbacks. Nobody sets it right
now so the code should have no impact.
2012-09-02 21:51:27 +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
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
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
5d526b7215 REORG/MEDIUM: fd: remove checks for FD_STERROR in ev_sepoll
This test is present only in this poller as an optimization, but this
optimization adds some complexity to remove fdtab[].state. Let's get
rid of it for now.
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
dec9814e74 MINOR: stats/cli: add plans to support more stick-table actions
Right now we only support show/clear on a table. In order to introduce
the "set" keyword we need to get rid of the "show" boolean arg. There
is no functional change up to this commit.
2012-09-02 21:51:06 +02:00
William Lallemand
1dc00efedc BUG/MINOR: to_log erased with unique-id-format
curproxy->to_log was reset to LW_INIT when using unique-id-format,
so logs looked like option logasap
2012-08-09 19:18:22 +02:00
Willy Tarreau
a9fddca778 MINOR: http: add the urlp_val ACL match
It's derived from other urlp_* matches, but there was no way to check for
an integer value and it seems like it's significantly used.
2012-07-31 07:55:32 +02:00
Willy Tarreau
491c498d97 BUG/MINOR: polling: some events were not set in various pollers
fdtab[].ev was only set in ev_sepoll. Unfortunately, some I/O handling
functions now rely on this, so depending on the polling mechanism, some
useless operations might have been performed, such as performing a useless
recv() when a HUP was reported.

This is a very old issue, the flags were only added to the fdtab and not
propagated into any poller. Then they were used in ev_sepoll which needed
them for the cache. It is unsure whether a backport to 1.4 is appropriate
or not.
2012-07-31 07:55:31 +02:00
Willy Tarreau
dae2a8a5a5 BUG/MINOR: tarpit: fix condition to return the HTTP 500 message
Commit fa7e1025 (1.3.16-rc1) introduced a minor bug by comparing req->flags
with BF_READ_ERROR instead of checking for the bit. The result is that the
error message is always returned even in case of client error. This has no
real impact but this must be fixed.

It may be backported to 1.4 and 1.3.
2012-07-31 07:55:31 +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
5b88da269c OPTIM: i386: make use of kernel-mode-linux when available
If haproxy is built with support for USE_VSYSCALL_DLSYM, it's very
easy to check for KML availability. So let's enable it. Tests show
a small overall performance improvement around 1%. Other tests show
that the syscall overhead is divided by 4 on a Geode LX using this
method.
2012-07-31 07:53:42 +02:00
Willy Tarreau
a7ad50cdb1 MEDIUM: pattern: add the "base" sample fetch method
This one returns the concatenation of the first Host header entry with
the path. It can make content-switching rules easier, help with fighting
DDoS on certain URLs and improve shared caches efficiency.
2012-07-26 19:08:38 +02:00
Willy Tarreau
6812bcfc94 MINOR: replace acl_fetch_{path,url}* with smp_fetch_*
Doing so allows us to support sticking on URL, URL's IP, URL's port and
path.

Both fetch functions should be improved to support an optional depth
allowing to stick to a server depending on just a few directory
components. This would help with portals, some prefetch-capable
caches and with outgoing connections using multiple internet links.
2012-07-26 19:06:40 +02:00
Willy Tarreau
e3a461118c BUG/MINOR: ACL implicit arguments must be created with unresolved flag
Commit 496aa0 fixed a design issue by adding an "unresolved" flag to the
ACL arguments. Unfortunately this unresolved flag was not set when building
the fake argument some ACL need when using an implicit argument pointing to
the local proxy.

Special thanks to Michael Kearey who reported the issue with a reproducer
and the commit introducing the bug.
2012-06-15 08:02:34 +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
a05903174f BUG/MAJOR: cookie prefix doesn't support cookie-less servers
Commit 827aee91 merged in 1.5-dev5 introduced a regression causing
the srv pointer to be tested twice instead of srv then srv->cookie.
The result is that if a server has no cookie in prefix mode, haproxy
will crash when trying to modify it.

Such a config is very unlikely to happen, except maybe with a backup
server, which would cause haproxy to die with the last server in the
farm.

No backport is needed, only 1.5-dev was affected.
2012-06-06 16:07:00 +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
39b0665bc7 BUG/MINOR: commit 196729ef used wrong condition resulting in freeing constants
Recent commit 196729ef had inverted condition to free format strings. No
backport is needed, it was never released.
2012-06-01 10:58:06 +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
99a7ca2fa6 BUG/MINOR: log: don't report logformat errors in backends
Logs have always been ignored by backends, do not report useless warnings there.
2012-05-31 19:39:23 +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
743a2d3e14 BUG/MEDIUM: buffers: fix bi_putchr() to correctly advance the pointer
bi_putchr() failed to move the buffer pointer forward. The only user
was the peer handler which was broken, it failed to sync. Thanks to
Hervé Commowick for reporting the issue.
2012-05-31 16:40:11 +02:00
Willy Tarreau
fa6bac6ec3 BUG/MEDIUM: register peer sync handler in the proper order
Hervé Commowick reported a failure to resync upon restart caused by a
segfault on the old process. This is due to the data_ctx of the connection
being initialized after the stream interface.
2012-05-31 14:16:59 +02:00
Willy Tarreau
cde18fc1ba BUG/MINOR: perform_http_redirect also needs to rewind the buffer
Commit d1de8af362 was incomplete, because
perform_http_redirect() also needs to rewind the buffer since it's called
after data are scheduled for forwarding.

No backport needed.
2012-05-30 08:00:56 +02:00
Cyril Bonté
a32d275ab0 BUG/MEDIUM: option forwardfor if-none doesn't work with some configurations
When "option forwardfor" is enabled in a frontend that uses backends,
"if-none" ignores the header name provided in the frontend.
This prevents haproxy to add the X-Forwarded-For header if the option is not
used in the backend.

This may introduce security issues for servers/applications that rely on the
header provided by haproxy.

A minimal configuration which can reproduce the bug:
defaults
	mode http

listen OK
	bind :9000

	option forwardfor if-none
	server s1 127.0.0.1:80

listen BUG-frontend
	bind :9001

	option forwardfor if-none

	default_backend BUG-backend

backend BUG-backend
	server s1 127.0.0.1:80
2012-05-30 06:43:24 +02:00
Willy Tarreau
7de211c88b MINOR: add a new function call tracer for debugging purposes
This feature relies on GCC's ability to call helpers at function entry/exit
points. We define these helpers to quickly dump the minimum info into a trace
file that can be converted to a human readable format using a script in the
contrib/trace directory. This has only been implemented in the GNU makefile
for now on as it is unsure whether it's supported on all OSes.

The feature is enabled by building with "TRACE=1". The performance impact is
huge, so this feature should only be used when debugging. To limit the loss
of performance, fprintf() has been disabled and the output is hand-crafted
and emitted using fwrite(), resulting in doubling the performance. Using the
TSC instead of gettimeofday() also doubles the performance. Around 1200 conns/s
may be achieved on a Pentium-M 1.7 GHz which leads to around 50 MB/s of traces.

The entry and exits of all functions will be dumped into a file designated
by the HAPROXY_TRACE environment variable, or by default "trace.out". If the
trace file name is empty or "/dev/null", then traces are disabled. If
opening the trace file fails, then stderr is used. If HAPROXY_TRACE_FAST is
used, then the time is taken from the global <now> variable. Last, if
HAPROXY_TRACE_TSC is used, then the machine's TSC is used instead of the
real time (almost twice as fast).

The output format is :

  <sec.usec> <level> <caller_ptr> <dir> <callee_ptr>
or :
  <tsc> <level> <caller_ptr> <dir> <callee_ptr>

where <dir> is '>' when entering a function and '<' when leaving.

The awk script in contrib/trace provides a nicer indented output :

6f74989e6f8 ->->->   run_poll_loop > signal_process_queue [src/haproxy.c:1097:0x804bd69] > [include/proto/signal.h:32:0x8049cd0]
6f74989eb00          run_poll_loop < signal_process_queue [src/haproxy.c:1097:0x804bd69] < [include/proto/signal.h:32:0x8049cd0]
6f74989ef44 ->->->   run_poll_loop > wake_expired_tasks [src/haproxy.c:1100:0x804bd72] > [src/task.c:123:0x8055060]
6f74989f3a6 ->->->->   wake_expired_tasks > eb32_lookup_ge [src/task.c:128:0x8055091] > [ebtree/eb32tree.c:138:0x80a8c70]
6f74989f7e9            wake_expired_tasks < eb32_lookup_ge [src/task.c:128:0x8055091] < [ebtree/eb32tree.c:138:0x80a8c70]
6f74989fc0d ->->->->   wake_expired_tasks > eb32_first [src/task.c:134:0x80550d5] > [ebtree/eb32tree.h:55:0x8054ad0]
6f7498a003d ->->->->->   eb32_first > eb_first [ebtree/eb32tree.h:56:0x8054af1] > [ebtree/ebtree.h:520:0x8054a10]
6f7498a0436 ->->->->->->   eb_first > eb_walk_down [ebtree/ebtree.h:521:0x8054a33] > [ebtree/ebtree.h:442:0x80549a0]
6f7498a0843 ->->->->->->->   eb_walk_down > eb_gettag [ebtree/ebtree.h:445:0x80549d6] > [ebtree/ebtree.h:418:0x80548e0]
6f7498a0c2b                  eb_walk_down < eb_gettag [ebtree/ebtree.h:445:0x80549d6] < [ebtree/ebtree.h:418:0x80548e0]
6f7498a1042 ->->->->->->->   eb_walk_down > eb_untag [ebtree/ebtree.h:447:0x80549e2] > [ebtree/ebtree.h:412:0x80548a0]
6f7498a1498                  eb_walk_down < eb_untag [ebtree/ebtree.h:447:0x80549e2] < [ebtree/ebtree.h:412:0x80548a0]
6f7498a18c6 ->->->->->->->   eb_walk_down > eb_root_to_node [ebtree/ebtree.h:448:0x80549e7] > [ebtree/ebtree.h:432:0x8054960]
6f7498a1cd4                  eb_walk_down < eb_root_to_node [ebtree/ebtree.h:448:0x80549e7] < [ebtree/ebtree.h:432:0x8054960]
6f7498a20c4                eb_first < eb_walk_down [ebtree/ebtree.h:521:0x8054a33] < [ebtree/ebtree.h:442:0x80549a0]
6f7498a24b4              eb32_first < eb_first [ebtree/eb32tree.h:56:0x8054af1] < [ebtree/ebtree.h:520:0x8054a10]
6f7498a289c            wake_expired_tasks < eb32_first [src/task.c:134:0x80550d5] < [ebtree/eb32tree.h:55:0x8054ad0]
6f7498a2c8c          run_poll_loop < wake_expired_tasks [src/haproxy.c:1100:0x804bd72] < [src/task.c:123:0x8055060]
6f7498a3095 ->->->   run_poll_loop > process_runnable_tasks [src/haproxy.c:1103:0x804bd7a] > [src/task.c:190:0x8055150]

A nice improvement would possibly consist in trying to get the function's
arguments in the stack and to dump a few more infor for some well-known
functions (eg: the session's status for process_session).
2012-05-26 00:12:37 +02:00
Willy Tarreau
1e44a49c89 BUG/MINOR: checks: expire on timeout.check if smaller than timeout.connect
It happens that haproxy doesn't displace the task in the wait queue when
validating a connection, so if the check timeout is set to a smaller value
than timeout.connect, it will not strike before timeout.connect.

The bug is present at least in 1.4.15..1.4.21, so the fix must be backported.
2012-05-25 07:42:37 +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
1348d4ce0b MINOR: peers: use the socket layer operations from the peer instead of sock_raw
At the moment, all the peers are initialized to use sock_raw as the socket
layer, so use this info in peers_session_create() instead of the hard-coded
sock_raw.
2012-05-21 22:21:37 +02:00
Willy Tarreau
4da69a91a0 MEDIUM: stream_interface: call si_data_close() before releasing the si
This will ensure that the data layer releases anything previously allocated.
2012-05-21 18:07:11 +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
fe7f1ea68e REORG/MINOR: session: detect the TCP monitor checks at the protocol accept
It does not make sense anymore to wait for a session creation to process
a TCP monitor check which only closes the connection and returns. Better
to process this immediately after the accept() return. It also saves us
from counting a connection for monitor checks, which is much more logical.
2012-05-20 19:22:25 +02:00
Willy Tarreau
a190d591fc REORG: move the send-proxy code to tcp_connect_write()
It is much better and more efficient to consider that the send-proxy
feature is part of the protocol layer than part of the data layer.
Now the connection is considered established once the send-proxy line
has been sent.

This way the data layer doesn't have to care anymore about this specific
part.

The tcp_connect_write() function now automatically calls the data layer
write() function once the connection is established, which saves calls
to epoll_ctl/epoll_wait/process_session.

It's starting to look more and more obvious that tcp_connect_read() and
tcp_connect_write() are not TCP-specific but only socket-specific and as
such should probably move, along with some functions from protocol.c, to
a socket-specific file (eg: stream_sock).

It would be nice to be able to support autonomous listeners to parse the
proxy protocol before accepting a connection, so that we get rid of it
at the session layer and to support using these informations in the
tcp-request connection rules.
2012-05-20 18:35:19 +02:00
Willy Tarreau
8ae52cb144 BUG/MINOR: stop connect timeout when connect succeeds
If the connect succeeds exactly at the same millisecond as the connect
timeout is supposed to strike, the timeout is still considered while
data may have already be sent. This results in a new connection attempt
with no data and with the response being lost.

Note that in practice the only real-world situation where this is observed
is when connect timeouts are extremely low, too low for safe operations.
This bug was encountered with a 1ms connect timeout.

It is also present on 1.4 and needs to be fixed there too.
2012-05-20 10:38:46 +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
ea95316bf1 MEDIUM: http: msg->sov and msg->sol will never wrap
These ones are offsets now, so they cannot wrap. Let's remove the useless
wrapping detection and simplify the forwarding code.
2012-05-18 23:50:43 +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
06a000f56e CLEANUP: http: make it more obvious that msg->som is always null outside of chunks
Since the recent buffer reorg, msg->som is redundant with buf->p but still
appears at a number of places. This tiny patch allows to confirm that som
follows two states :
  - 0 from the moment the message starts to be parsed
  - relative offset to ->p for start of chunk when parsing chunks

During this second state, ->sol is never used, so we should probably merge
the two.
2012-05-18 23:04:32 +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
d1de8af362 BUG/MAJOR: fix regression on content-based hashing and http-send-name-header
The recent split between the buffers and HTTP messages in 1.5-dev9 caused
a major trouble : in the past, we used to keep a pointer to HTTP data in the
buffer struct itself, which was the cause of most of the pain we had to deal
with buffers.

Now the two are split but we lost the information about the beginning of
the HTTP message once it's being forwarded. While it seems normal, it happens
that several parts of the code currently rely on this ability to inspect a
buffer containing old contents :
  - balance uri
  - balance url_param
  - balance url_param check_post
  - balance hdr()
  - balance rdp-cookie()
  - http-send-name-header

All these happen after the data are scheduled for being forwarded, which
also causes a server to be selected. So for a long time we've been relying
on supposedly sent data that we still had a pointer to.

Now that we don't have such a pointer anymore, we only have one possibility :
when we need to inspect such data, we have to rewind the buffer so that ->p
points to where it previously was. We're lucky, no data can leave the buffer
before it's being connecting outside, and since no inspection can begin until
it's empty, we know that the skipped data are exactly ->o. So we rewind the
buffer by ->o to get headers and advance it back by the same amount.

Proceeding this way is particularly important when dealing with chunked-
encoded requests, because the ->som and ->sov fields may be reused by the
chunk parser before the connection attempt is made, so we cannot rely on
them.

Also, we need to be able to come back after retries and redispatches, which
might change the size of the request if http-send-name-header is set. All of
this is accounted for by the output queue so in the end it does not look like
a bad solution.

No backport is needed.
2012-05-18 22:23:01 +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
dbcd47ea35 OPTIM/MAJOR: ev_sepoll: process spec events after polled events
A suboptimal behaviour was appearing quite often with sepoll. When a
speculative write failed after a connect(), the socket was added to
the poll list using epoll_ctl(ADD). Then when epoll_wait() returned a
write event, the send() was performed and write event disabled, causing
it to get back to the spec list in order to be disabled later. But if
some new accept() did succeed in the same run, then fd_created was not
null, causing a new run of the spec list to happen. This run would then
detect the old event in STOP state and would remove it from the poll
list using epoll_ctl(DEL).

After this, process_session() enables reading on the FD, attempting
an speculative recv() which fails then adds it again using epoll_ctl(ADD)
to do it again. So the total sequence of syscalls looked like this :

connect(fd) = EAGAIN
send(fd) = EAGAIN
epoll_ctl(ADD(fd:OUT))
epoll_wait() = fd:OUT
send(fd) > 0
epoll_ctl(DEL(fd))
recv(fd) = EAGAIN
epoll_ctl(ADD(fd:IN))
recv(fd) > 0

In order to fix this stupid situation, we must compute the epoll_ctl()
parameters at the last moment, just before doing epoll_wait(). This is
what was done except that the spec events were processed just before doing
that without leaving time for the tasks to adjust the FDs if needed. This
is also the reason we have the re_poll_once label to try to catch new
events in case of a successful accept().

The new solution consists in doing the opposite :

  - compute epoll_ctl()
  - call epoll_wait()
  - call spec events

This significantly reduces the number of iterations on the spec events
and avoids a huge number of epoll_ctl() ping/pongs. The new sequence
above simply becomes :

connect(fd) = EAGAIN
send(fd) = EAGAIN
epoll_ctl(ADD(fd:OUT))
epoll_wait() = fd:OUT
send(fd) > 0
epoll_ctl(MOD(fd:IN))
recv(fd) > 0

Also, there is no need to re-run the spec events after an accept() as
it will automatically be detected in the spec list after a return from
polled events.

The gains are important, with up to 4.5% global performance increase in
connection rate on HTTP with small objects. The code is less tricky and
does not need anymore to skip epoll_wait() every other call, nor to
track the number of FDs newly created.
2012-05-13 09:55:07 +02:00
Willy Tarreau
93548be149 OPTIM: proto_http: don't enable quick-ack on empty buffers
Commit 5e205524 was a bit overzealous by inconditionally enabling
quick ack when a request is not yet in the buffer, because it also
does so when nothing has been received yet, causing a useless ACK
to be emitted.

Improve the situation by doing this only if the input buffer is
empty (indicating that nothing was sent by the client).

In case of keep-alive, an empty buffer means we already have a
response in flight which will serve as an ACK.
2012-05-13 08:44:16 +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
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
2f5b6fc090 MINOR: session: call the socket layer init function when a session establishes
In sess_establish, once we've prepared everythin, we can call the socket layer
init function. We pass an argument for targets which have one (eg: servers). At
the moment, the existing socket layers don't have init functions, but SSL will
need one.
2012-05-12 08:09:27 +02:00
Willy Tarreau
eeda90e68c MAJOR: fd: remove the need for the socket layer to recheck the connection
Up to now, if an outgoing connection had no data to send, the socket layer
had to perform a connect() again to check for establishment. This is not
acceptable for SSL, and will cause problems with socketpair(). Some socket
layers will also need an initializer before sending data (eg: SSL).

The solution consists in moving the connect() test to the protocol layer
(eg: TCP) and to make it hold the fd->write callback until the connection
is validated. At this point, it will switch the write callback to the
socket layer's write function. In fact we need to hold both read and write
callbacks to ensure the socket layer is never called before being initialized.

This intermediate callback is used only if there is a socket init function
or if there are no data to send.

The socket layer does not have any code to check for connection establishment
anymore, which makes sense.
2012-05-11 20:18:26 +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
46b39d0dc6 BUG/MEDIUM: config: don't crash at config load time on invalid userlist names
Cyril Bonté reported that passing an invalid userlist name to
http_auth_group() caused haproxy to crash at load. This was due
to an attempt to use the unresolved userlist pointer later to
resolve auth groups since we report many errors before leaving
now.

This issue does not exist in earlier versions since they immediately
abort on the first error, so no backport is needed.
2012-05-10 23:42:22 +02:00
Willy Tarreau
b95095979c CLEANUP: auth: make the code build again with DEBUG_AUTH
Reported by Cyril Bonté, minor issue caused by recent ACL rework.
2012-05-10 23:25:35 +02:00
Willy Tarreau
4a3fd4c8df BUG/MAJOR: acl: http_auth_group() must not accept any user from the userlist
http_auth and http_auth_group used to share the same fetch function, while
they're doing very different things. The first one only checks whether the
supplied credentials are valid wrt a userlist while the second not only
checks this but also checks group ownership from a list of patterns.

Recent acl/pattern merge caused a simplification here by which the fetch
function would always return a boolean, so the group match was always fine
if the user:password was valid, regardless of the patterns provided with
the ACL.

The proper solution consists in splitting the function in two, depending
on what is desired.

It's also worth noting that check_user() would probably be split, one to
check user:password, and the other one to check for group ownership for
an already valid user:password combination. At this point it is not certain
if the group mask is still useful or not considering that the passwd check
is always made.

This bug was reported and diagnosed by Cyril Bonté. It first appeared
in 1.5-dev9 so it does not need any backporting.
2012-05-10 23:18:26 +02:00
Cyril Bonté
20a804ac6d BUG/MINOR: stats admin: "Unexpected result" was displayed unconditionally
I introduced a regression in commit 19979e176e while reworking the admin
actions results.
"Unexpected result" was displayed even if the action was applied due to a
misplaced initialization. This small patch should fix it.

Note: no need to backport.
2012-05-10 21:51:17 +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
f4068b6503 MINOR: cfgparse: use a common errmsg pointer for all parsers
In order to generalize the simplified error reporting mechanism, let's
centralize the error pointer.
2012-05-08 21:28:17 +02:00
Willy Tarreau
bd83314ee9 BUG/MEDIUM: log: ensure that unique_id is properly initialized
Last memory poisonning patch immediately made this issue appear.
The unique_id field is released but not properly initialized. The
feature was introduced very recently, no backport is needed.
2012-05-08 21:28:16 +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
63e7fe310e BUG/MEDIUM: send_proxy: fix initialisation of send_proxy_ofs
Commit b22e55bc introduced send_proxy_ofs but forgot to initialize it,
which remained unnoticed since it's always at the same place in the
stream interface. On a machine with dirty RAM returned by malloc(),
some responses were holding a PROXY header, which normally is not
possible.

The problem goes away after properly initializing the field upon each
new session_accept().

This fix does not need to be backported except if any code makes use of
a backport of this feature.
2012-05-08 21:28:16 +02:00
Willy Tarreau
515393649c MINOR: acl: add the cook_val() match to match a cookie against an integer 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
69d8c5d99e BUG/MINOR: http: ensure that msg->err_pos is always relative to buf->p
Since the beginning of buffer&msg changes, the error position (err_pos)
had not completely been converted and some offsets still appear wrong.
Now we ensure that everywhere msg->err_pos is relative to buf->p and
we always report buf->i bytes starting at buf->p in all error captures,
which ensures that err_pos is there.

This is not exactly a bug and is specific to latest changes so no backport
is needed.
2012-05-08 21:28:15 +02:00
Willy Tarreau
d6c2e8c916 BUG/MINOR: http: error snapshots are wrong if buffer wraps
Commit 81f2fb added support for wrapping buffer captures, but unfortunately
the code used to perform two memcpy() over the same destination, causing a
loss of the start of the buffer rendering some error snapshots unusable.

This bug is present in 1.4 too and must be backported.
2012-05-08 21:28:15 +02:00
Willy Tarreau
22bca61404 MEDIUM: proto_tcp: remove src6 and dst6 pattern fetch methods
These methods have been superseded by src and dst which support
multiple families. There is no point keeping them since they appeared
in a development version anyway.

For configurations using "src6", please use "src" instead. For "dst6",
use "dst" instead.
2012-05-08 21:28:15 +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
08ad0b38c4 MINOR: acl: report errors encountered when loading patterns from files
This happens in acl_read_patterns_from_file(). Errors are still incomplete,
parsing functions must be improved to report parsing errors.
2012-05-08 20:57:20 +02:00
Willy Tarreau
4e6336fdfd MINOR: arg: improve error reporting on invalid arguments
It's important to report the faulty argument position and to distinguish
between empty arguments and wrong ones.

Integers were not properly tested either, now their parsing has been improved
to report use of incorrect characters.
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
28376d62cb MEDIUM: http: merge ACL and pattern cookie fetches into a single one
It's easy to merge pattern and ACL fetches of cookies. It allows us
to remove two distinct fetch functions. The new function internally
uses an occurrence number to serve both purposes, but it didn't appear
worth exposing it outside so there is no keyword argument to set it.
However one of the benefits is that the "cookie" fetch for stick tables
now automatically adapts to requests and responses, so there is no more
need for set-cookie().
2012-05-08 20:57:19 +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
0d5fe144a1 MINOR: proto_tcp: validate arguments of payload and payload_lv ACLs
Now it's possible to control arguments, so let's do it.
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
d6281ae046 MEDIUM: pattern: use smp_fetch_rdp_cookie instead of the pattern specific version
pattern_fetch_rdp_cookie() is useless now since it only used to add controls
on top of smp_fetch_rdp_cookie() which have now been integrated into the
pattern subsystem. Let's remove it.
2012-05-08 20:57:18 +02:00
Willy Tarreau
40aebd9239 MINOR: pattern: centralize handling of unstable data in pattern_process()
Pattern fetch functions currently check for unstable data and return 0
when SMP_F_MAY_CHANGE is set. Instead of doing this everywhere and having
to support specific fetch functions, better do that in pattern_process()
which is the one interested in having stable data.
2012-05-08 20:57:18 +02:00
Willy Tarreau
7fc1c6eefb MINOR: stick_table: centralize the handling of empty keys
Right now, it's up to each pattern fetch method to return NULL when an
empty string is returned, which is neither correct nor desirable as it
is only stick tables which need to ignore empty patterns. Let's perform
this check in stktable_fetch_key() instead.
2012-05-08 20:57:18 +02:00
Willy Tarreau
82ea800b0f CLEANUP: pattern: ensure that payload and payload_lv always stay in the buffer
A test was already performed which worked by pure luck due to integer types,
otherwise it would have been possible to start checking for an offset out of
the buffer's bounds if the buffer size was large enough to allow an integer
wrap. Let's perform explicit checks and use unsigned ints for offsets instead
of risking being hit later.
2012-05-08 20:57:18 +02:00
Willy Tarreau
0ce3aa0c66 MEDIUM: acl: implement payload and payload_lv
These ones were easy to adapt to ACL usage and may really be useful,
so let's make them available right now. It's likely that some extension
such as regex, string-to-IP and raw IP matching will be implemented in
the near future.
2012-05-08 20:57:17 +02:00
Willy Tarreau
4a12981c68 MEDIUM: acl/pattern: factor out the src/dst address fetches
Since pattern_process() is able to automatically cast returned types
into expected types, we can safely use the sample functions to fetch
addresses whatever their family. The lowest castable type must be
declared with the keyword so that config checks pass.

Right now this means that src/dst use the same fetch function for ACLs
and patterns. src6/dst6 have been kept so that configs which explicitly
rely on v6 are properly checked.
2012-05-08 20:57:17 +02:00
Willy Tarreau
12e5011a76 MEDIUM: pattern: ensure that sample types always cast into other types.
We want to ensure that a dynamically returned type will always have a
cast before calling the cast function. This is done in pattern_process()
and in stktable_fetch_key().
2012-05-08 20:57:17 +02:00
Willy Tarreau
25c1ebc0c9 MEDIUM: acl/pattern: start merging common sample fetch functions
src_port, dst_port and url_param have converged between ACLs and patterns.
This means that src_port is now available in patterns and that urlp_* has
been added to ACLs. Some code has moved to accommodate for static function
definitions, but there were little changes.
2012-05-08 20:57:17 +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
9fb4bc7f43 MINOR: tcp: replace acl_fetch_rdp_cookie with smp_fetch_rdp_cookie
The former was only a wrapper to the second, let's remove it now that
the calling convention is exactly the same. This is the first function
to be unified between ACLs and samples.
2012-05-08 20:57:16 +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
b8c8f1f611 MEDIUM: pattern: retrieve the sample type in the sample, not in the keyword description
We need the pattern fetchers and converters to correctly set the output type
so that they can be used by ACL fetchers. By using the sample type instead of
the keyword type, we also open the possibility to create some multi-type
pattern fetch methods later (eg: "src" being v4/v6). Right now the type in
the keyword is used to validate the configuration.
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
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
b27c0d35dd MEDIUM: pattern: report the precise argument parsing error when known.
The argument parser knows what exact error it has faced, and the pattern
parser is able to report errors, so let's make use of it. From now on, it
becomes possible to detect such things :

$ ./haproxy -db -f echo5.cfg
[ALERT] 110/160344 (4791) : parsing [echo5.cfg:38] : 'stick': invalid arg 2 in fetch method 'payload' : Missing arguments (got 1/2), type 'unsigned integer' expected.
[ALERT] 110/160344 (4791) : parsing [echo5.cfg:39] : 'stick': invalid args in fetch method 'payload' : payload length must be > 0.
[ALERT] 110/160344 (4791) : parsing [echo5.cfg:40] : 'stick': invalid arg 3 in fetch method 'payload_lv' : Failed to parse 'x' as type 'signed integer'.
[ALERT] 110/160344 (4791) : parsing [echo5.cfg:41] : 'stick': invalid arg 4 in fetch method 'payload_lv' : End of arguments expected at ',13'.
[ALERT] 110/160344 (4791) : Error(s) found in configuration file : echo5.cfg
[ALERT] 110/160344 (4791) : Fatal errors found in configuration.
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
0146c2e873 MEDIUM: acl: remove unused tests for missing args when args are mandatory
A number of ACL fetch methods use mandatory arguments (eg: proxy names) so
it's pointless to test for the presence of this argument now.
2012-05-08 20:57:12 +02:00
Willy Tarreau
fc2c1fd449 MAJOR: acl: ensure that implicit table and proxies are valid
A large number of ACLs make use of frontend, backend or table names in their
arguments, and fall back to the current proxy when no argument is passed. If
the expected capability is not available, the ACL silently fails at runtime.

Now we make all those names mandatory in the parser and we rely on
acl_find_targets() to replace the missing names with the holding proxy,
then to perform the appropriate tests, and to reject errors at parsing
time.

It is possible that some faulty configurations will get rejected from now
on, while they used to silently fail till now. This is the reason why this
change is marked as MAJOR.
2012-05-08 20:57:12 +02:00
Willy Tarreau
d28c353fc5 MAJOR: acl: make acl_find_targets also resolve proxy names at config time
Proxy names are now resolved when the config is parsed and not at runtime.
This means that errors will be caught for real instead of having an ACL
silently never match. Another benefit is that the fetch will be much faster
since the lookup will not have to be performed anymore, eg for all ACLs
based on explicitly named stick-tables.

However some buggy configurations which used to silently fail in the past
will now refuse to load, hence the MAJOR tag.
2012-05-08 20:57:11 +02:00
Willy Tarreau
63364eed75 MEDIUM: acl: acl_find_target() now resolves arguments based on their types
This function does not rely on the keyword anymore but just on its type.
It's much cleaner and much safer. It should be extended to do the same for
all PRX type arguments.
2012-05-08 20:57:11 +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
d53e2428d1 MEDIUM: http/acl: make acl_fetch_hdr_{ip,val} rely on acl_fetch_hdr()
These two functions will now exploit the return of acl_fetch_hdr() instead
of doing the same work again and again.
2012-05-08 20:57:10 +02:00
Willy Tarreau
e333ec9f24 MEDIUM: http/acl: merge all request and response ACL fetches of headers and cookies
Latest changes have made it possible to remove all differences between
request and response processing, making it worth merging request and
response ACL fetch functions to reduce code size.

Most likely with minor adaptation it will be possible to use the same hdr_*
functions to match in the response path, and cook_* for the response cookie
too.
2012-05-08 20:57:10 +02:00
Willy Tarreau
7744e0cf43 BUG/MINOR: http_auth: ACLs are volatile, not permanent
ACLs are volatile since they require a fetch of request buffer data which is
then copied to a temporary shared place. The issue is minor though since auth
is generally checked very early.
2012-05-08 20:57:10 +02:00
Willy Tarreau
c0239e0425 MEDIUM: http: make all ACL fetch function use acl_prefetch_http()
All ACLs which need to process HTTP contents first call this function which
performs all the preliminary tests and also triggers the request parsing if
needed. A macro was written to simplify the code.

As a side effect, it's not required anymore to check for the HTTP ACL before
checking for HTTP contents.
2012-05-08 20:57:10 +02:00
Willy Tarreau
14174bc4c0 MEDIUM: http: add a prefetch function for ACL pattern fetch
This function will be called by all ACL fetch functions. Right now all ACL
fetch functions have to perform the exact same tests to check whether data
are available. Also, only one of them is able to actually parse an HTTP
request.

Using the prefetch function, it will be possible to try to parse a request
on the fly and to avoid the fetch if some data are missing. This will
significantly reduce the amount of tests in all ACL fetch functions.
2012-05-08 20:57:09 +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
8b1323e4cb MINOR: http: remove useless wrapping checks in http_msg_analyzer
The message cannot wrap here.
2012-05-08 12:28:14 +02:00
Willy Tarreau
4baf44ba67 MEDIUM: http: remove buffer arg in chunk parsing functions
The buffer pointer is now taken from the http_msg in the following
functions :

	http_parse_chunk_size
	http_forward_trailers
	http_skip_chunk_crlf

Most internal pointers were converted to const as the result of the
operation.
2012-05-08 12:28:14 +02:00
Willy Tarreau
21710ffa35 MEDIUM: http: remove buffer arg in http_buffer_heavy_realign
The buffer pointer is now taken from the http_msg. The function has also
been renamed "http_message_realign".
2012-05-08 12:28:13 +02:00
Willy Tarreau
418bfcc794 MEDIUM: http: remove buffer arg in http_upgrade_v09_to_v10
The buffer and http_msg pointers are now taken from the transaction.
2012-05-08 12:28:13 +02:00
Willy Tarreau
a560c21f54 MEDIUM: http: remove buffer arg in http_msg_analyzer
The buffer pointer is now taken from the http_msg.
2012-05-08 12:28:13 +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
6acf7c9179 MEDIUM: http: remove buffer arg in a few header manipulation functions
The buffer pointer is now taken from the http_msg in the following functions :

 - http_remove_header2
 - http_header_add_tail
 - http_header_add_tail2
 - http_parse_connection_header
 - http_change_connection_header
2012-05-08 12:28:12 +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
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
21337825c0 CLEANUP: remove a few warning about unchecked return values in debug code
There were a few unchecked write() calls in the debug code that cause
gcc 4.x to emit warnings on recent libc. We don't want to check them
as we can't make anything from the result, let's simply surround them
with an empty if statement.

Note that one of the warnings was for chdir("/") which normally cannot
fail since it follows a successful chroot (which means the perms are
necessarily there). Anyway let's move the call uppe to protect it too.
2012-04-30 11:56:30 +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
b56928a74c CLEANUP: http: message parser must ignore HTTP_MSG_ERROR
The issue only happens when DEBUG_FULL is enabled, which causes
http_msg_analyzer() to complain if it's called twice with an invalid
message, for instance because of two consecutive ACLs using req_proto_http.

The code is commented out when DEBUG_FULL is disabled, so this is not a bug,
just an annoyance for the developer.
2012-04-30 11:51:59 +02:00
Willy Tarreau
46787ed700 BUILD: http: stop gcc-4.1.2 from complaining about possibly uninitialized values
The three warnings below are totally wrong since the variables depend on another
one which is only turned on when the variables are initialized. Still this gcc-4.1.2
isn't able to see this and prefers to complain wrongly. So let's initialize the
variables to shut it up since we're not in the fast path.

src/proto_http.c: In function 'acl_fetch_any_cookie_cnt':
src/proto_http.c:8393: warning: 'val_end' may be used uninitialized in this function

src/proto_http.c: In function 'http_process_req_stat_post':
src/proto_http.c:2577: warning: 'st_next_param' may be used uninitialized in this function
src/proto_http.c:2577: warning: 'st_cur_param' may be used uninitialized in this function
2012-04-30 00:19:31 +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
Daniel Schultze
90690c7aca MINOR: cli: display the 4 IP addresses and ports on "show sess XXX"
I have modified dumpstats.c to show additional information for the show
session <id> command on the statistics socket. This will dump the
public, frontend, backend, and server ip/tcp addresses and port. We
found it useful to have this information available in real time and
could not find another way of getting this information.
2012-04-09 20:51:06 +02:00
Willy Tarreau
d017f113c0 BUG/MINOR: acl: req_ssl_sni would randomly fail if a session ID is present
The wrong byte was checked for the session_id length in the payload. This
used to work when the session ID was absent because zero was found there,
but when a session ID is present, there is 1/256 chance that the inspected
data contains 0x20 (the actual session ID length), so it fails.

Thanks to Emmanuel Bézagu for reporting this bug.

This bug does not need backporting, it is 1.5 specific.
2012-04-09 09:24:11 +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
d94991d236 CLEANUP: Fix some minor whitespace issues 2012-04-07 09:56:14 +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
64559c565f CLEANUP: lb_first: add reference to a paper describing the original idea
The original idea behind this implementation has been published in the
paper below :

   http://reports-archive.adm.cs.cmu.edu/anon/2012/CMU-CS-12-109.pdf
2012-04-07 09:08:45 +02:00
Willy Tarreau
04aa6a9ce8 MEDIUM: http: add cookie and scookie ACLs
The ACL matches rely on the extract_cookie_value() function as used for
for patterns. This permits ACLs to match cookie values based on the cookie
name instead of having to perform substring matching on the cookie header.
2012-04-07 08:47:26 +02:00
Willy Tarreau
4573af939c MEDIUM: http: make extract_cookie_value() iterate over cookie values
This will make the function usable for ACLs.
2012-04-06 18:20:06 +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
ceafb4aa92 CLEANUP: Fix some minor typos 2012-04-05 10:39:45 +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é
aa0a45d2ed MINOR: stats admin: use the backend id instead of its name in the form
Proxy ids are unique whereas names can be used several times in the
configuration. In order to prevent the ambiguity, the HTML form now provides
the backend id instead of its name (the name can still be provided in the POST
data).
2012-04-05 09:58:26 +02:00
Cyril Bonté
0bb519e6e5 CLEANUP: fix typo in findserver() log message
There was a typo in the findserver() log message :
"found" was written "fould".
2012-04-05 09:58:25 +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
Willy Tarreau
5dd7fa1f6b BUG/MEDIUM: balance source did not properly hash IPv6 addresses
The hash of IPv6 addresses was not properly aligned and resulted in the
last quarter of the address not being hashed. In practice, this is rarely
detected since MAC addresses are used in the second half. But this becomes
very visible with IPv6-mapped IPv4 addresses such as ::FFFF:1.2.3.4 where
the IPv4 part is never hashed.

This bug has been there forever, since introduction of "balance source" in
v1.2.11. The fix must then be backported to all stable versions.

Thanks to Alex Markham for reporting this issue to the list !
2012-03-31 19:53:37 +02:00
William Lallemand
51b5dcae85 BUG/MAJOR: log: possible segfault with logformat
Possible zero-pointer deference in sess_log().
Checks of return values in sess_log() fix the issue.

Fix bad computation in logformat_write_string().

This issue is 1.5-specific and was introduced just before 1.5-dev8.
No backport is needed.
2012-03-27 19:42:43 +02:00
Willy Tarreau
9eeb57bd7f [RELEASE] Released version 1.5-dev8
Released version 1.5-dev8 with the following main changes :
    - MINOR: patch for minor typo (ressources/resources)
    - MEDIUM: http: add support for sending the server's name in the outgoing request
    - DOC: mention that default checks are TCP connections
    - BUG/MINOR: fix options forwardfor if-none when an alternative header name is specified
    - CLEANUP: Make check_statuses, analyze_statuses and process_chk static
    - CLEANUP: Fix HCHK spelling errors
    - BUG/MINOR: fix typo in processing of http-send-name-header
    - MEDIUM: log: Use linked lists for loggers
    - BUILD: fix declaration inside a scope block
    - REORG: log: split send_log function
    - MINOR: config: Parse the string of the log-format config keyword
    - MINOR: add ultoa, ulltoa, ltoa, lltoa implementations
    - MINOR: Date and time fonctions that don't use snprintf
    - MEDIUM: log: make http_sess_log use log_format
    - DOC: log-format documentation
    - MEDIUM: log: use log_format for mode tcplog
    - MEDIUM: log-format: backend source address %Bi %Bp
    - BUG/MINOR: log-format: fix %o flag
    - BUG/MEDIUM: bad length in log_format and __send_log
    - MINOR: logformat %st is signed
    - BUILD/MINOR: fix the source URL in the spec file
    - DOC: acl is http_first_req, not http_req_first
    - BUG/MEDIUM: don't trim last spaces from headers consisting only of spaces
    - MINOR: acl: add new matches for header/path/url length
    - BUILD: halog: make halog build on solaris
    - BUG/MINOR: don't use a wrong port when connecting to a server with mapped ports
    - MINOR: remove the client/server side distinction in SI addresses
    - MINOR: halog: add support for matching queued requests
    - DOC: indicate that cookie "prefix" and "indirect" should not be mixed
    - OPTIM/MINOR: move struct sockaddr_storage to the tail of structs
    - OPTIM/MINOR: make it possible to change pipe size (tune.pipesize)
    - BUILD/MINOR: silent a build warning in src/pipe.c (fcntl)
    - OPTIM/MINOR: move the hdr_idx pools out of the proxy struct
    - MEDIUM: tune.http.maxhdr makes it possible to configure the maximum number of HTTP headers
    - BUG/MINOR: fix a segfault when parsing a config with undeclared peers
    - CLEANUP: rename possibly confusing struct field "tracked"
    - BUG/MEDIUM: checks: fix slowstart behaviour when server tracking is in use
    - MINOR: config: tolerate server "cookie" setting in non-HTTP mode
    - MEDIUM: buffers: add some new primitives and rework existing ones
    - BUG: buffers: don't return a negative value on buffer_total_space_res()
    - MINOR: buffers: make buffer_pointer() support negative pointers too
    - CLEANUP: kill buffer_replace() and use an inline instead
    - BUG: tcp: option nolinger does not work on backends
    - CLEANUP: ebtree: remove a few annoying signedness warnings
    - CLEANUP: ebtree: clarify licence and update to 6.0.6
    - CLEANUP: ebtree: remove 4-year old harmless typo in duplicates insertion code
    - CLEANUP: ebtree: remove another typo, a wrong initialization in insertion code
    - BUG: ebtree: ebst_lookup() could return the wrong entry
    - OPTIM: stream_sock: reduce the amount of in-flight spliced data
    - OPTIM: stream_sock: save a failed recv syscall when splice returns EAGAIN
    - MINOR: acl: add support for TLS server name matching using SNI
    - BUG: http: re-enable TCP quick-ack upon incomplete HTTP requests
    - BUG: proto_tcp: don't try to bind to a foreign address if sin_family is unknown
    - MINOR: pattern: export the global temporary pattern
    - CLEANUP: patterns: get rid of pattern_data_setstring()
    - MEDIUM: acl: use temp_pattern to store fetched information in the "method" match
    - MINOR: acl: include pattern.h to make pattern migration more transparent
    - MEDIUM: pattern: change the pattern data integer from unsigned to signed
    - MEDIUM: acl: use temp_pattern to store any integer-type information
    - MEDIUM: acl: use temp_pattern to store any address-type information
    - CLEANUP: acl: integer part of acl_test is not used anymore
    - MEDIUM: acl: use temp_pattern to store any string-type information
    - CLEANUP: acl: remove last data fields from the acl_test struct
    - MEDIUM: http: replace get_ip_from_hdr2() with http_get_hdr()
    - MEDIUM: patterns: the hdr() pattern is now of type string
    - DOC: add minimal documentation on how ACLs work internally
    - DOC: add a coding-style file
    - OPTIM: halog: keep a fast path for the lines-count only
    - CLEANUP: silence a warning when building on sparc
    - BUG: http: tighten the list of allowed characters in a URI
    - MEDIUM: http: block non-ASCII characters in URIs by default
    - DOC: add some documentation from RFC3986 about URI format
    - BUG/MINOR: cli: correctly remove the whole table on "clear table"
    - BUG/MEDIUM: correctly disable servers tracking another disabled servers.
    - BUG/MEDIUM: zero-weight servers must not dequeue requests from the backend
    - MINOR: halog: add some help on the command line
    - BUILD: fix build error on FreeBSD
    - BUG: fix double free in peers config error path
    - MEDIUM: improve config check return codes
    - BUILD: make it possible to look for pcre in the default system paths
    - MINOR: config: emit a warning when 'default_backend' masks servers
    - MINOR: backend: rework the LC definition to support other connection-based algos
    - MEDIUM: backend: add the 'first' balancing algorithm
    - BUG: fix httplog trailing LF
    - MEDIUM: increase chunk-size limit to 2GB-1
    - BUG: queue: fix dequeueing sequence on HTTP keep-alive sessions
    - BUG: http: disable TCP delayed ACKs when forwarding content-length data
    - BUG: checks: fix server maintenance exit sequence
    - BUG/MINOR: stream_sock: don't remove BF_EXPECT_MORE and BF_SEND_DONTWAIT on partial writes
    - DOC: enumerate valid status codes for "observe layer7"
    - MINOR: buffer: switch a number of buffer args to const
    - CLEANUP: silence signedness warning in acl.c
    - BUG: stream_sock: si->release was not called upon shutw()
    - MINOR: log: use "%ts" to log term status only and "%tsc" to log with cookie
    - BUG/CRITICAL: log: fix risk of crash in development snapshot
    - BUG/MAJOR: possible crash when using capture headers on TCP frontends
    - MINOR: config: disable header captures in TCP mode and complain
2012-03-26 06:16:43 +02: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
9a54e13788 MINOR: config: disable header captures in TCP mode and complain
In order to help users fix their configs, report a warning when a capture
has been set on a non-HTTP frontend.

This should be backported to 1.4.
2012-03-24 08:35:37 +01:00
Willy Tarreau
42f7d89156 BUG/MAJOR: possible crash when using capture headers on TCP frontends
Olufemi Omojola provided a config and a core showing a possible crash
when captures are configured on a TCP-mode frontend which branches to
an HTTP backend. The reason is that being in TCP mode, the frontend
does not allocate capture pools for the request, but the HTTP backend
tries to use them and dies on the NULL.

While such a config has long been unlikely to happen, it looks like
people using websocket tend to do this more often now.

Change the control to use the pointer instead of the number of captures
to know when to log.

This bug was reported in 1.4.20, so it must be backported there.
2012-03-24 08:35:36 +01:00
William Lallemand
7f25debbd2 MINOR: logformat %st is signed
replace ultoa by ltoa for HTTP status code (can be -1)
2012-03-22 17:23:23 +01:00
Adrian Bridgett
afdb6e57f7 MINOR: patch for minor typo (ressources/resources)
The main stats page says "ressources" (French spelling) rather than
"resources" (English spelling).

One little patch attached (against v1.4.20).

Many thanks,

Adrian
2012-03-21 07:54:41 +01:00
William Lallemand
bfb099c3b3 BUG/MEDIUM: bad length in log_format and __send_log
__send_log(): the size of the buffer sent is wrong when the facility
is lower than 3 digits.

logformat_write_string(): computation of size is wrong

Note: this was introduced after 1.5-dev7, no backport needed.
2012-03-19 17:15:13 +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
ad4cd58986 BUG: stream_sock: si->release was not called upon shutw()
The ->release function of the stream interface is never called upon
a shutw() because it's placed after a return statement. It is possible
that it has impacted inter-process stick-table replication by preventing
a full resync after certain sequences of connection breakage. Since this
bug has been present since the introduction of the ->release() callback,
it cannot have caused regressions, just possibly non-working situations.

This was detected at Exceliance by Emeric Brun during a code review. It
is 1.5-specific.
2012-03-10 13:42:32 +01:00
Willy Tarreau
62e7c7146e CLEANUP: silence signedness warning in acl.c
The recent SNI patch introduced a trivial warning in acl.c.
2012-03-10 09:05:30 +01:00
Willy Tarreau
f17810e4fa BUG/MINOR: stream_sock: don't remove BF_EXPECT_MORE and BF_SEND_DONTWAIT on partial writes
The flags are one-shot but should be maintained over all send() operations
as long as send_max is not flushed. The flags were incidentely cleared once
a complete send() was performed, regardless of the fact that the send()
might have been on the first half of a buffer before a wrapping. The result
is that on wrapping data (eg: which happens often with chunked encoding),
many incomplete segments are transmitted instead of being aggregated.

The fix consists in only flushing the flags only once send_max is empty,
which was the expected behaviour.

This fix should be backported to 1.4 though it is not critical, just sub-optimal.
2012-03-09 18:10:44 +01:00
Willy Tarreau
4544678490 BUG: checks: fix server maintenance exit sequence
Recent commit 62c3be broke maintenance mode by fixing srv_is_usable().
Enabling a disabled server would not re-introduce it into the farm.
The reason is that in set_server_up(), the SRV_MAINTAIN flag is still
present when recounting the servers. The flag was removed late only to
adjust a log message. Keep a copy of the old flag instead and update
SRV_MAINTAIN earlier.

This fix must also be backported to 1.4 (but no release got the regression).
2012-03-09 17:19:43 +01:00
Willy Tarreau
869fc1edc2 BUG: http: disable TCP delayed ACKs when forwarding content-length data
Commits 5c6209 and 072930 were aimed at avoiding undesirable PUSH flags
when forwarding chunked data, but had the undesired effect of causing
data advertised by content-length to be affected by the delayed ACK too.
This can happen when the data to be forwarded are small enough to fit into
a single send() call, otherwise the BF_EXPECT_MORE flag would be removed.

Content-length data don't need the BF_EXPECT_MORE flag since the low-level
forwarder already knows it can safely rely on bf->to_forward to set the
appropriate TCP flags.

Note that the issue is only observed in requests at the moment, though the
later introduction of server-side keep-alive could trigger the issue on the
response path too.

Special thanks to Randy Shults for reporting this issue with a lot of
details helping to reproduce it.

The fix must be backported to 1.4.
2012-03-05 08:46:34 +01:00
Willy Tarreau
2d5cd479bc BUG: queue: fix dequeueing sequence on HTTP keep-alive sessions
When a request completes on a server and the server connection is closed
while the client connection stays open, the HTTP engine releases all server
connection slots and scans the queues to offer the connection slot to
another pending request.

An issue happens when the released connection allows other requests to be
dequeued : may_dequeue_tasks() relies on srv->served which is only decremented
by sess_change_server() which itself is only called after may_dequeue_tasks().
This results in no connection being woken up until another connection terminates
so that may_dequeue_tasks() is called again.

This fix is minimalist and only moves sess_change_server() earlier (which is
safe). It should be reworked and the code factored out so that the same occurrence
in session.c shares the same code.

This bug has been there since the introduction of option-http-server-close and
the fix must be backported to 1.4.
2012-03-01 23:49:20 +01:00
Willy Tarreau
431946e961 MEDIUM: increase chunk-size limit to 2GB-1
Since commit 115acb97, chunk size was limited to 256MB. There is no reason for
such a limit and the comment on the code suggests a missing zero. However,
increasing the limit past 2 GB causes trouble due to some 32-bit subtracts
in various computations becoming negative (eg: buffer_max_len). So let's limit
the chunk size to 2 GB - 1 max.
2012-02-27 09:51:52 +01:00
Willy Tarreau
53bf6af3f9 BUG: fix httplog trailing LF
commit a1cc3811 introduced an undesirable \0\n ending on HTTP log messages. This
is because of an extra character count passed to __send_log() which causes the LF
to be appended past the \0. Some syslog daemons thus log an extra empty line. The
fix is obvious. Fix the function comments to remind what they expect on their input.

This is past 1.5-dev7 regression so there's no backport needed.
2012-02-24 11:48:42 +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
Willy Tarreau
ff67813f58 MINOR: config: emit a warning when 'default_backend' masks servers
When a "listen" instance uses a "default_backned" rule and has servers,
the servers will never be used. Report it so that users don't get trapped.
2012-02-13 14:32:34 +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
William Lallemand
d9e9066e71 BUILD: fix declaration inside a scope block 2012-02-06 09:46:16 +01:00
Willy Tarreau
8b15ba19c3 MEDIUM: improve config check return codes
When checking a configuration file using "-c -f xxx", sometimes it is
reported that a config is valid while it will later fail (eg: no enabled
listener). Instead, let's improve the return values :
  - return 0 if config is 100% OK
  - return 1 if config has errors
  - return 2 if config is OK but no listener nor peer is enabled
2012-02-02 17:53:37 +01:00
Willy Tarreau
6f9b003c2b BUG: fix double free in peers config error path
If the local host is not found as a peer in a "peers" section, we have a
double free, and possibly a use-after-free because the peers section is
freed since it's aliased as the table's name.
2012-02-02 17:53:37 +01:00
Willy Tarreau
b05405a3a8 BUILD: fix build error on FreeBSD
Marcello Gorlani reported that commit 5e205524ad
(BUG: http: re-enable TCP quick-ack upon incomplete HTTP requests) broke build
on FreeBSD.

Moving the include lower fixes the issue. This must be backported to 1.4 too.
2012-01-23 15:35:52 +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
Stathis Voukelatos
09a030a9a4 BUG/MINOR: fix typo in processing of http-send-name-header
I downloaded version 1.4.19 this morning. While merging the code changes
to a custom build that we have here for our project I noticed a typo in
'session.c', in the new code for inserting the server name in the HTTP
header. The fix that I did is shown in the patch below.

[WT: the bug is harmless, it is only suboptimal]
2012-01-09 14:27:13 +01:00
Willy Tarreau
8fa52f4e0e BUG/MINOR: cli: correctly remove the whole table on "clear table"
Joe Price reported that "clear table xxx" sent on the CLI would only clear
the last entry. This is true, some code was missing to remove an entry from
within the loop, and only the final condition was able to remove an entry.
The fix is obvious. No backport is needed.
2012-01-09 11:53:09 +01:00
Willy Tarreau
422246eb26 MEDIUM: http: block non-ASCII characters in URIs by default
These ones are invalid and blocked unless "option accept-invalid-http-request"
is specified in the frontend. In any case, the faulty request is logged.

Note that some of the remaining invalid chars are still not checked against,
those are the invalid ones between 32 and 127 :

    34 ('"'), 60 ('<'), 62 ('>'), 92 ('\'), 94 ('^'),
    96 ('`'), 123 ('{'), 124 ('|'), 125 ('}')

Using a lookup table might be better at some point.
2012-01-07 23:55:20 +01:00
Willy Tarreau
2e9506d771 BUG: http: tighten the list of allowed characters in a URI
The HTTP request parser was considering that any non-LWS char was
par of the URI. Unfortunately, this allows control chars to be sent
in the URI, sometimes resulting in backend servers misbehaving, for
instance when they interprete \0 as an end of string and respond
with plain HTTP/0.9 without headers, that haproxy blocks as invalid
responses.

RFC3986 clearly states the list of allowed characters in a URI. Even
non-ASCII chars are not allowed. Unfortunately, after having run 10
years with these chars allowed, we can't block them right now without
an optional workaround. So the first step consists in only blocking
control chars. A later patch will allow non-ASCII only when an appropriate
option is enabled in the frontend.

Control chars are 0..31 and 127, with the exception of 9, 10 and 13
(\t, \n, \r).
2012-01-07 23:22:31 +01:00
Willy Tarreau
7b77c9fd6d CLEANUP: silence a warning when building on sparc
On Solaris/sparc, getpid() returns pid_t which is not an int :

  src/peers.c: In function `peer_io_handler':
  src/peers.c:508: warning: int format, pid_t arg (arg 6)
2012-01-07 22:52:12 +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
e428fb7b4e MEDIUM: patterns: the hdr() pattern is now of type string
This pattern previously was limited to type IP. With the new header
extraction function, it becomes possible to extract strings, so that
the header can be returned as a string. This will not change anything
to existing configs, as string will automatically be converted to IP
when needed. However, new configs will be able to use IPv6 addresses
from headers in stick-tables, as well as stick on any non-IP header
(eg: host, user-agent, ...).
2011-12-30 17:33:27 +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
664092ccc1 MEDIUM: acl: use temp_pattern to store any string-type information
Now strings and data blocks are stored in the temp_pattern's chunk
and matched against this one.

The rdp_cookie currently makes extensive use of acl_fetch_rdp_cookie()
and will be a good candidate for the initial rework so that ACLs use
the patterns framework and not the other way around.
2011-12-30 17:33:26 +01:00
Willy Tarreau
f4362b3e3b MEDIUM: acl: use temp_pattern to store any address-type information
IPv4 and IPv6 addresses are now stored into temp_pattern instead of
the dirty hack consisting into storing them into the consumer's target
address.

Some refactoring should now be possible since the methods used to fetch
source and destination addresses are similar between patterns and ACLs.
2011-12-30 17:33:26 +01:00
Willy Tarreau
a5e375646c MEDIUM: acl: use temp_pattern to store any integer-type information
All ACL fetches which return integer value now store the result into
the temporary pattern struct. All ACL matches which rely on integer
also get their value there.

Note: the pattern data types are not set right now.
2011-12-30 17:33:26 +01:00
Willy Tarreau
8e5e955c50 MEDIUM: acl: use temp_pattern to store fetched information in the "method" match
This match was using both the int and ptr part of the acl_test struct. Let's
change this to be able to store it into a chunk with a special encoding.
2011-12-30 17:33:25 +01:00
Willy Tarreau
1ded605ad5 CLEANUP: patterns: get rid of pattern_data_setstring()
This function was only used to call chunk_init_len() from another chunk,
which in the end consists in simply assigning the source chunk to the
destination chunk. Let's remove this indirection to make the code clearer.
Anyway it was the only place such a function was used.
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
5dc1e98905 BUG: proto_tcp: don't try to bind to a foreign address if sin_family is unknown
This is 1.5-specific. It causes issues with transparent source binding involving
hdr_ip. We must not try to bind() to a foreign address when the family is not set,
and we must set the family when an address is set.
2011-12-30 17:33:24 +01:00
Willy Tarreau
5e205524ad BUG: http: re-enable TCP quick-ack upon incomplete HTTP requests
By default we disable TCP quick-acking on HTTP requests so that we
avoid sending a pure ACK immediately followed by the HTTP response.
However, if the client sends an incomplete request in a short packet,
its TCP stack might wait for this packet to be ACKed before sending
the rest of the request, delaying incoming requests by up to 40-200ms.

We can detect this undesirable situation when parsing the request :
  - if an incomplete request is received
  - if a full request is received and uses chunked encoding or advertises
    a content-length larger than the data available in the buffer

In these situations, we re-enable TCP quick-ack if we had previously
disabled it.
2011-12-17 16:45:29 +01:00
Willy Tarreau
b6672b547a MINOR: acl: add support for TLS server name matching using SNI
Server Name Indication (SNI) is a TLS extension which makes a client
present the name of the server it is connecting to in the client hello.
It allows a transparent proxy to take a decision based on the beginning
of an SSL/TLS stream without deciphering it.

The new ACL "req_ssl_sni" matches the name extracted from the TLS
handshake against a list of names which may be loaded from a file if
needed.
2011-12-12 17:26:23 +01:00
Willy Tarreau
82a04566ec OPTIM: stream_sock: save a failed recv syscall when splice returns EAGAIN
When splice() returns EAGAIN, on old kernels it could be caused by a read
shutdown which was not detected. Due to this behaviour, we had to fall
back to recv(), which in turn says if it's a real EAGAIN or a shutdown.
Since this behaviour was fixed in 2.6.27.14, on more recent kernels we'd
prefer to avoid the fallback to recv() when possible. For this, we set a
variable the first time splice() detects a shutdown, to indicate that it
works. We can then rely on this variable to adjust our behaviour.

Doing this alone increased the overall performance by about 1% on medium
sized objects.
2011-12-12 00:03:55 +01:00
Willy Tarreau
eb9fd5178e OPTIM: stream_sock: reduce the amount of in-flight spliced data
First, it's a waste not to call chk_snd() when spliced data are available,
because the pipe can almost always be transferred into the outgoing socket
buffers. Starting from now, when we splice data in, we immediately try to
send them. This results in less pipes used, and possibly less kernel memory
in use at once.

Second, if a pipe cannot be transferred into the outgoing socket buffers,
it means this buffer is full. There's no point trying again then, as space
will almost never be available, resulting in a useless syscall returning
EAGAIN.
2011-12-12 00:03:55 +01:00
Willy Tarreau
f6f8225390 BUG: tcp: option nolinger does not work on backends
Daniel Rankov reported that "option nolinger" is inefficient on backends.
The reason is that it is set on the file descriptor only, which does not
prevent haproxy from performing a clean shutdown() before closing. We must
set the flag on the stream_interface instead if we want an RST to be emitted
upon active close.
2011-11-30 18:06:23 +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
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
0cec331a0e MINOR: config: tolerate server "cookie" setting in non-HTTP mode
Up to now, if a cookie value was specified on a server when the proxy was
in TCP mode, it would cause a fatal error. Now we only report a warning,
since the cookie will be ignored. This makes it easier to generate configs
from scripts.
2011-10-31 14:09:13 +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
d66bf96d5b BUG/MINOR: fix a segfault when parsing a config with undeclared peers
Baptiste Assmann reported that a config where a non-existing peers
section is referenced by a stick-table causes a segfault after displaying
the error. This is caused by the freeing of the peers. Setting it to NULL
after displaying the error fixes the issue.
2011-10-28 14:16:49 +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
9ed560e964 BUILD/MINOR: silent a build warning in src/pipe.c (fcntl) 2011-10-24 17:09:22 +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
Sagi Bashari
1611e2d4a1 BUG/MINOR: fix options forwardfor if-none when an alternative header name is specified 2011-10-09 08:10:30 +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
dd164d0240 BUG/MINOR: don't use a wrong port when connecting to a server with mapped ports
Nick Chalk reported that a connection to a server which has no port specified
used twice the port number. The reason is that the port number was taken from
the wrong part of the address, the client's destination address was used as the
base port instead of the server's configured address.

Thanks to Nick for his helpful diagnostic.
2011-09-23 10:27:12 +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
275600b6c7 BUG/MEDIUM: don't trim last spaces from headers consisting only of spaces
Commit 588bd4 fixed header parsing so that trailing spaces were not part
of the returned string. Unfortunately, if a header only had spaces, the
last spaces were trimmed past the beginning of the value, causing a negative
length to be returned.

A quick code review shows that there should be no impact since the only
places where the vlen is used are either compared to a specific value or
with explicit contents (eg: digits).

This must be backported to 1.4.
2011-09-16 08:11:26 +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
69c0117ac2 [BUILD] stats: stdint is not present on solaris
It was added with commit cec9a227 to use uint32_t, though it does
not exist on solaris 8 but is not needed either.
2011-09-10 20:38:15 +02:00
Willy Tarreau
98c6121ee5 [OPTIM] task: don't scan the run queue if we know it's empty
It happens quite often in fact, so let's save those precious cycles.
2011-09-10 20:08:49 +02:00
Willy Tarreau
576132e533 [MINOR] startup: add an option to change to a new directory
Passing -C <dir> causes haproxy to chdir to <dir> before loading
any file. The argument may be passed anywhere on the command line.
A typical use case is :

  $ haproxy -C /etc/haproxy -f global.cfg -f haproxy.cfg
2011-09-10 19:26:56 +02:00
Willy Tarreau
3bafcdc07e [CLEANUP] startup: report only the basename in the usage message
Don't write the full path to the program, just the program name.
2011-09-10 19:20:23 +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
Finn Arne Gangstad
e8c7ecc2dd [MINOR] http: *_dom matching header functions now also split on ":"
*_dom is mostly used for matching Host headers, and host headers may
include port numbers. To avoid having to create multiple rules with
and without :<port-number> in hdr_dom rules, change the *_dom
matching functions to also handle : as a delimiter.

Typically there are rules like this in haproxy.cfg:

  acl is_foo  hdr_dom(host) www.foo.com

Most clients send "Host: www.foo.com" in their HTTP header, but some
send "Host: www.foo.com:80" (which is allowed), and the above
rule will now work for those clients as well.

[Note: patch was edited before merge, any unexpected bug is mine /willy]
2011-09-09 16:10:12 +02:00
Willy Tarreau
b0f7532a30 [MINOR] frontend: ensure debug message length is always initialized
If the socket family ever changes from AF_INET*/AF_UNIX, we'd have a problem.
2011-09-09 11:21:06 +02:00
Willy Tarreau
52b2d228ed [MEDIUM] stats: offer the possibility to kill sessions by server
It's now possible to issue "shutdown sessions server <back/srv>" and have
all this server's sessions immediately killed.
2011-09-07 23:56:16 +02:00
Willy Tarreau
d52c41ea2d [CLEANUP] stats: centralize tests for backend/server inputs on the CLI
The tests were repeated many times. Let's put them at one single place.
2011-09-07 23:56:16 +02:00
Willy Tarreau
a295edc51c [MEDIUM] stats: offer the possibility to kill a session from the CLI
It's now possible to issue "shutdown session 0xXXXXXXXX" and have this
session immediately killed. Useful for long-running fantoms.
2011-09-07 23:56:16 +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
c03ebbfca4 [BUG] peers: ensure the peers are resumed if they were paused
Upon an incoming soft restart request, we first pause all frontends and
peers. If the caller changes its mind and asks us to resume (eg: failed
binding), we must resume all the frontends and peers. Unfortunately the
peers were not resumed.

The code was arranged to avoid code duplication (which used to hide the
issue till now).
2011-09-07 22:47:43 +02:00
Willy Tarreau
122541c06a [BUG] peers: don't keep a peers section which has a NULL frontend
If a peers section has no peer named as the local peer, we must destroy
it, otherwise a NULL peer frontend remains in the lists and a segfault
can happen upon a soft restart.

We also now report the missing peer name in order to help troubleshooting.
2011-09-07 22:47:43 +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
b249e8454c [BUG] peers: the peer frontend must not emit any log
Peers' frontends must have logging disabled by default, which was not
the case, so logs were randomly emitted upon restart, sometimes causing
a new process to fail to replace the old one.
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
3ae65a16b9 [BUG] peers: don't pre-allocate 65000 connections to each peer
This made sense a long time ago but since the maxconn is dynamically
computed from the tracking tables, it does not make any sense anymore
and will harm future changes.
2011-09-07 22:47:42 +02:00
Willy Tarreau
f5b22875cd [MEDIUM] stats: add the ability to adjust the global maxconnrate
Using "set rate-limit connections global <xxx>" on the CLI, we can now
adjust the per-process connection rate limiting (equal to global.maxconnrate).
2011-09-07 22:47:42 +02:00
Willy Tarreau
9cd552d8f4 [MINOR] stats: report the current and max global connection rates
The HTML page reports the current process connection rate, and the
"show info" command on the stats socket also reports the conn rate
limit and the max conn rate that was once reached.

Note that the max value can be cleared using "clear counters".
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
abacc2cfd1 [CLEANUP] remove a useless test in manage_global_listener_queue()
The test for the empty list was done twice.
2011-09-07 18:09:27 +02:00
Willy Tarreau
c2adf8b906 [MEDIUM] stats: disable complex socket reservation for stats socket
The way the unix socket is initialized is awkward. Some of the settings are put
in the sockets itself, other ones in the backend. And more importantly the
global.maxsock value is adjusted so that the stats socket evades the global
maxconn value. This complexifies maxsock computations for nothing, since the
stats socket is not supposed to receive hundreds of concurrent connections when
the global maxconn is very low. What is needed however is to ensure that there
are always connections left for the stats socket even when traffic sockets are
saturated, but this guarantee is not offered anymore by current code.

So as of now, the stats socket is subject to the global maxconn limitation just
as any other socket until a reservation mechanism is implemented.
2011-09-07 18:05:48 +02:00
Willy Tarreau
46fa8355c0 [CLEANUP] remove dirty left-over of a debugging message
This debug message was added in commit e9b2602a and not noticed once
committed.
2011-09-07 11:55:40 +02:00
Willy Tarreau
b48f958e05 [CLEANUP] cfgparse: fix reported options for the "bind" keyword 2011-09-05 01:17:06 +02:00
Willy Tarreau
ad14f753ea [MINOR] http: take a capture of bad content-lengths.
Sometimes a bad content-length header is encountered and this causes
an abort. It's hard to debug without a trace, so let's take a capture
of the contents when this happens.
2011-09-05 00:54:57 +02:00
Willy Tarreau
3b8c08a174 [MINOR] http: take a capture of truncated responses
If a server starts to respond but stops before the body, then we
capture the truncated response. We don't do this on the request
because it would happen too often upon stupid attacks.
2011-09-05 00:54:56 +02:00
Willy Tarreau
fec4d89b24 [MINOR] http: take a capture of too large requests and responses
It's hard to prove a request or response is too large if there is no
capture, so let's take a snapshot of those too.
2011-09-05 00:54:56 +02:00
Willy Tarreau
509433391a [MINOR] stats: display "<NONE>" instead of the frontend name when unknown
"show sess" should display "<NONE>" instead of the frontend's name as
the backend's.
2011-09-05 00:54:56 +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
86ad42c5b7 [MINOR] make use of set_host_port() and get_host_port() to get rid of family mismatches
This also simplifies the code and makes it more auditable.
2011-09-05 00:54:35 +02:00
Willy Tarreau
542a31d6c3 [BUG] backend: risk of picking a wrong port when mapping is used with crossed families
A similar issue as the previous one causes port mapping to fail in some
combinations of client and server address families. Using the macros fixes
the issue.
2011-08-27 12:07:49 +02:00
Willy Tarreau
48da04a6af [BUG] checks: use the correct destination port for sending checks
In the number of switch/case statements added for IPv6 changes,
one was wrong and caused the check port to be ignored for outgoing
connection because the socket's family was not taken at the right
place. Use the set_host_port() macro instead to fix the issue.

The same cleanup could be performed at a number of other places
and should follow shortly.

Special thanks to Stephane Bakhos of Techboom for reporting a
detailed analysis of this bug.
2011-08-27 11:51:36 +02:00
Willy Tarreau
e17a8d02d9 [BUG] possible crash in 'show table' on stats socket
Patch d5b9fd95 was missing an initialisation of "ctx.table.target", which caused
"show table" to segfault if it was issued after a "show errors" (target pointer == -1).
2011-08-24 08:23:34 +02:00
Willy Tarreau
c9ebc446b8 [CLEANUP] update the year in the copyright banner
It was still 2010 !
2011-08-23 00:23:54 +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
Simon Horman
8effd3de5b [MINOR] Use DPRINTF in assign_server()
Use DPRINTF in assign_server() rather than open-coding its logic.
2011-08-18 23:52:36 +02:00
Simon Horman
7abd00d7eb [MINOR] Fix build error in stream_int_register_handler()
There is no parameter or variable fct in stream_int_register_handler()
so the build fails when DPRINTF is active.
2011-08-18 23:52:36 +02:00
Simon Horman
d281eedc07 [MEDIUM] Correct ipmask() logic
The netmask applied to table entries as configured using ipmask() is
stored in arg_p->data.ip not arg_i (which will be 1 if the netmask is set).
2011-08-18 23:52:35 +02:00
Simon Horman
8b7b05a92d [MEDIUM] Fix stick-table replication on soft-restart
"[MINOR] session: add a pointer to the new target into the session" (664beb8)
introduced a regression by changing the type of a peer's target from
TARG_TYPE_PROXY to TARG_TYPE_NONE. The effect of this is that during
a soft-restart the new process no longer tries to connect to the
old process to replicate its stick tables.

This patch sets the type of a peer's target as TARG_TYPE_PROXY and
replication on soft-restart works once again.
2011-08-18 23:52:35 +02:00
Willy Tarreau
f73cd1198f [MINOR] session-counters: add the ability to clear the counters
Sometimes it can be useful to reset a counter : one condition increments
it and another one resets it. It can be used to better detect abuses.
2011-08-13 01:45:16 +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
2a0f4d27a4 [MEDIUM] stats: add support for changing frontend's maxconn at runtime
The new "set maxconn frontend XXX" statement on the stats socket allows
the admin to change a frontend's maxconn value. If some connections are
queued, they will immediately be accepted up to the new limit. If the
limit is lowered, new connections acceptation might be delayed. This can
be used to temporarily reduce or increase the impact of a specific frontend's
traffic on the whole process.
2011-08-02 11:49:05 +02:00
Willy Tarreau
bc216c4ad0 [MINOR] proxy: make findproxy() return proxies from numeric IDs too
Sometimes it's useful to be able to search a proxy by its numeric ID,
so let's add support for names such as #<id>.
2011-08-02 11:25:54 +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
d634e7c673 [CLEANUP] proxy: merge maintain_proxies() operation inside a single loop
This will help transforming the processing into per-proxy tasks.
2011-07-25 11:54:17 +02:00