dovecot-2.0-sslstream: Added dns-client service and library for ...

dovecot at dovecot.org dovecot at dovecot.org
Sat Feb 13 03:00:02 EET 2010


details:   http://hg.dovecot.org/dovecot-2.0-sslstream/rev/8f9fc7fa7c73
changeset: 10616:8f9fc7fa7c73
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Jan 31 19:10:38 2010 +0200
description:
Added dns-client service and library for doing async dns lookups.

diffstat:

9 files changed, 447 insertions(+), 1 deletion(-)
configure.in                  |    4 
src/Makefile.am               |    2 
src/dns/Makefile.am           |   14 +++
src/dns/dns-client-settings.c |   47 ++++++++++
src/dns/dns-client.c          |  147 ++++++++++++++++++++++++++++++++
src/lib-dns/Makefile.am       |   17 +++
src/lib-dns/dns-lookup.c      |  184 +++++++++++++++++++++++++++++++++++++++++
src/lib-dns/dns-lookup.h      |   32 +++++++
src/lib-dovecot/Makefile.am   |    1 

diffs (truncated from 523 to 300 lines):

diff -r 45709a87e4b3 -r 8f9fc7fa7c73 configure.in
--- a/configure.in	Sun Jan 31 19:09:44 2010 +0200
+++ b/configure.in	Sun Jan 31 19:10:38 2010 +0200
@@ -2407,7 +2407,7 @@ if test "$want_shared_libs" = "yes"; the
   LIBDOVECOT_STORAGE='$(top_builddir)/src/lib-storage/libdovecot-storage.la'
   LIBDOVECOT_LOGIN='$(top_builddir)/src/login-common/libdovecot-login.la'
 else
-  LIBDOVECOT_DEPS='$(top_builddir)/src/lib-master/libmaster.la $(top_builddir)/src/lib-settings/libsettings.la $(top_builddir)/src/lib-dict/libdict.la $(top_builddir)/src/lib-imap/libimap.la $(top_builddir)/src/lib-mail/libmail.la $(top_builddir)/src/lib-auth/libauth.la $(top_builddir)/src/lib-charset/libcharset.la $(top_builddir)/src/lib/liblib.la'
+  LIBDOVECOT_DEPS='$(top_builddir)/src/lib-master/libmaster.la $(top_builddir)/src/lib-settings/libsettings.la $(top_builddir)/src/lib-dict/libdict.la $(top_builddir)/src/lib-dns/libdns.la $(top_builddir)/src/lib-imap/libimap.la $(top_builddir)/src/lib-mail/libmail.la $(top_builddir)/src/lib-auth/libauth.la $(top_builddir)/src/lib-charset/libcharset.la $(top_builddir)/src/lib/liblib.la'
   LIBDOVECOT="$LIBDOVECOT_DEPS \$(LIBICONV)"
   LIBDOVECOT_STORAGE_LAST='$(top_builddir)/src/lib-storage/list/libstorage_list.la $(top_builddir)/src/lib-storage/index/libstorage_index.la $(top_builddir)/src/lib-storage/libstorage.la $(top_builddir)/src/lib-index/libindex.la'
   LIBDOVECOT_STORAGE_FIRST='$(top_builddir)/src/lib-storage/libstorage_service.la $(top_builddir)/src/lib-storage/register/libstorage_register.la'
@@ -2578,6 +2578,7 @@ src/lib-auth/Makefile
 src/lib-auth/Makefile
 src/lib-charset/Makefile
 src/lib-dict/Makefile
+src/lib-dns/Makefile
 src/lib-imap/Makefile
 src/lib-index/Makefile
 src/lib-lda/Makefile
@@ -2609,6 +2610,7 @@ src/log/Makefile
 src/log/Makefile
 src/lmtp/Makefile
 src/dict/Makefile
+src/dns/Makefile
 src/imap/Makefile
 src/imap-login/Makefile
 src/login-common/Makefile
diff -r 45709a87e4b3 -r 8f9fc7fa7c73 src/Makefile.am
--- a/src/Makefile.am	Sun Jan 31 19:09:44 2010 +0200
+++ b/src/Makefile.am	Sun Jan 31 19:10:38 2010 +0200
@@ -2,6 +2,7 @@ LIBDOVECOT_SUBDIRS = \
 	lib \
 	lib-auth \
 	lib-charset \
+	lib-dns \
 	lib-mail \
 	lib-imap \
 	lib-master \
@@ -21,6 +22,7 @@ SUBDIRS = \
 	anvil \
 	auth \
 	dict \
+	dns \
 	master \
 	login-common \
 	imap-login \
diff -r 45709a87e4b3 -r 8f9fc7fa7c73 src/dns/Makefile.am
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dns/Makefile.am	Sun Jan 31 19:10:38 2010 +0200
@@ -0,0 +1,14 @@
+pkglibexecdir = $(libexecdir)/dovecot
+
+pkglibexec_PROGRAMS = dns-client
+
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src/lib \
+	-I$(top_srcdir)/src/lib-master \
+	-I$(top_srcdir)/src/lib-settings
+
+dns_client_LDADD = $(LIBDOVECOT) $(MODULE_LIBS)
+dns_client_DEPENDENCIES = $(LIBDOVECOT_DEPS)
+dns_client_SOURCES = \
+	dns-client.c \
+	dns-client-settings.c
diff -r 45709a87e4b3 -r 8f9fc7fa7c73 src/dns/dns-client-settings.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dns/dns-client-settings.c	Sun Jan 31 19:10:38 2010 +0200
@@ -0,0 +1,47 @@
+/* Copyright (c) 2010 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "buffer.h"
+#include "settings-parser.h"
+#include "service-settings.h"
+
+#include <stddef.h>
+
+/* <settings checks> */
+static struct file_listener_settings dns_client_unix_listeners_array[] = {
+	{ "dns-client", 0666, "", "" },
+	{ "login/dns-client", 0666, "", "" }
+};
+static struct file_listener_settings *dns_client_unix_listeners[] = {
+	&dns_client_unix_listeners_array[0],
+	&dns_client_unix_listeners_array[1]
+};
+static buffer_t dns_client_unix_listeners_buf = {
+	dns_client_unix_listeners, sizeof(dns_client_unix_listeners), { 0, }
+};
+/* </settings checks> */
+
+struct service_settings dns_client_service_settings = {
+	.name = "dns_client",
+	.protocol = "",
+	.type = "",
+	.executable = "dns-client",
+	.user = "dovecot",
+	.group = "",
+	.privileged_group = "",
+	.extra_groups = "",
+	.chroot = "",
+
+	.drop_priv_before_exec = FALSE,
+
+	.process_min_avail = 0,
+	.process_limit = 0,
+	.client_limit = 1,
+	.service_count = 0,
+	.vsz_limit = -1U,
+
+	.unix_listeners = { { &dns_client_unix_listeners_buf,
+			      sizeof(dns_client_unix_listeners[0]) } },
+	.fifo_listeners = ARRAY_INIT,
+	.inet_listeners = ARRAY_INIT
+};
diff -r 45709a87e4b3 -r 8f9fc7fa7c73 src/dns/dns-client.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dns/dns-client.c	Sun Jan 31 19:10:38 2010 +0200
@@ -0,0 +1,147 @@
+/* Copyright (c) 2010 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "ioloop.h"
+#include "istream.h"
+#include "ostream.h"
+#include "restrict-access.h"
+#include "master-service.h"
+
+#include <unistd.h>
+
+struct dns_client {
+	int fd;
+	struct istream *input;
+	struct ostream *output;
+	struct io *io;
+	struct timeout *to;
+};
+
+#define MAX_INBUF_SIZE 1024
+#define MAX_OUTBUF_SIZE (1024*64)
+#define INPUT_TIMEOUT_MSECS (1000*10)
+
+static struct dns_client *dns_client = NULL;
+
+static void dns_client_destroy(struct dns_client **client);
+
+static int dns_client_input_line(struct dns_client *client, const char *line)
+{
+	struct ip_addr *ips;
+	unsigned int i, ips_count;
+	int ret;
+
+	if (strncmp(line, "IP\t", 3) == 0) {
+		ret = net_gethostbyname(line + 3, &ips, &ips_count);
+		if (ret == 0 && ips_count == 0) {
+			/* shouldn't happen, but fix it anyway.. */
+			ret = NO_ADDRESS;
+		}
+		if (ret != 0) {
+			o_stream_send_str(client->output,
+				t_strdup_printf("%d\n", ret));
+		} else {
+			o_stream_send_str(client->output,
+				t_strdup_printf("0 %u\n", ips_count));
+			for (i = 0; i < ips_count; i++) {
+				o_stream_send_str(client->output, t_strconcat(
+					net_ip2addr(&ips[i]), "\n", NULL));
+			}
+		}
+	} else if (strcmp(line, "QUIT") == 0) {
+		return -1;
+	} else {
+		o_stream_send_str(client->output, "Unknown command\n");
+	}
+
+	if (client->output->overflow)
+		return -1;
+	return 0;
+}
+
+static void dns_client_input(struct dns_client *client)
+{
+	const char *line;
+	int ret = 0;
+
+	o_stream_cork(client->output);
+	while ((line = i_stream_read_next_line(client->input)) != NULL) {
+		if (dns_client_input_line(client, line) < 0) {
+			ret = -1;
+			break;
+		}
+	}
+	o_stream_uncork(client->output);
+	timeout_reset(client->to);
+
+	if (client->input->eof || client->input->stream_errno != 0 || ret < 0)
+		dns_client_destroy(&client);
+}
+
+static void dns_client_timeout(struct dns_client *client)
+{
+	dns_client_destroy(&client);
+}
+
+static struct dns_client *dns_client_create(int fd)
+{
+	struct dns_client *client;
+
+	client = i_new(struct dns_client, 1);
+	client->fd = fd;
+	client->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE);
+	client->output = o_stream_create_fd(fd, MAX_OUTBUF_SIZE, FALSE);
+	client->io = io_add(fd, IO_READ, dns_client_input, client);
+	client->to = timeout_add(INPUT_TIMEOUT_MSECS, dns_client_timeout,
+				 client);
+	return client;
+}
+
+static void dns_client_destroy(struct dns_client **_client)
+{
+	struct dns_client *client = *_client;
+
+	*_client = NULL;
+
+	timeout_remove(&client->to);
+	io_remove(&client->io);
+	i_stream_destroy(&client->input);
+	o_stream_destroy(&client->output);
+	if (close(client->fd) < 0)
+		i_error("close() failed: %m");
+	i_free(client);
+
+	dns_client = NULL;
+	master_service_client_connection_destroyed(master_service);
+}
+
+static void client_connected(const struct master_service_connection *conn)
+{
+	if (dns_client != NULL) {
+		i_error("dns-client must be configured with client_limit=1");
+		(void)close(conn->fd);
+		return;
+	}
+	dns_client = dns_client_create(conn->fd);
+}
+
+int main(int argc, char *argv[])
+{
+	master_service = master_service_init("dns-client", 0,
+					     &argc, &argv, NULL);
+	if (master_getopt(master_service) > 0)
+		return FATAL_DEFAULT;
+
+	master_service_init_log(master_service, "dns-client: ");
+	restrict_access_by_env(NULL, FALSE);
+	restrict_access_allow_coredumps(TRUE);
+
+	master_service_init_finish(master_service);
+
+	master_service_run(master_service, client_connected);
+	if (dns_client != NULL)
+		dns_client_destroy(&dns_client);
+
+	master_service_deinit(&master_service);
+        return 0;
+}
diff -r 45709a87e4b3 -r 8f9fc7fa7c73 src/lib-dns/Makefile.am
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-dns/Makefile.am	Sun Jan 31 19:10:38 2010 +0200
@@ -0,0 +1,17 @@
+noinst_LTLIBRARIES = libdns.la
+
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src/lib
+
+libdns_la_SOURCES = \
+	dns-lookup.c
+
+headers = \
+	dns-lookup.h
+
+if INSTALL_HEADERS
+  pkginc_libdir=$(pkgincludedir)
+  pkginc_lib_HEADERS = $(headers)
+else
+  noinst_HEADERS = $(headers)
+endif
diff -r 45709a87e4b3 -r 8f9fc7fa7c73 src/lib-dns/dns-lookup.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-dns/dns-lookup.c	Sun Jan 31 19:10:38 2010 +0200
@@ -0,0 +1,184 @@
+/* Copyright (c) 2010 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "ioloop.h"
+#include "network.h"
+#include "istream.h"
+#include "write-full.h"
+#include "time-util.h"


More information about the dovecot-cvs mailing list