diff --git a/include/types/peers.h b/include/types/peers.h index 50e4ea384..9e33d6de0 100644 --- a/include/types/peers.h +++ b/include/types/peers.h @@ -74,6 +74,8 @@ struct peer { time_t last_change; struct sockaddr_storage addr; /* peer address */ struct protocol *proto; /* peer address protocol */ + struct sock_ops *sock; /* peer socket operations */ + void *sock_init_arg; /* socket operations's opaque init argument if needed */ struct peer *next; /* next peer in the list */ }; diff --git a/include/types/server.h b/include/types/server.h index 31f036d83..aa2c4f8bb 100644 --- a/include/types/server.h +++ b/include/types/server.h @@ -149,6 +149,8 @@ struct server { int bind_hdr_occ; /* occurrence number of header above: >0 = from first, <0 = from end, 0=disabled */ #endif struct protocol *proto; /* server address protocol */ + struct sock_ops *sock; /* server socket operations */ + void *sock_init_arg; /* socket operations's opaque init argument if needed */ unsigned down_time; /* total time the server was down */ time_t last_change; /* last time, when the state was changed */ struct timeval check_start; /* last health check start time */ diff --git a/src/backend.c b/src/backend.c index 9467b2d0b..3f30bea04 100644 --- a/src/backend.c +++ b/src/backend.c @@ -968,17 +968,24 @@ int connect_server(struct session *s) return SN_ERR_INTERNAL; } - /* Prepare the stream interface for a TCP connection. Later - * we may assign a protocol-specific connect() function. - * NOTE: when we later support HTTP keep-alive, we'll have to - * decide here if we can reuse the connection by comparing the - * session's freshly assigned target with the stream interface's. - */ - stream_interface_prepare(s->req->cons, &sock_raw); - /* the target was only on the session, assign it to the SI now */ copy_target(&s->req->cons->target, &s->target); + /* set the correct protocol on the output stream interface */ + if (s->target.type == TARG_TYPE_SERVER) { + s->req->cons->proto = target_srv(&s->target)->proto; + stream_interface_prepare(s->req->cons, target_srv(&s->target)->sock); + } + else if (s->target.type == TARG_TYPE_PROXY) { + /* proxies exclusively run on sock_raw right now */ + s->req->cons->proto = protocol_by_family(s->req->cons->addr.to.ss_family); + stream_interface_prepare(s->req->cons, &sock_raw); + if (!s->req->cons->proto) + return SN_ERR_INTERNAL; + } + else + return SN_ERR_INTERNAL; /* how did we get there ? */ + /* process the case where the server requires the PROXY protocol to be sent */ s->req->cons->send_proxy_ofs = 0; if (s->target.type == TARG_TYPE_SERVER && (s->target.ptr.s->state & SRV_SEND_PROXY)) { @@ -986,15 +993,6 @@ int connect_server(struct session *s) si_get_to_addr(s->req->prod); } - /* set the correct protocol on the output stream interface */ - if (s->target.type == TARG_TYPE_SERVER) - s->req->cons->proto = target_srv(&s->target)->proto; - else if (s->target.type == TARG_TYPE_PROXY) { - s->req->cons->proto = protocol_by_family(s->req->cons->addr.to.ss_family); - if (!s->req->cons->proto) - return SN_ERR_INTERNAL; - } - assign_tproxy_address(s); /* flag for logging source ip/port */ diff --git a/src/cfgparse.c b/src/cfgparse.c index ec15fbad2..5d12056d0 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -61,6 +61,7 @@ #include #include #include +#include #include #include @@ -1270,6 +1271,8 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm) } newpeer->addr = *sk; newpeer->proto = protocol_by_family(newpeer->addr.ss_family); + newpeer->sock = &sock_raw; + newpeer->sock_init_arg = NULL; if (!sk) { Alert("parsing [%s:%d] : Unknown protocol family %d '%s'\n", @@ -4071,6 +4074,8 @@ stats_error_parsing: } newsrv->addr = *sk; newsrv->proto = protocol_by_family(newsrv->addr.ss_family); + newsrv->sock = &sock_raw; + newsrv->sock_init_arg = NULL; if (!sk) { Alert("parsing [%s:%d] : Unknown protocol family %d '%s'\n",