I’ve tried to modify examples/exec.c
file from libssh project to
create and destroy the channel 20 times:
/* simple exec example */
#include <stdio.h>
#include <libssh/libssh.h>
#include "examples_common.h"
int main(void) {
ssh_session session;
ssh_channel channel;
char buffer[256];
int nbytes;
int rc;
session = connect_ssh("hostname", "username", 22);
if (session == NULL) {
ssh_finalize();
return 1;
}
for (int i = 0; i < 20; i++) {
fprintf(stderr, "\ni = %d\n\n", i);
channel = ssh_channel_new(session);;
if (channel == NULL) {
ssh_disconnect(session);
ssh_free(session);
ssh_finalize();
return 1;
}
rc = ssh_channel_open_session(channel);
if (rc < 0) {
goto failed;
}
rc = ssh_channel_request_exec(channel, "lsof");
if (rc < 0) {
goto failed;
}
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
while (nbytes > 0) {
if (fwrite(buffer, 1, nbytes, stdout) != (unsigned int) nbytes) {
goto failed;
}
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
}
if (nbytes < 0) {
goto failed;
}
ssh_channel_send_eof(channel); // if I comment out these 3 lines, everything stops after i = 10
ssh_channel_close(channel); // if I comment out these 3 lines, everything stops after i = 10
ssh_channel_free(channel); // if I comment out these 3 lines, everything stops after i = 10
}
ssh_disconnect(session);
ssh_free(session);
ssh_finalize();
return 0;
failed:
ssh_channel_close(channel);
ssh_channel_free(channel);
ssh_disconnect(session);
ssh_free(session);
ssh_finalize();
return 1;
}
The channel is opened and closed successfully 20 times.
Then I try to comment out lines destroying the channel:
//ssh_channel_send_eof(channel);
//ssh_channel_close(channel);
//ssh_channel_free(channel);
Then the example stops after printing i = 10
. This proves that either
- I’m using Apache SSHD incorrectly to close the channel; OR
- There’s a bug in Apache SSHD’s channel closing code.
Also I’ve noticed that actually Apache SSHD’s
channel.close(true);
returns a future (CloseFuture
). But if I call
CloseFuture closeFuture = channel.close(true);
closeFuture.await();
or
CloseFuture closeFuture = channel.close(true);
closeFuture.awaitUninterruptibly();
and check closeFuture.isClosed()
, it doesn’t solve the problem: closeFuture.isClosed()
returns true
and the channels fail to reopen after 10th.
I’ll continue digging, maybe I should send something through the channel as it is done in libssh
:
ssh_channel_send_eof(channel);