[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Async Socket Interface
[Thread Prev] | [Thread Next]
- Subject: Re: Async Socket Interface
- From: Aris Adamantiadis <aris@xxxxxxxxxxxx>
- Reply-to: libssh@xxxxxxxxxx
- Date: Tue, 06 Oct 2009 16:48:10 +0200
- To: libssh@xxxxxxxxxx
Hello there, I made a little graph of how I see the flow of calls, from socket to user program. The upward direction (^) shows a forward call (std call). A bottom one (v) indicates a reverse call, ie a callback. Each layer will provide functions to registers callbacks (reverse function calls) and ideally each layer will also provide its interface (forward function calls) in a structure so it's easy to replace (socket comes to mind). Also, look how channel and socket are similar. Idealy one could do ssh over ssh easily with this... I also have glibnet integration in mind. Feel free to comment. Regards, Aris Aris Adamantiadis a écrit : > Hello Preston, > > I did some work during the holiday and as you will see I have made some > work in this direction. > > Just check out the branch libssh_async which can be found on > git clone http://www.0xbadc0de.be/git/libssh/libssh_async.git > (or some git add trickery if you manage to make it work.) > It's the skeleton of the future asyncronous libssh. Don't try to run it, > it doesn't really work (only some part of the calls have been made async > and there is not yet an integrated main loop provider). > > The callback systems (that is, reverse calls) are all made virtual > through function pointers, between the different layers of the library. > The forward calls (ie. send_packet() and al) are still hardcoded but > could be set the same way. > > Please feel free to comment on what you think about this, if I am going > in the good direction or not. I really think it is. > > Regards, > > Aris > > Preston A. Elder a écrit : >> I just realized in the below code I refer to 'OpenSSL' and 'LibSSL'. >> Both should be 'libssh'. >> >> Sorry for the confusion. >> >> PreZ :) >> >> Preston A. Elder wrote: >>> Aris et al, >>> >>> Here is the interface I conceived of for a communications layer that is >>> both a) replaceable and b) easy to adapt to any situation (including not >>> using TCP sockets for communications). Not to mention easy to implement >>> ;) I posted this in IRC a while back, but you mentioned you lost it. >>> >>> Two key concepts here are that there is a handle provided by the comms >>> implementation to libssl upon a connection being established, and libssl >>> provides back another handle (ssh_session) back to the comms layer which >>> is used for future communications. Both of these handles should be >>> opaque to the other (ie. the imeplementation does not matter). This >>> allows libssl to change the implementation of ssh_session, or the comms >>> implementor to change the implementation of their handle at will without >>> affecting the other at all. >>> >>> The interface itself consists of only 3 function calls and 2 >>> callbacks. ALL the details regarding how to setup the socket, whether >>> it's blocking >>> or not, how to send or receive data, or anything of the like are in the >>> complete control of the comms layer implementor. I also made sure that >>> all buffering (in both directions) of data is done in the comms layer. >>> >>> This, though, requires that libssl itself must be 'reactionary' to >>> received data, and not have any wait calls or anything that will require >>> libssl to have to block waiting for more data to arrive before being >>> able to do anything. This may mean some functions such as ssh_accept >>> need to be split up and/or rewritten to be able to handle that the send >>> and receive operations are separate entities. >>> >>> Proposed Interface: >>> >>> // --------------------------------------------------------------------- >>> // Callbacks >>> // --------------------------------------------------------------------- >>> >>> // Description: >>> // Callback to have data sent over the wire to the other side. >>> // >>> // It is the implementor's responsibility to ensure that all data >>> // gets to the other side. This could mean blocking while waiting >>> // for the send to complete, or it could mean the data has been >>> // buffered and will be sent asynchronously. >>> // Arguments: >>> // void * handle - Opaque (to libssl) handle for socket. >>> // void * buffer - Raw buffer to be sent over the wire. >>> // size_t size - Size of raw buffer. >>> // Return: >>> // int - 0 on success, otherwise -1 >>> typedef int (*comm_send_data)(void *, void *, size_t); >>> >>> // Description: >>> // Callback to request the communications channel be closed. >>> // Arguments: >>> // void * handle - Opaque (to libssl) handle for socket. >>> typedef void (*comm_close)(void *); >>> >>> // --------------------------------------------------------------------- >>> // LibSSL API >>> // --------------------------------------------------------------------- >>> >>> // Description: >>> // Create a libssl session from a newly created comms channel. >>> // Arguments: >>> // handle - Opaque (to libssl) handle for socket. >>> // send_func - Function pointer (see above) for sending data. >>> // close_func - Function pointer (see above) for closing socket. >>> // Return: >>> // ssl_esssion * - Opaque (to comms implementation) handle for an >>> // OpenSSL session. >>> ssl_session *session_create(void *handle, comm_send_data send_func, >>> comm_close close_func); >>> >>> // Description: >>> // Process data received over the wire. >>> // >>> // It is expected that LibSSL will take what it wants from the >>> // buffer and tell you how much it has taken. It is then assumed >>> // the caller will, if the entire buffer was not consumed, prepend >>> // the unconsumed data to the next invocation of this function call. >>> // The next invocation only need be made when there is additional >>> // date come over the wire (ie. there is no need to call this in a >>> // loop until 0 is returned), LibSSL will always consume as much as >>> // it can while still having fully-formed messages. >>> // Arguments: >>> // handle - Opaque (to comms implementation) handle for an >>> // OpenSSL session. >>> // buffer - Raw buffer received over the wire. >>> // size - Size of raw buffer. >>> // Return: >>> // int - The amount of data consumed. Or -1 on error. >>> int session_receive(ssl_session *handle, void *data, size_t sz); >>> >>> // Description: >>> // Callback to indicate the comms channel has been closed by the >>> // other side (ie. unsolicited closure). >>> // Arguments: >>> // handle - Opaque (to comms implementation) handle for an >>> // OpenSSL session. >>> void session_close(ssl_session *handle); >>> >>> >>> >>> >> >> >
Archive administrator: postmaster@lists.cynapses.org