Mercurial > dovecot > core-2.2
changeset 14908:deb47efdc006
connection API: Fixed connected() callback to actually allow detecting failed connects.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 16 Aug 2012 06:09:22 +0300 |
parents | f5dc8abad16b |
children | 7436df9a9922 |
files | src/lib-dict/dict-memcached-ascii.c src/lib-dict/dict-memcached.c src/lib-dict/dict-redis.c src/lib/connection.c src/lib/connection.h |
diffstat | 5 files changed, 39 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- 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)
--- 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 *
--- 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)
--- 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; }
--- 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 */