mirror of
git://anongit.mindrot.org/openssh.git
synced 2025-02-17 22:36:53 +00:00
- markus@cvs.openbsd.org 2001/10/09 21:59:41
[channels.c channels.h serverloop.c session.c session.h] simplify session close: no more delayed session_close, no more blocking wait() calls.
This commit is contained in:
parent
c71f4e40b6
commit
52b77beb65
@ -44,6 +44,10 @@
|
|||||||
[serverloop.c]
|
[serverloop.c]
|
||||||
close all channels if the connection to the remote host has been closed,
|
close all channels if the connection to the remote host has been closed,
|
||||||
should fix sshd's hanging with WCHAN==wait
|
should fix sshd's hanging with WCHAN==wait
|
||||||
|
- markus@cvs.openbsd.org 2001/10/09 21:59:41
|
||||||
|
[channels.c channels.h serverloop.c session.c session.h]
|
||||||
|
simplify session close: no more delayed session_close, no more
|
||||||
|
blocking wait() calls.
|
||||||
|
|
||||||
20011007
|
20011007
|
||||||
- (bal) ssh-copy-id corrected permissions for .ssh/ and authorized_keys.
|
- (bal) ssh-copy-id corrected permissions for .ssh/ and authorized_keys.
|
||||||
@ -6689,4 +6693,4 @@
|
|||||||
- Wrote replacements for strlcpy and mkdtemp
|
- Wrote replacements for strlcpy and mkdtemp
|
||||||
- Released 1.0pre1
|
- Released 1.0pre1
|
||||||
|
|
||||||
$Id: ChangeLog,v 1.1597 2001/10/10 05:08:36 djm Exp $
|
$Id: ChangeLog,v 1.1598 2001/10/10 05:14:37 djm Exp $
|
||||||
|
18
channels.c
18
channels.c
@ -39,7 +39,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: channels.c,v 1.138 2001/10/08 11:48:57 markus Exp $");
|
RCSID("$OpenBSD: channels.c,v 1.139 2001/10/09 21:59:41 markus Exp $");
|
||||||
|
|
||||||
#include "ssh.h"
|
#include "ssh.h"
|
||||||
#include "ssh1.h"
|
#include "ssh1.h"
|
||||||
@ -359,22 +359,6 @@ channel_free_all(void)
|
|||||||
channel_free(channels[i]);
|
channel_free(channels[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
channel_detach_all(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
Channel *c;
|
|
||||||
|
|
||||||
for (i = 0; i < channels_alloc; i++) {
|
|
||||||
c = channels[i];
|
|
||||||
if (c != NULL && c->detach_user != NULL) {
|
|
||||||
debug("channel_detach_all: channel %d", c->self);
|
|
||||||
c->detach_user(c->self, NULL);
|
|
||||||
c->detach_user = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Closes the sockets/fds of all channels. This is used to close extra file
|
* Closes the sockets/fds of all channels. This is used to close extra file
|
||||||
* descriptors after a fork.
|
* descriptors after a fork.
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
/* RCSID("$OpenBSD: channels.h,v 1.48 2001/10/07 17:49:40 markus Exp $"); */
|
/* RCSID("$OpenBSD: channels.h,v 1.49 2001/10/09 21:59:41 markus Exp $"); */
|
||||||
|
|
||||||
#ifndef CHANNEL_H
|
#ifndef CHANNEL_H
|
||||||
#define CHANNEL_H
|
#define CHANNEL_H
|
||||||
@ -143,7 +143,6 @@ Channel *channel_new(char *, int, int, int, int, int, int, int, char *, int);
|
|||||||
void channel_set_fds(int, int, int, int, int, int);
|
void channel_set_fds(int, int, int, int, int, int);
|
||||||
void channel_free(Channel *);
|
void channel_free(Channel *);
|
||||||
void channel_free_all(void);
|
void channel_free_all(void);
|
||||||
void channel_detach_all(void);
|
|
||||||
void channel_stop_listening(void);
|
void channel_stop_listening(void);
|
||||||
|
|
||||||
void channel_send_open(int);
|
void channel_send_open(int);
|
||||||
@ -177,7 +176,6 @@ void channel_output_poll(void);
|
|||||||
|
|
||||||
int channel_not_very_much_buffered_data(void);
|
int channel_not_very_much_buffered_data(void);
|
||||||
void channel_close_all(void);
|
void channel_close_all(void);
|
||||||
void channel_free_all(void);
|
|
||||||
int channel_still_open(void);
|
int channel_still_open(void);
|
||||||
char *channel_open_message(void);
|
char *channel_open_message(void);
|
||||||
int channel_find_open(void);
|
int channel_find_open(void);
|
||||||
|
36
serverloop.c
36
serverloop.c
@ -35,7 +35,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: serverloop.c,v 1.80 2001/10/09 19:51:18 markus Exp $");
|
RCSID("$OpenBSD: serverloop.c,v 1.81 2001/10/09 21:59:41 markus Exp $");
|
||||||
|
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
@ -674,6 +674,7 @@ server_loop2(Authctxt *authctxt)
|
|||||||
fd_set *readset = NULL, *writeset = NULL;
|
fd_set *readset = NULL, *writeset = NULL;
|
||||||
int rekeying = 0, max_fd, status, nalloc = 0;
|
int rekeying = 0, max_fd, status, nalloc = 0;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
sigset_t oset, nset;
|
||||||
|
|
||||||
debug("Entering interactive session for SSH2.");
|
debug("Entering interactive session for SSH2.");
|
||||||
|
|
||||||
@ -696,12 +697,17 @@ server_loop2(Authctxt *authctxt)
|
|||||||
channel_output_poll();
|
channel_output_poll();
|
||||||
wait_until_can_do_something(&readset, &writeset, &max_fd,
|
wait_until_can_do_something(&readset, &writeset, &max_fd,
|
||||||
&nalloc, 0);
|
&nalloc, 0);
|
||||||
|
|
||||||
|
/* block SIGCHLD while we check for dead children */
|
||||||
|
sigemptyset(&nset);
|
||||||
|
sigaddset(&nset, SIGCHLD);
|
||||||
|
sigprocmask(SIG_BLOCK, &nset, &oset);
|
||||||
if (child_terminated) {
|
if (child_terminated) {
|
||||||
while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
|
while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
|
||||||
session_close_by_pid(pid, status);
|
session_close_by_pid(pid, status);
|
||||||
/* XXX race */
|
|
||||||
child_terminated = 0;
|
child_terminated = 0;
|
||||||
}
|
}
|
||||||
|
sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||||
if (!rekeying)
|
if (!rekeying)
|
||||||
channel_after_select(readset, writeset);
|
channel_after_select(readset, writeset);
|
||||||
process_input(readset);
|
process_input(readset);
|
||||||
@ -709,35 +715,21 @@ server_loop2(Authctxt *authctxt)
|
|||||||
break;
|
break;
|
||||||
process_output(writeset);
|
process_output(writeset);
|
||||||
}
|
}
|
||||||
/* close all channels, no more reads and writes */
|
|
||||||
channel_close_all();
|
|
||||||
|
|
||||||
if (readset)
|
if (readset)
|
||||||
xfree(readset);
|
xfree(readset);
|
||||||
if (writeset)
|
if (writeset)
|
||||||
xfree(writeset);
|
xfree(writeset);
|
||||||
|
|
||||||
mysignal(SIGCHLD, SIG_DFL);
|
/* free all channels, no more reads and writes */
|
||||||
|
channel_free_all();
|
||||||
|
|
||||||
/* collect dead children */
|
/* collect remaining dead children, XXX not necessary? */
|
||||||
|
mysignal(SIGCHLD, SIG_DFL);
|
||||||
while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
|
while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
|
||||||
session_close_by_pid(pid, status);
|
session_close_by_pid(pid, status);
|
||||||
/*
|
|
||||||
* there is a race between channel_detach_all() killing remaining
|
|
||||||
* children and children dying before kill()
|
|
||||||
*/
|
|
||||||
channel_detach_all();
|
|
||||||
|
|
||||||
while (session_have_children()) {
|
/* close remaining sessions, e.g remove wtmp entries */
|
||||||
pid = waitpid(-1, &status, 0);
|
session_close_all();
|
||||||
if (pid > 0)
|
|
||||||
session_close_by_pid(pid, status);
|
|
||||||
else {
|
|
||||||
error("waitpid returned %d: %s", pid, strerror(errno));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
channel_free_all();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
44
session.c
44
session.c
@ -33,7 +33,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: session.c,v 1.105 2001/10/09 19:32:49 markus Exp $");
|
RCSID("$OpenBSD: session.c,v 1.106 2001/10/09 21:59:41 markus Exp $");
|
||||||
|
|
||||||
#include "ssh.h"
|
#include "ssh.h"
|
||||||
#include "ssh1.h"
|
#include "ssh1.h"
|
||||||
@ -1949,22 +1949,6 @@ session_close_by_pid(pid_t pid, int status)
|
|||||||
session_close(s);
|
session_close(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
session_have_children(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for(i = 0; i < MAX_SESSIONS; i++) {
|
|
||||||
Session *s = &sessions[i];
|
|
||||||
if (s->used && s->pid != -1) {
|
|
||||||
debug("session_have_children: id %d pid %d", i, s->pid);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
debug("session_have_children: no more children");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* this is called when a channel dies before
|
* this is called when a channel dies before
|
||||||
* the session 'child' itself dies
|
* the session 'child' itself dies
|
||||||
@ -1982,15 +1966,29 @@ session_close_by_channel(int id, void *arg)
|
|||||||
s->chanid = -1;
|
s->chanid = -1;
|
||||||
|
|
||||||
debug("session_close_by_channel: channel %d kill %d", id, s->pid);
|
debug("session_close_by_channel: channel %d kill %d", id, s->pid);
|
||||||
if (s->pid == 0) {
|
if (s->pid != 0) {
|
||||||
/* close session immediately */
|
/* notify child */
|
||||||
session_close(s);
|
if (kill(s->pid, SIGHUP) < 0)
|
||||||
} else {
|
|
||||||
/* notify child, delay session cleanup */
|
|
||||||
if (kill(s->pid, (s->ttyfd == -1) ? SIGTERM : SIGHUP) < 0)
|
|
||||||
error("session_close_by_channel: kill %d: %s",
|
error("session_close_by_channel: kill %d: %s",
|
||||||
s->pid, strerror(errno));
|
s->pid, strerror(errno));
|
||||||
}
|
}
|
||||||
|
session_close(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
session_close_all(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < MAX_SESSIONS; i++) {
|
||||||
|
Session *s = &sessions[i];
|
||||||
|
if (s->used) {
|
||||||
|
if (s->chanid != -1) {
|
||||||
|
channel_cancel_cleanup(s->chanid);
|
||||||
|
s->chanid = -1;
|
||||||
|
}
|
||||||
|
session_close(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: session.h,v 1.11 2001/07/02 13:59:15 markus Exp $ */
|
/* $OpenBSD: session.h,v 1.12 2001/10/09 21:59:41 markus Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||||
@ -32,6 +32,6 @@ int session_open(Authctxt*, int);
|
|||||||
void session_input_channel_req(int, void *);
|
void session_input_channel_req(int, void *);
|
||||||
void session_close_by_pid(pid_t, int);
|
void session_close_by_pid(pid_t, int);
|
||||||
void session_close_by_channel(int, void *);
|
void session_close_by_channel(int, void *);
|
||||||
int session_have_children(void);
|
void session_close_all(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user