title: timeout at net.schmizz.sshj.transport.KeyExchanger.waitForDone(KeyExchanger.java:160)
body: <p>I have a nightly job that is using <code>net.schmizz.sshj</code> SFTP library.</p>
  
  <p>I suspect that there was a change on the server that we SFTP into. However, I cannot pinpoint what the exact change is. Nor can I reproduce it outside the production server. So I am looking for insight of a root cause or how to reproduce the following error</p>
  
  <p><code>
  net.schmizz.sshj.transport.TransportException: Timeout expired
      at net.schmizz.sshj.transport.TransportException$1.chain(TransportException.java:33)
      at net.schmizz.sshj.transport.TransportException$1.chain(TransportException.java:27)
      at net.schmizz.concurrent.Promise.retrieve(Promise.java:139)
      at net.schmizz.concurrent.Event.await(Event.java:103)
      at net.schmizz.sshj.transport.KeyExchanger.waitForDone(KeyExchanger.java:160)
      at net.schmizz.sshj.transport.KeyExchanger.startKex(KeyExchanger.java:155)
      at net.schmizz.sshj.transport.TransportImpl.doKex(TransportImpl.java:247)
      at net.schmizz.sshj.SSHClient.doKex(SSHClient.java:735)
      at net.schmizz.sshj.SSHClient.onConnect(SSHClient.java:723)
      at net.schmizz.sshj.SocketClient.connect(SocketClient.java:54)
      at net.schmizz.sshj.SocketClient.connect(SocketClient.java:80)
  </code></p>
  
  <p>From what I can tell, we're connecting via a <code>java.net.Socket</code> ok and then timing out waiting for the key exchange to complete in this code</p>
  
  <pre><code>package net.schmizz.sshj.transport;
  
  /** Algorithm negotiation and key exchange. */
  final class KeyExchanger
          implements SSHPacketHandler, ErrorNotifiable {
  
      /**
       * Starts key exchange by sending a {@code SSH_MSG_KEXINIT} packet. Key exchange needs to be done once mandatorily
       * after initializing the {@link Transport} for it to be usable and may be initiated at any later point e.g. if
       * {@link Transport#getConfig() algorithms} have changed and should be renegotiated.
       *
       * @param waitForDone whether should block till key exchange completed
       *
       * @throws TransportException if there is an error during key exchange
       * @see {@link Transport#setTimeoutMs} for setting timeout for kex
       */
      void startKex(boolean waitForDone)
              throws TransportException {
          if (!kexOngoing.getAndSet(true)) {
              done.clear();
              sendKexInit();
          }
          if (waitForDone)
              waitForDone();
      }
  
      /**
       * Sends SSH_MSG_KEXINIT and sets the {@link #kexInitSent} event.
       *
       * @throws TransportException
       */
      private void sendKexInit()
              throws TransportException {
          log.debug("Sending SSH_MSG_KEXINIT");
          clientProposal = new Proposal(transport.getConfig());
          transport.write(clientProposal.getPacket());
          kexInitSent.set();
      }
  
  void waitForDone()
          throws TransportException {
      done.await(transport.getTimeoutMs(), TimeUnit.MILLISECONDS);
  }
  </code></pre>