-/* $OpenBSD: misc.c,v 1.184 2023/07/19 14:02:27 djm Exp $ */
+/* $OpenBSD: misc.c,v 1.185 2023/08/04 06:32:40 dtucker Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2005-2020 Damien Miller. All rights reserved.
{
struct pollfd pfd;
struct timeval t_start;
- int oerrno, r;
+ int oerrno, r, have_timeout = (*timeoutp >= 0);
pfd.fd = fd;
pfd.events = events;
- for (; *timeoutp >= 0;) {
+ for (; !have_timeout || *timeoutp >= 0;) {
monotime_tv(&t_start);
r = poll(&pfd, 1, *timeoutp);
oerrno = errno;
- ms_subtract_diff(&t_start, timeoutp);
+ if (have_timeout)
+ ms_subtract_diff(&t_start, timeoutp);
errno = oerrno;
if (r > 0)
return 0;
-/* $OpenBSD: mux.c,v 1.98 2023/07/26 23:06:00 djm Exp $ */
+/* $OpenBSD: mux.c,v 1.99 2023/08/04 06:32:40 dtucker Exp $ */
/*
* Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
*
#include "readconf.h"
#include "clientloop.h"
#include "ssherr.h"
+#include "misc.h"
/* from ssh.c */
extern int tty_flag;
}
static int
-mux_client_read(int fd, struct sshbuf *b, size_t need)
+mux_client_read(int fd, struct sshbuf *b, size_t need, int timeout_ms)
{
size_t have;
ssize_t len;
u_char *p;
- struct pollfd pfd;
int r;
- pfd.fd = fd;
- pfd.events = POLLIN;
if ((r = sshbuf_reserve(b, need, &p)) != 0)
fatal_fr(r, "reserve");
for (have = 0; have < need; ) {
if (len == -1) {
switch (errno) {
case EAGAIN:
- (void)poll(&pfd, 1, -1);
+ if (waitrfd(fd, &timeout_ms) == -1)
+ return -1; /* timeout */
/* FALLTHROUGH */
case EINTR:
continue;
}
static int
-mux_client_read_packet(int fd, struct sshbuf *m)
+mux_client_read_packet_timeout(int fd, struct sshbuf *m, int timeout_ms)
{
struct sshbuf *queue;
size_t need, have;
if ((queue = sshbuf_new()) == NULL)
fatal_f("sshbuf_new");
- if (mux_client_read(fd, queue, 4) != 0) {
+ if (mux_client_read(fd, queue, 4, timeout_ms) != 0) {
if ((oerrno = errno) == EPIPE)
debug3_f("read header failed: %s",
strerror(errno));
return -1;
}
need = PEEK_U32(sshbuf_ptr(queue));
- if (mux_client_read(fd, queue, need) != 0) {
+ if (mux_client_read(fd, queue, need, timeout_ms) != 0) {
oerrno = errno;
debug3_f("read body failed: %s", strerror(errno));
sshbuf_free(queue);
}
static int
-mux_client_hello_exchange(int fd)
+mux_client_read_packet(int fd, struct sshbuf *m)
+{
+ return mux_client_read_packet_timeout(fd, m, -1);
+}
+
+static int
+mux_client_hello_exchange(int fd, int timeout_ms)
{
struct sshbuf *m;
u_int type, ver;
sshbuf_reset(m);
/* Read their HELLO */
- if (mux_client_read_packet(fd, m) != 0) {
+ if (mux_client_read_packet_timeout(fd, m, timeout_ms) != 0) {
debug_f("read packet failed");
goto out;
}
muxclient(const char *path)
{
struct sockaddr_un addr;
- int sock;
+ int sock, timeout = options.connection_timeout, timeout_ms = -1;
u_int pid;
if (muxclient_command == 0) {
}
set_nonblock(sock);
- if (mux_client_hello_exchange(sock) != 0) {
+ /* Timeout on initial connection only. */
+ if (timeout > 0 && timeout < INT_MAX / 1000)
+ timeout_ms = timeout * 1000;
+
+ if (mux_client_hello_exchange(sock, timeout_ms) != 0) {
error_f("master hello exchange failed");
close(sock);
return -1;