Commit Graph

4729 Commits

Author SHA1 Message Date
Willy Tarreau
911fa2eb8e MEDIUM: config: reject invalid config with name duplicates
Since 1.4 we used to emit a warning when two frontends or two backends
had the same name. In 1.5 we added the same warning for two peers sections.
In 1.6 we added the same warning for two mailers sections. It's about time
to reject such invalid configurations, the impact they have on the code
complexity is huge and it is becoming a real obstacle to some improvements
such as restoring servers check status across reloads.

Now these errors are reported as fatal errors and will need to be fixed.
Anyway, till now there was no guarantee that what was written was working
as expected since the behaviour is not defined (eg: use_backend with a
name used by two backends leads to undefined behaviour).

Example of output :

[ALERT] 145/104759 (31564) : Parsing [prx.cfg:12]: mailers section 'm' has the same name as another mailers section declared at prx.cfg:10.
[ALERT] 145/104759 (31564) : Parsing [prx.cfg:16]: peers section 'p' has the same name as another peers section declared at prx.cfg:14.
[ALERT] 145/104759 (31564) : Parsing [prx.cfg:21]: frontend 'f' has the same name as another frontend declared at prx.cfg:18.
[ALERT] 145/104759 (31564) : Parsing [prx.cfg:27]: backend 'b' has the same name as another backend declared at prx.cfg:24.
[ALERT] 145/104759 (31564) : Error(s) found in configuration file : prx.cfg
[ALERT] 145/104759 (31564) : Fatal errors found in configuration.
2015-05-26 10:48:17 +02:00
Pavlos Parissis
1f673c72c1 DOC: Update doc about weight, act and bck fields in the statistics
Reorder description of the mentioned fields in order to match the
order of types
2015-05-26 07:28:38 +02:00
Dragan Dosen
26f77e534c BUG/MEDIUM: http: fix the url_param fetch
The "name" and "name_len" arguments in function "smp_fetch_url_param"
could be left uninitialized for subsequent calls.

[wt: no backport needed, this is an 1.6 regression introduced by
 commit 4fdc74c ("MINOR: http: split the url_param in two parts") ]
2015-05-25 19:01:39 +02:00
Joseph Lynch
726ab7145c MEDIUM: backend: Allow redispatch on retry intervals
For backend load balancing it sometimes makes sense to redispatch rather
than retrying against the same server. For example, when machines or routers
fail you may not want to waste time retrying against a dead server and
would instead prefer to immediately redispatch against other servers.

This patch allows backend sections to specify that they want to
redispatch on a particular interval. If the interval N is positive the
redispatch occurs on every Nth retry, and if the interval N is negative then
the redispatch occurs on the Nth retry prior to the last retry (-1 is the
default and maintains backwards compatibility). In low latency environments
tuning this setting can save a few hundred milliseconds when backends fail.
2015-05-22 07:07:40 +02:00
Thierry FOURNIER
9826c7781a DOC: http: req.body_param documentation
This patch adds the req.body_param documentation.
2015-05-20 16:06:11 +02:00
Thierry FOURNIER
8be451c52a MEDIUM: http: url-encoded parsing function can run throught wrapped buffer
The functions smp_fetch_param(), find_next_url_param() and
find_url_param_pos() can look for argument in 2 chunks and not only
one.
2015-05-20 16:05:38 +02:00
Thierry FOURNIER
e28c49975a MINOR: http: add body_param fetch
This fetch returns one body param or the list of each body param.
This first version runs only with one chunk.
2015-05-20 15:56:23 +02:00
Thierry FOURNIER
0948d41a12 CLEANUP: http: bad indentation
Some function argument uses space in place of tabulation
for the indentation.
2015-05-20 15:56:23 +02:00
Thierry FOURNIER
4fdc74c22c MINOR: http: split the url_param in two parts
This patch is the part of the body_param fetch. The goal is to have
generic url-encoded parser which can used for parsing the query string
and the body.
2015-05-20 15:56:23 +02:00
Willy Tarreau
b4e34da692 BUG/MEDIUM: peers: apply a random reconnection timeout
Commit 9ff95bb ("BUG/MEDIUM: peers: correctly configure the client timeout")
uncovered an old bug in the peers : upon disconnect, we reconnect immediately.
This sometimes results in both ends to do the same thing in parallel causing
a loop of connect/accept/close/close that can last several seconds. The risk
of occurrence of the trouble increases with latency, and is emphasized by the
fact that idle connections are now frequently recycled (after 5s of idle).

In order to avoid this we must apply a random delay before reconnecting.
Fortunately the mechanism already supports a reconnect delay, so here we
compute the random timeout when killing a session. The delay is 50ms plus
a random between 0 and 2 seconds. Ideally an exponential back-off would
be preferred but it's preferable to keep the fix simple.

This bug was reported by Marco Corte.

This fix must be backported to 1.5 since the fix above was backported into
1.5.12.
2015-05-20 10:49:07 +02:00
Willy Tarreau
1ede1daab6 MEDIUM: http: make url_param iterate over multiple occurrences
There are some situations hwere it's desirable to scan multiple occurrences
of a same parameter name in the query string. This change ensures this can
work, even with an empty name which will then iterate over all parameters.
2015-05-19 13:16:07 +02:00
Nenad Merdanovic
26ea822190 MINOR: Add sample fetch which identifies if the SSL session has been resumed
Signed-off-by: Nenad Merdanovic <nmerdan@anine.io>
2015-05-18 07:07:53 +02:00
Nenad Merdanovic
c6985f0f6c DOC: Document new socket commands "show tls-keys" and "set ssl tls-key"
Signed-off-by: Nenad Merdanovic <nmerdan@anine.io>
2015-05-16 11:28:04 +02:00
Nenad Merdanovic
200b0facde MEDIUM: Add support for updating TLS ticket keys via socket
Until now, HAproxy needed to be restarted to change the TLS ticket
keys. With this patch, the TLS keys can be updated on a per-file
basis using the admin socket. Two new socket commands have been
introduced: "show tls-keys" and "set ssl tls-keys".

Signed-off-by: Nenad Merdanovic <nmerdan@anine.io>
2015-05-16 11:28:04 +02:00
Nenad Merdanovic
146defaff4 MINOR: Add TLS ticket keys reference and use it in the listener struct
Within the listener struct we need to use a reference to the TLS
ticket keys which binds the actual keys with the filename. This will
make it possible to update the keys through the socket

Signed-off-by: Nenad Merdanovic <nmerdan@anine.io>
2015-05-16 11:28:04 +02:00
Willy Tarreau
449f952cb3 BUG/MAJOR: checks: break infinite loops when tcp-checks starts with comment
If a tcp-check sequence starts with "comment", then the action is not
matched in the while() loop and the pointer doesn't advance so we face
an endless loop. It is normally detected early except in the case where
very slow checks are performed causing it to trigger after the admin stops
watching.

This bug is 1.6-only and very recent so it didn't have the time to affect
anyone.
2015-05-13 15:39:48 +02:00
Willy Tarreau
5581c27b57 BUG/MEDIUM: checks: do not dereference a list as a tcpcheck struct
The method used to skip to next rule in the list is wrong, it assumes
that the list element starts at the same offset as the rule. It happens
to be true on most architectures since the list is the first element for
now but it's definitely wrong. Now the code doesn't crash anymore when
the struct list is moved anywhere else in the struct tcpcheck_rule.

This fix must be backported to 1.5.
2015-05-13 15:31:34 +02:00
Willy Tarreau
f2c87353a7 BUG/MAJOR: checks: always check for end of list before proceeding
This is the most important fix of this series. There's a risk of endless
loop and crashes caused by the fact that we go past the head of the list
when skipping to next rule, without checking if it's still a valid element.
Most of the time, the ->action field is checked, which points to the proxy's
check_req pointer (generally NULL), meaning the element is confused with a
TCPCHK_ACT_SEND action.

The situation was accidently made worse with the addition of tcp-check
comment since it also skips list elements. However, since the action that
makes it go forward is TCPCHK_ACT_COMMENT (3), there's little chance to
see this as a valid pointer, except on 64-bit machines where it can match
the end of a check_req string pointer.

This fix heavily depends on previous cleanup and both must be backported
to 1.5 where the bug is present.
2015-05-13 15:31:34 +02:00
Willy Tarreau
263013d031 CLEANUP: checks: simplify the loop processing of tcp-checks
There is some unobvious redundancy between the various ways we can leave
the loop. Some of them can be factored out. So now we leave the loop when
we can't go further, whether it's caused by reaching the end of the rules
or by a blocking I/O.
2015-05-13 12:30:46 +02:00
Willy Tarreau
53c5a049e1 BUG/MEDIUM: checks: do not dereference head of a tcp-check at the end
When the end of the list is reached, the current step's action is checked
to know if we must poll or not. Unfortunately, the main reason for going
there is that we walked past the end of list and current_step points to
the head. We cannot dereference ->action since it does not belong to this
structure and can definitely crash if the address is not mapped.

This bug is unlikely to cause a crash since the action appears just after
the list, and corresponds to the "char *check_req" pointer in the proxy
struct, and it seems that we can't go there with current_step being null.
At worst it can cause the check to register for recv events.

This fix needs to be backported to 1.5 since the code is incorrect there
as well.
2015-05-13 12:30:25 +02:00
Willy Tarreau
ce8c42a37a CLEANUP: checks: fix double usage of cur / current_step in tcp-checks
This cleanup is a preliminary requirement to the upcoming fixes for
the bug that affect tcp-check's improper use of lists. It will have
to be backported to 1.5 though it will not easily apply.

There are two variables pointing to the current rule within the loop,
and either one or the other is used depending on the code blocks,
making it much harder to apply checks to fix the list walking bug.
So first get rid of "cur" and only focus on current_step.
2015-05-13 12:02:09 +02:00
William Lallemand
b2f07451e5 MEDIUM: cfgparse: expand environment variables
Environment variables were expandables only in adresses.
Now there are expandables everywhere in the configuration file within
double quotes.

This patch breaks compatibility with the previous behavior of
environment variables in adresses, you must enclose adresses with double
quotes to make it work.
2015-05-12 15:28:20 +02:00
William Lallemand
64e84516c4 MINOR: cfgparse: remove line size limitation
Remove the line size limitation of the configuration parser.  The buffer
is now allocated dynamically and grows when the line is too long.
2015-05-12 15:28:07 +02:00
William Lallemand
3f41560f61 BUG/MEDIUM: cfgparse: incorrect memmove in quotes management
The size of the memmove was incorrect (one byte too far) in the quotes
parser and can lead to segfault during configuration parsing.
2015-05-12 15:27:45 +02:00
Willy Tarreau
6296a11ea4 BUG/MAJOR: check: fix breakage of inverted tcp-check rules
Recent commit 22b09d2 ("MINOR: include comment in tcpcheck error log")
accidently left a double-step to the next rule in case of an inverted
rule. The effect is that an inverted rule is necessarily skipped and
that we can crash if it was the last rule since we'd use as a rule the
head of the list, thus dereference random memory contents.

No backport is needed.
2015-05-12 14:45:02 +02:00
Baptiste Assmann
d60a9e5a39 DOC: tcpcheck comment documentation
Introduction of new tcpcheck comment directive and also update texpcheck
ruleset examples.
2015-05-12 11:06:21 +02:00
Baptiste Assmann
22b09d2393 MINOR: include comment in tcpcheck error log
tcpcheck error messages include the step id where the error occurs.
In some cases, this is not enough. Now, HAProxy also use the comment
field of the latest tcpcheck rule which has been run.
This commit allows HAProxy to parse a new directive in the tcpcheck
ruleset: 'comment'.
It is used to setup comments on the current tcpcheck rules.
2015-05-12 11:04:39 +02:00
Baptiste Assmann
aa12b47b06 MINOR: tcpcheck_rule structure update
A new field is added into the tcpcheck_rule structure.
This field will host a string used as a comment to describe the rule.
Then this comment can be used in logs to report a more user friendly
message on the step which failed during the tcpcheck ruleset.
2015-05-12 10:44:49 +02:00
Baptiste Assmann
cfbd1b8605 MINOR: use an int instead of calling tcpcheck_get_step_id
in src.checks.c, the function tcpcheck_get_step_id is called many times.
In order to save some cpu cycles, I save the result of this function in
an integer.
2015-05-12 10:44:13 +02:00
Baptiste Assmann
96a5c9b577 BUG/MINOR: check: fix tcpcheck error message
add the keyword 'string' when required (error in a tcpcheck expect
string)
2015-05-12 10:43:52 +02:00
Willy Tarreau
e26bf05115 BUILD/MINOR: ssl: fix build failure introduced by recent patch
Baptiste reported that commit 0a9a2b8 ("MEDIUM: sample change the
prototype of sample-fetches and converters functions") broke the
build of ssl_sock.c when using openssl-1.0.2 because one missed
replacement of sess with smp->sess. No backport is needed.
2015-05-12 10:30:12 +02:00
Thierry FOURNIER
0786d05a04 MEDIUM: sample: change the prototype of sample-fetches functions
This patch removes the "opt" entry from the prototype of the
sample-fetches fucntions. This permits to remove some weight
in the prototype call.
2015-05-11 20:03:08 +02:00
Thierry FOURNIER
1d33b882d2 MINOR: sample: fill the struct sample with the options.
Options are relative to the sample. Each sample fetched is associated with
fetch options or fetch flags.

This patch adds the 'opt' vaue in the sample struct. This permits to reduce
the sample-fetch function prototype. In other way, the converters will have
more detail about the origin of the sample.
2015-05-11 20:02:11 +02:00
Thierry FOURNIER
0a9a2b8cec MEDIUM: sample change the prototype of sample-fetches and converters functions
This patch removes the structs "session", "stream" and "proxy" from
the sample-fetches and converters function prototypes.

This permits to remove some weight in the prototype call.
2015-05-11 20:01:42 +02:00
Thierry FOURNIER
6879ad31a5 MEDIUM: sample: fill the struct sample with the session, proxy and stream pointers
Some sample analyzer (sample-fetch or converters) needs to known the proxy,
session and stream attached to the sampel. The sample-fetches and the converters
function pointers cannot be called without these 3 pointers filled.

This patch permits to reduce the sample-fetch and the converters called
prototypes, and provides a new mean to add information for this type of
functions.
2015-05-11 20:00:03 +02:00
Willy Tarreau
bbfb6c4085 BUG/MEDIUM: http: don't forward client shutdown without NOLINGER except for tunnels
There's an issue related with shutting down POST transfers or closing the
connection after the end of the upload : the shutdown is forwarded to the
server regardless of the abortonclose option. The problem it causes is that
during a scan, brute force or whatever, it becomes possible that all source
ports are exhausted with all sockets in TIME_WAIT state.

There are multiple issues at once in fact :
  - no action is done for the close, it automatically happens at the lower
    layers thanks for channel_auto_close(), so we cannot act on NOLINGER ;

  - we *do* want to continue to send a clean shutdown in tunnel mode because
    some protocols transported over HTTP may need this, regardless of option
    abortonclose, thus we can't set the option inconditionally

  - for all other modes, we do want to close the dirty way because we're
    certain whether we've sent everything or not, and we don't want to eat
    all source ports.

The solution is a bit complex and applies to DONE/TUNNEL states :

  1) disable automatic close for everything not a tunnel and not just
     keep-alive / server-close. Force-close is now covered, as is HTTP/1.0
     which implicitly works in force-close mode ;

  2) when processing option abortonclose, we know we can disable lingering
     if the client has closed and the connection is not in tunnel mode.

Since the last case above leads to a situation where the client side reports
an error, we know the connection will not be reused, so leaving the flag on
the stream-interface is safe. A client closing in the middle of the data
transmission already aborts the transaction so this case is not a problem.

This fix must be backported to 1.5 where the problem was detected.
2015-05-11 19:05:42 +02:00
Thierry FOURNIER
82ff3c9b05 MINOR: sample: add url_dec converter
This converter decodes an url-encoded string. It takes a string as
input and returns string as output.
2015-05-11 11:40:36 +02:00
Willy Tarreau
3986ac1860 BUG/MEDIUM: http: fix the http-request capture parser
Due to the code being mostly inspired from the tcp-request parser, it
does some crap because both don't work the same way. The "len" argument
could be mismatched and then the length could be used uninitialized.
2015-05-08 16:13:42 +02:00
Willy Tarreau
a9083d0722 MEDIUM: http: add new "capture" action for http-request
This is only possible in frontends of course, but it will finally
make it possible to capture arbitrary http parts, including URL
parameters or parts of the message body.

It's worth noting that an ugly (char **) cast had to be done to
call sample_fetch_string() which is caused by a 5- or 6- levels
of inheritance of this type in the API. Here it's harmless since
the function uses it as a const, but this API madness must be
fixed, starting with the one or two rare functions that modify
the args and inflict this on each and every keyword parser.
(cherry picked from commit 484a4f38460593919a1c1d9a047a043198d69f45)
2015-05-08 15:43:54 +02:00
William Lallemand
f9873ba63a MEDIUM: cfgparse: introduce weak and strong quoting
This patch introduces quoting which allows to write configuration string
including spaces without escaping them.

Strong (with single quotes) and weak (with double quotes) quoting are
supported. Weak quoting supports escaping and special characters when
strong quoting does not interpret anything.

This patch could break configuration files where ' and " where used.
2015-05-05 21:05:44 +02:00
Willy Tarreau
e428b08ee7 BUG/MEDIUM: config: properly compute the default number of processes for a proxy
Chad Lavoie reported an interesting regression caused by the latest
updates to automatically detect the processes a peers section runs on.
It turns out that if a config has neither nbproc nor a bind-process
statement and depending on the frontend->backend chaining, it is possible
to evade all bind_proc propagations, resulting in assigning only ~0UL (all
processes, which is 32 or 64) without ever restricting it to nbproc. It
was not visible in backends until they started to reference peers sections
which saw themselves with 64 processes at once.

This patch addresses this by replacing all those ~0UL with nbits(nbproc).
That way all "bind-process" settings *default* to the number of processes
defined in nbproc instead of 32 or 64.

This fix could possibly be backported into 1.5, though there is no indication
that this bug could have any effect there.
2015-05-04 21:57:58 +02:00
Willy Tarreau
64c5722e05 MINOR: config: report the number of processes using a peers section in the error case
It can be helpful to know how many different processes try to use the
same peers section when trying to find the culprits.
2015-05-04 21:48:51 +02:00
Willy Tarreau
0334ffc65d CLEANUP: config: fix misleading information in error message.
The parameter name is "bind-process", not "bind_proc" which is the
internal variable name.
2015-05-04 21:46:08 +02:00
Willy Tarreau
6bcb95da5b BUG/MEDIUM: stats: properly initialize the scope before dumping stats
Issuing a "show sess all" prior to a "show stat" on the CLI results in no
proxy being dumped because the scope_len union member was not properly
reinitialized.

This fix must be backported into 1.5.
2015-05-04 18:07:56 +02:00
Willy Tarreau
aee9314e71 BUILD: pattern: fix build warnings introduced in the LRU cache
They're caused by the cast to long long from ptr in 32-bit.

src/pattern.c: In function 'pat_match_str':
src/pattern.c:479:44: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
2015-05-04 17:18:42 +02:00
CJ Ess
6eac32ebc1 BUILD: Compile clean when debug options defined
Here you go!
2015-05-03 09:17:43 +02:00
Willy Tarreau
7b7011ca37 DOC: update the doc on the proxy protocol
Mention a few new implementations and explain the TLV format used
for SSL/TLS.
2015-05-02 15:13:07 +02:00
Willy Tarreau
a5910cc6ef MEDIUM: http: provide 3 fetches for the body
Body processing is still fairly limited, but this is a start. It becomes
possible to apply regex to find contents in order to decide where to route
a request for example. Only the first chunk is parsed for now, and the
response is not yet available (the parsing function must be duplicated for
this).

req.body : binary
  This returns the HTTP request's available body as a block of data. It
  requires that the request body has been buffered made available using
  "option http-buffer-request". In case of chunked-encoded body, currently only
  the first chunk is analyzed.

req.body_len : integer
  This returns the length of the HTTP request's available body in bytes. It may
  be lower than the advertised length if the body is larger than the buffer. It
  requires that the request body has been buffered made available using
  "option http-buffer-request".

req.body_size : integer
  This returns the advertised length of the HTTP request's body in bytes. It
  will represent the advertised Content-Length header, or the size of the first
  chunk in case of chunked encoding. In order to parse the chunks, it requires
  that the request body has been buffered made available using
  "option http-buffer-request".
2015-05-02 00:46:08 +02:00
Willy Tarreau
9fbe18e174 MEDIUM: http: add a new option http-buffer-request
It is sometimes desirable to wait for the body of an HTTP request before
taking a decision. This is what is being done by "balance url_param" for
example. The first use case is to buffer requests from slow clients before
connecting to the server. Another use case consists in taking the routing
decision based on the request body's contents. This option placed in a
frontend or backend forces the HTTP processing to wait until either the whole
body is received, or the request buffer is full, or the first chunk is
complete in case of chunked encoding. It can have undesired side effects with
some applications abusing HTTP by expecting unbufferred transmissions between
the frontend and the backend, so this should definitely not be used by
default.

Note that it would not work for the response because we don't reset the
message state before starting to forward. For the response we need to
1) reset the message state to MSG_100_SENT or BODY , and 2) to reset
body_len in case of chunked encoding to avoid counting it twice.
2015-05-02 00:10:44 +02:00
Willy Tarreau
748179eb5a MEDIUM: stream: move HTTP request body analyser before process_common
Since 1.5, the request body analyser has become independant from any
other element and does not even disturb the message forwarder anymore.
And since it's disabled by default, we can place it before most
analysers so that it's can preempt any other one if an intermediary
one enables it.
2015-05-02 00:10:44 +02:00