From 014f037b219d328d501ac90cc046efa9b84b3a32 Mon Sep 17 00:00:00 2001
From: Quentin Armitage <quentin@armitage.org.uk>
Date: Mon, 25 Jul 2022 18:06:24 +0100
Subject: [PATCH] check: use last entry if duplicate definition

Commits 8a3f145 - "fix mem leaks when virtualhost and snmp_name
are duplicate" and 86bbb2e - "fix mem leaks when virtualhost is
duplicate" changed the behaviour of virtualhost and snmp_name
configuration if there were duplicate definitions to use the
first defined entry, whereas previously the last defined entry
was used, albeit with a memory leak.

This commit retains the memory leak fixes, but reverts the
behaviour to use the last definition rather than the first.

Signed-off-by: Quentin Armitage <quentin@armitage.org.uk>
Conflict: adapt the input parameter of set_string function because the pre patch 516032ec39169d05c613de0e8ee10845658748ff reconstructs the configuration resolution
Reference: https://github.com/acassen/keepalived/commit/014f037b219d328d501ac90cc046efa9b84b3a32
---
 keepalived/check/check_http.c   |  4 ++--
 keepalived/check/check_parser.c |  8 ++++----
 lib/parser.c                    | 10 ++++++++++
 lib/parser.h                    |  1 +
 4 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/keepalived/check/check_http.c b/keepalived/check/check_http.c
index e5f4dfa..4b1f3f3 100644
--- a/keepalived/check/check_http.c
+++ b/keepalived/check/check_http.c
@@ -463,7 +463,7 @@ virtualhost_handler(const vector_t *strvec)
 		return;
 	}
 
-	http_get_chk->virtualhost = set_value(strvec);
+	set_string(&http_get_chk->virtualhost, strvec, "virtualhost");
 }
 
 static void
@@ -592,7 +592,7 @@ url_virtualhost_handler(const vector_t *strvec)
 		return;
 	}
 
-	url->virtualhost = set_value(strvec);
+	set_string(&url->virtualhost, strvec, "url virtualhost");
 }
 
 static void
diff --git a/keepalived/check/check_parser.c b/keepalived/check/check_parser.c
index a962581..ec8f779 100644
--- a/keepalived/check/check_parser.c
+++ b/keepalived/check/check_parser.c
@@ -607,7 +607,7 @@ vs_virtualhost_handler(const vector_t *strvec)
 		return;
 	}
 
-	vs->virtualhost = set_value(strvec);
+	set_string(&vs->virtualhost, strvec, "vs virtualhost");
 }
 
 #ifdef _WITH_SNMP_CHECKER_
@@ -621,7 +621,7 @@ vs_snmp_name_handler(const vector_t *strvec)
 		return;
 	}
 
-	vs->snmp_name = set_value(strvec);
+	set_string(&vs->snmp_name, strvec, "vs snmp_name");
 }
 #endif
 
@@ -891,7 +891,7 @@ rs_virtualhost_handler(const vector_t *strvec)
 		return;
 	}
 
-	rs->virtualhost = set_value(strvec);
+	set_string(&rs->virtualhost, strvec, "rs virtualhost");
 }
 
 #ifdef _WITH_SNMP_CHECKER_
@@ -906,7 +906,7 @@ rs_snmp_name_handler(const vector_t *strvec)
 		return;
 	}
 
-	rs->snmp_name = set_value(strvec);
+	set_string(&rs->snmp_name, strvec, "rs snmp_name");
 }
 #endif
 
diff --git a/lib/parser.c b/lib/parser.c
index bcabd07..68a6e49 100644
--- a/lib/parser.c
+++ b/lib/parser.c
@@ -804,6 +804,16 @@ read_hex_str(const char *str, uint8_t **data, uint8_t **data_mask)
 	return len;
 }
 
+void
+set_string(const char **var, const vector_t *strvec, const char *param_name)
+{
+	if (*var) {
+		report_config_error(CONFIG_GENERAL_ERROR, "Duplicate %s - overwriting %s with %s", param_name, *var, strvec_slot(strvec, 1));
+		FREE_CONST_PTR(*var);
+	}
+	*var = set_value(strvec);
+}
+
 void
 set_random_seed(unsigned int seed)
 {
diff --git a/lib/parser.h b/lib/parser.h
index 994eeb3..4fa0988 100644
--- a/lib/parser.h
+++ b/lib/parser.h
@@ -116,6 +116,7 @@ set_value_r(const vector_t *strvec)
 #endif
 
 /* Prototypes */
+extern void set_string(const char **, const vector_t *, const char *);
 extern void report_config_error(config_err_t, const char *format, ...)
 	__attribute__((format (printf, 2, 3)));
 extern void use_disk_copy_for_config(const char *);
-- 
2.33.0

