summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2015-09-25 08:26:42 +0200
committerMilan Crha <mcrha@redhat.com>2015-09-25 08:26:42 +0200
commit3fc24c8d5fee270e384ee5152a9f18b82942066e (patch)
tree827133ea290b69fc9edda56a0341aa658939292b
parentd7e018e28d1d32a18764021b792ef8ba96181649 (diff)
downloadevolution-data-server-3fc24c8d5fee270e384ee5152a9f18b82942066e.tar.gz
Bug 552425 - [SMTP] Try to reconnect on connection lost during AUTH command
-rw-r--r--camel/camel-stream-buffer.c2
-rw-r--r--camel/providers/smtp/camel-smtp-transport.c43
2 files changed, 43 insertions, 2 deletions
diff --git a/camel/camel-stream-buffer.c b/camel/camel-stream-buffer.c
index 730778f24..e00113654 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 cba3c8b79..d4bfb1ba6 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;