From: Willy Tarreau Date: Tue, 9 Oct 2007 15:14:37 +0000 (+0200) Subject: [MEDIUM] moved the sockaddr pointer to the fdtab structure X-Git-Tag: v1.3.13~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e94ebd0e37cb60c65549debb15f1965dab988df1;p=thirdparty%2Fhaproxy.git [MEDIUM] moved the sockaddr pointer to the fdtab structure The stream_sock_* functions had to know about sessions just in order to get the server's address for a connect() operation. This is not desirable, particularly for non-IP protocols (eg: PF_UNIX). Put a pointer to the peer's sockaddr_storage or sockaddr address in the fdtab structure so that we never need to look further. With this small change, the stream_sock.c file is now 100% protocol independant. --- diff --git a/include/types/fd.h b/include/types/fd.h index a1b6e9d4d4..3eacd7a32e 100644 --- a/include/types/fd.h +++ b/include/types/fd.h @@ -22,6 +22,7 @@ #ifndef _TYPES_FD_H #define _TYPES_FD_H +#include #include #include #include @@ -63,6 +64,8 @@ struct fdtab { struct task *owner; /* the session (or proxy) associated with this fd */ unsigned char state; /* the state of this fd */ unsigned char ev; /* event seen in return of poll() : FD_POLL_* */ + struct sockaddr *peeraddr; /* pointer to peer's network address, or NULL if unset */ + socklen_t peerlen; /* peer's address length, or 0 if unset */ }; /* diff --git a/src/backend.c b/src/backend.c index 91c0b34b29..b744703704 100644 --- a/src/backend.c +++ b/src/backend.c @@ -545,7 +545,10 @@ int connect_server(struct session *s) fdtab[fd].cb[DIR_RD].b = s->rep; fdtab[fd].cb[DIR_WR].f = &stream_sock_write; fdtab[fd].cb[DIR_WR].b = s->req; - + + fdtab[fd].peeraddr = (struct sockaddr *)&s->srv_addr; + fdtab[fd].peerlen = sizeof(s->srv_addr); + EV_FD_SET(fd, DIR_WR); /* for connect status */ fd_insert(fd); diff --git a/src/checks.c b/src/checks.c index cd6bd3007a..490ff02f26 100644 --- a/src/checks.c +++ b/src/checks.c @@ -403,6 +403,8 @@ void process_chk(struct task *t, struct timeval *next) fdtab[fd].cb[DIR_RD].b = NULL; fdtab[fd].cb[DIR_WR].f = &event_srv_chk_w; fdtab[fd].cb[DIR_WR].b = NULL; + fdtab[fd].peeraddr = (struct sockaddr *)&sa; + fdtab[fd].peerlen = sizeof(sa); fdtab[fd].state = FD_STCONN; /* connection in progress */ fdtab[fd].ev = 0; EV_FD_SET(fd, DIR_WR); /* for connect status */ diff --git a/src/client.c b/src/client.c index 1f58154c2f..e887b7c7c4 100644 --- a/src/client.c +++ b/src/client.c @@ -397,6 +397,8 @@ int event_accept(int fd) { fdtab[cfd].cb[DIR_RD].b = s->req; fdtab[cfd].cb[DIR_WR].f = &stream_sock_write; fdtab[cfd].cb[DIR_WR].b = s->rep; + fdtab[cfd].peeraddr = (struct sockaddr *)&s->cli_addr; + fdtab[cfd].peerlen = sizeof(s->cli_addr); fdtab[cfd].ev = 0; if ((p->mode == PR_MODE_HTTP && (s->flags & SN_MONITOR)) || diff --git a/src/proxy.c b/src/proxy.c index bd33c84e0b..f2967de311 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -158,6 +158,8 @@ int start_proxies(int verbose) fdtab[fd].cb[DIR_RD].b = fdtab[fd].cb[DIR_WR].b = NULL; fdtab[fd].owner = (struct task *)curproxy; /* reference the proxy instead of a task */ fdtab[fd].state = FD_STLISTEN; + fdtab[fd].peeraddr = NULL; + fdtab[fd].peerlen = 0; fdtab[fd].ev = 0; listeners++; } diff --git a/src/stream_sock.c b/src/stream_sock.c index 4541343229..8c47d318cb 100644 --- a/src/stream_sock.c +++ b/src/stream_sock.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -229,8 +228,6 @@ int stream_sock_write(int fd) { if (max == 0) { /* may be we have received a connection acknowledgement in TCP mode without data */ if (likely(fdtab[fd].state == FD_STCONN)) { - struct session *s = fdtab[fd].owner->context; - /* We have no data to send to check the connection, and * getsockopt() will not inform us whether the connection * is still pending. So we'll reuse connect() to check the @@ -240,7 +237,7 @@ int stream_sock_write(int fd) { * - connecting (EALREADY, EINPROGRESS) * - connected (EISCONN, 0) */ - if ((connect(fd, (struct sockaddr *)&s->srv_addr, sizeof(s->srv_addr)) == 0)) + if ((connect(fd, fdtab[fd].peeraddr, fdtab[fd].peerlen) == 0)) errno = 0; if (errno == EALREADY || errno == EINPROGRESS) {