MEDIUM: vars: replace the global name index with a hash

The global table of known variables names can only grow and was designed
for static names that are registered at boot. Nowadays it's possible to
set dynamic variable names from Lua or from the CLI, which causes a real
problem that was partially addressed in 2.2 with commit 4e172c93f
("MEDIUM: lua: Add `ifexist` parameter to `set_var`"). Please see github
issue #624 for more context.

This patch simplifies all this by removing the need for a central
registry of known names, and storing 64-bit hashes instead. This is
highly sufficient given the low number of variables in each context.
The hash is calculated using XXH64() which is bijective over the 64-bit
space thus is guaranteed collision-free for 1..8 chars. Above that the
risk remains around 1/2^64 per extra 8 chars so in practice this is
highly sufficient for our usage. A random seed is used at boot to seed
the hash so that it's not attackable from Lua for example.

There's one particular nit though. The "ifexist" hack mentioned above
is now limited to variables of scope "proc" only, and will only match
variables that were already created or declared, but will now verify
the scope as well. This may affect some bogus Lua scripts and SPOE
agents which used to accidentally work because a similarly named
variable used to exist in a different scope. These ones may need to be
fixed to comply with the doc.

Now we can sum up the situation as this one:
  - ephemeral variables (scopes sess, txn, req, res) will always be
    usable, regardless of any prior declaration. This effectively
    addresses the most problematic change from the commit above that
    in order to work well could have required some script auditing ;

  - process-wide variables (scope proc) that are mentioned in the
    configuration, referenced in a "register-var-names" SPOE directive,
    or created via "set-var" in the global section or the CLI, are
    permanent and will always accept to be set, with or without the
    "ifexist" restriction (SPOE uses this internally as well).

  - process-wide variables (scope proc) that are only created via a
    set-var() tcp/http action, via Lua's set_var() calls, or via an
    SPOE with the "force-set-var" directive), will not be permanent
    but will always accept to be replaced once they are created, even
    if "ifexist" is present

  - process-wide variables (scope proc) that do not exist will only
    support being created via the set-var() tcp/http action, Lua's
    set_var() calls without "ifexist", or an SPOE declared with
    "force-set-var".

This means that non-proc variables do not care about "ifexist" nor
prior declaration, and that using "ifexist" should most often be
reliable in Lua and that SPOE should most often work without any
prior declaration. It may be doable to turn "ifexist" to 1 by default
in Lua to further ease the transition. Note: regtests were adjusted.

Cc: Tim Düsterhus <tim@bastelstu.be>
diff --git a/reg-tests/lua/set_var.vtc b/reg-tests/lua/set_var.vtc
index 5ca49b6..0c8a4b1 100644
--- a/reg-tests/lua/set_var.vtc
+++ b/reg-tests/lua/set_var.vtc
@@ -23,18 +23,35 @@
     frontend fe2
         mode http
         bind "fd@${fe2}"
-
-        http-request set-header Dummy %[var(txn.fe2_foo)]
+        # just make sure the variable exists
+        http-request set-header Dummy %[var(proc.fe2_foo)]
 
         http-request use-service lua.set_var_ifexist
 } -start
 
 client c0 -connect ${h1_fe1_sock} {
+    # create var
     txreq -url "/" \
         -hdr "Var: txn.fe1_foo"
     rxresp
     expect resp.status == 202
     expect resp.http.echo == "value"
+
+    # rewrite var
+    txreq -url "/" \
+        -hdr "Var: txn.fe1_foo"
+    rxresp
+    expect resp.status == 202
+    expect resp.http.echo == "value"
+
+    # create var under scope "proc"
+    txreq -url "/" \
+        -hdr "Var: proc.fe1_foo"
+    rxresp
+    expect resp.status == 202
+    expect resp.http.echo == "value"
+
+    # fail to create bad scope
     txreq -url "/" \
         -hdr "Var: invalid.var"
     rxresp
@@ -43,14 +60,24 @@
 } -run
 
 client c1 -connect ${h1_fe2_sock} {
+    # this one exists in the conf, it must succeed
     txreq -url "/" \
-        -hdr "Var: txn.fe2_foo"
+        -hdr "Var: proc.fe2_foo"
     rxresp
     expect resp.status == 202
     expect resp.http.echo == "value"
+
+    # this one does not exist in the conf, it must fail
     txreq -url "/" \
-        -hdr "Var: txn.fe2_bar"
+        -hdr "Var: proc.fe2_bar"
     rxresp
     expect resp.status == 400
     expect resp.http.echo == "(nil)"
+
+    # this one is under txn, it must succeed
+    txreq -url "/" \
+        -hdr "Var: txn.fe2_foo"
+    rxresp
+    expect resp.status == 202
+    expect resp.http.echo == "value"
 } -run