[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Async Socket Interface


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);
>
>
>
>   


References:
Async Socket Interface"Preston A. Elder" <prez@xxxxxxxxxxxxxx>
Archive administrator: postmaster@lists.cynapses.org