dovecot-2.0: Added dns-client service and library for doing asyn...
dovecot at dovecot.org
dovecot at dovecot.org
Sun Jan 31 19:11:26 EET 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/8f9fc7fa7c73
changeset: 10615: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