I don't think you have gone so far for keycodes to be a problem. From the message you gave, I suspect you called an async function, but treated it as sync, erroring out instead of waiting.
Suppose we have the following code snippet:
n = recv(socket, buffer, sizeof buffer, 0);
if (n == -1) {
err(1, "Error receiving data from socket");
}
<work with the n bytes received on buffer>
This is perfectly fine for a synchronous socket in most cases¹, but if it is an asynchronous operation (you passed MSG_DONTWAIT on flags, or set O_NONBLOCK with fcntl/setsockopt) you should expect that it returns -1 with EAGAIN
as error number.
¹ On a real application you should also be handling EINTR (eg. the process received a signal).
In this case you are receiving EINPROGRESS, from which we can gather that the "failing" function that didn't complete is connect(). See what are possible reason for socket error einprogress?
The connect(2) man page is also very explicit about this error:
EINPROGRESS
The socket is nonblocking and the connection cannot be completed immediately.
It is possible to select(2) or poll(2) for completion by selecting the
socket for writing. After select(2) indicates writability, use getsockopt(2)
to read the SO_ERROR option at level SOL_SOCKET to determine whether connect()
completed successfully (SO_ERROR is zero) or unsuccessfully (SO_ERROR is
one of the usual error codes listed here, explaining the reason for the failure).
You can either change libssh to blocking with ssh_set_blocking() or use select/poll on the socket with ssh_get_poll_flags() flags.