Commit Graph

4459 Commits

Author SHA1 Message Date
Willy Tarreau
b550d009ca MEDIUM: protocol: use a family array to index the protocol handlers
Instead of walking over a list, we now have a direct mapping between
protocol families and their respective handlers. This will allow fast
lookups.
2015-02-28 23:12:31 +01:00
Thierry FOURNIER
2e05a8c742 MEDIUM: task: call session analyzers if the task is woken by a message.
When a task used to receive a message from another one, its analysers
were not called if there was no I/O activity.
2015-02-28 23:12:30 +01:00
Thierry FOURNIER
9cf7c4b9df MAJOR: poll: only rely on wake_expired_tasks() to compute the wait delay
Actually, HAProxy uses the function "process_runnable_tasks" and
"wake_expired_tasks" to get the next task which can expires.

If a task is added with "task_schedule" or other method during
the execution of an other task, the expiration of this new task
is not taken into account, and the execution of this task can be
too late.

Actualy, HAProxy seems to be no sensitive to this bug.

This fix moves the call to process_runnable_tasks() before the timeout
calculation and ensures that all wakeups are processed together. Only
wake_expired_tasks() needs to return a timeout now.
2015-02-28 23:12:30 +01:00
Willy Tarreau
e7acee70a3 BUILD/CLEANUP: config: silent 3 warnings about mixed declarations with code
These ones were present in the tcp-check parser.
2015-02-28 23:12:30 +01:00
Willy Tarreau
622317d5e2 BUILD/CLEANUP: ssl: avoid a warning due to mixed code and declaration
Actually it was caused by some dummy code meant to shut gcc up for
an unused argument!
2015-02-28 23:12:30 +01:00
Willy Tarreau
713a7566af BUILD: Makefile: add -Wdeclaration-after-statement
This one makes it easier to detect accidentally misplaced variables
declarations in the code which are always a pain to deal with when
functions grow.
2015-02-28 23:12:30 +01:00
Nenad Merdanovic
188ad3e9a2 DOC: Document the new tls-ticket-keys bind keyword
Signed-off-by: Nenad Merdanovic <nmerdan@anine.io>
2015-02-28 23:10:22 +01:00
Nenad Merdanovic
05552d4b98 MEDIUM: Add support for configurable TLS ticket keys
Until now, the TLS ticket keys couldn't have been configured and
shared between multiple instances or multiple servers running HAproxy.
The result was that if a request got a TLS ticket from one instance/server
and it hits another one afterwards, it will have to go through the full
SSL handshake and negotation.

This patch enables adding a ticket file to the bind line, which will be
used for all SSL contexts created from that bind line. We can use the
same file on all instances or servers to mitigate this issue and have
consistent TLS tickets assigned. Clients will no longer have to negotiate
every time they change the handling process.

Signed-off-by: Nenad Merdanovic <nmerdan@anine.io>
2015-02-28 23:10:22 +01:00
Simon Horman
eaabd52e29 BUG/MEDIUM: Do not consider an agent check as failed on L7 error
As failure to connect to the agent check is not sufficient to mark it as
failed it stands to reason that an L7 error shouldn't either.

Without this fix if an L7 error occurs, for example of connectivity to the
agent is lost immediately after establishing a connection to it, then the
agent check will be considered to have failed and thus may end up with zero
health. Once this has occurred if the primary health check also reaches
zero health, which is likely if connectivity to the server is lost, then
the server will be marked as down and not be marked as up again until a
successful agent check occurs regardless of the success of any primary
health checks.

This behaviour is not correct as a failed agent check should never cause a
server to be marked as down or by extension continue to be marked as down.

Signed-off-by: Simon Horman <horms@verge.net.au>
2015-02-26 07:06:50 +01:00
Adam Spiers
107ddc1b67 BUG/MINOR: don't start haproxy on reload
If haproxy is not already running, reload should not start it.
Unfortunately the LSB spec does not explicitly cover this case:

  http://refspecs.linuxbase.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/iniscrptact.html

but it seems like the more correct behaviour, and actually fixes a
real-world issue we saw in SUSE Cloud.

Signed-off-by: Adam Spiers <aspiers@suse.com>
2015-02-23 18:13:14 +01:00
Adam Spiers
ecb74a3d86 CLEANUP: extract quiet_check() to avoid duplication
Signed-off-by: Adam Spiers <aspiers@suse.com>
2015-02-23 18:13:14 +01:00
Adam Spiers
c5123f3982 CLEANUP: extract temporary $LOCKFILE to eliminate duplication
Signed-off-by: Adam Spiers <aspiers@suse.com>
2015-02-23 18:13:14 +01:00
Adam Spiers
922a37b2fb CLEANUP: extract temporary $PIDFILE to eliminate duplication
Signed-off-by: Adam Spiers <aspiers@suse.com>
2015-02-23 18:13:14 +01:00
Adam Spiers
85bb5ca39b CLEANUP: extract temporary $BIN to eliminate duplication
Signed-off-by: Adam Spiers <aspiers@suse.com>
2015-02-23 18:13:14 +01:00
Adam Spiers
5e71b6f803 CLEANUP: extract temporary $CFG to eliminate duplication
Signed-off-by: Adam Spiers <aspiers@suse.com>
2015-02-23 18:13:14 +01:00
Willy Tarreau
501260bf67 MEDIUM: task: always ensure that the run queue is consistent
As found by Thierry Fournier, if a task manages to kill another one and
if this other task is the next one in the run queue, we can do whatever
including crashing, because the scheduler restarts from the saved next
task. For now, there is no such concept of a task killing another one,
but with Lua it will come.

A solution consists in always performing the lookup of the first task in
the scheduler's loop, but it's expensive and costs around 2% of the
performance.

Another solution consists in keeping a global next run queue node and
ensuring that when this task gets removed, it updates this pointer to
the next one. This allows to simplify the code a bit and in the end to
slightly increase the performance (0.3-0.5%). The mechanism might still
be usable if we later migrate to a multi-threaded scheduler.
2015-02-23 16:07:01 +01:00
Thierry FOURNIER
70fd7480f9 BUG/MINOR: ARG6 and ARG7 don't fit in a 32 bits word
The patch "MEDIUM: args: increase arg type to 5 bits and limit arg count
to 5" (dbc79d0a) increased the number of types supported, but forgot to
remove the ARG6/ARG7 macros.
2015-02-20 14:34:16 +01:00
Willy Tarreau
eb27ec7569 MINOR: http: add the new sample fetches req.hdr_names and res.hdr_names
These new sample fetches retrieve the list of header names as they appear
in the request or response. This can be used for debugging, for statistics
as well as an aid to better detect the presence of proxies or plugins on
some browsers, which alter the request compared to a regular browser by
adding or reordering headers.
2015-02-20 14:00:44 +01:00
Willy Tarreau
c90dc23e99 MINOR: http: add a new function to iterate over each header line
New function http_find_next_header() will be used to scan all the input
headers for various processing and for http/1 to http/2 header mapping.
2015-02-20 14:00:44 +01:00
Willy Tarreau
2d7ec46b04 BUG/MAJOR: peers: initialize s->buffer_wait when creating the session
Commit bf883e0 ("MAJOR: session: implement a wait-queue for sessions who
need a buffer") introduced in 1.6 forgot to initialize the buffer_wait
list when the session is initiated by an applet for a peer, resulting in
a crash. Thanks to Chris Kopp for reporting the issue.
2015-02-14 14:16:35 +01:00
Thierry FOURNIER
73bc285be1 BUG/MEDIUM: pattern: some entries are not deleted with case insensitive match
ACL or map entries are not deleted with the command "del acl" or "del map"
if the case insentive flag is set.

This is because the the case insensitive string are stored in a list and the
default delete function associated with string looks in a tree. I add a check
of the case insensitive flag and execute the delete function for lists if it
is set.

This patch must be backported in 1.5 version.
2015-02-06 18:04:36 +01:00
Thierry FOURNIER
8aa8384e22 BUG/MINOR: pattern: error message missing
This patch must be backported in 1.5 version.
2015-02-06 18:04:27 +01:00
Willy Tarreau
2a3fb1c8bb MINOR: ssl/server: add the "no-ssl-reuse" server option
This option disables SSL session reuse when SSL is used to communicate with
the server. It will force the server to perform a full handshake for every
new connection. It's probably only useful for benchmarking, troubleshooting,
and for paranoid users.
2015-02-06 18:04:08 +01:00
Simon Horman
64e3416662 MEDIUM: Allow suppression of email alerts by log level
This patch adds a new option which allows configuration of the maximum
log level of messages for which email alerts will be sent.

The default is alert which is more restrictive than
the current code which sends email alerts for all priorities.
That behaviour may be configured using the new configuration
option to set the maximum level to notice or greater.

	email-alert level notice

Signed-off-by: Simon Horman <horms@verge.net.au>
2015-02-06 07:59:58 +01:00
Simon Horman
00b69e08d5 MINOR: Remove trailing '.' from email alert messages
This removes the trailing '.' from both the header and the body of email
alerts.

The main motivation for this change is to make the format of email alerts
generated from srv_set_stopped() consistent with those generated from
set_server_check_status().

Signed-off-by: Simon Horman <horms@verge.net.au>
2015-02-06 07:59:58 +01:00
Ilyas Bakirov
dfb124fe0d BUILD: add new target 'make uninstall' to support uninstalling haproxy from OS 2015-02-04 13:13:30 +01:00
Willy Tarreau
2af207a5f5 MEDIUM: tcp: implement tcp-ut bind option to set TCP_USER_TIMEOUT
On Linux since 2.6.37, it's possible to set the socket timeout for
pending outgoing data, with an accuracy of 1 millisecond. This is
pretty handy to deal with dead connections to clients and or servers.

For now we only implement it on the frontend side (bind line) so
that when a client disappears from the net, we're able to quickly
get rid of its connection and possibly release a server connection.
This can be useful with long-lived connections where an application
level timeout is not suited because long pauses are expected (remote
terminals, connection pools, etc).

Thanks to Thijs Houtenbos and John Eckersberg for the suggestion.
2015-02-04 00:54:40 +01:00
Simon Horman
51a1cf6bb4 DOC: Document email alerts
Signed-off-by: Simon Horman <horms@verge.net.au>
2015-02-03 07:47:48 +01:00
Simon Horman
0ba0e4ac07 MEDIUM: Support sending email alerts
Signed-off-by: Simon Horman <horms@verge.net.au>
2015-02-03 00:24:16 +01:00
Simon Horman
9dc4996344 MEDIUM: Allow configuration of email alerts
This currently does nothing beyond parsing the configuration
and storing in the proxy as there is no implementation of email alerts.

Signed-off-by: Simon Horman <horms@verge.net.au>
2015-02-03 00:24:16 +01:00
Simon Horman
0d16a4011e MEDIUM: Add parsing of mailers section
As mailer and mailers structures and allow parsing of
a mailers section into those structures.

These structures will subsequently be freed as it is
not yet possible to use reference them in the configuration.

Signed-off-by: Simon Horman <horms@verge.net.au>
2015-02-03 00:24:16 +01:00
Simon Horman
e16c1b3f3d MEDIUM: Attach tcpcheck_rules to check
This is to allow checks to be established whose tcpcheck_rules
are not those of its proxy.

Signed-off-by: Simon Horman <horms@verge.net.au>
2015-02-03 00:24:16 +01:00
Simon Horman
41f5876750 MEDIUM: Move proto and addr fields struct check
The motivation for this is to make checks more independent of each
other to allow further reuse of their infrastructure.

For nowserver->check and server->agent still always use the same values
for the addr and proto fields so this patch should not introduce any
behavioural changes.

Signed-off-by: Simon Horman <horms@verge.net.au>
2015-02-03 00:24:16 +01:00
Simon Horman
bfb5d33fe6 MEDIUM: Add free_check() helper
Add free_check() helper to free the memory allocated by init_check().

Signed-off-by: Simon Horman <horms@verge.net.au>
2015-02-03 00:24:15 +01:00
Simon Horman
b1900d55df MEDIUM: Refactor init_check and move to checks.c
Refactor init_check so that an error string is returned
rather than alerts being printed by it. Also
init_check to checks.c and provide a prototype to allow
it to be used from multiple C files.

Signed-off-by: Simon Horman <horms@verge.net.au>
2015-02-03 00:24:15 +01:00
Simon Horman
dbf70194b0 MEDIUM: Remove connect_chk
Remove connect_chk and instead call connect_proc_chk()
and connect_conn_chk(). There no longer seems to be any
value in having a wrapper function here.

Signed-off-by: Simon Horman <horms@verge.net.au>
2015-02-03 00:24:15 +01:00
Warren Turkal
b197d7f433 BUG/MINOR: stats:Fix incorrect printf type.
The value is defined in include/types/global.h to be an unsigned int.
The type format in the printf is for a signed int. This eventually wraps
around.

WT: This bug was introduced in 1.5.
2015-01-31 13:48:27 +01:00
Willy Tarreau
34d4c3c13f BUG/MINOR: http: abort request processing on filter failure
Commit c600204 ("BUG/MEDIUM: regex: fix risk of buffer overrun in
exp_replace()") added a control of failure on the response headers,
but forgot to check for the error during request processing. So if
the filters fail to apply, we could keep the request. It might
cause some headers to silently fail to be added for example. Note
that it's tagged MINOR because a standard configuration cannot make
this case happen.

The fix should be backported to 1.5 and 1.4 though.
2015-01-30 20:58:58 +01:00
Cyril Bonté
32602d2361 BUG/MINOR: checks: prevent http keep-alive with http-check expect
Sébastien Rohaut reported that string negation in http-check expect didn't
work as expected.

The misbehaviour is caused by responses with HTTP keep-alive. When the
condition is not met, haproxy awaits more data until the buffer is full or the
connection is closed, resulting in a check timeout when "timeout check" is
lower than the keep-alive timeout on the server side.

In order to avoid the issue, when a "http-check expect" is used, haproxy will
ask the server to disable keep-alive by automatically appending a
"Connection: close" header to the request.
2015-01-30 00:43:34 +01:00
Willy Tarreau
aa435e7d7e BUG/MINOR: http: fix incorrect header value offset in replace-hdr/replace-value
The two http-req/http-resp actions "replace-hdr" and "replace-value" were
expecting exactly one space after the colon, which is wrong. It was causing
the first char not to be seen/modified when no space was present, and empty
headers not to be modified either. Instead of using name->len+2, we must use
ctx->val which points to the first character of the value even if there is
no value.

This fix must be backported into 1.5.
2015-01-29 14:01:34 +01:00
Willy Tarreau
474b96ad41 MEDIUM: init: continue to enforce SYSTEM_MAXCONN with auto settings if set
Commit d025648 ("MAJOR: init: automatically set maxconn and/or maxsslconn
when possible") resulted in a case where if enough memory is available,
a maxconn value larger than SYSTEM_MAXCONN could be computed, resulting
in possibly overflowing other systems resources (eg: kernel socket buffers,
conntrack entries, etc). Let's bound any automatic maxconn to SYSTEM_MAXCONN
if it is defined. Note that the value is set to DEFAULT_MAXCONN since
SYSTEM_MAXCONN forces DEFAULT_MAXCONN, thus it is not an error.
2015-01-28 19:03:21 +01:00
Godbach
58048a2dc9 BUG/MINOR: parse: check the validity of size string in a more strict way
If a stick table is defined as below:
	stick-table type ip size 50ka expire 300s

HAProxy will stop parsing size after passing through "50k" and return the value
directly. But such format string of size should not be valid. The patch checks
the next character to report error if any.

Signed-off-by: Godbach <nylzhaowei@gmail.com>
2015-01-28 11:23:11 +01:00
Willy Tarreau
9770787e70 MEDIUM: samples: provide basic arithmetic and bitwise operators
This commit introduces a new category of converters. They are bitwise and
arithmetic operators which support performing basic operations on integers.
Some bitwise operations are supported (and, or, xor, cpl) and some arithmetic
operations are supported (add, sub, mul, div, mod, neg). Some comparators
are provided (odd, even, not, bool) which make it possible to report a match
without having to write an ACL.

The detailed list of new operators as they appear in the doc is :

add(<value>)
  Adds <value> to the input value of type unsigned integer, and returns the
  result as an unsigned integer.

and(<value>)
  Performs a bitwise "AND" between <value> and the input value of type unsigned
  integer, and returns the result as an unsigned integer.

bool
  Returns a boolean TRUE if the input value of type unsigned integer is
  non-null, otherwise returns FALSE. Used in conjunction with and(), it can be
  used to report true/false for bit testing on input values (eg: verify the
  presence of a flag).

cpl
  Takes the input value of type unsigned integer, applies a twos-complement
  (flips all bits) and returns the result as an unsigned integer.

div(<value>)
  Divides the input value of type unsigned integer by <value>, and returns the
  result as an unsigned integer. If <value> is null, the largest unsigned
  integer is returned (typically 2^32-1).

even
  Returns a boolean TRUE if the input value of type unsigned integer is even
  otherwise returns FALSE. It is functionally equivalent to "not,and(1),bool".

mod(<value>)
  Divides the input value of type unsigned integer by <value>, and returns the
  remainder as an unsigned integer. If <value> is null, then zero is returned.

mul(<value>)
  Multiplies the input value of type unsigned integer by <value>, and returns
  the product as an unsigned integer. In case of overflow, the higher bits are
  lost, leading to seemingly strange values.

neg
  Takes the input value of type unsigned integer, computes the opposite value,
  and returns the remainder as an unsigned integer. 0 is identity. This
  operator is provided for reversed subtracts : in order to subtract the input
  from a constant, simply perform a "neg,add(value)".

not
  Returns a boolean FALSE if the input value of type unsigned integer is
  non-null, otherwise returns TRUE. Used in conjunction with and(), it can be
  used to report true/false for bit testing on input values (eg: verify the
  absence of a flag).

odd
  Returns a boolean TRUE if the input value of type unsigned integer is odd
  otherwise returns FALSE. It is functionally equivalent to "and(1),bool".

or(<value>)
  Performs a bitwise "OR" between <value> and the input value of type unsigned
  integer, and returns the result as an unsigned integer.

sub(<value>)
  Subtracts <value> from the input value of type unsigned integer, and returns
  the result as an unsigned integer. Note: in order to subtract the input from
  a constant, simply perform a "neg,add(value)".

xor(<value>)
  Performs a bitwise "XOR" (exclusive OR) between <value> and the input value
  of type unsigned integer, and returns the result as an unsigned integer.
2015-01-27 15:41:13 +01:00
Cyril Bonté
3180f7b554 MINOR: ssl: load certificates in alphabetical order
As reported by Raphaël Enrici, certificates loaded from a directory are loaded
in a non predictive order. If no certificate was first loaded from a file, it
can result in different behaviours when haproxy is used in cluster.
We can also imagine other cases which weren't met yet.

Instead of using readdir(), we can use scandir() and sort files alphabetically.
This will ensure a predictive behaviour.

This patch should also be backported to 1.5.
2015-01-25 00:48:01 +01:00
Willy Tarreau
c4dc35047d DOC: fix missing closing brackend on regsub
"]" was missing for <flags>.
2015-01-23 20:39:28 +01:00
Willy Tarreau
a0dc23f093 MEDIUM: http: implement http-request set-{method,path,query,uri}
This commit implements the following new actions :

- "set-method" rewrites the request method with the result of the
  evaluation of format string <fmt>. There should be very few valid reasons
  for having to do so as this is more likely to break something than to fix
  it.

- "set-path" rewrites the request path with the result of the evaluation of
  format string <fmt>. The query string, if any, is left intact. If a
  scheme and authority is found before the path, they are left intact as
  well. If the request doesn't have a path ("*"), this one is replaced with
  the format. This can be used to prepend a directory component in front of
  a path for example. See also "set-query" and "set-uri".

  Example :
      # prepend the host name before the path
      http-request set-path /%[hdr(host)]%[path]

- "set-query" rewrites the request's query string which appears after the
  first question mark ("?") with the result of the evaluation of format
  string <fmt>. The part prior to the question mark is left intact. If the
  request doesn't contain a question mark and the new value is not empty,
  then one is added at the end of the URI, followed by the new value. If
  a question mark was present, it will never be removed even if the value
  is empty. This can be used to add or remove parameters from the query
  string. See also "set-query" and "set-uri".

  Example :
      # replace "%3D" with "=" in the query string
      http-request set-query %[query,regsub(%3D,=,g)]

- "set-uri" rewrites the request URI with the result of the evaluation of
  format string <fmt>. The scheme, authority, path and query string are all
  replaced at once. This can be used to rewrite hosts in front of proxies,
  or to perform complex modifications to the URI such as moving parts
  between the path and the query string. See also "set-path" and
  "set-query".

All of them are handled by the same parser and the same exec function,
which is why they're merged all together. For once, instead of adding
even more entries to the huge switch/case, we used the new facility to
register action keywords. A number of the existing ones should probably
move there as well.
2015-01-23 20:27:41 +01:00
Willy Tarreau
d817e468bf BUG/MINOR: sample: fix case sensitivity for the regsub converter
Two commits ago in 7eda849 ("MEDIUM: samples: add a regsub converter to
perform regex-based transformations"), I got caught for the second time
with the inverted case sensitivity usage of regex_comp(). So by default
it is case insensitive and passing the "i" flag makes it case sensitive.
I forgot to recheck that case before committing the cleanup. No harm
anyway, nobody had the time to use it.
2015-01-23 20:27:41 +01:00
Simon Horman
0766e441dd MEDIUM/BUG: Only explicitly report "DOWN (agent)" if the agent health is zero
Make check check used to report explicitly report "DOWN (agent)" slightly
more restrictive such that it only triggers if the agent health is zero.

This avoids the following problem.

1. Backend is started disabled, agent check is is enabled
2. Backend is stabled using set server vip/rip state ready
3. Health is marked as down using set server vip/rip health down

   At this point the http stats page will report "DOWN (agent)"
   but the backend being down has nothing to do with the agent check

This problem appears to have been introduced by cf2924bc25
("MEDIUM: stats: report down caused by agent prior to reporting up").

Note that "DOWN (agent)" may also be reported by a more generic conditional
which immediately follows the code changed by this patch.

Reported-by: Mark Brooks <mark@loadbalancer.org>
Signed-off-by: Simon Horman <horms@verge.net.au>
2015-01-23 16:47:41 +01:00
Simon Horman
1a23cf0dfb BUG/MEDIUM: Do not set agent health to zero if server is disabled in config
disable starts a server in the disabled state, however setting the health
of an agent implies that the agent is disabled as well as the server.

This is a problem because the state of the agent is not restored if
the state of the server is subsequently updated leading to an
unexpected state.

For example, if a server is started disabled and then the server
state is set to ready then without this change show stat indicates
that the server is "DOWN (agent)" when it is expected that the server
would be UP if its (non-agent) health check passes.

Reported-by: Mark Brooks <mark@loadbalancer.org>
Signed-off-by: Simon Horman <horms@verge.net.au>
2015-01-23 16:47:41 +01:00
Willy Tarreau
7eda849dce MEDIUM: samples: add a regsub converter to perform regex-based transformations
We can now replace matching regex parts with a string, a la sed. Note
that there are at least 3 different behaviours for existing sed
implementations when matching 0-length strings. Here is the result
of the following operation on each implementationt tested :

  echo 'xzxyz' | sed -e 's/x*y*/A/g'

  GNU sed 4.2.1       => AzAzA
  Perl's sed 5.16.1   => AAzAAzA
  Busybox v1.11.2 sed => AzAz

The psed behaviour was adopted because it causes the least exceptions
in the code and seems logical from a certain perspective :

  - "x"  matches x*y*  => add "A" and skip "x"
  - "z"  matches x*y*  => add "A" and keep "z", not part of the match
  - "xy" matches x*y*  => add "A" and skip "xy"
  - "z"  matches x*y*  => add "A" and keep "z", not part of the match
  - ""   matches x*y*  => add "A" and stop here

Anyway, given the incompatibilities between implementations, it's unlikely
that some processing will rely on this behaviour.

There currently is one big limitation : the configuration parser makes it
impossible to pass commas or closing parenthesis (or even closing brackets
in log formats). But that's still quite usable to replace certain characters
or character sequences. It will become more complete once the config parser
is reworked.
2015-01-22 14:24:53 +01:00