2011/2/22 Daniel Stenberg <dan...@haxx.se> > On Tue, 22 Feb 2011, Mateusz Pilski wrote: > > Please don't top-post, it makes it very hard to follow what's being said!
sorry for that. > > Thank you for quick response. Unfortunately this isn't the solution for my >> problem because channel is set for nonblocking few lines before code i >> pasted using >> > > Okay, so what version are you using on what operating system? > > i'm using system: Debian 2.6.32-28 libssh2 version 1.2.7 and all of this is on quite old and slow machine: cpu 800 mhz 64 KB cache memory 256 MB but still it isn't a piece of junk i remember i've played for example quake 2 on similar machine and there were no problems at all and i don't think that sending encrypted package of 4 KB size could be more demanding than that. i have made some test on faster machine (cpu 2400 mhz 1024 KB chache) and everything goes fine there. Have you tried to repeat the problem with a recent snapshot/git version? > > yes, nothing changed. > > also there i use function libssh2_channel_handle_extended_data2(channel, >> LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE); but i don't suppose that it have >> influence on my problem. >> > > Can you help us help you and provide a full example that repeats this > problem? > > i post here mostly simplified working code with this error(compile with -lssh2 -lncurses). Code is quite long but functions connection() and makeconnection() are just lightly modified code of connection example from libssh2 site (http://libssh2.org/examples/ssh2.html) so the interesting part is only function mainloop(). To make connection change first 3 lines of code. Because i cut most of the code result is litle messy, but what is important is when you connect and type command "cat largefile.dat" it will hang just like i described before. Note that if packet will be large but still smaller than BUFFSIZE (for example if you change BUFFSIZE to 124096 and HALFBUFFSIZE to 62048) all will go well. #define confighost "127.0.0.1" #define configusername "login" #define configpassword "password" #include <libssh2.h> #include <ncurses.h> #include <netinet/in.h> #include <fcntl.h> #include <stdio.h> #include <string.h> /* String function definitions */ #include <termios.h> /* POSIX terminal control definitions */ #define BUFFSIZE 4096 #define HALFBUFFSIZE 2048 char pass[64]; int curpos=0,comlen=0; static void kbd_callback(const char *name, int name_len, const char *instruction, int instruction_len, int num_prompts, const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts, LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses, void **abstract) { (void)name; (void)name_len; (void)instruction; (void)instruction_len; if (num_prompts == 1) { responses[0].text = strdup(pass); responses[0].length = strlen(pass); } (void)prompts; (void)abstract; } /* kbd_callback */ int block=0,arrow=0; LIBSSH2_SESSION *session; LIBSSH2_CHANNEL *channel; int connection(int *socke) { unsigned long hostaddr; int sock, auth_pw = 0; struct sockaddr_in sin; const char *fingerprint; char *userauthlist; #ifdef WIN32 WSADATA wsadata; WSAStartup(MAKEWORD(2,0), &wsadata); #endif hostaddr = inet_addr(confighost); sock = socket(AF_INET, SOCK_STREAM, 0); #ifndef WIN32 fcntl(sock, F_SETFL, 0); #endif *socke=sock; sin.sin_family = AF_INET; sin.sin_port = htons(22); sin.sin_addr.s_addr = hostaddr; if (connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in)) != 0) { fprintf(stderr, "Nie udało się nawiązać połączenia z %s!\nSprawdź swoje połączenie sieciowe.\nJeśli problem będzie się powtarzać skontaktuj się z administratorem.\n naciśnij enter aby spróbować ponownie",confighost); getchar(); return -1; } printf("połączenie z serwerem jest aktywne\n"); fflush(stdout); *socke=sock; } int makeconnection(LIBSSH2_SESSION **sesion,LIBSSH2_CHANNEL **chanel,int *socke) { LIBSSH2_CHANNEL *channel; LIBSSH2_SESSION *session; const char *keyfile1="~/.ssh/id_rsa.pub"; const char *keyfile2="~/.ssh/id_rsa"; strcpy(pass,configpassword); unsigned long hostaddr; int sock, auth_pw = 0; struct sockaddr_in sin; const char *fingerprint; char *userauthlist; sock=*socke; /* Create a session instance and start it up * This will trade welcome banners, exchange keys, and setup crypto, compression, and MAC layers */ session = libssh2_session_init(); int ind; for(ind=0;ind<5;ind++) if (!libssh2_session_startup(session, sock))break; if(ind==5) { if(sock) { #ifdef WIN32 closesocket(sock); #else close(sock); #endif } connection(&sock); for(ind=0;ind<5;ind++) if (!libssh2_session_startup(session, sock))break; if(ind==5) { fprintf(stderr, "Nie udało się nawiązać sesji SSH\n"); return-1; } } fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5); /* check what authentication methods are available */ userauthlist = libssh2_userauth_list(session, configusername, strlen(configusername)); //printf("Authentication methods: %s\n", userauthlist); if (strstr(userauthlist, "password") != NULL) { auth_pw |= 1; } if (strstr(userauthlist, "keyboard-interactive") != NULL) { auth_pw |= 2; } if (strstr(userauthlist, "publickey") != NULL) { auth_pw |= 4; } if (auth_pw & 1) { /* We could authenticate via password */ if (libssh2_userauth_password(session, configusername, configpassword)) { printf("\nNieprawidłowy login lub hasło!\n"); return -2; /*goto shutdown;*/ } else { // printf("\tAuthentication by password succeeded.\n"); } } else if (auth_pw & 2) { /* Or via keyboard-interactive */ if (libssh2_userauth_keyboard_interactive(session, configusername, &kbd_callback) ) { printf("\tAuthentication by keyboard-interactive failed!\n"); return -2; /*goto shutdown;*/ } else { printf("\tAuthentication by keyboard-interactive succeeded.\n"); } } else if (auth_pw & 4) { /* Or by public key */ if (libssh2_userauth_publickey_fromfile(session, configusername, keyfile1, keyfile2, configpassword)) { printf("\tAuthentication by public key failed!\n"); return -2; /*goto shutdown;*/ } else { printf("\tAuthentication by public key succeeded.\n"); } } else { printf("No supported authentication methods found!\n"); return -2; /*goto shutdown;*/ } /* Request a shell */ if (!(channel = libssh2_channel_open_session(session))) { fprintf(stderr, "Unable to open a session\n"); return -2; /*goto shutdown;*/ } // libssh2_channel_setenv(channel, "FOO", "bar"); /* * See /etc/termcap for more options */ char *termtype; termtype = getenv("TERM"); if (libssh2_channel_request_pty(channel, "vt102")) { fprintf(stderr, "Failed requesting pty\n"); return -3; /*goto skip_shell;*/ } /* Open a SHELL on that pty */ if (libssh2_channel_shell(channel)) { fprintf(stderr, "Unable to request shell on allocated pty\n"); return -2; /*goto shutdown;*/ } *chanel=channel; *sesion=session; return 1; } int mainloop(LIBSSH2_CHANNEL *channel) { char schelout[2*BUFFSIZE]; char c[2]; int readlen,flags; /*set stdin nonblockign*/ flags = fcntl(0, F_GETFL, 0); flags |= O_NONBLOCK; fcntl(0, F_SETFL, flags); /*set ssh channel nonblockign*/ libssh2_channel_set_blocking(channel, 0); libssh2_channel_handle_extended_data2(channel, LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE); /*set getch noecho*/ struct termios attrs,oldattrs; tcgetattr( 0, &attrs ); tcgetattr( 0, &oldattrs ); attrs.c_cc[VINTR] = 0; attrs.c_cc[VSUSP] = 0; tcsetattr( 0, 0, &attrs ); int i=0; initscr(); while(1) /*main loop*/ { libssh2_channel_flush_ex(channel,LIBSSH2_CHANNEL_FLUSH_ALL); /*reading*/ for(i=0;i<BUFFSIZE;i++)schelout[i]=0; readlen=libssh2_channel_read(channel,schelout,HALFBUFFSIZE); if(readlen>0) { printf("%s",schelout); fflush(stdout); } /*writing*/ c[0]=getch(); c[1]='\0'; if(c[0]!=-1) { libssh2_channel_write(channel,c,strlen(c)); libssh2_channel_flush(channel); } if(libssh2_channel_eof(channel)==1)break; } flags = fcntl(0, F_GETFL, 0); /*reseting terminal configuration*/ flags &= ~O_NONBLOCK; fcntl(0, F_SETFL, flags); tcsetattr( 0, 0, &oldattrs ); return 1; } int main(int argc, char* argv[]) { int sock; char tekst[128]; session=NULL; channel=NULL; sock=0; if(connection(&sock)==-1) { exit(1); } if (makeconnection(&session,&channel,&sock)==1) { system("clear"); mainloop(channel); } else { /*else faild to connect*/ getchar(); } /*disconnection*/ if (channel) { libssh2_channel_free(channel); channel = NULL; } if(session) { libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing"); libssh2_session_free(session); } if(sock) { close(sock); } return 0; }
_______________________________________________ libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel