Commit Graph

595 Commits

Author SHA1 Message Date
Christopher Faulet
6ad7df423b MINOR: arg: Use chunk_destroy() to release string arguments
This way, all fields of the buffer structure are reset when a string argument
(ARGT_STR) is released.  It is also a good way to explicitly specify this kind
of argument is a chunk. So .data and .size fields must be set.

This patch may be backported to ease backports.
2020-08-07 14:27:54 +02:00
Christopher Faulet
fd2e906084 MINOR: lua: Add support for regex as fetches and converters arguments
It means now regsub() converter is now exported to the lua. Map converters based
on regex are not available because the map arguments are not supported.
2020-08-07 14:27:54 +02:00
Christopher Faulet
d25d926806 MINOR: lua: Add support for userlist as fetches and converters arguments
It means now http_auth() and http_auth_group() sample fetches are now exported
to the lua.
2020-08-07 14:27:54 +02:00
Christopher Faulet
05e2d77441 MEDIUM: lua: Don't filter exported fetches and converters
Thanks to previous commits, it is now safe to use from lua the sample fetches
and sample converters that convert arguments, especially the strings
(ARGT_STR). So now, there are all exported to the lua. They was filtered on the
validation functions. Only fetches without validation functions or with val_hdr
or val_payload_lv functions were exported, and converters without validation
functions.

This patch depends on following commits :

  * aec27ef44 "BUG/MINOR: lua: Duplicate lua strings in sample fetches/converters arg array"
  * fdea1b631 "MINOR: hlua: Don't needlessly copy lua strings in trash during args validation"

It must be backported as far as 2.1 because the date() and http_date()
converters are no longer exported because of the filter on the validation
function, since the commit ae6f125c7 ("MINOR: sample: add us/ms support to
date/http_date)".
2020-08-07 14:27:37 +02:00
Christopher Faulet
aec27ef443 BUG/MINOR: lua: Duplicate lua strings in sample fetches/converters arg array
Strings in the argument array used by sample fetches and converters must be
duplicated. This is mandatory because, during the arguments validations, these
strings may be converted and released. It works this way during the
configuration parsing and there is no reason to adapt this behavior during the
runtime when a sample fetch or a sample converter is called from the lua. In
fact, there is a reason to not change the behavior. It must reamain simple for
everyone to add new fetches or converters.

Thus, lua strings are duplicated. It is only performed at the end of the
hlua_lua2arg_check() function, if the argument is still a ARGT_STR. Of course,
it requires a cleanup loop after the call or when an error is triggered.

This patch depends on following commits:

  * 959171376 "BUG/MINOR: arg: Fix leaks during arguments validation for fetches/converters"
  * fdea1b631 "MINOR: hlua: Don't needlessly copy lua strings in trash during args validation"

It may be backported to all supported versions, most probably as far as 2.1
only.
2020-08-07 14:26:35 +02:00
Christopher Faulet
fdea1b6319 MINOR: hlua: Don't needlessly copy lua strings in trash during args validation
Lua strings are NULL terminated. So in the hlua_lua2arg_check() function, used
to check arguments against the sample fetches specification, there is no reason
to copy these strings in a trash to add a terminating null byte.

In addition, when the array of arguments is built from lua values, we must take
care to count this terminating null bytes in the size of the buffer where a
string is stored. The same must be done when a sample is built from a lua value.

This patch may be backported to easy backports.
2020-08-07 14:25:31 +02:00
Christopher Faulet
e663a6e326 BUG/MINOR: lua: Check argument type to convert it to IP mask in arg validation
In hlua_lua2arg_check() function, before converting an argument to an IPv4 or
IPv6 mask, we must be sure to have an integer or a string argument (ARGT_SINT or
ARGT_STR).

This patch must be backported to all supported versions.
2020-08-07 14:25:31 +02:00
Christopher Faulet
8e09ac8592 BUG/MINOR: lua: Check argument type to convert it to IPv4/IPv6 arg validation
In hlua_lua2arg_check() function, before converting a string to an IP address,
we must be to sure to have a string argument (ARGT_STR).

This patch must be backported to all supported versions.
2020-08-07 14:25:31 +02:00
Christopher Faulet
73292e9e66 BUG/MINOR: lua: Duplicate map name to load it when a new Map object is created
When a new map is created, the sample_load_map() function is called. To do so,
an argument array is created with the name as first argument. Because it is a
lua string, owned by the lua, it must be duplicated. The sample_load_map()
function will convert this argument to a map. In theory, after the conversion,
it must release the original string. It is not performed for now and it is a bug
that will be fixed in the next commit.

This patch may be backported to all supported versions, most probably as far as
2.1 only. But it must be backported with the next commit "BUG/MINOR: arg: Fix
leaks during arguments validation for fetches/converters".
2020-08-07 14:24:30 +02:00
Christopher Faulet
2361fd9487 BUG/MINOR: lua: Fix a possible null pointer deref on lua ctx
This bug was introduced by the commit 8f587ea3 ("MEDIUM: lua: Set the analyse
expiration date with smaller wake_time only"). At the end of hlua_action(), the
lua context may be null if the alloc failed.

No backport needed, this is 2.3-dev.
2020-07-30 10:40:59 +02:00
Christopher Faulet
8f587ea347 MEDIUM: lua: Set the analyse expiration date with smaller wake_time only
If a lua action yields for any reason and if the wake timeout is set, it only
override the analyse expiration date if it is smaller. This way, a lower
inspect-delay will be respected, if any.
2020-07-30 09:31:09 +02:00
Christopher Faulet
498c483009 BUG/MINOR: lua: Abort execution of actions that yield on a final evaluation
A Lua action may yield. It may happen because the action returns explicitly
act.YIELD or because the script itself yield. In the first case, we must abort
the script execution if it is the final rule evaluation, i.e if the
ACT_OPT_FINAL flag is set. The second case is already covered.

This patch must be backported to 2.2.
2020-07-30 09:31:09 +02:00
Christopher Faulet
08ed98fd79 MEDIUM: lua: Add support for the Lua 5.4
On Lua 5.4, some API changes make HAProxy compilation to fail. Among other
things, the lua_resume() function has changed and now takes an extra argument in
Lua 5.4 and the error LUA_ERRGCMM was removed. Thus the LUA_VERSION_NUM macro is
now tested to know the lua version is used and adapt the code accordingly.

Here are listed the incompatibilities with the previous Lua versions :

   http://www.lua.org/manual/5.4/manual.html#8

This patch comes from the HAproxy's fedora RPM, committed by Tom Callaway :

  https://src.fedoraproject.org/rpms/haproxy/blob/db970613/f/haproxy-2.2.0-lua-5.4.patch

This patch should fix the issue #730. It must be backported to 2.2 and probably
as far as 2.0.
2020-07-30 09:31:09 +02:00
Willy Tarreau
f1ea47d896 BUG/MINOR: htx: add two missing HTX_FL_EOI and remove an unexpected one
A workaround for some difficulties encountered to anticipate end of
messages was addressed by commit 810df0614 ("MEDIUM: htx: Add a flag on
a HTX message when no more data are expected"), but there were 3 issues
in it (with minor impact):
  - the flag was mistakenly set before an EOH in Lua, which would only
    cause incomplete packets to be emitted for now but could cause
    truncated responses in the future. It's not needed to add it on
    the next EOM block as http_forward_proxy_resp() already does it.

  - one was still missing in hlua_applet_http_fct(), possibly causing
    delays on Lua services

  - one was missing in the Prometheus exporter.

All this simply shows that this mechanism is still quite fragile and
not trivial to use, especially in order to deal with the impossibility
to append the EOM, so we'll need to improve the solution in the future
and future backports should not be completely ruled out.

This fix must be backported where the patch above is backported,
typically 2.1 and later as it was required for a set of fixes.
2020-07-23 06:53:27 +02:00
Christopher Faulet
810df06145 MEDIUM: htx: Add a flag on a HTX message when no more data are expected
The HTX_FL_EOI flag must now be set on a HTX message when no more data are
expected. Most of time, it must be set before adding the EOM block. Thus, if
there is no space for the EOM, there is still an information to know all data
were received and pushed in the HTX message. There is only an exception for the
HTTP replies (deny, return...). For these messages, the flag is set after all
blocks are pushed in the message, including the EOM block, because, on error,
we remove all inserted data.
2020-07-22 16:43:32 +02:00
Tim Duesterhus
d0c0ca2720 CLEANUP: Add static void hlua_deinit()
Compiling HAProxy with USE_LUA=1 and running a configuration check within
valgrind with a very simple configuration such as:

    listen foo
    	bind *:8080

Will report quite a few possible leaks afterwards:

    ==24048== LEAK SUMMARY:
    ==24048==    definitely lost: 0 bytes in 0 blocks
    ==24048==    indirectly lost: 0 bytes in 0 blocks
    ==24048==      possibly lost: 95,513 bytes in 1,209 blocks
    ==24048==    still reachable: 329,960 bytes in 71 blocks
    ==24048==         suppressed: 0 bytes in 0 blocks

Printing these possible leaks shows that all of them are caused by Lua.
Luckily Lua makes it *very* easy to free all used memory, so let's do
this on shutdown.

Afterwards this patch is applied the output looks much better:

    ==24199== LEAK SUMMARY:
    ==24199==    definitely lost: 0 bytes in 0 blocks
    ==24199==    indirectly lost: 0 bytes in 0 blocks
    ==24199==      possibly lost: 0 bytes in 0 blocks
    ==24199==    still reachable: 329,960 bytes in 71 blocks
    ==24199==         suppressed: 0 bytes in 0 blocks
2020-07-07 16:52:35 +02:00
Ilya Shipitsin
46a030cdda CLEANUP: assorted typo fixes in the code and comments
This is 11th iteration of typo fixes
2020-07-06 14:34:32 +02:00
Tim Duesterhus
588b3148d9 BUILD: Re-enable -Wimplicit-fallthrough
Getting rid of this warning is cleaner solved using a 'fall through' comment,
because it clarifies intent to a human reader.

This patch adjust a few places that cause -Wimplicit-fallthrough to trigger:

- Fix typos in the comment.
- Remove redundant 'no break' that trips up gcc from comment.
- Move the comment out of the block when the 'case' is completely surrounded
  by braces.
- Add comments where I could determine that the fall through was intentional.

Changes tested on

    gcc (Debian 9.3.0-13) 9.3.0
    Copyright (C) 2019 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

using

    make -j4 all TARGET=linux-glibc USE_OPENSSL=1 USE_LUA=1 USE_ZLIB=1 USE_PCRE2=1 USE_PCRE2_JIT=1 USE_GETADDRINFO=1
2020-06-11 16:49:37 +02:00
Willy Tarreau
b2551057af CLEANUP: include: tree-wide alphabetical sort of include files
This patch fixes all the leftovers from the include cleanup campaign. There
were not that many (~400 entries in ~150 files) but it was definitely worth
doing it as it revealed a few duplicates.
2020-06-11 10:18:59 +02:00
Willy Tarreau
36979d9ad5 REORG: include: move the error reporting functions to from log.h to errors.h
Most of the files dealing with error reports have to include log.h in order
to access ha_alert(), ha_warning() etc. But while these functions don't
depend on anything, log.h depends on a lot of stuff because it deals with
log-formats and samples. As a result it's impossible not to embark long
dependencies when using ha_warning() or qfprintf().

This patch moves these low-level functions to errors.h, which already
defines the error codes used at the same places. About half of the users
of log.h could be adjusted, sometimes revealing other issues such as
missing tools.h. Interestingly the total preprocessed size shrunk by
4%.
2020-06-11 10:18:59 +02:00
Willy Tarreau
6be7849f39 REORG: include: move cfgparse.h to haproxy/cfgparse.h
There's no point splitting the file in two since only cfgparse uses the
types defined there. A few call places were updated and cleaned up. All
of them were in C files which register keywords.

There is nothing left in common/ now so this directory must not be used
anymore.
2020-06-11 10:18:58 +02:00
Willy Tarreau
dfd3de8826 REORG: include: move stream.h to haproxy/stream{,-t}.h
This one was not easy because it was embarking many includes with it,
which other files would automatically find. At least global.h, arg.h
and tools.h were identified. 93 total locations were identified, 8
additional includes had to be added.

In the rare files where it was possible to finalize the sorting of
includes by adjusting only one or two extra lines, it was done. But
all files would need to be rechecked and cleaned up now.

It was the last set of files in types/ and proto/ and these directories
must not be reused anymore.
2020-06-11 10:18:58 +02:00
Willy Tarreau
1e56f92693 REORG: include: move server.h to haproxy/server{,-t}.h
extern struct dict server_name_dict was moved from the type file to the
main file. A handful of inlined functions were moved at the bottom of
the file. Call places were updated to use server-t.h when relevant, or
to simply drop the entry when not needed.
2020-06-11 10:18:58 +02:00
Willy Tarreau
a55c45470f REORG: include: move queue.h to haproxy/queue{,-t}.h
Nothing outstanding here. A number of call places were not justified and
removed.
2020-06-11 10:18:58 +02:00
Willy Tarreau
a264d960f6 REORG: include: move proxy.h to haproxy/proxy{,-t}.h
This one is particularly difficult to split because it provides all the
functions used to manipulate a proxy state and to retrieve names or IDs
for error reporting, and as such, it was included in 73 files (down to
68 after cleanup). It would deserve a small cleanup though the cut points
are not obvious at the moment given the number of structs involved in
the struct proxy itself.
2020-06-11 10:18:58 +02:00
Willy Tarreau
c2b1ff04e5 REORG: include: move http_ana.h to haproxy/http_ana{,-t}.h
It was moved without any change, however many callers didn't need it at
all. This was a consequence of the split of proto_http.c into several
parts that resulted in many locations to still reference it.
2020-06-11 10:18:58 +02:00
Willy Tarreau
f1d32c475c REORG: include: move channel.h to haproxy/channel{,-t}.h
The files were moved with no change. The callers were cleaned up a bit
and a few of them had channel.h removed since not needed.
2020-06-11 10:18:58 +02:00
Willy Tarreau
5e539c9b8d REORG: include: move stream_interface.h to haproxy/stream_interface{,-t}.h
Almost no changes, removed stdlib and added buf-t and connection-t to
the types to avoid a warning.
2020-06-11 10:18:58 +02:00
Willy Tarreau
83487a833c REORG: include: move cli.h to haproxy/cli{,-t}.h
Almost no change except moving the cli_kw struct definition after the
defines. Almost all users had both types&proto included, which is not
surprizing since this code is old and it used to be the norm a decade
ago. These places were cleaned.
2020-06-11 10:18:58 +02:00
Willy Tarreau
2eec9b5f95 REORG: include: move stats.h to haproxy/stats{,-t}.h
Just some minor reordering, and the usual cleanup of call places for
those which didn't need it. We don't include the whole tools.h into
stats-t anymore but just tools-t.h.
2020-06-11 10:18:58 +02:00
Willy Tarreau
3f0f82e7a9 REORG: move applet.h to haproxy/applet{,-t}.h
The type file was slightly tidied. The cli-specific APPCTX_CLI_ST1_* flag
definitions were moved to cli.h. The type file was adjusted to include
buf-t.h and not the huge buf.h. A few call places were fixed because they
did not need this include.
2020-06-11 10:18:58 +02:00
Willy Tarreau
48d25b3bc9 REORG: include: move session.h to haproxy/session{,-t}.h
Almost no change was needed beyond a little bit of reordering of the
types file and adjustments to use session-t instead of session at a
few places.
2020-06-11 10:18:58 +02:00
Willy Tarreau
126ba3a1e1 REORG: include: move http_fetch.h to haproxy/http_fetch.h
There's no type file for this trivial one. The unneeded dependency on
htx.h was dropped.
2020-06-11 10:18:58 +02:00
Willy Tarreau
7ea393d95e REORG: include: move connection.h to haproxy/connection{,-t}.h
The type file is becoming a mess, half of it is for the proxy protocol,
another good part describes conn_streams and mux ops, it would deserve
being split again. At least it was reordered so that elements are easier
to find, with the PP-stuff left at the end. The MAX_SEND_FD macro was moved
to compat.h as it's said to be the value for Linux.
2020-06-11 10:18:58 +02:00
Willy Tarreau
8b550afe1e REORG: include: move tcp_rules.h to haproxy/tcp_rules.h
There's no type file on this one which is pretty simple.
2020-06-11 10:18:58 +02:00
Willy Tarreau
cea0e1bb19 REORG: include: move task.h to haproxy/task{,-t}.h
The TASK_IS_TASKLET() macro was moved to the proto file instead of the
type one. The proto part was a bit reordered to remove a number of ugly
forward declaration of static inline functions. About a tens of C and H
files had their dependency dropped since they were not using anything
from task.h.
2020-06-11 10:18:58 +02:00
Willy Tarreau
a171892501 REORG: include: move vars.h to haproxy/vars{,-t}.h
A few includes (sessions.h, stream.h, api-t.h) were added for arguments
that were first declared in function prototypes.
2020-06-11 10:18:58 +02:00
Willy Tarreau
e6ce10be85 REORG: include: move sample.h to haproxy/sample{,-t}.h
This one is particularly tricky to move because everyone uses it
and it depends on a lot of other types. For example it cannot include
arg-t.h and must absolutely only rely on forward declarations to avoid
dependency loops between vars -> sample_data -> arg. In order to address
this one, it would be nice to split the sample_data part out of sample.h.
2020-06-11 10:18:58 +02:00
Willy Tarreau
469509b39e REORG: include: move payload.h to haproxy/payload.h
There's no type file, it only contains fetch_rdp_cookie_name() and
val_payload_lv() which probably ought to move somewhere else instead
of staying there.
2020-06-11 10:18:58 +02:00
Willy Tarreau
2cd5809f94 REORG: include: move map to haproxy/map{,-t}.h
Only small cleanups, and removal of a few includes from files that
didn't need them.
2020-06-11 10:18:58 +02:00
Willy Tarreau
225a90aaec REORG: include: move pattern.h to haproxy/pattern{,-t}.h
It was moved as-is, except for extern declaration of pattern_reference.
A few C files used to include it but didn't need it anymore after having
been split apart so this was cleaned.
2020-06-11 10:18:58 +02:00
Willy Tarreau
c761f843da REORG: include: move http_rules.h to haproxy/http_rules.h
There was no include file. This one still includes types/proxy.h.
2020-06-11 10:18:57 +02:00
Willy Tarreau
8efbdfb77b REORG: include: move obj_type.h to haproxy/obj_type{,-t}.h
No change was necessary. It still includes lots of types/* files.
2020-06-11 10:18:57 +02:00
Willy Tarreau
aa74c4e1b3 REORG: include: move arg.h to haproxy/arg{,-t}.h
Almost no change was needed; chunk.h was replaced with buf-t.h.
It dpeends on types/vars.h and types/protocol_buffers.h.
2020-06-11 10:18:57 +02:00
Willy Tarreau
8c794000c4 REORG: include: move hlua_fcn.h to haproxy/hlua_fcn.h
Added lua.h which was missing from the includes.
2020-06-11 10:18:57 +02:00
Willy Tarreau
8641605ff6 REORG: include: move hlua.h to haproxy/hlua{,-t}.h
This one required a few more includes as it uses list and ebpt_node.
It still references lots of types/ files for now.
2020-06-11 10:18:57 +02:00
Willy Tarreau
87735330d1 REORG: include: move http_htx.h to haproxy/http_htx{,-t}.h
A few includes had to be added, namely list-t.h in the type file and
types/proxy.h in the proto file. actions.h was including http-htx.h
but didn't need it so it was dropped.
2020-06-11 10:18:57 +02:00
Willy Tarreau
48fbcae07c REORG: tools: split common/standard.h into haproxy/tools{,-t}.h
And also rename standard.c to tools.c. The original split between
tools.h and standard.h dates from version 1.3-dev and was mostly an
accident. This patch moves the files back to what they were expected
to be, and takes care of not changing anything else. However this
time tools.h was split between functions and types, because it contains
a small number of commonly used macros and structures (e.g. name_desc)
which in turn cause the massive list of includes of tools.h to conflict
with the callers.

They remain the ugliest files of the whole project and definitely need
to be cleaned and split apart. A few types are defined there only for
functions provided there, and some parts are even OS-specific and should
move somewhere else, such as the symbol resolution code.
2020-06-11 10:18:57 +02:00
Willy Tarreau
5413a87ad3 REORG: include: move common/h1.h to haproxy/h1.h
The file was moved as-is. There was a wrong dependency on dynbuf.h
instead of buf.h which was addressed. There was no benefit to
splitting this between types and functions.
2020-06-11 10:18:57 +02:00
Willy Tarreau
374b442cbc REORG: include: split common/xref.h into haproxy/xref{,-t}.h
The type is the only element needed by applet.h and hlua.h, while hlua.c
needs the various functions. XREF_BUSY was placed into the types as well
since it's better to have the special values there.
2020-06-11 10:18:57 +02:00
Willy Tarreau
7cd8b6e3a4 REORG: include: split common/regex.h into haproxy/regex{,-t}.h
Regex are essentially included for myregex_t but it turns out that
several of the C files didn't include it directly, relying on the
one included by their own .h. This has been cleanly addressed so
that only the type is included by H files which need it, and adding
the missing includes for the other ones.
2020-06-11 10:18:57 +02:00
Willy Tarreau
889faf467b CLEANUP: include: remove excessive includes of common/standard.h
Some of them were simply removed as unused (possibly some leftovers
from an older cleanup session), some were turned to haproxy/bitops.h
and a few had to be added (hlua.c and stick-table.h need standard.h
for parse_time_err; htx.h requires chunk.h but used to get it through
standard.h).
2020-06-11 10:18:56 +02:00
Willy Tarreau
3f567e4949 REORG: include: split hathreads into haproxy/thread.h and haproxy/thread-t.h
This splits the hathreads.h file into types+macros and functions. Given
that most users of this file used to include it only to get the definition
of THREAD_LOCAL and MAXTHREADS, the bare minimum was placed into thread-t.h
(i.e. types and macros).

All the thread management was left to haproxy/thread.h. It's worth noting
the drop of the trailing "s" in the name, to remove the permanent confusion
that arises between this one and the system implementation (no "s") and the
makefile's option (no "s").

For consistency, src/hathreads.c was also renamed thread.c.

A number of files were updated to only include thread-t which is the one
they really needed.

Some future improvements are possible like replacing empty inlined
functions with macros for the thread-less case, as building at -O0 disables
inlining and causes these ones to be emitted. But this really is cosmetic.
2020-06-11 10:18:56 +02:00
Willy Tarreau
4c7e4b7738 REORG: include: update all files to use haproxy/api.h or api-t.h if needed
All files that were including one of the following include files have
been updated to only include haproxy/api.h or haproxy/api-t.h once instead:

  - common/config.h
  - common/compat.h
  - common/compiler.h
  - common/defaults.h
  - common/initcall.h
  - common/tools.h

The choice is simple: if the file only requires type definitions, it includes
api-t.h, otherwise it includes the full api.h.

In addition, in these files, explicit includes for inttypes.h and limits.h
were dropped since these are now covered by api.h and api-t.h.

No other change was performed, given that this patch is large and
affects 201 files. At least one (tools.h) was already freestanding and
didn't get the new one added.
2020-06-11 10:18:42 +02:00
Willy Tarreau
8d2b777fe3 REORG: ebtree: move the include files from ebtree to include/import/
This is where other imported components are located. All files which
used to directly include ebtree were touched to update their include
path so that "import/" is now prefixed before the ebtree-related files.

The ebtree.h file was slightly adjusted to read compiler.h from the
common/ subdirectory (this is the only change).

A build issue was encountered when eb32sctree.h is loaded before
eb32tree.h because only the former checks for the latter before
defining type u32. This was addressed by adding the reverse ifdef
in eb32tree.h.

No further cleanup was done yet in order to keep changes minimal.
2020-06-11 09:31:11 +02:00
Christopher Faulet
5cf2dfc5fd BUG/MEDIUM: hlua: Lock pattern references to perform set/add/del operations
The pattern references lock must be hold to perform set/add/del
operations. Unfortunately, it is not true for the lua functions manipulating acl
and map files.

This patch should fix the issue #664. It must be backported as far as 1.8.
2020-06-03 19:08:35 +02:00
Christopher Faulet
23308ebf0d BUG/MEDIUM: lua: Reset analyse expiration timeout before executing a lua action
Before executing a lua action, the analyse expiration timeout of the
corresponding channel must be reset. Otherwise, when it expires, for instance
because of a call to core.msleep(), if the action yields, an expired timeout
will be used for the stream's task, leading to a loop.

This patch should fix the issue #661. It must be backported in all versions
supporting the lua.
2020-06-03 10:24:58 +02:00
Tim Duesterhus
4e172c93f9 MEDIUM: lua: Add ifexist parameter to set_var
As discussed in GitHub issue #624 Lua scripts should not use
variables that are never going to be read, because the memory
for variable names is never going to be freed.

Add an optional `ifexist` parameter to the `set_var` function
that allows a Lua developer to set variables that are going to
be ignored if the variable name was not used elsewhere before.

Usually this mean that there is no `var()` sample fetch for the
variable in question within the configuration.
2020-05-25 08:12:35 +02:00
Tim Duesterhus
84ebc136a1 MINOR: lua: Make set_var() and unset_var() return success
This patch makes `set_var()` and `unset_var()` return a boolean indicating
success.
2020-05-25 08:12:31 +02:00
Tim Duesterhus
94fa973f3e MINOR: lua: Use vars_unset_by_name_ifexist()
There is no good reason to register a variable name, just to unset
that value that could not even be set without the variable existing.

This change should be safe, may be backported if desired.
2020-05-25 08:12:17 +02:00
Ilya Shipitsin
c02a23f981 CLEANUP: assorted typo fixes in the code and comments
This is 9th iteration of typo fixes
2020-05-11 10:11:29 +02:00
Ilya Shipitsin
856aabcda5 CLEANUP: assorted typo fixes in the code and comments
This is 8th iteration of typo fixes
2020-04-17 09:37:36 +02:00
Ilya Shipitsin
d425950c68 CLEANUP: assorted typo fixes in the code and comments
This is 7th iteration of typo fixes
2020-04-16 10:04:36 +02:00
Olivier Houchard
8676514d4e MINOR: servers: Kill priv_conns.
Remove the list of private connections from server, it has been largely
unused, we only inserted connections in it, but we would never actually
use it.
2020-03-11 19:20:01 +01:00
Christopher Faulet
bc275a9e44 BUG/MINOR: lua: Init the lua wake_time value before calling a lua function
The wake_time of a lua context is now always set to TICK_ETERNITY when the
context is initialized and when everytime the execution of the lua stack is
started. It is mandatory to not set arbitrary wake_time when an action yields.

No backport needed.
2020-03-06 14:13:00 +01:00
Christopher Faulet
501465d94b MINOR: lua: Rename hlua_action_wake_time() to hlua_set_wake_time()
This function does not depends on the action class. So use a more generic
name. It will be easier to bind it on another class if necessary.
2020-03-06 14:13:00 +01:00
Christopher Faulet
d8f0e073dd MINOR: lua: Remove the flag HLUA_TXN_HTTP_RDY
This flag was used in some internal functions to be sure the current stream is
able to handle HTTP content. It was introduced when the legacy HTTP code was
still there. Now, It is possible to rely on stream's flags to be sure we have an
HTX stream.

So the flag HLUA_TXN_HTTP_RDY can be removed. Everywhere it was tested, it is
replaced by a call to the IS_HTX_STRM() macro.

This patch is mandatory to allow the support of the filters written in lua.
2020-03-06 14:13:00 +01:00
Christopher Faulet
d31c7b322c MINOR: lua: Stop using lua txn in hlua_http_del_hdr() and hlua_http_add_hdr()
In these functions, the lua txn was not used. So it can be removed from the
function argument list.

This patch is mandatory to allow the support of the filters written in lua.
2020-03-06 14:13:00 +01:00
Christopher Faulet
d1914aaa03 MINOR: lua: Stop using the lua txn in hlua_http_rep_hdr()
In this function, the lua txn was only used to retrieve the stream. But it can
be retieve from the HTTP message, using its channel pointer. So, the lua txn can
be removed from the function argument list.

This patch is mandatory to allow the support of the filters written in lua.
2020-03-06 14:13:00 +01:00
Christopher Faulet
9d1332bbf4 MINOR: lua: Stop using the lua txn in hlua_http_get_headers()
In this function, the lua txn was only used to test if the HTTP transaction is
defined. But it is always used in a context where it is true. So, the lua txn
can be removed from the function argument list.

This patch is mandatory to allow the support of the filters written in lua.
2020-03-06 14:13:00 +01:00
Christopher Faulet
2ac9ba2a1c MINOR: lua: Add function to know if a channel is a response one
It is now possible to call Channel.is_resp(chn) method to know if a channel is a
response channel or not.
2020-03-06 14:13:00 +01:00
Christopher Faulet
0ec740eaee BUG/MINOR: lua: Ignore the reserve to know if a channel is full or not
The Lua function Channel.is_full() should not take care of the reserve because
it is not called from a producer (an applet for instance). From an action, it is
allowed to overwrite the buffer reserve.

This patch should be backported as far as 1.7. But it must be adapted for 1.8
and lower because there is no HTX on these versions.
2020-03-06 14:13:00 +01:00
Christopher Faulet
4ad7310399 BUG/MINOR: lua: Abort when txn:done() is called from a Lua action
When a lua action aborts a transaction calling txn:done() function, the action
must return ACT_RET_ABRT instead of ACT_RET_DONE. It is mandatory to
abort the message analysis.

This patch must be backported everywhere the commit 7716cdf45 ("MINOR: lua: Get
the action return code on the stack when an action finishes") was
backported. For now, no backport needed.
2020-03-06 14:12:59 +01:00
Tim Duesterhus
ed5263739b CLEANUP: Use isttest() and istfree()
This adjusts a few locations to make use of `isttest()` and `istfree()`.
2020-03-05 19:52:07 +01:00
Willy Tarreau
908071171b BUILD: general: always pass unsigned chars to is* functions
The isalnum(), isalpha(), isdigit() etc functions from ctype.h are
supposed to take an int in argument which must either reflect an
unsigned char or EOF. In practice on some platforms they're implemented
as macros referencing an array, and when passed a char, they either cause
a warning "array subscript has type 'char'" when lucky, or cause random
segfaults when unlucky. It's quite unconvenient by the way since none of
them may return true for negative values. The recent introduction of
cygwin to the list of regularly tested build platforms revealed a lot
of breakage there due to the same issues again.

So this patch addresses the problem all over the code at once. It adds
unsigned char casts to every valid use case, and also drops the unneeded
double cast to int that was sometimes added on top of it.

It may be backported by dropping irrelevant changes if that helps better
support uncommon platforms. It's unlikely to fix bugs on platforms which
would already not emit any warning though.
2020-02-25 08:16:33 +01:00
Willy Tarreau
9d6bb5a546 BUILD: lua: silence a warning on systems where longjmp is not marked as noreturn
If the longjmp() call is not flagged as "noreturn", for example, because the
operating system doesn't target a gcc-compatible compiler, we may get this
warning when building Lua :

  src/hlua.c: In function 'hlua_panic_ljmp':
  src/hlua.c:128:1: warning: no return statement in function returning non-void [-Wreturn-type]
   static int hlua_panic_ljmp(lua_State *L) { longjmp(safe_ljmp_env, 1); }
   ^~~~~~

The function's prototype cannot be changed because it must be compatible
with Lua's callbacks. Let's simply enclose the call inside WILL_LJMP()
which we created exactly to signal a call to longjmp(). It lets the compiler
know we won't get back into the function and that the return statement is
not needed.
2020-02-06 16:01:04 +01:00
Christopher Faulet
700d9e88ad MEDIUM: lua: Add ability for actions to intercept HTTP messages
It is now possible to intercept HTTP messages from a lua action and reply to
clients. To do so, a reply object must be provided to the function
txn:done(). It may contain a status code with a reason, a header list and a
body. By default, if an empty reply object is used, an empty 200 response is
returned. If no reply is passed when txn:done() is called, the previous
behaviour is respected, the transaction is terminated and nothing is returned to
the client. The same is done for TCP streams. When txn:done() is called, the
action is terminated with the code ACT_RET_DONE on success and ACT_RET_ERR on
error, interrupting the message analysis.

The reply object may be created for the lua, by hand. Or txn:reply() may be
called. If so, this object provides some methods to fill it:

  * Reply:set_status(<status> [  <reason>]) : Set the status and optionally the
   reason. If no reason is provided, the default one corresponding to the status
   code is used.

  * Reply:add_header(<name>, <value>) : Add a header. For a given name, the
    values are stored in an ordered list.

  * Reply:del_header(<name>) : Removes all occurrences of a header name.

  * Reply:set_body(<body>) : Set the reply body.

Here are some examples, all doing the same:

    -- ex. 1
    txn:done{
        status  = 400,
        reason  = "Bad request",
        headers = {
            ["content-type"]  = { "text/html" },
            ["cache-control"] = { "no-cache", "no-store" },
        },
        body = "<html><body><h1>invalid request<h1></body></html>"
    }

    -- ex. 2
    local reply = txn:reply{
        status  = 400,
        reason  = "Bad request",
        headers = {
            ["content-type"]  = { "text/html" },
            ["cache-control"] = { "no-cache", "no-store" }
        },
        body = "<html><body><h1>invalid request<h1></body></html>"
    }
    txn:done(reply)

    -- ex. 3
    local reply = txn:reply()
    reply:set_status(400, "Bad request")
    reply:add_header("content-length", "text/html")
    reply:add_header("cache-control", "no-cache")
    reply:add_header("cache-control", "no-store")
    reply:set_body("<html><body><h1>invalid request<h1></body></html>")
    txn:done(reply)
2020-02-06 15:13:04 +01:00
Christopher Faulet
2c2c2e381b MINOR: lua: Add act:wake_time() function to set a timeout when an action yields
This function may be used to defined a timeout when a lua action returns
act:YIELD. It is a way to force to reexecute the script after a short time
(defined in milliseconds).

Unlike core:sleep() or core:yield(), the script is fully reexecuted if it
returns act:YIELD. With core functions to yield, the script is interrupted and
restarts from the yield point. When a script returns act:YIELD, it is finished
but the message analysis is blocked on the action waiting its end.
2020-02-06 15:13:04 +01:00
Christopher Faulet
0f3c8907c3 MINOR: lua: Create the global 'act' object to register all action return codes
ACT_RET_* code are now available from lua scripts. The gloabl object "act" is
used to register these codes as constant. Now, lua actions can return any of
following codes :

  * act.CONTINUE for ACT_RET_CONT
  * act.STOP for ACT_RET_STOP
  * act.YIELD for ACT_RET_YIELD
  * act.ERROR for ACT_RET_ERR
  * act.DONE for ACT_RET_DONE
  * act.DENY for ACT_RET_DENY
  * act.ABORT for ACT_RET_ABRT
  * act.INVALID for ACT_RET_INV

For instance, following script denied all requests :

  core.register_action("deny", { "http-req" }, function (txn)
      return act.DENY
  end)

Thus "http-request lua.deny" do exactly the same than "http-request deny".
2020-02-06 15:13:03 +01:00
Christopher Faulet
7716cdf450 MINOR: lua: Get the action return code on the stack when an action finishes
When an action successfully finishes, the action return code (ACT_RET_*) is now
retrieve on the stack, ff the first element is an integer. In addition, in
hlua_txn_done(), the value ACT_RET_DONE is pushed on the stack before
exiting. Thus, when a script uses this function, the corresponding action still
finishes with the good code. Thanks to this change, the flag HLUA_STOP is now
useless. So it has been removed.

It is a mandatory step to allow a lua action to return any action return code.
2020-02-06 15:13:03 +01:00
Christopher Faulet
07a718e712 CLEANUP: lua: Remove consistency check for sample fetches and actions
It is not possible anymore to alter the HTTP parser state from lua sample
fetches or lua actions. So there is no reason to still check for the parser
state consistency.
2020-02-06 15:13:03 +01:00
Tim Duesterhus
541fe1ec52 MINOR: lua: Add HLUA_PREPEND_C?PATH build option
This complements the lua-prepend-path configuration option to allow
distro maintainers to add a default path for HAProxy specific Lua
libraries.
2020-01-24 09:22:03 +01:00
Tim Duesterhus
dd74b5f237 MINOR: lua: Add lua-prepend-path configuration option
lua-prepend-path allows the administrator to specify a custom Lua library
path to load custom Lua modules that are useful within the context of HAProxy
without polluting the global Lua library folder.
2020-01-24 09:22:03 +01:00
Tim Duesterhus
c9fc9f2836 MINOR: lua: Add hlua_prepend_path function
This function is added in preparation for following patches.
2020-01-24 09:21:35 +01:00
Christopher Faulet
92d34fe38d MINOR: http-rules: Make replace-header and replace-value custom actions
Now, these actions use their own dedicated function and are no longer handled
"in place" during the HTTP rules evaluation. Thus the action names
ACT_HTTP_REPLACE_HDR and ACT_HTTP_REPLACE_VAL are removed. The action type is
now set to 0 to evaluate the whole header or to 1 to evaluate every
comma-delimited values.

The function http_transform_header_str() is renamed to http_replace_hdrs() to be
more explicit and the function http_transform_header() is removed. In fact, this
last one is now more or less the new action function.

The lua code has been updated accordingly to use http_replace_hdrs().
2020-01-20 15:18:45 +01:00
Christopher Faulet
105ba6cc54 MINOR: actions: Rename the act_flag enum into act_opt
The flags in the act_flag enum have been renamed act_opt. It means ACT_OPT
prefix is used instead of ACT_FLAG. The purpose of this patch is to reserve the
action flags for the actions configuration.
2020-01-20 15:18:45 +01:00
Christopher Faulet
96bff76087 MINOR: actions: Regroup some info about HTTP rules in the same struct
Info used by HTTP rules manipulating the message itself are splitted in several
structures in the arg union. But it is possible to group all of them in a unique
struct. Now, <arg.http> is used by most of these rules, which contains:

  * <arg.http.i>   : an integer used as status code, nice/tos/mark/loglevel or
                     action id.
  * <arg.http.str> : an IST used as header name, reason string or auth realm.
  * <arg.http.fmt> : a log-format compatible expression
  * <arg.http.re>  : a regular expression used by replace rules
2020-01-20 15:18:45 +01:00
Christopher Faulet
13403761d5 MINOR: actions: Use ACT_RET_CONT code to ignore an error from a custom action
Some custom actions are just ignored and skipped when an error is encoutered. In
that case, we jump to the next rule. To do so, most of them use the return code
ACT_RET_ERR. Currently, for http rules and tcp content rules, it is not a
problem because this code is handled the same way than ACT_RET_CONT. But, it
means there is no way to handle the error as other actions. The custom actions
must handle the error and return ACT_RET_DONE. For instance, when http-request
rules are processed, an error when we try to replace a header value leads to a
bad request and an error 400 is returned to the client. But when we fail to
replace the URI, the error is silently ignored. This difference between the
custom actions and the others is an obstacle to write new custom actions.

So, in this first patch, ACT_RET_CONT is now returned from custom actions
instead of ACT_RET_ERR when an error is encoutered if it should be ignored. The
behavior remains the same but it is now possible to handle true errors using the
return code ACT_RET_ERR. Some actions will probably be reviewed to determine if
an error is fatal or not. Other patches will be pushed to trigger an error when
a custom action returns the ACT_RET_ERR code.

This patch is not tagged as a bug because it is just a design issue. But others
will depends on it. So be careful during backports, if so.
2020-01-20 15:18:45 +01:00
Willy Tarreau
f31af9367e MEDIUM: lua: don't call the GC as often when dealing with outgoing connections
In order to properly close connections established from Lua in case
a Lua context dies, the context currently automatically gets a flag
HLUA_MUST_GC set whenever an outgoing connection is used. This causes
the GC to be enforced on the context's death as well as on yield. First,
it does not appear necessary to do it when yielding, since if the
connections die they are already cleaned up. Second, the problem with
the flag is that even if a connection gets properly closed, the flag is
not removed and the GC continues to be called on the Lua context.

The impact on performance looks quite significant, as noticed and
diagnosed by Sadasiva Gujjarlapudi in the following thread:

  https://www.mail-archive.com/haproxy@formilux.org/msg35810.html

This patch changes the flag for a counter so that each created
connection increments it and each cleanly closed connection decrements
it. That way we know we have to call the GC on the context's death only
if the count is non-null. As reported in the thread above, the Lua
performance gain is now over 20% by doing this.

Thanks to Sada and Thierry for the design discussion and tests that
led to this solution.
2020-01-14 10:12:31 +01:00
Christopher Faulet
ea009736d8 BUILD: debug: Avoid warnings in dev mode with -02 because of some BUG_ON tests
Some BUG_ON() tests emit a warning because of a potential null pointer
dereference on an HTX block. In fact, it should never happen, but now, GCC is
happy.

This patch must be backported to 2.0.
2019-11-20 14:11:47 +01:00
Tim Duesterhus
9fe7c6376a BUG/MEDIUM: lua: Store stick tables into the sample's t field
This patch fixes issue #306.

This bug was introduced in the stick table refactoring in
1b8e68e89a.

This fix must be backported to 2.0.
2019-09-30 04:11:36 +02:00
Tim Duesterhus
2e89dec513 CLEANUP: lua: Get rid of obsolete (size_t *) cast in hlua_lua2(smp|arg)
This was required for the `chunk` API (`data` was an int), but is not
required with the `buffer` API.
2019-09-30 04:11:36 +02:00
Tim Duesterhus
29d2e8aa9a BUG/MINOR: lua: Properly initialize the buffer's fields for string samples in hlua_lua2(smp|arg)
`size` is used in conditional jumps and valgrind complains:

==24145== Conditional jump or move depends on uninitialised value(s)
==24145==    at 0x4B3028: smp_is_safe (sample.h:98)
==24145==    by 0x4B3028: smp_make_safe (sample.h:125)
==24145==    by 0x4B3028: smp_to_stkey (stick_table.c:936)
==24145==    by 0x4B3F2A: sample_conv_in_table (stick_table.c:1113)
==24145==    by 0x420AD4: hlua_run_sample_conv (hlua.c:3418)
==24145==    by 0x54A308F: ??? (in /usr/lib/x86_64-linux-gnu/liblua5.3.so.0.0.0)
==24145==    by 0x54AFEFC: ??? (in /usr/lib/x86_64-linux-gnu/liblua5.3.so.0.0.0)
==24145==    by 0x54A29F1: ??? (in /usr/lib/x86_64-linux-gnu/liblua5.3.so.0.0.0)
==24145==    by 0x54A3523: lua_resume (in /usr/lib/x86_64-linux-gnu/liblua5.3.so.0.0.0)
==24145==    by 0x426433: hlua_ctx_resume (hlua.c:1097)
==24145==    by 0x42D7F6: hlua_action (hlua.c:6218)
==24145==    by 0x43A414: http_req_get_intercept_rule (http_ana.c:3044)
==24145==    by 0x43D946: http_process_req_common (http_ana.c:500)
==24145==    by 0x457892: process_stream (stream.c:2084)

Found while investigating issue #306.

A variant of this issue exists since 55da165301,
which was using the old `chunk` API instead of the `buffer` API thus this patch
must be backported to HAProxy 1.6 and higher.
2019-09-30 04:11:36 +02:00
Willy Tarreau
60409db0b1 MINOR: lua: export applet and task handlers
The current functions are seen outside from the debugging code and are
convenient to export so that we can improve the thread dump output :

  void hlua_applet_tcp_fct(struct appctx *ctx);
  void hlua_applet_http_fct(struct appctx *ctx);
  struct task *hlua_process_task(struct task *task, void *context, unsigned short state);

Of course they are only available when USE_LUA is defined.
2019-08-21 14:32:09 +02:00
Christopher Faulet
81921b1371 BUG/MEDIUM: lua: Fix test on the direction to set the channel exp timeout
This bug was introduced by the commit bfab2ddd ("MINOR: hlua: Add a flag on the
lua txn to know in which context it can be used"). The wrong test was done. So
the timeout was always set on the response channel. It may lead to an infinite
loop.

This patch must be backported everywhere the commit bfab2ddd is. For now, at
least to 2.0, 1.9 and 1.8.
2019-08-14 23:29:18 +02:00
Lukas Tribus
579e3e3dd5 BUG/MINOR: lua: fix setting netfilter mark
In the REORG of commit 1a18b5414 ("REORG: connection: centralize the
conn_set_{tos,mark,quickack} functions") a bug was introduced by
calling conn_set_tos instead of conn_set_mark.

This was reported in issue #212

This should be backported to 1.9 and 2.0.
2019-08-12 07:41:31 +02:00
Christopher Faulet
301eff8e21 BUG/MINOR: hlua: Only execute functions of HTTP class if the txn is HTTP ready
The flag HLUA_TXN_HTTP_RDY was added in the previous commit to know when a
function is called for a channel with a valid HTTP message or not. Of course it
also depends on the calling direction. In this commit, we allow the execution of
functions of the HTTP class only if this flag is set.

Nobody seems to use them from an unsupported context (for instance, trying to
set an HTTP header from a tcp-request rule). But it remains a bug leading to
undefined behaviors or crashes.

This patch may be backported to all versions since the 1.6. It depends on the
commits "MINOR: hlua: Add a flag on the lua txn to know in which context it can
be used" and "MINOR: hlua: Don't set request analyzers on response channel for
lua actions".
2019-07-29 11:17:52 +02:00
Christopher Faulet
bfab2dddad MINOR: hlua: Add a flag on the lua txn to know in which context it can be used
When a lua action or a lua sample fetch is called, a lua transaction is
created. It is an entry in the stack containing the class TXN. Thanks to it, we
can know the direction (request or response) of the call. But, for some
functions, it is also necessary to know if the buffer is "HTTP ready" for the
given direction. "HTTP ready" means there is a valid HTTP message in the
channel's buffer. So, when a lua action or a lua sample fetch is called, the
flag HLUA_TXN_HTTP_RDY is set if it is appropriate.
2019-07-29 11:17:52 +02:00
Christopher Faulet
51fa358432 MINOR: hlua: Don't set request analyzers on response channel for lua actions
Setting some requests analyzers on the response channel was an old trick to be
sure to re-evaluate the request's analyers after the response's ones have been
called. It is no more necessary. In fact, this trick was removed in the version
1.8 and backported up to the version 1.6.

This patch must be backported to all versions since 1.6 to ease the backports of
fixes on the lua code.
2019-07-29 11:17:52 +02:00
Christopher Faulet
84a6d5bc21 BUG/MEDIUM: hlua: Check the calling direction in lua functions of the HTTP class
It is invalid to manipulate responses from http-request rules or to manipulate
requests from http-response rules. When http-request rules are evaluated, the
connection to server is not yet established, so there is no response at all. And
when http-response rules are evaluated, the request has already been sent to the
server.

Now, the calling direction is checked. So functions "txn.http:req_*" can now
only be called from http-request rules and the functions "txn.http:res_*" can
only be called from http-response rules.

This issue was reported on Github (#190).

This patch must be backported to all versions since the 1.6.
2019-07-29 11:17:52 +02:00