[Dovecot] imap-login hanging when firewall blocks ssl handshaking
Ben Morrow
ben at morrow.me.uk
Tue Dec 4 16:18:23 EET 2012
At 12PM +0000 on 4/12/12 Ben Morrow wrote:
>
> Well, it looks to me as though xnu/bsd/kern/uipc_socket.c:soreceive will
> indeed return ENOTCONN for a socket which was once successfully
> connected but has now been disconnected. This happens when the socket is
> in the DEFUNCT state, which is a state that doesn't exist in FreeBSD;
> it's not completely clear but I suspect firewalls may be able to put
> arbitrary sockets into that state.
Investigating a little further, it should be possible to test for this
situation directly. Assuming I'm correct about what's going on here,
this should be both cleaner and safer than mucking about looking for
ENOTCONN and guessing about what's happening.
Erik, does this make the problem go away? I left out the
proxy->client_proxy test, since AFAICT this is just as likely to happen
on a client socket.
Ben
--- src/login-common/ssl-proxy-openssl.c~ 2012-07-28 17:56:31 +0100
+++ src/login-common/ssl-proxy-openssl.c 2012-12-04 14:12:03 +0000
@@ -407,6 +407,21 @@
switch (err) {
case SSL_ERROR_WANT_READ:
+#ifdef SO_ISDEFUNCT
+ /* Some Apple firewalls appear to be able to mark a
+ * socket DEFUNCT, at which point all reads return
+ * immediately with ENOTCONN. Since that is supposed to
+ * mean 'the socket hasn't finished connecting yet',
+ * OpenSSL keeps asking for another read and we go into
+ * an infinite loop.
+ */
+ if (getsockopt(proxy->fd_ssl, SOL_SOCKET, SO_ISDEFUNCT,
+ (void *)&err, sizeof(err)) == 0 && err) {
+ errstr = t_strdup_printf(
+ "%s: socket is defunct", func_name);
+ break;
+ }
+#endif
ssl_set_io(proxy, SSL_ADD_INPUT);
break;
case SSL_ERROR_WANT_WRITE:
More information about the dovecot
mailing list