mirror of
https://github.com/yrutschle/sslh.git
synced 2025-06-06 02:13:47 +03:00
refactor: move all file descriptor info for select to its own struct
This commit is contained in:
parent
f91f16d753
commit
90975fd6c3
@ -27,6 +27,15 @@
|
|||||||
|
|
||||||
const char* server_type = "sslh-select";
|
const char* server_type = "sslh-select";
|
||||||
|
|
||||||
|
/* Global state for a select() loop */
|
||||||
|
struct select_info {
|
||||||
|
int max_fd; /* Highest fd number to pass to select() */
|
||||||
|
int num_probing; /* Number of connections currently probing
|
||||||
|
* We use this to know if we need to time out of
|
||||||
|
* select() */
|
||||||
|
fd_set fds_r, fds_w; /* reference fd sets (used to init working copies) */
|
||||||
|
};
|
||||||
|
|
||||||
/* cnx_num_alloc is the number of connection to allocate at once (at start-up,
|
/* cnx_num_alloc is the number of connection to allocate at once (at start-up,
|
||||||
* and then every time we get too many simultaneous connections: e.g. start
|
* and then every time we get too many simultaneous connections: e.g. start
|
||||||
* with 100 slots, then if we get more than 100 connections allocate another
|
* with 100 slots, then if we get more than 100 connections allocate another
|
||||||
@ -296,25 +305,24 @@ static int is_fd_active(int fd, fd_set* set)
|
|||||||
*/
|
*/
|
||||||
void main_loop(struct listen_endpoint listen_sockets[], int num_addr_listen)
|
void main_loop(struct listen_endpoint listen_sockets[], int num_addr_listen)
|
||||||
{
|
{
|
||||||
fd_set fds_r, fds_w; /* reference fd sets (used to init the next 2) */
|
struct select_info fd_info = {0};
|
||||||
|
|
||||||
fd_set readfds, writefds; /* working read and write fd sets */
|
fd_set readfds, writefds; /* working read and write fd sets */
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
int max_fd, i, j, res;
|
int i, j, res;
|
||||||
int in_socket = 0;
|
int in_socket = 0;
|
||||||
struct connection *cnx;
|
struct connection *cnx;
|
||||||
int num_cnx; /* Number of connections in *cnx */
|
int num_cnx; /* Number of connections in *cnx */
|
||||||
int num_probing = 0; /* Number of connections currently probing
|
|
||||||
* We use this to know if we need to time out of
|
|
||||||
* select() */
|
|
||||||
|
|
||||||
FD_ZERO(&fds_r);
|
fd_info.num_probing = 0;
|
||||||
FD_ZERO(&fds_w);
|
FD_ZERO(&fd_info.fds_r);
|
||||||
|
FD_ZERO(&fd_info.fds_w);
|
||||||
|
|
||||||
for (i = 0; i < num_addr_listen; i++) {
|
for (i = 0; i < num_addr_listen; i++) {
|
||||||
FD_SET(listen_sockets[i].socketfd, &fds_r);
|
FD_SET(listen_sockets[i].socketfd, &fd_info.fds_r);
|
||||||
set_nonblock(listen_sockets[i].socketfd);
|
set_nonblock(listen_sockets[i].socketfd);
|
||||||
}
|
}
|
||||||
max_fd = listen_sockets[num_addr_listen-1].socketfd + 1;
|
fd_info.max_fd = listen_sockets[num_addr_listen-1].socketfd + 1;
|
||||||
|
|
||||||
cnx_num_alloc = getpagesize() / sizeof(struct connection);
|
cnx_num_alloc = getpagesize() / sizeof(struct connection);
|
||||||
|
|
||||||
@ -329,25 +337,26 @@ void main_loop(struct listen_endpoint listen_sockets[], int num_addr_listen)
|
|||||||
memset(&tv, 0, sizeof(tv));
|
memset(&tv, 0, sizeof(tv));
|
||||||
tv.tv_sec = cfg.timeout;
|
tv.tv_sec = cfg.timeout;
|
||||||
|
|
||||||
memcpy(&readfds, &fds_r, sizeof(readfds));
|
memcpy(&readfds, &fd_info.fds_r, sizeof(readfds));
|
||||||
memcpy(&writefds, &fds_w, sizeof(writefds));
|
memcpy(&writefds, &fd_info.fds_w, sizeof(writefds));
|
||||||
|
|
||||||
if (cfg.verbose)
|
if (cfg.verbose)
|
||||||
fprintf(stderr, "selecting... max_fd=%d num_probing=%d\n", max_fd, num_probing);
|
fprintf(stderr, "selecting... max_fd=%d num_probing=%d\n",
|
||||||
res = select(max_fd, &readfds, &writefds, NULL, num_probing ? &tv : NULL);
|
fd_info.max_fd, fd_info.num_probing);
|
||||||
|
res = select(fd_info.max_fd, &readfds, &writefds,
|
||||||
|
NULL, fd_info.num_probing ? &tv : NULL);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
perror("select");
|
perror("select");
|
||||||
|
|
||||||
|
|
||||||
/* Check main socket for new connections */
|
/* Check main socket for new connections */
|
||||||
for (i = 0; i < num_addr_listen; i++) {
|
for (i = 0; i < num_addr_listen; i++) {
|
||||||
if (FD_ISSET(listen_sockets[i].socketfd, &readfds)) {
|
if (FD_ISSET(listen_sockets[i].socketfd, &readfds)) {
|
||||||
in_socket = accept_new_connection(listen_sockets[i].socketfd, &cnx, &num_cnx);
|
in_socket = accept_new_connection(listen_sockets[i].socketfd, &cnx, &num_cnx);
|
||||||
if (in_socket > 0) {
|
if (in_socket > 0) {
|
||||||
num_probing++;
|
fd_info.num_probing++;
|
||||||
FD_SET(in_socket, &fds_r);
|
FD_SET(in_socket, &fd_info.fds_r);
|
||||||
if (in_socket >= max_fd)
|
if (in_socket >= fd_info.max_fd)
|
||||||
max_fd = in_socket + 1;;
|
fd_info.max_fd = in_socket + 1;;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -359,16 +368,16 @@ void main_loop(struct listen_endpoint listen_sockets[], int num_addr_listen)
|
|||||||
if (is_fd_active(cnx[i].q[j].fd, &writefds)) {
|
if (is_fd_active(cnx[i].q[j].fd, &writefds)) {
|
||||||
res = flush_deferred(&cnx[i].q[j]);
|
res = flush_deferred(&cnx[i].q[j]);
|
||||||
if ((res == -1) && ((errno == EPIPE) || (errno == ECONNRESET))) {
|
if ((res == -1) && ((errno == EPIPE) || (errno == ECONNRESET))) {
|
||||||
if (cnx[i].state == ST_PROBING) num_probing--;
|
if (cnx[i].state == ST_PROBING) fd_info.num_probing--;
|
||||||
tidy_connection(&cnx[i], &fds_r, &fds_w);
|
tidy_connection(&cnx[i], &fd_info.fds_r, &fd_info.fds_w);
|
||||||
if (cfg.verbose)
|
if (cfg.verbose)
|
||||||
fprintf(stderr, "closed slot %d\n", i);
|
fprintf(stderr, "closed slot %d\n", i);
|
||||||
} else {
|
} else {
|
||||||
/* If no deferred data is left, stop monitoring the fd
|
/* If no deferred data is left, stop monitoring the fd
|
||||||
* for write, and restart monitoring the other one for reads*/
|
* for write, and restart monitoring the other one for reads*/
|
||||||
if (!cnx[i].q[j].deferred_data_size) {
|
if (!cnx[i].q[j].deferred_data_size) {
|
||||||
FD_CLR(cnx[i].q[j].fd, &fds_w);
|
FD_CLR(cnx[i].q[j].fd, &fd_info.fds_w);
|
||||||
FD_SET(cnx[i].q[1-j].fd, &fds_r);
|
FD_SET(cnx[i].q[1-j].fd, &fd_info.fds_r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -407,13 +416,13 @@ void main_loop(struct listen_endpoint listen_sockets[], int num_addr_listen)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
num_probing--;
|
fd_info.num_probing--;
|
||||||
cnx[i].state = ST_SHOVELING;
|
cnx[i].state = ST_SHOVELING;
|
||||||
|
|
||||||
/* libwrap check if required for this protocol */
|
/* libwrap check if required for this protocol */
|
||||||
if (cnx[i].proto->service &&
|
if (cnx[i].proto->service &&
|
||||||
check_access_rights(in_socket, cnx[i].proto->service)) {
|
check_access_rights(in_socket, cnx[i].proto->service)) {
|
||||||
tidy_connection(&cnx[i], &fds_r, &fds_w);
|
tidy_connection(&cnx[i], &fd_info.fds_r, &fd_info.fds_w);
|
||||||
res = -1;
|
res = -1;
|
||||||
} else if (cnx[i].proto->fork) {
|
} else if (cnx[i].proto->fork) {
|
||||||
struct connection *pcnx_i = &cnx[i];
|
struct connection *pcnx_i = &cnx[i];
|
||||||
@ -435,18 +444,18 @@ void main_loop(struct listen_endpoint listen_sockets[], int num_addr_listen)
|
|||||||
default: /* parent */
|
default: /* parent */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tidy_connection(&cnx[i], &fds_r, &fds_w);
|
tidy_connection(&cnx[i], &fd_info.fds_r, &fd_info.fds_w);
|
||||||
res = -1;
|
res = -1;
|
||||||
} else {
|
} else {
|
||||||
res = connect_queue(&cnx[i], &fds_r, &fds_w);
|
res = connect_queue(&cnx[i], &fd_info.fds_r, &fd_info.fds_w);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res >= max_fd)
|
if (res >= fd_info.max_fd)
|
||||||
max_fd = res + 1;;
|
fd_info.max_fd = res + 1;;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ST_SHOVELING:
|
case ST_SHOVELING:
|
||||||
shovel(&cnx[i], j, &fds_r, &fds_w);
|
shovel(&cnx[i], j, &fd_info.fds_r, &fd_info.fds_w);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: /* illegal */
|
default: /* illegal */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user