On 05/25/2018 06:10 PM, Willy Tarreau wrote:
Hi all,
[sniped]
- peers over SSL [Fred] : the purpose is to allow all bind options with
peers so that peers can exchange information securely. I think I've
seen it posted somewhere, I'll have to dig through the archives.
Here are the rebased patches for this feature.
Fred.
>From e41942d0c85dd4270a685e5db5bf8523e87ef287 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= <[email protected]>
Date: Mon, 28 May 2018 08:47:52 +0200
Subject: [PATCH 10/10] DOC: peers: Update "peers" section SSL/TLS support
documentation.
---
doc/configuration.txt | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/doc/configuration.txt b/doc/configuration.txt
index e27d666..544b697 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -1833,6 +1833,12 @@ peers <peersect>
Creates a new peer list with name <peersect>. It is an independent section,
which is referenced by one or more stick-tables.
+bind [param*]
+ Defines the binding parameters of the local peer of this "peers" section.
+ To avoid some redundancy, and as the <address> and <port> parameters
+ are already provided on "peer" (or "server") lines, they are not supported
+ by "bind" keyword in "peers" sections.
+
disabled
Disables a peers section. It disables both listening and any synchronization
related to this section. This is provided to disable synchronization of stick
@@ -1841,7 +1847,7 @@ disabled
enable
This re-enables a disabled peers section which was previously disabled.
-peer <peername> <ip>:<port>
+peer <peername> <ip>:<port> [param*]
Defines a peer inside a peers section.
If <peername> is set to the local peer name (by default hostname, or forced
using "-L" command line option), haproxy will listen for incoming remote peer
@@ -1860,6 +1866,15 @@ peer <peername> <ip>:<port>
You may want to reference some environment variables in the address
parameter, see section 2.3 about environment variables.
+ Note: "peer" keyword may transparently be replaced by "server" keyword (see
+ "server" keyword explanation below).
+
+server <peername> <ip>:<port> [param*]
+ As previously mentionned, "peer" keyword may be replaced by "server" keyword
+ with a support for all "server" parameters found in 5.2 paragraph.
+ Some of these parameters are irrelevant for "peers" sections.
+
+
Example:
peers mypeers
peer haproxy1 192.168.0.1:1024
--
2.1.4
>From a546f38d9e6fe980c477b91df0681ac6fa0289a9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= <[email protected]>
Date: Fri, 27 Apr 2018 13:56:13 +0200
Subject: [PATCH 09/10] MINOR: peers: Make incoming connections to SSL/TLS
local peer work.
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.
---
src/cfgparse.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 90 insertions(+), 5 deletions(-)
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 96ccc9f..90735e6 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -1992,6 +1992,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 :
@@ -2012,7 +2037,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;
@@ -2112,7 +2186,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) {
@@ -8912,9 +8986,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;
}
peers_init_sync(curpeers);
--
2.1.4
>From e450e5b19ee944c262a30cafa76f3020b138b919 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= <[email protected]>
Date: Thu, 26 Apr 2018 14:35:21 +0200
Subject: [PATCH 08/10] MINOR: peers: Make outgoing connection to SSL/TLS peers
work.
This patch adds pointer to a struct server to peer structure which
is initialized after having parsed a remote "peer" line.
After having parsed all peers section we run ->prepare_srv to initialize
all SSL/TLS stuff of remote perr (or server).
Remaining thing to do to completely support peer protocol over SSL/TLS:
make "bind" keyword be supported in "peers" sections to make SSL/TLS
incoming connections to local peers work.
---
include/proto/peers.h | 26 ++++++++++++++++++++++++++
include/types/peers.h | 1 +
src/cfgparse.c | 13 +++++++++++--
src/peers.c | 5 +++--
4 files changed, 41 insertions(+), 4 deletions(-)
diff --git a/include/proto/peers.h b/include/proto/peers.h
index 782b66e..7158716 100644
--- a/include/proto/peers.h
+++ b/include/proto/peers.h
@@ -25,9 +25,35 @@
#include <common/config.h>
#include <common/ticks.h>
#include <common/time.h>
+#include <proto/connection.h>
#include <types/stream.h>
#include <types/peers.h>
+#if defined(USE_OPENSSL)
+static inline enum obj_type *peer_session_target(struct peer *p, struct stream *s)
+{
+ if (p->srv->use_ssl)
+ return &p->srv->obj_type;
+ else
+ return &s->be->obj_type;
+}
+
+static inline struct xprt_ops *peer_xprt(struct peer *p)
+{
+ return p->srv->use_ssl ? xprt_get(XPRT_SSL) : xprt_get(XPRT_RAW);
+}
+#else
+static inline enum obj_type *peer_session_target(struct peer *p, struct stream *s)
+{
+ return &s->be->obj_type;
+}
+
+static inline struct xprt_ops *peer_xprt(struct peer *p)
+{
+ return xprt_get(XPRT_RAW);
+}
+#endif
+
void peers_init_sync(struct peers *peers);
void peers_register_table(struct peers *, struct stktable *table);
void peers_setup_frontend(struct proxy *fe);
diff --git a/include/types/peers.h b/include/types/peers.h
index 58c8c4e..5200d56 100644
--- a/include/types/peers.h
+++ b/include/types/peers.h
@@ -67,6 +67,7 @@ struct peer {
struct shared_table *remote_table;
struct shared_table *last_local_table;
struct shared_table *tables;
+ struct server *srv;
__decl_hathreads(HA_SPINLOCK_T lock); /* lock used to handle this peer section */
struct peer *next; /* next peer in the list */
};
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 258e655..96ccc9f 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -1985,6 +1985,7 @@ static int init_peers_frontend(const char *file, int linenum,
out:
if (id && !p->id)
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;
@@ -2095,9 +2096,10 @@ 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)
- /* We are done. */
+ if (strcmp(newpeer->id, localpeer) != 0) {
+ 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",
@@ -8908,6 +8910,13 @@ out_uri_auth_compat:
curpeers->peers_fe = NULL;
}
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);
+ p = p->next;
+ }
peers_init_sync(curpeers);
last = &curpeers->next;
continue;
diff --git a/src/peers.c b/src/peers.c
index 20f4f4d..365304f 100644
--- a/src/peers.c
+++ b/src/peers.c
@@ -39,6 +39,7 @@
#include <proto/log.h>
#include <proto/hdr_idx.h>
#include <proto/mux_pt.h>
+#include <proto/peers.h>
#include <proto/proto_tcp.h>
#include <proto/proto_http.h>
#include <proto/proxy.h>
@@ -1925,11 +1926,11 @@ static struct appctx *peer_session_create(struct peers *peers, struct peer *peer
if (unlikely((cs = cs_new(conn)) == NULL))
goto out_free_conn;
- conn_prepare(conn, peer->proto, peer->xprt);
+ conn_prepare(conn, peer->proto, peer_xprt(peer));
conn_install_mux(conn, &mux_pt_ops, cs);
si_attach_cs(&s->si[1], cs);
- conn->target = s->target = &s->be->obj_type;
+ conn->target = s->target = peer_session_target(peer, s);
memcpy(&conn->addr.to, &peer->addr, sizeof(conn->addr.to));
s->do_log = NULL;
s->uniq_id = 0;
--
2.1.4
>From 49b50073cfb9aa96da2d4c0b7ebbc976d13d8162 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= <[email protected]>
Date: Thu, 26 Apr 2018 10:06:41 +0200
Subject: [PATCH 07/10] MINOR: cfgparse: Make "peer" lines be parsed as
"server" lines.
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.
---
src/cfgparse.c | 87 ++++++++++++++++++++--------------------------------------
src/peers.c | 2 +-
src/server.c | 3 +-
3 files changed, 32 insertions(+), 60 deletions(-)
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 20678ad..258e655 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -1957,15 +1957,18 @@ static int create_cond_regex_rule(const char *file, int line,
/* 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) {
@@ -1974,12 +1977,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;
}
@@ -2004,7 +2011,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;
@@ -2048,26 +2062,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;
@@ -2084,37 +2080,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);
@@ -2134,11 +2110,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) {
- 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 6d5a556..20f4f4d 100644
--- a/src/peers.c
+++ b/src/peers.c
@@ -1859,7 +1859,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 277d140..4de9f02 100644
--- a/src/server.c
+++ b/src/server.c
@@ -1921,11 +1921,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.1.4
>From 9738b491f26c888bb8a4a67a523ece831f19778a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= <[email protected]>
Date: Wed, 25 Apr 2018 16:08:35 +0200
Subject: [PATCH 06/10] MINOR: cfgparse: Simplication.
Make init_peers_frontend() be callable without having to check if
there is something to do or not.
---
src/cfgparse.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/src/cfgparse.c b/src/cfgparse.c
index d29617a..20678ad 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -1963,6 +1963,10 @@ static int init_peers_frontend(const char *file, int linenum,
{
struct proxy *p;
+ if (peers->peers_fe)
+ /* Nothing to do */
+ return 0;
+
p = calloc(1, sizeof *p);
if (!p) {
ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
@@ -2130,10 +2134,9 @@ 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 (!curpeers->peers_fe &&
- init_peers_frontend(file, linenum, args[1], curpeers) != 0) {
- err_code |= ERR_ALERT | ERR_ABORT;
- goto out;
+ if (init_peers_frontend(file, linenum, args[1], curpeers) != 0) {
+ err_code |= ERR_ALERT | ERR_ABORT;
+ goto out;
}
bind_conf = bind_conf_alloc(curpeers->peers_fe, file, linenum, args[2], xprt_get(XPRT_RAW));
--
2.1.4
>From 5fa179f17663580cb759ae77ef4fb487699d9147 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= <[email protected]>
Date: Wed, 25 Apr 2018 15:58:41 +0200
Subject: [PATCH 05/10] MINOR: cfgparse: Seperate peers frontend init from its
binding init.
Even if not already the case, we suppose that the frontend "peers" section
may have been already initialized outside of "peer" line, we seperate
their initializations from their binding initializations.
---
src/cfgparse.c | 51 +++++++++++++++++++++++++--------------------------
1 file changed, 25 insertions(+), 26 deletions(-)
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 045f492..d29617a 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -2130,38 +2130,37 @@ 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 (!curpeers->peers_fe) {
- if (init_peers_frontend(file, linenum, args[1], curpeers) != 0) {
+ if (!curpeers->peers_fe &&
+ init_peers_frontend(file, linenum, args[1], curpeers) != 0) {
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)) {
- 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;
- }
+ bind_conf = bind_conf_alloc(curpeers->peers_fe, file, linenum, args[2], xprt_get(XPRT_RAW));
- 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;
+ if (!str2listener(args[2], 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);
}
- cfg_peers->local = newpeer;
+ 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;
}
+
+ 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;
} /* neither "peer" nor "peers" */
else if (!strcmp(args[0], "disabled")) { /* disables this peers section */
curpeers->state = PR_STSTOPPED;
--
2.1.4
>From d797560cc17b5d62a53f5dfa7f4d959e6c29166a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= <[email protected]>
Date: Wed, 25 Apr 2018 15:32:18 +0200
Subject: [PATCH 04/10] MINOR: cfgparse: Useless frontend initialization in
"peers" sections.
Use ->local "peers" struct member to flag a "peers" section frontend
has being initialized. This is to be able to initialize the frontend
of "peers" sections on lines different from "peer" lines.
---
src/cfgparse.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/src/cfgparse.c b/src/cfgparse.c
index d5ffd49..045f492 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -2119,9 +2119,16 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
/* We are done. */
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;
+ goto out;
+ }
+
/* Current is local peer, it define a frontend */
newpeer->local = 1;
- cfg_peers->local = newpeer;
if (!curpeers->peers_fe) {
if (init_peers_frontend(file, linenum, args[1], curpeers) != 0) {
@@ -2153,13 +2160,7 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
l->options |= LI_O_UNLIMITED; /* don't make the peers subject to global limits */
global.maxsock += l->maxconn;
}
- }
- else {
- 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;
- goto out;
+ cfg_peers->local = newpeer;
}
} /* neither "peer" nor "peers" */
else if (!strcmp(args[0], "disabled")) { /* disables this peers section */
--
2.1.4
>From 880ae5e1beff1bcc97f61fe4f5f8eb953baa4606 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= <[email protected]>
Date: Wed, 25 Apr 2018 15:19:14 +0200
Subject: [PATCH 03/10] CLEANUP: cfgparse: Code reindentation.
May help to review.
---
src/cfgparse.c | 70 +++++++++++++++++++++++++++++-----------------------------
1 file changed, 35 insertions(+), 35 deletions(-)
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 827766c..d5ffd49 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -2119,48 +2119,48 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
/* We are done. */
goto out;
- /* Current is local peer, it define a frontend */
- newpeer->local = 1;
- cfg_peers->local = newpeer;
+ /* Current is local peer, it define a frontend */
+ newpeer->local = 1;
+ cfg_peers->local = newpeer;
- if (!curpeers->peers_fe) {
- if (init_peers_frontend(file, linenum, args[1], curpeers) != 0) {
- 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 (!curpeers->peers_fe) {
+ if (init_peers_frontend(file, linenum, args[1], curpeers) != 0) {
+ err_code |= ERR_ALERT | ERR_ABORT;
+ goto out;
+ }
- if (!str2listener(args[2], 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;
- }
+ bind_conf = bind_conf_alloc(curpeers->peers_fe, file, linenum, args[2], xprt_get(XPRT_RAW));
- 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;
+ if (!str2listener(args[2], 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' : 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);
+ 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;
}
+
+ 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;
+ }
+ }
+ else {
+ 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;
+ goto out;
+ }
} /* neither "peer" nor "peers" */
else if (!strcmp(args[0], "disabled")) { /* disables this peers section */
curpeers->state = PR_STSTOPPED;
--
2.1.4
>From fdf45ed7e86017ad1d59813364923d35ac07ac50 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= <[email protected]>
Date: Wed, 25 Apr 2018 15:13:38 +0200
Subject: [PATCH 02/10] CLEANUP: cfgparse: Return asap from cfg_parse_peers().
Avoid useless code indentation.
---
src/cfgparse.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/cfgparse.c b/src/cfgparse.c
index c22aeec..827766c 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -2115,7 +2115,10 @@ 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 (strcmp(newpeer->id, localpeer) != 0)
+ /* We are done. */
+ goto out;
+
/* Current is local peer, it define a frontend */
newpeer->local = 1;
cfg_peers->local = newpeer;
@@ -2158,7 +2161,6 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
err_code |= ERR_FATAL;
goto out;
}
- }
} /* neither "peer" nor "peers" */
else if (!strcmp(args[0], "disabled")) { /* disables this peers section */
curpeers->state = PR_STSTOPPED;
--
2.1.4
>From fcf998c178a5e306cac279be933dfd5533638cbf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= <[email protected]>
Date: Wed, 25 Apr 2018 11:18:46 +0200
Subject: [PATCH 01/10] MINOR: cfgparse: Extract the code to init the frontend
of "peers" sections.
Create init_peers_frontend() function to allocate and initialize
the frontend of "peers" sections (->peers_fe) so that to reuse it later.
---
src/cfgparse.c | 36 +++++++++++++++++++++++++++---------
1 file changed, 27 insertions(+), 9 deletions(-)
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 3d224b9..c22aeec 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -1954,6 +1954,32 @@ static int create_cond_regex_rule(const char *file, int line,
return ret_code;
}
+/* 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.
+ */
+static int init_peers_frontend(const char *file, int linenum,
+ const char *id, struct peers *peers)
+{
+ struct proxy *p;
+
+ p = calloc(1, sizeof *p);
+ if (!p) {
+ ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
+ return -1;
+ }
+
+ init_new_proxy(p);
+ p->parent = peers;
+ 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;
+}
+
/*
* Parse a line in a <listen>, <frontend> or <backend> section.
* Returns the error code, 0 if OK, or any combination of :
@@ -2095,19 +2121,11 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
cfg_peers->local = newpeer;
if (!curpeers->peers_fe) {
- if ((curpeers->peers_fe = calloc(1, sizeof(struct proxy))) == NULL) {
- ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
+ if (init_peers_frontend(file, linenum, args[1], curpeers) != 0) {
err_code |= ERR_ALERT | ERR_ABORT;
goto out;
}
- init_new_proxy(curpeers->peers_fe);
- curpeers->peers_fe->parent = curpeers;
- curpeers->peers_fe->id = strdup(args[1]);
- curpeers->peers_fe->conf.args.file = curpeers->peers_fe->conf.file = strdup(file);
- curpeers->peers_fe->conf.args.line = curpeers->peers_fe->conf.line = linenum;
- peers_setup_frontend(curpeers->peers_fe);
-
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)) {
--
2.1.4