REORG: server: use flags for parse_server
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.
diff --git a/src/server.c b/src/server.c
index cbeae85..3c26243 100644
--- a/src/server.c
+++ b/src/server.c
@@ -2326,161 +2326,155 @@
* 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]);
+ /* 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_addr)
- goto skip_addr;
+ /* 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,
- (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;
- }
+ 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 @@
* 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 @@
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 @@
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;
+ int cur_arg;
- 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;
- }
+ 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;
+ }
- 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_IN_PEER_SECTION|SRV_PARSE_PARSE_ADDR)) ==
+ (SRV_PARSE_IN_PEER_SECTION|SRV_PARSE_PARSE_ADDR)) {
+ if (!*args[2])
+ return 0;
+ }
- /* the servers are linked backwards first */
- if (newsrv && !defsrv) {
- newsrv->next = curproxy->srv;
- curproxy->srv = newsrv;
- }
+ 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);
+ }
- if (err_code & ERR_CODE)
- goto out;
+ /* 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: