-/* $OpenBSD: channels.c,v 1.432 2023/07/04 03:59:21 dlg Exp $ */
+/* $OpenBSD: channels.c,v 1.433 2023/09/04 00:01:46 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
/*
* Enqueue data for channels with open or draining c->input.
+ * Returns non-zero if a packet was enqueued.
*/
-static void
+static int
channel_output_poll_input_open(struct ssh *ssh, Channel *c)
{
size_t len, plen;
else
chan_ibuf_empty(ssh, c);
}
- return;
+ return 0;
}
if (!c->have_remote_id)
*/
if (plen > c->remote_window || plen > c->remote_maxpacket) {
debug("channel %d: datagram too big", c->self);
- return;
+ return 0;
}
/* Enqueue it */
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_DATA)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
fatal_fr(r, "channel %i: send datagram", c->self);
c->remote_window -= plen;
- return;
+ return 1;
}
/* Enqueue packet for buffered data. */
if (len > c->remote_maxpacket)
len = c->remote_maxpacket;
if (len == 0)
- return;
+ return 0;
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_DATA)) != 0 ||
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_put_string(ssh, sshbuf_ptr(c->input), len)) != 0 ||
if ((r = sshbuf_consume(c->input, len)) != 0)
fatal_fr(r, "channel %i: consume", c->self);
c->remote_window -= len;
+ return 1;
}
/*
* Enqueue data for channels with open c->extended in read mode.
+ * Returns non-zero if a packet was enqueued.
*/
-static void
+static int
channel_output_poll_extended_read(struct ssh *ssh, Channel *c)
{
size_t len;
int r;
if ((len = sshbuf_len(c->extended)) == 0)
- return;
+ return 0;
debug2("channel %d: rwin %u elen %zu euse %d", c->self,
c->remote_window, sshbuf_len(c->extended), c->extended_usage);
if (len > c->remote_maxpacket)
len = c->remote_maxpacket;
if (len == 0)
- return;
+ return 0;
if (!c->have_remote_id)
fatal_f("channel %d: no remote id", c->self);
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_EXTENDED_DATA)) != 0 ||
fatal_fr(r, "channel %i: consume", c->self);
c->remote_window -= len;
debug2("channel %d: sent ext data %zu", c->self, len);
+ return 1;
}
-/* If there is data to send to the connection, enqueue some of it now. */
-void
+/*
+ * If there is data to send to the connection, enqueue some of it now.
+ * Returns non-zero if data was enqueued.
+ */
+int
channel_output_poll(struct ssh *ssh)
{
struct ssh_channels *sc = ssh->chanctxt;
Channel *c;
u_int i;
+ int ret = 0;
for (i = 0; i < sc->channels_alloc; i++) {
c = sc->channels[i];
/* Get the amount of buffered data for this channel. */
if (c->istate == CHAN_INPUT_OPEN ||
c->istate == CHAN_INPUT_WAIT_DRAIN)
- channel_output_poll_input_open(ssh, c);
+ ret |= channel_output_poll_input_open(ssh, c);
/* Send extended data, i.e. stderr */
if (!(c->flags & CHAN_EOF_SENT) &&
c->extended_usage == CHAN_EXTENDED_READ)
- channel_output_poll_extended_read(ssh, c);
+ ret |= channel_output_poll_extended_read(ssh, c);
}
+ return ret;
}
/* -- mux proxy support */
-/* $OpenBSD: channels.h,v 1.151 2023/07/04 03:59:21 dlg Exp $ */
+/* $OpenBSD: channels.h,v 1.152 2023/09/04 00:01:46 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
void channel_prepare_poll(struct ssh *, struct pollfd **,
u_int *, u_int *, u_int, struct timespec *);
void channel_after_poll(struct ssh *, struct pollfd *, u_int);
-void channel_output_poll(struct ssh *);
+int channel_output_poll(struct ssh *);
int channel_not_very_much_buffered_data(struct ssh *);
void channel_close_all(struct ssh *);