BUG/MEDIUM: peers: Missing peer initializations.

Initialize ->srv peer field for all the peers, the local peer included.
Indeed, a haproxy process needs to connect to the local peer of a remote
process. Furthermore, when a "peer" or "server" line is parsed by parse_server()
the address must be copied to ->addr field of the peer object only if this address
has been also parsed by parse_server(). This is not the case if this address belongs
to the local peer and is provided on a "server" line.

After having parsed the "peer" or "server" lines of a peer
sections, the ->srv part of all the peer must be initialized for SSL, if
enabled. Same thing for the binding part.

Revert 1417f0b commit which is no more required.

No backport is needed, this is purely 2.0.
This commit is contained in:
Frdric Lcaille 2019-02-12 19:12:32 +01:00 committed by Willy Tarreau
parent cdce54c2b7
commit 76d2cef0c2
2 changed files with 32 additions and 18 deletions

View File

@ -32,7 +32,7 @@
#if defined(USE_OPENSSL)
static inline enum obj_type *peer_session_target(struct peer *p, struct stream *s)
{
if (p->srv && p->srv->use_ssl)
if (p->srv->use_ssl)
return &p->srv->obj_type;
else
return &s->be->obj_type;
@ -40,7 +40,7 @@ static inline enum obj_type *peer_session_target(struct peer *p, struct stream *
static inline struct xprt_ops *peer_xprt(struct peer *p)
{
return (p->srv && p->srv->use_ssl) ? xprt_get(XPRT_SSL) : xprt_get(XPRT_RAW);
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)

View File

@ -809,21 +809,29 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
goto out;
}
/* This initializes curpeer->peers->peers_fe->srv. */
/* This initializes curpeer->peers->peers_fe->srv.
* The server address is parsed only if we are parsing a "peer" line,
* or if we are parsing a "server" line and the current peer is not the local one.
*/
err_code |= parse_server(file, linenum, args, curpeers->peers_fe, NULL, peer || !local_peer);
if (!curpeers->peers_fe->srv)
goto out;
newpeer->addr = curpeers->peers_fe->srv->addr;
newpeer->proto = protocol_by_family(newpeer->addr.ss_family);
/* If the peer address has just been parsed, let's copy it to <newpeer>
* and initializes ->proto.
*/
if (peer || !local_peer) {
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);
if (!newpeer->local) {
newpeer->srv = curpeers->peers_fe->srv;
newpeer->srv = curpeers->peers_fe->srv;
if (!newpeer->local)
goto out;
}
/* The lines above are reserved to "peer" lines. */
if (*args[0] == 's')
@ -3864,24 +3872,30 @@ int check_config_validity()
curpeers->peers_fe = NULL;
}
else {
/* Initializes the transport layer of the server part of all the peers belonging to
* <curpeers> section if required.
* Note that ->srv is used by the local peer of a new process to connect to the local peer
* of an old process.
*/
p = curpeers->remote;
while (p) {
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;
}
/* Configure the SSL bindings of the local peer if required. */
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++;
}
if (!peers_init_sync(curpeers)) {
ha_alert("Peers section '%s': out of memory, giving up on peers.\n",
curpeers->id);