]> git.kaiwu.me - haproxy.git/commit
BUG/MINOR: resolvers: do not index resolvers names in the proxies
authorWilly Tarreau <w@1wt.eu>
Wed, 22 Jul 2026 13:17:38 +0000 (15:17 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 22 Jul 2026 14:02:32 +0000 (16:02 +0200)
commit0f441a843ce2454bb212d0eac2455f1aa4c0e42f
tree374347b5f8039a205f2d412e448bd0fc8a5c566c
parentca686e32084d7aed18b01d45f51eb6079c02d9da
BUG/MINOR: resolvers: do not index resolvers names in the proxies

Resolvers are self-sustaining sections that have their own list, but for
the purpose of supporting TCP connections, a backend proxy is created
with them, and it holds the same name as the section. Since we started
to create a "default" resolvers section, a similarly named backend in
TCP mode automatically appeared, resulting in issues such as the one
described in GH #3445:

   defaults
       mode http

   frontend public
       bind :8001
       default_backend default

It yells: "... tries to use incompatible tcp proxy 'default' (<internal>:0)
in a 'use_backend' rule (see 'mode')" because it in fact finds the hidden
resolvers proxy. Depending on versions, adding such a default backend makes
the issue go away or not.

Worse, the following config:

   frontend public
       bind :8001
       default_backend default

actually routes the traffic to the local resolvers :-(

Resolvers do not need to appear in proxies index tree, as they're looked
up by find_resolvers_by_id() which iterates over all resolvers sections
(i.e. tree not used), so we can safely avoid indexing them.

Some other proxies are now protected against this via the use of PR_CAP_INT
which also prevents indexing, but that flag changed multiple times along
versions and is extremely sensitive in older ones, to the point of not
being suitable for a backport.

Instead, commit 116983ad94 ("MEDIUM: cfgparse: do not store unnamed
defaults in name tree") added the following test to refrain from
indexing an unnamed proxy in setup_new_proxy():

  @@ -1718,7 +1718,8 @@ int setup_new_proxy(struct proxy *px, const char *name, unsigned int cap, char *
          px->cap = cap;
          px->last_change = ns_to_sec(now_ns);

  -       if (name && !(cap & PR_CAP_INT))
  +       /* Internal proxies or with empty name are not stored in the named tree. */
  +       if (name && name[0] != '\0' && !(cap & PR_CAP_INT))
                  proxy_store_name(px);

          if (!(cap & PR_CAP_DEF))

This part is totally suitable for backporting and permits to simply
change the resolvers' proxy creation to pass NULL or an empty string
instead of the resolvers section's name so that we don't index that
proxy. That's what this patch does. For versions before 3.4, the
commented patch above must be explicitly backported. This patch must
be backported to 3.0. Thanks to Lukasz Nowak for reporting this bug.

It's worth noting that this area is really falling apart and urgently
needs attention. The internal API is currently too limited to permit
reliable lookups, which is the reason why so many proxies are hidden
that way. In an ideal world, all names would be indexed and caps and
modes properly set to unambiguous values, so that lookup functions
only look up specific caps and modes, and support being passed a mask
to avoid matching undesired caps. At the very least a mask should be
given in lookups, and a few extra caps should permit to distinguish
regular proxies (those declared with the "frontend" and "backend"
keyword, supporting use_backend) from other ones (rings, resolvers,
log-forward etc).
src/resolvers.c