Hi Allen,

Thanks for sending this out, I've been using this since you sent it and
it is working as expected! This is awesome because I no longer have to
close my IMAP connections before closing my laptop!

Do let me know if you need some specific testing or if there's something
else I can help with!

Yoshiki.

On (Apr-28-15|21:06), egbert. wrote:
> Hi all,
> 
> > > There was an irritating glitch, which I have also seen mentioned a few 
> > > times 
> > > online. It is that if you have mutt open, pack up your laptop, and go 
> > > somewhere else, mutt is completely unresponsive and needs to be killed. I 
> > > tracked down what was causing this and to my satisfaction my fix works. 
> > > 
> > > Would you be interested in this patch? And, if the intended behaviour is 
> > > that it should hang like this, then perhaps my fix could be implemented 
> > > as a 
> > > config variable. (It’s basically just a simple timeout + retry mechanism 
> > > in 
> > > the socket_connect function).
> > 
> > Please go ahead and post your patch, either to this list, or perhaps to
> > a ticket.  It looks like http://dev.mutt.org/trac/ticket/3369 or
> > http://dev.mutt.org/trac/ticket/3491 might be related.
> > 
> > Most of the committers are quite busy right now, so it may take a while
> > to get a response.
> 
> Attached is my patch for the hanging socket problem.
> 
> I hope this fixes 3369 and 3491, which indeed sound very similar to the 
> problem I reported.
> 
> All comments welcome.
> 
> I used hg export against the tip of the default branch to produce the diff; 
> please let me know if you would rather have it another way.
> 
> > 
> > > Also, you’ve probably talked about this many times before, but is there a 
> > > reason not to implement a config option to call a command when there is 
> > > new 
> > > mail? 
> > 
> > Yoshiki Vazquez Baeza posted a patch for this a couple months ago, and
> > David Champion is incorporating it into a related patch set.
> > 
> 
> Yours, Allen

> # HG changeset patch
> # User misterfish <al...@netherrealm.net>
> # Date 1430247531 -7200
> #      Tue Apr 28 20:58:51 2015 +0200
> # Node ID 65d3b99e229cefaec62e8205fec116a7c00fce72
> # Parent  755a18da99bc0a57bd6e462f5971eba7b9f61604
> Fix bug where mutt hangs indefinitely when, for example, you pack up your
> laptop and open it again somewhere else.
> 
> Introduce a timeout on sockets ("socket_timeout" in muttrc, default 5
> seconds) and a fixed number of retries for GNUTLS ("ssl_socket_num_tries" in
> muttrc, default is 2).
> 
> Hopefully fixes #3369 and #3491.
> 
> diff -r 755a18da99bc -r 65d3b99e229c globals.h
> --- a/globals.h       Sat Apr 25 19:00:13 2015 -0700
> +++ b/globals.h       Tue Apr 28 20:58:51 2015 +0200
> @@ -193,6 +193,8 @@
>  WHERE unsigned short Counter INITVAL (0);
>  
>  WHERE short ConnectTimeout;
> +WHERE short SocketTimeout;
> +WHERE short GNUTLSSocketNumTries;
>  WHERE short HistSize;
>  WHERE short MenuContext;
>  WHERE short PagerContext;
> diff -r 755a18da99bc -r 65d3b99e229c init.h
> --- a/init.h  Sat Apr 25 19:00:13 2015 -0700
> +++ b/init.h  Tue Apr 28 20:58:51 2015 +0200
> @@ -2888,6 +2888,14 @@
>    ** variable.
>    */
>  #endif /* USE_SMTP */
> +  { "socket_timeout", DT_NUM, R_NONE, UL &SocketTimeout, 5 },
> +  /*
> +  ** .pp
> +  ** Close inactive sockets after this many seconds. When set to zero or a
> +  ** negative value, mutt will wait indefinitely on sockets, but be warned
> +  ** that this can cause mutt to hang. If using GNUTLS, you must also set
> +  ** $$ssl_socket_num_tries to a non-zero value.
> +  */
>    { "sort",          DT_SORT, R_INDEX|R_RESORT, UL &Sort, SORT_DATE },
>    /*
>    ** .pp
> @@ -3025,6 +3033,15 @@
>    ** for use in any Diffie-Hellman key exchange. A value of 0 will use
>    ** the default from the GNUTLS library.
>    */
> +  { "ssl_socket_num_tries", DT_NUM, R_NONE, UL &GNUTLSSocketNumTries, 2 },
> +  /*
> +  ** .pp
> +  ** When using GNUTLS, this can be used in conjunction with
> +  ** $$socket_timeout to cause the mailbox to close after the socket has
> +  ** timed out this many times. If set to zero or a negative number, the
> +  ** socket will wait for data indefinitely, but be aware that this can
> +  ** cause mutt to hang.
> +  */
>  # endif /* USE_SSL_GNUTLS */
>    { "ssl_starttls", DT_QUAD, R_NONE, OPT_SSLSTARTTLS, M_YES },
>    /*
> diff -r 755a18da99bc -r 65d3b99e229c mutt_socket.c
> --- a/mutt_socket.c   Sat Apr 25 19:00:13 2015 -0700
> +++ b/mutt_socket.c   Tue Apr 28 20:58:51 2015 +0200
> @@ -344,6 +344,7 @@
>  {
>    int sa_size;
>    int save_errno;
> +  struct timeval socket_timeout_tv = {0};
>  
>    if (sa->sa_family == AF_INET)
>      sa_size = sizeof (struct sockaddr_in);
> @@ -364,6 +365,28 @@
>  
>    save_errno = 0;
>  
> +  /* Set a timeout on the socket. 
> +   * Can be set to 0 for no timeout, but then, mutt can hang forever waiting
> +   * for data.
> +   * For OpenSSL this is enough to avoid hanging, but with GNUTLS,
> +   * ssl_socket_num_tries must also be set in the config.
> +   */
> +
> +  if (SocketTimeout > 0) {
> +    socket_timeout_tv.tv_sec = SocketTimeout;
> +    if (setsockopt(fd, 
> +      SOL_SOCKET,         /* protocol level */
> +      SO_RCVTIMEO,        /* optname */
> +      &socket_timeout_tv, /* const void *optval */
> +      sizeof(struct timeval)
> +    )) 
> +    {
> +      mutt_perror(_("Couldn't set socket_timeout"));
> +      mutt_sleep(3);
> +      return -1;
> +    }
> +  }
> +
>    if (connect (fd, sa, sa_size) < 0)
>    {
>        save_errno = errno;
> diff -r 755a18da99bc -r 65d3b99e229c mutt_ssl_gnutls.c
> --- a/mutt_ssl_gnutls.c       Sat Apr 25 19:00:13 2015 -0700
> +++ b/mutt_ssl_gnutls.c       Tue Apr 28 20:58:51 2015 +0200
> @@ -131,6 +131,7 @@
>  {
>    tlssockdata *data = conn->sockdata;
>    int ret;
> +  int try = 0;
>  
>    if (!data)
>    {
> @@ -139,7 +140,20 @@
>      return -1;
>    }
>  
> +  /* When the socket times out, ret is GNUTLS_E_AGAIN. 
> +   * When socket_timeout (SocketTimeout) is 0, the socket is set to
> +   * blocking, and this will hang forever on gnutls_record_recv.
> +   * If the timeout is set, but ssl_socket_num_tries (GNUTLSSocketNumTries)
> +   * is equal to zero or a negative value, this will become an infinite loop
> +   * and mutt will hang.
> +   */
> +
>    do {
> +    if (GNUTLSSocketNumTries > 0 && ++try > GNUTLSSocketNumTries) {
> +      mutt_error(_("Timed out reading from socket, closing mailbox."));
> +      mutt_sleep(2);
> +      return -1;
> +    }
>      ret = gnutls_record_recv (data->state, buf, len);
>      if (ret < 0 && gnutls_error_is_fatal(ret) == 1)
>      {



Reply via email to