[PATCH] SO_KEEPALIVE for port forwards

Manoj Kasichainula manoj at collab.net
Tue Aug 28 10:46:21 EST 2001


[Please keep cc:ing me on replies]
On Fri, Aug 24, 2001 at 09:50:11AM +0200, Markus Friedl wrote:
> On Thu, Aug 23, 2001 at 05:48:08PM -0700, Manoj Kasichainula wrote:
> > --- openssh-2.9p2/channels.c.keepalivetunnel	Wed Jun 13 12:18:05 2001
> > +++ openssh-2.9p2/channels.c	Thu Aug 23 15:40:43 2001
> > @@ -61,6 +61,9 @@
> >  #include "canohost.h"
> >  #include "key.h"
> >  #include "authfd.h"
> > +#include "readconf.h"
> > +
> > +extern Options options;
> 
> not allowed in channels.c

Now that I understand the code somewhat better, I see why. Here's a
rewritten version.

It sets SO_KEEPALIVE on the listening socket instead of each of the
accepted sockets. It passes around a keepalive parameter to a few
different functions to avoid putting client or server options in
channels.c. And, since the basis was there, I added support for
keepalives in -R style port forwards too.

This patch is now against the cvs repo instead of the 2.9p2 tarball.

How is this?

-------------- next part --------------
Index: channels.c
===================================================================
RCS file: /cvs/openssh_cvs/channels.c,v
retrieving revision 1.103
diff -u -d -r1.103 channels.c
--- channels.c	2001/07/18 16:01:47	1.103
+++ channels.c	2001/08/28 00:41:19
@@ -2029,12 +2029,12 @@
  */
 int
 channel_request_local_forwarding(u_short listen_port, const char *host_to_connect,
-    u_short port_to_connect, int gateway_ports)
+    u_short port_to_connect, int gateway_ports, int keepalive)
 {
 	return channel_request_forwarding(
 	    NULL, listen_port,
 	    host_to_connect, port_to_connect,
-	    gateway_ports, /*remote_fwd*/ 0);
+	    gateway_ports, /*remote_fwd*/ 0, keepalive);
 }
 
 /*
@@ -2045,7 +2045,7 @@
 channel_request_forwarding(
     const char *listen_address, u_short listen_port,
     const char *host_to_connect, u_short port_to_connect,
-    int gateway_ports, int remote_fwd)
+    int gateway_ports, int remote_fwd, int keepalive)
 {
 	Channel *c;
 	int success, sock, on = 1, type;
@@ -2105,6 +2105,10 @@
 		linger.l_onoff = 1;
 		linger.l_linger = 5;
 		setsockopt(sock, SOL_SOCKET, SO_LINGER, (void *)&linger, sizeof(linger));
+		if (keepalive) {
+		    setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on));
+		}
+
 		debug("Local forwarding listening on %s port %s.", ntop, strport);
 
 		/* Bind the socket to the address. */
@@ -2210,7 +2214,7 @@
  */
 
 void
-channel_input_port_forward_request(int is_root, int gateway_ports)
+channel_input_port_forward_request(int is_root, int gateway_ports, int keepalive)
 {
 	u_short port, host_port;
 	char *hostname;
@@ -2230,7 +2234,8 @@
 				  port);
 #endif
 	/* Initiate forwarding */
-	channel_request_local_forwarding(port, hostname, host_port, gateway_ports);
+	channel_request_local_forwarding(port, hostname, host_port, gateway_ports,
+	    keepalive);
 
 	/* Free the argument string. */
 	xfree(hostname);
Index: channels.h
===================================================================
RCS file: /cvs/openssh_cvs/channels.h,v
retrieving revision 1.37
diff -u -d -r1.37 channels.h
--- channels.h	2001/07/18 16:01:47	1.37
+++ channels.h	2001/08/28 00:41:19
@@ -185,14 +185,15 @@
 void     channel_permit_all_opens(void);
 void	 channel_add_permitted_opens(char *, int);
 void	 channel_clear_permitted_opens(void);
-void     channel_input_port_forward_request(int, int);
+void     channel_input_port_forward_request(int, int, int);
 int	 channel_connect_to(const char *, u_short);
 int	 channel_connect_by_listen_address(u_short);
 void	 channel_request_remote_forwarding(u_short, const char *, u_short);
-int	 channel_request_local_forwarding(u_short, const char *, u_short, int);
+int	 channel_request_local_forwarding(u_short, const char *, u_short, int,
+    int);
 int
 channel_request_forwarding(const char *, u_short, const char *, u_short, int,
-    int);
+    int, int);
 
 /* x11 forwarding */
 
Index: readconf.c
===================================================================
RCS file: /cvs/openssh_cvs/readconf.c,v
retrieving revision 1.61
diff -u -d -r1.61 readconf.c
--- readconf.c	2001/08/15 22:59:00	1.61
+++ readconf.c	2001/08/28 00:41:19
@@ -109,7 +109,7 @@
 	oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
 	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
 	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
-	oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts,
+	oCompressionLevel, oKeepAlives, oKeepAlivesForward, oNumberOfPasswordPrompts,
 	oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
 	oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
 	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
@@ -177,6 +177,7 @@
 	{ "compression", oCompression },
 	{ "compressionlevel", oCompressionLevel },
 	{ "keepalive", oKeepAlives },
+	{ "keepaliveforward", oKeepAlivesForward },
 	{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
 	{ "loglevel", oLogLevel },
 	{ "dynamicforward", oDynamicForward },
@@ -399,6 +400,10 @@
 		intptr = &options->keepalives;
 		goto parse_flag;
 
+	case oKeepAlivesForward:
+		intptr = &options->keepalives_forward;
+		goto parse_flag;
+
 	case oNumberOfPasswordPrompts:
 		intptr = &options->number_of_password_prompts;
 		goto parse_int;
@@ -753,6 +758,7 @@
 	options->strict_host_key_checking = -1;
 	options->compression = -1;
 	options->keepalives = -1;
+	options->keepalives_forward = -1;
 	options->compression_level = -1;
 	options->port = -1;
 	options->connection_attempts = -1;
@@ -844,6 +850,8 @@
 		options->compression = 0;
 	if (options->keepalives == -1)
 		options->keepalives = 1;
+	if (options->keepalives_forward == -1)
+		options->keepalives_forward = 0;
 	if (options->compression_level == -1)
 		options->compression_level = 6;
 	if (options->port == -1)
Index: readconf.h
===================================================================
RCS file: /cvs/openssh_cvs/readconf.h,v
retrieving revision 1.30
diff -u -d -r1.30 readconf.h
--- readconf.h	2001/08/06 21:35:52	1.30
+++ readconf.h	2001/08/28 00:41:19
@@ -63,6 +63,7 @@
 	int     compression_level;	/* Compression level 1 (fast) to 9
 					 * (best). */
 	int     keepalives;	/* Set SO_KEEPALIVE. */
+	int     keepalives_forward;	/* Set SO_KEEPALIVE for port forwards. */
 	LogLevel log_level;	/* Level for logging. */
 
 	int     port;		/* Port to connect. */
Index: servconf.c
===================================================================
RCS file: /cvs/openssh_cvs/servconf.c,v
retrieving revision 1.63
diff -u -d -r1.63 servconf.c
--- servconf.c	2001/07/14 02:20:32	1.63
+++ servconf.c	2001/08/28 00:41:20
@@ -62,6 +62,7 @@
 	options->xauth_location = NULL;
 	options->strict_modes = -1;
 	options->keepalives = -1;
+	options->keepalives_forward = -1;
 	options->log_facility = (SyslogFacility) - 1;
 	options->log_level = (LogLevel) - 1;
 	options->rhosts_authentication = -1;
@@ -156,6 +157,8 @@
 		options->strict_modes = 1;
 	if (options->keepalives == -1)
 		options->keepalives = 1;
+	if (options->keepalives_forward == -1)
+		options->keepalives_forward = 0;
 	if (options->log_facility == (SyslogFacility) (-1))
 		options->log_facility = SYSLOG_FACILITY_AUTH;
 	if (options->log_level == (LogLevel) (-1))
@@ -241,7 +244,7 @@
 	sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
 	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
 	sX11Forwarding, sX11DisplayOffset,
-	sStrictModes, sEmptyPasswd, sKeepAlives, sCheckMail,
+	sStrictModes, sEmptyPasswd, sKeepAlives, sKeepAlivesForward, sCheckMail,
 	sUseLogin, sAllowTcpForwarding,
 	sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
 	sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
@@ -302,6 +305,7 @@
 	{ "permitemptypasswords", sEmptyPasswd },
 	{ "uselogin", sUseLogin },
 	{ "keepalive", sKeepAlives },
+	{ "keepaliveforward", sKeepAlivesForward },
 	{ "allowtcpforwarding", sAllowTcpForwarding },
 	{ "allowusers", sAllowUsers },
 	{ "denyusers", sDenyUsers },
@@ -659,6 +663,10 @@
 
 		case sKeepAlives:
 			intptr = &options->keepalives;
+			goto parse_flag;
+
+		case sKeepAlivesForward:
+			intptr = &options->keepalives_forward;
 			goto parse_flag;
 
 		case sEmptyPasswd:
Index: servconf.h
===================================================================
RCS file: /cvs/openssh_cvs/servconf.h,v
retrieving revision 1.38
diff -u -d -r1.38 servconf.h
--- servconf.h	2001/07/04 18:37:21	1.38
+++ servconf.h	2001/08/28 00:41:20
@@ -59,6 +59,7 @@
 	char   *xauth_location;	/* Location of xauth program */
 	int     strict_modes;	/* If true, require string home dir modes. */
 	int     keepalives;	/* If true, set SO_KEEPALIVE. */
+	int     keepalives_forward;	/* If true, set SO_KEEPALIVE for -R port forwards. */
 	char   *ciphers;	/* Supported SSH2 ciphers. */
 	char   *macs;		/* Supported SSH2 macs. */
 	int	protocol;	/* Supported protocol versions. */
Index: serverloop.c
===================================================================
RCS file: /cvs/openssh_cvs/serverloop.c,v
retrieving revision 1.75
diff -u -d -r1.75 serverloop.c
--- serverloop.c	2001/07/26 17:51:50	1.75
+++ serverloop.c	2001/08/28 00:41:21
@@ -941,7 +941,8 @@
 			    listen_address, listen_port,
 			    /*unspec host_to_connect*/ "<unspec host>",
 			    /*unspec port_to_connect*/ 0,
-			    options.gateway_ports, /*remote*/ 1);
+			    options.gateway_ports, /*remote*/ 1,
+			    options.keepalives_forward);
 		}
 		xfree(listen_address);
 	}
Index: session.c
===================================================================
RCS file: /cvs/openssh_cvs/session.c,v
retrieving revision 1.143
diff -u -d -r1.143 session.c
--- session.c	2001/07/14 02:19:36	1.143
+++ session.c	2001/08/28 00:41:22
@@ -303,7 +303,7 @@
 				break;
 			}
 			debug("Received TCP/IP port forwarding request.");
-			channel_input_port_forward_request(s->pw->pw_uid == 0, options.gateway_ports);
+			channel_input_port_forward_request(s->pw->pw_uid == 0, options.gateway_ports, options.keepalives_forward);
 			success = 1;
 			break;
 
Index: ssh.1
===================================================================
RCS file: /cvs/openssh_cvs/ssh.1,v
retrieving revision 1.86
diff -u -d -r1.86 ssh.1
--- ssh.1	2001/08/15 23:25:46	1.86
+++ ssh.1	2001/08/28 00:41:22
@@ -871,6 +871,12 @@
 To disable keepalives, the value should be set to
 .Dq no
 in both the server and the client configuration files.
+.It Cm KeepAliveForward
+Similar to KeepAlive, but applies to -L port forwards
+.Pp
+The default is
+.Dq no
+(to not send keepalives)
 .It Cm KerberosAuthentication
 Specifies whether Kerberos authentication will be used.
 The argument to this keyword must be
Index: ssh.c
===================================================================
RCS file: /cvs/openssh_cvs/ssh.c,v
retrieving revision 1.112
diff -u -d -r1.112 ssh.c
--- ssh.c	2001/08/15 23:19:22	1.112
+++ ssh.c	2001/08/28 00:41:25
@@ -830,7 +830,7 @@
 		    options.local_forwards[i].port,
 		    options.local_forwards[i].host,
 		    options.local_forwards[i].host_port,
-		    options.gateway_ports);
+		    options.gateway_ports, options.keepalives_forward);
 	}
 	if (i > 0 && success == 0)
 		error("Could not request local forwarding.");
Index: sshd.8
===================================================================
RCS file: /cvs/openssh_cvs/sshd.8,v
retrieving revision 1.96
diff -u -d -r1.96 sshd.8
--- sshd.8	2001/08/06 21:38:11	1.96
+++ sshd.8	2001/08/28 00:41:25
@@ -514,6 +514,12 @@
 To disable keepalives, the value should be set to
 .Dq no
 in both the server and the client configuration files.
+.It Cm KeepAliveForward
+Similar to KeepAlive, but applies to -R port forwards
+.Pp
+The default is
+.Dq no
+(to not send keepalives)
 .It Cm KerberosAuthentication
 Specifies whether Kerberos authentication is allowed.
 This can be in the form of a Kerberos ticket, or if


More information about the openssh-unix-dev mailing list