Re: Maybe too strict check for frontend/backend name conflicts

From: Krzysztof Oledzki <ole#ans.pl>
Date: Fri, 2 Nov 2007 03:09:01 +0100 (CET)

On Fri, 2 Nov 2007, Krzysztof Oledzki wrote:

<CUT>

>> I will see if I find a way to do that test very easily, but I think I
>> have an idea.
>
> Actually, I believe one of my patches, I have developed for some time, can be
> very easily adopted to do this. If you can wait a day or two I can post
> finished version with this additional improvement.

Here it is, much faster than previously announced. ;) Below you can find the stripped version of mentioned patch, with unready parts removed, but extended to do what I hope you had expected. RFC quality so not for commit this time.

This patch:

diff -Nur haproxy-1.3.13-orig/include/proto/proxy.h haproxy-1.3.13-gpf/include/proto/proxy.h

--- haproxy-1.3.13-orig/include/proto/proxy.h	2007-10-18 22:38:22.000000000 +0200
+++ haproxy-1.3.13-gpf/include/proto/proxy.h	2007-11-02 02:14:14.000000000 +0100
@@ -33,7 +33,7 @@
  void pause_proxies(void);
  void listen_proxies(void);
  const char *proxy_type_str(struct proxy *proxy); -
+const char *proxy_mode_str(int mode);

  #endif /* _PROTO_PROXY_H */

diff -Nur haproxy-1.3.13-orig/src/cfgparse.c haproxy-1.3.13-gpf/src/cfgparse.c

--- haproxy-1.3.13-orig/src/cfgparse.c	2007-11-02 01:12:24.000000000 +0100
+++ haproxy-1.3.13-gpf/src/cfgparse.c	2007-11-02 03:02:15.000000000 +0100
@@ -494,6 +494,38 @@
  	tv_eternity(&defproxy.appsession_timeout);
  }
+struct proxy *findproxy(const char *name, int mode) {
+
+	struct proxy *curproxy, *target=NULL;
+
+	for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
+		if (!(curproxy->cap & PR_CAP_BE) || 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 man want to use 'mode %s'.\n", proxy_mode_str(mode));
+			return NULL;
+		}
+
+		if (!target) {
+			target = curproxy;
+			continue;
+		}
+
+		Alert("Refused to use duplicated proxy '%s' with conflicting capabilities: %X/%X!\n",
+			name, curproxy->cap, target->cap);
+
+		return NULL;
+	}
+
+	if (!target)
+		Alert("Proxy '%s' with backend capability was not found!\n", name);
+ 
+	return target;
+}
+
  /*

                  if ((curproxy = (struct proxy *)calloc(1, sizeof(struct proxy))) == NULL) { @@ -2553,21 +2584,14 @@

  		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);
+			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;
@@ -2578,24 +2602,20 @@
  		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);
+				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);

@@ -2606,24 +2626,17 @@
  		/* 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);

-			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 -Nur haproxy-1.3.13-orig/src/proxy.c haproxy-1.3.13-gpf/src/proxy.c
--- haproxy-1.3.13-orig/src/proxy.c	2007-10-18 22:38:22.000000000 +0200
+++ haproxy-1.3.13-gpf/src/proxy.c	2007-11-02 02:13:59.000000000 +0100
@@ -54,6 +54,22 @@
  		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";
+}

  /*

Best regards,

                                         Krzysztof Olędzki Received on 2007/11/02 03:09

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