Bugzilla – Attachment 1350 Details for
Bug 1363
sshd gets stuck: select() in packet_read_seqnr waits indefinitely
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
revised patch
ssh-packet-timeout.diff (text/plain), 7.06 KB, created by
Damien Miller
on 2007-09-18 10:50:15 AEST
(
hide
)
Description:
revised patch
Filename:
MIME Type:
Creator:
Damien Miller
Created:
2007-09-18 10:50:15 AEST
Size:
7.06 KB
patch
obsolete
>Index: misc.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/misc.c,v >retrieving revision 1.65 >diff -u -p -r1.65 misc.c >--- misc.c 23 Nov 2006 01:35:11 -0000 1.65 >+++ misc.c 18 Sep 2007 00:46:23 -0000 >@@ -803,3 +803,23 @@ put_u16(void *vp, u_int16_t v) > p[0] = (u_char)(v >> 8) & 0xff; > p[1] = (u_char)v & 0xff; > } >+ >+void >+ms_subtract_diff(struct timeval *start, int *ms) >+{ >+ struct timeval diff, finish; >+ >+ gettimeofday(&finish, NULL); >+ timersub(&finish, start, &diff); >+ *ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000); >+} >+ >+void >+ms_to_timeval(struct timeval *tv, int ms) >+{ >+ if (ms < 0) >+ ms = 0; >+ tv->tv_sec = ms / 1000; >+ tv->tv_usec = (ms % 1000) * 1000; >+} >+ >Index: misc.h >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/misc.h,v >retrieving revision 1.36 >diff -u -p -r1.36 misc.h >--- misc.h 18 Aug 2006 10:27:16 -0000 1.36 >+++ misc.h 18 Sep 2007 00:46:23 -0000 >@@ -33,6 +33,8 @@ char *tilde_expand_filename(const char * > char *percent_expand(const char *, ...) __attribute__((__sentinel__)); > char *tohex(const void *, size_t); > void sanitise_stdfd(void); >+void ms_subtract_diff(struct timeval *, int *); >+void ms_to_timeval(struct timeval *, int); > > struct passwd *pwcopy(struct passwd *); > >Index: packet.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/packet.c,v >retrieving revision 1.148 >diff -u -p -r1.148 packet.c >--- packet.c 7 Jun 2007 19:37:34 -0000 1.148 >+++ packet.c 18 Sep 2007 00:46:23 -0000 >@@ -132,6 +132,9 @@ static int server_side = 0; > /* Set to true if we are authenticated. */ > static int after_authentication = 0; > >+/* Set to the maximum time that we will wait to send or receive a packet */ >+static int packet_timeout_ms = -1; >+ > /* Session key information for Encryption and MAC */ > Newkeys *newkeys[MODE_MAX]; > static struct packet_state { >@@ -185,6 +188,19 @@ packet_set_connection(int fd_in, int fd_ > } > } > >+void >+packet_set_timeout(int timeout, int count) >+{ >+ if (timeout == 0 || count == 0) { >+ packet_timeout_ms = -1; >+ return; >+ } >+ if ((INT_MAX / 1000) / count < timeout) >+ packet_timeout_ms = INT_MAX; >+ else >+ packet_timeout_ms = timeout * count * 1000; >+} >+ > /* Returns 1 if remote host is connected via socket, 0 if not. */ > > int >@@ -880,10 +896,11 @@ packet_send(void) > int > packet_read_seqnr(u_int32_t *seqnr_p) > { >- int type, len; >+ int type, len, ret, ms_remain; > fd_set *setp; > char buf[8192]; > DBG(debug("packet_read()")); >+ struct timeval timeout, start, *timeoutp = NULL; > > setp = (fd_set *)xcalloc(howmany(connection_in+1, NFDBITS), > sizeof(fd_mask)); >@@ -914,11 +931,30 @@ packet_read_seqnr(u_int32_t *seqnr_p) > sizeof(fd_mask)); > FD_SET(connection_in, setp); > >+ if (packet_timeout_ms > 0) { >+ ms_remain = packet_timeout_ms; >+ ms_to_timeval(&timeout, ms_remain); >+ timeoutp = &timeout; >+ } > /* Wait for some data to arrive. */ >- while (select(connection_in + 1, setp, NULL, NULL, NULL) == -1 && >- (errno == EAGAIN || errno == EINTR)) >- ; >- >+ for (;;) { >+ gettimeofday(&start, NULL); >+ if ((ret = select(connection_in + 1, setp, NULL, >+ NULL, timeoutp)) >= 0) >+ break; >+ if (errno != EAGAIN && errno != EINTR) >+ break; >+ ms_subtract_diff(&start, &ms_remain); >+ if (ms_remain <= 0) { >+ ret = 0; >+ break; >+ } >+ } >+ if (ret == 0) { >+ logit("Connection to %.200s timed out while " >+ "waiting to read", get_remote_ipaddr()); >+ cleanup_exit(255); >+ } > /* Read data from the socket. */ > len = read(connection_in, buf, sizeof(buf)); > if (len == 0) { >@@ -1432,6 +1468,8 @@ void > packet_write_wait(void) > { > fd_set *setp; >+ int ret, ms_remain; >+ struct timeval start, timeout, *timeoutp = NULL; > > setp = (fd_set *)xcalloc(howmany(connection_out + 1, NFDBITS), > sizeof(fd_mask)); >@@ -1440,9 +1478,30 @@ packet_write_wait(void) > memset(setp, 0, howmany(connection_out + 1, NFDBITS) * > sizeof(fd_mask)); > FD_SET(connection_out, setp); >- while (select(connection_out + 1, NULL, setp, NULL, NULL) == -1 && >- (errno == EAGAIN || errno == EINTR)) >- ; >+ >+ if (packet_timeout_ms > 0) { >+ ms_remain = packet_timeout_ms; >+ ms_to_timeval(&timeout, ms_remain); >+ timeoutp = &timeout; >+ } >+ for (;;) { >+ gettimeofday(&start, NULL); >+ if ((ret = select(connection_out + 1, NULL, setp, >+ NULL, timeoutp)) >= 0) >+ break; >+ if (errno != EAGAIN && errno != EINTR) >+ break; >+ ms_subtract_diff(&start, &ms_remain); >+ if (ms_remain <= 0) { >+ ret = 0; >+ break; >+ } >+ } >+ if (ret == 0) { >+ logit("Connection to %.200s timed out while " >+ "waiting to write", get_remote_ipaddr()); >+ cleanup_exit(255); >+ } > packet_write_poll(); > } > xfree(setp); >Index: packet.h >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/packet.h,v >retrieving revision 1.45 >diff -u -p -r1.45 packet.h >--- packet.h 25 Mar 2006 22:22:43 -0000 1.45 >+++ packet.h 18 Sep 2007 00:46:23 -0000 >@@ -21,6 +21,7 @@ > #include <openssl/bn.h> > > void packet_set_connection(int, int); >+void packet_set_timeout(int, int); > void packet_set_nonblocking(void); > int packet_get_connection_in(void); > int packet_get_connection_out(void); >Index: sshconnect.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/sshconnect.c,v >retrieving revision 1.202 >diff -u -p -r1.202 sshconnect.c >--- sshconnect.c 4 Sep 2007 11:15:55 -0000 1.202 >+++ sshconnect.c 18 Sep 2007 00:46:23 -0000 >@@ -64,23 +64,6 @@ extern pid_t proxy_command_pid; > static int show_other_keys(const char *, Key *); > static void warn_changed_key(Key *); > >-static void >-ms_subtract_diff(struct timeval *start, int *ms) >-{ >- struct timeval diff, finish; >- >- gettimeofday(&finish, NULL); >- timersub(&finish, start, &diff); >- *ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000); >-} >- >-static void >-ms_to_timeval(struct timeval *tv, int ms) >-{ >- tv->tv_sec = ms / 1000; >- tv->tv_usec = (ms % 1000) * 1000; >-} >- > /* > * Connect to the given ssh server using a proxy command. > */ >@@ -165,6 +148,8 @@ ssh_proxy_connect(const char *host, u_sh > > /* Set the connection file descriptors. */ > packet_set_connection(pout[0], pin[1]); >+ packet_set_timeout(options.server_alive_interval, >+ options.server_alive_count_max); > > /* Indicate OK return */ > return 0; >@@ -409,6 +394,8 @@ ssh_connect(const char *host, struct soc > > /* Set the connection. */ > packet_set_connection(sock, sock); >+ packet_set_timeout(options.server_alive_interval, >+ options.server_alive_count_max); > > return 0; > } >Index: sshd.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/sshd.c,v >retrieving revision 1.351 >diff -u -p -r1.351 sshd.c >--- sshd.c 22 May 2007 10:18:52 -0000 1.351 >+++ sshd.c 18 Sep 2007 00:46:24 -0000 >@@ -1611,6 +1611,8 @@ main(int ac, char **av) > * not have a key. > */ > packet_set_connection(sock_in, sock_out); >+ packet_set_timeout(options.client_alive_interval, >+ options.client_alive_count_max); > packet_set_server(); > > /* Set SO_KEEPALIVE if requested. */
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 1363
:
1348
|
1350
|
1351
|
1446