[Dovecot] [PATCH] net_connect_*(): Wait for fd to complete connect(2) when fd is non-blocking

2011-07-30 Thread SATOH Fumiyasu
Hi,

Dovecot ignores EINPROGRESS on connect(2) for non-blocking fd.
This is wrong. After that, read(2) to fd (or write(2) to fd) fails
with ENOTCONN if the connection of fd is not completed.

The attached patch fixes this problem.

-- 
-- Name: SATOH Fumiyasu (fumiyas @ osstech co jp)
-- Business Home: http://www.OSSTech.co.jp/
-- Personal Home: http://www.SFO.jp/blog/
changeset:   12875:43012b126401
branch:  fumiyas
tag: tip
user:SATOH Fumiyasu 
date:Sat Jul 30 14:17:06 2011 +0900
summary: net_connect_*(): Wait for fd to complete connect(2) when fd is non-blocking

diff -r 86c6f58e5756 -r 43012b126401 src/lib/network.c
--- a/src/lib/network.c	Sat Jul 30 01:21:35 2011 +0900
+++ b/src/lib/network.c	Sat Jul 30 14:17:06 2011 +0900
@@ -5,6 +5,7 @@
 #include "fd-set-nonblock.h"
 #include "time-util.h"
 #include "network.h"
+#include "ioloop.h"
 
 #include 
 #include 
@@ -138,6 +139,11 @@
 	return 0;
 }
 
+static void net_connect_in_progress(struct ioloop *ioloop)
+{
+	io_loop_stop(ioloop);
+}
+
 #ifdef __FreeBSD__
 static int
 net_connect_ip_full_freebsd(const struct ip_addr *ip, unsigned int port,
@@ -207,16 +213,31 @@
 	/* connect */
 	sin_set_ip(&so, ip);
 	sin_set_port(&so, port);
-	ret = connect(fd, &so.sa, SIZEOF_SOCKADDR(so));
+	do {
+		ret = connect(fd, &so.sa, SIZEOF_SOCKADDR(so));
+	} while (ret < 0 && errno == EINTR);
+
+	if (ret >= 0) {
+		return fd;
+	}
 
 #ifndef WIN32
-	if (ret < 0 && errno != EINPROGRESS)
+	if (errno != EINPROGRESS && errno != EALREADY)
 #else
-	if (ret < 0 && WSAGetLastError() != WSAEWOULDBLOCK)
+	if (WSAGetLastError() != WSAEWOULDBLOCK)
 #endif
 	{
-close_keep_errno(fd);
+		close_keep_errno(fd);
 		return -1;
+	} else {
+		struct ioloop *ioloop;
+		struct io *io;
+
+		ioloop = io_loop_create();
+		io = io_add(fd, IO_WRITE, net_connect_in_progress, ioloop);
+		io_loop_run(ioloop);
+		io_remove(&io);
+		io_loop_destroy(&ioloop);
 	}
 
 	return fd;
@@ -286,10 +307,26 @@
 	net_set_nonblock(fd, TRUE);
 
 	/* connect */
-	ret = connect(fd, &sa.sa, sizeof(sa));
-	if (ret < 0 && errno != EINPROGRESS) {
-close_keep_errno(fd);
+	do {
+		ret = connect(fd, &sa.sa, sizeof(sa));
+	} while (ret < 0 && errno == EINTR);
+
+	if (ret >= 0) {
+		return fd;
+	}
+
+	if (errno != EINPROGRESS && errno != EALREADY) {
+		close_keep_errno(fd);
 		return -1;
+	} else {
+		struct ioloop *ioloop;
+		struct io *io;
+
+		ioloop = io_loop_create();
+		io = io_add(fd, IO_WRITE, net_connect_in_progress, ioloop);
+		io_loop_run(ioloop);
+		io_remove(&io);
+		io_loop_destroy(&ioloop);
 	}
 
 	return fd;



Re: [Dovecot] Dovecot 2.0.x + Sendmail 8.14.4 SMTP AUTH not working

2011-07-30 Thread Alexander Dalloz
Am 30.07.2011 00:58, schrieb Serhiy Kolesnyk:

> As I understand Sendmail now can't find Dovecot authentication via
> userdb and that's why a client isn't authenticated. Please help.

Sendmail has never worked against dovecot's sasl implementation. To use
SMTP AUTH with Sendmail you will have to use Cyrus-SASL.

Check your previous setup in detail.

Alexander


Re: [Dovecot] Dovecot 2.0.x + Sendmail 8.14.4 SMTP AUTH not working

2011-07-30 Thread Serhiy Kolesnyk
Yep, I didn't pay enough attention to that. I've setup SMTP AUTH via
cyrus-SASL-sql. Works fine.

I try to do the same with Dovecot's Password verification by SQL
server. Which "default_pass_scheme = " I should set? Password is
stored as plain text in the db table field. Client (Outlook)
authenticates with PLAIN login via POP3s. I guest pass_scheme should
be also set to PLAIN ?


On Sun, Jul 31, 2011 at 1:21 AM, Alexander Dalloz  wrote:
> Am 30.07.2011 00:58, schrieb Serhiy Kolesnyk:
>
>> As I understand Sendmail now can't find Dovecot authentication via
>> userdb and that's why a client isn't authenticated. Please help.
>
> Sendmail has never worked against dovecot's sasl implementation. To use
> SMTP AUTH with Sendmail you will have to use Cyrus-SASL.
>
> Check your previous setup in detail.
>
> Alexander
>


Re: [Dovecot] [PATCH] net_connect_*(): Wait for fd to complete connect(2) when fd is non-blocking

2011-07-30 Thread SATOH Fumiyasu
Hi,

I've regenerated the patch with 'hg export' instead of 'hg log -p'.
(Sorry, I'm a Mercurial newbie.)

At Sun, 31 Jul 2011 01:41:22 +0900,
SATOH Fumiyasu wrote:
> Dovecot ignores EINPROGRESS on connect(2) for non-blocking fd.
> This is wrong. After that, read(2) to fd (or write(2) to fd) fails
> with ENOTCONN if the connection of fd is not completed.
> 
> The attached patch fixes this problem.

-- 
-- Name: SATOH Fumiyasu (fumiyas @ osstech co jp)
-- Business Home: http://www.OSSTech.co.jp/
-- Personal Home: http://www.SFO.jp/blog/
# HG changeset patch
# User SATOH Fumiyasu 
# Date 1312003026 -32400
# Branch fumiyas
# Node ID 43012b1264013ce316a23d530d2f0c44c2f53f15
# Parent  86c6f58e57568c9e6b9320365af612cf26d5b278
net_connect_*(): Wait for fd to complete connect(2) when fd is non-blocking
mode and connect(2) failes with EINPROGRESS or EALREADY.

diff -r 86c6f58e5756 -r 43012b126401 src/lib/network.c
--- a/src/lib/network.c	Sat Jul 30 01:21:35 2011 +0900
+++ b/src/lib/network.c	Sat Jul 30 14:17:06 2011 +0900
@@ -5,6 +5,7 @@
 #include "fd-set-nonblock.h"
 #include "time-util.h"
 #include "network.h"
+#include "ioloop.h"
 
 #include 
 #include 
@@ -138,6 +139,11 @@
 	return 0;
 }
 
+static void net_connect_in_progress(struct ioloop *ioloop)
+{
+	io_loop_stop(ioloop);
+}
+
 #ifdef __FreeBSD__
 static int
 net_connect_ip_full_freebsd(const struct ip_addr *ip, unsigned int port,
@@ -207,16 +213,31 @@
 	/* connect */
 	sin_set_ip(&so, ip);
 	sin_set_port(&so, port);
-	ret = connect(fd, &so.sa, SIZEOF_SOCKADDR(so));
+	do {
+		ret = connect(fd, &so.sa, SIZEOF_SOCKADDR(so));
+	} while (ret < 0 && errno == EINTR);
+
+	if (ret >= 0) {
+		return fd;
+	}
 
 #ifndef WIN32
-	if (ret < 0 && errno != EINPROGRESS)
+	if (errno != EINPROGRESS && errno != EALREADY)
 #else
-	if (ret < 0 && WSAGetLastError() != WSAEWOULDBLOCK)
+	if (WSAGetLastError() != WSAEWOULDBLOCK)
 #endif
 	{
-close_keep_errno(fd);
+		close_keep_errno(fd);
 		return -1;
+	} else {
+		struct ioloop *ioloop;
+		struct io *io;
+
+		ioloop = io_loop_create();
+		io = io_add(fd, IO_WRITE, net_connect_in_progress, ioloop);
+		io_loop_run(ioloop);
+		io_remove(&io);
+		io_loop_destroy(&ioloop);
 	}
 
 	return fd;
@@ -286,10 +307,26 @@
 	net_set_nonblock(fd, TRUE);
 
 	/* connect */
-	ret = connect(fd, &sa.sa, sizeof(sa));
-	if (ret < 0 && errno != EINPROGRESS) {
-close_keep_errno(fd);
+	do {
+		ret = connect(fd, &sa.sa, sizeof(sa));
+	} while (ret < 0 && errno == EINTR);
+
+	if (ret >= 0) {
+		return fd;
+	}
+
+	if (errno != EINPROGRESS && errno != EALREADY) {
+		close_keep_errno(fd);
 		return -1;
+	} else {
+		struct ioloop *ioloop;
+		struct io *io;
+
+		ioloop = io_loop_create();
+		io = io_add(fd, IO_WRITE, net_connect_in_progress, ioloop);
+		io_loop_run(ioloop);
+		io_remove(&io);
+		io_loop_destroy(&ioloop);
 	}
 
 	return fd;