dovecot-2.0: master: If inet listener uses DNS name, which retur...

dovecot at dovecot.org dovecot at dovecot.org
Tue May 4 19:21:02 EEST 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/1ea46423cfd0
changeset: 11263:1ea46423cfd0
user:      Timo Sirainen <tss at iki.fi>
date:      Tue May 04 19:21:00 2010 +0300
description:
master: If inet listener uses DNS name, which returns multiple IPs, listen in all of them.

diffstat:

 src/master/service.c |  46 +++++++++++++++++++++++++++++-----------------
 1 files changed, 29 insertions(+), 17 deletions(-)

diffs (109 lines):

diff -r a4614f53d298 -r 1ea46423cfd0 src/master/service.c
--- a/src/master/service.c	Tue May 04 18:47:13 2010 +0300
+++ b/src/master/service.c	Tue May 04 19:21:00 2010 +0300
@@ -54,7 +54,8 @@
 }
 
 static int
-resolve_ip(const char *address, struct ip_addr *ip_r, const char **error_r)
+resolve_ip(const char *address, const struct ip_addr **ips_r,
+	   unsigned int *ips_count_r, const char **error_r)
 {
 	struct ip_addr *ip_list;
 	unsigned int ips_count;
@@ -62,13 +63,19 @@
 
 	if (address == NULL || strcmp(address, "*") == 0) {
 		/* IPv4 any */
-		net_get_ip_any4(ip_r);
+		ip_list = t_new(struct ip_addr, 1);
+		net_get_ip_any4(ip_list);
+		*ips_r = ip_list;
+		*ips_count_r = 1;
 		return 0;
 	}
 
 	if (strcmp(address, "::") == 0) {
 		/* IPv6 any */
-		net_get_ip_any6(ip_r);
+		ip_list = t_new(struct ip_addr, 1);
+		net_get_ip_any6(ip_list);
+		*ips_r = ip_list;
+		*ips_count_r = 1;
 		return 0;
 	}
 
@@ -84,20 +91,17 @@
 		*error_r = t_strdup_printf("No IPs for address: %s", address);
 		return -1;
 	}
-	if (ips_count > 1) {
-		*error_r = t_strdup_printf("Multiple IPs for address: %s",
-					   address);
-		return -1;
-	}
 
-	*ip_r = ip_list[0];
+	*ips_r = ip_list;
+	*ips_count_r = ips_count;
 	return 0;
 }
 
 static struct service_listener *
 service_create_one_inet_listener(struct service *service,
 				 const struct inet_listener_settings *set,
-				 const char *address, const char **error_r)
+				 const char *address, const struct ip_addr *ip,
+				 const char **error_r)
 {
 	struct service_listener *l;
 
@@ -108,11 +112,9 @@
 	l->type = SERVICE_LISTENER_INET;
 	l->fd = -1;
 	l->set.inetset.set = set;
+	l->set.inetset.ip = *ip;
 	l->inet_address = p_strdup(service->list->pool, address);
 
-	if (resolve_ip(address, &l->set.inetset.ip, error_r) < 0)
-		return NULL;
-
 	if (set->port > 65535) {
 		*error_r = t_strdup_printf("Invalid port: %u", set->port);
 		return NULL;
@@ -128,6 +130,8 @@
 {
 	static struct service_listener *l;
 	const char *const *tmp, *addresses;
+	const struct ip_addr *ips;
+	unsigned int i, ips_count;
 	bool ssl_disabled = strcmp(service->set->master_set->ssl, "no") == 0;
 
 	if (set->port == 0) {
@@ -144,14 +148,22 @@
 
 	tmp = t_strsplit_spaces(addresses, ", ");
 	for (; *tmp != NULL; tmp++) {
+		const char *address = *tmp;
+
 		if (set->ssl && ssl_disabled)
 			continue;
 
-		l = service_create_one_inet_listener(service, set, *tmp,
-						     error_r);
-		if (l == NULL)
+		if (resolve_ip(address, &ips, &ips_count, error_r) < 0)
 			return -1;
-		array_append(&service->listeners, &l, 1);
+
+		for (i = 0; i < ips_count; i++) {
+			l = service_create_one_inet_listener(service, set,
+							     address, &ips[i],
+							     error_r);
+			if (l == NULL)
+				return -1;
+			array_append(&service->listeners, &l, 1);
+		}
 		service->have_inet_listeners = TRUE;
 	}
 	return 0;


More information about the dovecot-cvs mailing list