From: Frédéric Lécaille <flecai...@haproxy.com>

This patch makes "bind" work in "peers" sections. All "bind" settings
are supported, excepted ip:port parameters which are provided on
"peer" (or server) line matching the local peer.
After having parsed the configuration files ->prepare_bind_conf is run
to initialize all SSL/TLS stuff for the local peer.

May be backported to 1.5 and newer.
---
 src/cfgparse.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 90 insertions(+), 5 deletions(-)

diff --git a/src/cfgparse.c b/src/cfgparse.c
index f6f25143..ef69b37d 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -521,6 +521,31 @@ static int init_peers_frontend(const char *file, int 
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;
+}
 /*
  * Parse a line in a <listen>, <frontend> or <backend> section.
  * Returns the error code, 0 if OK, or any combination of :
@@ -541,7 +566,56 @@ int cfg_parse_peers(const char *file, int linenum, char 
**args, int kwm)
        int err_code = 0;
        char *errmsg = NULL;
 
-       if (strcmp(args[0], "default-server") == 0) {
+       if (strcmp(args[0], "bind") == 0) {
+               int cur_arg;
+               static int kws_dumped;
+               struct bind_conf *bind_conf;
+               struct bind_kw *kw;
+               char *kws;
+
+               cur_arg = 1;
+
+               if (init_peers_frontend(file, linenum, NULL, curpeers) != 0) {
+                       err_code |= ERR_ALERT | ERR_ABORT;
+                       goto out;
+               }
+
+               bind_conf = bind_conf_uniq_alloc(curpeers->peers_fe, file, 
linenum,
+                                                NULL, xprt_get(XPRT_RAW));
+               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, linenum, NULL, curpeers) != 0) {
                        err_code |= ERR_ALERT | ERR_ABORT;
                        goto out;
@@ -641,7 +715,7 @@ int cfg_parse_peers(const char *file, int linenum, char 
**args, int kwm)
                /* 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) {
@@ -3638,9 +3712,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)) {
-- 
2.11.0

Reply via email to