]> git.ipfire.org Git - thirdparty/haproxy.git/commit
MEDIUM: pattern: always consider gen_id for pat_ref lookup operations
authorAurelien DARRAGON <adarragon@haproxy.com>
Wed, 20 Nov 2024 18:03:00 +0000 (19:03 +0100)
committerAurelien DARRAGON <adarragon@haproxy.com>
Tue, 26 Nov 2024 15:12:31 +0000 (16:12 +0100)
commitaa69a02d7fe9d9024024fb8d12c34b18dc29c843
tree9278e0118cd48fc23906c455e807b6e24db1bbe8
parent010c34b8c776504528d454f231e3b0cbe73d1c95
MEDIUM: pattern: always consider gen_id for pat_ref lookup operations

Historically, pat_ref lookup operations were performed on the whole
pat_ref elements list. As such, set, find and delete operations on a given
key would cause any matching element in pat_ref to be considered.

When prepare/commit operations were added, gen_id was impelemnted in
order to be able to work on a subset from pat_ref without impacting
the current (live) version from pat_ref, until a new subset is committed
to replace the current one.

While the logic was good, there remained a design flaw from the historical
implementation: indeed, legacy functions such as pat_ref_set(),
pat_ref_delete() and pat_ref_find_elt() kept performing the lookups on the
whole set of elements instead of considering only elements from the current
subset. Because of this, mixing new prepare/commit operations with legacy
operations could yield unexpected results.

For instance, before this commit:

  echo "add map #0 key oldvalue" | socat /tmp/ha.sock -
  echo "prepare map #0" | socat /tmp/ha.sock -
  New version created: 1
  echo "add map @1 #0 key newvalue" | socat /tmp/ha.sock -
  echo "del map #0 key" | socat /tmp/ha.sock -
  echo "commit map @1 #0" | socat /tmp/ha.sock -

  -> the result would be that "key" entry doesn't exist anymore after the
  commit, while we would expect the new value to be there instead.

Thanks to the previous commits, we may finally fix this issue: for set,
find_elt and delete operations, the current generation id is considered.

With the above example, it means that the "del map #0 key" would only
target elements from the current subset, thus elements in "version 1" of
the map would be immune to the delete (as we would expect it to work).
src/pattern.c