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.
This commit is contained in:
Willy Tarreau 2012-05-11 18:32:18 +02:00
parent 64798bd720
commit d02394b5a1
4 changed files with 24 additions and 17 deletions

View File

@ -74,6 +74,8 @@ struct peer {
time_t last_change; time_t last_change;
struct sockaddr_storage addr; /* peer address */ struct sockaddr_storage addr; /* peer address */
struct protocol *proto; /* peer address protocol */ 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 */ struct peer *next; /* next peer in the list */
}; };

View File

@ -149,6 +149,8 @@ struct server {
int bind_hdr_occ; /* occurrence number of header above: >0 = from first, <0 = from end, 0=disabled */ int bind_hdr_occ; /* occurrence number of header above: >0 = from first, <0 = from end, 0=disabled */
#endif #endif
struct protocol *proto; /* server address protocol */ 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 */ unsigned down_time; /* total time the server was down */
time_t last_change; /* last time, when the state was changed */ time_t last_change; /* last time, when the state was changed */
struct timeval check_start; /* last health check start time */ struct timeval check_start; /* last health check start time */

View File

@ -968,17 +968,24 @@ int connect_server(struct session *s)
return SN_ERR_INTERNAL; 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 */ /* the target was only on the session, assign it to the SI now */
copy_target(&s->req->cons->target, &s->target); 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 */ /* process the case where the server requires the PROXY protocol to be sent */
s->req->cons->send_proxy_ofs = 0; s->req->cons->send_proxy_ofs = 0;
if (s->target.type == TARG_TYPE_SERVER && (s->target.ptr.s->state & SRV_SEND_PROXY)) { 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); 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); assign_tproxy_address(s);
/* flag for logging source ip/port */ /* flag for logging source ip/port */

View File

@ -61,6 +61,7 @@
#include <proto/sample.h> #include <proto/sample.h>
#include <proto/server.h> #include <proto/server.h>
#include <proto/session.h> #include <proto/session.h>
#include <proto/sock_raw.h>
#include <proto/task.h> #include <proto/task.h>
#include <proto/stick_table.h> #include <proto/stick_table.h>
@ -1270,6 +1271,8 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
} }
newpeer->addr = *sk; newpeer->addr = *sk;
newpeer->proto = protocol_by_family(newpeer->addr.ss_family); newpeer->proto = protocol_by_family(newpeer->addr.ss_family);
newpeer->sock = &sock_raw;
newpeer->sock_init_arg = NULL;
if (!sk) { if (!sk) {
Alert("parsing [%s:%d] : Unknown protocol family %d '%s'\n", Alert("parsing [%s:%d] : Unknown protocol family %d '%s'\n",
@ -4071,6 +4074,8 @@ stats_error_parsing:
} }
newsrv->addr = *sk; newsrv->addr = *sk;
newsrv->proto = protocol_by_family(newsrv->addr.ss_family); newsrv->proto = protocol_by_family(newsrv->addr.ss_family);
newsrv->sock = &sock_raw;
newsrv->sock_init_arg = NULL;
if (!sk) { if (!sk) {
Alert("parsing [%s:%d] : Unknown protocol family %d '%s'\n", Alert("parsing [%s:%d] : Unknown protocol family %d '%s'\n",