[openssh-commits] [openssh] 07/07: upstream: add a ssh_packet_process_read() function that reads from

git+noreply at mindrot.org git+noreply at mindrot.org
Tue Jan 25 12:19:03 AEDT 2022


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch master
in repository openssh.

commit b30d32159dc3c7052f4bfdf36357996c905af739
Author: djm at openbsd.org <djm at openbsd.org>
Date:   Sat Jan 22 00:49:34 2022 +0000

    upstream: add a ssh_packet_process_read() function that reads from
    
    a fd directly into the transport input buffer.
    
    Use this in the client and server mainloops to avoid unnecessary
    copying. It also lets us use a more greedy read size without penalty.
    
    Yields a 2-3% performance gain on cipher-speed.sh (in a fairly
    unscientific test tbf)
    
    feedback dtucker@ ok markus@
    
    OpenBSD-Commit-ID: df4112125bf79d8e38e79a77113e1b373078e632
---
 channels.h   |  5 ++++-
 clientloop.c | 41 +++++++++++++----------------------------
 packet.c     | 27 ++++++++++++++++++++++++++-
 packet.h     |  3 ++-
 serverloop.c | 27 ++++++++++++---------------
 5 files changed, 57 insertions(+), 46 deletions(-)

diff --git a/channels.h b/channels.h
index 420099ee..82f33ba2 100644
--- a/channels.h
+++ b/channels.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.h,v 1.140 2022/01/06 21:48:38 djm Exp $ */
+/* $OpenBSD: channels.h,v 1.141 2022/01/22 00:49:34 djm Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
@@ -247,6 +247,9 @@ struct Channel {
 /* Read buffer size */
 #define CHAN_RBUF	(16*1024)
 
+/* Maximum size for direct reads to buffers */
+#define CHANNEL_MAX_READ	CHAN_SES_PACKET_DEFAULT
+
 /* Maximum channel input buffer size */
 #define CHAN_INPUT_MAX	(16*1024*1024)
 
diff --git a/clientloop.c b/clientloop.c
index 5145f011..fd190980 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: clientloop.c,v 1.377 2022/01/21 07:04:19 djm Exp $ */
+/* $OpenBSD: clientloop.c,v 1.378 2022/01/22 00:49:34 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -630,40 +630,25 @@ client_suspend_self(struct sshbuf *bin, struct sshbuf *bout, struct sshbuf *berr
 static void
 client_process_net_input(struct ssh *ssh)
 {
-	char buf[SSH_IOBUFSZ];
-	int len;
+	int r;
 
 	/*
 	 * Read input from the server, and add any such data to the buffer of
 	 * the packet subsystem.
 	 */
 	schedule_server_alive_check();
-	/* Read as much as possible. */
-	len = read(connection_in, buf, sizeof(buf));
-	if (len == 0) {
-		/* Received EOF. The remote host has closed the connection. */
-		quit_message("Connection to %.300s closed by remote host.",
-		    host);
-		return;
+	if ((r = ssh_packet_process_read(ssh, connection_in)) == 0)
+		return; /* success */
+	if (r == SSH_ERR_SYSTEM_ERROR) {
+		if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK)
+			return;
+		if (errno == EPIPE) {
+			quit_message("Connection to %s closed by remote host.",
+			    host);
+			return;
+		}
 	}
-	/*
-	 * There is a kernel bug on Solaris that causes poll to
-	 * sometimes wake up even though there is no data available.
-	 */
-	if (len == -1 &&
-	    (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK))
-		len = 0;
-
-	if (len == -1) {
-		/*
-		 * An error has encountered.  Perhaps there is a
-		 * network problem.
-		 */
-		quit_message("Read from remote host %s: %s",
-		    host, strerror(errno));
-		return;
-	}
-	ssh_packet_process_incoming(ssh, buf, len);
+	quit_message("Read from remote host %s: %s", host, ssh_err(r));
 }
 
 static void
diff --git a/packet.c b/packet.c
index 5a50fcd9..bde6c104 100644
--- a/packet.c
+++ b/packet.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.c,v 1.306 2022/01/21 06:58:06 djm Exp $ */
+/* $OpenBSD: packet.c,v 1.307 2022/01/22 00:49:34 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -1784,6 +1784,31 @@ ssh_packet_process_incoming(struct ssh *ssh, const char *buf, u_int len)
 	return 0;
 }
 
+/* Reads and buffers data from the specified fd */
+int
+ssh_packet_process_read(struct ssh *ssh, int fd)
+{
+	struct session_state *state = ssh->state;
+	int r;
+	size_t rlen;
+
+	if ((r = sshbuf_read(fd, state->input, PACKET_MAX_SIZE, &rlen)) != 0)
+		return r;
+
+	if (state->packet_discard) {
+		if ((r = sshbuf_consume_end(state->input, rlen)) != 0)
+			return r;
+		state->keep_alive_timeouts = 0; /* ?? */
+		if (rlen >= state->packet_discard) {
+			if ((r = ssh_packet_stop_discard(ssh)) != 0)
+				return r;
+		}
+		state->packet_discard -= rlen;
+		return 0;
+	}
+	return 0;
+}
+
 int
 ssh_packet_remaining(struct ssh *ssh)
 {
diff --git a/packet.h b/packet.h
index 2ad0e70c..176488b1 100644
--- a/packet.h
+++ b/packet.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.h,v 1.93 2021/07/16 09:00:23 djm Exp $ */
+/* $OpenBSD: packet.h,v 1.94 2022/01/22 00:49:34 djm Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
@@ -128,6 +128,7 @@ int	 ssh_packet_read_expect(struct ssh *, u_int type);
 int      ssh_packet_read_poll(struct ssh *);
 int ssh_packet_read_poll2(struct ssh *, u_char *, u_int32_t *seqnr_p);
 int	 ssh_packet_process_incoming(struct ssh *, const char *buf, u_int len);
+int	 ssh_packet_process_read(struct ssh *, int);
 int      ssh_packet_read_seqnr(struct ssh *, u_char *, u_int32_t *seqnr_p);
 int      ssh_packet_read_poll_seqnr(struct ssh *, u_char *, u_int32_t *seqnr_p);
 
diff --git a/serverloop.c b/serverloop.c
index e31dbed5..15beac2d 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: serverloop.c,v 1.230 2022/01/06 21:55:23 djm Exp $ */
+/* $OpenBSD: serverloop.c,v 1.231 2022/01/22 00:49:34 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -272,27 +272,24 @@ wait_until_can_do_something(struct ssh *ssh,
 static int
 process_input(struct ssh *ssh, int connection_in)
 {
-	int r, len;
-	char buf[16384];
+	int r;
 
-	/* Read and buffer any input data from the client. */
-	len = read(connection_in, buf, sizeof(buf));
-	if (len == 0) {
-		verbose("Connection closed by %.100s port %d",
-		    ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
-		return -1;
-	} else if (len == -1) {
-		if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
+	if ((r = ssh_packet_process_read(ssh, connection_in)) == 0)
+		return 0; /* success */
+	if (r == SSH_ERR_SYSTEM_ERROR) {
+		if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK)
 			return 0;
+		if (errno == EPIPE) {
+			verbose("Connection closed by %.100s port %d",
+			    ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
+			return -1;
+		}
 		verbose("Read error from remote host %s port %d: %s",
 		    ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
 		    strerror(errno));
 		cleanup_exit(255);
 	}
-	/* Buffer any received data. */
-	if ((r = ssh_packet_process_incoming(ssh, buf, len)) != 0)
-		fatal_fr(r, "ssh_packet_process_incoming");
-	return 0;
+	return -1;
 }
 
 /*

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list