mirror of
https://github.com/yrutschle/sslh.git
synced 2025-04-12 23:27:15 +03:00
fix fork failure handling
This commit is contained in:
parent
c8c6688d16
commit
3ab2acdafa
@ -166,15 +166,15 @@ void main_loop(int listen_sockets[], int num_addr_listen)
|
||||
case -1: log_message(LOG_ERR, "fork failed: err %d: %s\n", errno, strerror(errno));
|
||||
break;
|
||||
|
||||
/* In parent process */
|
||||
case 0: break;
|
||||
|
||||
/* In child process */
|
||||
default:
|
||||
case 0:
|
||||
for (i = 0; i < num_addr_listen; ++i)
|
||||
close(listen_sockets[i]);
|
||||
start_shoveler(in_socket);
|
||||
exit(0);
|
||||
|
||||
/* In parent process */
|
||||
default: break;
|
||||
}
|
||||
close(in_socket);
|
||||
}
|
||||
|
@ -275,18 +275,6 @@ void connect_proxy(struct connection *cnx)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Close all connection fd except one (used when forking) */
|
||||
void keep_cnx(int index, struct connection* cnx, int num_cnx)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < num_cnx; i++)
|
||||
if (i != index)
|
||||
for (j = 0; j < 2; j++)
|
||||
if (cnx[i].q[j].fd != -1)
|
||||
close(cnx[i].q[j].fd);
|
||||
}
|
||||
|
||||
/* returns true if specified fd is initialised and present in fd_set */
|
||||
int is_fd_active(int fd, fd_set* set)
|
||||
{
|
||||
@ -422,29 +410,36 @@ void main_loop(int listen_sockets[], int num_addr_listen)
|
||||
num_probing--;
|
||||
cnx[i].state = ST_SHOVELING;
|
||||
|
||||
/* libwrap check if required for this protocol */
|
||||
if (cnx[i].proto->service &&
|
||||
check_access_rights(in_socket, cnx[i].proto->service)) {
|
||||
tidy_connection(&cnx[i], &fds_r, &fds_w);
|
||||
res = -1;
|
||||
} else if (cnx[i].proto->fork) {
|
||||
switch (fork()) {
|
||||
case 0: break;
|
||||
case -1: log_message(LOG_ERR, "fork failed: err %d: %s\n", errno, strerror(errno));
|
||||
break;
|
||||
default:
|
||||
for (i = 0; i < num_addr_listen; i++)
|
||||
close(listen_sockets[i]);
|
||||
keep_cnx(i, cnx, num_cnx);
|
||||
free(cnx);
|
||||
connect_proxy(&cnx[i]);
|
||||
exit(0);
|
||||
}
|
||||
tidy_connection(&cnx[i], &fds_r, &fds_w);
|
||||
res = -1;
|
||||
} else {
|
||||
res = connect_queue(&cnx[i], &fds_r, &fds_w);
|
||||
}
|
||||
/* libwrap check if required for this protocol */
|
||||
if (cnx[i].proto->service &&
|
||||
check_access_rights(in_socket, cnx[i].proto->service)) {
|
||||
tidy_connection(&cnx[i], &fds_r, &fds_w);
|
||||
res = -1;
|
||||
} else if (cnx[i].proto->fork) {
|
||||
struct connection *pcnx_i = &cnx[i];
|
||||
struct connection cnx_i = *pcnx_i;
|
||||
switch (fork()) {
|
||||
case 0: /* child */
|
||||
for (i = 0; i < num_addr_listen; i++)
|
||||
close(listen_sockets[i]);
|
||||
for (i = 0; i < num_cnx; i++)
|
||||
if (&cnx[i] != pcnx_i)
|
||||
for (j = 0; j < 2; j++)
|
||||
if (cnx[i].q[j].fd != -1)
|
||||
close(cnx[i].q[j].fd);
|
||||
free(cnx);
|
||||
connect_proxy(&cnx_i);
|
||||
exit(0);
|
||||
case -1: log_message(LOG_ERR, "fork failed: err %d: %s\n", errno, strerror(errno));
|
||||
break;
|
||||
default: /* parent */
|
||||
break;
|
||||
}
|
||||
tidy_connection(&cnx[i], &fds_r, &fds_w);
|
||||
res = -1;
|
||||
} else {
|
||||
res = connect_queue(&cnx[i], &fds_r, &fds_w);
|
||||
}
|
||||
|
||||
if (res >= max_fd)
|
||||
max_fd = res + 1;;
|
||||
|
Loading…
x
Reference in New Issue
Block a user