Commit Graph

654 Commits

Author SHA1 Message Date
Tim Duesterhus
2281738256 BUG/MEDIUM lua: Add missing call to RESET_SAFE_LJMP in hlua_filter_new()
In one case before exiting leaving the function the panic handler was not
reset.

Introduced in 69c581a092, which is 2.5+.
No backport required.
2021-09-12 08:21:07 +02:00
Willy Tarreau
e352b9dac7 MINOR: vars: make vars_get_by_* support an optional default value
In preparation for support default values when fetching variables, we
need to update the internal API to pass an extra argument to functions
vars_get_by_{name,desc} to provide an optional default value. This
patch does this and always passes NULL in this argument. var_to_smp()
was extended to fall back to this value when available.
2021-09-03 12:08:54 +02:00
Willy Tarreau
b131049eb5 BUILD: ssl: fix two remaining occurrences of #if USE_OPENSSL
One was in backend.c and the other one in hlua.c. No other candidate
was found with "git grep '^#if\s*USE'". It's worth noting that 3
other such tests exist for SSL_OP_NO_{SSLv3,TLSv1_1,TLSv1_2} but
that these ones are properly set to 0 in openssl-compat.h when not
defined.
2021-08-30 09:39:24 +02:00
Willy Tarreau
5ef965606b BUG/MINOR: lua: use strlcpy2() not strncpy() to copy sample keywords
The lua initialization code which creates the Lua mapping of all converters
and sample fetch keywords makes use of strncpy(), and as such can take ages
to start with large values of tune.bufsize because it spends its time zeroing
gigabytes of memory for nothing. A test performed with an extreme value of
16 MB takes roughly 4 seconds, so it's possible that some users with huge
1 MB buffers (e.g. for payload analysis) notice a small startup latency.
However this does not affect config checks since the Lua stack is not yet
started. Let's replace this with strlcpy2().

This should be backported to all supported versions.
2021-08-26 16:57:48 +02:00
Amaury Denoyelle
bc2ebfa5a4 MEDIUM: server: extend refcount for all servers
In a future patch, it will be possible to remove at runtime every
servers, both static and dynamic. This requires to extend the server
refcount for all instances.

First, refcount manipulation functions have been renamed to better
express the API usage.

* srv_refcount_use -> srv_take
The refcount is always initialize to 1 on the server creation in
new_server. It's also incremented for each check/agent configured on a
server instance.

* free_server -> srv_drop
This decrements the refcount and if null, the server is freed, so code
calling it must not use the server reference after it. As a bonus, this
function now returns the next server instance. This is useful when
calling on the server loop without having to save the next pointer
before each invocation.

In these functions, remove the checks that prevent refcount on
non-dynamic servers. Each reference to "dynamic" in variable/function
naming have been eliminated as well.
2021-08-25 15:53:54 +02:00
Ilya Shipitsin
ff0f278860 CLEANUP: assorted typo fixes in the code and comments
This is 26th iteration of typo fixes
2021-08-25 05:13:31 +02:00
Willy Tarreau
1e7bef17df MINOR: hlua: take the global Lua lock inside a global function
Some users are facing huge CPU usage or even watchdog panics due to
the Lua global lock when many threads compete on it, but they have
no way to see that in the usual dumps. We take the lock at 2 or 3
places only, thus it's trivial to move it to a global function so
that stack dumps will now explicitly show it, increasing the change
that it rings a bell and someone suggests switch to lua-load-per-thread:

  Current executing Lua from a stream analyser -- stack traceback:
      loop.lua:1: in function line 1
  call trace(27):
  |       0x5ff157 [48 83 c4 10 5b 5d 41 5c]: wdt_handler+0xf7/0x104
  | 0x7fe37fe82690 [48 c7 c0 0f 00 00 00 0f]: libpthread:+0x13690
  |       0x614340 [66 48 0f 7e c9 48 01 c2]: main+0x1e8a40
  |       0x607b85 [48 83 c4 08 48 89 df 31]: main+0x1dc285
  |       0x6070bc [48 8b 44 24 20 48 8b 14]: main+0x1db7bc
  |       0x607d37 [41 89 c4 89 44 24 1c 83]: lua_resume+0xc7/0x214
  |       0x464ad6 [83 f8 06 0f 87 f1 01 00]: main+0x391d6
  |       0x4691a7 [83 f8 06 0f 87 03 20 fc]: main+0x3d8a7
  |       0x51dacb [85 c0 74 61 48 8b 5d 20]: sample_process+0x4b/0xf7
  |       0x51e55c [48 85 c0 74 3f 64 48 63]: sample_fetch_as_type+0x3c/0x9b
  |       0x525613 [48 89 c6 48 85 c0 0f 84]: sess_build_logline+0x2443/0x3cae
  |       0x4af0be [4c 63 e8 4c 03 6d 10 4c]: http_apply_redirect_rule+0xbfe/0xdf8
  |       0x4af523 [83 f8 01 19 c0 83 e0 03]: main+0x83c23
  |       0x4b2326 [83 f8 07 0f 87 99 00 00]: http_process_req_common+0xf6/0x15f6
  |       0x4d5b30 [85 c0 0f 85 9f f5 ff ff]: process_stream+0x2010/0x4e18

It also allows "perf top" to directly show the time spent on this lock.

This may be backported to some stable versions as it improves the
overall debuggability.
2021-08-20 17:33:26 +02:00
Christopher Faulet
e48d1dc2d9 BUG/MINOR: lua/filters: Return right code when txn:done() is called
txn functions can now be called from an action or a filter context. Thus the
return code must be adapted depending on this context. From an action, act.ABORT
is returned. From a filter, -1 is returned. It is the filter error code.

This bug only affects 2.5-dev. No backport needed.
2021-08-13 17:14:47 +02:00
Christopher Faulet
c86bb87f10 BUG/MINOR: lua: Properly catch alloc errors when parsing lua filter directives
When a lua filter declaration is parsed, some allocation errors were not
properly handled. In addition, we must be sure the filter identifier is defined
in lua to duplicate it when the filter configuration is filled.

This patch fix a defect reported in the issue #1347. It only concerns
2.5-dev. No backport needed.
2021-08-13 08:42:00 +02:00
Christopher Faulet
70c4345dbc BUG/MINOR: lua: Properly check negative offset in Channel/HttpMessage functions
In Channel and HTTPMessage classes, several functions uses an offset that
may be negative to start from the end of incoming data. But, after
calculation, the offset must never be negative. However, there is a bug
because of a bad cast to unsigned when "input + offset" is performed. The
result must be a signed integer.

This patch should fix most of defects reported in the issue #1347. It only
affects 2.5-dev. No backport needed.
2021-08-13 08:36:42 +02:00
Christopher Faulet
eae8afaa60 MINOR: filters/lua: Support the HTTP filtering from filters written in lua
Now an HTTPMessage class is available to manipulate HTTP message from a filter
it is possible to bind HTTP filters callback function on lua functions. Thus,
following methods may now be defined by a lua filter:

  * Filter:http_headers(txn, http_msg)
  * Filter:http_payload(txn, http_msg, offset, len)
  * Filter:http_end(txn, http_msg)

http_headers() and http_end() may return one of the constant filter.CONTINUE,
filter.WAIT or filter.ERROR. If nothing is returned, filter.CONTINUE is used as
the default value. On its side, http_payload() may return the amount of data to
forward. If nothing is returned, all incoming data are forwarded.

For now, these functions are not allowed to yield because this interferes with
the filter workflow.
2021-08-12 08:57:07 +02:00
Christopher Faulet
78c35471f8 MINOR: filters/lua: Add request and response HTTP messages in the lua TXN
When a lua TXN is created from a filter context, the request and the response
HTTP message objects are accessible from ".http_req" and ".http_res" fields. For
an HTTP proxy, these objects are always defined. Otherwise, for a TCP proxy, no
object is created and nil is used instead. From any other context (action or
sample fetch), these fields don't exist.
2021-08-12 08:57:07 +02:00
Christopher Faulet
df97ac4584 MEDIUM: filters/lua: Add HTTPMessage class to help HTTP filtering
This new class exposes methods to manipulate HTTP messages from a filter
written in lua. Like for the HTTP class, there is a bunch of methods to
manipulate the message headers. But there are also methods to manipulate the
message payload. This part is similar to what is available in the Channel
class. Thus the payload can be duplicated, erased, modified or
forwarded. For now, only DATA blocks can be retrieved and modified because
the current API is limited. No HTTPMessage method is able to yield. Those
manipulating the headers are always called on messages containing all the
headers, so there is no reason to yield. Those manipulating the payload are
called from the http_payload filters callback function where yielding is
forbidden.

When an HTTPMessage object is instantiated, the underlying Channel object
can be retrieved via the ".channel" field.

For now this class is not used because the HTTP filtering is not supported
yet. It will be the purpose of another commit.

There is no documentation for now.
2021-08-12 08:57:07 +02:00
Christopher Faulet
c404f1126c MEDIUM: filters/lua: Support declaration of some filter callback functions in lua
It is now possible to write some filter callback functions in lua. All
filter callbacks are not supported yet but the mechanism to call them is now
in place. Following method may be defined in the Lua filter class to be
bound on filter callbacks:

  * Filter:start_analyse(txn, chn)
  * Filter:end_analyse(txn, chn)
  * Filter:tcp_payload(txn, chn, offset, length)

hlua_filter_callback() function is responsible to call the good lua function
depending on the filter callback function. Using some flags it is possible
to allow a lua call to yield or not, to retrieve a return value or not, and
to specify if a channel or an http message must be passed as second
argument. For now, the HTTP part has not been added yet. It is also possible
to add extra argument adding them on the stack before the call.

3 new functions are exposed by the global object "filter". The first one,
filter.wake_time(ms_delay), to set the wake_time when a Lua callback
function yields (if allowed). The two others,
filter.register_data_filter(filter, chn) and
filter.unregister_data_filter(filter, chn), to enable or disable the data
filtering on a channel for a specific lua filter instance.

start_analyse() and end_analyse() may return one of the constant
filter.CONTINUE, filter.WAIT or filter.ERROR. If nothing is returned,
filter.CONTINUE is used as the default value. On its side, tcp_payload() may
return the amount of data to forward. If nothing is returned, all incoming
data are forwarded.

For now, these functions are not allowed to yield because this interferes
with the filter workflow.

Here is a simple example :

    MyFilter = {}
    MyFilter.id = "My Lua filter"
    MyFilter.flags = filter.FLT_CFG_FL_HTX
    MyFilter.__index = MyFilter

    function MyFilter:new()
        flt = {}
        setmetatable(flt, MyFilter)
        flt.req_len = 0
        flt.res_len = 0
        return flt
     end

    function MyFilter:start_analyze(txn, chn)
        filter.register_data_filter(self, chn)
    end

    function MyFilter:end_analyze(txn, chn)
        print("<Total> request: "..self.req_len.." - response: "..self.res_len)
    end

    function MyFilter:tcp_payload(txn, chn)
        offset = chn:ouput()
	len    = chn:input()
        if chn:is_resp() then
            self.res_len = self.res_len + len
            print("<TCP:Response> offset: "..offset.." - length: "..len)
        else
            self.req_len = self.req_len + len
            print("<TCP:Request> offset: "..offset.." - length: "..len)
        end
    end
2021-08-12 08:57:07 +02:00
Christopher Faulet
a1ac5fb28e MEDIUM: filters/lua: Be prepared to filter TCP payloads
For filters written in lua, the tcp payloads will be filtered using methods
exposed by the Channel class. So the corrsponding C binding functions must
be prepared to process payload in a filter context and not only in an action
context.

The main change is the offset where to start to process data in the channel
buffer, and the length of these data. For an action, all input data are
considered. But for a filter, it depends on what the filter is allow to
forward when the tcp_payload callback function is called. It depends on
previous calls but also on other filters.

In addition, when the payload is modified by a lua filter, its context must
be updated. Note also that channel functions cannot yield when called from a
filter context.

For now, it is not possible to define callbacks to filter data and the
documentation has not been updated.
2021-08-12 08:57:07 +02:00
Christopher Faulet
8c9e6bba0f MINOR: lua: Add flags on the lua TXN to know the execution context
A lua TXN can be created when a sample fetch, an action or a filter callback
function is executed. A flag is now used to track the execute context.
Respectively, HLUA_TXN_SMP_CTX, HLUA_TXN_ACT_CTX and HLUA_TXN_FLT_CTX. The
filter flag is not used for now.
2021-08-12 08:57:07 +02:00
Christopher Faulet
9f55a5012e MINOR: lua: Add a function to get a filter attached to a channel class
For now, there is no support for filters written in lua. So this function,
if called, will always return NULL. But when it will be called in a filter
context, it will return the filter structure attached to a channel
class. This function is also responsible to set the offset of data that may
be processed and the length of these data. When called outside a filter
context (so from an action), the offset is the input data position and the
length is the input data length. From a filter, the offset and the length of
data that may be filtered are retrieved the filter context.
2021-08-12 08:57:07 +02:00
Christopher Faulet
69c581a092 MEDIUM: filters/lua: Add support for dummy filters written in lua
It is now possible to write dummy filters in lua. Only the basis to declare
such filters has been added for now. There is no way to declare callbacks to
filter anything. Lua filters are for now empty nutshells.

To do so, core.register_filter() must be called, with 3 arguments, the
filter's name (as it appears in HAProxy config), the lua class that will be
used to instantiate filters and a function to parse arguments passed on the
filter line in HAProxy configuration file. The lua filter class must at
least define the method new(), without any extra args, to create new
instances when streams are created. If this method is not found, the filter
will be ignored.

Here is a template to declare a new Lua filter:

    // haproxy.conf
    global
        lua-load /path/to/my-filter.lua
        ...

    frontend fe
        ...
        filter lua.my-lua-filter arg1 arg2 arg3
        filter lua.my-lua-filter arg4 arg5

    // my-filter.lua
    MyFilter = {}
    MyFilter.id = "My Lua filter"          -- the filter ID (optional)
    MyFilter.flags = filter.FLT_CFG_FL_HTX -- process HTX streams (optional)
    MyFilter.__index = MyFilter

    function MyFilter:new()
        flt = {}
        setmetatable(flt, MyFilter)
        -- Set any flt fields. self.args can be used
	flt.args = self.args

        return flt -- The new instance of Myfilter
    end

    core.register_filter("my-lua-filter", MyFilter, function(filter, args)
        -- process <args>, an array of strings. For instance:
        filter.args = args
        return filter
    end)

In this example, 2 filters are declared using the same lua class. The
parsing function is called for both, with its own copy of the lua class. So
each filter will be unique.

The global object "filter" exposes some constants and flags, and later some
functions, to help writting filters in lua.

Internally, when a lua filter is instantiated (so when new() method is
called), 2 lua contexts are created, one for the request channel and another
for the response channel. It is a prerequisite to let some callbacks yield
on one side independently on the other one.

There is no documentation for now.
2021-08-12 08:57:07 +02:00
Christopher Faulet
6a79fc16bd MEDIUM: lua: Improve/revisit the lua api to manipulate channels
First of all, following functions are now considered deprecated:

  * Channel:dup()
  * Channel:get()
  * Channel:getline()
  * Channel:get_in_len()
  * Cahnnel:get_out_len()

It is just informative, there is no warning and functions may still be
used. Howver it is recommended to use new functions. New functions are more
flexible and use a better naming pattern. In addition, the same names will
be used in the http_msg class to manipulate http messages from lua filters.

The new API is:

  * Channel:data()
  * Channel:line()
  * Channel:append()
  * Channel:prepend()
  * Channel:insert()
  * Channel:remove()
  * Channel:set()
  * Channel:input()
  * Channel:output()
  * Channel:send()
  * Channel:forward()
  * Channel:is_resp()
  * Channel:is_full()
  * Channel:may_recv()

The lua documentation was updated accordingly.
2021-08-12 08:57:07 +02:00
Christopher Faulet
9a6ffda795 MEDIUM: lua: Process buffer data using an offset and a length
The main change is that following functions will now process channel's data
using an offset and a length:

  * hlua_channel_dup_yield()
  * hlua_channel_get_yield()
  * hlua_channel_getline_yield()
  * hlua_channel_append_yield()
  * hlua_channel_set()
  * hlua_channel_send_yield()
  * hlua_channel_forward_yield()

So for now, the offset is always the input data position and the length is
the input data length. But with the support for filters, from a filter
context, these values will be relative to the filter.

To make all processing clearer, the function _hlua_channel_dup() has been
updated and _hlua_channel_dupline(), _hlua_channel_insert() and
_hlua_channel_delete() have been added.

This patch is mandatory to allow the support of the filters written in lua.
2021-08-12 08:57:07 +02:00
Christopher Faulet
ba9e21dc68 MINOR: lua: Add a function to get a reference on a table in the stack
The hlua_checktable() function may now be used to create and return a
reference on a table in stack, given its position. This function ensures it
is really a table and throws an exception if not.

This patch is mandatory to allow the support of the filters written in lua.
2021-08-12 08:57:07 +02:00
Christopher Faulet
23976d9e40 BUG/MINOR: lua: Don't yield in channel.append() and channel.set()
Lua functions to set or append data to the input part of a channel must not
yield because new data may be received while the lua script is suspended. So
adding data to the input part in several passes is highly unpredicatble and
may be interleaved with received data.

Note that if necessary, it is still possible to suspend a lua action by
returning act.YIELD. This way the whole action will be reexecuted later
because of I/O events or a timer. Another solution is to call core.yield().

This bug affects all stable versions. So, it may be backported. But it is
probably not necessary because nobody notice it till now.
2021-08-12 08:57:07 +02:00
Christopher Faulet
2e60aa4dee BUG/MINOR: lua: Yield in channel functions only if lua context can yield
When a script is executed, it is not always allowed to yield. Lua sample
fetches and converters cannot yield. For lua actions, it depends on the
context. When called from tcp content ruleset, an action may yield until the
expiration of the inspect-delay timeout. From http rulesets, yield is not
possible.

Thus, when channel functions (dup, get, append, send...) are called, instead
of yielding when it is not allowed and triggering an error, we just give
up. In this case, some functions do nothing (dup, append...), some others
just interrupt the in-progress job (send, forward...). But, because these
functions don't yield anymore when it is not allowed, the script regains the
control and can continue its execution.

This patch depends on "MINOR: lua: Add a flag on lua context to know the
yield capability at run time". Both may be backported in all stable
versions. However, because nobody notice this bug till now, it is probably
not necessary, excepted if someone ask for it.
2021-08-12 08:57:07 +02:00
Christopher Faulet
1f43a3430e MINOR: lua: Add a flag on lua context to know the yield capability at run time
When a script is executed, a flag is used to allow it to yield. An error is
returned if a lua function yield, explicitly or not. But there is no way to
get this capability in C functions. So there is no way to choose to yield or
not depending on this capability.

To fill this gap, the flag HLUA_NOYIELD is introduced and added on the lua
context if the current script execution is not authorized to yield. Macros
to set, clear and test this flags are also added.

This feature will be usefull to fix some bugs in lua actions execution.
2021-08-12 08:57:07 +02:00
William Lallemand
6bb77b9c64 MINOR: proxy: rename PR_CAP_LUA to PR_CAP_INT
This patch renames the proxy capability "LUA" to "INT" so it could be
used for any internal proxy.

Every proxy that are not user defined should use this flag.
2021-07-28 15:51:42 +02:00
Willy Tarreau
ee0d727989 CLEANUP: hlua: use free_args() to release args arrays
Argument arrays used in hlua_lua2arg_check() as well as in the functions
used to call sample fetches and converters were manually released, let's
use the cleaner and more reliable free_args() instead. The prototype of
hlua_lua2arg_check() was amended to mention that the function relies on
the final ARGT_STOP, which is already the case, and the pointless test
for this was removed.
2021-07-16 19:18:41 +02:00
Willy Tarreau
6a51090780 BUILD: lua: silence a build warning with TCC
TCC doesn't have the equivalent of __builtin_unreachable() and complains
that hlua_panic_ljmp() may return no value. Let's add a return 0 there.
All compilers that know that longjmp() doesn't return will see no change
and tcc will be happy.
2021-07-14 19:41:25 +02:00
Amaury Denoyelle
c453f9547e MINOR: http: use http uri parser for path
Replace http_get_path by the http_uri_parser API. The new functions is
renamed http_parse_path. Replace duplicated code for scheme and
authority parsing by invocations to http_parse_scheme/authority.

If no scheme is found for an URI detected as an absolute-uri/authority,
consider it to be an authority format : no path will be found. For an
absolute-uri or absolute-path, use the remaining of the string as the
path. A new http_uri_parser state is declared to mark the path parsing
as done.
2021-07-08 17:11:17 +02:00
Willy Tarreau
3d6ee407e7 BUILD: hlua: include proxy.h from hlua.c
Many proxy functions are called there but the include was missing and
inherited via cfgparse.h.
2021-05-08 20:35:39 +02:00
Amaury Denoyelle
e4a617c931 MINOR: action: replace match_pfx by a keyword flags field
Define a new keyword flag KWF_MATCH_PREFIX. This is used to replace the
match_pfx field of action struct.

This has the benefit to have more explicit action declaration, and now
it is possible to quickly implement experimental actions.
2021-05-07 14:35:01 +02:00
Christopher Faulet
c31b200872 BUG/MINOR: hlua: Don't rely on top of the stack when using Lua buffers
When the lua buffers are used, a variable number of stack slots may be
used. Thus we cannot assume that we know where the top of the stack is. It
was not an issue for lua < 5.4.3 (at least for small buffers). But
'socket:receive()' now fails with lua 5.4.3 because a light userdata is
systematically pushed on the top of the stack when a buffer is initialized.

To fix the bug, in hlua_socket_receive(), we save the index of the top of
the stack before creating the buffer. This way, we can check the number of
arguments, regardless anything was pushed on the stack or not.

Note that the other buffer usages seem to be safe.

This patch should solve the issue #1240. It should be backport to all stable
branches.
2021-05-03 10:34:48 +02:00
Willy Tarreau
7e702d13f4 CLEANUP: hlua: rename hlua_appctx* appctx to luactx
There is some serious confusion in the lua interface code related to
sockets and services coming from the hlua_appctx structs being called
"appctx" everywhere, and where the real appctx is reached using
appctx->appctx. This part is a bit of a pain to debug so let's rename
all occurrences of this local variable to "luactx".
2021-04-28 17:59:21 +02:00
Christopher Faulet
bd878d2c73 BUG/MINOR: hlua: Don't consume headers when starting an HTTP lua service
When an HTTP lua service is started, headers are consumed before calling the
script. When it was initialized, the headers were stored in a lua array,
thus they can be removed from the HTX message because the lua service will
no longer access them. But it is a problem with bodyless messages because
the EOM flag is lost. Indeed, once the headers are consumed, the message is
empty and the buffer is reset, included the flags.

Now, the headers are not immediately consumed. We will skip them if
applet:receive() or applet:getline(). This way, the EOM flag is preserved.
At the end, when the script is finished, all output data are consumed, thus
this remains safe.

It is a 2.4-specific bug. No backport is needed.
2021-04-28 11:05:05 +02:00
Willy Tarreau
2b71810cb3 CLEANUP: lists/tree-wide: rename some list operations to avoid some confusion
The current "ADD" vs "ADDQ" is confusing because when thinking in terms
of appending at the end of a list, "ADD" naturally comes to mind, but
here it does the opposite, it inserts. Several times already it's been
incorrectly used where ADDQ was expected, the latest of which was a
fortunate accident explained in 6fa922562 ("CLEANUP: stream: explain
why we queue the stream at the head of the server list").

Let's use more explicit (but slightly longer) names now:

   LIST_ADD        ->       LIST_INSERT
   LIST_ADDQ       ->       LIST_APPEND
   LIST_ADDED      ->       LIST_INLIST
   LIST_DEL        ->       LIST_DELETE

The same is true for MT_LISTs, including their "TRY" variant.
LIST_DEL_INIT keeps its short name to encourage to use it instead of the
lazier LIST_DELETE which is often less safe.

The change is large (~674 non-comment entries) but is mechanical enough
to remain safe. No permutation was performed, so any out-of-tree code
can easily map older names to new ones.

The list doc was updated.
2021-04-21 09:20:17 +02:00
Christopher Faulet
3a9a12bb2a BUG/MINOR: hlua: Fix memory leaks on error path when registering a cli keyword
When an error occurred in hlua_register_cli(), the allocated lua function
and keyword must be released to avoid memory leaks.

This patch depends on "MINOR: hlua: Add function to release a lua
function". It may be backported in all stable versions.
2021-04-12 19:05:05 +02:00
Christopher Faulet
5c028d7f9d BUG/MINOR: hlua: Fix memory leaks on error path when registering a service
When an error occurred in hlua_register_service(), the allocated lua
function and keyword must be released to avoid memory leaks.

This patch depends on "MINOR: hlua: Add function to release a lua
function". It may be backported in all stable versions.
2021-04-12 19:04:42 +02:00
Christopher Faulet
4fc9da01d2 BUG/MINOR: hlua: Fix memory leaks on error path when registering an action
When an error occurred in hlua_register_action(), the allocated lua function
and keyword must be released to avoid memory leaks.

This patch depends on "MINOR: hlua: Add function to release a lua
function". It may be backported in all stable versions.
2021-04-12 19:04:42 +02:00
Christopher Faulet
528526f2cc BUG/MINOR: hlua: Fix memory leaks on error path when parsing a lua action
hen an error occurred in action_register_lua(), the allocated hlua rule and
arguments must be released to avoid memory leaks.

This patch may be backported in all stable versions.
2021-04-12 19:04:42 +02:00
Christopher Faulet
2567f18382 BUG/MINOR: hlua: Fix memory leaks on error path when registering a fetch
When an error occurred in hlua_register_fetches(), the allocated lua
function and keyword must be released to avoid memory leaks.

This patch depends on "MINOR: hlua: Add function to release a lua
function". It may be backported in all stable versions. It should fix #1112.
2021-04-12 19:04:42 +02:00
Christopher Faulet
aa22430bba BUG/MINOR: hlua: Fix memory leaks on error path when registering a converter
When an error occurred in hlua_register_converters(), the allocated lua
function and keyword must be released to avoid memory leaks.

This patch depends on "MINOR: hlua: Add function to release a lua
function". It may be backported in all stable versions.
2021-04-12 19:04:42 +02:00
Christopher Faulet
5294ec0708 BUG/MINOR: hlua: Fix memory leaks on error path when registering a task
When an error occurred in hlua_register_task(), the allocated lua context
and task must be released to avoid memory leaks.

This patch may be backported in all stable versions.
2021-04-12 19:04:42 +02:00
Christopher Faulet
dda44442d5 MINOR: hlua: Add function to release a lua function
release_hlua_function() must be used to release a lua function. Some fixes
depends on this function.
2021-04-12 15:46:53 +02:00
Willy Tarreau
4781b1521a CLEANUP: atomic/tree-wide: replace single increments/decrements with inc/dec
This patch replaces roughly all occurrences of an HA_ATOMIC_ADD(&foo, 1)
or HA_ATOMIC_SUB(&foo, 1) with the equivalent HA_ATOMIC_INC(&foo) and
HA_ATOMIC_DEC(&foo) respectively. These are 507 changes over 45 files.
2021-04-07 18:18:37 +02:00
Christopher Faulet
eccb31c939 BUG/MINOR: hlua: Detect end of request when reading data for an HTTP applet
When a script retrieves request data from an HTTP applet, line per line or
not, we must be sure to properly detect the end of the request by checking
HTX_FL_EOM flag when everything was consumed. Otherwise, the script may
hang.

It is pretty easy to reproduce the bug by calling applet:receive() without
specifying any length. If the request is not chunked, the function never
returns.

The bug was introduced when the EOM block was removed. Thus, it is specific
to the 2.4. This patch should fix the issue #1207. No backport needed.
2021-04-06 07:31:51 +02:00
Christopher Faulet
1bb6afa35d MINOR: stream: Use stream type instead of proxy mode when appropriate
We now use the stream instead of the proxy to know if we are processing HTTP
data or not. If the stream is an HTX stream, it means we are dealing with
HTTP data. It is more accurate than the proxy mode because when an HTTP
upgrade is performed, the proxy is not changed and only the stream may be
used.

Note that it was not a problem to rely on the proxy because HTTP upgrades
may only happen when an HTTP backend was set. But, we will add the support
of HTTP upgrades on the frontend side, after te tcp-request rules
evaluation.  In this context, we cannot rely on the proxy mode.
2021-04-01 11:06:48 +02:00
Amaury Denoyelle
704ba1d63e MINOR: lua: properly allocate the lua Socket servers
Instantiate both lua Socket servers tcp/ssl using standard function
new_server. There is currently no need to tune their settings except to
activate the ssl mode with noverify for the second one. Both servers are
freed with the free_server function.
2021-03-26 15:28:33 +01:00
Amaury Denoyelle
239fdbf548 MINOR: lua: properly allocate the lua Socket proxy
Replace static initialization of the lua Socket proxy with the standard
function alloc_new_proxy. The settings proxy are properly applied thanks
to PR_CAP_LUA. The proxy is freed with the free_proxy function.
2021-03-26 15:28:33 +01:00
Christopher Faulet
1e8433f594 BUG/MEDIUM: lua: Always init the lua stack before referencing the context
When a lua context is allocated, its stack must be initialized to NULL
before attaching it to its owner (task, stream or applet).  Otherwise, if
the watchdog is fired before the stack is really created, that may lead to a
segfault because we try to dump the traceback of an uninitialized lua stack.

It is easy to trigger this bug if a lua script do a blocking call while
another thread try to initialize a new lua context. Because of the global
lua lock, the init is blocked before the stack creation. Of course, it only
happens if the script is executed in the shared global context.

This patch must be backported as far as 2.0.
2021-03-24 16:36:36 +01:00
Christopher Faulet
cc2c4f8f4c BUG/MEDIUM: debug/lua: Use internal hlua function to dump the lua traceback
The commit reverts following commits:
  * 83926a04 BUG/MEDIUM: debug/lua: Don't dump the lua stack if not dumpable
  * a61789a1 MEDIUM: lua: Use a per-thread counter to track some non-reentrant parts of lua

Instead of relying on a Lua function to print the lua traceback into the
debugger, we are now using our own internal function (hlua_traceback()).
This one does not allocate memory and use a chunk instead. This avoids any
issue with a possible deadlock in the memory allocator because the thread
processing was interrupted during a memory allocation.

This patch relies on the commit "BUG/MEDIUM: debug/lua: Use internal hlua
function to dump the lua traceback". Both must be backported wherever the
patches above are backported, thus as far as 2.0
2021-03-24 16:35:23 +01:00
Christopher Faulet
d09cc519bd MINOR: lua: Slightly improve function dumping the lua traceback
The separator string is now configurable, passing it as parameter when the
function is called. In addition, the message have been slightly changed to
be a bit more readable.
2021-03-24 16:33:26 +01:00