On Sat, Nov 26, 2022 at 11:38:24AM -0800, Matthew Sotoudeh via Mutt-dev wrote: > On an unreliable connection (e.g., laptop put to sleep and changing wifi > networks) I've had mutt fairly regularly become stuck in SSL_read and > have to be killed. > > Per some of the comments on > https://stackoverflow.com/questions/46517875/ssl-read-blocks-indefinitely > adding a timeout to the socket should carry over to the SSL_read call. > > Using this receive_timeout option appears to resolve the issue for me, > thought others may find it useful. > > Signed-off-by: Matthew Sotoudeh <matt...@masot.net> > --- > globals.h | 1 + > init.h | 6 ++++++ > mutt_socket.c | 5 +++++ > 3 files changed, 12 insertions(+) > > diff --git a/globals.h b/globals.h > index 06ce410e..b782114e 100644 > --- a/globals.h > +++ b/globals.h > @@ -236,6 +236,7 @@ WHERE short PagerContext; > WHERE short PagerIndexLines; > WHERE short PagerSkipQuotedContext; > WHERE short ReadInc; > +WHERE short ReceiveTimeout; > WHERE short ReflowWrap; > WHERE short SaveHist; > WHERE short SendmailWait; > diff --git a/init.h b/init.h > index e160d3d3..f701c9a7 100644 > --- a/init.h > +++ b/init.h > @@ -3221,6 +3221,12 @@ struct option_t MuttVars[] = { > ** .pp > ** Also see $$postponed variable. > */ > + { "receive_timeout", DT_NUM, R_NONE, {.p=&ReceiveTimeout}, {.l=0} }, > + /* > + ** .pp > + ** Receive timeout (in seconds) to set on opened sockets. Zero (default) > + ** means no timeout.
nit: Can we be precise and say "Zero (default) or less" here, as we do for $timeout [0]. Also, "Receive timeout" is relatively self-explanatory, but I'd suggest being very explicit in exactly what this timeout provides given that we have other timeouts that e.g. poll IMAP connections, etc. [0]: http://www.mutt.org/doc/manual/#timeout > + */ > { "record", DT_PATH, R_NONE, {.p=&Outbox}, {.p="~/sent"} }, > /* > ** .pp > diff --git a/mutt_socket.c b/mutt_socket.c > index 3e192072..28c56996 100644 > --- a/mutt_socket.c > +++ b/mutt_socket.c > @@ -617,6 +617,11 @@ int raw_socket_open (CONNECTION* conn) > fd = socket (cur->ai_family, cur->ai_socktype, cur->ai_protocol); > if (fd >= 0) > { > + if (ReceiveTimeout > 0) > + { > + struct timeval tv = { ReceiveTimeout, 0 }; > + setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)); > + } > if ((rc = socket_connect (fd, cur->ai_addr)) == 0) +1 to Kevin's suggestion that this be moved into socket_connect(). > { > fcntl (fd, F_SETFD, FD_CLOEXEC); > -- > 2.34.1 >