dovecot-2.2: lib-dns: dns_lookup() returns now the lookup struct...

dovecot at dovecot.org dovecot at dovecot.org
Mon Feb 27 11:34:05 EET 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/f5aa38f0a9ac
changeset: 14222:f5aa38f0a9ac
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Feb 27 11:33:34 2012 +0200
description:
lib-dns: dns_lookup() returns now the lookup struct, and it can be aborted.
Changed all dns_lookup() users also to abort the lookup when needed
(previously it probably would have just accessed freed memory and crash).

diffstat:

 src/auth/auth-request.c                    |  25 +++++++++++++++----------
 src/auth/auth-request.h                    |   1 +
 src/lib-dns/dns-lookup.c                   |   8 ++++++++
 src/lib-dns/dns-lookup.h                   |  13 +++++++++++--
 src/lib-imap-client/imapc-connection.c     |  10 +++++++---
 src/lib-lda/lmtp-client.c                  |   8 +++++++-
 src/lib-storage/index/pop3c/pop3c-client.c |  14 ++++++++++----
 7 files changed, 59 insertions(+), 20 deletions(-)

diffs (279 lines):

diff -r 31119136ee6e -r f5aa38f0a9ac src/auth/auth-request.c
--- a/src/auth/auth-request.c	Mon Feb 27 10:36:09 2012 +0200
+++ b/src/auth/auth-request.c	Mon Feb 27 11:33:34 2012 +0200
@@ -33,6 +33,12 @@
 #define AUTH_DNS_WARN_MSECS 500
 #define CACHED_PASSWORD_SCHEME "SHA1"
 
+struct auth_request_proxy_dns_lookup_ctx {
+	struct auth_request *request;
+	auth_request_proxy_cb_t *callback;
+	struct dns_lookup *dns_lookup;
+};
+
 unsigned int auth_request_state_count[AUTH_REQUEST_STATE_MAX];
 
 static void get_log_prefix(string_t *str, struct auth_request *auth_request,
@@ -167,6 +173,8 @@
 			    strlen(request->mech_password));
 	}
 
+	if (request->dns_lookup_ctx != NULL)
+		dns_lookup_abort(&request->dns_lookup_ctx->dns_lookup);
 	if (request->to_abort != NULL)
 		timeout_remove(&request->to_abort);
 	if (request->to_penalty != NULL)
@@ -1480,20 +1488,17 @@
 	}
 }
 
-struct auth_request_proxy_dns_lookup_ctx {
-	struct auth_request *request;
-	auth_request_proxy_cb_t *callback;
-};
-
 static void
 auth_request_proxy_dns_callback(const struct dns_lookup_result *result,
-				void *context)
+				struct auth_request_proxy_dns_lookup_ctx *ctx)
 {
-	struct auth_request_proxy_dns_lookup_ctx *ctx = context;
 	struct auth_request *request = ctx->request;
 	const char *host;
 	unsigned int i;
 
+	request->dns_lookup_ctx = NULL;
+	ctx->dns_lookup = NULL;
+
 	host = auth_stream_reply_find(request->extra_fields, "host");
 	i_assert(host != NULL);
 
@@ -1522,7 +1527,6 @@
 	}
 	if (ctx->callback != NULL)
 		ctx->callback(result->ret == 0, request);
-	i_free(ctx);
 }
 
 static int auth_request_proxy_host_lookup(struct auth_request *request,
@@ -1557,10 +1561,11 @@
 		}
 	}
 
-	ctx = i_new(struct auth_request_proxy_dns_lookup_ctx, 1);
+	ctx = p_new(request->pool, struct auth_request_proxy_dns_lookup_ctx, 1);
 	ctx->request = request;
 
-	if (dns_lookup(host, &dns_set, auth_request_proxy_dns_callback, ctx) < 0) {
+	if (dns_lookup(host, &dns_set, auth_request_proxy_dns_callback, ctx,
+		       &ctx->dns_lookup) < 0) {
 		/* failed early */
 		request->internal_failure = TRUE;
 		auth_request_proxy_finish_failure(request);
diff -r 31119136ee6e -r f5aa38f0a9ac src/auth/auth-request.h
--- a/src/auth/auth-request.h	Mon Feb 27 10:36:09 2012 +0200
+++ b/src/auth/auth-request.h	Mon Feb 27 11:33:34 2012 +0200
@@ -55,6 +55,7 @@
 	struct auth_stream_reply *extra_cache_fields;
 	/* the whole userdb result reply */
 	struct auth_stream_reply *userdb_reply;
+	struct auth_request_proxy_dns_lookup_ctx *dns_lookup_ctx;
 
 	const struct mech_module *mech;
 	const struct auth_settings *set;
diff -r 31119136ee6e -r f5aa38f0a9ac src/lib-dns/dns-lookup.c
--- a/src/lib-dns/dns-lookup.c	Mon Feb 27 10:36:09 2012 +0200
+++ b/src/lib-dns/dns-lookup.c	Mon Feb 27 11:33:34 2012 +0200
@@ -121,6 +121,7 @@
 
 #undef dns_lookup
 int dns_lookup(const char *host, const struct dns_lookup_settings *set,
+	       struct dns_lookup **lookup_r,
 	       dns_lookup_callback_t *callback, void *context)
 {
 	struct dns_lookup *lookup;
@@ -162,6 +163,8 @@
 	lookup->context = context;
 	if (gettimeofday(&lookup->start_time, NULL) < 0)
 		i_fatal("gettimeofday() failed: %m");
+
+	*lookup_r = lookup;
 	return 0;
 }
 
@@ -182,3 +185,8 @@
 	i_free(lookup->path);
 	i_free(lookup);
 }
+
+void dns_lookup_abort(struct dns_lookup **lookup)
+{
+	dns_lookup_free(lookup);
+}
diff -r 31119136ee6e -r f5aa38f0a9ac src/lib-dns/dns-lookup.h
--- a/src/lib-dns/dns-lookup.h	Mon Feb 27 10:36:09 2012 +0200
+++ b/src/lib-dns/dns-lookup.h	Mon Feb 27 11:33:34 2012 +0200
@@ -1,6 +1,8 @@
 #ifndef DNS_LOOKUP_H
 #define DNS_LOOKUP_H
 
+struct dns_lookup;
+
 struct dns_lookup_settings {
 	const char *dns_client_socket_path;
 	unsigned int timeout_msecs;
@@ -22,11 +24,18 @@
 typedef void dns_lookup_callback_t(const struct dns_lookup_result *result,
 				   void *context);
 
+/* Do asynchronous DNS lookup via dns-client UNIX socket. Returns 0 if lookup
+   started, -1 if there was an error communicating with the UNIX socket.
+   When failing with -1, the callback is called before returning from the
+   function. */
 int dns_lookup(const char *host, const struct dns_lookup_settings *set,
+	       struct dns_lookup **lookup_r,
 	       dns_lookup_callback_t *callback, void *context);
-#define dns_lookup(host, set, callback, context) \
+#define dns_lookup(host, set, callback, context, lookup_r) \
 	CONTEXT_CALLBACK2(dns_lookup, dns_lookup_callback_t, \
 			  callback, const struct dns_lookup_result *, \
-			  context, host, set)
+			  context, host, set, lookup_r)
+/* Abort the DNS lookup without calling the callback. */
+void dns_lookup_abort(struct dns_lookup **lookup);
 
 #endif
diff -r 31119136ee6e -r f5aa38f0a9ac src/lib-imap-client/imapc-connection.c
--- a/src/lib-imap-client/imapc-connection.c	Mon Feb 27 10:36:09 2012 +0200
+++ b/src/lib-imap-client/imapc-connection.c	Mon Feb 27 11:33:34 2012 +0200
@@ -86,6 +86,7 @@
 	struct imap_parser *parser;
 	struct timeout *to;
 	struct timeout *to_output;
+	struct dns_lookup *dns_lookup;
 
 	struct ssl_iostream *ssl_iostream;
 
@@ -352,6 +353,8 @@
 	if (conn->client->set.debug)
 		i_debug("imapc(%s): Disconnected", conn->name);
 
+	if (conn->dns_lookup != NULL)
+		dns_lookup_abort(&conn->dns_lookup);
 	imapc_connection_lfiles_free(conn);
 	imapc_connection_literal_reset(&conn->literal);
 	if (conn->to != NULL)
@@ -1315,9 +1318,9 @@
 
 static void
 imapc_connection_dns_callback(const struct dns_lookup_result *result,
-			      void *context)
+			      struct imapc_connection *conn)
 {
-	struct imapc_connection *conn = context;
+	conn->dns_lookup = NULL;
 
 	if (result->ret != 0) {
 		i_error("imapc(%s): dns_lookup(%s) failed: %s",
@@ -1385,7 +1388,8 @@
 
 	if (conn->ips_count == 0) {
 		(void)dns_lookup(conn->client->set.host, &dns_set,
-				 imapc_connection_dns_callback, conn);
+				 imapc_connection_dns_callback, conn,
+				 &conn->dns_lookup);
 	} else {
 		imapc_connection_connect_next_ip(conn);
 	}
diff -r 31119136ee6e -r f5aa38f0a9ac src/lib-lda/lmtp-client.c
--- a/src/lib-lda/lmtp-client.c	Mon Feb 27 10:36:09 2012 +0200
+++ b/src/lib-lda/lmtp-client.c	Mon Feb 27 11:33:34 2012 +0200
@@ -49,6 +49,7 @@
 	string_t *input_multiline;
 	const char **xclient_args;
 
+	struct dns_lookup *dns_lookup;
 	struct istream *input;
 	struct ostream *output;
 	struct io *io;
@@ -107,6 +108,8 @@
 
 void lmtp_client_close(struct lmtp_client *client)
 {
+	if (client->dns_lookup != NULL)
+		dns_lookup_abort(&client->dns_lookup);
 	if (client->io != NULL)
 		io_remove(&client->io);
 	if (client->input != NULL)
@@ -600,6 +603,8 @@
 static void lmtp_client_dns_done(const struct dns_lookup_result *result,
 				 struct lmtp_client *client)
 {
+	client->dns_lookup = NULL;
+
 	if (result->ret != 0) {
 		i_error("lmtp client: DNS lookup of %s failed: %s",
 			client->host, result->error);
@@ -651,7 +656,8 @@
 		client->ip = ips[0];
 	} else {
 		if (dns_lookup(host, &dns_lookup_set,
-			       lmtp_client_dns_done, client) < 0)
+			       lmtp_client_dns_done, client,
+			       &client->dns_lookup) < 0)
 			return -1;
 		return 0;
 	}
diff -r 31119136ee6e -r f5aa38f0a9ac src/lib-storage/index/pop3c/pop3c-client.c
--- a/src/lib-storage/index/pop3c/pop3c-client.c	Mon Feb 27 10:36:09 2012 +0200
+++ b/src/lib-storage/index/pop3c/pop3c-client.c	Mon Feb 27 11:33:34 2012 +0200
@@ -50,6 +50,7 @@
 	struct ostream *output, *raw_output;
 	struct ssl_iostream *ssl_iostream;
 	struct timeout *to;
+	struct dns_lookup *dns_lookup;
 
 	enum pop3c_client_state state;
 	enum pop3c_capability capabilities;
@@ -66,7 +67,8 @@
 };
 
 static void
-pop3c_dns_callback(const struct dns_lookup_result *result, void *context);
+pop3c_dns_callback(const struct dns_lookup_result *result,
+		   struct pop3c_client *client);
 
 struct pop3c_client *
 pop3c_client_init(const struct pop3c_client_settings *set)
@@ -134,6 +136,8 @@
 	if (client->running)
 		io_loop_stop(current_ioloop);
 
+	if (client->dns_lookup != NULL)
+		dns_lookup_abort(&client->dns_lookup);
 	if (client->to != NULL)
 		timeout_remove(&client->to);
 	if (client->io != NULL)
@@ -215,7 +219,8 @@
 			client->set.dns_client_socket_path;
 		dns_set.timeout_msecs = POP3C_DNS_LOOKUP_TIMEOUT_MSECS;
 		(void)dns_lookup(client->set.host, &dns_set,
-				 pop3c_dns_callback, client);
+				 pop3c_dns_callback, client,
+				 &client->dns_lookup);
 	} else if (client->to == NULL) {
 		client->to = timeout_add(POP3C_COMMAND_TIMEOUT_MSECS,
 					 pop3c_client_timeout, client);
@@ -542,9 +547,10 @@
 }
 
 static void
-pop3c_dns_callback(const struct dns_lookup_result *result, void *context)
+pop3c_dns_callback(const struct dns_lookup_result *result,
+		   struct pop3c_client *client)
 {
-	struct pop3c_client *client = context;
+	client->dns_lookup = NULL;
 
 	if (result->ret != 0) {
 		i_error("pop3c(%s): dns_lookup() failed: %s",


More information about the dovecot-cvs mailing list