[Dovecot] [PATCH] net_connect_*(): Wait for fd to complete connect(2) when fd is non-blocking
SATOH Fumiyasu
fumiyas at osstech.jp
Mon Aug 15 10:41:04 EEST 2011
At Wed, 10 Aug 2011 20:37:46 +0300,
Timo Sirainen wrote:
> On 2.8.2011, at 5.25, 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.
>
> If you do that, then there's no point in making the socket
> non-blocking before connect().
Linux connect(2) manpage said:
EINPROGRESS
The socket is nonblocking and the connection
cannot be completed immediately. It is pos-
sible to select(2) or poll(2) for completion
by selecting the socket for writing. After
select(2) indicates writability, use get-
sockopt(2) to read the SO_ERROR option at
level SOL_SOCKET to determine whether con-
nect() completed successfully (SO_ERROR is
zero) or unsuccessfully (SO_ERROR is one of
the usual error codes listed here, explain-
ing the reason for the failure).
Solaris 10 connect(3SOCKET) manpage said:
EINPROGRESS The socket is non-blocking,
and the connection cannot
be completed immediately.
You can use select(3C) to
complete the connection by
selecting the socket for
writing.
Windows connect function document said
(http://msdn.microsoft.com/en-us/library/ms737625%28v=vs.85%29.aspx):
With a nonblocking socket, the connection attempt cannot be completed
immediately. In this case, connect will return SOCKET_ERROR, and
WSAGetLastError will return WSAEWOULDBLOCK. In this case, there are
three possible scenarios:
* Use the select function to determine the completion of the
connection request by checking to see if the socket is writeable.
* If the application is using WSAAsyncSelect to indicate interest
in connection events, then the application will receive an
FD_CONNECT notification indicating that the connect operation is
complete (successfully or not).
* If the application is using WSAEventSelect to indicate interest
in connection events, then the associated event object will be
signaled indicating that the connect operation is complete
(successfully or not).
> > On a high-load Solaris 10 box, dovecot-lda fails to query (I/O) to
> > dovecot dict socket with ENOTCONN. My patch fixes this problem.
>
> I think Linux/etc returns EAGAIN in such situation. Maybe the right
> fix is to just add EINPROGRESS check for net_connect_unix_with_retries()?
> (With some extra changes so that it actually sees that errno from
> net_connect_unix())
I think you MUST wait for the fd to complete connect() before
read() from / write() to the fd in such situation.
--
-- Name: SATOH Fumiyasu (fumiyas @ osstech co jp)
-- Business Home: http://www.OSSTech.co.jp/
-- Personal Home: http://www.SFO.jp/blog/
More information about the dovecot
mailing list