Subject: Need advice using channels from high level c++ framework (qt)

Need advice using channels from high level c++ framework (qt)

From: Dmitry Teslenko <dteslenko_at_gmail.com>
Date: Mon, 20 Dec 2010 17:00:34 +0300

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

Received on 2010-12-20