Hi Willy, On 8/9/23 13:48, Willy Tarreau wrote: > Hi Johannes, > > On Wed, Aug 09, 2023 at 01:02:29PM +0200, Johannes Naab wrote: >> Hi, >> >> I'm trying to use a stick table with general purpose tags (gpt) to do longer >> term (beyond the window itself) maximum connection rate tracking: >> - stick table with conn_rate and one gpt >> - update/set gpt0 if the current conn_rate is greater than what is stored in >> the gpt. >> >> But I have trouble setting the gpt even from a trivial sample expression, >> erroring during config parsing with `internal error, unexpected rule->from=0, >> please report this bug!`. > > At first glance I can't find a reason why your config would not work, > so you've definitely discovered a bug. > > I have no idea what causes it at the moment. A few things you could try, > in any order, to help locate the bug: > > - check if it accepts it using "http-request sc-set-gpt" instead of > "tcp-request connection" so that we know if it's related to the ruleset > or something else ; >
Thanks, that seems to narrow the problem down. "http-request sc-set-gpt" does work, so does "tcp-request session". I.e. the bug seems to depend on "tcp-request connection". "session" works for me, for setting session variables it might even be necessary, but those might be avoidable by setting the conditional directly. (But not trivially since "sub(<value>)" only takes values or variables but not fetches and "-m int gt <value>" only seem to takes direct values). "tcp-request connection" state could be helpful to avoid TLS handshakes. > - please also try sc0-set-gpt(0) instead of sc-set-gpt(0,0), maybe there > is something wrong in the latter's parser. > That does not seem to make any difference. > - does your other test with "int(1)" as the expression also fail or did > it work ? If it did work, maybe forcing a cat to integer on the variable > using "var(proc.baz),add(0)" could work. > Any expression fails in "tcp-request connection", even the more trivial "int(1)", "var(proc.baz),add(0)" does fail as well. > In any case some feedback on these points could be useful. The last two > ones would be safe workarounds if they work. > > For completeness a running/working config for tracking the max conn_rate (https://xkcd.com/979/): ``` frontend foo bind :::8080 v4v6 default_backend bar tcp-request connection track-sc0 src table stick1 ## track max conn_rate tcp-request session set-var(sess.prev_conn_rate) sc_get_gpt(0,0,stick1) tcp-request session set-var(sess.cur_conn_rate) sc_conn_rate(0,stick1) tcp-request session sc-set-gpt(0,0) var(sess.cur_conn_rate) if { var(sess.cur_conn_rate),sub(sess.prev_conn_rate) -m int gt 0 } http-response set-header cur-conn-rate %[var(sess.cur_conn_rate)] http-response set-header prev-conn-rate %[var(sess.prev_conn_rate)] backend stick1 stick-table type ipv6 size 1m expire 1h store conn_rate(10s),gpt(1) ``` Thanks! Johannes >> Config, output, and haproxy -vv below. >> >> Should this work, or do I misunderstand what sc-set-gpt can achieve? > > For me it should work, and if there's a corner case that makes it > impossible with your config, I'm not seeing it and we should report it > in a much more user-friendly way! > > Thanks! > Willy >