From: Willy Tarreau Date: Fri, 11 May 2012 16:32:18 +0000 (+0200) Subject: MEDIUM: stream_interface: derive the socket operations from the target X-Git-Tag: v1.5-dev10~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d02394b5a1468618cf708fb240a8b0930c077663;p=thirdparty%2Fhaproxy.git MEDIUM: stream_interface: derive the socket operations from the target Instead of hard-coding sock_raw in connect_server(), we set this socket operation at config parsing time. Right now, only servers and peers have it. Proxies are still hard-coded as sock_raw. This will be needed for future work on SSL which requires a different socket layer. --- diff --git a/include/types/peers.h b/include/types/peers.h index 50e4ea3840..9e33d6de02 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 31f036d836..aa2c4f8bbc 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 9467b2d0b0..3f30bea048 100644 --- a/src/backend.c +++ b/src/backend.c @@ -968,32 +968,30 @@ 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); - /* 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)) { - s->req->cons->send_proxy_ofs = 1; /* must compute size */ - si_get_to_addr(s->req->prod); - } - /* set the correct protocol on the output stream interface */ - if (s->target.type == TARG_TYPE_SERVER) + 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)) { + s->req->cons->send_proxy_ofs = 1; /* must compute size */ + si_get_to_addr(s->req->prod); + } assign_tproxy_address(s); diff --git a/src/cfgparse.c b/src/cfgparse.c index ec15fbad21..5d12056d05 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",