Skip to content

Commit

Permalink
BUG/MEDIUM: backend: always release the previous connection into its …
Browse files Browse the repository at this point in the history
…own target srv_list

There was a bug reported in issue #19 regarding the fact that haproxy
could mis-route requests to the wrong server. It turns out that when
switching to another server, the old connection was put back into the
srv_list corresponding to the stream's target instead of this connection's
target. Thus if this connection was later picked, it was pointing to the
wrong server.

The patch fixes this and also clarifies the assignment to srv_conn->target
so that it's clear we don't change it when picking it from the srv_list.

This must be backported to 1.9 only.

(cherry picked from commit 3c4e19f)
Signed-off-by: Willy Tarreau <[email protected]>
  • Loading branch information
wtarreau committed Feb 1, 2019
1 parent 13ac3ea commit a4d49a4
Showing 1 changed file with 3 additions and 5 deletions.
8 changes: 3 additions & 5 deletions src/backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -1282,7 +1282,7 @@ int connect_server(struct stream *s)
s->sess->idle_conns--;
session_unown_conn(s->sess, old_conn);
old_conn->owner = sess;
if (!session_add_conn(sess, old_conn, s->target)) {
if (!session_add_conn(sess, old_conn, old_conn->target)) {
old_conn->owner = NULL;
old_conn->mux->destroy(old_conn);
} else
Expand Down Expand Up @@ -1323,14 +1323,15 @@ int connect_server(struct stream *s)
/* no reuse or failed to reuse the connection above, pick a new one */
if (!srv_conn) {
srv_conn = conn_new();
srv_conn->target = s->target;
srv_cs = NULL;
}

if (srv_conn && old_conn != srv_conn) {
if (srv_conn->owner)
session_unown_conn(srv_conn->owner, srv_conn);
srv_conn->owner = s->sess;
if (!session_add_conn(s->sess, srv_conn, s->target)) {
if (!session_add_conn(s->sess, srv_conn, srv_conn->target)) {
/* If we failed to attach the connection, detach the
* conn_stream, possibly destroying the connection */
if (alloced_cs)
Expand All @@ -1354,9 +1355,6 @@ int connect_server(struct stream *s)
}

if (!conn_xprt_ready(srv_conn) && !srv_conn->mux) {
/* the target was only on the stream, assign it to the SI now */
srv_conn->target = s->target;

/* set the correct protocol on the output stream interface */
if (srv)
conn_prepare(srv_conn, protocol_by_family(srv_conn->addr.to.ss_family), srv->xprt);
Expand Down

0 comments on commit a4d49a4

Please sign in to comment.