Print this page
OS-2204 SunSSH has a maximum of 10 multiplexed sessions
@@ -33,10 +33,13 @@
*/
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
#include "includes.h"
RCSID("$OpenBSD: session.c,v 1.150 2002/09/16 19:55:33 stevesk Exp $");
#ifdef HAVE_DEFOPEN
@@ -52,10 +55,11 @@
#include "ssh.h"
#include "ssh1.h"
#include "ssh2.h"
#include "xmalloc.h"
+#include "sys-queue.h"
#include "sshpty.h"
#include "packet.h"
#include "buffer.h"
#include "mpaux.h"
#include "uidswap.h"
@@ -137,11 +141,13 @@
/* original command from peer. */
const char *original_command = NULL;
/* data */
#define MAX_SESSIONS 10
-Session sessions[MAX_SESSIONS];
+static int sessions_next_id = 0;
+static LIST_HEAD(sessions_head, Session) sessions =
+ LIST_HEAD_INITIALIZER(sessions);
#define SUBSYSTEM_NONE 0
#define SUBSYSTEM_EXT 1
#define SUBSYSTEM_INT_SFTP 2
@@ -1525,44 +1531,34 @@
}
Session *
session_new(void)
{
- int i;
- static int did_init = 0;
- if (!did_init) {
+ Session *s;
+
debug("session_new: init");
- for (i = 0; i < MAX_SESSIONS; i++) {
- sessions[i].used = 0;
- }
- did_init = 1;
- }
- for (i = 0; i < MAX_SESSIONS; i++) {
- Session *s = &sessions[i];
- if (! s->used) {
+
+ s = xmalloc(sizeof (*s));
memset(s, 0, sizeof(*s));
s->chanid = -1;
s->ptyfd = -1;
s->ttyfd = -1;
- s->used = 1;
- s->self = i;
+ s->self = sessions_next_id++;
s->env = NULL;
- debug("session_new: session %d", i);
- return s;
- }
- }
- return NULL;
+ LIST_INSERT_HEAD(&sessions, s, list_entry);
+
+ debug("session_new: session %d", s->self);
+
+ return (s);
}
static void
session_dump(void)
{
- int i;
- for (i = 0; i < MAX_SESSIONS; i++) {
- Session *s = &sessions[i];
- debug("dump: used %d session %d %p channel %d pid %ld",
- s->used,
+ Session *s;
+ LIST_FOREACH(s, &sessions, list_entry) {
+ debug("dump: session %d %p channel %d pid %ld",
s->self,
s,
s->chanid,
(long)s->pid);
}
@@ -1588,15 +1584,14 @@
#ifndef lint
Session *
session_by_tty(char *tty)
{
- int i;
- for (i = 0; i < MAX_SESSIONS; i++) {
- Session *s = &sessions[i];
- if (s->used && s->ttyfd != -1 && strcmp(s->tty, tty) == 0) {
- debug("session_by_tty: session %d tty %s", i, tty);
+ Session *s;
+ LIST_FOREACH(s, &sessions, list_entry) {
+ if (s->ttyfd != -1 && strcmp(s->tty, tty) == 0) {
+ debug("session_by_tty: session %d tty %s", s->self, tty);
return s;
}
}
debug("session_by_tty: unknown tty %.100s", tty);
session_dump();
@@ -1605,15 +1600,14 @@
#endif /* lint */
static Session *
session_by_channel(int id)
{
- int i;
- for (i = 0; i < MAX_SESSIONS; i++) {
- Session *s = &sessions[i];
- if (s->used && s->chanid == id) {
- debug("session_by_channel: session %d channel %d", i, id);
+ Session *s;
+ LIST_FOREACH(s, &sessions, list_entry) {
+ if (s->chanid == id) {
+ debug("session_by_channel: session %d channel %d", s->self, id);
return s;
}
}
debug("session_by_channel: unknown channel %d", id);
session_dump();
@@ -1621,15 +1615,14 @@
}
static Session *
session_by_pid(pid_t pid)
{
- int i;
+ Session *s;
debug("session_by_pid: pid %ld", (long)pid);
- for (i = 0; i < MAX_SESSIONS; i++) {
- Session *s = &sessions[i];
- if (s->used && s->pid == pid)
+ LIST_FOREACH(s, &sessions, list_entry) {
+ if (s->pid == pid)
return s;
}
error("session_by_pid: unknown pid %ld", (long)pid);
session_dump();
return NULL;
@@ -2285,12 +2278,14 @@
if (s->auth_proto)
xfree(s->auth_proto);
if (s->command)
xfree(s->command);
session_free_env(&s->env);
- s->used = 0;
+
+ LIST_REMOVE(s, list_entry);
session_proctitle(s);
+ xfree(s);
}
void
session_close_by_pid(pid_t pid, int status)
{
@@ -2339,31 +2334,27 @@
}
void
session_destroy_all(void (*closefunc)(Session *))
{
- int i;
- for (i = 0; i < MAX_SESSIONS; i++) {
- Session *s = &sessions[i];
- if (s->used) {
+ Session *s;
+ LIST_FOREACH(s, &sessions, list_entry) {
if (closefunc != NULL)
closefunc(s);
else
session_close(s);
}
- }
}
static char *
session_tty_list(void)
{
+ Session *s;
static char buf[1024];
- int i;
buf[0] = '\0';
- for (i = 0; i < MAX_SESSIONS; i++) {
- Session *s = &sessions[i];
- if (s->used && s->ttyfd != -1) {
+ LIST_FOREACH(s, &sessions, list_entry) {
+ if (s->ttyfd != -1) {
if (buf[0] != '\0')
strlcat(buf, ",", sizeof buf);
strlcat(buf, strrchr(s->tty, '/') + 1, sizeof buf);
}
}