MEDIUM: server: make use of init-addr
authorWilly Tarreau <w@1wt.eu>
Fri, 4 Nov 2016 14:10:17 +0000 (15:10 +0100)
committerWilly Tarreau <w@1wt.eu>
Wed, 9 Nov 2016 14:30:47 +0000 (15:30 +0100)
It is now supported. If not set, we default to the legacy methods list
which is "last,libc".

include/proto/server.h
src/server.c

index f2cca94..41bb31a 100644 (file)
@@ -244,6 +244,19 @@ static inline int srv_append_initaddr(unsigned int *list, enum srv_initaddr addr
        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 */
 
 /*
index 9da8b27..b4d4f50 100644 (file)
@@ -3223,6 +3223,52 @@ static int srv_apply_lastaddr(struct server *srv, int *err_code)
        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 @@ int srv_init_addr(void)
        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;