Grant Byers
Modifying TCP payload via LUA action & yield issues
May 15, 2018 03:20AM
Hi all,

Is it at all feasible to modify a TCP payload via a custom LUA action
in a stable manner? ie, something like this;


function enrich_query(txn)
--- Duplicate request. :set() will replace the request, if possible
local req = txn.req:dup()

-- if error or client closes connection, quit
if req == nil then return end

--- Add an identifier for haproxy and include client's IP address.
if txn.req:set("-Vha1.8," .. txn.f:src() .. " " .. req) == -1 then
txn.Error(txn, "Failed to enrich query")
end
end

core.register_action('enrich_query', {'tcp-req'}, enrich_query)


Then called as an action in the frontend;

# Don't enrich if query already contains client identification
acl has_client_version req.payload(0,0) -m sub -- -V --client

# Enrich our query
tcp-request content lua.enrich_query if !has_client_version
WAIT_END


The reason I ask is that I randomly get yield errors, I assume during
the txn.req:set() ;

Lua function 'enrich_query': yield not allowed.


I have experimented with different values of tune.lua.forced-yield with
little success. Sometimes this occurs very infrequently, other times,
very frequently.

FYI - I have experimented with PROXY, but our backend application is
using a java API that doesn't have native PROXY support (although
there's been a patch pending for about 5 years). Have also experimented
with PROXY and Cloudflare's "mmproxy". That works well, but i've been
asked to use LUA to extend haproxy if possible.


Thanks,
Grant
Thierry FOURNIER
Re: Modifying TCP payload via LUA action & yield issues
May 18, 2018 02:20PM
Hi Grant,

It seems to be a bug. The action should allow yield.

Could you have a method for reproducing the bug ?

Thierry


On Tue, 15 May 2018 01:11:46 +0000
Grant Byers <[email protected]> wrote:

> Hi all,
>
> Is it at all feasible to modify a TCP payload via a custom LUA action
> in a stable manner? ie, something like this;
>
>
> function enrich_query(txn)
> --- Duplicate request. :set() will replace the request, if possible
> local req = txn.req:dup()
>
> -- if error or client closes connection, quit
> if req == nil then return end
>
> --- Add an identifier for haproxy and include client's IP address.
> if txn.req:set("-Vha1.8," .. txn.f:src() .. " " .. req) == -1 then
> txn.Error(txn, "Failed to enrich query")
> end
> end
>
> core.register_action('enrich_query', {'tcp-req'}, enrich_query)
>
>
> Then called as an action in the frontend;
>
> # Don't enrich if query already contains client identification
> acl has_client_version req.payload(0,0) -m sub -- -V --client
>
> # Enrich our query
> tcp-request content lua.enrich_query if !has_client_version
> WAIT_END
>
>
> The reason I ask is that I randomly get yield errors, I assume during
> the txn.req:set() ;
>
> Lua function 'enrich_query': yield not allowed.
>
>
> I have experimented with different values of tune.lua.forced-yield with
> little success. Sometimes this occurs very infrequently, other times,
> very frequently.
>
> FYI - I have experimented with PROXY, but our backend application is
> using a java API that doesn't have native PROXY support (although
> there's been a patch pending for about 5 years). Have also experimented
> with PROXY and Cloudflare's "mmproxy". That works well, but i've been
> asked to use LUA to extend haproxy if possible.
>
>
> Thanks,
> Grant
Anonymous User
Re: Modifying TCP payload via LUA action & yield issues
May 18, 2018 02:30PM
Could you change your configuration to test a workaround ?

After the line:

tcp-request content lua.enrich_query if !has_client_version

Add a fake action:

tcp-request set-var(req.wa) int(0)

Tell me if this work around fix the issue.

Thierry


On Tue, 15 May 2018 01:11:46 +0000
Grant Byers <[email protected]> wrote:

> Hi all,
>
> Is it at all feasible to modify a TCP payload via a custom LUA action
> in a stable manner? ie, something like this;
>
>
> function enrich_query(txn)
> --- Duplicate request. :set() will replace the request, if possible
> local req = txn.req:dup()
>
> -- if error or client closes connection, quit
> if req == nil then return end
>
> --- Add an identifier for haproxy and include client's IP address.
> if txn.req:set("-Vha1.8," .. txn.f:src() .. " " .. req) == -1 then
> txn.Error(txn, "Failed to enrich query")
> end
> end
>
> core.register_action('enrich_query', {'tcp-req'}, enrich_query)
>
>
> Then called as an action in the frontend;
>
> # Don't enrich if query already contains client identification
> acl has_client_version req.payload(0,0) -m sub -- -V --client
>
> # Enrich our query
> tcp-request content lua.enrich_query if !has_client_version
> WAIT_END
>
>
> The reason I ask is that I randomly get yield errors, I assume during
> the txn.req:set() ;
>
> Lua function 'enrich_query': yield not allowed.
>
>
> I have experimented with different values of tune.lua.forced-yield with
> little success. Sometimes this occurs very infrequently, other times,
> very frequently.
>
> FYI - I have experimented with PROXY, but our backend application is
> using a java API that doesn't have native PROXY support (although
> there's been a patch pending for about 5 years). Have also experimented
> with PROXY and Cloudflare's "mmproxy". That works well, but i've been
> asked to use LUA to extend haproxy if possible.
>
>
> Thanks,
> Grant
Anonymous User
Re: Modifying TCP payload via LUA action & yield issues
May 18, 2018 02:50PM
Hi,

I can reproduce the bug, forgot my previous workaround proposition and just add an inspect delay:

https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-tcp-request%20inspect-delay
tcp-request inspect-delay 10s

If some actions can't be executed because it have no data, haproxy wait
XX seconds for more data. In this case, the yield is allowed during at
mean 10s.

Thierry



On Fri, 18 May 2018 14:22:20 +0200
thierry.fournier@arpalert.org wrote:

> Could you change your configuration to test a workaround ?
>
> After the line:
>
> tcp-request content lua.enrich_query if !has_client_version
>
> Add a fake action:
>
> tcp-request set-var(req.wa) int(0)
>
> Tell me if this work around fix the issue.
>
> Thierry
>
>
> On Tue, 15 May 2018 01:11:46 +0000
> Grant Byers <[email protected]> wrote:
>
> > Hi all,
> >
> > Is it at all feasible to modify a TCP payload via a custom LUA action
> > in a stable manner? ie, something like this;
> >
> >
> > function enrich_query(txn)
> > --- Duplicate request. :set() will replace the request, if possible
> > local req = txn.req:dup()
> >
> > -- if error or client closes connection, quit
> > if req == nil then return end
> >
> > --- Add an identifier for haproxy and include client's IP address.
> > if txn.req:set("-Vha1.8," .. txn.f:src() .. " " .. req) == -1 then
> > txn.Error(txn, "Failed to enrich query")
> > end
> > end
> >
> > core.register_action('enrich_query', {'tcp-req'}, enrich_query)
> >
> >
> > Then called as an action in the frontend;
> >
> > # Don't enrich if query already contains client identification
> > acl has_client_version req.payload(0,0) -m sub -- -V --client
> >
> > # Enrich our query
> > tcp-request content lua.enrich_query if !has_client_version
> > WAIT_END
> >
> >
> > The reason I ask is that I randomly get yield errors, I assume during
> > the txn.req:set() ;
> >
> > Lua function 'enrich_query': yield not allowed.
> >
> >
> > I have experimented with different values of tune.lua.forced-yield with
> > little success. Sometimes this occurs very infrequently, other times,
> > very frequently.
> >
> > FYI - I have experimented with PROXY, but our backend application is
> > using a java API that doesn't have native PROXY support (although
> > there's been a patch pending for about 5 years). Have also experimented
> > with PROXY and Cloudflare's "mmproxy". That works well, but i've been
> > asked to use LUA to extend haproxy if possible.
> >
> >
> > Thanks,
> > Grant
>
Sorry, only registered users may post in this forum.

Click here to login