So, I come up with some news. After a lot of prototyping, I managed to implement the desired behavior using the FileServer, but only to the point that I can establish a "duplex" communication channel between the SSH server and the Proxy server. How I did it?
1. The Proxy server initiates the connection by creating two SSH sessions (Ssh component): one for the input queue and the other one for the output queue.
2. The SSH Server receives the commands in the ShellCommand event from the Proxy. The session of the Proxy's input queue becomes the session of the SSH Server's output queue (ServerSession component) and the session of the Proxy's output queue becomes the session of the SSH Server's input queue (also ServerSession component).
Side note: at this point it would be interesting to see how can I use a sigle session for the duplex communication (currently, when I use a single session for the input and output queues, a Send would crash if a ReadLine is active).
The communication protocol works like this:
A. SSH Server sends a request.
1. SSH Server out: ServerSession.SendMessage(string_encoded_message).
2. Proxy in: Scripting.ReadLine until message is completely received.
3. Proxy processes the message.
4. Proxy out: Scripting.SendCommand(string_encoded_response).
5. SSH Server in: ShellCommand handler receives response and matches the request.
B. Proxy sends a request.
1. Proxy out: Scripting.SendCommand(string_encoded_message).
2. SSH Server in: ShellCommand handler receives message.
3. SSH Server processes the request.
4. SSH Server out: ServerSession.SendMessage(string_encoded_response).
5. Proxy in: Scripting.ReadLine until response is completely received and matches the request.
The communication works fine so far. The problem arises when I try to start a tunnel from the SSH Server to a target. So here is the flow, assuming that the duplex connection is up and running:
1. Identify a free port on the SSH Server.
2. Send to the proxy the free port number and the target host/port.
3. The proxy uses its out queue's SSH session to start an incoming tunnel from (127.0.0.1, free-port) to (target-host, target-port). BANG! This is the moment when the method crashes with the cryptical "The request has failed" exception.
(from log: ID:3|area:SSH|Rebex.Net.SshException: The request has failed.
at Rebex.Net.SshSession.ExecuteRequest(ConnectGlobalRequest request, GlobalRequestKind kind)
at Rebex.Net.SshSession.StartTcpIpForward(String address, Int32 port))
This is the region which generates the crash:
object[] result = WaitFor<object[], SshGlobalRequest>(ExecuteRequestFinishCheck, r);
if (result == null)
throw new SshException(SshExceptionStatus.OperationFailure, SshStrings.RequestFailed);
Trying to build a tunnel using putty indicates an error: "Remote port forwarding from 127.0.0.1:4800 refused." (a connection was previously established to the server, and the tunnel is created in this connection.)
Side note: there is no notification in both Ssh and ServerSession when the underlying connection is closed/dead (such as a Closed event). I implemented a timer that checks periodically (each minute) if the connection is alive.
Any additional help would be appreciated.