Index | Thread | Search

From:
Damien Miller <djm@mindrot.org>
Subject:
ssh: factor out TCP_KEEPALIVE handling
To:
tech@openbsd.org
Cc:
openssh@openssh.com
Date:
Thu, 13 Aug 2026 10:39:23 +1000

Download raw body.

Thread
  • Damien Miller:

    ssh: factor out TCP_KEEPALIVE handling

self-explanatory; ok?

diff --git a/misc.c b/misc.c
index 4ce2e4e..34df55c 100644
--- a/misc.c
+++ b/misc.c
@@ -233,6 +233,19 @@ set_reuseaddr(int fd)
 	return 0;
 }
 
+/* Set TCP keepalives */
+int
+set_keepalive(int fd)
+{
+	int on = 1;
+
+	if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) == -1) {
+		error("setsockopt SO_KEEPALIVE fd %d: %s", fd, strerror(errno));
+		return -1;
+	}
+	return 0;
+}
+
 /* Get/set routing domain */
 char *
 get_rdomain(int fd)
diff --git a/misc.h b/misc.h
index 6ec6c3a..8426cae 100644
--- a/misc.h
+++ b/misc.h
@@ -65,6 +65,7 @@ int	 set_nonblock(int);
 int	 unset_nonblock(int);
 void	 set_nodelay(int);
 int	 set_reuseaddr(int);
+int	 set_keepalive(int);
 char	*get_rdomain(int);
 int	 set_rdomain(int, const char *);
 int	 get_sock_af(int);
diff --git a/sshconnect.c b/sshconnect.c
index 12b999c..c7af99f 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -465,7 +465,7 @@ ssh_connect_direct(struct ssh *ssh, const char *host, struct addrinfo *aitop,
     struct sockaddr_storage *hostaddr, u_short port, int connection_attempts,
     int *timeout_ms, int want_keepalive)
 {
-	int on = 1, saved_timeout_ms = *timeout_ms;
+	int saved_timeout_ms = *timeout_ms;
 	int oerrno, sock = -1, attempt;
 	char ntop[NI_MAXHOST], strport[NI_MAXSERV];
 	struct addrinfo *ai;
@@ -546,10 +546,8 @@ ssh_connect_direct(struct ssh *ssh, const char *host, struct addrinfo *aitop,
 	debug("Connection established.");
 
 	/* Set SO_KEEPALIVE if requested. */
-	if (want_keepalive &&
-	    setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on,
-	    sizeof(on)) == -1)
-		error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
+	if (want_keepalive)
+		set_keepalive(sock); /* logs errors */
 
 	/* Set the connection. */
 	if (ssh_packet_set_connection(ssh, sock, sock) == NULL)
diff --git a/sshd-session.c b/sshd-session.c
index ca5229e..db49983 100644
--- a/sshd-session.c
+++ b/sshd-session.c
@@ -735,7 +735,7 @@ main(int ac, char **av)
 	struct ssh *ssh = NULL;
 	extern char *optarg;
 	extern int optind;
-	int devnull, r, opt, on = 1, remote_port;
+	int devnull, r, opt, remote_port;
 	int sock_in = -1, sock_out = -1, rexeced_flag = 0, have_key = 0;
 	const char *remote_ip, *rdomain;
 	char *line, *laddr, *logfile = NULL;
@@ -1085,9 +1085,8 @@ main(int ac, char **av)
 	server_process_permitopen(ssh);
 
 	/* Set SO_KEEPALIVE if requested. */
-	if (options.tcp_keep_alive && ssh_packet_connection_is_on_socket(ssh) &&
-	    setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) == -1)
-		error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
+	if (options.tcp_keep_alive && ssh_packet_connection_is_on_socket(ssh))
+		set_keepalive(sock_in); /* logs errors */
 
 	if ((remote_port = ssh_remote_port(ssh)) < 0) {
 		debug("ssh_remote_port failed");