Bugzilla – Attachment 14 Details for
Bug 91
timeout patches
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
timeout patches (work by Ian Jackson and Matthew Vernon)
openssh-3.0.2p1-timeouts.diff (text/plain), 13.38 KB, created by
Matthew Vernon
on 2002-01-31 21:31:33 AEDT
(
hide
)
Description:
timeout patches (work by Ian Jackson and Matthew Vernon)
Filename:
MIME Type:
Creator:
Matthew Vernon
Created:
2002-01-31 21:31:33 AEDT
Size:
13.38 KB
patch
obsolete
>diff -ru orig/clientloop.c openssh-3.0.2p1/clientloop.c >--- orig/clientloop.c Mon Nov 12 00:06:33 2001 >+++ openssh-3.0.2p1/clientloop.c Fri Jan 4 13:32:14 2002 >@@ -316,10 +316,14 @@ > * one of the file descriptors). > */ > >-static void >+static int > client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, > int *maxfdp, int *nallocp, int rekeying) > { >+ struct timeval tv, *tvp; >+ int n; >+ extern Options options; >+ > /* Add any selections by the channel mechanism. */ > channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, rekeying); > >@@ -348,7 +352,7 @@ > /* clear mask since we did not call select() */ > memset(*readsetp, 0, *nallocp); > memset(*writesetp, 0, *nallocp); >- return; >+ return 0; > } else { > FD_SET(connection_in, *readsetp); > } >@@ -367,7 +371,21 @@ > * SSH_MSG_IGNORE packet when the timeout expires. > */ > >- if (select((*maxfdp)+1, *readsetp, *writesetp, NULL, NULL) < 0) { >+ /* >+ * We don't do the 'random' bit, but we want periodic ignored >+ * message anyway, so as to notice when the other ends TCP >+ * has given up during an outage. >+ */ >+ >+ if (options.protocolkeepalives > 0) { >+ tvp = &tv; >+ tv.tv_sec = options.protocolkeepalives; >+ tv.tv_usec = 0; >+ } else >+ tvp = 0; >+ >+ n = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp); >+ if (n < 0) { > char buf[100]; > > /* >@@ -379,12 +397,13 @@ > memset(*writesetp, 0, *nallocp); > > if (errno == EINTR) >- return; >+ return 0; > /* Note: we might still have data in the buffers. */ > snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno)); > buffer_append(&stderr_buffer, buf, strlen(buf)); > quit_pending = 1; > } >+ return n == 0; > } > > static void >@@ -777,6 +796,7 @@ > { > fd_set *readset = NULL, *writeset = NULL; > double start_time, total_time; >+ int timed_out; > int max_fd = 0, max_fd2 = 0, len, rekeying = 0, nalloc = 0; > char buf[100]; > >@@ -884,7 +904,7 @@ > * available on one of the descriptors). > */ > max_fd2 = max_fd; >- client_wait_until_can_do_something(&readset, &writeset, >+ timed_out = client_wait_until_can_do_something(&readset, &writeset, > &max_fd2, &nalloc, rekeying); > > if (quit_pending) >@@ -907,6 +927,21 @@ > > if (quit_pending) > break; >+ >+ if(timed_out) { >+ /* >+ * Nothing is happening, so synthesize some >+ * bogus activity >+ */ >+ packet_start(compat20 >+ ? SSH2_MSG_IGNORE >+ : SSH_MSG_IGNORE); >+ packet_put_cstring(""); >+ packet_send(); >+ if (FD_ISSET(connection_out, writeset)) >+ packet_write_poll(); >+ continue; >+ } > > if (!compat20) { > /* Buffer data from stdin */ >diff -ru orig/packet.c openssh-3.0.2p1/packet.c >--- orig/packet.c Mon Nov 12 00:07:58 2001 >+++ openssh-3.0.2p1/packet.c Fri Jan 4 13:30:49 2002 >@@ -74,6 +74,7 @@ > */ > static int connection_in = -1; > static int connection_out = -1; >+static int setup_timeout = -1; > > /* Protocol flags for the remote side. */ > static u_int remote_protocol_flags = 0; >@@ -123,13 +124,14 @@ > * packet_set_encryption_key is called. > */ > void >-packet_set_connection(int fd_in, int fd_out) >+packet_set_connection(int fd_in, int fd_out, int new_setup_timeout) > { > Cipher *none = cipher_by_name("none"); > if (none == NULL) > fatal("packet_set_connection: cannot load cipher 'none'"); > connection_in = fd_in; > connection_out = fd_out; >+ setup_timeout = new_setup_timeout; > cipher_init(&send_context, none, (u_char *) "", 0, NULL, 0); > cipher_init(&receive_context, none, (u_char *) "", 0, NULL, 0); > newkeys[MODE_IN] = newkeys[MODE_OUT] = NULL; >@@ -615,6 +617,7 @@ > int type, len; > fd_set *setp; > char buf[8192]; >+ struct timeval tv, *tvp; > DBG(debug("packet_read()")); > > setp = (fd_set *)xmalloc(howmany(connection_in+1, NFDBITS) * >@@ -646,10 +649,19 @@ > sizeof(fd_mask)); > FD_SET(connection_in, setp); > >+ if (setup_timeout > 0) { >+ tvp = &tv; >+ tv.tv_sec = setup_timeout; >+ tv.tv_usec = 0; >+ } else >+ tvp = 0; >+ > /* Wait for some data to arrive. */ >- while (select(connection_in + 1, setp, NULL, NULL, NULL) == -1 && >+ while (select(connection_in + 1, setp, NULL, NULL, tvp) == -1 && > (errno == EAGAIN || errno == EINTR)) > ; >+ if (!FD_ISSET(connection_in, setp)) >+ fatal("packet_read: Setup timeout expired, giving up"); > > /* Read data from the socket. */ > len = read(connection_in, buf, sizeof(buf)); >diff -ru orig/packet.h openssh-3.0.2p1/packet.h >--- orig/packet.h Mon Nov 12 00:02:52 2001 >+++ openssh-3.0.2p1/packet.h Fri Jan 4 13:30:49 2002 >@@ -18,7 +18,7 @@ > > #include <openssl/bn.h> > >-void packet_set_connection(int, int); >+void packet_set_connection(int, int, int); > void packet_set_nonblocking(void); > int packet_get_connection_in(void); > int packet_get_connection_out(void); >diff -ru orig/readconf.c openssh-3.0.2p1/readconf.c >--- orig/readconf.c Wed Oct 3 18:39:39 2001 >+++ openssh-3.0.2p1/readconf.c Fri Jan 4 13:30:49 2002 >@@ -83,6 +83,8 @@ > UseRsh no > StrictHostKeyChecking yes > KeepAlives no >+ ProtocolKeepAlives 0 >+ SetupTimeOut 0 > IdentityFile ~/.ssh/identity > Port 22 > EscapeChar ~ >@@ -115,7 +117,8 @@ > oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, > oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, > oHostKeyAlgorithms, oBindAddress, oSmartcardDevice, >- oClearAllForwardings, oNoHostAuthenticationForLocalhost >+ oClearAllForwardings, oNoHostAuthenticationForLocalhost, >+ oProtocolKeepAlives, oSetupTimeOut > } OpCodes; > > /* Textual representations of the tokens. */ >@@ -187,6 +190,8 @@ > { "smartcarddevice", oSmartcardDevice }, > { "clearallforwardings", oClearAllForwardings }, > { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost }, >+ { "protocolkeepalives", oProtocolKeepAlives }, >+ { "setuptimeout", oSetupTimeOut }, > { NULL, 0 } > }; > >@@ -420,6 +425,14 @@ > intptr = &options->no_host_authentication_for_localhost; > goto parse_flag; > >+ case oProtocolKeepAlives: >+ intptr = &options->protocolkeepalives; >+ goto parse_int; >+ >+ case oSetupTimeOut: >+ intptr = &options->setuptimeout; >+ goto parse_int; >+ > case oNumberOfPasswordPrompts: > intptr = &options->number_of_password_prompts; > goto parse_int; >@@ -772,6 +785,8 @@ > options->strict_host_key_checking = -1; > options->compression = -1; > options->keepalives = -1; >+ options->protocolkeepalives = -1; >+ options->setuptimeout = -1; > options->compression_level = -1; > options->port = -1; > options->connection_attempts = -1; >@@ -865,6 +880,14 @@ > options->compression = 0; > if (options->keepalives == -1) > options->keepalives = 1; >+ if (options->protocolkeepalives == -1){ >+ if (options->batch_mode == 1) /*in batch mode, default is 5mins */ >+ options->protocolkeepalives = 300; >+ else options->protocolkeepalives = 0;} >+ if (options->setuptimeout == -1){ >+ if (options->batch_mode == 1) /*in batch mode, default is 5mins */ >+ options->setuptimeout = 300; >+ else options->setuptimeout = 0;} > if (options->compression_level == -1) > options->compression_level = 6; > if (options->port == -1) >diff -ru orig/readconf.h openssh-3.0.2p1/readconf.h >--- orig/readconf.h Wed Oct 3 18:39:39 2001 >+++ openssh-3.0.2p1/readconf.h Fri Jan 4 13:30:49 2002 >@@ -63,6 +63,8 @@ > int compression_level; /* Compression level 1 (fast) to 9 > * (best). */ > int keepalives; /* Set SO_KEEPALIVE. */ >+ int protocolkeepalives; /* ssh-level keepalives */ >+ int setuptimeout; /* timeout in the protocol banner exchange */ > LogLevel log_level; /* Level for logging. */ > > int port; /* Port to connect. */ >diff -ru orig/ssh-keyscan.c openssh-3.0.2p1/ssh-keyscan.c >--- orig/ssh-keyscan.c Wed Nov 14 21:40:45 2001 >+++ openssh-3.0.2p1/ssh-keyscan.c Fri Jan 4 13:30:49 2002 >@@ -348,7 +348,7 @@ > { > int j; > >- packet_set_connection(c->c_fd, c->c_fd); >+ packet_set_connection(c->c_fd, c->c_fd, timeout); > enable_compat20(); > myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = c->c_keytype == KT_DSA? > "ssh-dss": "ssh-rsa"; >diff -ru orig/ssh.1 openssh-3.0.2p1/ssh.1 >--- orig/ssh.1 Mon Nov 12 00:05:49 2001 >+++ openssh-3.0.2p1/ssh.1 Fri Jan 4 13:30:49 2002 >@@ -711,8 +711,15 @@ > If set to > .Dq yes , > passphrase/password querying will be disabled. >+In addition, the >+.Cm ProtocolKeepAlives >+and >+.Cm SetupTimeOut >+options will both be set to 300 seconds by default. > This option is useful in scripts and other batch jobs where no user >-is present to supply the password. >+is present to supply the password, >+and where it is desirable to detect a >+broken network swiftly. > The argument must be > .Dq yes > or >@@ -930,7 +937,12 @@ > Specifies whether the system should send keepalive messages to the > other side. > If they are sent, death of the connection or crash of one >-of the machines will be properly noticed. >+of the machines will be properly noticed. This option only uses TCP >+keepalives (as opposed to using ssh level keepalives), so takes a long >+time to notice when the connection dies. As such, you probably want >+the >+.Cm ProtocolKeepAlives >+option as well. > However, this means that > connections will die if the route is down temporarily, and some people > find it annoying. >@@ -1029,6 +1041,13 @@ > .Nm > tries version 2 and falls back to version 1 > if version 2 is not available. >+.It Cm ProtocolKeepAlives >+Specifies the interval at which IGNORE packets will be sent to >+the server during dile periods. Use this option in scripts to detect >+when the network fails. The argument must be an integer. The default >+is 0 (disabled), or 300 if the >+.Cm BatchMode >+option is set. > .It Cm ProxyCommand > Specifies the command to use to connect to the server. > The command >@@ -1121,6 +1140,19 @@ > .Dq no . > The default is > .Dq yes . >+.It Cm SetupTimeOut >+Normally, >+.Nm ssh >+blocks indefinitly whilst waiting to receive the ssh banner and other >+setup protocol from the server, during the session setup. This can cause >+.Nm ssh >+to hang under certain circumstances. If this option is set, >+.Nm ssh >+will give up if no data from the server is received for the specified >+number of seconds. The argument must be an integer. The default is 0 >+(disabled), or 300 if >+.Cm BatchMode >+is set. > .It Cm SmartcardDevice > Specifies which smartcard device to use. The argument to this keyword is > the device >diff -ru orig/sshconnect.c openssh-3.0.2p1/sshconnect.c >--- orig/sshconnect.c Wed Oct 10 06:07:45 2001 >+++ openssh-3.0.2p1/sshconnect.c Fri Jan 4 13:30:49 2002 >@@ -42,6 +42,8 @@ > #define INET6_ADDRSTRLEN 46 > #endif > >+static sig_atomic_t banner_timedout; >+ > static const char * > sockaddr_ntop(struct sockaddr *sa) > { >@@ -63,6 +65,11 @@ > return addrbuf; > } > >+static void banner_alarm_catch (int signum) >+{ >+ banner_timedout = 1; >+} >+ > /* > * Connect to the given ssh server using a proxy command. > */ >@@ -158,7 +165,7 @@ > buffer_free(&command); > > /* Set the connection file descriptors. */ >- packet_set_connection(pout[0], pin[1]); >+ packet_set_connection(pout[0], pin[1], options.setuptimeout); > > /* Indicate OK return */ > return 0; >@@ -378,7 +385,7 @@ > error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); > > /* Set the connection. */ >- packet_set_connection(sock, sock); >+ packet_set_connection(sock, sock, options.setuptimeout); > > return 0; > } >@@ -395,24 +402,42 @@ > int connection_in = packet_get_connection_in(); > int connection_out = packet_get_connection_out(); > int minor1 = PROTOCOL_MINOR_1; >+ struct sigaction sa, osa; > >- /* Read other side\'s version identification. */ >+ /* Read other side's version identification. >+ * If SetupTimeOut has been set, give up after >+ * the specified amount of time >+ */ >+ if(options.setuptimeout > 0){ >+ memset(&sa, 0, sizeof(sa)); >+ sa.sa_handler = banner_alarm_catch; >+ /*throw away any pending alarms, since we'd block otherwise*/ >+ alarm(0); >+ sigaction(SIGALRM, &sa, &osa); >+ alarm(options.setuptimeout); >+ } > for (;;) { >- for (i = 0; i < sizeof(buf) - 1; i++) { >- int len = atomicio(read, connection_in, &buf[i], 1); >- if (len < 0) >+ for (i = 0; i < sizeof(buf) - 1; ) { >+ int len = read(connection_in, &buf[i], 1); >+ if (banner_timedout) >+ fatal("ssh_exchange_identification: Timeout waiting for version information."); >+ if (len < 0) { >+ if (errno == EINTR) >+ continue; > fatal("ssh_exchange_identification: read: %.100s", strerror(errno)); >+ } > if (len != 1) > fatal("ssh_exchange_identification: Connection closed by remote host"); >- if (buf[i] == '\r') { >- buf[i] = '\n'; >- buf[i + 1] = 0; >- continue; /**XXX wait for \n */ >- } > if (buf[i] == '\n') { > buf[i + 1] = 0; > break; > } >+ if (buf[i] == '\r') { >+ buf[i] = '\n'; >+ buf[i + 1] = 0; /**XXX wait for \n */ >+ } >+ i++; > } > buf[sizeof(buf) - 1] = 0; > if (strncmp(buf, "SSH-", 4) == 0) >@@ -420,6 +445,14 @@ > debug("ssh_exchange_identification: %s", buf); > } > server_version_string = xstrdup(buf); >+ >+ /* If SetupTimeOut has been set, unset the alarm now, and >+ * put the correct handler for SIGALRM back. >+ */ >+ if (options.setuptimeout > 0) { >+ alarm(0); >+ sigaction(SIGALRM,&osa,NULL); >+ } > > /* > * Check that the versions match. In future this might accept >diff -ru orig/sshd.c openssh-3.0.2p1/sshd.c >--- orig/sshd.c Mon Nov 12 00:07:12 2001 >+++ openssh-3.0.2p1/sshd.c Fri Jan 4 13:30:49 2002 >@@ -1129,7 +1129,7 @@ > * Register our connection. This turns encryption off because we do > * not have a key. > */ >- packet_set_connection(sock_in, sock_out); >+ packet_set_connection(sock_in, sock_out, -1); > > remote_port = get_remote_port(); > remote_ip = get_remote_ipaddr();
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 91
: 14