Туннелинг
От: klkvitaliy  
Дата: 17.08.10 10:26
Оценка:
Добрый день...

ВОт код, простой туннель, но при этом libssh2_channel_read всегда возвращает не то что нужно. Укажите в какой стороне ошибко углядеть, а то мозг уже пухнет. Буду благодарен.

#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>

#include "libssh2.h"

#define MAX_BUF_LEN 16536

int main(int argc, char *argv[])
{
LIBSSH2_SESSION *session;
int rc;
int sock = -1, listensock = -1, forwardsock = -1;
struct sockaddr_in sin;
WSADATA wsadata;
const char *fingerprint;
LIBSSH2_LISTENER *pLibSSH2Listener;
LIBSSH2_CHANNEL* channel = NULL;
unsigned long mode = 1;
int iretval;
SOCKET local_sock;
fd_set read_set, write_set;
char buf[MAX_BUF_LEN];
char* chunk;
long bytes_read = 0;
long bytes_written = 0;
int total_set = 0;
struct timeval wait;
struct sockaddr_in localhost;
int err;

rc = libssh2_init (0);
if (rc != 0)
{
fprintf (stderr, "libssh2_init() failed: %d\n", rc);
return -1;
}

WSAStartup( MAKEWORD(2,2), &wsadata );
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
sin.sin_family = AF_INET;
if (INADDR_NONE == (sin.sin_addr.s_addr = inet_addr("xx.xxx.xxx.xxx"))) {
fprintf (stderr, "inet_addr() failed.\n");
return -1;
}
sin.sin_port = htons( 22 );
if (connect(sock, (struct sockaddr*)(&sin) , sizeof(struct sockaddr_in)) != 0) {
fprintf (stderr, "connect() failed.\n");
return -1;
}

session = libssh2_session_init();
if (!session)
{
fprintf (stderr, "libssh2_session_init() failed\n");
return -1;
}

rc = libssh2_session_startup(session, sock);
if (rc)
{
fprintf (stderr, "libssh2_session_startup() failed.\n");
return -1;
}

fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);

if (libssh2_userauth_password(session, "popa", "123"))
{
fprintf (stderr, "Invalid username or password!\n");
goto shutdown;
}

pLibSSH2Listener = libssh2_channel_forward_listen(session, 3391 );
if ( !pLibSSH2Listener )
{
fprintf (stderr, "libssh2_channel_forward_listen fail.\n");
goto shutdown;
}

ioctlsocket( sock , FIONBIO , &mode );
libssh2_session_set_blocking( session , 0 );
err = LIBSSH2_ERROR_EAGAIN;
while (err == LIBSSH2_ERROR_EAGAIN)
{
channel = libssh2_channel_forward_accept( pLibSSH2Listener );
if (channel) break;
err = libssh2_session_last_errno(session);
Sleep( 10 );
}

if (channel)
{
wait.tv_sec = 0;
wait.tv_usec = 2000;

localhost.sin_family = AF_INET;
localhost.sin_addr.s_addr = inet_addr("127.0.0.1");
localhost.sin_port = htons(3389);
local_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
ioctlsocket(local_sock, FIONBIO, &mode);
iretval = connect(local_sock, (struct sockaddr*)(&localhost), sizeof(struct sockaddr_in) );
if (iretval == SOCKET_ERROR)
{
fprintf (stderr, "Connect to 127.0.0.1 fails. Error=%d.\n", WSAGetLastError());
//goto shutdown;
}

while (1)
{
bytes_read = libssh2_channel_read(channel, buf, MAX_BUF_LEN);
if (bytes_read >= 0)
{
FD_ZERO(&read_set);
FD_ZERO(&write_set);
FD_SET(local_sock, &write_set);

// wait until the socket can be written to
while (select(0, &read_set, &write_set, NULL, &wait) < 1)
Sleep( 10 );

if (FD_ISSET(local_sock, &write_set))
{
FD_CLR(local_sock, &write_set);
chunk = buf;

// everything may not get written in this call because we're non blocking. So
// keep writing more data until we've emptied the buffer pointer.
while ((bytes_written = send(local_sock, chunk, bytes_read, 0)) < bytes_read)
{
// if it couldn't write anything because the buffer is full, bytes_written
// will be negative which won't help our pointer math much
if (bytes_written > 0)
{
chunk = buf + bytes_written;
bytes_read -= bytes_written;
if (bytes_read == 0)
break;
}
FD_ZERO(&read_set);
FD_ZERO(&write_set);
FD_SET(local_sock, &write_set);

// wait until the socket can be written to
while (select(0, &read_set, &write_set, NULL, &wait) < 1)
Sleep( 100 );
}
}
}

FD_ZERO(&read_set);
FD_ZERO(&write_set);
FD_SET(local_sock, &read_set);
select(0, &read_set, &write_set, NULL, &wait);
if (FD_ISSET(local_sock, &read_set))
{
FD_CLR(local_sock, &read_set);
bytes_read = recv(local_sock, buf, MAX_BUF_LEN, 0);
if (bytes_read >= 0)
{
while ((bytes_written = libssh2_channel_write_ex(channel, 0, buf, bytes_read)) == LIBSSH2_ERROR_EAGAIN)
Sleep( 10 );
}
}
Sleep( 10 );
}
}


shutdown:
libssh2_session_free(session);

libssh2_exit ();

return 0;
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.