dovecot-2.2: connection API: Fixed connected() callback to actua...

dovecot at dovecot.org dovecot at dovecot.org
Thu Aug 16 06:09:35 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/deb47efdc006
changeset: 14908:deb47efdc006
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Aug 16 06:09:22 2012 +0300
description:
connection API: Fixed connected() callback to actually allow detecting failed connects.

diffstat:

 src/lib-dict/dict-memcached-ascii.c |   7 ++++---
 src/lib-dict/dict-memcached.c       |   9 +++++----
 src/lib-dict/dict-redis.c           |   6 +++---
 src/lib/connection.c                |  26 ++++++++++++++++++++------
 src/lib/connection.h                |   8 +++++++-
 5 files changed, 39 insertions(+), 17 deletions(-)

diffs (159 lines):

diff -r f5dc8abad16b -r deb47efdc006 src/lib-dict/dict-memcached-ascii.c
--- a/src/lib-dict/dict-memcached-ascii.c	Thu Aug 16 05:41:57 2012 +0300
+++ b/src/lib-dict/dict-memcached-ascii.c	Thu Aug 16 06:09:22 2012 +0300
@@ -285,11 +285,12 @@
 	return 0;
 }
 
-static void memcached_ascii_conn_connected(struct connection *_conn)
+static void
+memcached_ascii_conn_connected(struct connection *_conn, bool success)
 {
 	struct memcached_ascii_connection *conn = (struct memcached_ascii_connection *)_conn;
 
-	if ((errno = net_geterror(_conn->fd_in)) != 0) {
+	if (!success) {
 		i_error("memcached_ascii: connect(%s, %u) failed: %m",
 			net_ip2addr(&conn->dict->ip), conn->dict->port);
 	}
@@ -306,7 +307,7 @@
 static const struct connection_vfuncs memcached_ascii_conn_vfuncs = {
 	.destroy = memcached_ascii_conn_destroy,
 	.input = memcached_ascii_conn_input,
-	.connected = memcached_ascii_conn_connected
+	.client_connected = memcached_ascii_conn_connected
 };
 
 static const char *memcached_ascii_escape_username(const char *username)
diff -r f5dc8abad16b -r deb47efdc006 src/lib-dict/dict-memcached.c
--- a/src/lib-dict/dict-memcached.c	Thu Aug 16 05:41:57 2012 +0300
+++ b/src/lib-dict/dict-memcached.c	Thu Aug 16 06:09:22 2012 +0300
@@ -140,11 +140,12 @@
 		memcached_conn_destroy(_conn);
 }
 
-static void memcached_conn_connected(struct connection *_conn)
+static void memcached_conn_connected(struct connection *_conn, bool success)
 {
-	struct memcached_connection *conn = (struct memcached_connection *)_conn;
+	struct memcached_connection *conn =
+		(struct memcached_connection *)_conn;
 
-	if ((errno = net_geterror(_conn->fd_in)) != 0) {
+	if (!success) {
 		i_error("memcached: connect(%s, %u) failed: %m",
 			net_ip2addr(&conn->dict->ip), conn->dict->port);
 	} else {
@@ -163,7 +164,7 @@
 static const struct connection_vfuncs memcached_conn_vfuncs = {
 	.destroy = memcached_conn_destroy,
 	.input = memcached_conn_input,
-	.connected = memcached_conn_connected
+	.client_connected = memcached_conn_connected
 };
 
 static struct dict *
diff -r f5dc8abad16b -r deb47efdc006 src/lib-dict/dict-redis.c
--- a/src/lib-dict/dict-redis.c	Thu Aug 16 05:41:57 2012 +0300
+++ b/src/lib-dict/dict-redis.c	Thu Aug 16 06:09:22 2012 +0300
@@ -255,11 +255,11 @@
 		redis_conn_destroy(_conn);
 }
 
-static void redis_conn_connected(struct connection *_conn)
+static void redis_conn_connected(struct connection *_conn, bool success)
 {
 	struct redis_connection *conn = (struct redis_connection *)_conn;
 
-	if ((errno = net_geterror(_conn->fd_in)) != 0) {
+	if (!success) {
 		i_error("redis: connect(%s, %u) failed: %m",
 			net_ip2addr(&conn->dict->ip), conn->dict->port);
 	} else {
@@ -278,7 +278,7 @@
 static const struct connection_vfuncs redis_conn_vfuncs = {
 	.destroy = redis_conn_destroy,
 	.input = redis_conn_input,
-	.connected = redis_conn_connected
+	.client_connected = redis_conn_connected
 };
 
 static const char *redis_escape_username(const char *username)
diff -r f5dc8abad16b -r deb47efdc006 src/lib/connection.c
--- a/src/lib/connection.c	Thu Aug 16 05:41:57 2012 +0300
+++ b/src/lib/connection.c	Thu Aug 16 06:09:22 2012 +0300
@@ -132,8 +132,21 @@
 			"VERSION\t%s\t%u\t%u\n", set->service_name_out,
 			set->major_version, set->minor_version));
 	}
-	if (conn->list->v.connected != NULL)
-		conn->list->v.connected(conn);
+}
+
+static void connection_client_connected(struct connection *conn, bool success)
+{
+	i_assert(conn->list->set.client);
+
+	if (success)
+		connection_init_streams(conn);
+	if (conn->list->v.client_connected != NULL)
+		conn->list->v.client_connected(conn, success);
+	if (!success) {
+		conn->disconnect_reason =
+			CONNECTION_DISCONNECT_CONN_CLOSED;
+		conn->list->v.destroy(conn);
+	}
 }
 
 void connection_init_server(struct connection_list *list,
@@ -180,13 +193,14 @@
 	DLLIST_PREPEND(&list->connections, conn);
 }
 
-static void connection_connected(struct connection *conn)
+static void connection_ip_connected(struct connection *conn)
 {
 	io_remove(&conn->io);
 	if (conn->to != NULL)
 		timeout_remove(&conn->to);
 
-	connection_init_streams(conn);
+	errno = net_geterror(conn->fd_in);
+	connection_client_connected(conn, errno == 0);
 }
 
 int connection_client_connect(struct connection *conn)
@@ -207,13 +221,13 @@
 
 	if (conn->port != 0) {
 		conn->io = io_add(conn->fd_out, IO_WRITE,
-				  connection_connected, conn);
+				  connection_ip_connected, conn);
 		if (set->client_connect_timeout_msecs != 0) {
 			conn->to = timeout_add(set->client_connect_timeout_msecs,
 					       connection_connect_timeout, conn);
 		}
 	} else {
-		connection_init_streams(conn);
+		connection_client_connected(conn, TRUE);
 	}
 	return 0;
 }
diff -r f5dc8abad16b -r deb47efdc006 src/lib/connection.h
--- a/src/lib/connection.h	Thu Aug 16 05:41:57 2012 +0300
+++ b/src/lib/connection.h	Thu Aug 16 06:09:22 2012 +0300
@@ -27,7 +27,13 @@
 
 struct connection_vfuncs {
 	void (*destroy)(struct connection *conn);
-	void (*connected)(struct connection *conn);
+	/* For UNIX socket clients this gets called immediately with
+	   success=TRUE, for IP connections it gets called later:
+
+	   If connect() fails, sets success=FALSE and errno. Streams aren't
+	   initialized in that situation either. destroy() is called after
+	   the callback. */
+	void (*client_connected)(struct connection *conn, bool success);
 
 	/* implement one of the input*() methods.
 	   They return 0 = ok, -1 = error, disconnect the client */


More information about the dovecot-cvs mailing list