MEDIUM: server: make use of init-addr

It is now supported. If not set, we default to the legacy methods list
which is "last,libc".
diff --git a/include/proto/server.h b/include/proto/server.h
index f2cca94..41bb31a 100644
--- a/include/proto/server.h
+++ b/include/proto/server.h
@@ -244,6 +244,19 @@
 	return 1;
 }
 
+/* returns the next initaddr method and removes it from <list> by shifting
+ * it right (implying that it MUST NOT be the server's. Returns SRV_IADDR_END
+ * at the end.
+ */
+static inline enum srv_initaddr srv_get_next_initaddr(unsigned int *list)
+{
+	enum srv_initaddr ret;
+
+	ret = *list & 7;
+	*list >>= 3;
+	return ret;
+}
+
 #endif /* _PROTO_SERVER_H */
 
 /*
diff --git a/src/server.c b/src/server.c
index 9da8b27..b4d4f50 100644
--- a/src/server.c
+++ b/src/server.c
@@ -3223,6 +3223,52 @@
 	return 0;
 }
 
+/* returns 0 if no error, otherwise a combination of ERR_* flags */
+static int srv_iterate_initaddr(struct server *srv)
+{
+	int return_code = 0;
+	int err_code;
+	unsigned int methods;
+
+	methods = srv->init_addr_methods;
+	if (!methods) { // default to "last,libc"
+		srv_append_initaddr(&methods, SRV_IADDR_LAST);
+		srv_append_initaddr(&methods, SRV_IADDR_LIBC);
+	}
+
+	while (methods) {
+		err_code = 0;
+		switch (srv_get_next_initaddr(&methods)) {
+		case SRV_IADDR_LAST:
+			if (!srv->lastaddr)
+				continue;
+			if (srv_apply_lastaddr(srv, &err_code) == 0)
+				return return_code;
+			return_code |= err_code;
+			break;
+
+		case SRV_IADDR_LIBC:
+			if (!srv->hostname)
+				continue;
+			if (srv_set_addr_via_libc(srv, &err_code) == 0)
+				return return_code;
+			return_code |= err_code;
+			break;
+
+		default: /* unhandled method */
+			break;
+		}
+	}
+
+	if (!return_code) {
+		Alert("parsing [%s:%d] : 'server %s' : no method found to resolve address '%s'\n",
+		      srv->conf.file, srv->conf.line, srv->id, srv->hostname);
+	}
+
+	return_code |= ERR_ALERT | ERR_FATAL;
+	return return_code;
+}
+
 /*
  * This function parses all backends and all servers within each backend
  * and performs servers' addr resolution based on information provided by:
@@ -3239,27 +3285,14 @@
 	curproxy = proxy;
 	while (curproxy) {
 		struct server *srv;
-		int err_code = 0;
 
 		/* servers are in backend only */
 		if (!(curproxy->cap & PR_CAP_BE))
 			goto srv_init_addr_next;
 
-		for (srv = curproxy->srv; srv; srv = srv->next) {
-			err_code = 0;
-
-			if (srv->lastaddr) {
-				if (srv_apply_lastaddr(srv, &err_code) == 0)
-					continue;
-				return_code |= err_code;
-			}
-
-			if (srv->hostname) {
-				if (srv_set_addr_via_libc(srv, &err_code) == 0)
-					continue;
-				return_code = err_code;
-			}
-		}
+		for (srv = curproxy->srv; srv; srv = srv->next)
+			if (srv->hostname)
+				return_code |= srv_iterate_initaddr(srv);
 
  srv_init_addr_next:
 		curproxy = curproxy->next;