mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-02 19:44:46 +02:00
upstream: Use sshbuf_read() to read directly into the channel input
buffer rather than into a stack buffer that needs to be copied again; Improves performance by about 1% on cipher-speed.sh feedback dtucker@ ok markus@ OpenBSD-Commit-ID: bf5e6e3c821ac3546dc8241d8a94e70d47716572
This commit is contained in:
parent
29a76994e2
commit
a1a8efeaaa
50
channels.c
50
channels.c
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: channels.c,v 1.411 2022/01/06 21:48:38 djm Exp $ */
|
/* $OpenBSD: channels.c,v 1.412 2022/01/22 00:45:31 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
@ -1919,25 +1919,56 @@ channel_handle_rfd(struct ssh *ssh, Channel *c)
|
|||||||
char buf[CHAN_RBUF];
|
char buf[CHAN_RBUF];
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
int r, force;
|
int r, force;
|
||||||
|
size_t have, avail, maxlen = CHANNEL_MAX_READ;
|
||||||
|
int pty_zeroread = 0;
|
||||||
|
|
||||||
|
#ifdef PTY_ZEROREAD
|
||||||
|
/* Bug on AIX: read(1) can return 0 for a non-closed fd */
|
||||||
|
pty_zeroread = c->isatty;
|
||||||
|
#endif
|
||||||
|
|
||||||
force = c->isatty && c->detach_close && c->istate != CHAN_INPUT_CLOSED;
|
force = c->isatty && c->detach_close && c->istate != CHAN_INPUT_CLOSED;
|
||||||
|
|
||||||
if (!force && (c->io_ready & SSH_CHAN_IO_RFD) == 0)
|
if (!force && (c->io_ready & SSH_CHAN_IO_RFD) == 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
if ((avail = sshbuf_avail(c->input)) == 0)
|
||||||
|
return 1; /* Shouldn't happen */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For "simple" channels (i.e. not datagram or filtered), we can
|
||||||
|
* read directly to the channel buffer.
|
||||||
|
*/
|
||||||
|
if (!pty_zeroread && c->input_filter == NULL && !c->datagram) {
|
||||||
|
/* Only OPEN channels have valid rwin */
|
||||||
|
if (c->type == SSH_CHANNEL_OPEN) {
|
||||||
|
if ((have = sshbuf_len(c->input)) >= c->remote_window)
|
||||||
|
return 1; /* shouldn't happen */
|
||||||
|
if (maxlen > c->remote_window - have)
|
||||||
|
maxlen = c->remote_window - have;
|
||||||
|
}
|
||||||
|
if (maxlen > avail)
|
||||||
|
maxlen = avail;
|
||||||
|
if ((r = sshbuf_read(c->rfd, c->input, maxlen, NULL)) != 0) {
|
||||||
|
debug2("channel %d: read failed rfd %d maxlen %zu: %s",
|
||||||
|
c->self, c->rfd, maxlen, ssh_err(r));
|
||||||
|
goto rfail;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
len = read(c->rfd, buf, sizeof(buf));
|
len = read(c->rfd, buf, sizeof(buf));
|
||||||
|
/* fixup AIX zero-length read with errno set to look more like errors */
|
||||||
|
if (pty_zeroread && len == 0 && errno != 0)
|
||||||
|
len = -1;
|
||||||
if (len == -1 && (errno == EINTR ||
|
if (len == -1 && (errno == EINTR ||
|
||||||
((errno == EAGAIN || errno == EWOULDBLOCK) && !force)))
|
((errno == EAGAIN || errno == EWOULDBLOCK) && !force)))
|
||||||
return 1;
|
return 1;
|
||||||
#ifndef PTY_ZEROREAD
|
if (len < 0 || (!pty_zeroread && len == 0)) {
|
||||||
if (len <= 0) {
|
debug2("channel %d: read<=0 rfd %d len %zd: %s",
|
||||||
#else
|
c->self, c->rfd, len,
|
||||||
if ((!c->isatty && len <= 0) ||
|
len == 0 ? "closed" : strerror(errno));
|
||||||
(c->isatty && (len < 0 || (len == 0 && errno != 0)))) {
|
rfail:
|
||||||
#endif
|
|
||||||
debug2("channel %d: read<=0 rfd %d len %zd",
|
|
||||||
c->self, c->rfd, len);
|
|
||||||
if (c->type != SSH_CHANNEL_OPEN) {
|
if (c->type != SSH_CHANNEL_OPEN) {
|
||||||
debug2("channel %d: not open", c->self);
|
debug2("channel %d: not open", c->self);
|
||||||
chan_mark_dead(ssh, c);
|
chan_mark_dead(ssh, c);
|
||||||
@ -1957,6 +1988,7 @@ channel_handle_rfd(struct ssh *ssh, Channel *c)
|
|||||||
fatal_fr(r, "channel %i: put datagram", c->self);
|
fatal_fr(r, "channel %i: put datagram", c->self);
|
||||||
} else if ((r = sshbuf_put(c->input, buf, len)) != 0)
|
} else if ((r = sshbuf_put(c->input, buf, len)) != 0)
|
||||||
fatal_fr(r, "channel %i: put data", c->self);
|
fatal_fr(r, "channel %i: put data", c->self);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user