dummzeuch 1499 Posted 10 hours ago (edited) I'm trying to get ssh tunneling to work with ssh-pascal. The goal is to replace the currently used ssh tunnel for Remote Desktop via Putty with my own program. I adapted the LocalForward demo and I can connect to and read from http://detectportal.firefox.com/success.txt (the original url http://git.php.net/ is apparently no longer available) Then I changed the code to connect to my employer's internet facing ssh server port and forwarded a local port to the remote 3389 port of a computer in our LAN. I can log on fine to the ssh server, even the Remote Desktop client starts, connects and gets a valid logon. But then it asks whether it should connect even though the certificate is not from a trusted certifying authority (which is normal for that connection) and pressing Yes there odes not do anything and the RDC connection times out after a while. I added some debug WriteLns and found that the processing thread while executing TSshTunnel.ForwardLocalPort is waiting to read from ForwardSock here, after apparently FD_ISSET returned True: SetLength(Buf, FBufferSize); while not FCancelled do begin FD_ZERO(ReadFds); _FD_SET(ForwardSock, ReadFds); _FD_SET(ChannelSock, ReadFds); // wait for action ReturnCode := select(0, @ReadFds, nil, nil, @TimeVal); if ReturnCode < 0 then CheckSocketResult(ReturnCode, 'select'); if ReturnCode = 0 then Continue; // we should be able to read now WriteLn('Checking ForwardSock'); if FD_ISSET(ForwardSock, ReadFds) then begin WriteLn('Reading from ForwardSock'); Read := recv(Forwardsock, Buf[0], FBufferSize, 0); // <=== hangs here if Read = SOCKET_ERROR then CheckSocketResult(WSAGetLastError, 'recv'); if Read = 0 then raise ESshTunnelError.CreateRes(@Err_ConnClosed); WriteLn(Read, ' bytes read from ForwardSock'); Total := 0; While (Total < Read) do begin Written := libssh2_channel_write(Channel, PAnsiChar(Buf) + Total, Read - Total); // Takes care of LIBSSH2_ERROR_EAGAIN CheckLibSsh2Result(Written, FSession, 'libssh2_channel_write'); Inc(Total, Written); Writeln(Written, ' bytes written to ChannelSock'); end; end; WriteLn('Checking ChannelSock'); if FD_ISSET(ChannelSock, ReadFds) then begin WriteLn('Reading from ChannelSock'); Read := libssh2_channel_read(channel, PAnsiChar(Buf), FBufferSize); if Read = LIBSSH2_ERROR_EAGAIN then // Go to Wait state again Continue; CheckLibSsh2Result(Read, FSession, 'libssh2_channel_read'); WriteLn(Read, ' bytes read from ChannelSock'); Total := 0; While (Total < Read) do begin Written := send(forwardsock, Buf[Total], Read - Total, 0); if Written = SOCKET_ERROR then CheckSocketResult(WSAGetLastError, 'send'); Inc(Total, Written); Writeln(Written, ' bytes written to ForwardSock'); end; end; end; These are the last lines of the debug output: Checking ChannelSock Checking ForwardSock Checking ChannelSock Reading from ChannelSock 88 bytes read from ChannelSock 88 bytes written to ForwardSock Checking ForwardSock Reading from ForwardSock Has anybody ever used this code successfully for more than requesting a simple webpage? Edited 10 hours ago by dummzeuch Share this post Link to post
Kas Ob. 120 Posted 7 hours ago @dummzeuch Can't test it right now, as it need more code to make it work, but Don't ever use select in that way, in general all looks fine and correct, but without socket errors not the ones with API calls return, but the ones from "exceptfds", without checking for socket level errors you are driving in the dark, if error was signaled on the socket then read will hang for ever ! Add exceptfds, and then check for errors before read or write, as in many cases both error and read/write might be triggered and reported at the same time, in your case most likely this what did happen, an acknowledgment received to close and both readfds and exceptfds had been signaled. Share this post Link to post
pyscripter 684 Posted 7 hours ago (edited) @dummzeuch I have pushed a couple of fixes to SshTunnel.pas (issues found by Copilot!). Could you please check whether they make a difference? One of them might: SocketOption := 1; // Initialize SocketOption Edited 7 hours ago by pyscripter Share this post Link to post