aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAris Adamantiadis <aris@0xbadc0de.be>2009-12-11 23:26:25 +0100
committerAris Adamantiadis <aris@0xbadc0de.be>2009-12-11 23:26:25 +0100
commit3ace7817b4c438d34f63313493cd82ae0dcf2757 (patch)
tree998a5415377a1e1b7006059a093d37ce179202b5
parent0de35ca8f09cf6d2ac101db3730cea58ca72caf1 (diff)
downloadlibssh-3ace7817b4c438d34f63313493cd82ae0dcf2757.tar.gz
libssh-3ace7817b4c438d34f63313493cd82ae0dcf2757.tar.xz
libssh-3ace7817b4c438d34f63313493cd82ae0dcf2757.zip
Async connection + banner fetch is working
-rw-r--r--include/libssh/session.h2
-rw-r--r--libssh/client.c26
-rw-r--r--libssh/packet.c4
-rw-r--r--libssh/socket.c42
4 files changed, 37 insertions, 37 deletions
diff --git a/include/libssh/session.h b/include/libssh/session.h
index 09ed655d..2dae9ccb 100644
--- a/include/libssh/session.h
+++ b/include/libssh/session.h
@@ -65,8 +65,6 @@ struct ssh_session_struct {
ssh_string banner; /* that's the issue banner from
the server */
- char *remotebanner; /* that's the SSH- banner from
- remote host. */
char *discon_msg; /* disconnect message from
the remote host */
ssh_buffer in_buffer;
diff --git a/libssh/client.c b/libssh/client.c
index 580a7d5c..117afe90 100644
--- a/libssh/client.c
+++ b/libssh/client.c
@@ -67,6 +67,21 @@ static void socket_callback_connected(int code, int errno, void *user){
/**
* @internal
+ * @brief Callback to be called when the socket received an exception code.
+ * @param user is a pointer to session
+ */
+static void socket_callback_exception(int code, int errno, void *user){
+ ssh_session session=(ssh_session)user;
+ enter_function();
+ ssh_log(session,SSH_LOG_RARE,"Socket exception callback: %d (%d)",code, errno);
+ session->session_state=SSH_SESSION_STATE_ERROR;
+ ssh_set_error(session,SSH_FATAL,"Socket error: %s",strerror(errno));
+ connection_callback(session);
+ leave_function();
+}
+
+/**
+ * @internal
*
* @brief Gets the banner from socket and saves it in session.
* Updates the session state
@@ -96,8 +111,9 @@ static int callback_receive_banner(const void *data, size_t len, void *user) {
str=strdup(buffer);
/* number of bytes read */
ret=i+1;
- session->remotebanner=str;
+ session->serverbanner=str;
session->session_state=SSH_SESSION_STATE_BANNER_RECEIVED;
+ ssh_log(session,SSH_LOG_PACKET,"Received banner: %s",str);
connection_callback(session);
leave_function();
return ret;
@@ -510,6 +526,7 @@ static void connection_callback(ssh_session session){
case SSH_SESSION_STATE_NONE:
case SSH_SESSION_STATE_CONNECTING:
case SSH_SESSION_STATE_SOCKET_CONNECTED:
+ break;
case SSH_SESSION_STATE_BANNER_RECEIVED:
if (session->serverbanner == NULL) {
goto error;
@@ -535,9 +552,11 @@ static void connection_callback(ssh_session session){
}
/* from now, the packet layer is handling incoming packets */
session->socket_callbacks.data=ssh_packet_socket_callback;
+ ssh_packet_set_default_callbacks(session);
ssh_send_banner(session, 0);
set_status(session, 0.5);
session->session_state=SSH_SESSION_STATE_INITIAL_KEX;
+ break;
case SSH_SESSION_STATE_INITIAL_KEX:
switch (session->version) {
case 2:
@@ -614,6 +633,7 @@ int ssh_connect(ssh_session session) {
ssh_socket_set_callbacks(session->socket,&session->socket_callbacks);
session->socket_callbacks.connected=socket_callback_connected;
session->socket_callbacks.data=callback_receive_banner;
+ session->socket_callbacks.exception=socket_callback_exception;
session->socket_callbacks.user=session;
if (session->fd != -1) {
ssh_socket_set_fd(session->socket, session->fd);
@@ -631,11 +651,13 @@ int ssh_connect(ssh_session session) {
set_status(session, 0.2);
session->alive = 1;
+ ssh_log(session,SSH_LOG_PROTOCOL,"Socket connecting, now waiting for the callbacks to work");
while(session->session_state != SSH_SESSION_STATE_ERROR &&
session->session_state != SSH_SESSION_STATE_AUTHENTICATING){
/* loop until SSH_SESSION_STATE_BANNER_RECEIVED or
* SSH_SESSION_STATE_ERROR */
-
+ ssh_handle_packets(session);
+ ssh_log(session,SSH_LOG_PACKET,"ssh_connect: Actual state : %d",session->session_state);
}
leave_function();
return 0;
diff --git a/libssh/packet.c b/libssh/packet.c
index ef406bcc..09b0a745 100644
--- a/libssh/packet.c
+++ b/libssh/packet.c
@@ -311,7 +311,7 @@ void ssh_packet_set_default_callbacks(ssh_session session){
*/
void ssh_packet_process(ssh_session session, uint8_t type){
struct ssh_iterator *i;
- int r;
+ int r=SSH_PACKET_NOT_USED;
ssh_packet_callbacks cb;
enter_function();
ssh_log(session,SSH_LOG_PACKET, "Dispatching handler for packet type %d",type);
@@ -335,6 +335,8 @@ void ssh_packet_process(ssh_session session, uint8_t type){
if(r==SSH_PACKET_USED)
break;
}
+ if(r==SSH_PACKET_NOT_USED)
+ ssh_log(session,SSH_LOG_RARE,"Couldn't do anything with packet type %d",type);
error:
leave_function();
}
diff --git a/libssh/socket.c b/libssh/socket.c
index 93e76a0d..85afe81a 100644
--- a/libssh/socket.c
+++ b/libssh/socket.c
@@ -163,7 +163,7 @@ int ssh_socket_pollcallback(ssh_poll_handle p, int fd, int revents, void *v_s){
if(r<0){
if(p != NULL)
ssh_poll_set_events(p,ssh_poll_get_events(p) & ~POLLIN);
- if(s->callbacks){
+ if(s->callbacks && s->callbacks->exception){
s->callbacks->exception(
SSH_SOCKET_EXCEPTION_ERROR,
s->last_errno,s->callbacks->user);
@@ -171,7 +171,7 @@ int ssh_socket_pollcallback(ssh_poll_handle p, int fd, int revents, void *v_s){
}
if(r==0){
ssh_poll_set_events(p,ssh_poll_get_events(p) & ~POLLIN);
- if(s->callbacks){
+ if(s->callbacks && s->callbacks->exception){
s->callbacks->exception(
SSH_SOCKET_EXCEPTION_EOF,
0,s->callbacks->user);
@@ -180,7 +180,7 @@ int ssh_socket_pollcallback(ssh_poll_handle p, int fd, int revents, void *v_s){
if(r>0){
/* Bufferize the data and then call the callback */
buffer_add_data(s->in_buffer,buffer,r);
- if(s->callbacks){
+ if(s->callbacks && s->callbacks->data){
r= s->callbacks->data(buffer_get_rest(s->in_buffer),
buffer_get_rest_len(s->in_buffer),
s->callbacks->user);
@@ -206,12 +206,12 @@ int ssh_socket_pollcallback(ssh_poll_handle p, int fd, int revents, void *v_s){
buffer_get_rest_len(s->out_buffer));
if(w>0)
buffer_pass_bytes(s->out_buffer,w);
- } else if(s->callbacks){
+ } else if(s->callbacks && s->callbacks->controlflow){
/* Otherwise advertise the upper level that write can be done */
s->callbacks->controlflow(SSH_SOCKET_FLOW_WRITEWONTBLOCK,s->callbacks->user);
- ssh_poll_set_events(p,ssh_poll_get_events(p) & ~POLLOUT);
- /* TODO: Find a way to put back POLLOUT when buffering occurs */
}
+ ssh_poll_remove_events(p,POLLOUT);
+ /* TODO: Find a way to put back POLLOUT when buffering occurs */
}
return 0;
}
@@ -785,7 +785,6 @@ int ssh_socket_get_status(ssh_socket s) {
int ssh_socket_connect(ssh_socket s, const char *host, int port, const char *bind_addr){
socket_t fd;
ssh_session session=s->session;
- ssh_poll_ctx ctx;
enter_function();
if(s->state != SSH_SOCKET_NONE)
return SSH_ERROR;
@@ -795,31 +794,10 @@ int ssh_socket_connect(ssh_socket s, const char *host, int port, const char *bin
return SSH_ERROR;
ssh_socket_set_fd(s,fd);
s->state=SSH_SOCKET_CONNECTING;
- if(s->callbacks && s->callbacks->connected && s->poll){
- /* POLLOUT is the event to wait for in a nonblocking connect */
- ssh_poll_set_events(s->poll,POLLOUT);
- leave_function();
- return SSH_OK;
- } else {
- /* we have to do the connect ourselves */
- ssh_poll_set_events(ssh_socket_get_poll_handle(s),POLLOUT);
- ctx=ssh_poll_ctx_new(1);
- ssh_poll_ctx_add(ctx,s->poll);
- while(s->state == SSH_SOCKET_CONNECTING){
- ssh_poll_ctx_dopoll(ctx,-1);
- }
- ssh_poll_ctx_free(ctx);
- if(s->state == SSH_SOCKET_CONNECTED){
- ssh_log(session,SSH_LOG_PACKET,"ssh_socket_connect blocking: connected");
- leave_function();
- return SSH_OK;
- } else {
- ssh_log(session,SSH_LOG_PACKET,"ssh_socket_connect blocking: not connected");
- ssh_set_error(session,SSH_FATAL,"Error during blocking connect: %d",s->last_errno);
- leave_function();
- return SSH_ERROR;
- }
- }
+ /* POLLOUT is the event to wait for in a nonblocking connect */
+ ssh_poll_set_events(ssh_socket_get_poll_handle(s),POLLOUT);
+ leave_function();
+ return SSH_OK;
}
/** @}
*/