[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: libssh questions
[Thread Prev] | [Thread Next]
- Subject: Re: libssh questions
- From: Vishwanathan Chandru <vishwanathanc@xxxxxxxxx>
- Reply-to: libssh@xxxxxxxxxx
- Date: Wed, 18 Nov 2020 08:32:43 -0800
- To: libssh@xxxxxxxxxx
Hello, I am not sure what's the follow up process. Requesting some pointers or suggestions or answers for these question(s). Thanks, Vish On Mon, Nov 9, 2020 at 8:12 AM Vishwanathan Chandru <vishwanathanc@xxxxxxxxx> wrote: > Hello, > > My name is Vish and I am a newbie to socket programming in general. This > library was very easy to understand and made my life easier as > I got curious about secure communications, so would like to thank the > developers. > > I am trying to develop a peer to peer application using libssh (for > learning sake). From the documentation it seems like using > ssh_event_dopoll seems to be the way to go. There's also some aspect of > non-secure communication with a local client and ssh_event_dopoll > handles it fine. > > Here's what I am came up with for the server implementation: > > int process_call_back(socket_t fd, int revents, void* userdata) { > if(revents & POLLIN) { > // non libssh socket > if(fd == normal_listener_socket_fd) { > // accept and all. > } > if(fd == ssh_listener_socket) { > // allocate session > sd = accept(fd...) > int rc = fcntl(sd, F_SETFL, O_NONBLOCK); > ssh_bind_accept_fd(sshbind, session, new_sd); > // one of these callbacks set the channel_data_function > to keep track of data coming from ssh client via channels. > ssh_callbacks_init(&cb); > ssh_set_server_callbacks(session, &cb); > ssh_callbacks_init(&scb); > ssh_set_callbacks(session, &scb); > if (ssh_handle_key_exchange(session)) { > printf("ssh_handle_key_exchange: %s\n", > ssh_get_error(session)); > } else { > ssh_set_auth_methods(session,SSH_AUTH_METHOD_PASSWORD); > ssh_event_add_session(mainloop, session); > } > } > else if(is_non_ssh_socket(fd)) { > recv(fd) > send(fd...) > } > } > } > > int main() { > // setup boilerplate > if (ssh_bind_listen(sshbind) < 0) { > printf("Error listening to socket: %s\n", > ssh_get_error(sshbind)); > return 1; > } > ssh_listener_socket = ssh_bind_get_fd(sshbind); > ssh_event_add_fd(mainloop, ssh_listener_socket, POLLIN, > process_call_back, NULL); > ssh_event_add_fd(mainloop, ssh_listener_socket, POLLPRI, > process_call_back, NULL); > do { > if(ssh_event_dopoll(mainloop, -1)) == SSH_ERROR) { > printf("\n something went wrong with errno %d ", errno); > for(auto session : sessions) { > // check if session is alive > if(ssh_is_connected(session)) { > continue; > } > else { > auto emsg = ssh_get_error(session); > auto ecode = ssh_get_error_code(session); > // this session has gone to hell, take it out > ssh_event_remove_session(mainloop, session); > // more possible cleanup here. > } > } > } > } while (true) > } > > Now this thing works. I was hoping to use incoming_connections callback on > ssh_bind to accept incoming ssh connections but it didnt > seem to work out. Is this the best way to achieve this? > > Second question is about handling timeouts and connection closures. I came > across this > thread https://www.libssh.org/archive/libssh/2019-03/0000011.html, which > answered some questions. So I came up with do while loop > style error handling, if ssh_event_dopoll returns error, loop through all > the active sessions and remove the bad session using > ssh_is_connected. Is there a better way to acheive the error handling? > > Third question is I also want to add the client part of the code (since > this a peer to peer application). I understand that there is non blocking > usage of ssh_connect. > From what I can read in the documentation, I will have to call ssh_connect > if SSH_AGAIN is returned and until it returns SSH_OK, I cannot > proceed with the authentication step. Can I do something like this on a > separate thread (the previous code snippet will be in the server thread)? > > ssh_session session; > int session_fd = -1; > int connected = 0; > > int process_call_back(socket_t fd, int revents, void* userdata) { > if(revents & POLLOUT) { > if(fd == session_fd) { > int optval = 0; > int optlen = sizeof(optval); > int rc = getsockopt(fd, SOL_SOCKET, SO_ERROR, &optval, optlen); > if (optval == 0 ) { > rc = ssh_connect(session); > } > if (rc == SSH_OK) { > // remove the fd, because session callbacks will be added. > ssh_event_remove_fd(mainloop, fd); > // enable the blocking mode otherwise we have to call authentication > // until it returns success. > ssh_is_blocking(session, 1); > // authenticate > .... > // set the channels and associate callbacks > .... > // add the session to event loop. > ssh_event_add_session(mainloop, session); > connected = 1; > } > } > } > } > > > int main() { > // boiler plate > .... > session = ssh_new(); > ssh_set_blocking(session, 0); > int rc = ssh_connect(session); > if (rc == SSH_ERROR) { > return 1; > } > if (rc == SSH_AGAIN) { > session_fd = ssh_get_fd(session); > // add POLLOUT for eastablishing connection > ssh_event_add_fd(mainloop, session_fd, POLLOUT, process_call_back, NULL); > } > do { > if (ssh_event_dopoll(mainloop, -1) == SSH_ERROR) { > break; > } > } while (!connected); > // exchange buffers with server via channel read/write > ... > } > > Thanks and Best regards, > Vish >
libssh questions | Vishwanathan Chandru <vishwanathanc@xxxxxxxxx> |