]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
9 years agoMEDIUM: stats: compute the color code only in the HTML form
Willy Tarreau [Fri, 8 Jan 2016 15:51:35 +0000 (16:51 +0100)] 
MEDIUM: stats: compute the color code only in the HTML form

The color code requires a complex logic, and we use it only in the
HTML part. So let's compute it there based on the server state, its
health and its weight. The thing is tricky but OK. There's a 1-to-1
mapping of down servers, but not of up servers, hence the need for
the weight and health.

9 years agoMEDIUM: stats: report the cookie value in the server & backend CSV dumps
Willy Tarreau [Fri, 8 Jan 2016 14:43:54 +0000 (15:43 +0100)] 
MEDIUM: stats: report the cookie value in the server & backend CSV dumps

The server's cookie value is now reported in the "cookie" column and
used as-is from the HTML dump. It was the last reference to the sv
pointer from this place.

The same was done for the backend's dump.

9 years agoMEDIUM: stats: report server's address in the CSV output
Willy Tarreau [Fri, 8 Jan 2016 14:35:43 +0000 (15:35 +0100)] 
MEDIUM: stats: report server's address in the CSV output

This new field "addr" presents the server's address:port if the client
is either enabled via "stats show legends" in case of HTTP dumps, or
has at least level operator on the CLI. The address formats might be :
 - ipv4:port
 - [ipv6]:port
 - unix
 - (error message)

9 years agoMEDIUM: stats: expose the same flags for CLI and HTTP accesses
Willy Tarreau [Fri, 8 Jan 2016 14:33:18 +0000 (15:33 +0100)] 
MEDIUM: stats: expose the same flags for CLI and HTTP accesses

The HTML dump over HTTP request may have several flags including
ST_SHLGNDS (to show legends), ST_SHNODE (to show node name),
ST_SHDESC (to show some descriptions).

There's no such thing over the CLI so we need to have an equivalent.
Let's compute the flags earlier so that we can make use of these flags
regardless of the call point.

9 years agoMEDIUM: stats: only report observe errors when observe is set
Willy Tarreau [Fri, 8 Jan 2016 14:12:28 +0000 (15:12 +0100)] 
MEDIUM: stats: only report observe errors when observe is set

This doesn't produce this field when not relevant anymore.

9 years agoMEDIUM: stats: make the HTML server state dump use the CSV states
Willy Tarreau [Fri, 8 Jan 2016 13:57:09 +0000 (14:57 +0100)] 
MEDIUM: stats: make the HTML server state dump use the CSV states

Now instead of recomputing the state based on the health, rise etc,
we reuse the same state as in the CSV file, and optionally complete
it with a down or an up arrow if a change is occurring. We could
have parsed the strings to detect a '/' indicating a state change,
but it was easier to check the health against rise and fall.

9 years agoMINOR: stats: add check and agent's health values in the output
Willy Tarreau [Fri, 8 Jan 2016 13:25:28 +0000 (14:25 +0100)] 
MINOR: stats: add check and agent's health values in the output

This adds the following fields :
- check_rise [...S]: server's "rise" parameter used by checks
- check_fall [...S]: server's "fall" parameter used by checks
- check_health [...S]: server's health check value between 0 and rise+fall-1
- agent_rise [...S]: agent's "rise" parameter, normally 1
- agent_fall [...S]: agent's "fall" parameter, normally 1
- agent_health [...S]: agent's health parameter, between 0 and rise+fall-1

9 years agoMINOR: stats: add check_desc and agent_desc to the output fields
Willy Tarreau [Fri, 8 Jan 2016 12:47:26 +0000 (13:47 +0100)] 
MINOR: stats: add check_desc and agent_desc to the output fields

Added these two new fields to the CSV output :
- check_desc : short human-readable description of check_status
- agent_desc : short human-readable description of agent_status

Also factor two tests for enabled checks.

9 years agoMINOR: stats: add agent_status, agent_code, agent_duration to output
Willy Tarreau [Fri, 8 Jan 2016 10:40:03 +0000 (11:40 +0100)] 
MINOR: stats: add agent_status, agent_code, agent_duration to output

The agent check status is now reported :
- agent_status : status of last agent check
- agent_code : numeric code reported by agent if any (unused for now)
- agent_duration : time in ms taken to finish last check

9 years agoMINOR: stats: make HTML stats dump rely on the table for the check status
Willy Tarreau [Fri, 8 Jan 2016 08:48:26 +0000 (09:48 +0100)] 
MINOR: stats: make HTML stats dump rely on the table for the check status

We can now check that the check status field is present to know that a
check is enabled.

9 years agoMINOR: stats: prepend '*' in front of the check status when in progress
Willy Tarreau [Fri, 8 Jan 2016 08:43:54 +0000 (09:43 +0100)] 
MINOR: stats: prepend '*' in front of the check status when in progress

The HTML version already does this, but the CSV doesn't provide this
status, so make both of them report the same status.

9 years agoMINOR: stats: only report backend's down time if it has servers
Willy Tarreau [Mon, 11 Jan 2016 11:04:02 +0000 (12:04 +0100)] 
MINOR: stats: only report backend's down time if it has servers

There's no point in reporting a backend's up/down time if it has no
servers. The CSV output used to report "0" for a serverless backend
while the HTML version already removed the field. For servers, this
field is already omitted if checks are disabled. Let's uniformize
all of this and remove the field in CSV as well when irrelevant.

9 years agoMINOR: stats: make CSV report server check status only when enabled
Willy Tarreau [Fri, 8 Jan 2016 08:41:59 +0000 (09:41 +0100)] 
MINOR: stats: make CSV report server check status only when enabled

The HTML version doesn't report a check status when the server is in
maintenance since it can be quite old and irrelevant. The CSV forgot
to care about that, so let's do it here as well.

9 years agoMINOR: stats: do not check srv->state for SRV_ST_STOPPED in HTML dumps
Willy Tarreau [Thu, 7 Jan 2016 12:59:10 +0000 (13:59 +0100)] 
MINOR: stats: do not check srv->state for SRV_ST_STOPPED in HTML dumps

We don't want the HTML dump to rely on the server state. We
already have this piece of information in the status field by
checking that it starts with "DOWN".

9 years agoMINOR: stats: do not use srv->admin & STATS_ADMF_MAINT in HTML dumps
Willy Tarreau [Thu, 7 Jan 2016 11:59:57 +0000 (12:59 +0100)] 
MINOR: stats: do not use srv->admin & STATS_ADMF_MAINT in HTML dumps

We don't want the HTML dump to rely on the server admin bits. We
already have this piece of information in the status field.

9 years agoMEDIUM: stats: move the server state coloring logic to the server dump function
Willy Tarreau [Thu, 7 Jan 2016 08:54:40 +0000 (09:54 +0100)] 
MEDIUM: stats: move the server state coloring logic to the server dump function

It currently is really not convenient to have a state and a color detection
outside of the function and to use these ones inside. It makes it harder to
adjust the stats output based on the server state exactly. Let's move the
logic into the dump function itself.

9 years agoMEDIUM: stats: make stats_dump_sv_stats() use the stats field for HTML
Willy Tarreau [Wed, 6 Jan 2016 18:48:21 +0000 (19:48 +0100)] 
MEDIUM: stats: make stats_dump_sv_stats() use the stats field for HTML

Here we still have a huge amount of stuff to extract from the HTML code
and even from the caller. Indeed, the calling function computes the
server state and prepares a color code that will be used to determine
what style to use. The operations needed to decide what field to present
or not depend a lot on the server's state, admin state, health value,
rise and fall etc... all of which are not easily present in the table.

We also have to check the reference's values for all of the above.

There are also a number of differences between the CSV and HTML outputs :
  - CSV always reports check duration, HTML only if not zero
  - regarding last_change, CSV always report the server's while the HTML
    considers either the server's or the reference based on the admin state.
  - agent and health are separate in the CSV but mixed in the HTML.
  - too few info on agent anyway.

After careful code inspection it happens that both sv->last_change and
ref->last_change are identical and can both derive from [LASTCHG].

Also, the following info are missing from the array to complete the HTML
code :
  - cookie, address, status description, check-in-progress, srv->admin

At least for now it still works but a lot of info now need to be added.

9 years agoMEDIUM: stats: convert stats_dump_sv_stats() to use stats_dump_fields_csv()
Willy Tarreau [Wed, 6 Jan 2016 18:25:38 +0000 (19:25 +0100)] 
MEDIUM: stats: convert stats_dump_sv_stats() to use stats_dump_fields_csv()

This function now only fills the relevant fields with raw values and
calls stats_dump_fields_csv() for the CSV part. The output remains
exactly the same for now.

Some limits are only emitted if set, so the HTML part will have to
check for these being set.

A number of fields had to be built using printf-format strings, so
instead of allocating strings that risk not being freed, we use
chunk_newstr() and chunk_appendf().

Text strings are now copied verbatim in the stats fields so that only
the CSV dump encodes them as CSV. A single "out" chunk is used and cut
into multiple substrings using chunk_newstr() so that we don't need
distinct chunks for each stats field holding a string. The total amount
of data being emitted at once will never overflow the "out" chunk since
only a small part of it goes into the trash buffer which is the same size
and will thus overflow first.

One point of care is that failed_checks and down_trans were logged as
64-bit quantities on servers but they're 32-bit on proxies. This may
have to be changed later to unify them.

9 years agoMEDIUM: stats: make stats_dump_be_stats() use stats fields for HTML dump
Willy Tarreau [Wed, 6 Jan 2016 16:14:42 +0000 (17:14 +0100)] 
MEDIUM: stats: make stats_dump_be_stats() use stats fields for HTML dump

Some fields are still needed to complete the conversion :
  - px->srv : used to take decisions when backend has no server (eg: print down or not)
  - algo string (useful for CSV as well) // only if SHLGNDS
  - cookie_name (useful for CSV as well) // only if SHLGNDS
  - px->mode == HTTP (or px->mode as a string) // same for frontend
  - px->be_counters.intercepted_req (stats and redirects ?)

The following field already has a place but was not presented in the
CSV output, so it should simply be added afterwards :
  - px->be_counters.http.cum_req (was in HTML and missing from CSV)

9 years agoMEDIUM: stats: convert stats_dump_be_stats() to use stats_dump_fields_csv()
Willy Tarreau [Wed, 6 Jan 2016 15:14:50 +0000 (16:14 +0100)] 
MEDIUM: stats: convert stats_dump_be_stats() to use stats_dump_fields_csv()

This function now only fills the relevant fields with raw values and
calls stats_dump_fields_csv() for the CSV part. The output remains
exactly the same for now. It's worth noting that there are some
ambiguities between connections and sessions, for example cum_conn
is dumped into cum_sess. Additionally, there is a naming ambiguity
in that the internal "d_time" (time where the beginning of data
appeared) is called "rtime" in the output (response time) and they
actually are indeed the same.

9 years agoMEDIUM: stats: make stats_dump_li_stats() use stats fields for HTML dump
Willy Tarreau [Wed, 6 Jan 2016 14:49:26 +0000 (15:49 +0100)] 
MEDIUM: stats: make stats_dump_li_stats() use stats fields for HTML dump

The conversion still requires some elements which are not present in the
current fields :
  - the HTML status may emit "WAITING"/"OPEN"/"FULL" while the CSV format
    doesn't propose "WAITING", so this last one will have to be added.

  - the HTML output emits the listening adresses when the ST_SHLGNDS flag
    is set but this address field doesn't exist in the CSV format

  - it's interesting to note that when the ST_SHLGNDS flag is not set, the
    HTML output doesn't provide the listener's ID while it's present in the
    CSV output accessible from the same interface.

9 years agoMEDIUM: stats: convert stats_dump_li_stats() to use stats_dump_fields_csv()
Willy Tarreau [Wed, 6 Jan 2016 14:41:29 +0000 (15:41 +0100)] 
MEDIUM: stats: convert stats_dump_li_stats() to use stats_dump_fields_csv()

This function now only fills the relevant fields with raw values and
calls stats_dump_fields_csv() for the CSV part. The output remains
exactly the same for now.

It is worth mentionning that l->cum_conn is being dumped into a cum_sess
field and that once we introduce an official cum_conn field we may have
to dump the same value at both places to maintain compatibility with the
existing stats.

9 years agoMEDIUM: stats: make stats_dump_fe_stats() use stats fields for HTML dump
Willy Tarreau [Wed, 6 Jan 2016 14:26:40 +0000 (15:26 +0100)] 
MEDIUM: stats: make stats_dump_fe_stats() use stats fields for HTML dump

Now we avoid directly accessing the proxy and instead we pick the values
from the stats fields. This unveils that only a few fields are missing to
complete the job :
  - know whether or not the checkbox column needs to be displayed. This
    is not directly relevant to the stats but rather to the fact that the
    HTML dump is also a control interface. This doesn't need a field, just
    a function argument.
  - px->mode == HTTP (or px->mode as a string)
  - px->fe_counters.intercepted_req (stats and redirects ?)
  - px->fe_counters.cum_conn
  - px->fe_counters.cps_max
  - px->fe_conn_per_sec

All the last ones make sense in the CSV, so they'll have to be added as well.

9 years agoMEDIUM: stats: convert stats_dump_fe_stats() to use stats_dump_fields_csv()
Willy Tarreau [Mon, 4 Jan 2016 18:36:41 +0000 (19:36 +0100)] 
MEDIUM: stats: convert stats_dump_fe_stats() to use stats_dump_fields_csv()

This function now only fills the relevant fields with raw values and
calls stats_dump_fields_csv() for the CSV part. The output remains
exactly the same for now.

9 years agoMINOR: stats: create stats fields storage and CSV dump function
Willy Tarreau [Mon, 4 Jan 2016 18:04:18 +0000 (19:04 +0100)] 
MINOR: stats: create stats fields storage and CSV dump function

The new function stats_dump_fields_csv() currenty walks over all CSV
fields and prints all non-empty ones as one line. Strings are csv-encoded
on the fly.

9 years agoMINOR: stats: don't hard-code the CSV fields list anymore
Willy Tarreau [Mon, 4 Jan 2016 16:24:29 +0000 (17:24 +0100)] 
MINOR: stats: don't hard-code the CSV fields list anymore

Now the list of CSV fields is directly taken from the table.

9 years agoMINOR: stats: add a declaration of all stats fields
Willy Tarreau [Mon, 4 Jan 2016 16:23:25 +0000 (17:23 +0100)] 
MINOR: stats: add a declaration of all stats fields

This is in preparation for a unifying of the stats output between the
multiple formats. The long-term goal will be that HTML stats are built
from the array used to produce the CSV output in order to ensure that
no information is missing in any format.

9 years agoMEDIUM: stats: make use of stats_dump_info_fields() for "show info"
Willy Tarreau [Mon, 11 Jan 2016 17:29:04 +0000 (18:29 +0100)] 
MEDIUM: stats: make use of stats_dump_info_fields() for "show info"

Now we can get rid of the huge chunk_printf() and use this new function
instead.

9 years agoMINOR: stats: add stats_dump_info_fields() to dump one field per line
Willy Tarreau [Mon, 11 Jan 2016 17:27:29 +0000 (18:27 +0100)] 
MINOR: stats: add stats_dump_info_fields() to dump one field per line

This function dumps non-empty fields, one per line with their name and
values, in the same format as is currently used by "show info". It relies
on previously added stats_emit_raw_data_field().

9 years agoMINOR: stats: add a function to emit fields into a chunk
Willy Tarreau [Wed, 24 Feb 2016 22:11:01 +0000 (23:11 +0100)] 
MINOR: stats: add a function to emit fields into a chunk

New function stats_emit_raw_data_field() may be used to write a field
into a chunk. It takes care of the field format to know how to print
it.

9 years agoMEDIUM: stats: fill all the show info elements prior to displaying them
Willy Tarreau [Mon, 11 Jan 2016 17:17:07 +0000 (18:17 +0100)] 
MEDIUM: stats: fill all the show info elements prior to displaying them

The table is completely filled with all relevant information. Only the
fields that should appear are presented. The description field is now
properly omitted if not set, instead of being reported as empty.

9 years agoMINOR: stats: add all the "show info" fields in a table
Willy Tarreau [Mon, 11 Jan 2016 17:12:26 +0000 (18:12 +0100)] 
MINOR: stats: add all the "show info" fields in a table

This will be used to dump them in the most appropriate format.

9 years agoMINOR: stats: create fields types suitable for all CSV output data
Willy Tarreau [Mon, 4 Jan 2016 16:23:25 +0000 (17:23 +0100)] 
MINOR: stats: create fields types suitable for all CSV output data

We're preparing for various data types for each stats field as they
appear in the CSV output. For now we only cover the regular types handled
by printf, so we have 32 and 64 bit ints and counters, strings, and of
course "empty" to indicate that there's nothing in the field and which
guarantees that any accessed entry will return 0.

More types will surely come later so that some fields are properly
represented. For example, we could see limits where only the value 0
doesn't show up, or human time, etc.

9 years agoBUG/MINOR: ssl: fix usage of the various sample fetch functions
Willy Tarreau [Thu, 10 Mar 2016 16:05:28 +0000 (17:05 +0100)] 
BUG/MINOR: ssl: fix usage of the various sample fetch functions

Technically speaking, many SSL sample fetch functions act on the
connection and depend on USE_L5CLI on the client side, which means
they're usable as soon as a handshake is completed on a connection.
This means that the test consisting in refusing to call them when
the stream is NULL will prevent them from working when we implement
the tcp-request session ruleset. Better fix this now. The fix consists
in using smp->sess->origin when they're called for the front connection,
and smp->strm->si[1].end when called for the back connection.

There is currently no known side effect for this issue, though it would
better be backported into 1.6 so that the code base remains consistend.

9 years agoCLEANUP: payload: remove useless and confusing nullity checks for channel buffer
Willy Tarreau [Thu, 10 Mar 2016 15:53:03 +0000 (16:53 +0100)] 
CLEANUP: payload: remove useless and confusing nullity checks for channel buffer

The buffer could not be null by definition since we moved the stream out
of the session. It's the stream which gained the ability to be NULL (hence
the recent fix for this case). The checks in place are useless and make one
think this situation can happen.

9 years agoBUG/MAJOR: vars: always retrieve the stream and session from the sample
Willy Tarreau [Thu, 10 Mar 2016 15:33:04 +0000 (16:33 +0100)] 
BUG/MAJOR: vars: always retrieve the stream and session from the sample

This is the continuation of previous patch called "BUG/MAJOR: samples:
check smp->strm before using it".

It happens that variables may have a session-wide scope, and that their
session is retrieved by dereferencing the stream. But nothing prevents them
from being used from a streamless context such as tcp-request connection,
thus crashing the process. Example :

    tcp-request connection accept if { src,set-var(sess.foo) -m found }

In order to fix this, we have to always ensure that variable manipulation
only happens via the sample, which contains the correct owner and context,
and that we never use one from a different source. This results in quite a
large change since a lot of functions are inderctly involved in the call
chain, but the change is easy to follow.

This fix must be backported to 1.6, and requires the last two patches.

9 years agoMINOR: sample: always set a new sample's owner before evaluating it
Willy Tarreau [Thu, 10 Mar 2016 15:28:58 +0000 (16:28 +0100)] 
MINOR: sample: always set a new sample's owner before evaluating it

Some functions like sample_conv_var2smp(), var_get_byname(), and
var_set_byname() directly or indirectly need to access the current
stream and/or session and must find it in the sample itself and not
as a distinct argument. Thus we first need to call smp_set_owner()
prior to each such calls.

9 years agoMINOR: sample: add a new helper to initialize the owner of a sample
Willy Tarreau [Thu, 10 Mar 2016 15:15:46 +0000 (16:15 +0100)] 
MINOR: sample: add a new helper to initialize the owner of a sample

Since commit 6879ad3 ("MEDIUM: sample: fill the struct sample with the
session, proxy and stream pointers") merged in 1.6-dev2, the sample
contains the pointer to the stream and sample fetch functions as well
as converters use it heavily. This requires from a lot of call places
to initialize 4 fields, and it was even forgotten at a few places.

This patch provides a convenient helper to initialize all these fields
at once, making it easy to prepare a new sample from a previous one for
example.

A few call places were cleaned up to make use of it. It will be needed
by further fixes.

At one place in the Lua code, it was moved earlier because we used to
call sample casts with a non completely initialized sample, which is
not clean eventhough at the moment there are no consequences.

9 years agoBUG/MAJOR: samples: check smp->strm before using it
Willy Tarreau [Thu, 10 Mar 2016 10:47:01 +0000 (11:47 +0100)] 
BUG/MAJOR: samples: check smp->strm before using it

Since commit 6879ad3 ("MEDIUM: sample: fill the struct sample with the
session, proxy and stream pointers") merged in 1.6-dev2, the sample
contains the pointer to the stream and sample fetch functions as well
as converters use it heavily.

The problem is that earlier commit 87b0966 ("REORG/MAJOR: session:
rename the "session" entity to "stream"") had split the session and
stream resulting in the possibility for smp->strm to be NULL before
the stream was initialized. This is what happens in tcp-request
connection rulesets, as discovered by Baptiste.

The sample fetch functions must now check that smp->strm is valid
before using it. An alternative could consist in using a dummy stream
with nothing in it to avoid some checks but it would only result in
deferring them to the next step anyway, and making it harder to detect
that a stream is valid or the dummy one.

There is still an issue with variables which requires a complete
independant fix. They use strm->sess to find the session with strm
possibly NULL and passed as an argument. All call places indirectly
use smp->strm to build strm. So the problem is there but the API needs
to be changed to remove this duplicate argument that makes it much
harder to know what pointer to use.

This fix must be backported to 1.6, as well as the next one fixing
variables.

9 years agoBUG/MINOR: tcpcheck: fix incorrect list usage resulting in failure to load certain...
Willy Tarreau [Tue, 8 Mar 2016 14:20:25 +0000 (15:20 +0100)] 
BUG/MINOR: tcpcheck: fix incorrect list usage resulting in failure to load certain configs

Commit baf9794 ("BUG/MINOR: tcpcheck: conf parsing error when no port
configured on server and first rule(s) is (are) COMMENT") was wrong, it
incorrectly implemented a list access by dereferencing a pointer of an
incorrect type resulting in checking the next element in the list. The
consequence is that it stops before the last comment instead of at the
last one and skips the first rule. In the end, rules starting with
comments are not affected, but if a sequence of checks directly starts
with connect, it is then skipped and this is visible when no port is
configured on the server line as the config refuses to load.

There was another occurence of the same bug a few lines below, both
of them were fixed. Tests were made on different configs and confirm
the new fix is OK.

This fix must be backported to 1.6.

9 years agoCLEANUP: map: Avoid memory leak in out-of-memory condition.
Andreas Seltenreich [Thu, 3 Mar 2016 19:32:23 +0000 (20:32 +0100)] 
CLEANUP: map: Avoid memory leak in out-of-memory condition.

This memory leak of about 100 bytes occurs only if there is an error
condidtion during evaluation of a "map" directive in the configuration
file.  This evaluation only happens once on startup because haproxy
does not have a mechanism for re-loading the configuration file during
run-time.  The startup will be aborted anyway due to error conditions
raised.

Nevertheless fix it to silence warnings of static code analysis tools
and be safe against future revisions of the code.

Found in haproxy 1.5.14.

9 years agoCLEANUP: pattern: Ignore unknown samples in pat_match_ip().
Andreas Seltenreich [Thu, 3 Mar 2016 19:08:35 +0000 (20:08 +0100)] 
CLEANUP: pattern: Ignore unknown samples in pat_match_ip().

Ignore samples that are neither SMP_T_IPV4 nor SMP_T_IPV6 instead of
matching with an uninitialized value in this case.

This situation should not occur in the current codebase but triggers
warnings in static code analysis tools.

Found in haproxy 1.5.

9 years agoCLEANUP: stats: Avoid computation with uninitialized bits.
Andreas Seltenreich [Thu, 3 Mar 2016 18:32:25 +0000 (19:32 +0100)] 
CLEANUP: stats: Avoid computation with uninitialized bits.

stats_map_lookup() sets bit SMP_F_CONST in the uninitialized member
flags of a stack-allocated sample, leaving the other bits
uninitialized.  All code paths that can access the struct only ever
check for this specific flag, so there is no risk of unintended
behavior.

Nevertheless fix it as it triggers warnings in static code analysis
tools and might become a problem on future revisions of the code.

Problem found in version 1.5.

9 years agoBUG/MEDIUM: cfgparse: wrong argument offset after parsing server "sni" keyword
Cyril Bonté [Mon, 7 Mar 2016 21:13:22 +0000 (22:13 +0100)] 
BUG/MEDIUM: cfgparse: wrong argument offset after parsing server "sni" keyword

Owen Marshall reported an issue depending on the server keywords order in the
configuration.

Working line :
  server dev1 <ip>:<port> check inter 5000 ssl verify none sni req.hdr(Host)

Non working line :
  server dev1 <ip>:<port> check inter 5000 ssl sni req.hdr(Host) verify none

Indeed, both parse_server() and srv_parse_sni() modified the current argument
offset at the same time. To fix the issue, srv_parse_sni() can work on a local
copy ot the offset, leaving parse_server() responsible of the actual value.

This fix must be backported to 1.6.

9 years agoMINOR: systemd: ensure a reload doesn't mask a stop
Willy Tarreau [Sat, 27 Feb 2016 07:26:14 +0000 (08:26 +0100)] 
MINOR: systemd: ensure a reload doesn't mask a stop

If a SIGHUP/SIGUSR2 is sent immediately after a SIGTERM/SIGINT and
before wait() is notified, it will mask it since there's no queue,
only a copy of the last received signal. Let's add a special check
before overwriting the signal so that SIGTERM/SIGINT are not masked.

9 years agoBUG/MINOR: systemd: propagate the correct signal to haproxy
Willy Tarreau [Sat, 27 Feb 2016 07:20:17 +0000 (08:20 +0100)] 
BUG/MINOR: systemd: propagate the correct signal to haproxy

Some people report that sometimes there's a collection of old processes
after a restart of the systemd wrapper. It's not surprizing when reading
the code, the SIGTERM is propagated as a SIGINT which asks for a graceful
stop instead. If people ask for termination, we should terminate.

9 years agoBUG/MINOR: systemd: report the correct signal in debug message output
Willy Tarreau [Sat, 27 Feb 2016 07:18:04 +0000 (08:18 +0100)] 
BUG/MINOR: systemd: report the correct signal in debug message output

Commit c54bdd2 ("MINOR: Also accept SIGHUP/SIGTERM in systemd-wrapper")
added support for extra signals but did not adapt the debug message,
which continues to report incorrect signal types. Let's pass the signal
number to the do_restart() and do_shutdown() functions so that the output
matches the signal that was received.

9 years agoBUG/MINOR: systemd: ensure we don't miss signals
Willy Tarreau [Sat, 27 Feb 2016 06:58:50 +0000 (07:58 +0100)] 
BUG/MINOR: systemd: ensure we don't miss signals

There's a race condition in the systemd wrapper. People who restart it
too fast report old processes remaining there. Here if the signal is
caught before entering the "while" loop we block indefinitely on the
wait() call. Let's check the caught signal before calling wait(). It
doesn't completely close the race, a window still exists between the
test of the flag and the call to wait(), but it's much smaller. A
safer solution could involve pselect() to wait for the signal
delivery.

9 years agoBUG/MEDIUM: chunks: always reject negative-length chunks
Willy Tarreau [Thu, 25 Feb 2016 15:15:19 +0000 (16:15 +0100)] 
BUG/MEDIUM: chunks: always reject negative-length chunks

The recent addition of "show env" on the CLI has revealed an interesting
design bug. Chunks are supposed to support a negative length to indicate
that they carry no data. chunk_printf() sets this size to -1 if the string
is too large for the buffer. At a few places in the http engine we may end
up with trash.len = -1. But bi_putchk(), chunk_appendf() and a few other
chunks consumers don't consider this case as possible and will use such a
chunk, possibly restoring an invalid string or trying to copy -1 bytes.

This fix takes care of clarifying the situation in a backportable way
where such sizes are used, so that a negative length indicating an error
remains present until the chunk is reinitialized or overwritten. But a
cleaner design adjustment needs to be done so that there's a clear contract
on how to use these chunks. At first glance it doesn't seem *that* useful
to support negative sizes, so probably this is what should change.

This fix must be backported to 1.6 and 1.5.

9 years agoMINOR: server: generalize the "updater" source
Thierry Fournier [Wed, 24 Feb 2016 07:25:39 +0000 (08:25 +0100)] 
MINOR: server: generalize the "updater" source

the function server_parse_addr_change_request() contain an hardcoded
updater source "stats command". this function can be called from other
sources than the "stats command", so this patch make this argument
generic.

9 years agoCLEANUP: server: add "const" to some message strings
Thierry Fournier [Wed, 24 Feb 2016 07:23:22 +0000 (08:23 +0100)] 
CLEANUP: server: add "const" to some message strings

"updater" is used in "read only" mode, so I add a const qualifier
to the variable declaration.

9 years agoBUG/MINOR: server: fix the format of the warning on address change
Thierry Fournier [Wed, 24 Feb 2016 07:13:13 +0000 (08:13 +0100)] 
BUG/MINOR: server: fix the format of the warning on address change

When the server address is changed, a message with unrequired '\n' or
'.' is displayed, like this:

   [WARNING] 054/101137 (3229) : zzzz/s3 changed its IP from 127.0.0.1 to ::55 by stats command
   .

This patch remove the '\n' which is sent before the '.'.

This patch must be backported in 1.6

9 years agoBUG/MEDIUM: stats: stats bind-process doesn't propagate the process mask correctly
Cyril Bonté [Tue, 23 Feb 2016 23:14:54 +0000 (00:14 +0100)] 
BUG/MEDIUM: stats: stats bind-process doesn't propagate the process mask correctly

With nbproc > 1, it is possible to specify on which process the stats socket
will be bound using "stats bind-process", but the behaviour was not correct,
ignoring the value in some configurations.

Example :
global
  nbproc 4
  stats bind-process 1
  stats socket /var/run/haproxy.sock

With such a configuration, all the processes will listen on the stats socket.
As a workaround, it is also possible to declare a "process" keyword on
the "stats stocket" line.

The patch must be applied to 1.7, 1.6 and 1.5

9 years agoBUG/MINOR: lua: Useless copy
Thierry Fournier [Fri, 19 Feb 2016 17:30:13 +0000 (18:30 +0100)] 
BUG/MINOR: lua: Useless copy

A value is copied two time in teh stack, but only one is usefull. The
second copy leaves unused in the stack and take some room for noting.

This path removes the second copy.

Must be backported in 1.6

9 years agoBUG/MINOR: server: some prototypes are renamed
Thierry Fournier [Mon, 22 Feb 2016 15:08:58 +0000 (16:08 +0100)] 
BUG/MINOR: server: some prototypes are renamed

The commit 87b096 renames the functions srv_shutdown_backup_sessions()
and srv_shutdown_sessions() to srv_shutdown_backup_streams() and
srv_shutdown_streams().

The header file <proto/servers.h> does not repport these changes.

This bug should be repported in the 1.6 branch, even if it is useless
because new dev are frozen.

9 years agoBUG/MAJOR: lua: applets can't sleep.
Thierry Fournier [Sat, 20 Feb 2016 16:47:43 +0000 (17:47 +0100)] 
BUG/MAJOR: lua: applets can't sleep.

This patch must be backported in 1.6

hlua_yield() function returns the required sleep time. The Lua core must
be resume the execution after the required time. The core dedicated to
the http and tcp applet doesn't implement the wake up function. It is a
miss.

This patch fix this.

9 years agoMINOR: mailers: make it possible to configure the connection timeout
Pieter Baauw [Sat, 13 Feb 2016 14:33:40 +0000 (15:33 +0100)] 
MINOR: mailers: make it possible to configure the connection timeout

This patch introduces a configurable connection timeout for mailers
with a new "timeout mail <time>" directive.

Acked-by: Simon Horman <horms@verge.net.au>
9 years agoMEDIUM: dns: add a "resolve-net" option which allow to prefer an ip in a network
Thierry Fournier [Wed, 17 Feb 2016 21:05:30 +0000 (22:05 +0100)] 
MEDIUM: dns: add a "resolve-net" option which allow to prefer an ip in a network

This options prioritize th choice of an ip address matching a network. This is
useful with clouds to prefer a local ip. In some cases, a cloud high
avalailibility service can be announced with many ip addresses on many
differents datacenters. The latency between datacenter is not negligible, so
this patch permitsto prefers a local datacenter. If none address matchs the
configured network, another address is selected.

9 years agoMEDIUM: dns: extract options
Thierry Fournier [Wed, 17 Feb 2016 20:25:09 +0000 (21:25 +0100)] 
MEDIUM: dns: extract options

DNS selection preferences are actually declared inline in the
struct server. There are copied from the server struct to the
dns_resolution struct for each resolution.

Next patchs adds new preferences options, and it is not a good
way to copy all the configuration information before each dns
resolution.

This patch extract the configuration preference from the struct
server and declares a new dedicated struct. Only a pointer to this
new striuict will be copied before each dns resolution.

9 years agoMINOR: common: mask conversion
Thierry Fournier [Wed, 17 Feb 2016 16:12:14 +0000 (17:12 +0100)] 
MINOR: common: mask conversion

Add function which converts network mask from bit length form
to struct in*_addr form.

9 years agoDOC: lua: copyrights
Thierry Fournier [Thu, 11 Feb 2016 16:57:57 +0000 (17:57 +0100)] 
DOC: lua: copyrights

9 years agoBUG/MAJOR: lua: segfault using Concat object
Thierry Fournier [Fri, 19 Feb 2016 11:09:29 +0000 (12:09 +0100)] 
BUG/MAJOR: lua: segfault using Concat object

Concat object is based on "luaL_Buffer". The luaL_Buffer documentation says:

   During its normal operation, a string buffer uses a variable number of stack
   slots. So, while using a buffer, you cannot assume that you know where the
   top of the stack is. You can use the stack between successive calls to buffer
   operations as long as that use is balanced; that is, when you call a buffer
   operation, the stack is at the same level it was immediately after the
   previous buffer operation. (The only exception to this rule is
   luaL_addvalue.) After calling luaL_pushresult the stack is back to its level
   when the buffer was initialized, plus the final string on its top.

So, the stack cannot be manipulated between the first call at the function
"luaL_buffinit()" and the last call to the function "luaL_pushresult()" because
we cannot known the stack status.

In other way, the memory used by these functions seems to be collected by GC, so
if the GC is triggered during the usage of the Concat object, it can be used
some released memory.

This patch rewrite the Concat class without the "luaL_Buffer" system. It uses
"userdata()" forr the memory allocation of the buffer strings.

9 years agoMINOR: mailers: use <CRLF> for all line endings
Pieter Baauw [Sat, 13 Feb 2016 15:27:35 +0000 (16:27 +0100)] 
MINOR: mailers: use <CRLF> for all line endings

Not doing so causes issues with Exchange2013 not processing the message
body from the email. Specification seems to specify that as correct
behavior : https://www.ietf.org/rfc/rfc2821.txt # 2.3.7 Lines

 > SMTP client implementations MUST NOT transmit "bare" "CR" or "LF" characters.

This patch should be backported to 1.6.

Acked-by: Simon Horman <horms@verge.net.au>
9 years agoMINOR: mailers: increase default timeout to 10 seconds
Pieter Baauw [Fri, 12 Feb 2016 13:35:20 +0000 (14:35 +0100)] 
MINOR: mailers: increase default timeout to 10 seconds

This allows the tcp connection to send multiple SYN packets, so 1 lost
packet does not cause the mail to be lost. It changes the socket timeout
from 2 to 10 seconds, this allows for 3 syn packets to be send and
waiting a little for their reply.

This patch should be backported to 1.6.

Acked-by: Simon Horman <horms@verge.net.au>
9 years agoMEDIUM: cfgparse: reject incorrect 'timeout retry' keyword spelling in resolvers
Pieter Baauw [Sat, 13 Feb 2016 14:51:58 +0000 (15:51 +0100)] 
MEDIUM: cfgparse: reject incorrect 'timeout retry' keyword spelling in resolvers

If for example it was written as 'timeout retri 1s' or 'timeout wrong 1s'
this would be used for the retry timeout value. Resolvers section only
timeout setting currently is 'retry', others are still parsed as before
this patch to not break existing configurations.

A less strict version will be backported to 1.6.

9 years agoMEDIUM: config: allow to manipulate environment variables in the global section
Willy Tarreau [Tue, 16 Feb 2016 11:41:57 +0000 (12:41 +0100)] 
MEDIUM: config: allow to manipulate environment variables in the global section

With new init systems such as systemd, environment variables became a
real mess because they're only considered on startup but not on reload
since the init script's variables cannot be passed to the process that
is signaled to reload.

This commit introduces an alternative method consisting in making it
possible to modify the environment from the global section with directives
like "setenv", "unsetenv", "presetenv" and "resetenv".

Since haproxy supports loading multiple config files, it now becomes
possible to put the host-dependant variables in one file and to
distribute the rest of the configuration to all nodes, without having
to deal with the init system's deficiencies.

Environment changes take effect immediately when the directives are
processed, so it's possible to do perform the same operations as are
usually performed in regular service config files.

9 years agoMINOR: cli: add a new "show env" command
Willy Tarreau [Tue, 16 Feb 2016 10:27:28 +0000 (11:27 +0100)] 
MINOR: cli: add a new "show env" command

Using environment variables in configuration files can make troubleshooting
complicated because there's no easy way to verify that the variables are
correct. This patch introduces a new "show env" command which displays the
whole environment on the CLI, one variable per line.

The socket must at least have level operator to display the environment.

9 years agoDOC: LUA: fix some typos and syntax errors
Godbach [Tue, 16 Feb 2016 03:59:17 +0000 (11:59 +0800)] 
DOC: LUA: fix some typos and syntax errors

This fix must be backported to 1.6.

Signed-off-by: Godbach <nylzhaowei@gmail.com>
9 years agoBUG/MEDIUM: ssl: fix off-by-one in NPN list allocation
Willy Tarreau [Fri, 12 Feb 2016 16:11:12 +0000 (17:11 +0100)] 
BUG/MEDIUM: ssl: fix off-by-one in NPN list allocation

After seeing previous ALPN fix, I suspected that NPN code was wrong
as well, and indeed it was since ALPN was copied from it. This fix
must be backported into 1.6 and 1.5.

9 years agoBUG/MEDIUM: ssl: fix off-by-one in ALPN list allocation
Marcoen Hirschberg [Fri, 12 Feb 2016 16:05:24 +0000 (17:05 +0100)] 
BUG/MEDIUM: ssl: fix off-by-one in ALPN list allocation

The first time I tried it (1.6.3) I got a segmentation fault :(

After some investigation with gdb and valgrind I found the
problem. memcpy() copies past an allocated buffer in
"bind_parse_alpn". This patch fixes it.

[wt: this fix must be backported into 1.6 and 1.5]

9 years agoDOC: add server name at rate-limit sessions example
Panagiotis Panagiotopoulos [Thu, 11 Feb 2016 14:37:15 +0000 (16:37 +0200)] 
DOC: add server name at rate-limit sessions example

9 years agoMEDIUM: log: add a new log format flag "E"
Dragan Dosen [Fri, 12 Feb 2016 12:23:03 +0000 (13:23 +0100)] 
MEDIUM: log: add a new log format flag "E"

The +E mode escapes characters '"', '\' and ']' with '\' as prefix. It
mostly makes sense to use it in the RFC5424 structured-data log formats.

Example:

log-format-sd %{+Q,+E}o\ [exampleSDID@1234\ header=%[capture.req.hdr(0)]]

9 years agoMINOR: standard: add function "escape_chunk"
Dragan Dosen [Fri, 12 Feb 2016 12:23:02 +0000 (13:23 +0100)] 
MINOR: standard: add function "escape_chunk"

This function tries to prefix all characters tagged in the <map> with the
<escape> character. The specified <chunk> contains the input to be
escaped.

9 years agoMINOR: lua: Add concat class
Thierry Fournier [Wed, 27 Jan 2016 08:49:07 +0000 (09:49 +0100)] 
MINOR: lua: Add concat class

This patch adds the Concat class. This class provides a fast
way for the string concatenation.

9 years agoMINOR: lua: merge function
Thierry Fournier [Wed, 27 Jan 2016 09:34:09 +0000 (10:34 +0100)] 
MINOR: lua: merge function

This patch merges the last imported functions in one, because
the function hlua_metatype is only used by hlua_checudata.
This patch fix also the compilation error became by the
copy of the code.

9 years agoMINOR: lua: move common function
Thierry Fournier [Wed, 27 Jan 2016 08:55:30 +0000 (09:55 +0100)] 
MINOR: lua: move common function

This patch moves the function hlua_checkudata which check that
an object contains the expected class_reference as metatable.
This function is commonly used by all the lua functions.
The function hlua_metatype is also moved.

9 years agoMINOR: lua: Add date functions
Thierry Fournier [Thu, 21 Jan 2016 08:35:41 +0000 (09:35 +0100)] 
MINOR: lua: Add date functions

This patch add date parsing function in Lua API. These function
are usefull for parsing standard HTTP date provided in headers.

9 years agoMINOR: standard: add RFC HTTP date parser
Thierry Fournier [Wed, 20 Jan 2016 17:49:45 +0000 (18:49 +0100)] 
MINOR: standard: add RFC HTTP date parser

This parser takes a string containing an HTTP date. It returns
a broken-down time struct. We must considers considers this
time as GMT. Maybe later the timezone will be taken in account.

9 years agoMINOR: lua: add "now" time function
Thierry Fournier [Thu, 21 Jan 2016 08:46:15 +0000 (09:46 +0100)] 
MINOR: lua: add "now" time function

This function returns the current time in the Lua.

9 years agoMINOR: lua: file dedicated to unsafe functions
Thierry Fournier [Thu, 21 Jan 2016 08:28:58 +0000 (09:28 +0100)] 
MINOR: lua: file dedicated to unsafe functions

When Lua executes functions from its API, these can throws an error.
These function must be executed in a special environment which catch
these error, otherwise a critical error (like segfault) can raise.

This patch add a c file called "hlua_fcn.c" which collect all the
Lua/c function needing safe environment for its execution.

9 years agoDOC: lua: fix somme errors
Thierry FOURNIER [Fri, 25 Dec 2015 01:05:25 +0000 (02:05 +0100)] 
DOC: lua: fix somme errors

This patch fix some errors in the class TXN doc.

Should be backported in 1.6

9 years agoBUG/MINOR: lua: unsafe initialization
Thierry Fournier [Thu, 21 Jan 2016 08:30:18 +0000 (09:30 +0100)] 
BUG/MINOR: lua: unsafe initialization

During the Lua HAProxy initialisation, C functions using Lua calls
can throws an error. This error was not catched. This patch fix
this behaviour.

9 years agoMINOR: map: Add regex matching replacement
Thierry Fournier [Wed, 10 Feb 2016 21:55:20 +0000 (22:55 +0100)] 
MINOR: map: Add regex matching replacement

This patch declares a new map which provides a string based on
a string with back references replaced by the content matched
by the regex.

9 years agoMINOR: filters: Extract proxy stuff from the struct filter
Christopher Faulet [Thu, 4 Feb 2016 12:40:26 +0000 (13:40 +0100)] 
MINOR: filters: Extract proxy stuff from the struct filter

Now, filter's configuration (.id, .conf and .ops fields) is stored in the
structure 'flt_conf'. So proxies own a flt_conf list instead of a filter
list. When a filter is attached to a stream, it gets a pointer on its
configuration. This avoids mixing the filter's context (owns by a stream) and
its configuration (owns by a proxy). It also saves 2 pointers per filter
instance.

9 years agoMINOR: filters: Add an filter example
Christopher Faulet [Wed, 2 Sep 2015 15:15:16 +0000 (17:15 +0200)] 
MINOR: filters: Add an filter example

The "trace" filter has been added. It defines all available callbacks and for
each one it prints a trace message. To enable it:

  listener test
      ...
      filter trace
      ...

9 years agoMINOR: filters/http: Forward remaining data when a channel has no "data" filters
Christopher Faulet [Tue, 15 Dec 2015 09:41:47 +0000 (10:41 +0100)] 
MINOR: filters/http: Forward remaining data when a channel has no "data" filters

This is an improvement, especially when the message body is big. Before this
patch, remaining data were forwarded when there is no filter on the stream. Now,
the forwarding is triggered when there is no "data" filter on the channel. When
no filter is used, there is no difference, but when at least one filter is used,
it can be really significative.

9 years agoMINOR: filters/http: Slightly update the parsing of chunks
Christopher Faulet [Mon, 14 Dec 2015 13:52:13 +0000 (14:52 +0100)] 
MINOR: filters/http: Slightly update the parsing of chunks

Now, http_parse_chunk_size and http_skip_chunk_crlf return the number of bytes
parsed on success. http_skip_chunk_crlf does not use msg->sol anymore.

On the other hand, http_forward_trailers is unchanged. It returns >0 if the end
of trailers is reached and 0 if not. In all cases (except if an error is
encountered), msg->sol contains the length of the last parsed part of the
trailer headers.

Internal doc and comments about msg->sol has been updated accordingly.

9 years agoMEDIUM: filters: Optimize the HTTP compression for chunk encoded response
Christopher Faulet [Mon, 7 Dec 2015 15:48:42 +0000 (16:48 +0100)] 
MEDIUM: filters: Optimize the HTTP compression for chunk encoded response

Instead of compressing all chunks as they come, we store them in a temporary
buffer. The compression happens during the forwarding phase. This change speeds
up the compression of chunked response.

9 years agoMINOR: filters: Remove unused or useless stuff and do small optimizations
Christopher Faulet [Mon, 7 Dec 2015 12:39:08 +0000 (13:39 +0100)] 
MINOR: filters: Remove unused or useless stuff and do small optimizations

9 years agoMAJOR: filters: Require explicit registration to filter HTTP body and TCP data
Christopher Faulet [Fri, 4 Dec 2015 08:25:05 +0000 (09:25 +0100)] 
MAJOR: filters: Require explicit registration to filter HTTP body and TCP data

Before, functions to filter HTTP body (and TCP data) were called from the moment
at least one filter was attached to the stream. If no filter is interested by
these data, this uselessly slows data parsing.
A good example is the HTTP compression filter. Depending of request and response
headers, the response compression can be enabled or not. So it could be really
nice to call it only when enabled.

So, now, to filter HTTP/TCP data, a filter must use the function
register_data_filter. For TCP streams, this function can be called only
once. But for HTTP streams, when needed, it must be called for each HTTP request
or HTTP response.
Only registered filters will be called during data parsing. At any time, a
filter can be unregistered by calling the function unregister_data_filter.

9 years agoMINOR: filters: Add stream_filters structure to hide filters info
Christopher Faulet [Thu, 3 Dec 2015 10:48:03 +0000 (11:48 +0100)] 
MINOR: filters: Add stream_filters structure to hide filters info

From the stream point of view, this new structure is opaque. it hides filters
implementation details. So, impact for future optimizations will be reduced
(well, we hope so...).

Some small improvements has been made in filters.c to avoid useless checks.

9 years agoMEDIUM: filters/http: Move body parsing of HTTP messages in dedicated functions
Christopher Faulet [Wed, 2 Dec 2015 09:01:17 +0000 (10:01 +0100)] 
MEDIUM: filters/http: Move body parsing of HTTP messages in dedicated functions

Now body parsing is done in http_msg_forward_body and
http_msg_forward_chunked_body functions, regardless of whether we parse a
request or a response.
Parsing result is still handled in http_request_forward_body and
http_response_forward_body functions.

This patch will ease futur optimizations, mainly on filters.

9 years agoMEDIUM: filters: Replace filter_http_headers callback by an analyzer
Christopher Faulet [Wed, 2 Dec 2015 08:57:32 +0000 (09:57 +0100)] 
MEDIUM: filters: Replace filter_http_headers callback by an analyzer

This new analyzer will be called for each HTTP request/response, before the
parsing of the body. It is identified by AN_FLT_HTTP_HDRS.

Special care was taken about the following condition :

  * the frontend is a TCP proxy
  * filters are defined in the frontend section
  * the selected backend is a HTTP proxy

So, this patch explicitly add AN_FLT_HTTP_HDRS analyzer on the request and the
response channels when the backend is a HTTP proxy and when there are filters
attatched on the stream.
This patch simplifies http_request_forward_body and http_response_forward_body
functions.

9 years agoMEDIUM: filters: remove http_start_chunk, http_last_chunk and http_chunk_end
Christopher Faulet [Tue, 1 Dec 2015 09:40:57 +0000 (10:40 +0100)] 
MEDIUM: filters: remove http_start_chunk, http_last_chunk and http_chunk_end

For Chunked HTTP request/response, the body filtering can be really
expensive. In the worse case (many chunks of 1 bytes), the filters overhead is
of 3 calls per chunk. If http_data callback is useful, others are just
informative.

So these callbacks has been removed. Of course, existing filters (trace and
compression) has beeen updated accordingly. For the HTTP compression filter, the
update is quite huge. Its implementation is closer to the old one.

9 years agoMEDIUM: filters: Use macros to call filters callbacks to speed-up processing
Christopher Faulet [Tue, 24 Nov 2015 15:24:13 +0000 (16:24 +0100)] 
MEDIUM: filters: Use macros to call filters callbacks to speed-up processing

When no filter is attached to the stream, the CPU footprint due to the calls to
filters_* functions is huge, especially for chunk-encoded messages. Using macros
to check if we have some filters or not is a great improvement.

Furthermore, instead of checking the filter list emptiness, we introduce a flag
to know if filters are attached or not to a stream.

9 years agoMAJOR: filters/http: Rewrite the HTTP compression as a filter
Christopher Faulet [Thu, 5 Nov 2015 12:35:03 +0000 (13:35 +0100)] 
MAJOR: filters/http: Rewrite the HTTP compression as a filter

HTTP compression has been rewritten to use the filter API. This is more a PoC
than other thing for now. It allocates memory to work. So, if only for that, it
should be rewritten.

In the mean time, the implementation has been refactored to allow its use with
other filters. However, there are limitations that should be respected:

  - No filter placed after the compression one is allowed to change input data
    (in 'http_data' callback).
  - No filter placed before the compression one is allowed to change forwarded
    data (in 'http_forward_data' callback).

For now, these limitations are informal, so you should be careful when you use
several filters.

About the configuration, 'compression' keywords are still supported and must be
used to configure the HTTP compression behavior. In absence of a 'filter' line
for the compression filter, it is added in the filter chain when the first
compression' line is parsed. This is an easy way to do when you do not use other
filters. But another filter exists, an error is reported so that the user must
explicitly declare the filter.

For example:

  listen tst
      ...
      compression algo gzip
      compression offload
      ...
      filter flt_1
      filter compression
      filter flt_2
      ...

9 years agoREORG: filters: Prepare creation of the HTTP compression filter
Christopher Faulet [Wed, 9 Dec 2015 13:59:38 +0000 (14:59 +0100)] 
REORG: filters: Prepare creation of the HTTP compression filter

HTTP compression will be moved in a true filter. To prepare the ground, some
functions have been moved in a dedicated file. Idea is to keep everything about
compression algos in compression.c and everything related to the filtering in
flt_http_comp.c.

For now, a header has been added to help during the transition. It will be
removed later.

Unused empty ACL keyword list was removed. The "compression" keyword
parser was moved from cfgparse.c to flt_http_comp.c.

9 years agoMINOR: filters: Do not reset stream analyzers if the client is gone
Christopher Faulet [Tue, 22 Dec 2015 11:01:29 +0000 (12:01 +0100)] 
MINOR: filters: Do not reset stream analyzers if the client is gone

When all callbacks have been called for all filters registered on a stream, if
we are waiting for the next HTTP request, we must reset stream analyzers. But it
is useless to do so if the client has already closed the connection.

9 years agoMAJOR: filters: Add filters support
Christopher Faulet [Thu, 30 Apr 2015 09:48:27 +0000 (11:48 +0200)] 
MAJOR: filters: Add filters support

This patch adds the support of filters in HAProxy. The main idea is to have a
way to "easely" extend HAProxy by adding some "modules", called filters, that
will be able to change HAProxy behavior in a programmatic way.

To do so, many entry points has been added in code to let filters to hook up to
different steps of the processing. A filter must define a flt_ops sutrctures
(see include/types/filters.h for details). This structure contains all available
callbacks that a filter can define:

struct flt_ops {
       /*
        * Callbacks to manage the filter lifecycle
        */
       int  (*init)  (struct proxy *p);
       void (*deinit)(struct proxy *p);
       int  (*check) (struct proxy *p);

        /*
         * Stream callbacks
         */
        void (*stream_start)     (struct stream *s);
        void (*stream_accept)    (struct stream *s);
        void (*session_establish)(struct stream *s);
        void (*stream_stop)      (struct stream *s);

       /*
        * HTTP callbacks
        */
       int  (*http_start)         (struct stream *s, struct http_msg *msg);
       int  (*http_start_body)    (struct stream *s, struct http_msg *msg);
       int  (*http_start_chunk)   (struct stream *s, struct http_msg *msg);
       int  (*http_data)          (struct stream *s, struct http_msg *msg);
       int  (*http_last_chunk)    (struct stream *s, struct http_msg *msg);
       int  (*http_end_chunk)     (struct stream *s, struct http_msg *msg);
       int  (*http_chunk_trailers)(struct stream *s, struct http_msg *msg);
       int  (*http_end_body)      (struct stream *s, struct http_msg *msg);
       void (*http_end)           (struct stream *s, struct http_msg *msg);
       void (*http_reset)         (struct stream *s, struct http_msg *msg);
       int  (*http_pre_process)   (struct stream *s, struct http_msg *msg);
       int  (*http_post_process)  (struct stream *s, struct http_msg *msg);
       void (*http_reply)         (struct stream *s, short status,
                                   const struct chunk *msg);
};

To declare and use a filter, in the configuration, the "filter" keyword must be
used in a listener/frontend section:

  frontend test
    ...
    filter <FILTER-NAME> [OPTIONS...]

The filter referenced by the <FILTER-NAME> must declare a configuration parser
on its own name to fill flt_ops and filter_conf field in the proxy's
structure. An exemple will be provided later to make it perfectly clear.

For now, filters cannot be used in backend section. But this is only a matter of
time. Documentation will also be added later. This is the first commit of a long
list about filters.

It is possible to have several filters on the same listener/frontend. These
filters are stored in an array of at most MAX_FILTERS elements (define in
include/types/filters.h). Again, this will be replaced later by a list of
filters.

The filter API has been highly refactored. Main changes are:

* Now, HA supports an infinite number of filters per proxy. To do so, filters
  are stored in list.

* Because filters are stored in list, filters state has been moved from the
  channel structure to the filter structure. This is cleaner because there is no
  more info about filters in channel structure.

* It is possible to defined filters on backends only. For such filters,
  stream_start/stream_stop callbacks are not called. Of course, it is possible
  to mix frontend and backend filters.

* Now, TCP streams are also filtered. All callbacks without the 'http_' prefix
  are called for all kind of streams. In addition, 2 new callbacks were added to
  filter data exchanged through a TCP stream:

    - tcp_data: it is called when new data are available or when old unprocessed
      data are still waiting.

    - tcp_forward_data: it is called when some data can be consumed.

* New callbacks attached to channel were added:

    - channel_start_analyze: it is called when a filter is ready to process data
      exchanged through a channel. 2 new analyzers (a frontend and a backend)
      are attached to channels to call this callback. For a frontend filter, it
      is called before any other analyzer. For a backend filter, it is called
      when a backend is attached to a stream. So some processing cannot be
      filtered in that case.

    - channel_analyze: it is called before each analyzer attached to a channel,
      expects analyzers responsible for data sending.

    - channel_end_analyze: it is called when all other analyzers have finished
      their processing. A new analyzers is attached to channels to call this
      callback. For a TCP stream, this is always the last one called. For a HTTP
      one, the callback is called when a request/response ends, so it is called
      one time for each request/response.

* 'session_established' callback has been removed. Everything that is done in
  this callback can be handled by 'channel_start_analyze' on the response
  channel.

* 'http_pre_process' and 'http_post_process' callbacks have been replaced by
  'channel_analyze'.

* 'http_start' callback has been replaced by 'http_headers'. This new one is
  called just before headers sending and parsing of the body.

* 'http_end' callback has been replaced by 'channel_end_analyze'.

* It is possible to set a forwarder for TCP channels. It was already possible to
  do it for HTTP ones.

* Forwarders can partially consumed forwardable data. For this reason a new
  HTTP message state was added before HTTP_MSG_DONE : HTTP_MSG_ENDING.

Now all filters can define corresponding callbacks (http_forward_data
and tcp_forward_data). Each filter owns 2 offsets relative to buf->p, next and
forward, to track, respectively, input data already parsed but not forwarded yet
by the filter and parsed data considered as forwarded by the filter. A any time,
we have the warranty that a filter cannot parse or forward more input than
previous ones. And, of course, it cannot forward more input than it has
parsed. 2 macros has been added to retrieve these offets: FLT_NXT and FLT_FWD.

In addition, 2 functions has been added to change the 'next size' and the
'forward size' of a filter. When a filter parses input data, it can alter these
data, so the size of these data can vary. This action has an effet on all
previous filters that must be handled. To do so, the function
'filter_change_next_size' must be called, passing the size variation. In the
same spirit, if a filter alter forwarded data, it must call the function
'filter_change_forward_size'. 'filter_change_next_size' can be called in
'http_data' and 'tcp_data' callbacks and only these ones. And
'filter_change_forward_size' can be called in 'http_forward_data' and
'tcp_forward_data' callbacks and only these ones. The data changes are the
filter responsability, but with some limitation. It must not change already
parsed/forwarded data or data that previous filters have not parsed/forwarded
yet.

Because filters can be used on backends, when we the backend is set for a
stream, we add filters defined for this backend in the filter list of the
stream. But we must only do that when the backend and the frontend of the stream
are not the same. Else same filters are added a second time leading to undefined
behavior.

The HTTP compression code had to be moved.

So it simplifies http_response_forward_body function. To do so, the way the data
are forwarded has changed. Now, a filter (and only one) can forward data. In a
commit to come, this limitation will be removed to let all filters take part to
data forwarding. There are 2 new functions that filters should use to deal with
this feature:

 * flt_set_http_data_forwarder: This function sets the filter (using its id)
   that will forward data for the specified HTTP message. It is possible if it
   was not already set by another filter _AND_ if no data was yet forwarded
   (msg->msg_state <= HTTP_MSG_BODY). It returns -1 if an error occurs.

 * flt_http_data_forwarder: This function returns the filter id that will
   forward data for the specified HTTP message. If there is no forwarder set, it
   returns -1.

When an HTTP data forwarder is set for the response, the HTTP compression is
disabled. Of course, this is not definitive.

9 years agoBUG/MINOR: stats: fix missing comma in stats on agent drain
Raghu Udiyar [Fri, 5 Feb 2016 17:00:11 +0000 (22:30 +0530)] 
BUG/MINOR: stats: fix missing comma in stats on agent drain

The csv stats format breaks when agent changes server state to drain.
Tools like hatop, metric or check agents will fail due to this. This
should be backported to 1.6.