Commit Graph

238 Commits

Author SHA1 Message Date
Willy Tarreau
6204cd9f27 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.
2016-03-10 17:28:04 +01:00
Willy Tarreau
7560dd4b6a 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.
2016-03-10 16:42:58 +01:00
Willy Tarreau
1777ea63e0 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.
2016-03-10 16:42:58 +01:00
Willy Tarreau
be508f1580 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.
2016-03-10 16:42:58 +01:00
Thierry Fournier
9d5fb6d6a0 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
2016-02-23 22:42:47 +01:00
Thierry Fournier
0164f200ab 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.
2016-02-20 18:55:33 +01:00
Thierry Fournier
e726b14d23 DOC: lua: copyrights 2016-02-19 13:24:21 +01:00
Thierry Fournier
9e7e3ea991 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.
2016-02-12 11:08:53 +01:00
Thierry Fournier
fb0b5467ca 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.
2016-02-12 11:08:53 +01:00
Thierry Fournier
75933d48fe 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.
2016-02-11 19:30:19 +01:00
Thierry FOURNIER
8db004cbf4 MINOR: lua: add set/get priv for applets
The applet can't have access to the session private data. This patch
fix this problem. Now an applet can use private data stored by actions
and fecthes.
2015-12-25 10:34:28 +01:00
Thierry FOURNIER
ed0bdaa623 CLEANUP: lua: bad error messages
An error message reference "register_service" in place of
"register_action".

This one should be backported to 1.6.
2015-12-20 23:13:01 +01:00
Thierry FOURNIER
52e2606188 BUG/MAJOR: lua: Do not force the HTTP analysers in use-services
INNER and XFERBODY analyzer were set in order to support HTTP applets
from TCP rulesets, but this does not work (cf previous patch).

Other cases already provides theses analyzers, so their addition is
not needed. Furthermore if INNER was set it could cause some headers
to be rewritten (ex: connection) after headers were already forwarded,
resulting in a crash in buffer_insert_line2().

Special thanks to Bernd Helm for providing very detailed information,
captures and stack traces making it possible to spot the root cause
here.

This fix must be backported to 1.6.
2015-12-20 23:13:01 +01:00
Thierry FOURNIER
718e2a73a2 BUG/MEDIUM: lua: Forbid HTTP applets from being called from tcp rulesets
HTTP applets request requires everything initilized by
"http_process_request" (analyzer flag AN_REQ_HTTP_INNER).
The applet will be immediately initilized, but its before
the call of this analyzer.

Due to this problem HTTP applets could be called with uncompletely
initialized http_txn.

This fix must be backported to 1.6.
2015-12-20 23:13:01 +01:00
Thierry FOURNIER
d93ea2b603 BUG/MINOR: lua: Lua applets must not use http_txn
In certain circumstances (eg: Lua HTTP applet called from a
TCP ruleset before http_process_request()), the HTTP TXN is not
yet fully initialized so some information it contains cannot be
relied on. Such information include the HTTP version, the state
of the expect: 100-continue header, the connection header and
the transfer-encoding header.

Here the bug only turns something which already doesn't work
into something wrong, but better avoid any references to the
http_txn from the Lua code to avoid future mistakes.

This patch should be backported into 1.6 for code consistency.
2015-12-20 23:13:00 +01:00
Thierry FOURNIER
ca98866bcf BUG/MEDIUM: lua: Lua applets must not fetch samples using http_txn
If a sample fetch needing http_txn is called from an HTTP Lua applet,
the result will be invalid and may even cause a crash because some HTTP
data can be forwarded and the HTTP txn is no longer valid.

Here the solution is to ensure that a fetch called from Lua never
needs http_txn. This is done thanks to a new flag HLUA_F_MAY_USE_HTTP
which indicates whether or not it is safe to call a fetch which needs
HTTP.

This fix needs to be backported to 1.6.
2015-12-20 23:13:00 +01:00
Thierry FOURNIER
7fa0549a2b REORG/MINOR: lua: convert boolean "int" to bitfield
This patch converts a boolean "int" to a bitfiled. The main
reason is to save space in the struct if another flag may will
be require.

Note that this patch is required for next fix and will need to be
backported to 1.6.
2015-12-20 23:13:00 +01:00
Thierry FOURNIER
841475e304 MINOR: lua: service/applet can have access to the HTTP headers when a POST is received
When a POST is processed by a Lua service, the HTTP header are
potentially gone. So, we cannot retrieve their content using
the standard "hdr" sample fetchs (which will soon become invalid
anyway) from an applet.

This patch add an entry "headers" to the object applet_http. This
entry is an array containing all the headers. It permits to use the
HTTP headers during the processing of the service.

Many thanks to Jan Bruder for reporting this issue with enough
details to reproduce it.

This patch will have to be backported to 1.6 since it will be the
only way to access headers from Lua applets.
2015-12-20 23:12:12 +01:00
Lukas Tribus
d334a2c843 BUG/MINOR: lua: don't force-sslv3 LUA's SSL socket
Sander Klein reported an error messages about SSLv3 not
being supported on Debian 8, although he didn't force-sslv3.

Vincent Bernat tracked this down to the LUA initialization, which
actually does force-sslv3.

This patch removes force-sslv3 from the LUA initialization, so
the LUA SSL socket can actually use TLS and doesn't trigger
warnings when SSLv3 is not supported by libssl (such as in
Debian 8).

This should be backported to 1.6.
2015-11-26 07:30:22 +01:00
Thierry FOURNIER
a3308fd8c1 BUG/MEDIUM: lua: clean output buffer
When the txn.done() fiunction is called, the ouput buffer is cleaned,
but the associated relative pointer on the HTTP requests elements
is not reseted.

This patch remove this cleanup, because the output buffer may contain
data to forward.
2015-11-06 01:15:34 +01:00
Thierry FOURNIER
c4eebc8157 BUG/MEDIUM: lua: sample fetches based on response doesn't work
The direction (request or response) is not propagated in the
sample fecthes called throught Lua. This patch adds the direction
status in some structs (hlua_txn and hlua_smp) to make sure that
the sample fetches will be called with all the information.

The converters can not access to a TXN object, so there are not
impacted the direction. However, the samples used as input of the
Lua converter wrapper are initiliazed with the direction. Thereby,
the struct smp stay consistent.
[wt: needs to be backported to 1.6]
2015-11-03 10:50:14 +01:00
Thierry FOURNIER
6e01f38e73 CLEANUP: use direction names in place of numeric values
This patch cleanups the direction names. It replaces numeric values,
by the associated defines. It ensure the compliance with values found
somwhere else in HAProxy.

It is required by the bugfix patch which is following.
[wt: needs to be backported to 1.6]
2015-11-03 10:48:00 +01:00
Thierry FOURNIER
26a7aacaff BUG/MEDIUM: lua: direction test failed
Lua needs to known the direction of the http data processed (request or
response). It checks the flag SMP_OPT_DIR_REQ, buf this flag is 0. This patch
correctly checks the flags after applying the SMP_OPT_DIR mask.
2015-10-13 15:49:31 +02:00
Vincent Bernat
a72db18243 MINOR: lua: fix a spelling error in some error messages
"unknown" was spelled "unkown".
2015-10-10 08:13:37 +02:00
Willy Tarreau
0078bfcb43 BUG/MEDIUM: lua: force server-close mode on Lua services
Thierry reported that keep-alive still didn't cope well with Lua
services. The reason is that for now applets have to be closed at
the end of a transaction so we want to work in server-close mode,
which isn't noticeable by the client since it still sees keep-alive.
Additionally we want to enable the request body transfer analyser
which will be needed to synchronize with the response analyser to
indicate the end of the transfer.
2015-10-07 20:24:05 +02:00
Thierry FOURNIER
56da1012d2 MINOR: lua: rename the tune.lua.applet-timeout
The name of applet is "service", so this patch renames the
tune.lua.applet-timeout to tune.lua.service-timeout
2015-10-02 22:56:10 +02:00
Thierry FOURNIER
10770faf8e MEDIUM: lua: change the timeout execution
Now, the Lua timeout is relative to the effective run time.
When the Lua is waiting for I/O, this time is not took in
lua run time account.
2015-09-29 19:13:49 +02:00
Thierry FOURNIER
bee90aeda1 MINOR: lua: remove the run flag
Only the main execution function can set the run flag, because it is
the last function before the execution time.

This patch removes the flag set by another function. It will be used
by the new lua timeout counter.
2015-09-29 18:57:03 +02:00
Thierry FOURNIER
a30b5dbf85 MINOR: lua: add AppletHTTP class and service
This class is used by Lua code for running as an applet called in HTTP mode
It defines also the associated lua service
2015-09-28 01:03:48 +02:00
Thierry FOURNIER
f0a64b676f MINOR: lua: add AppletTCP class and service
This class is used by Lua code for running as an applet called in TCP mode.
It defines also the lua service.
2015-09-28 01:03:48 +02:00
Thierry FOURNIER
2f3867f429 BUG/MEDIUM: lua: don't reset undesired flags in hlua_ctx_resume
Some flags like HLUA_MUST_GC must not be cleared otherwise sessions are
not properly cleaned.
2015-09-28 01:03:43 +02:00
Thierry FOURNIER
7c39ab4ac2 OPTIM/MEDIUM: lua: executes the garbage collector only when using cosocket
The garbage collector is a little bit heavy to run, and it was added
only for cosockets. This patch prevent useless executions when no
cosockets are used.
2015-09-27 22:56:40 +02:00
Thierry FOURNIER
6ab4d8ec0e MEDIUM: lua: change the GC policy
The GC is run each times that an Lua function exit with an error or with a success.
2015-09-27 22:22:37 +02:00
Thierry FOURNIER
6d695e6314 BUG/MEDIUM: lua: socket destroy before reading pending data
When the channel is down, the applet is waked up. Before this patch,
the applet closes the stream and the unread data are discarded.

After this patch, the stream is not closed except if the buffers are
empty.

It will be closed later by the close function, or by the garbage collector.
2015-09-27 21:50:26 +02:00
Thierry FOURNIER
8c8fbbe103 MINOR: lua/applet: the cosocket applet should use appctx_wakeup in place of task_wakeup
It seems that in the new applet system, the applet me be wakeup with the
function appctx_wakeup() in place of the function task_wakeup().
2015-09-27 19:30:26 +02:00
Thierry FOURNIER
c2f5653452 MINOR: lua: extend socket address to support non-IP families
The HAProxy Lua socket respects the Lua Socket tcp specs. these specs
are a little bit limited, it not permits to connect to unix socket.

this patch extends a little it the specs. It permit to accept a
syntax that begin with "unix@", "ipv4@", "ipv6@", "fd@" or "abns@".
2015-09-27 15:04:32 +02:00
Willy Tarreau
528192d310 MEDIUM: lua: only allow actions to yield if not in a final call
Actions may yield but must not do it during the final call from a ruleset
because it indicates there will be no more opportunity to complete or
clean up. This is indicated by ACT_FLAG_FINAL in the action's flags,
which must be passed to hlua_resume().

Thanks to this, an action called from a TCP ruleset is properly woken
up and possibly finished when the client disconnects.
2015-09-27 11:04:19 +02:00
Willy Tarreau
658b85b68d MEDIUM: actions: pass a new "flags" argument to custom actions
Since commit bc4c1ac ("MEDIUM: http/tcp: permit to resume http and tcp
custom actions"), some actions may yield and be called back when new
information are available. Unfortunately some of them may continue to
yield because they simply don't know that it's the last call from the
rule set. For this reason we'll need to pass a flag to the custom
action to pass such information and possibly other at the same time.
2015-09-27 11:04:06 +02:00
Thierry FOURNIER
eba6f64a5f BUG/MEDIUM: lua: wakeup task on bad conditions
the condition was :
 * wakeup for read if the output channel contains data
 * wakeup for write if the input channel have some room.
2015-09-27 11:03:19 +02:00
Thierry FOURNIER
5a50a85f4f BUG/MEDIUM: lua: forces a garbage collection
When a thread stops this patch forces a garbage collection which
cleanup and free the memory.

The HAProxy Lua Socket class contains an HAProxy session, so it
uses a big amount of memory, in other this Socket class uses a
filedescriptor and maintain a connection open.

If the class Socket is stored in a global variable, the Socket stay
alive along of the life of the process (except if it is closed by the
other size, or if a timeout is reached). If the class Socket is stored
in a local variable, it must die with this variable.

The socket is closed by a call from the garbage collector. And the
portability and use of a variable is known by the same garbage collector.

so, running the GC just after the end of all Lua code ensure that the
heavy resources like the socket class are freed quickly.
2015-09-27 11:03:08 +02:00
Willy Tarreau
3adac08849 BUG/MEDIUM: lua: properly set the target on the connection
Not having the target set on the connection causes it to be released
at the last moment, and the destination address to randomly be valid
depending on the data found in the memory at this moment. In practice
it works as long as memory poisonning is disabled. The deep reason is
that connect_server() doesn't expect to be called with SF_ADDR_SET and
an existing connection with !reuse. This causes the release of the
connection, its reallocation (!reuse), and taking the address from the
newly allocated connection. This should certainly be improved.
2015-09-26 17:56:23 +02:00
Willy Tarreau
9af89f7905 BUG/MEDIUM: lua: better fix for the protocol check
Commit d75cb0f ("BUG/MAJOR: lua: segfault after the channel data is
modified by some Lua action.") introduced a regression causing an
action run from a TCP rule in an HTTP proxy to end in HTTP error
if it terminated cleanly, because it didn't parse the HTTP request!

Relax the test so that it takes into account the opportunity for the
analysers to parse the message.
2015-09-26 11:50:08 +02:00
Willy Tarreau
de70fa17a9 MINOR: lua: use the proper applet wakeup mechanism
The lua code must the the appropriate wakeup mechanism for cosockets.
It wakes them up from outside the stream and outside the applet, so it
shouldn't use the applet's wakeup callback which is designed only for
use from within the applet itself. For now it didn't cause any trouble
(yet).
2015-09-26 11:25:05 +02:00
Thierry FOURNIER
10e5bc76c7 BUG/MEDIUM: lua: longjmp function must be unregistered
the longjmp function must be unregistered when we leaves the function
who install it.
2015-09-26 01:34:29 +02:00
Willy Tarreau
7a4501757f CLEANUP: lua: remove unneeded memset(0) after calloc()
No need for these memset() anymore, since calloc() was put there
to avoid them.
2015-09-26 01:33:24 +02:00
Thierry FOURNIER
3c7a77c0e7 CLEANUP: lua: use calloc in place of malloc
calloc is safer because it fills the allocated memory zone with zeros.
2015-09-26 01:32:06 +02:00
Thierry FOURNIER
d75cb0fce6 BUG/MAJOR: lua: segfault after the channel data is modified by some Lua action.
When an action or a fetch modify the channel data, the http request parser
pointer become inconsistent. This patch detects the modification and call
again the parser.
2015-09-26 00:37:55 +02:00
Thierry FOURNIER
84e73c8882 MEDIUM: lua: use the function lua_rawset in place of lua_settable
The function lua_settable uses the metatable for acessing data,
so in the C part, we want to index value in the real table and
not throught the meta-methods. It's much faster this way.
2015-09-26 00:37:35 +02:00
Thierry FOURNIER
d2a3dcc8bd MINOR: lua: identify userdata objects
This patch adds lua primitives for identifying lua class
associated with userdata.
2015-09-25 23:40:20 +02:00
Thierry FOURNIER
a7b536b53b MINOR: lua: reset pointer after use
After releasing the Lua environment, this patch set the only one pointer to
the Lua stack to NULL. This prevents an accidental re-use.
2015-09-25 23:40:02 +02:00