dovecot-2.2: dns, lib-dns: Added support for async DNS PTR lookups.

dovecot at dovecot.org dovecot at dovecot.org
Fri Jun 28 19:48:48 EEST 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/1fbac590b9d4
changeset: 16576:1fbac590b9d4
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Jun 28 19:48:37 2013 +0300
description:
dns, lib-dns: Added support for async DNS PTR lookups.

diffstat:

 src/dns/dns-client.c     |  13 ++++++++++++-
 src/lib-dns/dns-lookup.c |  48 ++++++++++++++++++++++++++++++++++++++++++------
 src/lib-dns/dns-lookup.h |  12 ++++++++++++
 3 files changed, 66 insertions(+), 7 deletions(-)

diffs (171 lines):

diff -r eaa712530f3f -r 1fbac590b9d4 src/dns/dns-client.c
--- a/src/dns/dns-client.c	Fri Jun 28 19:48:15 2013 +0300
+++ b/src/dns/dns-client.c	Fri Jun 28 19:48:37 2013 +0300
@@ -27,7 +27,8 @@
 
 static int dns_client_input_line(struct dns_client *client, const char *line)
 {
-	struct ip_addr *ips;
+	struct ip_addr *ips, ip;
+	const char *name;
 	unsigned int i, ips_count;
 	int ret;
 
@@ -48,6 +49,16 @@
 					net_ip2addr(&ips[i]), "\n", NULL));
 			}
 		}
+	} else if (strncmp(line, "NAME\t", 5) == 0) {
+		if (net_addr2ip(line+5, &ip) < 0)
+			o_stream_nsend_str(client->output, "-1\n");
+		else if ((ret = net_gethostbyaddr(&ip, &name)) != 0) {
+			o_stream_nsend_str(client->output,
+				t_strdup_printf("%d\n", ret));
+		} else {
+			o_stream_nsend_str(client->output,
+				t_strdup_printf("0 %s\n", name));
+		}
 	} else if (strcmp(line, "QUIT") == 0) {
 		return -1;
 	} else {
diff -r eaa712530f3f -r 1fbac590b9d4 src/lib-dns/dns-lookup.c
--- a/src/lib-dns/dns-lookup.c	Fri Jun 28 19:48:15 2013 +0300
+++ b/src/lib-dns/dns-lookup.c	Fri Jun 28 19:48:37 2013 +0300
@@ -16,6 +16,7 @@
 struct dns_lookup {
 	int fd;
 	char *path;
+	bool ptr_lookup;
 
 	struct istream *input;
 	struct io *io;
@@ -27,6 +28,7 @@
 	struct dns_lookup_result result;
 	struct ip_addr *ips;
 	unsigned int ip_idx;
+	char *name;
 
 	dns_lookup_callback_t *callback;
 	void *context;
@@ -39,6 +41,20 @@
 	struct dns_lookup_result *result = &lookup->result;
 
 	if (result->ips_count == 0) {
+		if (lookup->ptr_lookup) {
+			/* <ret> [<name>] */
+			if (strncmp(line, "0 ", 2) == 0) {
+				result->name = lookup->name =
+					i_strdup(line + 2);
+				result->ret = 0;
+			} else {
+				if (str_to_int(line, &result->ret) < 0) {
+					return -1;
+				}
+				result->error = net_gethosterror(result->ret);
+			}
+			return 1;
+		}
 		/* first line: <ret> <ip count> */
 		if (sscanf(line, "%d %u", &result->ret,
 			   &result->ips_count) == 0)
@@ -119,14 +135,14 @@
 	dns_lookup_free(&lookup);
 }
 
-#undef dns_lookup
-int dns_lookup(const char *host, const struct dns_lookup_settings *set,
-	       dns_lookup_callback_t *callback, void *context,
-	       struct dns_lookup **lookup_r)
+static int
+dns_lookup_common(const char *cmd, bool ptr_lookup,
+		  const struct dns_lookup_settings *set,
+		  dns_lookup_callback_t *callback, void *context,
+		  struct dns_lookup **lookup_r)
 {
 	struct dns_lookup *lookup;
 	struct dns_lookup_result result;
-	const char *cmd;
 	int fd;
 
 	memset(&result, 0, sizeof(result));
@@ -140,7 +156,6 @@
 		return -1;
 	}
 
-	cmd = t_strconcat("IP\t", host, "\n", NULL);
 	if (write_full(fd, cmd, strlen(cmd)) < 0) {
 		result.error = t_strdup_printf("write(%s) failed: %m",
 					       set->dns_client_socket_path);
@@ -150,6 +165,7 @@
 	}
 
 	lookup = i_new(struct dns_lookup, 1);
+	lookup->ptr_lookup = ptr_lookup;
 	lookup->fd = fd;
 	lookup->path = i_strdup(set->dns_client_socket_path);
 	lookup->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE);
@@ -168,6 +184,25 @@
 	return 0;
 }
 
+#undef dns_lookup
+int dns_lookup(const char *host, const struct dns_lookup_settings *set,
+	       dns_lookup_callback_t *callback, void *context,
+	       struct dns_lookup **lookup_r)
+{
+	return dns_lookup_common(t_strconcat("IP\t", host, "\n", NULL), FALSE,
+				 set, callback, context, lookup_r);
+}
+
+#undef dns_lookup_ptr
+int dns_lookup_ptr(const struct ip_addr *ip,
+		   const struct dns_lookup_settings *set,
+		   dns_lookup_callback_t *callback, void *context,
+		   struct dns_lookup **lookup_r)
+{
+	const char *cmd = t_strconcat("NAME\t", net_ip2addr(ip), "\n", NULL);
+	return dns_lookup_common(cmd, TRUE, set, callback, context, lookup_r);
+}
+
 static void dns_lookup_free(struct dns_lookup **_lookup)
 {
 	struct dns_lookup *lookup = *_lookup;
@@ -181,6 +216,7 @@
 	if (close(lookup->fd) < 0)
 		i_error("close(%s) failed: %m", lookup->path);
 
+	i_free(lookup->name);
 	i_free(lookup->ips);
 	i_free(lookup->path);
 	i_free(lookup);
diff -r eaa712530f3f -r 1fbac590b9d4 src/lib-dns/dns-lookup.h
--- a/src/lib-dns/dns-lookup.h	Fri Jun 28 19:48:15 2013 +0300
+++ b/src/lib-dns/dns-lookup.h	Fri Jun 28 19:48:37 2013 +0300
@@ -19,8 +19,11 @@
 	/* how many milliseconds the lookup took. */
 	unsigned int msecs;
 
+	/* for IP lookup: */
 	unsigned int ips_count;
 	const struct ip_addr *ips;
+	/* for PTR lookup: */
+	const char *name;
 };
 
 typedef void dns_lookup_callback_t(const struct dns_lookup_result *result,
@@ -38,6 +41,15 @@
 		CALLBACK_TYPECHECK(callback, void (*)( \
 			const struct dns_lookup_result *, typeof(context))), \
 		set, (dns_lookup_callback_t *)callback, context, lookup_r)
+int dns_lookup_ptr(const struct ip_addr *ip,
+		   const struct dns_lookup_settings *set,
+		   dns_lookup_callback_t *callback, void *context,
+		   struct dns_lookup **lookup_r) ATTR_NULL(4);
+#define dns_lookup_ptr(host, set, callback, context, lookup_r) \
+	dns_lookup_ptr(host + \
+		CALLBACK_TYPECHECK(callback, void (*)( \
+			const struct dns_lookup_result *, typeof(context))), \
+		set, (dns_lookup_callback_t *)callback, context, lookup_r)
 /* Abort the DNS lookup without calling the callback. */
 void dns_lookup_abort(struct dns_lookup **lookup);
 


More information about the dovecot-cvs mailing list