diff --git a/include/types/fd.h b/include/types/fd.h index 3ab89feba..63c59eead 100644 --- a/include/types/fd.h +++ b/include/types/fd.h @@ -1,23 +1,23 @@ /* - include/types/fd.h - File descriptors states. - - Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation, version 2.1 - exclusively. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ + * include/types/fd.h + * File descriptors states. + * + * Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, version 2.1 + * exclusively. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ #ifndef _TYPES_FD_H #define _TYPES_FD_H @@ -75,10 +75,14 @@ struct fdtab { unsigned short flags; /* various flags precising the exact status of 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 */ - int local_port; /* optional local port */ +}; + +/* less often used information */ +struct fdinfo { struct port_range *port_range; /* optional port range to bind to */ + int local_port; /* optional local port */ + struct sockaddr *peeraddr; /* pointer to peer's network address, or NULL if unset */ + socklen_t peerlen; /* peer's address length, or 0 if unset */ }; /* @@ -123,6 +127,7 @@ extern int nbpollers; extern struct poller pollers[MAX_POLLERS]; /* all registered pollers */ extern struct fdtab *fdtab; /* array of all the file descriptors */ +extern struct fdinfo *fdinfo; /* less-often used infos for file descriptors */ extern int maxfd; /* # of the highest fd + 1 */ extern int totalconn; /* total # of terminated sessions */ extern int actconn; /* # of active sessions */ diff --git a/src/checks.c b/src/checks.c index 0e9aca5e8..e7aefb493 100644 --- a/src/checks.c +++ b/src/checks.c @@ -838,19 +838,19 @@ struct task *process_chk(struct task *t) /* note: in case of retry, we may have to release a previously * allocated port, hence this loop's construct. */ - port_range_release_port(fdtab[fd].port_range, fdtab[fd].local_port); - fdtab[fd].port_range = NULL; + port_range_release_port(fdinfo[fd].port_range, fdinfo[fd].local_port); + fdinfo[fd].port_range = NULL; if (!bind_attempts) break; bind_attempts--; - fdtab[fd].local_port = port_range_alloc_port(s->sport_range); - if (!fdtab[fd].local_port) + fdinfo[fd].local_port = port_range_alloc_port(s->sport_range); + if (!fdinfo[fd].local_port) break; - fdtab[fd].port_range = s->sport_range; - src.sin_port = htons(fdtab[fd].local_port); + fdinfo[fd].port_range = s->sport_range; + src.sin_port = htons(fdinfo[fd].local_port); ret = tcpv4_bind_socket(fd, flags, &src, remote); } while (ret != 0); /* binding NOK */ @@ -926,8 +926,8 @@ struct task *process_chk(struct task *t) 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); + fdinfo[fd].peeraddr = (struct sockaddr *)&sa; + fdinfo[fd].peerlen = sizeof(sa); fdtab[fd].state = FD_STCONN; /* connection in progress */ fdtab[fd].flags = FD_FL_TCP | FD_FL_TCP_NODELAY; EV_FD_SET(fd, DIR_WR); /* for connect status */ @@ -963,8 +963,8 @@ struct task *process_chk(struct task *t) } } } - port_range_release_port(fdtab[fd].port_range, fdtab[fd].local_port); - fdtab[fd].port_range = NULL; + port_range_release_port(fdinfo[fd].port_range, fdinfo[fd].local_port); + fdinfo[fd].port_range = NULL; close(fd); /* socket creation error */ } diff --git a/src/client.c b/src/client.c index b9e304a12..68a192d26 100644 --- a/src/client.c +++ b/src/client.c @@ -449,8 +449,8 @@ int event_accept(int fd) { fdtab[cfd].cb[DIR_RD].b = s->req; fdtab[cfd].cb[DIR_WR].f = l->proto->write; fdtab[cfd].cb[DIR_WR].b = s->rep; - fdtab[cfd].peeraddr = (struct sockaddr *)&s->cli_addr; - fdtab[cfd].peerlen = sizeof(s->cli_addr); + fdinfo[cfd].peeraddr = (struct sockaddr *)&s->cli_addr; + fdinfo[cfd].peerlen = sizeof(s->cli_addr); if ((p->mode == PR_MODE_HTTP && (s->flags & SN_MONITOR)) || (p->mode == PR_MODE_HEALTH && (p->options & PR_O_HTTP_CHK))) { diff --git a/src/fd.c b/src/fd.c index 9dd365a50..c850efa79 100644 --- a/src/fd.c +++ b/src/fd.c @@ -22,6 +22,7 @@ #include struct fdtab *fdtab = NULL; /* array of all the file descriptors */ +struct fdinfo *fdinfo = NULL; /* less-often used infos for file descriptors */ int maxfd; /* # of the highest fd + 1 */ int totalconn; /* total # of terminated sessions */ int actconn; /* # of active sessions */ @@ -37,8 +38,8 @@ int nbpollers = 0; void fd_delete(int fd) { EV_FD_CLO(fd); - port_range_release_port(fdtab[fd].port_range, fdtab[fd].local_port); - fdtab[fd].port_range = NULL; + port_range_release_port(fdinfo[fd].port_range, fdinfo[fd].local_port); + fdinfo[fd].port_range = NULL; close(fd); fdtab[fd].state = FD_STCLOSE; diff --git a/src/haproxy.c b/src/haproxy.c index 83df0925e..43aee22a5 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -641,6 +641,8 @@ void init(int argc, char **argv) if (global.nbproc < 1) global.nbproc = 1; + fdinfo = (struct fdinfo *)calloc(1, + sizeof(struct fdinfo) * (global.maxsock)); fdtab = (struct fdtab *)calloc(1, sizeof(struct fdtab) * (global.maxsock)); for (i = 0; i < global.maxsock; i++) { diff --git a/src/proto_tcp.c b/src/proto_tcp.c index 884016f5a..68da06336 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -279,19 +279,19 @@ int tcpv4_connect_server(struct stream_interface *si, /* note: in case of retry, we may have to release a previously * allocated port, hence this loop's construct. */ - port_range_release_port(fdtab[fd].port_range, fdtab[fd].local_port); - fdtab[fd].port_range = NULL; + port_range_release_port(fdinfo[fd].port_range, fdinfo[fd].local_port); + fdinfo[fd].port_range = NULL; if (!attempts) break; attempts--; - fdtab[fd].local_port = port_range_alloc_port(srv->sport_range); - if (!fdtab[fd].local_port) + fdinfo[fd].local_port = port_range_alloc_port(srv->sport_range); + if (!fdinfo[fd].local_port) break; - fdtab[fd].port_range = srv->sport_range; - src.sin_port = htons(fdtab[fd].local_port); + fdinfo[fd].port_range = srv->sport_range; + src.sin_port = htons(fdinfo[fd].local_port); ret = tcpv4_bind_socket(fd, flags, &src, remote); } while (ret != 0); /* binding NOK */ @@ -301,8 +301,8 @@ int tcpv4_connect_server(struct stream_interface *si, } if (ret) { - port_range_release_port(fdtab[fd].port_range, fdtab[fd].local_port); - fdtab[fd].port_range = NULL; + port_range_release_port(fdinfo[fd].port_range, fdinfo[fd].local_port); + fdinfo[fd].port_range = NULL; close(fd); if (ret == 1) { @@ -388,8 +388,8 @@ int tcpv4_connect_server(struct stream_interface *si, msg = "local address already in use"; qfprintf(stderr,"Cannot connect: %s.\n",msg); - port_range_release_port(fdtab[fd].port_range, fdtab[fd].local_port); - fdtab[fd].port_range = NULL; + port_range_release_port(fdinfo[fd].port_range, fdinfo[fd].local_port); + fdinfo[fd].port_range = NULL; close(fd); send_log(be, LOG_EMERG, "Connect() failed for server %s/%s: %s.\n", @@ -397,15 +397,15 @@ int tcpv4_connect_server(struct stream_interface *si, return SN_ERR_RESOURCE; } else if (errno == ETIMEDOUT) { //qfprintf(stderr,"Connect(): ETIMEDOUT"); - port_range_release_port(fdtab[fd].port_range, fdtab[fd].local_port); - fdtab[fd].port_range = NULL; + port_range_release_port(fdinfo[fd].port_range, fdinfo[fd].local_port); + fdinfo[fd].port_range = NULL; close(fd); return SN_ERR_SRVTO; } else { // (errno == ECONNREFUSED || errno == ENETUNREACH || errno == EACCES || errno == EPERM) //qfprintf(stderr,"Connect(): %d", errno); - port_range_release_port(fdtab[fd].port_range, fdtab[fd].local_port); - fdtab[fd].port_range = NULL; + port_range_release_port(fdinfo[fd].port_range, fdinfo[fd].local_port); + fdinfo[fd].port_range = NULL; close(fd); return SN_ERR_SRVCL; } @@ -419,8 +419,8 @@ int tcpv4_connect_server(struct stream_interface *si, fdtab[fd].cb[DIR_WR].f = &stream_sock_write; fdtab[fd].cb[DIR_WR].b = si->ob; - fdtab[fd].peeraddr = (struct sockaddr *)srv_addr; - fdtab[fd].peerlen = sizeof(struct sockaddr_in); + fdinfo[fd].peeraddr = (struct sockaddr *)srv_addr; + fdinfo[fd].peerlen = sizeof(struct sockaddr_in); fd_insert(fd); EV_FD_SET(fd, DIR_WR); /* for connect status */ @@ -562,8 +562,8 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen) if (listener->options & LI_O_NOLINGER) fdtab[fd].flags |= FD_FL_TCP_NOLING; - fdtab[fd].peeraddr = NULL; - fdtab[fd].peerlen = 0; + fdinfo[fd].peeraddr = NULL; + fdinfo[fd].peerlen = 0; tcp_return: if (msg && errlen) strlcpy2(errmsg, msg, errlen); diff --git a/src/proto_uxst.c b/src/proto_uxst.c index 4fceadcd0..186ddda54 100644 --- a/src/proto_uxst.c +++ b/src/proto_uxst.c @@ -267,8 +267,8 @@ static int uxst_bind_listener(struct listener *listener) fdtab[fd].cb[DIR_RD].b = fdtab[fd].cb[DIR_WR].b = NULL; fdtab[fd].owner = listener; /* reference the listener instead of a task */ fdtab[fd].state = FD_STLISTEN; - fdtab[fd].peeraddr = NULL; - fdtab[fd].peerlen = 0; + fdinfo[fd].peeraddr = NULL; + fdinfo[fd].peerlen = 0; return ERR_NONE; } @@ -537,8 +537,8 @@ int uxst_event_accept(int fd) { fdtab[cfd].cb[DIR_RD].b = s->req; fdtab[cfd].cb[DIR_WR].f = l->proto->write; fdtab[cfd].cb[DIR_WR].b = s->rep; - fdtab[cfd].peeraddr = (struct sockaddr *)&s->cli_addr; - fdtab[cfd].peerlen = sizeof(s->cli_addr); + fdinfo[cfd].peeraddr = (struct sockaddr *)&s->cli_addr; + fdinfo[cfd].peerlen = sizeof(s->cli_addr); EV_FD_SET(cfd, DIR_RD); diff --git a/src/stream_sock.c b/src/stream_sock.c index 2846b3604..65b790a0b 100644 --- a/src/stream_sock.c +++ b/src/stream_sock.c @@ -712,7 +712,7 @@ int stream_sock_write(int fd) * - connecting (EALREADY, EINPROGRESS) * - connected (EISCONN, 0) */ - if ((connect(fd, fdtab[fd].peeraddr, fdtab[fd].peerlen) == 0)) + if ((connect(fd, fdinfo[fd].peeraddr, fdinfo[fd].peerlen) == 0)) errno = 0; if (errno == EALREADY || errno == EINPROGRESS) {