MINOR: cache: Reject duplicate cache names

Using a duplicate cache name most likely is the result of a misgenerated
configuration. There is no good reason to allow this, as the duplicate
caches can't be referred to.

This commit resolves GitHub issue #820.

It can be argued whether this is a fix for a bug or not. I'm erring on the
side of caution and marking this as a "new feature". It can be considered for
backporting to 2.2, but for other branches the risk of accidentally breaking
some working (but non-ideal) configuration might be too large.
diff --git a/src/cache.c b/src/cache.c
index 4f8d2e0..b422629 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -1176,7 +1176,7 @@
 	if (strcmp(args[0], "cache") == 0) { /* new cache section */
 
 		if (!*args[1]) {
-			ha_alert("parsing [%s:%d] : '%s' expects an <id> argument\n",
+			ha_alert("parsing [%s:%d] : '%s' expects a <name> argument\n",
 				 file, linenum, args[0]);
 			err_code |= ERR_ALERT | ERR_ABORT;
 			goto out;
@@ -1188,6 +1188,8 @@
 		}
 
 		if (tmp_cache_config == NULL) {
+			struct cache *cache_config;
+
 			tmp_cache_config = calloc(1, sizeof(*tmp_cache_config));
 			if (!tmp_cache_config) {
 				ha_alert("parsing [%s:%d]: out of memory.\n", file, linenum);
@@ -1197,10 +1199,20 @@
 
 			strlcpy2(tmp_cache_config->id, args[1], 33);
 			if (strlen(args[1]) > 32) {
-				ha_warning("parsing [%s:%d]: cache id is limited to 32 characters, truncate to '%s'.\n",
+				ha_warning("parsing [%s:%d]: cache name is limited to 32 characters, truncate to '%s'.\n",
 					   file, linenum, tmp_cache_config->id);
 				err_code |= ERR_WARN;
 			}
+
+			list_for_each_entry(cache_config, &caches_config, list) {
+				if (strcmp(tmp_cache_config->id, cache_config->id) == 0) {
+					ha_alert("parsing [%s:%d]: Duplicate cache name '%s'.\n",
+					         file, linenum, tmp_cache_config->id);
+					err_code |= ERR_ALERT | ERR_ABORT;
+					goto out;
+				}
+			}
+
 			tmp_cache_config->maxage = 60;
 			tmp_cache_config->maxblocks = 0;
 			tmp_cache_config->maxobjsz = 0;