8

I am calling ssh (OpenSSH) from a OSX/Linux-C++-Application via fork/exec to create a dynamic port forwarding. This is done using batch mode (-o BatchMode=yes) and a private key which is supplied to ssh (-i Option). The SSH call itself does not open a shell (-N Option).

This is my full SSH-Call:

ssh -N -D 9000 -o BatchMode=yes -i /path/to/private-key user@host

I would like to proceed with my application as soon as I can and so I have to find out if ssh succeeded creating the channel. SSH itself only returns if it has a problem.

Is there a possibility how I can detect a successful port forwarding?

Of course I can wait until the port is opened by SSH but I am looking for a more elegant solution. Another solution is to inspect SSH's Log (-v) waiting for "Entering interactive Session" but this sounds not very portable to me.

2 Answers 2

5

Use the -f option and ssh will go into the background (i.e. fork and exit in the parent process), so you can just waitpid for the original ssh to finish and then you know (based on exit status) either that the connection failed or port forwarding is already setup.

3
  • 1
    This sounds good. But now I would have the problem that I cannot figure out the PID of the forked SSH process and thus cannot easily clean up after program termination. There is this discussion on Debians Bugzilla: bugzilla.mindrot.org/show_bug.cgi?id=1473 The only chance I see to use it in conjunction with -f is to use ControlMaster/Slave-Communication.
    – nob
    May 2, 2013 at 13:08
  • 1
    @nob you can signal the grandchild using process groups. Basically, when your application forks to exec ssh, the child process should make itself a process group leader before calling exec. Here is an example in perl of doing that.
    – Kenster
    May 2, 2013 at 14:37
  • Process groups sound like the best solution, but it may also be possible to arrange for the ssh process to die when a particular pipe or socket is closed by your process. May 2, 2013 at 15:25
1

I think I found another (also hackish) solution. When starting SSH with

ssh -S /some/domain/socket -M ...args... host

it will create the control domain socket only it it succesfully established the connection. So I would have to wait for the domain socket to appear in the filesystem. Still not beautiful, but this sounds more robust than waiting for a network socket to appear.

Interestingly this can also be used to find out the PID of the Master (see R.. s Answer). Using

$ ssh -S /some/domain/socket -O check host
Master running (pid=25503)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .