Guys,

I just tried patching 6.0.20 with the tomcat6 fix mentioned at
http://www.mail-archive.com/users@tomcat.apache.org/msg70131.html

This gives me a concurrentmodificationexception:

java.util.ConcurrentModificationException
        at java.util.HashMap$HashIterator.nextEntry(Unknown Source)
        at java.util.HashMap$EntryIterator.next(Unknown Source)
        at java.util.HashMap$EntryIterator.next(Unknown Source)
        at
com.sun.net.ssl.internal.ssl.SSLSocketImpl$NotifyHandshakeThread.run(Unknown
Source)


>From http://java.sun.com/j2se/1.5.0/docs/api/java/util/HashMap.html, I see:
"The iterators returned by all of this class's "collection view methods" are
fail-fast: if the map is structurally modified at any time after the
iterator is created, in any way except through the iterator's own remove or
add methods, the iterator will throw a ConcurrentModificationException. ..."

Now, looks like The NotifyHandshakeThread iterates map of socket listeners,
performing callback on each. The new disableSslHandshake listener closes
containing socket, causing our failfast iterator to, well, fail.

Attempting to handle this error, I do a form of asynchronous close as
follows:

    private static class DisableSslRenegotiation
            implements HandshakeCompletedListener {
        private volatile boolean completed = false;

        /** commented out. This method is called from SSLSocketImpl
            which iterates set of listeners. Closing the containing socket
            can cause error in iterator execution **/
        public void handshakeCompleted(HandshakeCompletedEvent event) {
            if (completed) {
                try {
                log.warn("SSL renegotiation is disabled, closing
connection");
                    event.getSession().invalidate();
                    event.getSocket().close();
                } catch (IOException e) {
                    // ignore
                }
            }
            completed = true;
        }
        */

        public void handshakeCompleted(HandshakeCompletedEvent event) {
            if (completed) {
                final SSLSession session = event.getSession();
                final SSLSocket  socket  = event.getSocket();

                // spawn anon thread to close session
            new Thread(){
            public void run() {
                        synchronized(socket) {
                            try {
                            log.warn("SSL renegotiation is disabled, closing
connection");
                                session.invalidate();
                                socket.close();
                            } catch (IOException e) {
                                // ignore
                            }
                        }
            }

            }.start();
            }
            completed = true;
        }
    }


While this does seem to resolve concurrent modifications, I believe it is a
race-condition at best, which is working in my favour for now. Please
suggest me another fix, if there is one.


Thanks in advance,
Timir

Reply via email to