[BUG] peers: don't keep a peers section which has a NULL frontend
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.
diff --git a/src/cfgparse.c b/src/cfgparse.c
index f63c615..39a289a 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -5870,8 +5870,8 @@
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 @@
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: