connection timeout

vectro at pipeline.com vectro at pipeline.com
Tue Jun 6 12:50:57 EST 2000


Attached is a patch which adds a ConnectionTimeout option, and corrects
the ConnectionAttempts documentation.

Previously, ssh would try to make a connection ConnectionAttempts times,
sleeping 1 second between tries. But each connection attempt could take a
very long time to fail if the packets die before the get to the host. So
if ssh is being run in a script or what-have-you, it might be desirable to
wait a shorter period of time.

So this limits the time per connection attempt to the lesser of
ConnectionTimeout, and the kernel timeout for a socket in SYN_SENT state.

The patch is against the portable ssh, because I run linux, but it applies
to the current version of ssh as well, albiet with some fuzz and offsets.
I have also not patched ssh.0 because it appears to be a generated file,
and my troff must work differently from whoever generated it.

I'm thinking I might add a command line option to parse another config
file after the defaults, mabye even instead of the user's home directory.
Any thoughts?

Ian Turner
-------------- next part --------------
diff -Naur openssh-2.1.0p3/readconf.c openssh-2.1.0p3-new/readconf.c
--- openssh-2.1.0p3/readconf.c	Mon May 29 20:44:53 2000
+++ openssh-2.1.0p3-new/readconf.c	Mon Jun  5 19:06:58 2000
@@ -102,9 +102,10 @@
 	oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
 	oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
 	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
-	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
-	oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication,
-	oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oIdentityFile2,
+	oConnectionTimeout, oBatchMode, oCheckHostIP, oStrictHostKeyChecking,
+	oCompression, oCompressionLevel, oKeepAlives,
+	oNumberOfPasswordPrompts, oTISAuthentication, oUsePrivilegedPort,
+	oLogLevel, oCiphers, oProtocol, oIdentityFile2,
 	oGlobalKnownHostsFile2, oUserKnownHostsFile2, oDSAAuthentication
 } OpCodes;
 
@@ -151,6 +152,7 @@
 	{ "globalknownhostsfile2", oGlobalKnownHostsFile2 },
 	{ "userknownhostsfile2", oUserKnownHostsFile2 },
 	{ "connectionattempts", oConnectionAttempts },
+	{ "connectiontimeout", oConnectionTimeout },
 	{ "batchmode", oBatchMode },
 	{ "checkhostip", oCheckHostIP },
 	{ "stricthostkeychecking", oStrictHostKeyChecking },
@@ -460,6 +462,10 @@
 	case oConnectionAttempts:
 		intptr = &options->connection_attempts;
 		goto parse_int;
+		
+	case oConnectionTimeout:
+	        intptr = &options->connection_timeout;
+		goto parse_int;
 
 	case oCipher:
 		intptr = &options->cipher;
@@ -669,6 +675,7 @@
 	options->compression_level = -1;
 	options->port = -1;
 	options->connection_attempts = -1;
+	options->connection_timeout = -1;
 	options->number_of_password_prompts = -1;
 	options->cipher = -1;
 	options->ciphers = NULL;
@@ -746,6 +753,8 @@
 		options->port = 0;	/* Filled in ssh_connect. */
 	if (options->connection_attempts == -1)
 		options->connection_attempts = 4;
+	if (options->connection_timeout == -1)
+	        options->connection_timeout = 120;
 	if (options->number_of_password_prompts == -1)
 		options->number_of_password_prompts = 3;
 	/* Selected in ssh_login(). */
diff -Naur openssh-2.1.0p3/readconf.h openssh-2.1.0p3-new/readconf.h
--- openssh-2.1.0p3/readconf.h	Mon May  8 18:03:01 2000
+++ openssh-2.1.0p3-new/readconf.h	Mon Jun  5 19:39:31 2000
@@ -60,8 +60,9 @@
 	LogLevel log_level;	/* Level for logging. */
 
 	int     port;		/* Port to connect. */
-	int     connection_attempts;	/* Max attempts (seconds) before
+	int     connection_attempts;	/* Max attempts before
 					 * giving up */
+	int     connection_timeout;     /* Max time to wait per attempt */
 	int     number_of_password_prompts;	/* Max number of password
 						 * prompts. */
 	int     cipher;		/* Cipher to use. */
diff -Naur openssh-2.1.0p3/ssh.1 openssh-2.1.0p3-new/ssh.1
--- openssh-2.1.0p3/ssh.1	Mon May 29 20:44:54 2000
+++ openssh-2.1.0p3-new/ssh.1	Mon Jun  5 19:12:24 2000
@@ -628,10 +628,13 @@
 The meaning of the values is the same as in
 .Xr gzip 1 .
 .It Cm ConnectionAttempts
-Specifies the number of tries (one per second) to make before falling
+Specifies the maximum number of tries to make before falling
 back to rsh or exiting.
 The argument must be an integer.
 This may be useful in scripts if the connection sometimes fails.
+.It Cm ConnectionTimeout
+Specifies the maximum amount of time, in seconds, to wait, for every
+connection attempt. The argument must be an integer.
 .It Cm DSAAuthentication
 Specifies whether to try DSA authentication.
 The argument to this keyword must be
diff -Naur openssh-2.1.0p3/ssh.c openssh-2.1.0p3-new/ssh.c
--- openssh-2.1.0p3/ssh.c	Mon May 29 20:44:54 2000
+++ openssh-2.1.0p3-new/ssh.c	Mon Jun  5 19:12:59 2000
@@ -578,6 +578,7 @@
 
 	ok = ssh_connect(host, &hostaddr, options.port,
 			 options.connection_attempts,
+			 options.connection_timeout,
 			 !options.rhosts_authentication &&
 			 !options.rhosts_rsa_authentication,
 			 original_real_uid,
diff -Naur openssh-2.1.0p3/ssh.h openssh-2.1.0p3-new/ssh.h
--- openssh-2.1.0p3/ssh.h	Wed May 17 05:34:24 2000
+++ openssh-2.1.0p3-new/ssh.h	Mon Jun  5 19:13:55 2000
@@ -323,13 +323,14 @@
  * is 0, the default port will be used.  If anonymous is zero, a privileged
  * port will be allocated to make the connection. This requires super-user
  * privileges if anonymous is false. Connection_attempts specifies the
- * maximum number of tries, one per second.  This returns true on success,
+ * maximum number of tries; Connection_timeout specifies the maximum number
+ * of time to wait for each try.  This returns true on success,
  * and zero on failure.  If the connection is successful, this calls
  * packet_set_connection for the connection.
  */
 int
 ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
-    u_short port, int connection_attempts,
+    u_short port, int connection_attempts, int connection_timeout,
     int anonymous, uid_t original_real_uid,
     const char *proxy_command);
 
diff -Naur openssh-2.1.0p3/sshconnect.c openssh-2.1.0p3-new/sshconnect.c
--- openssh-2.1.0p3/sshconnect.c	Thu May 18 07:03:23 2000
+++ openssh-2.1.0p3-new/sshconnect.c	Mon Jun  5 19:32:56 2000
@@ -175,14 +175,16 @@
  * If port is 0, the default port will be used.  If anonymous is zero,
  * a privileged port will be allocated to make the connection.
  * This requires super-user privileges if anonymous is false.
- * Connection_attempts specifies the maximum number of tries (one per
- * second).  If proxy_command is non-NULL, it specifies the command (with %h
+ * Connection_attempts specifies the maximum number of tries and
+ * connection_timeout specifies the time to wait on each try.
+ * If proxy_command is non-NULL, it specifies the command (with %h
  * and %p substituted for host and port, respectively) to use to contact
  * the daemon.
  */
 int
 ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
 	    u_short port, int connection_attempts,
+	    int connection_timeout,
 	    int anonymous, uid_t original_real_uid,
 	    const char *proxy_command)
 {
@@ -230,6 +232,9 @@
 		/* Loop through addresses for this host, and try each one in
 		   sequence until the connection succeeds. */
 		for (ai = aitop; ai; ai = ai->ai_next) {
+		        fd_set ourset;
+			struct timeval timeout;
+
 			if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
 				continue;
 			if (getnameinfo(ai->ai_addr, ai->ai_addrlen,
@@ -253,7 +258,15 @@
 			 * the remote uid as root.
 			 */
 			temporarily_use_uid(original_real_uid);
-			if (connect(sock, ai->ai_addr, ai->ai_addrlen) >= 0) {
+			fcntl(sock, F_SETFL, O_NONBLOCK);
+			FD_ZERO(&ourset);
+			FD_SET(sock, &ourset);
+			timeout.tv_sec = connection_timeout;
+			timeout.tv_usec = 0;
+			connect(sock, ai->ai_addr, ai->ai_addrlen);
+			select(sock + 1, &ourset, &ourset, &ourset, &timeout);
+			connect(sock, ai->ai_addr, ai->ai_addrlen);
+			if (errno == EISCONN) {
 				/* Successful connection. */
 				memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen);
 				restore_uid();


More information about the openssh-unix-dev mailing list