mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 23:56:57 +02:00
BUG/MEDIUM: Special-case http_proxy when dealing with outgoing connections.
http_proxy is special, because it creates its connection and conn_stream earlier. So in assign_server(), check that the connection associated with the conn_stream has a destination address set, and in connect_server(), use the connection and the conn_stream already attached to the stream_interface, instead of looking for a connection in the session, and creating a new conn_stream.
This commit is contained in:
parent
ba4fff5fd2
commit
2442f68dd3
@ -744,10 +744,16 @@ int assign_server(struct stream *s)
|
|||||||
else if (s->be->options & (PR_O_DISPATCH | PR_O_TRANSP)) {
|
else if (s->be->options & (PR_O_DISPATCH | PR_O_TRANSP)) {
|
||||||
s->target = &s->be->obj_type;
|
s->target = &s->be->obj_type;
|
||||||
}
|
}
|
||||||
else if ((s->be->options & PR_O_HTTP_PROXY) &&
|
else if ((s->be->options & PR_O_HTTP_PROXY)) {
|
||||||
conn && is_addr(&conn->addr.to)) {
|
conn = cs_conn(objt_cs(s->si[1].end));
|
||||||
|
|
||||||
|
if (conn && is_addr(&conn->addr.to)) {
|
||||||
/* in proxy mode, we need a valid destination address */
|
/* in proxy mode, we need a valid destination address */
|
||||||
s->target = &s->be->obj_type;
|
s->target = &s->be->obj_type;
|
||||||
|
} else {
|
||||||
|
err = SRV_STATUS_NOSRV;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
err = SRV_STATUS_NOSRV;
|
err = SRV_STATUS_NOSRV;
|
||||||
@ -1109,13 +1115,14 @@ int connect_server(struct stream *s)
|
|||||||
struct connection *cli_conn = NULL;
|
struct connection *cli_conn = NULL;
|
||||||
struct connection *srv_conn = NULL;
|
struct connection *srv_conn = NULL;
|
||||||
struct connection *old_conn = NULL;
|
struct connection *old_conn = NULL;
|
||||||
struct conn_stream *srv_cs;
|
struct conn_stream *srv_cs = NULL;
|
||||||
struct server *srv;
|
struct server *srv;
|
||||||
int reuse = 0;
|
int reuse = 0;
|
||||||
int err;
|
int err;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
||||||
|
if (!(s->be->options & PR_O_HTTP_PROXY)) {
|
||||||
for (i = 0; i < MAX_SRV_LIST; i++) {
|
for (i = 0; i < MAX_SRV_LIST; i++) {
|
||||||
if (s->sess->srv_list[i].target == s->target) {
|
if (s->sess->srv_list[i].target == s->target) {
|
||||||
list_for_each_entry(srv_conn, &s->sess->srv_list[i].list,
|
list_for_each_entry(srv_conn, &s->sess->srv_list[i].list,
|
||||||
@ -1137,6 +1144,17 @@ int connect_server(struct stream *s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
/* http_proxy is special, we can't just reuse any connection,
|
||||||
|
* as the destination may be different. We should have created
|
||||||
|
* a connection and a conn_stream earlier, so get the
|
||||||
|
* connection from the conn_stream.
|
||||||
|
*/
|
||||||
|
srv_cs = objt_cs(s->si[1].end);
|
||||||
|
old_conn = srv_conn = cs_conn(srv_cs);
|
||||||
|
if (old_conn)
|
||||||
|
reuse = 1;
|
||||||
|
}
|
||||||
old_conn = srv_conn;
|
old_conn = srv_conn;
|
||||||
|
|
||||||
srv = objt_server(s->target);
|
srv = objt_server(s->target);
|
||||||
@ -1227,6 +1245,10 @@ int connect_server(struct stream *s)
|
|||||||
srv_conn = conn_new();
|
srv_conn = conn_new();
|
||||||
srv_cs = NULL;
|
srv_cs = NULL;
|
||||||
} else {
|
} else {
|
||||||
|
/* We already created a cs earlier when using http_proxy, so
|
||||||
|
* only create a new one if we don't have one already.
|
||||||
|
*/
|
||||||
|
if (!srv_cs) {
|
||||||
if (srv_conn->mux->avail_streams(srv_conn) == 1) {
|
if (srv_conn->mux->avail_streams(srv_conn) == 1) {
|
||||||
/* No more streams available, remove it from the list */
|
/* No more streams available, remove it from the list */
|
||||||
LIST_DEL(&srv_conn->list);
|
LIST_DEL(&srv_conn->list);
|
||||||
@ -1236,6 +1258,7 @@ int connect_server(struct stream *s)
|
|||||||
if (srv_cs)
|
if (srv_cs)
|
||||||
si_attach_cs(&s->si[1], srv_cs);
|
si_attach_cs(&s->si[1], srv_cs);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (srv_conn && old_conn != srv_conn) {
|
if (srv_conn && old_conn != srv_conn) {
|
||||||
srv_conn->owner = s->sess;
|
srv_conn->owner = s->sess;
|
||||||
LIST_DEL(&srv_conn->session_list);
|
LIST_DEL(&srv_conn->session_list);
|
||||||
|
Loading…
Reference in New Issue
Block a user