mirror of
https://github.com/tmate-io/tmate-ssh-server.git
synced 2020-11-18 19:53:51 -08:00
Being more careful with signals to avoid deadlocks
This commit is contained in:
parent
9fe781453d
commit
23bbaab3d2
@ -316,6 +316,11 @@ static void setup_ncurse(int fd, const char *name)
|
|||||||
tmate_fatal("Cannot setup terminal");
|
tmate_fatal("Cannot setup terminal");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_sigterm(__unused int sig)
|
||||||
|
{
|
||||||
|
request_server_termination();
|
||||||
|
}
|
||||||
|
|
||||||
static void tmate_spawn_slave_daemon(struct tmate_session *session)
|
static void tmate_spawn_slave_daemon(struct tmate_session *session)
|
||||||
{
|
{
|
||||||
struct tmate_ssh_client *client = &session->ssh_client;
|
struct tmate_ssh_client *client = &session->ssh_client;
|
||||||
@ -355,6 +360,7 @@ static void tmate_spawn_slave_daemon(struct tmate_session *session)
|
|||||||
event_reinit(session->ev_base);
|
event_reinit(session->ev_base);
|
||||||
|
|
||||||
tmux_server_init();
|
tmux_server_init();
|
||||||
|
signal(SIGTERM, handle_sigterm);
|
||||||
server_start(session->ev_base, -1, NULL);
|
server_start(session->ev_base, -1, NULL);
|
||||||
/* never reached */
|
/* never reached */
|
||||||
}
|
}
|
||||||
|
@ -169,6 +169,11 @@ static void register_on_ssh_read(struct tmate_ssh_client *client)
|
|||||||
event_add(&client->ev_ssh, NULL);
|
event_add(&client->ev_ssh, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_sigalrm(__unused int sig)
|
||||||
|
{
|
||||||
|
tmate_fatal("Connection grace period (%d) passed", TMATE_SSH_GRACE_PERIOD);
|
||||||
|
}
|
||||||
|
|
||||||
static void client_bootstrap(struct tmate_session *_session)
|
static void client_bootstrap(struct tmate_session *_session)
|
||||||
{
|
{
|
||||||
struct tmate_ssh_client *client = &_session->ssh_client;
|
struct tmate_ssh_client *client = &_session->ssh_client;
|
||||||
@ -187,6 +192,7 @@ static void client_bootstrap(struct tmate_session *_session)
|
|||||||
setsockopt(ssh_get_fd(session), IPPROTO_TCP, TCP_NODELAY,
|
setsockopt(ssh_get_fd(session), IPPROTO_TCP, TCP_NODELAY,
|
||||||
&flag, sizeof(flag));
|
&flag, sizeof(flag));
|
||||||
|
|
||||||
|
signal(SIGALRM, handle_sigalrm);
|
||||||
alarm(grace_period);
|
alarm(grace_period);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -228,55 +234,6 @@ static void client_bootstrap(struct tmate_session *_session)
|
|||||||
/* never reached */
|
/* never reached */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_sigchld(void)
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
pid_t pid;
|
|
||||||
|
|
||||||
while ((pid = waitpid(WAIT_ANY, &status, WNOHANG)) > 0) {
|
|
||||||
if (WIFEXITED(status))
|
|
||||||
tmate_info("Child %d exited (%d)", pid, WEXITSTATUS(status));
|
|
||||||
if (WIFSIGNALED(status))
|
|
||||||
tmate_info("Child %d killed (%d)", pid, WTERMSIG(status));
|
|
||||||
if (WIFSTOPPED(status))
|
|
||||||
tmate_info("Child %d stopped (%d)", pid, WSTOPSIG(status));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_sigalrm(void)
|
|
||||||
{
|
|
||||||
tmate_fatal("Connection grace period (%d) passed", TMATE_SSH_GRACE_PERIOD);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_sigsegv(void)
|
|
||||||
{
|
|
||||||
tmate_info("CRASH, printing stack trace");
|
|
||||||
tmate_print_stack_trace();
|
|
||||||
tmate_fatal("CRASHED");
|
|
||||||
}
|
|
||||||
static void handle_sigterm(void)
|
|
||||||
{
|
|
||||||
request_server_termination();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void signal_handler(int sig)
|
|
||||||
{
|
|
||||||
switch (sig) {
|
|
||||||
case SIGTERM: handle_sigterm(); break;
|
|
||||||
case SIGCHLD: handle_sigchld(); break;
|
|
||||||
case SIGALRM: handle_sigalrm(); break;
|
|
||||||
case SIGSEGV: handle_sigsegv(); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void setup_signals(void)
|
|
||||||
{
|
|
||||||
signal(SIGTERM, signal_handler);
|
|
||||||
signal(SIGCHLD, signal_handler);
|
|
||||||
signal(SIGALRM, signal_handler);
|
|
||||||
signal(SIGSEGV, signal_handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_ip(int fd, char *dst, size_t len)
|
static int get_ip(int fd, char *dst, size_t len)
|
||||||
{
|
{
|
||||||
struct sockaddr sa;
|
struct sockaddr sa;
|
||||||
@ -340,14 +297,42 @@ static ssh_bind prepare_ssh(const char *keys_dir, int port)
|
|||||||
return bind;
|
return bind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_sigchld(__unused int sig)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
while ((pid = waitpid(WAIT_ANY, &status, WNOHANG)) > 0) {
|
||||||
|
if (WIFEXITED(status))
|
||||||
|
tmate_info("Child %d exited (%d)", pid, WEXITSTATUS(status));
|
||||||
|
if (WIFSIGNALED(status))
|
||||||
|
tmate_info("Child %d killed (%d)", pid, WTERMSIG(status));
|
||||||
|
if (WIFSTOPPED(status))
|
||||||
|
tmate_info("Child %d stopped (%d)", pid, WSTOPSIG(status));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_sigsegv(__unused int sig)
|
||||||
|
{
|
||||||
|
tmate_info("CRASH, printing stack trace");
|
||||||
|
tmate_print_stack_trace();
|
||||||
|
tmate_fatal("CRASHED");
|
||||||
|
}
|
||||||
|
|
||||||
void tmate_ssh_server_main(struct tmate_session *session,
|
void tmate_ssh_server_main(struct tmate_session *session,
|
||||||
const char *keys_dir, int port)
|
const char *keys_dir, int port)
|
||||||
{
|
{
|
||||||
|
sigset_t sigchld_set;
|
||||||
struct tmate_ssh_client *client = &session->ssh_client;
|
struct tmate_ssh_client *client = &session->ssh_client;
|
||||||
ssh_bind bind;
|
ssh_bind bind;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
setup_signals();
|
signal(SIGSEGV, handle_sigsegv);
|
||||||
|
signal(SIGCHLD, handle_sigchld);
|
||||||
|
|
||||||
|
sigemptyset(&sigchld_set);
|
||||||
|
sigaddset(&sigchld_set, SIGCHLD);
|
||||||
|
sigprocmask(SIG_BLOCK, &sigchld_set, NULL);
|
||||||
|
|
||||||
bind = prepare_ssh(keys_dir, port);
|
bind = prepare_ssh(keys_dir, port);
|
||||||
|
|
||||||
@ -360,8 +345,10 @@ void tmate_ssh_server_main(struct tmate_session *session,
|
|||||||
if (!client->session)
|
if (!client->session)
|
||||||
tmate_fatal("Cannot initialize session");
|
tmate_fatal("Cannot initialize session");
|
||||||
|
|
||||||
|
sigprocmask(SIG_UNBLOCK, &sigchld_set, NULL);
|
||||||
if (ssh_bind_accept(bind, client->session) < 0)
|
if (ssh_bind_accept(bind, client->session) < 0)
|
||||||
tmate_fatal("Error accepting connection: %s", ssh_get_error(bind));
|
tmate_fatal("Error accepting connection: %s", ssh_get_error(bind));
|
||||||
|
sigprocmask(SIG_BLOCK, &sigchld_set, NULL);
|
||||||
|
|
||||||
if (get_ip(ssh_get_fd(client->session),
|
if (get_ip(ssh_get_fd(client->session),
|
||||||
client->ip_address, sizeof(client->ip_address)) < 0)
|
client->ip_address, sizeof(client->ip_address)) < 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user