Properly closing SSLSocket

Viewed 19056

I want to implement an SSL proxy in Java. I basically open two sockets browser-proxy,proxy-server, and run two threads which would write to proxy-server what they read from browser-proxy, and vice versa. Each thread looks like this:

while (true) {
   nr = in.read(buffer);
   if (nr == -1) System.out.println(sockin.toString()+" EOF  "+nr);
   if (nr == -1) break;
   out.write(buffer, 0, nr);
}
sockin.shutdownInput();
sockout.shutdownOutput(); // now the second thread will receive -1 on read

Each thread will only close the input socket, so that eventually both sockets are closed.

But what do I do if I want to use an SSLSocket? It seems that the shutdownOutput/Input methods are not supported there. Here's the exception I get.

Exception in thread "Thread-35" java.lang.UnsupportedOperationException: \
The method shutdownInput() is not supported in SSLSocket
    at com.sun.net.ssl.internal.ssl.BaseSSLSocketImpl.shutdownInput(Unknown Source)

What I came up with is:

try {
    while (true) {
       nr = in.read(buffer);
       if (nr == -1) System.out.println(sockin.toString()+" EOF  "+nr);
       if (nr == -1) break;
       out.write(buffer, 0, nr);
    }
    // possible race condition if by some mysterious way both threads would get EOF
    if (!sockin.isClosed()) sockin.close();
    if (!sockout.isClosed()) sockout.close();
} catch (SocketException e) {/*ignore expected "socket closed" exception, */}

I must catch and ignore end of socket exception every time my socket ends.

My questions are:

  1. If shutdownInput() is unsupported, how come I'm getting a -1 answer from an SSLSocket.
  2. Is there a better solution for my agony? I don't think there's anything sane, since one of the thread might be already in the blocking read method when the other thread marks him "I'm done". And the only way I see to kick him out of the blocking thread is by closing the socket and raising a "closed socket" exception.

    (You could I guess use some unholy combination of multithread message passing and asynchronous data reading in order to signal the other thread your work is done, but this is so horrible that I'm afraid IntelliJ's style cop will come after me just for thinking about it...)

Clarification: I know that shutdownInput and shutdownOutput doesn't make sense, since you cannot have a half-duplex TLS connection, per spec. But given that, how can I end a TLS connection in Java without getting an exception?

Please, don't tell me shutdownIput doesn't make sense for TLS. I know that, this is not what I'm asking. I'm asking what else can I use, in order to close SSLSocket properly (hence the title, "Properly closing SSLSocket".

3 Answers
Related