From 968252bbdcca15fc73060a5bc709c3dbbc96c5ca Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Wed, 19 Sep 2018 20:37:12 +0100 Subject: [PATCH] Move alloc_channel_id into sshcommon.c. That function _did_ depend on ssh.c's internal facilities, namely the layout of 'struct ssh_channel'. In place of that, it now takes an extra integer argument telling it where to find the channel id in whatever data structure you give it a tree of - so now I can split up the SSH-1 and SSH-2 channel handling without losing the services of that nice channel-number allocator. --- ssh.c | 34 +--------------------------------- ssh.h | 8 ++++++++ sshcommon.c | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 33 deletions(-) diff --git a/ssh.c b/ssh.c index 3d91a672..d5f203b0 100644 --- a/ssh.c +++ b/ssh.c @@ -814,38 +814,6 @@ static int ssh_rportcmp_ssh2(void *av, void *bv) return 0; } -static unsigned alloc_channel_id(Ssh ssh) -{ - const unsigned CHANNEL_NUMBER_OFFSET = 256; - search234_state ss; - - /* - * First-fit allocation of channel numbers: we always pick the - * lowest unused one. - * - * Every channel before that, and no channel after it, has an ID - * exactly equal to its tree index plus CHANNEL_NUMBER_OFFSET. So - * we can use the search234 system to identify the length of that - * initial sequence, in a single log-time pass down the channels - * tree. - */ - search234_start(&ss, ssh->channels); - while (ss.element) { - struct ssh_channel *c = (struct ssh_channel *)ss.element; - if (c->localid == ss.index + CHANNEL_NUMBER_OFFSET) - search234_step(&ss, +1); - else - search234_step(&ss, -1); - } - - /* - * Now ss.index gives exactly the number of channels in that - * initial sequence. So adding CHANNEL_NUMBER_OFFSET to it must - * give precisely the lowest unused channel number. - */ - return ss.index + CHANNEL_NUMBER_OFFSET; -} - static void c_write_stderr(int trusted, const void *vbuf, int len) { const char *buf = (const char *)vbuf; @@ -5676,7 +5644,7 @@ static int ssh_is_simple(Ssh ssh) static void ssh_channel_init(struct ssh_channel *c) { Ssh ssh = c->ssh; - c->localid = alloc_channel_id(ssh); + c->localid = alloc_channel_id(ssh->channels, struct ssh_channel); c->closes = 0; c->pending_eof = FALSE; c->throttling_conn = FALSE; diff --git a/ssh.h b/ssh.h index bfeb20df..fc61aa31 100644 --- a/ssh.h +++ b/ssh.h @@ -1326,3 +1326,11 @@ enum { SSH_IMPL_BUG_LIST(TMP_DECLARE_REAL_ENUM) }; void write_ttymodes_to_packet_from_conf( BinarySink *bs, Frontend *frontend, Conf *conf, int ssh_version, int ospeed, int ispeed); + +/* Shared system for allocating local SSH channel ids. Expects to be + * passed a tree full of structs that have a field called 'localid' of + * type unsigned, and will check that! */ +unsigned alloc_channel_id_general(tree234 *channels, size_t localid_offset); +#define alloc_channel_id(tree, type) \ + TYPECHECK(&((type *)0)->localid == (unsigned *)0, \ + alloc_channel_id_general(tree, offsetof(type, localid))) diff --git a/sshcommon.c b/sshcommon.c index 024b64c7..28f28cf9 100644 --- a/sshcommon.c +++ b/sshcommon.c @@ -466,3 +466,40 @@ void write_ttymodes_to_packet_from_conf( put_uint32(bs, ospeed); put_byte(bs, SSH_TTY_OP_END); } + +/* ---------------------------------------------------------------------- + * Routine for allocating a new channel ID, given a means of finding + * the index field in a given channel structure. + */ + +unsigned alloc_channel_id_general(tree234 *channels, size_t localid_offset) +{ + const unsigned CHANNEL_NUMBER_OFFSET = 256; + search234_state ss; + + /* + * First-fit allocation of channel numbers: we always pick the + * lowest unused one. + * + * Every channel before that, and no channel after it, has an ID + * exactly equal to its tree index plus CHANNEL_NUMBER_OFFSET. So + * we can use the search234 system to identify the length of that + * initial sequence, in a single log-time pass down the channels + * tree. + */ + search234_start(&ss, channels); + while (ss.element) { + unsigned localid = *(unsigned *)((char *)ss.element + localid_offset); + if (localid == ss.index + CHANNEL_NUMBER_OFFSET) + search234_step(&ss, +1); + else + search234_step(&ss, -1); + } + + /* + * Now ss.index gives exactly the number of channels in that + * initial sequence. So adding CHANNEL_NUMBER_OFFSET to it must + * give precisely the lowest unused channel number. + */ + return ss.index + CHANNEL_NUMBER_OFFSET; +}