[evolution-data-server/gnome-3-18] Bug 552425 - [SMTP] Try to reconnect on connection lost during AUTH command



commit 3fc24c8d5fee270e384ee5152a9f18b82942066e
Author: Milan Crha <mcrha redhat com>
Date:   Fri Sep 25 08:26:42 2015 +0200

    Bug 552425 - [SMTP] Try to reconnect on connection lost during AUTH command

 camel/camel-stream-buffer.c                 |    2 +-
 camel/providers/smtp/camel-smtp-transport.c |   43 ++++++++++++++++++++++++++-
 2 files changed, 43 insertions(+), 2 deletions(-)
---
diff --git a/camel/camel-stream-buffer.c b/camel/camel-stream-buffer.c
index 730778f..e001136 100644
--- a/camel/camel-stream-buffer.c
+++ b/camel/camel-stream-buffer.c
@@ -498,7 +498,7 @@ camel_stream_buffer_read_line (CamelStreamBuffer *sbf,
                nread = camel_stream_buffer_gets (
                        sbf, (gchar *) p, sbf->priv->linesize -
                        (p - sbf->priv->linebuf), cancellable, &local_error);
-               if (nread <=0) {
+               if (nread <= 0) {
                        if (p > sbf->priv->linebuf)
                                break;
                        if (local_error)
diff --git a/camel/providers/smtp/camel-smtp-transport.c b/camel/providers/smtp/camel-smtp-transport.c
index cba3c8b..d4bfb1b 100644
--- a/camel/providers/smtp/camel-smtp-transport.c
+++ b/camel/providers/smtp/camel-smtp-transport.c
@@ -64,6 +64,16 @@ enum {
        PROP_HOST_REACHABLE
 };
 
+#define CAMEL_SMTP_TRANSPORT_ERROR camel_smtp_transport_error_quark ()
+
+GQuark camel_smtp_transport_error_quark (void);
+
+G_DEFINE_QUARK (camel-smtp-transport-error-quark, camel_smtp_transport_error)
+
+enum {
+       CAMEL_SMTP_TRANSPORT_ERROR_CONNECTION_LOST
+};
+
 /* support prototypes */
 static GHashTable *    esmtp_get_authtypes     (const guchar *buffer);
 static gboolean                smtp_helo               (CamelSmtpTransport *transport,
@@ -527,9 +537,36 @@ smtp_transport_connect_sync (CamelService *service,
                session = camel_service_ref_session (service);
 
                if (g_hash_table_lookup (transport->authtypes, mechanism)) {
+                       gint tries = 0;
+                       GError *local_error = NULL;
+
                        success = camel_session_authenticate_sync (
                                session, service, mechanism,
-                               cancellable, error);
+                               cancellable, &local_error);
+
+                       while (g_error_matches (local_error, CAMEL_SMTP_TRANSPORT_ERROR, 
CAMEL_SMTP_TRANSPORT_ERROR_CONNECTION_LOST) &&
+                              !g_cancellable_is_cancelled (cancellable) && tries < 3) {
+                               d (fprintf (stderr, "[SMTP] reconnecting after dropped connection, %d. 
try\r\n", tries + 1));
+
+                               tries++;
+
+                               g_clear_error (&local_error);
+
+                               transport->connected = FALSE;
+                               g_mutex_lock (&transport->stream_lock);
+                               g_clear_object (&transport->istream);
+                               g_clear_object (&transport->ostream);
+                               g_mutex_unlock (&transport->stream_lock);
+
+                               success = connect_to_server (service, cancellable, error);
+                               if (success)
+                                       success = camel_session_authenticate_sync (
+                                               session, service, mechanism,
+                                               cancellable, &local_error);
+                       }
+
+                       if (local_error)
+                               g_propagate_error (error, local_error);
                } else {
                        g_set_error (
                                error, CAMEL_SERVICE_ERROR,
@@ -668,6 +705,10 @@ smtp_transport_authenticate_sync (CamelService *service,
 
        while (!camel_sasl_get_authenticated (sasl)) {
                if (!respbuf) {
+                       /* It's an EOF state on the input stream. */
+                       if (error && !*error)
+                               g_set_error (error, CAMEL_SMTP_TRANSPORT_ERROR,
+                                       CAMEL_SMTP_TRANSPORT_ERROR_CONNECTION_LOST, _("Connection 
cancelled"));
                        g_prefix_error (error, _("AUTH command failed: "));
                        transport->connected = FALSE;
                        goto lose;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]