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