dovecot-1.0: FreeBSD: If connect() fails with EADDRINUSE or EACC...

dovecot at dovecot.org dovecot at dovecot.org
Wed Nov 28 16:24:29 EET 2007


details:   http://hg.dovecot.org/dovecot-1.0/rev/046ed83ff29b
changeset: 5468:046ed83ff29b
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Nov 28 16:24:25 2007 +0200
description:
FreeBSD: If connect() fails with EADDRINUSE or EACCES, try again max. 3 times.

diffstat:

1 file changed, 18 insertions(+), 2 deletions(-)
src/lib/network.c |   20 ++++++++++++++++++--

diffs (37 lines):

diff -r e320272af290 -r 046ed83ff29b src/lib/network.c
--- a/src/lib/network.c	Wed Nov 28 16:08:59 2007 +0200
+++ b/src/lib/network.c	Wed Nov 28 16:24:25 2007 +0200
@@ -107,7 +107,7 @@ int net_connect_ip(const struct ip_addr 
 		   const struct ip_addr *my_ip)
 {
 	union sockaddr_union so;
-	int fd, ret, opt = 1;
+	int fd, ret, try, opt = 1;
 
 	if (my_ip != NULL && ip->family != my_ip->family) {
 		i_warning("net_connect_ip(): ip->family != my_ip->family");
@@ -143,7 +143,23 @@ int net_connect_ip(const struct ip_addr 
 	/* connect */
 	sin_set_ip(&so, ip);
 	sin_set_port(&so, port);
-	ret = connect(fd, &so.sa, SIZEOF_SOCKADDR(so));
+	for (try = 0;;) {
+		ret = connect(fd, &so.sa, SIZEOF_SOCKADDR(so));
+		if (ret != -1 || ++try == 3)
+			break;
+#ifdef __FreeBSD__
+		if (errno == EADDRINUSE) {
+			/* busy, retrying hopefully helps */
+			continue;
+		}
+		if (errno == EACCES) {
+			/* pf may cause this if another connection used
+			   the same port recently. try again. */
+			continue;
+		}
+#endif
+		break;
+	}
 
 #ifndef WIN32
 	if (ret < 0 && errno != EINPROGRESS)


More information about the dovecot-cvs mailing list