-
Type:
Bug
-
Status: Resolved
-
Priority:
Major
-
Resolution: Fixed
-
Affects Version/s: 2.0.0-M24
-
Fix Version/s: 2.0.0.AM25
-
Component/s: None
-
Labels:None
-
Environment:ApacheDS
ApacheDS uses a KerberosProtocolHandler as the handler of the
IoAcceptor in KdcServer.java:
// Inject the protocol handler acceptor.setHandler( new KerberosProtocolHandler( this, store ) );
When a TCP connection is about to be closed, KerberosProtocolHandler$inputClosed(IoSession session) is invoked when
filterChain.fireInputClosed();
is reached in AbstractPollingIoProcessor.java. But KerberosProtocolHandler$inputClosed(IoSession session) does nothing:
public void inputClosed( IoSession session )
{
}
which leaves the session unclosed, which in turn prevents its SocketChannel from being deregistered from the selector in NioProcessor. As a result,
int selected = select(SELECT_TIMEOUT);
in AbstractPollingIoProcessor.Processor.run() keeps returning a readable channel, on which read() returns -1. This infinite loop consumes all available CPU.
By constrast, LdapServer sets a LdapProtocolHandler to its acceptor, and LdapProtocolHandler inherits inputClosed(IoSession session) from IoHandlerAdapter:
public void inputClosed(IoSession session) throws Exception { session.close(true); }
which closes properly the session.
How to reproduce:
Simply run kinit with TCP (by setting udp_preference_limit = 1 in /etc/krb5.conf), and ApacheDS will be running at 100% CPU. Doing it again will consume more CPU resources depending on core number.