We have below thread to perform SSLHandshake but in some edge cases I noticed ((SSLSocket) clientSocket).startHandshake();
is blocked forever and its not going to the next block of while
loop code where SSL_HANDSHAKE_TIMEOUT is 1500
milli seconds and it works fine, Am wondering if adding clientSocket.setSoTimeout(90000);
would fix this issue or should it handled in a different way?
MainServerHandshakeThread
public class MainServerHandshakeThread implements com.ssltunnel.utilities.threading.Shutdown, Runnable {
private final Socket clientSocket;
private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(MainServerHandshakeThread.class.getName());
private boolean done;
public MainServerHandshakeThread(Socket clientSocket) {
this.clientSocket = clientSocket;
}
private void handshake() throws CertificateExpiredException, InterruptedException, IOException {
long start = System.currentTimeMillis();
((SSLSocket) clientSocket).setNeedClientAuth(true);
MainServerHandshakeHandler handshake = new MainServerHandshakeHandler();
((SSLSocket) clientSocket).addHandshakeCompletedListener(handshake);
((SSLSocket) clientSocket).startHandshake();
while (!handshake.isDone() && !done) {
Thread.sleep(10);
long duration = System.currentTimeMillis() - start;
if (duration>SSL_HANDSHAKE_TIMEOUT) {
done = true;
LOG.warn("Handshake timeout");
}
}
long stop = System.currentTimeMillis();
serialNumber = handshake.getSerialNumber();
LOG.info("MainServer Handshake Handshake done in ms: " + ((stop - start))+" For serialNumber "+serialNumber );
}
@Override
public void run() {
try {
handshake();
} catch (CertificateExpiredException ex) {
LOG.error("Client Certificate Expired", ex.getMessage());
SocketUtils.closeQuietly(clientSocket);
}
catch (InterruptedException ex) {
LOG.error("Interrupted waiting for handshake", ex);
SocketUtils.closeQuietly(clientSocket);
}
catch (IOException ex) {
LOG.error("IO Error waiting for handshake", ex);
SocketUtils.closeQuietly(clientSocket);
}
finally {
LOG.debug("Handshake thread is done");
done = true;
}
}
@Override
public void shutdown() {
if (clientSocket!=null) {
SocketUtils.closeQuietly(clientSocket);
}
}
}