1

I am running an ssh tunnel from an application using a QProcess:

QProcess* process = new QProcess();
process->start("ssh", QStringList()<<"-L"<<"27017:localhost:27017"<<"example.com");

So far it works great, the only problem being that there is no way for me to see when the port has actually been created.

When I run the command on a shell, it takes about 10 seconds to connect to the remote host after which the forwarded port is ready for usage. How do I detect it from my application?

EDIT:

As suggested by vahancho, I used the fact that post-connection there is some output on the terminal that can be used to detect that the connection has succeeded. However, there is a line which is run instantly after launch Pseudo-terminal will not be allocated because stdin is not a terminal, which probably would give a false alarm. The correct output is available in the second signal, emitted a bit later (which is a true indicator of the port having being opened). To get rid of the first message, I am now running ssh using ssh -t -t to force an stdin allocation.

So, the only question left is, can anyone help me without any concerns in this approach?

László Papp
  • 51,870
  • 39
  • 111
  • 135
Rohan Prabhu
  • 7,180
  • 5
  • 37
  • 71
  • 1
    Is there any output from ssh upon connection is done? – vahancho Dec 23 '13 at 12:41
  • Actually.. yes. Thanks for that idea! I'm going to try it out now... – Rohan Prabhu Dec 23 '13 at 12:43
  • This almost works. The first line is "Pseudo-terminal will not be allocated because stdin is not a terminal". This happens instantly after launching the process. I get the readyReadStandardOuptut signal again, which is when it is actually ready to be used. However, I am not sure if this is guaranteed to happen all the time across all platforms. Any suggestions? – Rohan Prabhu Dec 23 '13 at 12:49
  • I was able to use this "ssh -t -t" to get rid of the first message. Taken from http://stackoverflow.com/questions/7114990/pseudo-terminal-will-not-be-allocated-because-stdin-is-not-a-terminal . Any concerns that you can think of? – Rohan Prabhu Dec 23 '13 at 12:50
  • I suggest to read the 'ssh' documentation for more details about the possible output. – vahancho Dec 23 '13 at 12:53
  • 2
    Actually, what I am really considering is to go ahead with using libssh for more granular control over the tunneling process and that also looks like the way to a more robust system. – Rohan Prabhu Dec 23 '13 at 12:59
  • Yes Rohan, if you're on linux just move forward with libssh2. but for Windoze, I've had mixed results with libssh (X11 can be flakey). But in general both will work fine – Son-Huy Pham Dec 23 '13 at 19:42
  • It's only Mac/Linux we are ever planning to support. Windows is pretty much a no-no.. so we should be good there.. Thanks :) – Rohan Prabhu Dec 24 '13 at 07:38

2 Answers2

2

So, the only question left is, can anyone help me without any concerns in this approach?

This is not a stable and robust solution, unfortunately. It is similarly a broken concept to handling git outputs rather than using an actual library. The main problem is that these softwares do not have any guarantee for output compatibility, rightfully.

Just imagine that what happens if they have an unclear text, a typo, et all, unnoticed. They inherently need to fix the output respectively, and all the applications relying on the output would abruptly break.

This is also the reason behind working on dedicated libraries giving access to the functionality for reuse rather than working with the user facing output directly. In case of git, this means the libgit2 library, for instance.

Qt does not have an ssh mechanism in place by default like you can have such libraries in python, e.g. paramiko.

I would suggest to establish a way in your code by using libssh or libssh2 as you also noted yourself in the comment. I can understand the inconvenience that is not a truly Qt'ish way as of now, but at this point Qt cannot provide anything more robust without third-party.

That being said, it would be nice to see a similar add-on library in the Qt Project for the future, but this may not be happen any soon. If you write your software with proper design in mind, you will be able to switch to such a library withour major issues once someone stands up to maintain such an additional library to Qt or elsewhere.

László Papp
  • 51,870
  • 39
  • 111
  • 135
0

I had the same problem, but in my case ssh do not output anything - so I couldn't just wait for output. I'm also using ssh to setupt tunnel, so I used QTcpSocket:

program = "ssh";
arguments << m_host << "-N" << "-L" << QString("3306:%1:3306").arg(m_host);
connect(tunnelProcess, &QProcess::started, this, &Database::waitForTunnel);
tunnelProcess->start(program, arguments);

waitForTunnel() slot:

QTcpSocket sock;
sock.connectToHost("127.0.0.1", 3306);
if(sock.waitForConnected(100000))
{
     sock.disconnectFromHost();
     openDatabaseConnection();
}
else
    qDebug() << "timeout";

I hope this will help future people finding this question ;)

konserw
  • 494
  • 2
  • 10