[PATCH] Connect timeout
Jean-Charles Longuet
jclonguet at free.fr
Sun Jan 27 09:45:39 EST 2002
The attached patch adds a new 'ConnectTimeout' option (man page updated
in patch) to avoid wasting time when the target host is down. I needed that
because I was using rsync/rdist over ssh for massive files update and the
default connect() took too long for my purpose.
The patch was tested on Linux only, but I used a similar one for ssh 1.2.XX
on Linux, Solaris and HP-UX without problems.
The patch can also be found on:
http://charts.free.fr/openssh-3.0.2p1-timeout.patch
PS: I did not suscribe to the list, so please cc: me regarding this patch
-------------- next part --------------
--- includes.h.OK Thu Sep 20 04:07:51 2001
+++ includes.h Sat Jan 26 21:44:35 2002
@@ -44,6 +44,8 @@
#include <grp.h>
#include <time.h>
#include <dirent.h>
+#include <setjmp.h>
+#include <signal.h>
#ifdef HAVE_LIMITS_H
# include <limits.h>
--- readconf.c.OK Wed Oct 3 19:39:39 2001
+++ readconf.c Sat Jan 26 21:44:35 2002
@@ -115,7 +115,8 @@
oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
- oClearAllForwardings, oNoHostAuthenticationForLocalhost
+ oClearAllForwardings, oNoHostAuthenticationForLocalhost,
+ oConnectTimeout
} OpCodes;
/* Textual representations of the tokens. */
@@ -187,6 +188,7 @@
{ "smartcarddevice", oSmartcardDevice },
{ "clearallforwardings", oClearAllForwardings },
{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
+ { "connecttimeout", oConnectTimeout },
{ NULL, 0 }
};
@@ -294,6 +296,11 @@
/* don't panic, but count bad options */
return -1;
/* NOTREACHED */
+
+ case oConnectTimeout:
+ intptr = &options->connection_timeout;
+ goto parse_int;
+
case oForwardAgent:
intptr = &options->forward_agent;
parse_flag:
@@ -775,6 +782,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;
--- readconf.h.OK Wed Oct 3 19:39:39 2001
+++ readconf.h Sat Jan 26 21:44:35 2002
@@ -68,6 +68,8 @@
int port; /* Port to connect. */
int connection_attempts; /* Max attempts (seconds) before
* giving up */
+ int connection_timeout; /* Max time (seconds) before
+ * aborting connection attempt */
int number_of_password_prompts; /* Max number of password
* prompts. */
int cipher; /* Cipher to use. */
--- ssh.1.OK Mon Nov 12 01:05:49 2001
+++ ssh.1 Sat Jan 26 21:44:35 2002
@@ -804,6 +804,12 @@
The argument must be an integer.
This may be useful in scripts if the connection sometimes fails.
The default is 1.
+.It Cm ConnectTimeout
+Specifies the timeout (in seconds) used when connecting to the ssh
+server, instead of using default system values. This value is used
+only when the target is down or really unreachable, not when it
+refuses the connection. This may be usefull for tools using ssh
+for communication, as it avoid long waits.
.It Cm DynamicForward
Specifies that a TCP/IP port on the local machine be forwarded
over the secure channel, and the application
--- ssh.c.OK Mon Nov 12 00:52:04 2001
+++ ssh.c Sat Jan 26 21:44:35 2002
@@ -674,7 +674,7 @@
/* Open a connection to the remote host. */
cerr = ssh_connect(host, &hostaddr, options.port, IPv4or6,
- options.connection_attempts,
+ options.connection_attempts, options.connection_timeout,
original_effective_uid != 0 || !options.use_privileged_port,
pw, options.proxy_command);
--- sshconnect.c.OK Wed Oct 10 07:07:45 2001
+++ sshconnect.c Sat Jan 26 21:44:35 2002
@@ -35,6 +35,8 @@
char *client_version_string = NULL;
char *server_version_string = NULL;
+static jmp_buf jmpenv;
+
extern Options options;
extern char *__progname;
@@ -221,6 +223,43 @@
return sock;
}
+/* for alarm() */
+static void
+timeout_sigh(int dummy)
+{
+ errno = ETIMEDOUT;
+ longjmp(jmpenv, !0);
+}
+
+int
+timeout_connect(int sockfd, const struct sockaddr *serv_addr,
+ socklen_t addrlen, int timeout)
+{
+ void (*sigh)(int);
+ int rc;
+
+ if (timeout <= 0)
+ return(connect(sockfd, serv_addr, addrlen));
+
+ if (setjmp(jmpenv) == 0)
+ {
+ debug("ssh: setting connect() timeout to %d s.",
+ timeout);
+ sigh = signal(SIGALRM, timeout_sigh);
+ if (sigh == SIG_ERR)
+ sigh = SIG_IGN; /* For further restore */
+ (void) alarm((unsigned int) timeout);
+ rc = connect(sockfd, serv_addr, addrlen);
+ /* restore previous behaviour */
+ (void) alarm((unsigned int) 0);
+ (void) signal(SIGALRM, sigh);
+ return rc;
+ } else {
+ errno = ETIMEDOUT;
+ return -1;
+ }
+}
+
/*
* Opens a TCP/IP connection to the remote server on the given host.
* The address of the remote host will be returned in hostaddr.
@@ -240,7 +279,7 @@
*/
int
ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
- u_short port, int family, int connection_attempts,
+ u_short port, int family, int connection_attempts, int connection_timeout,
int anonymous, struct passwd *pw, const char *proxy_command)
{
int gaierr;
@@ -322,7 +361,8 @@
* the remote uid as root.
*/
temporarily_use_uid(pw);
- if (connect(sock, ai->ai_addr, ai->ai_addrlen) >= 0) {
+ if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen,
+ connection_timeout) >= 0) {
/* Successful connection. */
memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen);
restore_uid();
--- sshconnect.h.OK Wed Oct 10 07:07:45 2001
+++ sshconnect.h Sat Jan 26 21:44:35 2002
@@ -28,7 +28,7 @@
int
ssh_connect(const char *, struct sockaddr_storage *, u_short, int, int,
- int, struct passwd *, const char *);
+ int, int, struct passwd *, const char *);
void
ssh_login(Key **, int, const char *, struct sockaddr *, struct passwd *);
More information about the openssh-unix-dev
mailing list