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
> 

Reply via email to