upstream: Wait for FD to be readable or writeable during a nonblocking

connect, not just readable.  Prevents a timeout when the server doesn't
immediately send a banner (eg multiplexers like sslh) but is also slightly
quicker for other connections since, unlike ssh1, ssh2 doesn't specify
that the client should parse the server banner before sending its own.
Patch from mnissler@chromium.org, ok djm@

OpenBSD-Commit-ID: aba9cd8480d1d9dd31d0ca0422ea155c26c5df1d
This commit is contained in:
dtucker@openbsd.org 2019-11-22 06:50:30 +00:00 committed by Darren Tucker
parent 2f95d43dc2
commit e2c0a21ade
1 changed files with 16 additions and 6 deletions

22
misc.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: misc.c,v 1.142 2019/09/03 08:32:11 djm Exp $ */
/* $OpenBSD: misc.c,v 1.143 2019/11/22 06:50:30 dtucker Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2005,2006 Damien Miller. All rights reserved.
@ -238,12 +238,12 @@ set_rdomain(int fd, const char *name)
}
/*
* Wait up to *timeoutp milliseconds for fd to be readable. Updates
* Wait up to *timeoutp milliseconds for events on fd. Updates
* *timeoutp with time remaining.
* Returns 0 if fd ready or -1 on timeout or error (see errno).
*/
int
waitrfd(int fd, int *timeoutp)
static int
waitfd(int fd, int *timeoutp, short events)
{
struct pollfd pfd;
struct timeval t_start;
@ -251,7 +251,7 @@ waitrfd(int fd, int *timeoutp)
monotime_tv(&t_start);
pfd.fd = fd;
pfd.events = POLLIN;
pfd.events = events;
for (; *timeoutp >= 0;) {
r = poll(&pfd, 1, *timeoutp);
oerrno = errno;
@ -269,6 +269,16 @@ waitrfd(int fd, int *timeoutp)
return -1;
}
/*
* Wait up to *timeoutp milliseconds for fd to be readable. Updates
* *timeoutp with time remaining.
* Returns 0 if fd ready or -1 on timeout or error (see errno).
*/
int
waitrfd(int fd, int *timeoutp) {
return waitfd(fd, timeoutp, POLLIN);
}
/*
* Attempt a non-blocking connect(2) to the specified address, waiting up to
* *timeoutp milliseconds for the connection to complete. If the timeout is
@ -295,7 +305,7 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr,
} else if (errno != EINPROGRESS)
return -1;
if (waitrfd(sockfd, timeoutp) == -1)
if (waitfd(sockfd, timeoutp, POLLIN | POLLOUT) == -1)
return -1;
/* Completed or failed */