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

With this patch "default-server" lines are supported in "peers" sections
to setup the default settings of peers which are from now setup
when parsing both "peer" and "server" lines.

May be backported to 1.5 and newer.
---
 src/cfgparse.c | 88 +++++++++++++++++++---------------------------------------
 src/peers.c    |  2 +-
 src/server.c   |  3 +-
 3 files changed, 32 insertions(+), 61 deletions(-)

diff --git a/src/cfgparse.c b/src/cfgparse.c
index 715faaef..6d199c97 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -486,15 +486,18 @@ void init_default_instance()
 /* Allocate and initialize the frontend of a "peers" section found in
  * file <file> at line <linenum> with <id> as ID.
  * Return 0 if succeeded, -1 if not.
+ * Note that this function may be called from "default-server"
+ * or "peer" lines.
  */
 static int init_peers_frontend(const char *file, int linenum,
                                const char *id, struct peers *peers)
 {
        struct proxy *p;
 
-       if (peers->peers_fe)
-               /* Nothing to do */
-               return 0;
+       if (peers->peers_fe) {
+               p = peers->peers_fe;
+               goto out;
+       }
 
        p = calloc(1, sizeof *p);
        if (!p) {
@@ -503,12 +506,16 @@ static int init_peers_frontend(const char *file, int 
linenum,
        }
 
        init_new_proxy(p);
+       peers_setup_frontend(p);
        p->parent = peers;
-       p->id = strdup(id);
+       /* Finally store this frontend. */
+       peers->peers_fe = p;
+
+ out:
+       if (id && !p->id)
+               p->id = strdup(id);
        p->conf.args.file = p->conf.file = strdup(file);
        p->conf.args.line = p->conf.line = linenum;
-       peers_setup_frontend(p);
-       peers->peers_fe = p;
 
        return 0;
 }
@@ -533,7 +540,14 @@ int cfg_parse_peers(const char *file, int linenum, char 
**args, int kwm)
        int err_code = 0;
        char *errmsg = NULL;
 
-       if (strcmp(args[0], "peers") == 0) { /* new peers section */
+       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);
+       }
+       else if (strcmp(args[0], "peers") == 0) { /* new peers section */
                if (!*args[1]) {
                        ha_alert("parsing [%s:%d] : missing name for peers 
section.\n", file, linenum);
                        err_code |= ERR_ALERT | ERR_ABORT;
@@ -577,26 +591,8 @@ int cfg_parse_peers(const char *file, int linenum, char 
**args, int kwm)
                curpeers->id = strdup(args[1]);
                curpeers->state = PR_STNEW;
        }
-       else if (strcmp(args[0], "peer") == 0) { /* peer definition */
-               struct sockaddr_storage *sk;
-               int port1, port2;
-               struct protocol *proto;
-
-               if (!*args[2]) {
-                       ha_alert("parsing [%s:%d] : '%s' expects <name> and 
<addr>[:<port>] as arguments.\n",
-                                file, linenum, args[0]);
-                       err_code |= ERR_ALERT | ERR_FATAL;
-                       goto out;
-               }
-
-               err = invalid_char(args[1]);
-               if (err) {
-                       ha_alert("parsing [%s:%d] : character '%c' is not 
permitted in server name '%s'.\n",
-                                file, linenum, *err, args[1]);
-                       err_code |= ERR_ALERT | ERR_FATAL;
-                       goto out;
-               }
-
+       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);
                        err_code |= ERR_ALERT | ERR_ABORT;
@@ -613,37 +609,17 @@ int cfg_parse_peers(const char *file, int linenum, char 
**args, int kwm)
                newpeer->last_change = now.tv_sec;
                newpeer->id = strdup(args[1]);
 
-               sk = str2sa_range(args[2], NULL, &port1, &port2, &errmsg, NULL, 
NULL, 1);
-               if (!sk) {
-                       ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, 
linenum, args[0], args[1], errmsg);
-                       err_code |= ERR_ALERT | ERR_FATAL;
-                       goto out;
-               }
-
-               proto = protocol_by_family(sk->ss_family);
-               if (!proto || !proto->connect) {
-                       ha_alert("parsing [%s:%d] : '%s %s' : connect() not 
supported for this address family.\n",
-                                file, linenum, args[0], args[1]);
-                       err_code |= ERR_ALERT | ERR_FATAL;
-                       goto out;
-               }
-
-               if (port1 != port2) {
-                       ha_alert("parsing [%s:%d] : '%s %s' : port ranges and 
offsets are not allowed in '%s'\n",
-                                file, linenum, args[0], args[1], args[2]);
-                       err_code |= ERR_ALERT | ERR_FATAL;
+               if (init_peers_frontend(file, linenum, newpeer->id, curpeers) 
!= 0) {
+                       err_code |= ERR_ALERT | ERR_ABORT;
                        goto out;
                }
 
-               if (!port1) {
-                       ha_alert("parsing [%s:%d] : '%s %s' : missing or 
invalid port in '%s'\n",
-                                file, linenum, args[0], args[1], args[2]);
-                       err_code |= ERR_ALERT | ERR_FATAL;
+               err_code |= parse_server(file, linenum, args, 
curpeers->peers_fe, NULL);
+               if (!curpeers->peers_fe->srv)
                        goto out;
-               }
 
-               newpeer->addr = *sk;
-               newpeer->proto = proto;
+               newpeer->addr = curpeers->peers_fe->srv->addr;
+               newpeer->proto = protocol_by_family(newpeer->addr.ss_family);
                newpeer->xprt  = xprt_get(XPRT_RAW);
                newpeer->sock_init_arg = NULL;
                HA_SPIN_INIT(&newpeer->lock);
@@ -663,12 +639,6 @@ int cfg_parse_peers(const char *file, int linenum, char 
**args, int kwm)
                /* Current is local peer, it define a frontend */
                newpeer->local = 1;
 
-               if (init_peers_frontend(file, linenum, args[1], curpeers) != 0) 
{
-                               ha_alert("parsing [%s:%d] : out of memory.\n", 
file, linenum);
-                               err_code |= ERR_ALERT | ERR_ABORT;
-                               goto out;
-               }
-
                bind_conf = bind_conf_alloc(curpeers->peers_fe, file, linenum, 
args[2], xprt_get(XPRT_RAW));
 
                if (!str2listener(args[2], curpeers->peers_fe, bind_conf, file, 
linenum, &errmsg)) {
diff --git a/src/peers.c b/src/peers.c
index 4314d58f..e580f2ca 100644
--- a/src/peers.c
+++ b/src/peers.c
@@ -1930,7 +1930,7 @@ static void peer_session_forceshutdown(struct appctx 
*appctx)
 void peers_setup_frontend(struct proxy *fe)
 {
        fe->last_change = now.tv_sec;
-       fe->cap = PR_CAP_FE;
+       fe->cap = PR_CAP_FE | PR_CAP_BE;
        fe->maxconn = 0;
        fe->conn_retries = CONN_RETRIES;
        fe->timeout.client = MS_TO_TICKS(5000);
diff --git a/src/server.c b/src/server.c
index bc9e8052..7f8b2855 100644
--- a/src/server.c
+++ b/src/server.c
@@ -2087,11 +2087,12 @@ int parse_server(const char *file, int linenum, char 
**args, struct proxy *curpr
        char *fqdn = NULL;
 
        if (!strcmp(args[0], "server")         ||
+           !strcmp(args[0], "peer")           ||
            !strcmp(args[0], "default-server") ||
            !strcmp(args[0], "server-template")) {
                int cur_arg;
                int defsrv = (*args[0] == 'd');
-               int srv = !defsrv && !strcmp(args[0], "server");
+               int srv = !defsrv && (*args[0] == 'p' || !strcmp(args[0], 
"server"));
                int srv_tmpl = !defsrv && !srv;
                int tmpl_range_low = 0, tmpl_range_high = 0;
 
-- 
2.11.0

Reply via email to