]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
12 years agoMEDIUM: compression: use pool for comp_ctx
William Lallemand [Fri, 16 Nov 2012 17:06:41 +0000 (18:06 +0100)] 
MEDIUM: compression: use pool for comp_ctx

Use pool for comp_ctx, it is allocated during the comp_algo->init().
The allocation of comp_ctx is accounted for in the zlib_memory_available.

12 years agoMINOR: cli: report the fd state in "show sess xxx"
Willy Tarreau [Mon, 19 Nov 2012 17:15:19 +0000 (18:15 +0100)] 
MINOR: cli: report the fd state in "show sess xxx"

This is useful to check the FD polling state during debugging sessions.

12 years agoBUILD: cli: fix build when SSL is enabled
Willy Tarreau [Mon, 19 Nov 2012 16:13:16 +0000 (17:13 +0100)] 
BUILD: cli: fix build when SSL is enabled

Commit bc174aa forgot to include proto/ssl_sock.h.

12 years agoBUG/MAJOR: stream_interface: certain workloads could cause get stuck
Willy Tarreau [Mon, 19 Nov 2012 15:43:14 +0000 (16:43 +0100)] 
BUG/MAJOR: stream_interface: certain workloads could cause get stuck

Some very specifically scheduled workloads could sometimes get stuck when
data receive was disabled due to buffer full then re-enabled due to a full
send(). A conn_data_want_recv() had to be set again in this specific case.

This bug was introduced with connection rework and polling changes in dev12.

12 years agoMINOR: cli: report connection status in "show sess xxx"
Willy Tarreau [Mon, 19 Nov 2012 15:10:32 +0000 (16:10 +0100)] 
MINOR: cli: report connection status in "show sess xxx"

Connection flags, targets and transport layers are now reported in
"show sess $PTR", as it is an absolute requirement in debugging.

12 years agoMEDIUM: compression: don't compress when no data
William Lallemand [Mon, 19 Nov 2012 11:35:37 +0000 (12:35 +0100)] 
MEDIUM: compression: don't compress when no data

This patch makes changes in the http_response_forward_body state
machine. It checks if the compress algorithm had consumed data before
swapping the temporary and the input buffer. So it prevents null sized
zlib chunks.

12 years agoBUG: compression: properly disable compression when content-type does not match
Willy Tarreau [Mon, 19 Nov 2012 13:55:02 +0000 (14:55 +0100)] 
BUG: compression: properly disable compression when content-type does not match

Disabling compression based on the content-type was improperly done since the
introduction of the COMP_READY flag, sometimes resulting in truncated responses.

12 years agoMEDIUM: adjust the maxaccept per listener depending on the number of processes
Willy Tarreau [Mon, 19 Nov 2012 11:39:59 +0000 (12:39 +0100)] 
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.

12 years agoMINOR: standard: add a simple popcount function
Willy Tarreau [Mon, 19 Nov 2012 11:11:07 +0000 (12:11 +0100)] 
MINOR: standard: add a simple popcount function

This function returns the number of ones in a word.

12 years agoDOC: update the PROXY protocol spec to support v2
Willy Tarreau [Mon, 19 Nov 2012 10:27:29 +0000 (11:27 +0100)] 
DOC: update the PROXY protocol spec to support v2

The doc updates covers the following points :
  - description of protocol version 2
  - discourage emission of UNKNOWN and encourage it acceptance
  - clarify that each header must fit in an MSS and be sent at once
  - provide an example of receiver code that explains how to use MSG_PEEK.

12 years agoMINOR: ssl: Add tune.ssl.lifetime statement in global.
Emeric Brun [Fri, 16 Nov 2012 14:11:00 +0000 (15:11 +0100)] 
MINOR: ssl: Add tune.ssl.lifetime statement in global.

Sets the ssl session <lifetime> in seconds. Openssl default is 300 seconds.

12 years agoMINOR: ssl: rename and document the tune.ssl.cachesize option
Willy Tarreau [Fri, 16 Nov 2012 15:32:15 +0000 (16:32 +0100)] 
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.

12 years agoMEDIUM: global: add support for CPU binding on Linux ("cpu-map")
Willy Tarreau [Fri, 16 Nov 2012 15:12:27 +0000 (16:12 +0100)] 
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.

12 years agoMINOR: conf: add warning if ssl is not enabled and a certificate is present on bind.
Emeric Brun [Thu, 15 Nov 2012 17:28:02 +0000 (18:28 +0100)] 
MINOR: conf: add warning if ssl is not enabled and a certificate is present on bind.

12 years agoMINOR: config: support process ranges for "bind-process"
Willy Tarreau [Thu, 15 Nov 2012 16:50:01 +0000 (17:50 +0100)] 
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.

12 years agoMINOR: global: don't prevent nbproc from being redefined
Willy Tarreau [Thu, 15 Nov 2012 16:38:15 +0000 (17:38 +0100)] 
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.

12 years agoBUG/MEDIUM: compression: release the zlib pools between keep-alive requests
Willy Tarreau [Thu, 15 Nov 2012 15:41:22 +0000 (16:41 +0100)] 
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().

12 years agoBUG/MINOR: compression: deinit zlib only when required
William Lallemand [Mon, 12 Nov 2012 16:02:18 +0000 (17:02 +0100)] 
BUG/MINOR: compression: deinit zlib only when required

The zlib stream was deinitialized even when the init failed.

12 years agoBUG/MEDIUM: compression: no Content-Type header but type in configuration
William Lallemand [Mon, 12 Nov 2012 12:56:25 +0000 (13:56 +0100)] 
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.

12 years agoBUG: compression: do not always increment the round counter on allocation failure
Willy Tarreau [Thu, 15 Nov 2012 13:57:56 +0000 (14:57 +0100)] 
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.

12 years agoMINOR: build: allow packagers to specify the ssl cache size
Emeric Brun [Wed, 14 Nov 2012 10:32:56 +0000 (11:32 +0100)] 
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.

12 years agoBUG: proxy: fix server name lookup in get_backend_server()
Willy Tarreau [Wed, 14 Nov 2012 23:15:18 +0000 (00:15 +0100)] 
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.

12 years agoBUG: halog: fix broken output limitation
Willy Tarreau [Tue, 13 Nov 2012 19:48:15 +0000 (20:48 +0100)] 
BUG: halog: fix broken output limitation

Commit 667c905f introduced parameter -m to halog which limits the size
of the output. Unfortunately it is completely broken in that it doesn't
check that the limit was previously set or not, and also prevents a
simple counting operation from returning anything if a limit is not set.

Note that the -gt and -pct outputs behave differently in face of this
limit, since they count the valid output lines BEFORE actually producing
the data, so the limit really applies to valid input lines.

12 years agoMINOR: build: allow packagers to specify the default maxzlibmem
Willy Tarreau [Mon, 12 Nov 2012 14:52:53 +0000 (15:52 +0100)] 
MINOR: build: allow packagers to specify the default maxzlibmem

This is done by passing the default value to DEFAULT_MAXZLIBMEM in megs.

12 years agoMINOR: splice: disable it when the system returns EBADF
Willy Tarreau [Mon, 12 Nov 2012 11:00:09 +0000 (12:00 +0100)] 
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().

12 years agoBUG/MEDIUM: ssl: Fix sometimes reneg fails if requested by server.
Emeric Brun [Thu, 8 Nov 2012 18:21:55 +0000 (19:21 +0100)] 
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.

12 years agoBUG/MEDIUM: ssl: Fix some reneg cases not correctly handled.
Emeric Brun [Thu, 8 Nov 2012 17:02:56 +0000 (18:02 +0100)] 
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.

12 years agoBUG/MEDIUM: ssl: review polling on reneg.
Emeric Brun [Thu, 8 Nov 2012 16:56:20 +0000 (17:56 +0100)] 
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.

12 years agoBUG: polling: don't skip polled events in the spec list
Willy Tarreau [Mon, 12 Nov 2012 00:57:14 +0000 (01:57 +0100)] 
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.

12 years agoBUG: connection: fix typo in previous commit
Willy Tarreau [Mon, 12 Nov 2012 00:14:56 +0000 (01:14 +0100)] 
BUG: connection: fix typo in previous commit

A typo broke the logs (obj_type() instead of objt_server()).

12 years agoMAJOR: connection: replace struct target with a pointer to an enum
Willy Tarreau [Sun, 11 Nov 2012 23:42:33 +0000 (00:42 +0100)] 
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.

12 years agoCLEANUP: stream_interface: remove the external task type target
Willy Tarreau [Sun, 11 Nov 2012 22:14:16 +0000 (23:14 +0100)] 
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.

12 years agoCLEANUP: channel: remove any reference of the hijackers
Willy Tarreau [Sun, 11 Nov 2012 22:05:39 +0000 (23:05 +0100)] 
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.

12 years agoMEDIUM: http: refrain from sending "Connection: close" when Upgrade is present
Willy Tarreau [Sun, 11 Nov 2012 21:19:57 +0000 (22:19 +0100)] 
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.

12 years agoMAJOR: polling: remove unused callbacks from the poller struct
Willy Tarreau [Sun, 11 Nov 2012 20:02:34 +0000 (21:02 +0100)] 
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.

12 years agoMAJOR: polling: replace epoll with sepoll and remove sepoll
Willy Tarreau [Sun, 11 Nov 2012 16:42:00 +0000 (17:42 +0100)] 
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.

12 years agoMAJOR: ev_kqueue: make the poller support speculative events
Willy Tarreau [Sun, 11 Nov 2012 19:49:49 +0000 (20:49 +0100)] 
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.

12 years agoMAJOR: ev_poll: make the poller support speculative events
Willy Tarreau [Sun, 11 Nov 2012 16:25:15 +0000 (17:25 +0100)] 
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.

12 years agoMAJOR: ev_select: make the poller support speculative events
Willy Tarreau [Sun, 11 Nov 2012 15:53:50 +0000 (16:53 +0100)] 
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.

12 years agoBUILD: compression: enable build in BSD and OSX Makefiles
Willy Tarreau [Sun, 11 Nov 2012 18:29:27 +0000 (19:29 +0100)] 
BUILD: compression: enable build in BSD and OSX Makefiles

The file was missing there.

12 years agoBUILD: stream_interface: remove si_fd() and its references
Willy Tarreau [Sun, 11 Nov 2012 18:27:15 +0000 (19:27 +0100)] 
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.

12 years agoBUG: raw_sock: also consider ENOTCONN in addition to EAGAIN
Willy Tarreau [Sun, 11 Nov 2012 19:38:30 +0000 (20:38 +0100)] 
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.

12 years agoREORG: fd: centralize the processing of speculative events
Willy Tarreau [Sun, 11 Nov 2012 15:43:45 +0000 (16:43 +0100)] 
REORG: fd: centralize the processing of speculative events

Speculative events are independant on the poller, so they can be
centralized in fd.c.

12 years agoREORG: fd: move the fd state management from ev_sepoll
Willy Tarreau [Sun, 11 Nov 2012 15:05:19 +0000 (16:05 +0100)] 
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.

12 years agoREORG: fd: move the speculative I/O management from ev_sepoll
Willy Tarreau [Sun, 11 Nov 2012 14:02:54 +0000 (15:02 +0100)] 
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.

12 years agoMEDIUM: fd: don't unset fdtab[].updated upon delete
Willy Tarreau [Sun, 11 Nov 2012 16:08:32 +0000 (17:08 +0100)] 
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.

12 years agoMINOR: log-format: check number of arguments in cfgparse.c
William Lallemand [Sun, 11 Nov 2012 16:30:56 +0000 (17:30 +0100)] 
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.

12 years agoDOC: compression: add some details and clean up the formatting
Cyril Bonté [Sun, 11 Nov 2012 12:38:27 +0000 (13:38 +0100)] 
DOC: compression: add some details and clean up the formatting

commit 82fe75c1 provided useful details in its log message. We should report
part of them in the documentation to know which algorithms are available.

This patch also makes some formatting cleanups (including a line outside the
compression scope, which exceeded 80 chars).

12 years agoBUILD: report zlib support in haproxy -vv
Cyril Bonté [Sat, 10 Nov 2012 18:27:47 +0000 (19:27 +0100)] 
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.

12 years agoBUILD: compression: remove a build warning
Willy Tarreau [Sat, 10 Nov 2012 16:49:37 +0000 (17:49 +0100)] 
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.

12 years agoMINOR: compression: maximum compression rate limit
William Lallemand [Fri, 9 Nov 2012 16:05:39 +0000 (17:05 +0100)] 
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.

12 years agoMINOR: compression: tune.comp.maxlevel
William Lallemand [Fri, 9 Nov 2012 11:33:10 +0000 (12:33 +0100)] 
MINOR: compression: tune.comp.maxlevel

This option allows you to set the maximum compression level usable by
the compression algorithm. It affects CPU usage.

12 years agoBUG: http: revert broken optimisation from 82fe75c1a79dac933391501b9d293bce34513755
Finn Arne Gangstad [Fri, 9 Nov 2012 20:02:36 +0000 (21:02 +0100)] 
BUG: http: revert broken optimisation from 82fe75c1a79dac933391501b9d293bce34513755

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]

12 years agoOPTIM: stream_interface: disable reading when CF_READ_DONTWAIT is set
Willy Tarreau [Fri, 9 Nov 2012 17:27:26 +0000 (18:27 +0100)] 
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).

12 years agoMAJOR: sepoll: make the poller totally event-driven
Willy Tarreau [Tue, 6 Nov 2012 01:34:46 +0000 (02:34 +0100)] 
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.

12 years agoBUG/MAJOR: always clear the CO_FL_WAIT_* flags after updating polling flags
Willy Tarreau [Mon, 5 Nov 2012 19:00:43 +0000 (20:00 +0100)] 
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.

12 years agoMAJOR: connection: remove the CO_FL_CURR_*_POL flag
Willy Tarreau [Mon, 5 Nov 2012 16:52:26 +0000 (17:52 +0100)] 
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.

12 years agoBUG/MINOR: session: mark the handshake as complete earlier
Willy Tarreau [Mon, 5 Nov 2012 23:14:25 +0000 (00:14 +0100)] 
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().

12 years agoOPTIM: session: don't process the whole session when only timers need a refresh
Willy Tarreau [Thu, 8 Nov 2012 13:49:17 +0000 (14:49 +0100)] 
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.

12 years agoMEDIUM: compression: limit RAM usage
William Lallemand [Wed, 7 Nov 2012 15:12:57 +0000 (16:12 +0100)] 
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.

12 years agoMINOR: compression: init before deleting headers
William Lallemand [Wed, 7 Nov 2012 14:00:23 +0000 (15:00 +0100)] 
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.

12 years agoMINOR: compression: try init in cfgparse.c
William Lallemand [Wed, 7 Nov 2012 12:21:47 +0000 (13:21 +0100)] 
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.

12 years agoMEDIUM: use pool for zlib
William Lallemand [Tue, 30 Oct 2012 13:30:39 +0000 (14:30 +0100)] 
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.

12 years agoMINOR: compression: memlevel and windowsize
William Lallemand [Wed, 7 Nov 2012 15:54:34 +0000 (16:54 +0100)] 
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.

12 years agoBUILD: remove dependency to zlib.h
William Lallemand [Wed, 31 Oct 2012 10:19:18 +0000 (11:19 +0100)] 
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.

12 years agoCLEANUP: use struct comp_ctx instead of union
William Lallemand [Tue, 30 Oct 2012 14:52:53 +0000 (15:52 +0100)] 
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.

12 years agoDOC: Change is_ssl acl to ssl_fc acl in example
David BERARD [Fri, 2 Nov 2012 23:11:31 +0000 (00:11 +0100)] 
DOC: Change is_ssl acl to ssl_fc acl in example

12 years agoBUG/MINOR: session: ensure that we don't retry connection if some data were sent
Willy Tarreau [Mon, 29 Oct 2012 21:41:31 +0000 (22:41 +0100)] 
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.

12 years agoBUG/MINOR: stream_interface: don't loop over ->snd_buf()
Willy Tarreau [Mon, 29 Oct 2012 22:27:14 +0000 (23:27 +0100)] 
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.

12 years agoMINOR: compression: Enable compression for IE6 w/SP2, IE7 and IE8
Finn Arne Gangstad [Mon, 29 Oct 2012 20:43:01 +0000 (21:43 +0100)] 
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.

12 years agoMEDIUM: stick-table: allocate the table key of size buffer size
Willy Tarreau [Mon, 29 Oct 2012 20:56:59 +0000 (21:56 +0100)] 
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.

12 years agoMEDIUM: remove remains of BUFSIZE in HTTP auth and sample conversions
Willy Tarreau [Mon, 29 Oct 2012 19:44:36 +0000 (20:44 +0100)] 
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".

12 years agoMEDIUM: make the trash be a chunk instead of a char *
Willy Tarreau [Mon, 29 Oct 2012 15:51:55 +0000 (16:51 +0100)] 
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.

12 years agoCLEANUP: replace chunk_printf() with chunk_appendf()
Willy Tarreau [Mon, 29 Oct 2012 15:14:26 +0000 (16:14 +0100)] 
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.

12 years agoMINOR: chunk: add a function to reset a chunk
Willy Tarreau [Mon, 29 Oct 2012 12:23:11 +0000 (13:23 +0100)] 
MINOR: chunk: add a function to reset a chunk

This is a first step in avoiding to constantly reinitialize chunks.
It replaces the old chunk_reset() which was not properly named as it
used to drop everything and was only used by chunk_destroy(). It has
been renamed chunk_drop().

12 years agoCLEANUP: completely remove trashlen
Willy Tarreau [Mon, 29 Oct 2012 12:27:23 +0000 (13:27 +0100)] 
CLEANUP: completely remove trashlen

Commit c919dc66 did not remove the trashlen assigment.

12 years agoMINOR: log: add '%Tl' to log-format
Yuxans Yao [Fri, 19 Oct 2012 02:36:09 +0000 (10:36 +0800)] 
MINOR: log: add '%Tl' to log-format

The '%Tl' is similar to '%T', but using local timezone.

12 years agoBUG: compression: disable auto-close and enable MSG_MORE during transfer
Willy Tarreau [Fri, 26 Oct 2012 23:36:34 +0000 (01:36 +0200)] 
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.

12 years agoMINOR: compression: add an offload option to remove the Accept-Encoding header
Willy Tarreau [Fri, 26 Oct 2012 22:34:28 +0000 (00:34 +0200)] 
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).

12 years agoBUILD: make it possible to specify ZLIB path
Willy Tarreau [Fri, 10 Feb 2012 19:37:26 +0000 (20:37 +0100)] 
BUILD: make it possible to specify ZLIB path

12 years agoDOC: update document describing relations between internal entities
Willy Tarreau [Fri, 26 Oct 2012 18:40:13 +0000 (20:40 +0200)] 
DOC: update document describing relations between internal entities

Connections have left the stream interface. fdtab[] has been represented.

12 years agoMAJOR: session: detach the connections from the stream interfaces
Willy Tarreau [Fri, 26 Oct 2012 18:10:28 +0000 (20:10 +0200)] 
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.

12 years agoCLEANUP: remove trashlen
Willy Tarreau [Fri, 26 Oct 2012 15:35:22 +0000 (17:35 +0200)] 
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.

12 years agoBUG/MEDIUM: tcp: transparent bind to the source only when address is set
Willy Tarreau [Fri, 26 Oct 2012 17:57:58 +0000 (19:57 +0200)] 
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.

12 years agoMINOR: tools: add a clear_addr() function to unset an address
Willy Tarreau [Fri, 26 Oct 2012 17:47:23 +0000 (19:47 +0200)] 
MINOR: tools: add a clear_addr() function to unset an address

This will be used to unset a from address.

12 years agoBUG/MEDIUM: command-line option -D must have precedence over "debug"
Willy Tarreau [Fri, 26 Oct 2012 14:04:28 +0000 (16:04 +0200)] 
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.

12 years agoMINOR: ssl: checks the consistency of a private key with the corresponding certificate
Emeric Brun [Fri, 26 Oct 2012 11:35:33 +0000 (13:35 +0200)] 
MINOR: ssl: checks the consistency of a private key with the corresponding certificate

12 years agoMINOR: ssl: add 'crt' statement on server.
Emeric Brun [Fri, 26 Oct 2012 10:58:00 +0000 (12:58 +0200)] 
MINOR: ssl: add 'crt' statement on server.

crt: client certificate to send

12 years agoMINOR: ssl: add pattern and ACLs fetches 'ssl_c_notbefore', 'ssl_c_notafter', 'ssl_f_...
Emeric Brun [Mon, 22 Oct 2012 12:11:22 +0000 (14:11 +0200)] 
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])

12 years agoMINOR: ssl: add pattern and ACLs fetches 'ssl_c_key_alg' and 'ssl_f_key_alg'
Emeric Brun [Mon, 22 Oct 2012 10:22:55 +0000 (12:22 +0200)] 
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)

12 years agoMINOR: ssl: add pattern and ACLs 'ssl_c_sig_alg' and 'ssl_f_sig_alg'
Emeric Brun [Fri, 19 Oct 2012 16:15:40 +0000 (18:15 +0200)] 
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"

12 years agoMINOR: ssl: add pattern and ACLs fetches 'ssl_c_s_dn', 'ssl_c_i_dn', 'ssl_f_s_dn...
Emeric Brun [Wed, 17 Oct 2012 15:39:35 +0000 (17:39 +0200)] 
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).

12 years agoMINOR: ssl: add pattern and ACLs fetches 'ssl_c_version' and 'ssl_f_version'
Emeric Brun [Wed, 17 Oct 2012 13:03:11 +0000 (15:03 +0200)] 
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)

12 years agoMINOR: ssl: add pattern and ACLs fetches 'ssl_c_serial' and 'ssl_f_serial'
Willy Tarreau [Mon, 22 Oct 2012 15:58:39 +0000 (17:58 +0200)] 
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.

12 years agoMINOR: ssl: add pattern fetch 'ssl_fc_session_id'
Emeric Brun [Tue, 16 Oct 2012 12:59:28 +0000 (14:59 +0200)] 
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.

12 years agoMINOR: ssl: add pattern and ACLs fetches 'ssl_fc_protocol', 'ssl_fc_cipher', 'ssl_fc_...
Emeric Brun [Tue, 16 Oct 2012 12:13:26 +0000 (14:13 +0200)] 
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)

12 years agoMINOR: conf: rename all ssl modules fetches using prefix 'ssl_fc' and 'ssl_c'
Emeric Brun [Thu, 18 Oct 2012 13:59:43 +0000 (15:59 +0200)] 
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

12 years agoBUILD: fix coexistence of openssl and zlib
Willy Tarreau [Fri, 26 Oct 2012 13:05:35 +0000 (15:05 +0200)] 
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.

12 years agoBUG/MINOR: http: compression should consider all Accept-Encoding header values
Willy Tarreau [Fri, 26 Oct 2012 12:50:26 +0000 (14:50 +0200)] 
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.

12 years agoMINOR: compression: optimize memLevel to improve byte rate
Willy Tarreau [Fri, 26 Oct 2012 09:36:40 +0000 (11:36 +0200)] 
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.