Hi Feng,

Your program seems fine, but I've never used servers in a thread so I'm
not sure where's the problem.
Could you tell us which version of libssh you're using, and also what's
the output when sessions are in debug mode as described
here:http://api.libssh.org/master/guided_tour.html

Thanks,

Aris

Le 15/09/10 10:53, Feng Yi a écrit :
> Dear Developers,
> 
> Our company is currently using libssh for developing server side
> softwares. Thanks for your wonderful work.
> 
> Here 's problem we met. When we are trying to develop multithread ssh
> server to serve clients (each client has its serving thread), the server
> only responses to the newly added client ! ie. the old connection is not
> responsing anymore after new client joins. And after the newly added
> client quits, the old connection recover again !!!
> 
> We search through the internet but find little help. Could you please
> give me a hint?.
> 
> Here's the sshd like code we use:
> 
> 
> #include <libssh/libssh.h>                                        
> #include <libssh/server.h>                                        
> #include <argp.h>                                                 
> #include <stdlib.h>                                               
> #include <string.h>                                               
> #include <stdio.h>                                                
> #include <unistd.h>                                               
> #include <string>                                                 
> #include <iostream>                                               
> #include <boost/thread.hpp>                                       
> 
> static int auth_password(char *user, char *password){
>     if(strcmp(user,"aris"))                         
>         return 0;                                   
>     if(strcmp(password,"lala"))                     
>         return 0;                                   
>     return 1; // authenticated                      
> }                                                   
> 
> class Console
> {           
> public:     
>     explicit Console(const std::string addr,
>                      const std::string port)
>        
> :addr_(addr),port_(port),SSH_HOST_DSA_KEY_PATH_("./ssh_host_dsa_key"),SSH_HOST_RSA_KEY_PATH_("./ssh_host_rsa_key"){}
>                                                                               
>                                        
> 
>    
> ~Console(){};                                                                 
>                                       
> 
> 
> private:
>     Console(const Console&);
>     Console& operator=(const Console&);
> 
> private:
>     std::string addr_;
>     std::string port_;
>     std::string SSH_HOST_DSA_KEY_PATH_;
>     std::string SSH_HOST_RSA_KEY_PATH_;
>     //ssh_session session;            
>     ssh_bind sshbind;                 
>     //ssh_message message;            
>     //ssh_channel chan;               
>     //int i;                          
> 
> public:
>     int32_t Start() {
>         sshbind=ssh_bind_new();
> 
>         ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY,
> SSH_HOST_DSA_KEY_PATH_.c_str());
>         ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY,
> SSH_HOST_RSA_KEY_PATH_.c_str());
>         ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR,
> port_.c_str());          
>         //ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY,
> arg);                       
>         //ssh_bind_options_set(sshbind,
> SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "3");             
>         ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR,
> addr_.c_str());              
> 
>         if (ssh_bind_listen(sshbind) < 0) {
>             std::cout << "ERROR: listening to socket: " <<
> ssh_get_error(sshbind) << std::endl;
>            
> ssh_bind_free(sshbind);                                                       
>     
> 
>             return
> -1;                                                                        
>        
> }                                                                             
>         
> 
>         for(;;)
> {                                                                             
> 
>             ssh_session
> session=ssh_new();                                                    
>             if (ssh_bind_accept(sshbind,session) != SSH_ERROR) {
>                 // every client will use a thread running Session(...)
>                             
>                 boost::thread *t = new
> boost::thread(boost::bind(&Console::Session, this, session));
>                
> sleep(10);                                                                    
>      
> 
>             }else
> {                                                                             
>    
> 
>                 std::cout << "ERROR: accepting a connection: " <<
> ssh_get_error(sshbind) << std::endl;
>                
> ssh_bind_free(sshbind);                                                       
>        
> 
>                
> ssh_free(session);                                                            
>        
> 
>                 return
> -1;                                                                           
> 
>            
> }                                                                             
>            
> 
>        
> }                                                                             
>                
> 
>    
> }                                                                             
>                    
> 
> 
>     int32_t Session(ssh_session newSession) {
>         ssh_session session = newSession;   
>         ssh_channel chan = 0;               
>         ssh_message message;                
>         int auth = 0;                       
>         int sftp = 0;                       
>         if (ssh_handle_key_exchange(session)) {
>             std::cout << "ERROR: ssh_handle_key_exchange: " <<
> ssh_get_error(session) << std::endl;
>             return
> -1;                                                                           
>  
> 
>        
> }                                                                             
>             
> 
>         do
> {                                                                             
>          
> 
>            
> message=ssh_message_get(session);                                             
>         
> 
>            
> if(!message)                                                                  
>         
> 
>                
> break;                                                                        
>     
> 
>            
> switch(ssh_message_type(message)){                                            
>         
> 
>             case
> SSH_REQUEST_AUTH:                                                             
>    
> 
>                
> switch(ssh_message_subtype(message)){                                         
>     
> 
>                 case
> SSH_AUTH_METHOD_PASSWORD:                                                    
> 
>                     std::cout << "User " <<
> ssh_message_auth_user(message) << " wants to auth with pass " <<
>                         ssh_message_auth_password(message) <<
> std::endl;                                   
>                    
> if(auth_password(ssh_message_auth_user(message),                              
>          
> 
>                                     
> ssh_message_auth_password(message))){                                 
>                        
> auth=1;                                                                       
>      
> 
>                        
> ssh_message_auth_reply_success(message,0);                                    
>      
> 
>                        
> break;                                                                        
>      
> 
>                    
> }                                                                             
>          
> 
>                     // not authenticated, send default
> message                                             
>                 case
> SSH_AUTH_METHOD_NONE:                                                         
>         
> 
>                
> default:                                                                      
>              
> 
>                    
> ssh_message_auth_set_methods(message,SSH_AUTH_METHOD_PASSWORD);               
>          
> 
>                    
> ssh_message_reply_default(message);                                           
>          
> 
>                    
> break;                                                                        
>          
> 
>                
> }                                                                             
>              
> 
>                
> break;                                                                        
>              
> 
>            
> default:                                                                      
>                  
> 
>                
> ssh_message_reply_default(message);                                           
>              
> 
>            
> }                                                                             
>                  
> 
>            
> ssh_message_free(message);                                                    
>                  
> 
>         } while
> (!auth);                                                                      
>              
> 
>        
> if(!auth){                                                                    
>                      
> 
>             std::cout << "ERROR: auth error: " << ssh_get_error(session)
> << std::endl;                     
>            
> ssh_disconnect(session);                                                      
>                  
> 
>             return
> -1;                                                                           
>           
> 
>        
> }                                                                             
>                      
> 
>         do
> {                                                                             
>                   
> 
>            
> message=ssh_message_get(session);                                             
>                  
> 
>            
> if(message){                                                                  
>                  
> 
>                
> switch(ssh_message_type(message)){                                            
>              
> 
>                 case
> SSH_REQUEST_CHANNEL_OPEN:                                                     
>         
> 
>                    
> if(ssh_message_subtype(message)==SSH_CHANNEL_SESSION){                        
>          
> 
>                        
> chan=ssh_message_channel_request_open_reply_accept(message);                  
>      
> 
>                        
> break;                                                                        
>      
> 
>                    
> }                                                                             
>          
> 
>                
> default:                                                                      
>              
> 
>                    
> ssh_message_reply_default(message);                                           
>          
> 
>                
> }                                                                             
>              
> 
>                
> ssh_message_free(message);                                                    
>              
> 
>            
> }                                                                             
>                  
> 
>         } while(message &&
> !chan);                                                                       
>   
> 
>        
> if(!chan){                                                                    
>                      
> 
>             std::cout << "ERROR: " << ssh_get_error(session) <<
> std::endl;                                 
>             return
> -1;                                                                           
>           
> 
>        
> }                                                                             
>                      
> 
>         do
> {                                                                             
>                   
> 
>            
> message=ssh_message_get(session);                                             
>                  
> 
>             if(message && ssh_message_type(message)==SSH_REQUEST_CHANNEL
> &&                                
>               
> ssh_message_subtype(message)==SSH_CHANNEL_REQUEST_SHELL){                     
>               
> 
>                 //           
> if(!strcmp(ssh_message_channel_request_subsystem(message),"sftp")){          
> 
>                
> sftp=1;                                                                       
>              
> 
>                
> ssh_message_channel_request_reply_success(message);                           
>              
> 
>                
> break;                                                                        
>              
> 
>                 //          
> }                                                                             
> 
>            
> }                                                                             
>                  
> 
>            
> if(!sftp){                                                                    
>                  
> 
>                
> ssh_message_reply_default(message);                                           
>              
> 
>            
> }                                                                             
>                  
> 
>             ssh_message_free(message);
>         } while (message && !sftp);
>         if(!sftp){
>             std::cout << "ERROR: " << ssh_get_error(session) << std::endl;
>             return -1;
>         }
>         printf("it works !\n");
>         char buf[2048];
>         int i = 0;
>         ssh_channel_write(chan, "#:", 2);
>         do{
>             i = ssh_channel_read(chan, buf, 2048, 0);
>             if (i > 0) {
>                 ssh_channel_write(chan, buf, i);
>                 if (buf[0] == 'q') {
>                     break;
>                 }
>                 if (buf[0] == '\r'|| buf[i] == '\r')
>                     ssh_channel_write(chan, "\r\nabcd\r\n#:", 10);
>                 if (write(1,buf,i) < 0) {
>                     printf("error writing to buffer\n");
>                     return 1;
>                 }
>             }
>         } while (i > 0);
>         ssh_disconnect(session);
>         ssh_channel_close(chan); //?
>         ssh_channel_free(chan); //?
>         ssh_free(session);
>         return 0;
>     }
>     int32_t Stop()
>     {
>         ssh_finalize();
>     }
> };
> 
> int main()
> {
>     Console c("127.0.0.1", "1200");
>     c.Start();
> 
>     return 0;
> }
> 
> 
> Thanks & Best Regards,
> FY
> 
> 


Reply via email to