5

I am developing a library that uses SSHJ for SFTP transfer. Since requests are frequent, I have wondered whether I could just keep the connection open.

Obviously, this will achieve nothing if the server frequently times out the connection. Since I have no control of the server, I have to keep the connection alive: With a regular SSH client, I could specify a ServerAliveInterval and have the client do it for me.

I'd like to do the same with SSHJ, but I do not know what message to send.

The SSH manual just states that ServerAliveInterval

Sets a timeout interval in seconds after which if no data has been received from the server, ssh(1) will send a message through the encrypted channel to request a response from the server.

So I'm wondering: What message is sent? How could I reproduce this message through SSHJ?

Urs Reupke
  • 6,791
  • 3
  • 35
  • 49

2 Answers2

8

Sorry this isn't documented, but you can set a heartbeat:

https://github.com/hierynomus/sshj/blob/master/examples/src/main/java/net/schmizz/sshj/examples/RemotePF.java#L51

Robert
  • 39,162
  • 17
  • 99
  • 152
shikhar
  • 2,432
  • 1
  • 19
  • 14
  • in case that link ever breaks or changes, the line is client.getTransport().setHeartbeatInterval(30); – Scott Apr 12 '13 at 20:05
  • 1
    It has indeed broken. – Sridhar Sarnobat Jun 17 '15 at 01:17
  • 1
    current version 0.23.0, it should be `sshClient.getConnection.getKeepAlive.setKeepAliveInterval(15)`. – LoranceChen Feb 26 '18 at 08:34
  • What's the difference between heartbeat and keepalive? – golimar Jun 26 '19 at 19:07
  • 2
    @golimar - your question was a while ago - but I also had the same question. It looks like the original heartbeat solution was to send a Message.IGNORE periodically. From my digging it appears that this was enhanced in (https://github.com/hierynomus/sshj/issues/166) which Marboni's answer references (0.11.0). This introduced the KEEP_ALIVE option sends standard ssh keep-alive messages instead. Note: This fix kept HEARTBEAT as the default position - so to use it you must use setKeepAliveProvider(KeepAliveProvider.KEEP_ALIVE) on the DefaultConfig once it is created. – Dazed Sep 14 '19 at 20:16
3

Starting from version 0.11.0, you can use built-in KeepAliveProvider:

public class KeepAlive {

    public static void main(String... args)
            throws IOException, InterruptedException {
        DefaultConfig defaultConfig = new DefaultConfig();
        defaultConfig.setKeepAliveProvider(KeepAliveProvider.KEEP_ALIVE);
        final SSHClient ssh = new SSHClient(defaultConfig);
        try {
            ssh.addHostKeyVerifier(new PromiscuousVerifier());
            ssh.connect(args[0]);
            ssh.getConnection().getKeepAlive().setKeepAliveInterval(5); //every 60sec
            ssh.authPassword(args[1], args[2]);
            Session session = ssh.startSession();
            session.allocateDefaultPTY();
            new CountDownLatch(1).await();
            try {
                session.allocateDefaultPTY();
            } finally {
                session.close();
            }
        } finally {
            ssh.disconnect();
        }
    }
}

To send heartbeats, you may use KeepAliveProvider.HEARTBEAT.

Marboni
  • 2,399
  • 3
  • 25
  • 42