mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-12 08:49:29 +00:00
MINOR: cfgparse: SSL/TLS binding in "peers" sections.
Make "bind" keywork be supported in "peers" sections. All "bind" settings are supported on this line. Add "default-bind" option to parse the binding options excepted the bind address. Do not parse anymore the bind address for local peers on "server" lines. Do not use anymore list_for_each_entry() to set the "peers" section listener parameters because there is only one listener by "peers" section. May be backported to 1.5 and newer.
This commit is contained in:
parent
1055e687a2
commit
355b2033ec
@ -39,7 +39,7 @@
|
||||
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, struct proxy *defproxy);
|
||||
int parse_server(const char *file, int linenum, char **args, struct proxy *curproxy, struct proxy *defproxy, int parse_addr);
|
||||
int update_server_addr(struct server *s, void *ip, int ip_sin_family, const char *updater);
|
||||
const char *update_server_addr_port(struct server *s, const char *addr, const char *port, char *updater);
|
||||
struct server *server_find_by_id(struct proxy *bk, int id);
|
||||
|
@ -675,7 +675,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
||||
if (!strcmp(args[0], "server") ||
|
||||
!strcmp(args[0], "default-server") ||
|
||||
!strcmp(args[0], "server-template")) {
|
||||
err_code |= parse_server(file, linenum, args, curproxy, &defproxy);
|
||||
err_code |= parse_server(file, linenum, args, curproxy, &defproxy, 1);
|
||||
if (err_code & ERR_FATAL)
|
||||
goto out;
|
||||
}
|
||||
|
284
src/cfgparse.c
284
src/cfgparse.c
@ -515,11 +515,75 @@ static int init_peers_frontend(const char *file, int linenum,
|
||||
p->id = strdup(id);
|
||||
free(p->conf.file);
|
||||
p->conf.args.file = p->conf.file = strdup(file);
|
||||
p->conf.args.line = p->conf.line = linenum;
|
||||
if (linenum != -1)
|
||||
p->conf.args.line = p->conf.line = linenum;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Only change ->file, ->line and ->arg struct bind_conf member values
|
||||
* if already present.
|
||||
*/
|
||||
static struct bind_conf *bind_conf_uniq_alloc(struct proxy *p,
|
||||
const char *file, int line,
|
||||
const char *arg, struct xprt_ops *xprt)
|
||||
{
|
||||
struct bind_conf *bind_conf;
|
||||
|
||||
if (!LIST_ISEMPTY(&p->conf.bind)) {
|
||||
bind_conf = LIST_ELEM((&p->conf.bind)->n, typeof(bind_conf), by_fe);
|
||||
free(bind_conf->file);
|
||||
bind_conf->file = strdup(file);
|
||||
bind_conf->line = line;
|
||||
if (arg) {
|
||||
free(bind_conf->arg);
|
||||
bind_conf->arg = strdup(arg);
|
||||
}
|
||||
}
|
||||
else {
|
||||
bind_conf = bind_conf_alloc(p, file, line, arg, xprt);
|
||||
}
|
||||
|
||||
return bind_conf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a new struct peer parsed at line <linenum> in file <file>
|
||||
* to be added to <peers>.
|
||||
* Returns the new allocated structure if succeeded, NULL if not.
|
||||
*/
|
||||
static struct peer *cfg_peers_add_peer(struct peers *peers,
|
||||
const char *file, int linenum,
|
||||
const char *id, int local)
|
||||
{
|
||||
struct peer *p;
|
||||
|
||||
p = calloc(1, sizeof *p);
|
||||
if (!p) {
|
||||
ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* the peers are linked backwards first */
|
||||
peers->count++;
|
||||
p->next = peers->remote;
|
||||
peers->remote = p;
|
||||
p->conf.file = strdup(file);
|
||||
p->conf.line = linenum;
|
||||
p->last_change = now.tv_sec;
|
||||
p->xprt = xprt_get(XPRT_RAW);
|
||||
p->sock_init_arg = NULL;
|
||||
HA_SPIN_INIT(&p->lock);
|
||||
if (id)
|
||||
p->id = strdup(id);
|
||||
if (local) {
|
||||
p->local = 1;
|
||||
peers->local = p;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a line in a <listen>, <frontend> or <backend> section.
|
||||
* Returns the error code, 0 if OK, or any combination of :
|
||||
@ -539,15 +603,117 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
|
||||
struct listener *l;
|
||||
int err_code = 0;
|
||||
char *errmsg = NULL;
|
||||
static int bind_line, peer_line;
|
||||
|
||||
if (strcmp(args[0], "bind") == 0 || strcmp(args[0], "default-bind") == 0) {
|
||||
int cur_arg;
|
||||
static int kws_dumped;
|
||||
struct bind_conf *bind_conf;
|
||||
struct bind_kw *kw;
|
||||
char *kws;
|
||||
|
||||
cur_arg = 1;
|
||||
|
||||
if (strcmp(args[0], "default-server") == 0) {
|
||||
if (init_peers_frontend(file, linenum, NULL, curpeers) != 0) {
|
||||
err_code |= ERR_ALERT | ERR_ABORT;
|
||||
goto out;
|
||||
}
|
||||
err_code |= parse_server(file, linenum, args, curpeers->peers_fe, NULL);
|
||||
|
||||
bind_conf = bind_conf_uniq_alloc(curpeers->peers_fe, file, linenum,
|
||||
NULL, xprt_get(XPRT_RAW));
|
||||
if (*args[0] == 'b') {
|
||||
struct listener *l;
|
||||
|
||||
if (peer_line) {
|
||||
ha_alert("parsing [%s:%d] : mixing \"peer\" and \"bind\" line is forbidden\n", file, linenum);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!str2listener(args[1], curpeers->peers_fe, bind_conf, file, linenum, &errmsg)) {
|
||||
if (errmsg && *errmsg) {
|
||||
indent_msg(&errmsg, 2);
|
||||
ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
|
||||
}
|
||||
else
|
||||
ha_alert("parsing [%s:%d] : '%s %s' : error encountered while parsing listening address %s.\n",
|
||||
file, linenum, args[0], args[1], args[2]);
|
||||
err_code |= ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
l = LIST_ELEM(bind_conf->listeners.n, typeof(l), by_bind);
|
||||
l->maxaccept = 1;
|
||||
l->maxconn = curpeers->peers_fe->maxconn;
|
||||
l->backlog = curpeers->peers_fe->backlog;
|
||||
l->accept = session_accept_fd;
|
||||
l->analysers |= curpeers->peers_fe->fe_req_ana;
|
||||
l->default_target = curpeers->peers_fe->default_target;
|
||||
l->options |= LI_O_UNLIMITED; /* don't make the peers subject to global limits */
|
||||
global.maxsock += l->maxconn;
|
||||
|
||||
bind_line = 1;
|
||||
if (cfg_peers->local) {
|
||||
newpeer = cfg_peers->local;
|
||||
}
|
||||
else {
|
||||
/* This peer is local.
|
||||
* Note that we do not set the peer ID. This latter is initialized
|
||||
* when parsing "peer" or "server" line.
|
||||
*/
|
||||
newpeer = cfg_peers_add_peer(curpeers, file, linenum, NULL, 1);
|
||||
if (!newpeer) {
|
||||
err_code |= ERR_ALERT | ERR_ABORT;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
newpeer->addr = l->addr;
|
||||
newpeer->proto = protocol_by_family(newpeer->addr.ss_family);
|
||||
cur_arg++;
|
||||
}
|
||||
|
||||
while (*args[cur_arg] && (kw = bind_find_kw(args[cur_arg]))) {
|
||||
int ret;
|
||||
|
||||
ret = kw->parse(args, cur_arg, curpeers->peers_fe, bind_conf, &errmsg);
|
||||
err_code |= ret;
|
||||
if (ret) {
|
||||
if (errmsg && *errmsg) {
|
||||
indent_msg(&errmsg, 2);
|
||||
ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
|
||||
}
|
||||
else
|
||||
ha_alert("parsing [%s:%d]: error encountered while processing '%s'\n",
|
||||
file, linenum, args[cur_arg]);
|
||||
if (ret & ERR_FATAL)
|
||||
goto out;
|
||||
}
|
||||
cur_arg += 1 + kw->skip;
|
||||
}
|
||||
kws = NULL;
|
||||
if (!kws_dumped) {
|
||||
kws_dumped = 1;
|
||||
bind_dump_kws(&kws);
|
||||
indent_msg(&kws, 4);
|
||||
}
|
||||
if (*args[cur_arg] != 0) {
|
||||
ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section.%s%s\n",
|
||||
file, linenum, args[cur_arg], cursection,
|
||||
kws ? " Registered keywords :" : "", kws ? kws: "");
|
||||
free(kws);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else if (strcmp(args[0], "default-server") == 0) {
|
||||
if (init_peers_frontend(file, -1, NULL, curpeers) != 0) {
|
||||
err_code |= ERR_ALERT | ERR_ABORT;
|
||||
goto out;
|
||||
}
|
||||
err_code |= parse_server(file, linenum, args, curpeers->peers_fe, NULL, 0);
|
||||
}
|
||||
else if (strcmp(args[0], "peers") == 0) { /* new peers section */
|
||||
/* Initialize these static variables when entering a new "peers" section*/
|
||||
bind_line = peer_line = 0;
|
||||
if (!*args[1]) {
|
||||
ha_alert("parsing [%s:%d] : missing name for peers section.\n", file, linenum);
|
||||
err_code |= ERR_ALERT | ERR_ABORT;
|
||||
@ -593,28 +759,51 @@ 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 */
|
||||
if ((newpeer = calloc(1, sizeof(*newpeer))) == NULL) {
|
||||
ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
|
||||
int local_peer;
|
||||
|
||||
local_peer = !strcmp(args[1], localpeer);
|
||||
/* The local peer may have already partially been parsed on a "bind" line. */
|
||||
if (*args[0] == 'p') {
|
||||
if (bind_line) {
|
||||
ha_alert("parsing [%s:%d] : mixing \"peer\" and \"bind\" line is forbidden\n", file, linenum);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
peer_line = 1;
|
||||
}
|
||||
if (cfg_peers->local && !cfg_peers->local->id && local_peer) {
|
||||
/* The local peer has already been initialized on a "bind" line.
|
||||
* Let's use it and store its ID.
|
||||
*/
|
||||
newpeer = cfg_peers->local;
|
||||
newpeer->id = strdup(localpeer);
|
||||
}
|
||||
else {
|
||||
if (local_peer && cfg_peers->local) {
|
||||
ha_alert("parsing [%s:%d] : '%s %s' : local peer name already referenced at %s:%d. %s\n",
|
||||
file, linenum, args[0], args[1],
|
||||
curpeers->peers_fe->conf.file, curpeers->peers_fe->conf.line, cfg_peers->local->id);
|
||||
err_code |= ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
newpeer = cfg_peers_add_peer(curpeers, file, linenum, args[1], local_peer);
|
||||
if (!newpeer) {
|
||||
err_code |= ERR_ALERT | ERR_ABORT;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* Line number and peer ID are updated only if this peer is the local one. */
|
||||
if (init_peers_frontend(file,
|
||||
newpeer->local ? linenum: -1,
|
||||
newpeer->local ? newpeer->id : NULL,
|
||||
curpeers) != 0) {
|
||||
err_code |= ERR_ALERT | ERR_ABORT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* the peers are linked backwards first */
|
||||
curpeers->count++;
|
||||
newpeer->next = curpeers->remote;
|
||||
curpeers->remote = newpeer;
|
||||
newpeer->conf.file = strdup(file);
|
||||
newpeer->conf.line = linenum;
|
||||
|
||||
newpeer->last_change = now.tv_sec;
|
||||
newpeer->id = strdup(args[1]);
|
||||
|
||||
if (init_peers_frontend(file, linenum, newpeer->id, curpeers) != 0) {
|
||||
err_code |= ERR_ALERT | ERR_ABORT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err_code |= parse_server(file, linenum, args, curpeers->peers_fe, NULL);
|
||||
/* This initializes curpeer->peers->peers_fe->srv. */
|
||||
err_code |= parse_server(file, linenum, args, curpeers->peers_fe, NULL, !local_peer);
|
||||
if (!curpeers->peers_fe->srv)
|
||||
goto out;
|
||||
|
||||
@ -624,23 +813,16 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
|
||||
newpeer->sock_init_arg = NULL;
|
||||
HA_SPIN_INIT(&newpeer->lock);
|
||||
|
||||
if (strcmp(newpeer->id, localpeer) != 0) {
|
||||
if (!newpeer->local) {
|
||||
newpeer->srv = curpeers->peers_fe->srv;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (cfg_peers->local) {
|
||||
ha_alert("parsing [%s:%d] : '%s %s' : local peer name already referenced at %s:%d.\n",
|
||||
file, linenum, args[0], args[1],
|
||||
curpeers->peers_fe->conf.file, curpeers->peers_fe->conf.line);
|
||||
err_code |= ERR_FATAL;
|
||||
/* The lines above are reserved to "peer" lines. */
|
||||
if (*args[0] == 's')
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Current is local peer, it define a frontend */
|
||||
newpeer->local = 1;
|
||||
|
||||
bind_conf = bind_conf_alloc(curpeers->peers_fe, file, linenum, args[2], xprt_get(XPRT_RAW));
|
||||
bind_conf = bind_conf_uniq_alloc(curpeers->peers_fe, file, linenum, args[2], xprt_get(XPRT_RAW));
|
||||
|
||||
if (!str2listener(args[2], curpeers->peers_fe, bind_conf, file, linenum, &errmsg)) {
|
||||
if (errmsg && *errmsg) {
|
||||
@ -653,17 +835,16 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
|
||||
err_code |= ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
list_for_each_entry(l, &bind_conf->listeners, by_bind) {
|
||||
l->maxaccept = 1;
|
||||
l->maxconn = curpeers->peers_fe->maxconn;
|
||||
l->backlog = curpeers->peers_fe->backlog;
|
||||
l->accept = session_accept_fd;
|
||||
l->analysers |= curpeers->peers_fe->fe_req_ana;
|
||||
l->default_target = curpeers->peers_fe->default_target;
|
||||
l->options |= LI_O_UNLIMITED; /* don't make the peers subject to global limits */
|
||||
global.maxsock += l->maxconn;
|
||||
}
|
||||
cfg_peers->local = newpeer;
|
||||
|
||||
l = LIST_ELEM(bind_conf->listeners.n, typeof(l), by_bind);
|
||||
l->maxaccept = 1;
|
||||
l->maxconn = curpeers->peers_fe->maxconn;
|
||||
l->backlog = curpeers->peers_fe->backlog;
|
||||
l->accept = session_accept_fd;
|
||||
l->analysers |= curpeers->peers_fe->fe_req_ana;
|
||||
l->default_target = curpeers->peers_fe->default_target;
|
||||
l->options |= LI_O_UNLIMITED; /* don't make the peers subject to global limits */
|
||||
global.maxsock += l->maxconn;
|
||||
} /* neither "peer" nor "peers" */
|
||||
else if (!strcmp(args[0], "disabled")) { /* disables this peers section */
|
||||
curpeers->state = PR_STSTOPPED;
|
||||
@ -3637,9 +3818,20 @@ out_uri_auth_compat:
|
||||
else {
|
||||
p = curpeers->remote;
|
||||
while (p) {
|
||||
if (p->srv && p->srv->use_ssl &&
|
||||
xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->prepare_srv)
|
||||
cfgerr += xprt_get(XPRT_SSL)->prepare_srv(p->srv);
|
||||
if (p->srv) {
|
||||
if (p->srv->use_ssl && xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->prepare_srv)
|
||||
cfgerr += xprt_get(XPRT_SSL)->prepare_srv(p->srv);
|
||||
}
|
||||
else if (!LIST_ISEMPTY(&curpeers->peers_fe->conf.bind)) {
|
||||
struct list *l;
|
||||
struct bind_conf *bind_conf;
|
||||
|
||||
l = &curpeers->peers_fe->conf.bind;
|
||||
bind_conf = LIST_ELEM(l->n, typeof(bind_conf), by_fe);
|
||||
if (bind_conf->xprt->prepare_bind_conf &&
|
||||
bind_conf->xprt->prepare_bind_conf(bind_conf) < 0)
|
||||
cfgerr++;
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
if (!peers_init_sync(curpeers)) {
|
||||
|
10
src/server.c
10
src/server.c
@ -2078,7 +2078,7 @@ static int server_template_init(struct server *srv, struct proxy *px)
|
||||
return i - srv->tmpl_info.nb_low;
|
||||
}
|
||||
|
||||
int parse_server(const char *file, int linenum, char **args, struct proxy *curproxy, struct proxy *defproxy)
|
||||
int parse_server(const char *file, int linenum, char **args, struct proxy *curproxy, struct proxy *defproxy, int parse_addr)
|
||||
{
|
||||
struct server *newsrv = NULL;
|
||||
const char *err = NULL;
|
||||
@ -2106,7 +2106,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
|
||||
err_code |= ERR_WARN;
|
||||
|
||||
/* There is no mandatory first arguments for default server. */
|
||||
if (srv) {
|
||||
if (srv && parse_addr) {
|
||||
if (!*args[2]) {
|
||||
/* 'server' line number of argument check. */
|
||||
ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
|
||||
@ -2186,6 +2186,9 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
|
||||
* - 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, &errmsg, NULL, &fqdn, 0);
|
||||
if (!sk) {
|
||||
ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
|
||||
@ -2242,10 +2245,11 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
|
||||
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);
|
||||
cur_arg++;
|
||||
} else {
|
||||
newsrv = &curproxy->defsrv;
|
||||
cur_arg = 1;
|
||||
|
Loading…
Reference in New Issue
Block a user