Announcement Announcement Module
Collapse
No announcement yet.
LDAP w/ SSL hangs on slow connection Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • LDAP w/ SSL hangs on slow connection

    We are using Acegi Security to connect to a LDAP server for our application. Recently, the LDAP server was overloaded, and I expected the app to throw a connection timeout error so that Acegi could attempt to connect to our failover LDAP server. Instead, we saw the app hang.

    To repro the scenario, I am using 'redir' to simulate a slow connection to the LDAP server (redir --lport=3890 --cport=389 --caddr=lab-ldap.lab --random_wait=8000 --bufsize=16, redir --lport=6360 --cport=636 --caddr=lab-ldap.lab --random_wait=8000 --bufsize=16).

    When I start the app using ldap url "ldaps://localhost:6360/dc=company,dc=com", I experience a hang after the Socket has been opened and connected to, but before an attempted read. It appears to hang during the handshake. However, when I use the insecure url "ldap://localhost:3890/dc=company,dc=com)", I see a message in the console about a read timeout. I have a connect and read timeout configured to 5000ms. Is there another timeout I need to specify? Am I missing something here?


    Here is how I've included the read and connect timeout:

    <bean id="initialDirContextFactoryMaster" class="org.acegisecurity.ldap.DefaultInitialDirCon textFactory">
    <constructor-arg value="${ldap.protocol}://${ldap.master.url}/${ldap.baseDN}"/>
    <property name="extraEnvVars">
    <map>
    <entry key="com.sun.jndi.ldap.connect.timeout" value="${ldap.timeout}"/>
    <entry key="com.sun.jndi.ldap.read.timeout" value="${ldap.timeout}"/>
    </map>
    </property>
    </bean>

    Here is the stack I pulled from the app during the hang:

    main@1, priority=5, in group 'main', status: 'MONITOR'
    waiting for Thread-1@994
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.perform InitialHandshake(SSLSocketImpl.java:1,114)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRe cord(SSLSocketImpl.java:632)
    at com.sun.net.ssl.internal.ssl.AppOutputStream.write (AppOutputStream.java:59)
    at java.io.BufferedOutputStream.flushBuffer(BufferedO utputStream.java:65)
    at java.io.BufferedOutputStream.flush(BufferedOutputS tream.java:123)
    at com.sun.jndi.ldap.Connection.writeRequest(Connecti on.java:396)
    at com.sun.jndi.ldap.LdapClient.ldapBind(LdapClient.j ava:334)
    at com.sun.jndi.ldap.LdapClient.authenticate(LdapClie nt.java:192)
    at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2,6 94)
    at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:293)
    at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapC txFactory.java:175)
    at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(Ldap CtxFactory.java:193)
    at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstanc e(LdapCtxFactory.java:136)
    at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext (LdapCtxFactory.java:66)
    at javax.naming.spi.NamingManager.getInitialContext(N amingManager.java:667)
    at javax.naming.InitialContext.getDefaultInitCtx(Init ialContext.java:288)
    at javax.naming.InitialContext.init(InitialContext.ja va:223)
    at javax.naming.InitialContext.<init>(InitialContext. java:197)
    at javax.naming.directory.InitialDirContext.<init>(In itialDirContext.java:82)

    Any help would be appreciated! And no, I can't upgrade to Spring Security right now...
    Last edited by mmoy; Dec 16th, 2010, 05:16 PM.

  • #2
    update

    In case anyone has this same problem in the future, I solved it by creating a custom socket factory that mostly delegates methods to the SSLSocketFactory,

    Code:
    import javax.net.SocketFactory;
    import javax.net.ssl.SSLSocketFactory;
    import java.io.IOException;
    import java.net.InetAddress;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    public class CustomSSLSocketFactory extends SocketFactory {
    
        private static final int SO_TIMEOUT = 5000;
        
        private static final CustomSSLSocketFactory _instance = new CustomSSLSocketFactory();
        private static final SocketFactory _sslSocketFactory = SSLSocketFactory.getDefault();
    
        public static SocketFactory getDefault() {
            return _instance;
        }
    
        public Socket createSocket() throws IOException {
            Socket s = _sslSocketFactory.createSocket();
            s.setSoTimeout(SO_TIMEOUT);
            return s;
        }
    
        @Override
        public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort)
                throws IOException {
            Socket s = _sslSocketFactory.createSocket(address, port, localAddress, localPort);
            s.setSoTimeout(SO_TIMEOUT);
            return s;
        }
    
        @Override
        public Socket createSocket(InetAddress host, int port)
                throws IOException {
            Socket s = _sslSocketFactory.createSocket(host, port);
            s.setSoTimeout(SO_TIMEOUT);
            return s;
        }
    
        @Override
        public Socket createSocket(String host, int port)
                throws IOException, UnknownHostException {
            Socket s = _sslSocketFactory.createSocket(host, port);
            s.setSoTimeout(SO_TIMEOUT);
            return s;
        }
    
        @Override
        public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
                throws IOException, UnknownHostException {
            Socket s = _sslSocketFactory.createSocket(host, port, localHost, localPort);
            s.setSoTimeout(SO_TIMEOUT);
            return s;
        }
    }
    Last edited by mmoy; Jan 20th, 2011, 06:21 PM.

    Comment

    Working...
    X