[PATCH] Implement and use generic findproxy and relax duplicated proxy check

From: Krzysztof Oledzki <ole#ans.pl>
Date: Sat, 03 Nov 2007 23:45:06 +0100


From 75ff987b5693047f91360e707e7b35e008df3bf9 Mon Sep 17 00:00:00 2001 From: Krzysztof Piotr Oledzki <ole#ans.pl> Date: Sat, 3 Nov 2007 23:41:58 +0100
Subject: [MEDIUM] Implement and use generic findproxy and relax duplicated proxy check

This patch:

diff --git a/include/proto/proxy.h b/include/proto/proxy.h index 38d7325..839cce5 100644
--- a/include/proto/proxy.h
+++ b/include/proto/proxy.h

@@ -32,8 +32,10 @@ void soft_stop(void);  void pause_proxy(struct proxy *p);
 void pause_proxies(void);
 void listen_proxies(void);
-const char *proxy_type_str(struct proxy *proxy);  

+const char *proxy_type_str(struct proxy *proxy);
+const char *proxy_mode_str(int mode);
+struct proxy *findproxy(const char *name, int mode, int cap);
 

 #endif /* _PROTO_PROXY_H */  

diff --git a/src/cfgparse.c b/src/cfgparse.c index 5e6ce4e..fc333bf 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c

@@ -539,9 +539,8 @@ int cfg_parse_listen(const char *file, int linenum, char **args)

 			if (!strcmp(curproxy->id, args[1]) &&
 				(rc!=(PR_CAP_FE|PR_CAP_RS) || curproxy->cap!=(PR_CAP_BE|PR_CAP_RS)) &&
 				(rc!=(PR_CAP_BE|PR_CAP_RS) || curproxy->cap!=(PR_CAP_FE|PR_CAP_RS))) {
-				Alert("parsing %s: duplicated proxy %s with conflicting capabilities: %X/%X!\n",
-					file, args[1], curproxy->cap, rc);
-				return -1;

+ Warning("Parsing [%s:%d]: duplicated proxy '%s' with conflicting capabilities: %s/%s!\n",
+ file, linenum, args[1], proxy_type_str(curproxy), args[0]);
} } @@ -2529,21 +2528,14 @@ int readcfgfile(const char *file) if (curproxy->defbe.name) { struct proxy *target; - for (target = proxy; target != NULL; target = target->next) { - if ((target->cap & PR_CAP_BE) && !strcmp(target->id, curproxy->defbe.name)) - break; - } - if (target == NULL) { - Alert("parsing %s: default proxy '%s' with backend capability in HTTP %s '%s' was not found!\n", - file, curproxy->defbe.name, proxy_type_str(curproxy), curproxy->id);
+ target = findproxy(curproxy->defbe.name, curproxy->mode, PR_CAP_BE);
+ if (!target) {
+ Alert("Proxy '%s': unable to find required default_backend: '%s'.\n",
+ curproxy->id, curproxy->defbe.name);
cfgerr++; } else if (target == curproxy) { - Alert("parsing %s : loop detected for default backend %s !\n", file, curproxy->defbe.name); - cfgerr++; - } else if (target->mode != curproxy->mode) { - Alert("parsing %s : default backend '%s' in HTTP %s '%s' is not of same mode (tcp/http) !\n", - file, curproxy->defbe.name, proxy_type_str(curproxy), curproxy->id); - cfgerr++;
+ Alert("Proxy '%s': loop detected for default_backend: '%s'.\n",
+ curproxy->id, curproxy->defbe.name);
} else { free(curproxy->defbe.name); curproxy->defbe.be = target; @@ -2554,24 +2546,20 @@ int readcfgfile(const char *file) if (curproxy->mode == PR_MODE_HTTP && curproxy->req_exp != NULL) { /* map jump target for ACT_SETBE in req_rep chain */ struct hdr_exp *exp; - struct proxy *target; for (exp = curproxy->req_exp; exp != NULL; exp = exp->next) {
+ struct proxy *target;
+
if (exp->action != ACT_SETBE) continue; - for (target = proxy; target != NULL; target = target->next) { - if ((target->cap & PR_CAP_BE) && !strcmp(target->id, exp->replace)) - break; - } - if (target == NULL) { - Alert("parsing %s: proxy '%s' with backend capability in HTTP %s '%s' was not found!\n", - file, exp->replace, proxy_type_str(curproxy), curproxy->id);
+
+ target = findproxy(exp->replace, PR_MODE_HTTP, PR_CAP_BE);
+ if (!target) {
+ Alert("Proxy '%s': unable to find required setbe: '%s'.\n",
+ curproxy->id, exp->replace);
cfgerr++; } else if (target == curproxy) { - Alert("parsing %s : loop detected for backend %s !\n", file, exp->replace); - cfgerr++; - } else if (target->mode != PR_MODE_HTTP) { - Alert("parsing %s : backend '%s' in HTTP %s '%s' is not HTTP (use 'mode http') !\n", - file, exp->replace, proxy_type_str(curproxy), curproxy->id);
+ Alert("Proxy '%s': loop detected for setbe: '%s'.\n",
+ curproxy->id, exp->replace);
cfgerr++; } else { free((void *)exp->replace);

@@ -2582,24 +2570,17 @@ int readcfgfile(const char *file)  
 		/* find the target proxy for 'use_backend' rules */
 		list_for_each_entry(rule, &curproxy->switching_rules, list) {
-			/* map jump target for ACT_SETBE in req_rep chain */ 
 			struct proxy *target;
 
-			for (target = proxy; target != NULL; target = target->next) {
-				if ((target->cap & PR_CAP_BE) && !strcmp(target->id, rule->be.name))
-					break;
-			}

+ target = findproxy(rule->be.name, curproxy->mode, PR_CAP_BE);
- if (target == NULL) { - Alert("parsing %s: proxy '%s' with backend capability in HTTP %s '%s' was not found!\n", - file, rule->be.name, proxy_type_str(curproxy), curproxy->id);
+ if (!target) {
+ Alert("Proxy '%s': unable to find required use_backend: '%s'.\n",
+ curproxy->id, rule->be.name);
cfgerr++; } else if (target == curproxy) { - Alert("parsing %s : loop detected for backend %s !\n", file, rule->be.name); - cfgerr++; - } else if (target->mode != curproxy->mode) { - Alert("parsing %s : backend '%s' referenced in %s '%s' is of different mode !\n", - file, rule->be.name, proxy_type_str(curproxy), curproxy->id);
+ Alert("Proxy '%s': loop detected for use_backend: '%s'.\n",
+ curproxy->id, rule->be.name);
cfgerr++; } else { free((void *)rule->be.name);

diff --git a/src/proxy.c b/src/proxy.c
index 435a1e2..1f54818 100644
--- a/src/proxy.c
+++ b/src/proxy.c

@@ -55,6 +55,57 @@ const char *proxy_type_str(struct proxy *proxy)

                 return "proxy";
 }  

+/*
+ * This function returns a string containing the mode of the proxy in a format
+ * suitable for error messages.
+ */
+
+const char *proxy_mode_str(int mode) {
+
+ if (mode == PR_MODE_TCP)
+ return "tcp";
+ else if (mode == PR_MODE_HTTP)
+ return "http";
+ else if (mode == PR_MODE_HEALTH)
+ return "health";
+ else
+ return "unknown";
+}
+
+/*
+ * This function finds a proxy with matching name, mode and with satisfying
+ * capabilities. It also checks if there are more matching proxies with
+ * requested name as this often leads into unexpected situations.
+ */
+
+struct proxy *findproxy(const char *name, int mode, int cap) {
+
+ struct proxy *curproxy, *target=NULL;
+
+ for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
+ if ((curproxy->cap & cap)!=cap || strcmp(curproxy->id, name))
+ continue;
+
+ if (curproxy->mode != mode) {
+ Alert("Unable to use proxy '%s' with wrong mode, required: %s, has: %s.\n",
+ name, proxy_mode_str(mode), proxy_mode_str(curproxy->mode));
+ Alert("You may want to use 'mode %s'.\n", proxy_mode_str(mode));
+ return NULL;
+ }
+
+ if (!target) {
+ target = curproxy;
+ continue;
+ }
+
+ Alert("Refusing to use duplicated proxy '%s' with conflicting capabilities: %s/%s!\n",
+ name, proxy_type_str(curproxy), proxy_type_str(target));
+
+ return NULL;
+ }
+
+ return target;
+}
 

 /*

Received on 2007/11/03 23:45

This archive was generated by hypermail 2.2.0 : 2007/11/04 19:21 CET