dovecot-2.0: lmtp proxy: Added support for DNS lookups.

dovecot at dovecot.org dovecot at dovecot.org
Tue Mar 2 11:41:03 EET 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/cc3f6adc1e0b
changeset: 10825:cc3f6adc1e0b
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Mar 02 11:40:52 2010 +0200
description:
lmtp proxy: Added support for DNS lookups.

diffstat:

 src/lib-lda/Makefile.am   |   1 +
 src/lib-lda/lmtp-client.c |  91 +++++++++++++++++++++++++++++++++------------
 src/lib-lda/lmtp-client.h |   8 +++-
 src/lmtp/commands.c       |   1 +
 src/lmtp/lmtp-proxy.c     |  16 ++++++-
 src/lmtp/lmtp-proxy.h     |   3 +-
 src/lmtp/main.c           |   4 ++
 src/lmtp/main.h           |   1 +
 8 files changed, 96 insertions(+), 29 deletions(-)

diffs (truncated from 326 to 300 lines):

diff -r bd28e6f29711 -r cc3f6adc1e0b src/lib-lda/Makefile.am
--- a/src/lib-lda/Makefile.am	Tue Mar 02 11:19:32 2010 +0200
+++ b/src/lib-lda/Makefile.am	Tue Mar 02 11:40:52 2010 +0200
@@ -4,6 +4,7 @@
 	-I$(top_srcdir)/src/lib \
 	-I$(top_srcdir)/src/lib-settings \
 	-I$(top_srcdir)/src/lib-master \
+	-I$(top_srcdir)/src/lib-dns \
 	-I$(top_srcdir)/src/lib-imap \
 	-I$(top_srcdir)/src/lib-mail \
 	-I$(top_srcdir)/src/lib-storage
diff -r bd28e6f29711 -r cc3f6adc1e0b src/lib-lda/lmtp-client.c
--- a/src/lib-lda/lmtp-client.c	Tue Mar 02 11:19:32 2010 +0200
+++ b/src/lib-lda/lmtp-client.c	Tue Mar 02 11:40:52 2010 +0200
@@ -6,11 +6,13 @@
 #include "network.h"
 #include "istream.h"
 #include "ostream.h"
+#include "dns-lookup.h"
 #include "lmtp-client.h"
 
 #include <ctype.h>
 
 #define LMTP_MAX_LINE_LEN 1024
+#define LMTP_CLIENT_DNS_LOOKUP_TIMEOUT_MSECS (60*1000)
 
 enum lmtp_input_state {
 	LMTP_INPUT_STATE_GREET,
@@ -33,10 +35,9 @@
 
 struct lmtp_client {
 	pool_t pool;
-	const char *mail_from;
 	int refcount;
 
-	const char *my_hostname;
+	struct lmtp_client_settings set;
 	const char *host;
 	struct ip_addr ip;
 	unsigned int port;
@@ -71,21 +72,23 @@
 static void lmtp_client_send_rcpts(struct lmtp_client *client);
 
 struct lmtp_client *
-lmtp_client_init(const char *mail_from, const char *my_hostname,
+lmtp_client_init(const struct lmtp_client_settings *set,
 		 lmtp_finish_callback_t *finish_callback, void *context)
 {
 	struct lmtp_client *client;
 	pool_t pool;
 
-	i_assert(*mail_from == '<');
-	i_assert(*my_hostname != '\0');
+	i_assert(*set->mail_from == '<');
+	i_assert(*set->my_hostname != '\0');
 
 	pool = pool_alloconly_create("lmtp client", 512);
 	client = p_new(pool, struct lmtp_client, 1);
 	client->refcount = 1;
 	client->pool = pool;
-	client->mail_from = p_strdup(pool, mail_from);
-	client->my_hostname = p_strdup(pool, my_hostname);
+	client->set.mail_from = p_strdup(pool, set->mail_from);
+	client->set.my_hostname = p_strdup(pool, set->my_hostname);
+	client->set.dns_client_socket_path =
+		p_strdup(pool, set->dns_client_socket_path);
 	client->finish_callback = finish_callback;
 	client->finish_context = context;
 	client->fd = -1;
@@ -319,15 +322,17 @@
 	switch (client->protocol) {
 	case LMTP_CLIENT_PROTOCOL_LMTP:
 		o_stream_send_str(client->output,
-			t_strdup_printf("LHLO %s\r\n", client->my_hostname));
+			t_strdup_printf("LHLO %s\r\n",
+					client->set.my_hostname));
 		break;
 	case LMTP_CLIENT_PROTOCOL_SMTP:
 		o_stream_send_str(client->output,
-			t_strdup_printf("EHLO %s\r\n", client->my_hostname));
+			t_strdup_printf("EHLO %s\r\n",
+					client->set.my_hostname));
 		break;
 	}
 	o_stream_send_str(client->output,
-		t_strdup_printf("MAIL FROM:%s\r\n", client->mail_from));
+		t_strdup_printf("MAIL FROM:%s\r\n", client->set.mail_from));
 	o_stream_uncork(client->output);
 }
 
@@ -466,22 +471,12 @@
 	return ret;
 }
 
-int lmtp_client_connect_tcp(struct lmtp_client *client,
-			    enum lmtp_client_protocol protocol,
-			    const char *host, unsigned int port)
+static int lmtp_client_connect(struct lmtp_client *client)
 {
-	client->host = p_strdup(client->pool, host);
-	client->port = port;
-	client->protocol = protocol;
-
-	if (net_addr2ip(host, &client->ip) < 0) {
-		i_error("lmtp client: %s is not a valid IP", host);
-		return -1;
-	}
-
-	client->fd = net_connect_ip(&client->ip, port, NULL);
+	client->fd = net_connect_ip(&client->ip, client->port, NULL);
 	if (client->fd == -1) {
-		i_error("lmtp client: connect(%s, %u) failed: %m", host, port);
+		i_error("lmtp client: connect(%s, %u) failed: %m",
+			client->host, client->port);
 		return -1;
 	}
 	client->input =
@@ -491,7 +486,55 @@
 	/* we're already sending data in ostream, so can't use IO_WRITE here */
 	client->io = io_add(client->fd, IO_READ,
 			    lmtp_client_wait_connect, client);
+	return 0;
+}
+
+static void lmtp_client_dns_done(const struct dns_lookup_result *result,
+				 struct lmtp_client *client)
+{
+	if (result->ret != 0) {
+		i_error("lmtp client: DNS lookup of %s failed: %s",
+			client->host, result->error);
+		lmtp_client_fail(client, ERRSTR_TEMP_REMOTE_FAILURE
+				 " (DNS lookup)");
+	} else {
+		client->ip = result->ips[0];
+		if (lmtp_client_connect(client) < 0) {
+			lmtp_client_fail(client, ERRSTR_TEMP_REMOTE_FAILURE
+					 " (connect)");
+		}
+	}
+}
+
+int lmtp_client_connect_tcp(struct lmtp_client *client,
+			    enum lmtp_client_protocol protocol,
+			    const char *host, unsigned int port)
+{
+	struct dns_lookup_settings dns_lookup_set;
+
 	client->input_state = LMTP_INPUT_STATE_GREET;
+	client->host = p_strdup(client->pool, host);
+	client->port = port;
+	client->protocol = protocol;
+
+	if (*host == '\0') {
+		i_error("lmtp client: host not given");
+		return -1;
+	}
+
+	memset(&dns_lookup_set, 0, sizeof(dns_lookup_set));
+	dns_lookup_set.dns_client_socket_path =
+		client->set.dns_client_socket_path;
+	dns_lookup_set.timeout_msecs = LMTP_CLIENT_DNS_LOOKUP_TIMEOUT_MSECS;
+
+	if (net_addr2ip(host, &client->ip) < 0) {
+		if (dns_lookup(host, &dns_lookup_set,
+			       lmtp_client_dns_done, client) < 0)
+			return -1;
+	} else {
+		if (lmtp_client_connect(client) < 0)
+			return -1;
+	}
 	return 0;
 }
 
diff -r bd28e6f29711 -r cc3f6adc1e0b src/lib-lda/lmtp-client.h
--- a/src/lib-lda/lmtp-client.h	Tue Mar 02 11:19:32 2010 +0200
+++ b/src/lib-lda/lmtp-client.h	Tue Mar 02 11:40:52 2010 +0200
@@ -10,6 +10,12 @@
 	LMTP_CLIENT_PROTOCOL_SMTP
 };
 
+struct lmtp_client_settings {
+	const char *my_hostname;
+	const char *mail_from;
+	const char *dns_client_socket_path;
+};
+
 /* reply contains the reply coming from remote server, or NULL
    if it's a connection error. */
 typedef void lmtp_callback_t(bool success, const char *reply, void *context);
@@ -18,7 +24,7 @@
 typedef void lmtp_finish_callback_t(void *context);
 
 struct lmtp_client *
-lmtp_client_init(const char *mail_from, const char *my_hostname,
+lmtp_client_init(const struct lmtp_client_settings *set,
 		 lmtp_finish_callback_t *finish_callback, void *context);
 void lmtp_client_deinit(struct lmtp_client **client);
 
diff -r bd28e6f29711 -r cc3f6adc1e0b src/lmtp/commands.c
--- a/src/lmtp/commands.c	Tue Mar 02 11:19:32 2010 +0200
+++ b/src/lmtp/commands.c	Tue Mar 02 11:40:52 2010 +0200
@@ -251,6 +251,7 @@
 
 	if (client->proxy == NULL) {
 		client->proxy = lmtp_proxy_init(client->set->hostname,
+						dns_client_socket_path,
 						client->output);
 		if (client->mail_body_8bitmime)
 			args = " BODY=8BITMIME";
diff -r bd28e6f29711 -r cc3f6adc1e0b src/lmtp/lmtp-proxy.c
--- a/src/lmtp/lmtp-proxy.c	Tue Mar 02 11:19:32 2010 +0200
+++ b/src/lmtp/lmtp-proxy.c	Tue Mar 02 11:40:52 2010 +0200
@@ -35,6 +35,8 @@
 struct lmtp_proxy {
 	pool_t pool;
 	const char *mail_from, *my_hostname;
+	const char *dns_client_socket_path;
+
 	ARRAY_DEFINE(connections, struct lmtp_proxy_connection *);
 	ARRAY_DEFINE(rcpt_to, struct lmtp_proxy_recipient *);
 	unsigned int next_data_reply_idx;
@@ -59,7 +61,8 @@
 static void lmtp_proxy_data_input(struct lmtp_proxy *proxy);
 
 struct lmtp_proxy *
-lmtp_proxy_init(const char *my_hostname, struct ostream *client_output)
+lmtp_proxy_init(const char *my_hostname, const char *dns_client_socket_path,
+		struct ostream *client_output)
 {
 	struct lmtp_proxy *proxy;
 	pool_t pool;
@@ -71,6 +74,7 @@
 	proxy->pool = pool;
 	proxy->my_hostname = p_strdup(pool, my_hostname);
 	proxy->client_output = client_output;
+	proxy->dns_client_socket_path = p_strdup(pool, dns_client_socket_path);
 	i_array_init(&proxy->rcpt_to, 32);
 	i_array_init(&proxy->connections, 32);
 	return proxy;
@@ -121,6 +125,7 @@
 			  const struct lmtp_proxy_settings *set)
 {
 	struct lmtp_proxy_connection *const *conns, *conn;
+	struct lmtp_client_settings client_set;
 
 	i_assert(set->timeout_msecs > 0);
 
@@ -132,14 +137,19 @@
 			return conn;
 	}
 
+	memset(&client_set, 0, sizeof(client_set));
+	client_set.mail_from = proxy->mail_from;
+	client_set.my_hostname = proxy->my_hostname;
+	client_set.dns_client_socket_path = proxy->dns_client_socket_path;
+
 	conn = p_new(proxy->pool, struct lmtp_proxy_connection, 1);
 	conn->proxy = proxy;
 	conn->set.host = p_strdup(proxy->pool, set->host);
 	conn->set.port = set->port;
 	conn->set.timeout_msecs = set->timeout_msecs;
 	array_append(&proxy->connections, &conn, 1);
-	conn->client = lmtp_client_init(proxy->mail_from, proxy->my_hostname,
-					lmtp_conn_finish, conn);
+
+	conn->client = lmtp_client_init(&client_set, lmtp_conn_finish, conn);
 	if (lmtp_client_connect_tcp(conn->client, set->protocol,
 				    conn->set.host, conn->set.port) < 0)
 		conn->failed = TRUE;
diff -r bd28e6f29711 -r cc3f6adc1e0b src/lmtp/lmtp-proxy.h
--- a/src/lmtp/lmtp-proxy.h	Tue Mar 02 11:19:32 2010 +0200
+++ b/src/lmtp/lmtp-proxy.h	Tue Mar 02 11:40:52 2010 +0200
@@ -14,7 +14,8 @@
 typedef void lmtp_proxy_finish_callback_t(bool timeout, void *context);
 
 struct lmtp_proxy *
-lmtp_proxy_init(const char *my_hostname, struct ostream *client_output);
+lmtp_proxy_init(const char *my_hostname, const char *dns_client_socket_path,
+		struct ostream *client_output);
 void lmtp_proxy_deinit(struct lmtp_proxy **proxy);
 
 /* Set the "MAIL FROM:" line, including <> and options */
diff -r bd28e6f29711 -r cc3f6adc1e0b src/lmtp/main.c
--- a/src/lmtp/main.c	Tue Mar 02 11:19:32 2010 +0200
+++ b/src/lmtp/main.c	Tue Mar 02 11:40:52 2010 +0200
@@ -4,6 +4,7 @@
 #include "array.h"
 #include "ioloop.h"
 #include "hostpid.h"
+#include "abspath.h"
 #include "restrict-access.h"
 #include "fd-close-on-exec.h"
 #include "master-service.h"
@@ -18,11 +19,13 @@
 #include <stdlib.h>
 #include <unistd.h>
 
+#define DNS_CLIENT_SOCKET_PATH "dns-client"
 #define LMTP_MASTER_FIRST_LISTEN_FD 3
 


More information about the dovecot-cvs mailing list