]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
REORG: server: use flags for parse_server
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 8 Mar 2021 15:36:46 +0000 (16:36 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 18 Mar 2021 14:37:05 +0000 (15:37 +0100)
Modify the API of parse_server function. Use flags to describe the type
of the parsed server instead of discrete arguments. These flags can be
used to specify if a server/default-server/server-template is parsed.
Additional parameters are also specified (parsing of the address
required, resolve of a name must be done immediately).

It is now unneeded to use strcmp on args[0] in parse_server. Also, the
calls to parse_server are more explicit thanks to the flags.

include/haproxy/server-t.h
include/haproxy/server.h
src/cfgparse-listen.c
src/cfgparse.c
src/resolvers.c
src/server.c
src/sink.c

index e59ba4de19d80d81db874d33711075a1f26f9060..647cdae3dbd13efd4667be7628eb33617f743381 100644 (file)
@@ -432,6 +432,12 @@ struct srv_kw_list {
        struct srv_kw kw[VAR_ARRAY];
 };
 
+#define SRV_PARSE_DEFAULT_SERVER  0x01    /* 'default-server' keyword */
+#define SRV_PARSE_TEMPLATE        0x02    /* 'server-template' keyword */
+#define SRV_PARSE_IN_PEER_SECTION 0x04    /* keyword in a peer section */
+#define SRV_PARSE_PARSE_ADDR      0x08    /* required to parse the server address in the second argument */
+#define SRV_PARSE_INITIAL_RESOLVE 0x10    /* resolve immediately the fqdn to an ip address */
+
 #endif /* _HAPROXY_SERVER_T_H */
 
 /*
index 518c20a0ff50591f23a3d3310f6426cb15c7ca6d..d3dc1d6442a5f7078f80ddc908272b82fd16e029 100644 (file)
@@ -45,7 +45,7 @@ extern struct dict server_key_dict;
 int srv_downtime(const struct server *s);
 int srv_lastsession(const struct server *s);
 int srv_getinter(const struct check *check);
-int parse_server(const char *file, int linenum, char **args, struct proxy *curproxy, const struct proxy *defproxy, int parse_addr, int in_peers_section, int initial_resolve);
+int parse_server(const char *file, int linenum, char **args, struct proxy *curproxy, const struct proxy *defproxy, int parse_flags);
 int srv_update_addr(struct server *s, void *ip, int ip_sin_family, const char *updater);
 const char *srv_update_addr_port(struct server *s, const char *addr, const char *port, char *updater);
 const char *srv_update_check_addr_port(struct server *s, const char *addr, const char *port);
index 07878330f67e3fb3e501e3ec8e5a5eada0ae041b..aa2b5eb07726e515bd0e0819656a001acc527546 100644 (file)
@@ -342,10 +342,27 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
        curproxy->conf.args.line = linenum;
 
        /* Now let's parse the proxy-specific keywords */
-       if (strcmp(args[0], "server") == 0         ||
-           strcmp(args[0], "default-server") == 0 ||
-           strcmp(args[0], "server-template") == 0) {
-               err_code |= parse_server(file, linenum, args, curproxy, curr_defproxy, 1, 0, 0);
+       if ((strcmp(args[0], "server") == 0)) {
+               err_code |= parse_server(file, linenum, args,
+                                        curproxy, curr_defproxy,
+                                        SRV_PARSE_PARSE_ADDR);
+
+               if (err_code & ERR_FATAL)
+                       goto out;
+       }
+       else if (strcmp(args[0], "default-server") == 0) {
+               err_code |= parse_server(file, linenum, args,
+                                        curproxy, curr_defproxy,
+                                        SRV_PARSE_DEFAULT_SERVER);
+
+               if (err_code & ERR_FATAL)
+                       goto out;
+       }
+       else if (strcmp(args[0], "server-template") == 0) {
+               err_code |= parse_server(file, linenum, args,
+                                        curproxy, curr_defproxy,
+                                        SRV_PARSE_TEMPLATE|SRV_PARSE_PARSE_ADDR);
+
                if (err_code & ERR_FATAL)
                        goto out;
        }
index f6ff36161df593ded8006158c7bb0a8074d8b5ae..a718cd6149fb9aef8b5605e0f737d78d9bc2906f 100644 (file)
@@ -706,7 +706,8 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
                        err_code |= ERR_ALERT | ERR_ABORT;
                        goto out;
                }
-               err_code |= parse_server(file, linenum, args, curpeers->peers_fe, NULL, 0, 1, 1);
+               err_code |= parse_server(file, linenum, args, curpeers->peers_fe, NULL,
+                                        SRV_PARSE_DEFAULT_SERVER|SRV_PARSE_IN_PEER_SECTION|SRV_PARSE_INITIAL_RESOLVE);
        }
        else if (strcmp(args[0], "log") == 0) {
                if (init_peers_frontend(file, linenum, NULL, curpeers) != 0) {
@@ -768,6 +769,7 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
        else if (strcmp(args[0], "peer") == 0 ||
                 strcmp(args[0], "server") == 0) { /* peer or server definition */
                int local_peer, peer;
+               int parse_addr = 0;
 
                peer = *args[0] == 'p';
                local_peer = strcmp(args[1], localpeer) == 0;
@@ -815,7 +817,9 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
                 * The server address is parsed only if we are parsing a "peer" line,
                 * or if we are parsing a "server" line and the current peer is not the local one.
                 */
-               err_code |= parse_server(file, linenum, args, curpeers->peers_fe, NULL, peer || !local_peer, 1, 1);
+               parse_addr = (peer || !local_peer) ? SRV_PARSE_PARSE_ADDR : 0;
+               err_code |= parse_server(file, linenum, args, curpeers->peers_fe, NULL,
+                                        SRV_PARSE_IN_PEER_SECTION|parse_addr|SRV_PARSE_INITIAL_RESOLVE);
                if (!curpeers->peers_fe->srv) {
                        /* Remove the newly allocated peer. */
                        if (newpeer != curpeers->local) {
index f3564927fe64545e581fedfd0624455bcf4b428e..c14b9706ad46a78fa667beb7cf83035c61abff52 100644 (file)
@@ -2971,7 +2971,8 @@ int cfg_parse_resolvers(const char *file, int linenum, char **args, int kwm)
                HA_SPIN_INIT(&curr_resolvers->lock);
        }
        else if (strcmp(args[0],"server") == 0) {
-               err_code |= parse_server(file, linenum, args, curr_resolvers->px, NULL, 1, 0, 1);
+               err_code |= parse_server(file, linenum, args, curr_resolvers->px, NULL,
+                                        SRV_PARSE_PARSE_ADDR|SRV_PARSE_INITIAL_RESOLVE);
         }
        else if (strcmp(args[0], "nameserver") == 0) { /* nameserver definition */
                struct dns_nameserver *newnameserver = NULL;
index cbeae85d1a3e01b0ef50a10d2a3d316ac9203634..3c26243f0c26a48e9bcbc7e7c37b267de0d5a95a 100644 (file)
@@ -2326,161 +2326,155 @@ static int _srv_parse_tmpl_init(struct server *srv, struct proxy *px)
  * of memory exhaustion, ERR_ABORT is set. If the server cannot be allocated,
  * <srv> will be set to NULL.
  */
-static int _srv_parse_init(struct server **srv, char **args, int *cur_arg, struct proxy *curproxy,
-                           int parse_addr, int in_peers_section, int initial_resolve,
-                           char **errmsg)
+static int _srv_parse_init(struct server **srv, char **args, int *cur_arg,
+                           struct proxy *curproxy,
+                           int parse_flags, char **errmsg)
 {
        struct server *newsrv = NULL;
        const char *err = NULL;
        int err_code = 0;
        char *fqdn = NULL;
+       int tmpl_range_low = 0, tmpl_range_high = 0;
 
        *srv = NULL;
 
-       if (strcmp(args[0], "server") == 0         ||
-           strcmp(args[0], "peer") == 0           ||
-           strcmp(args[0], "default-server") == 0 ||
-           strcmp(args[0], "server-template") == 0) {
-               int defsrv = (*args[0] == 'd');
-               int srv_kw = !defsrv && (*args[0] == 'p' || strcmp(args[0], "server") == 0);
-               int srv_tmpl = !defsrv && !srv_kw;
-               int tmpl_range_low = 0, tmpl_range_high = 0;
-
-               /* There is no mandatory first arguments for default server. */
-               if (srv_kw && parse_addr) {
-                       if (!*args[2]) {
-                               /* 'server' line number of argument check. */
-                               memprintf(errmsg, "'%s' expects <name> and <addr>[:<port>] as arguments.",
+       /* There is no mandatory first arguments for default server. */
+       if (parse_flags & SRV_PARSE_PARSE_ADDR) {
+               if (parse_flags & SRV_PARSE_TEMPLATE) {
+                       if (!*args[3]) {
+                               /* 'server-template' line number of argument check. */
+                               memprintf(errmsg, "'%s' expects <prefix> <nb | range> <addr>[:<port>] as arguments.",
                                          args[0]);
                                err_code |= ERR_ALERT | ERR_FATAL;
                                goto out;
                        }
 
-                       err = invalid_char(args[1]);
+                       err = invalid_prefix_char(args[1]);
                }
-               else if (srv_tmpl) {
-                       if (!*args[3]) {
-                               /* 'server-template' line number of argument check. */
-                               memprintf(errmsg, "'%s' expects <prefix> <nb | range> <addr>[:<port>] as arguments.",
+               else {
+                       if (!*args[2]) {
+                               /* 'server' line number of argument check. */
+                               memprintf(errmsg, "'%s' expects <name> and <addr>[:<port>] as arguments.",
                                          args[0]);
                                err_code |= ERR_ALERT | ERR_FATAL;
                                goto out;
                        }
 
-                       err = invalid_prefix_char(args[1]);
+                       err = invalid_char(args[1]);
                }
 
                if (err) {
                        memprintf(errmsg, "character '%c' is not permitted in %s %s '%s'.",
-                                 *err, args[0], srv_kw ? "name" : "prefix", args[1]);
+                                 *err, args[0], !(parse_flags & SRV_PARSE_TEMPLATE) ? "name" : "prefix", args[1]);
                        err_code |= ERR_ALERT | ERR_FATAL;
                        goto out;
                }
+       }
 
-               *cur_arg = 2;
-               if (srv_tmpl) {
-                       /* Parse server-template <nb | range> arg. */
-                       if (_srv_parse_tmpl_range(newsrv, args[*cur_arg], &tmpl_range_low, &tmpl_range_high) < 0) {
-                               memprintf(errmsg, "Wrong %s number or range arg '%s'.",
-                                         args[0], args[*cur_arg]);
-                               err_code |= ERR_ALERT | ERR_FATAL;
-                               goto out;
-                       }
-                       (*cur_arg)++;
+       *cur_arg = 2;
+       if (parse_flags & SRV_PARSE_TEMPLATE) {
+               /* Parse server-template <nb | range> arg. */
+               if (_srv_parse_tmpl_range(newsrv, args[*cur_arg], &tmpl_range_low, &tmpl_range_high) < 0) {
+                       memprintf(errmsg, "Wrong %s number or range arg '%s'.",
+                                 args[0], args[*cur_arg]);
+                       err_code |= ERR_ALERT | ERR_FATAL;
+                       goto out;
                }
+               (*cur_arg)++;
+       }
 
-               if (!defsrv) {
-                       struct sockaddr_storage *sk;
-                       int port1, port2, port;
+       if (!(parse_flags & SRV_PARSE_DEFAULT_SERVER)) {
+               struct sockaddr_storage *sk;
+               int port1, port2, port;
 
-                       *srv = newsrv = new_server(curproxy);
-                       if (!newsrv) {
-                               memprintf(errmsg, "out of memory.");
-                               err_code |= ERR_ALERT | ERR_ABORT;
-                               goto out;
-                       }
+               *srv = newsrv = new_server(curproxy);
+               if (!newsrv) {
+                       memprintf(errmsg, "out of memory.");
+                       err_code |= ERR_ALERT | ERR_ABORT;
+                       goto out;
+               }
 
-                       if (srv_tmpl) {
-                               newsrv->tmpl_info.nb_low = tmpl_range_low;
-                               newsrv->tmpl_info.nb_high = tmpl_range_high;
-                       }
+               if (parse_flags & SRV_PARSE_TEMPLATE) {
+                       newsrv->tmpl_info.nb_low = tmpl_range_low;
+                       newsrv->tmpl_info.nb_high = tmpl_range_high;
+               }
 
-                       /* Note: for a server template, its id is its prefix.
-                        * This is a temporary id which will be used for server allocations to come
-                        * after parsing.
-                        */
-                       if (srv_kw)
-                               newsrv->id = strdup(args[1]);
-                       else
-                               newsrv->tmpl_info.prefix = strdup(args[1]);
-
-                       /* several ways to check the port component :
-                        *  - IP    => port=+0, relative (IPv4 only)
-                        *  - IP:   => port=+0, relative
-                        *  - IP:N  => port=N, absolute
-                        *  - IP:+N => port=+N, relative
-                        *  - IP:-N => port=-N, relative
-                        */
-                       if (!parse_addr)
-                               goto skip_addr;
-
-                       sk = str2sa_range(args[*cur_arg], &port, &port1, &port2, NULL, NULL,
-                                         errmsg, NULL, &fqdn,
-                                         (initial_resolve ? PA_O_RESOLVE : 0) | PA_O_PORT_OK | PA_O_PORT_OFS | PA_O_STREAM | PA_O_XPRT | PA_O_CONNECT);
-                       if (!sk) {
-                               memprintf(errmsg, "'%s %s' : %s", args[0], args[1], *errmsg);
-                               err_code |= ERR_ALERT | ERR_FATAL;
-                               goto out;
-                       }
+               /* Note: for a server template, its id is its prefix.
+                * This is a temporary id which will be used for server allocations to come
+                * after parsing.
+                */
+               if (!(parse_flags & SRV_PARSE_TEMPLATE))
+                       newsrv->id = strdup(args[1]);
+               else
+                       newsrv->tmpl_info.prefix = strdup(args[1]);
+
+               /* several ways to check the port component :
+                *  - IP    => port=+0, relative (IPv4 only)
+                *  - IP:   => port=+0, relative
+                *  - IP:N  => port=N, absolute
+                *  - IP:+N => port=+N, relative
+                *  - IP:-N => port=-N, relative
+                */
+               if (!(parse_flags & SRV_PARSE_PARSE_ADDR))
+                       goto skip_addr;
+
+               sk = str2sa_range(args[*cur_arg], &port, &port1, &port2, NULL, NULL,
+                                 errmsg, NULL, &fqdn,
+                                 (parse_flags & SRV_PARSE_INITIAL_RESOLVE ? PA_O_RESOLVE : 0) | PA_O_PORT_OK | PA_O_PORT_OFS | PA_O_STREAM | PA_O_XPRT | PA_O_CONNECT);
+               if (!sk) {
+                       memprintf(errmsg, "'%s %s' : %s", args[0], args[1], *errmsg);
+                       err_code |= ERR_ALERT | ERR_FATAL;
+                       goto out;
+               }
 
-                       if (!port1 || !port2) {
-                               /* no port specified, +offset, -offset */
-                               newsrv->flags |= SRV_F_MAPPORTS;
-                       }
+               if (!port1 || !port2) {
+                       /* no port specified, +offset, -offset */
+                       newsrv->flags |= SRV_F_MAPPORTS;
+               }
 
-                       /* save hostname and create associated name resolution */
-                       if (fqdn) {
-                               if (fqdn[0] == '_') { /* SRV record */
-                                       /* Check if a SRV request already exists, and if not, create it */
-                                       if ((newsrv->srvrq = find_srvrq_by_name(fqdn, curproxy)) == NULL)
-                                               newsrv->srvrq = new_resolv_srvrq(newsrv, fqdn);
-                                       if (newsrv->srvrq == NULL) {
-                                               err_code |= ERR_ALERT | ERR_FATAL;
-                                               goto out;
-                                       }
-                               }
-                               else if (srv_prepare_for_resolution(newsrv, fqdn) == -1) {
-                                       memprintf(errmsg, "Can't create DNS resolution for server '%s'",
-                                                 newsrv->id);
+               /* save hostname and create associated name resolution */
+               if (fqdn) {
+                       if (fqdn[0] == '_') { /* SRV record */
+                               /* Check if a SRV request already exists, and if not, create it */
+                               if ((newsrv->srvrq = find_srvrq_by_name(fqdn, curproxy)) == NULL)
+                                       newsrv->srvrq = new_resolv_srvrq(newsrv, fqdn);
+                               if (newsrv->srvrq == NULL) {
                                        err_code |= ERR_ALERT | ERR_FATAL;
                                        goto out;
                                }
                        }
-
-                       newsrv->addr = *sk;
-                       newsrv->svc_port = port;
-                       // we don't need to lock the server here, because
-                       // we are in the process of initializing
-                       srv_set_addr_desc(newsrv);
-
-                       if (!newsrv->srvrq && !newsrv->hostname && !protocol_by_family(newsrv->addr.ss_family)) {
-                               memprintf(errmsg, "Unknown protocol family %d '%s'",
-                                         newsrv->addr.ss_family, args[*cur_arg]);
+                       else if (srv_prepare_for_resolution(newsrv, fqdn) == -1) {
+                               memprintf(errmsg, "Can't create DNS resolution for server '%s'",
+                                         newsrv->id);
                                err_code |= ERR_ALERT | ERR_FATAL;
                                goto out;
                        }
+               }
 
-                       (*cur_arg)++;
- skip_addr:
-                       /* Copy default server settings to new server settings. */
-                       srv_settings_cpy(newsrv, &curproxy->defsrv, 0);
-                       HA_SPIN_INIT(&newsrv->lock);
-               } else {
-                       *srv = newsrv = &curproxy->defsrv;
-                       *cur_arg = 1;
-                       newsrv->resolv_opts.family_prio = AF_INET6;
-                       newsrv->resolv_opts.accept_duplicate_ip = 0;
+               newsrv->addr = *sk;
+               newsrv->svc_port = port;
+               // we don't need to lock the server here, because
+               // we are in the process of initializing
+               srv_set_addr_desc(newsrv);
+
+               if (!newsrv->srvrq && !newsrv->hostname && !protocol_by_family(newsrv->addr.ss_family)) {
+                       memprintf(errmsg, "Unknown protocol family %d '%s'",
+                                 newsrv->addr.ss_family, args[*cur_arg]);
+                       err_code |= ERR_ALERT | ERR_FATAL;
+                       goto out;
                }
+
+               (*cur_arg)++;
+ skip_addr:
+               /* Copy default server settings to new server settings. */
+               srv_settings_cpy(newsrv, &curproxy->defsrv, 0);
+               HA_SPIN_INIT(&newsrv->lock);
+       }
+       else {
+               *srv = newsrv = &curproxy->defsrv;
+               *cur_arg = 1;
+               newsrv->resolv_opts.family_prio = AF_INET6;
+               newsrv->resolv_opts.accept_duplicate_ip = 0;
        }
 
        free(fqdn);
@@ -2501,9 +2495,9 @@ out:
  * A mask of errors is returned. ERR_FATAL is set if the parsing should be
  * interrupted.
  */
-static int _srv_parse_kw(struct server *srv, int defsrv, char **args, int *cur_arg, struct proxy *curproxy,
-                         int parse_addr, int in_peers_section, int initial_resolve,
-                         char **errmsg)
+static int _srv_parse_kw(struct server *srv, char **args, int *cur_arg,
+                         struct proxy *curproxy,
+                         int parse_flags, char **errmsg)
 {
        int err_code = 0;
        struct srv_kw *kw;
@@ -2529,7 +2523,7 @@ static int _srv_parse_kw(struct server *srv, int defsrv, char **args, int *cur_a
                goto out;
        }
 
-       if (defsrv && !kw->default_ok) {
+       if ((parse_flags & SRV_PARSE_DEFAULT_SERVER) && !kw->default_ok) {
                memprintf(errmsg, "'%s' option is not accepted in default-server sections",
                          args[*cur_arg]);
                err_code = ERR_ALERT;
@@ -2606,87 +2600,79 @@ static int _srv_parse_finalize(char **args, int cur_arg,
        return 0;
 }
 
-int parse_server(const char *file, int linenum, char **args, struct proxy *curproxy,
-                 const struct proxy *defproxy, int parse_addr, int in_peers_section, int initial_resolve)
+int parse_server(const char *file, int linenum, char **args,
+                 struct proxy *curproxy, const struct proxy *defproxy,
+                 int parse_flags)
 {
        struct server *newsrv = NULL;
        char *errmsg = NULL;
        int err_code = 0;
 
-       if (strcmp(args[0], "server") == 0         ||
-           strcmp(args[0], "peer") == 0           ||
-           strcmp(args[0], "default-server") == 0 ||
-           strcmp(args[0], "server-template") == 0) {
-               int cur_arg;
-               int defsrv = (*args[0] == 'd');
-               int srv = !defsrv && (*args[0] == 'p' || strcmp(args[0], "server") == 0);
-               int srv_tmpl = !defsrv && !srv;
-
-               if (!defsrv && curproxy == defproxy) {
-                       ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
-                       err_code |= ERR_ALERT | ERR_FATAL;
-                       goto out;
-               }
-               else if (failifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL)) {
-                       err_code |= ERR_ALERT | ERR_FATAL;
-                       goto out;
-               }
+       int cur_arg;
 
-               if (srv && parse_addr) {
-                       if (!*args[2]) {
-                               if (in_peers_section)
-                                       return 0;
-                       }
-               }
-               err_code = _srv_parse_init(&newsrv, args, &cur_arg, curproxy,
-                                          parse_addr, in_peers_section, initial_resolve, &errmsg);
-               if (errmsg) {
-                       ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
-                       free(errmsg);
-               }
+       if (!(parse_flags & SRV_PARSE_DEFAULT_SERVER) && curproxy == defproxy) {
+               ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
+               err_code |= ERR_ALERT | ERR_FATAL;
+               goto out;
+       }
+       else if (failifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL)) {
+               err_code |= ERR_ALERT | ERR_FATAL;
+               goto out;
+       }
 
-               /* the servers are linked backwards first */
-               if (newsrv && !defsrv) {
-                       newsrv->next = curproxy->srv;
-                       curproxy->srv = newsrv;
-               }
+       if ((parse_flags & (SRV_PARSE_IN_PEER_SECTION|SRV_PARSE_PARSE_ADDR)) ==
+           (SRV_PARSE_IN_PEER_SECTION|SRV_PARSE_PARSE_ADDR)) {
+               if (!*args[2])
+                       return 0;
+       }
 
-               if (err_code & ERR_CODE)
-                       goto out;
+       err_code = _srv_parse_init(&newsrv, args, &cur_arg, curproxy,
+                                  parse_flags, &errmsg);
+       if (errmsg) {
+               ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
+               free(errmsg);
+       }
+
+       /* the servers are linked backwards first */
+       if (newsrv && !(parse_flags & SRV_PARSE_DEFAULT_SERVER)) {
+               newsrv->next = curproxy->srv;
+               curproxy->srv = newsrv;
+       }
 
-               newsrv->conf.file = strdup(file);
-               newsrv->conf.line = linenum;
+       if (err_code & ERR_CODE)
+               goto out;
 
-               while (*args[cur_arg]) {
-                       errmsg = NULL;
-                       err_code |= _srv_parse_kw(newsrv, defsrv, args, &cur_arg,
-                                                 curproxy,
-                                                 parse_addr, in_peers_section, initial_resolve, &errmsg);
+       newsrv->conf.file = strdup(file);
+       newsrv->conf.line = linenum;
 
-                       if (err_code & ERR_ALERT) {
-                               display_parser_err(file, linenum, args, cur_arg, err_code, &errmsg);
-                               free(errmsg);
-                       }
+       while (*args[cur_arg]) {
+               errmsg = NULL;
+               err_code = _srv_parse_kw(newsrv, args, &cur_arg, curproxy,
+                                        parse_flags, &errmsg);
 
-                       if (err_code & ERR_FATAL)
-                               goto out;
+               if (err_code & ERR_ALERT) {
+                       display_parser_err(file, linenum, args, cur_arg, err_code, &errmsg);
+                       free(errmsg);
                }
 
-               if (!defsrv) {
-                       err_code |= _srv_parse_finalize(args, cur_arg, newsrv, curproxy, &errmsg);
-                       if (err_code) {
-                               display_parser_err(file, linenum, args, cur_arg, err_code, &errmsg);
-                               free(errmsg);
-                       }
+               if (err_code & ERR_FATAL)
+                       goto out;
+       }
 
-                       if (err_code & ERR_FATAL)
-                               goto out;
+       if (!(parse_flags & SRV_PARSE_DEFAULT_SERVER)) {
+               err_code |= _srv_parse_finalize(args, cur_arg, newsrv, curproxy, &errmsg);
+               if (err_code) {
+                       display_parser_err(file, linenum, args, cur_arg, err_code, &errmsg);
+                       free(errmsg);
                }
 
-               if (srv_tmpl)
-                       _srv_parse_tmpl_init(newsrv, curproxy);
+               if (err_code & ERR_FATAL)
+                       goto out;
        }
 
+       if (parse_flags & SRV_PARSE_TEMPLATE)
+               _srv_parse_tmpl_init(newsrv, curproxy);
+
        return 0;
 
  out:
index 88dbe9095778107800c3707c201108e9b8df4e3f..f734b07c938392fcf7f0aaa1446aafeadff3497a 100644 (file)
@@ -812,7 +812,8 @@ int cfg_parse_ring(const char *file, int linenum, char **args, int kwm)
                }
        }
        else if (strcmp(args[0],"server") == 0) {
-               err_code |= parse_server(file, linenum, args, cfg_sink->forward_px, NULL, 1, 0, 1);
+               err_code |= parse_server(file, linenum, args, cfg_sink->forward_px, NULL,
+                                        SRV_PARSE_PARSE_ADDR|SRV_PARSE_INITIAL_RESOLVE);
        }
        else if (strcmp(args[0],"timeout") == 0) {
                if (!cfg_sink || !cfg_sink->forward_px) {