]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[BUG] peers: don't keep a peers section which has a NULL frontend
authorWilly Tarreau <w@1wt.eu>
Wed, 7 Sep 2011 19:24:49 +0000 (21:24 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 7 Sep 2011 20:47:43 +0000 (22:47 +0200)
If a peers section has no peer named as the local peer, we must destroy
it, otherwise a NULL peer frontend remains in the lists and a segfault
can happen upon a soft restart.

We also now report the missing peer name in order to help troubleshooting.

src/cfgparse.c

index f63c615419a311fee52310899bacd7615526fcc4..39a289af36f24a71dd8e030eff3a5e77591770fa 100644 (file)
@@ -5870,8 +5870,8 @@ int check_config_validity()
                                cfgerr++;
                        }
                        else if (!curpeers->peers_fe) {
-                               Alert("Proxy '%s': unable to identify local peer in peers section '%s'.\n",
-                                     curproxy->id, curpeers->id);
+                               Alert("Proxy '%s': unable to find local peer '%s' in peers section '%s'.\n",
+                                     curproxy->id, localpeer, curpeers->id);
                                cfgerr++;
                        }
                }
@@ -6553,6 +6553,43 @@ out_uri_auth_compat:
                                global.last_checks |= cfg_opts2[optnum].checks;
        }
 
+       if (peers) {
+               struct peers *curpeers = peers, **last;
+               struct peer *p, *pb;
+
+               /* Remove all peers sections which don't have a valid listener.
+                * This can happen when a peers section is never referenced and
+                * does not contain a local peer.
+                */
+               last = &peers;
+               while (*last) {
+                       curpeers = *last;
+                       if (curpeers->peers_fe) {
+                               last = &curpeers->next;
+                               continue;
+                       }
+
+                       Warning("Removing incomplete section 'peers %s' (no peer named '%s').\n",
+                               curpeers->id, localpeer);
+
+                       p = curpeers->remote;
+                       while (p) {
+                               pb = p->next;
+                               free(p->id);
+                               free(p);
+                               p = pb;
+                       }
+
+                       /* Destroy and unlink this curpeers section.
+                        * Note: curpeers is backed up into *last.
+                        */
+                       free(curpeers->id);
+                       curpeers = curpeers->next;
+                       free(*last);
+                       *last = curpeers;
+               }
+       }
+
        if (cfgerr > 0)
                err_code |= ERR_ALERT | ERR_FATAL;
  out: