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.
+  */
   { "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)
       {
        fcntl (fd, F_SETFD, FD_CLOEXEC);
-- 
2.34.1

Reply via email to