Hello!
I need help on using libssh2 for forwading ports in c++ application
with high-level framework (qt4).
Currently I'm usging 1.2.6 libssh2 version.
I've started with direct_tcpip.c example and come with following:
1) establishing connection, setting up libssh2 session and authenticating
2) setting up listening tcp socket and starting framework event loop
3) on incoming connection setting up libssh2 channel
4) every second iterating over channel list and for each one
reading data from socket and writing to libssh2 channel and vice versa
5) closing and freeing channel on socket disconnect
Source that can be compiled and run attached to message.
Here's example with libssh2 function calls:
//authentication from example
int libssh2_error = libssh2_init(0);
...
LIBSSH2_SESSION *session = libssh2_session_init();
QTcpSocket socket;
socket.connectToHost(...);
if(!socket.waitForConnected())
...
libssh2_error = libssh2_session_startup(session, socket.socketDescriptor());
...
libssh2_userauth_list(session, ...);
if(libssh2_userauth_password(...)
...
//setup local tcp socket
//on incoming connection
void openConnection()
{
QTcpServer *server = ...;
QTcpSocket *socket = server->nextPendingConnection();
libssh2_session_set_blocking(m_session, 1);
LIBSSH2_CHANNEL *channel = libssh2_channel_direct_tcpip_ex(
m_session,
tunnel.m_host.toLocal8Bit().constData(),
tunnel.m_hostPort,
server->serverAddress().toString().toLocal8Bit().constData(),
server->serverPort()
);
...
//reading and writing data
void transmit()
{
char buffer[4096];
libssh2_session_set_blocking(m_session, 1);
QTcpSocket *socket = ...;
LIBSSH2_CHANNEL *channel = ...;
int read = socket->read(buffer, sizeof(buffer));
int written = 0;
int i = 0;
if(read > 0)
{
do
{
i = libssh2_channel_write(
channel,
buffer,
read
);
if(i < 0)
{
...
}
written += i;
} while (i > 0 && written < read);
}
while(true)
{
read = libssh2_channel_read(channel, buffer, sizeof(buffer));
if(LIBSSH2_ERROR_EAGAIN == read)
{
break;
}
else if(read < 0)
{
...
}
written = 0;
while(written < read)
{
i = socket->write(buffer + written, read - written);
if(i < 0)
{
...
}
}
i = libssh2_channel_eof(channel);
if(i)
{
...
}
}
...
//closing connection
LIBSSH2_CHANNEL *channel = ...;
if(channel)
{
//there's no libssh2_channel_close close in example
//should I close channel on socket disconnect or not?
//libssh2_channel_close(channel);
//libssh2_channel_wait_closed(channel);
libssh2_channel_free(channel);
}
...
//cleanup
socket.disconnectFromHost();
libssh2_session_disconnect(session, "Client disconnecting normally");
libssh2_session_free(session);
libssh2_exit();
Example says all channel IO should go in unblocked mode, but in this mode
no data transfered without select()/poll() which I cant use in high
level networking API.
And in unblocked mode I can't setup new channel.
In blocking mode some data transferred, for example I can get html via
http with curl
through forwarded port but I have to wait about 15 seconds till
libssh2_channel_read
timeout. Using, say, ssh shell through forwarded port is unusable
because there's plenty of
timeouts to wait.
-- A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing? A: Top-posting. Q: What is the most annoying thing in e-mail?
_______________________________________________
libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel