Missed this thread earlier. I am quite interested in this proposal. It is similar to Dean Gaudet's iol work in early Apache 2.0 and is pretty much in line with what I was needing/thinking as well. Any interest in reviving this? The implementation should be quite straightforward. I'll start working on pieces if there is general agreement this is a good thing to do (I think it is).
Bill Stoddard ----- Original Message ----- From: "Sander Striker" <[EMAIL PROTECTED]> To: <[email protected]> Cc: <[EMAIL PROTECTED]>; <[EMAIL PROTECTED]> Sent: Wednesday, February 28, 2001 6:47 AM Subject: [RFC] Network Abstraction Layer > Hi, > > Before I start throwing stuff at you, I'll introduce myself. > I'm Sander Striker, one of the Samba TNG team members. We have > been looking at the APR a bit to find out if we can use it in > our code. > > It looks all very promissing and that's why we want to contribute > some ideas to (from our point of view) improve the APR. The first > thing we are going to need is a higher level of abstraction for > the network layer. We have a complicated (to explain to outsiders) > protocol stack in which protocols can be called upon from several > layers. > Example: > > +-------------------+ > | D | > +---------+ | > | C | | > | +----+----+ | > | | B | | > +----+----+---------+ > | A | > +-------------------+ > > In short: > > A <> B > A <> B <> C > A <> B <> C <> D > A <> C > A <> C <> D > A <> D > > To make it even more complex B can run over other things than A... > > But, I'm boring you guys, so I'll proceed. > > Below is a simple draft of the NAL. The goal is to be able to > add transports easily, even when not present in the kernel. > Also this allows an easy way of protocol/transport stacking. > A 'transport' can also do buffering, authentication, filtering. > > Ignore name clashes with current APR code please. > Also, I haven't looked into the apr_pool package to understand > how it works quite yet. I want it to be _possible_ to tie transports > to memory management (so we can dump all memory that we used for: > a session, a request, a reply, etc). > > I'll post a memory management draft aswell in a few days. It will > be similar to this when it comes abstraction. > > Thanks, > > Sander > > > /* typedefs */ > > typedef struct apr_socket_t apr_socket_t; > typedef struct apr_transport_t apr_transport_t; > > typedef int apr_transport_id_t; > /* maybe this should be a string?? So you can > * do apr_socket_create("smb", &socket, some_pool) */ > > > typedef apr_status_t (*apr_socket_create_fn_t) (apr_socket_t **socket, > apr_pool_t *context); > > typedef apr_status_t (*apr_socket_bind_fn_t) (apr_socket_t *socket, > apr_sockaddr_t *sa); > > typedef apr_status_t (*apr_socket_connect_fn_t) (apr_socket_t *socket, > apr_sockaddr_t *sa); > > typedef apr_status_t (*apr_socket_listen_fn_t) (apr_socket_t *socket, > apr_int32_t backlog); > > typedef apr_status_t (*apr_socket_accept_fn_t) (apr_socket_t > **client_socket, > apr_socket_t *socket, > apr_pool_t > *connection_pool); > > typedef apr_status_t (*apr_socket_close_fn_t) (apr_socket_t *socket); > > typedef apr_status_t (*apr_socket_setopt_fn_t) (apr_socket_t *socket, > apr_int32_t opt, > apr_int32_t on); > > typedef apr_status_t (*apr_socket_getopt_fn_t) (apr_socket_t *socket, > apr_int32_t opt, > apr_int32_t *on); > > typedef apr_status_t (*apr_socket_send_fn_t) (apr_socket_t *socket, > const char *buf, > apr_size_t *len); > > typedef apr_status_t (*apr_socket_recv_fn_t) (apr_socket_t *socket, > char *buf, > apr_size_t *len); > > typedef apr_status_t (*apr_socket_shutdown_fn_t)(apr_socket_t *socket, > apr_shutdown_how_e how); > > > /* more functions that I possibly left out */ > > > > /* structures */ > > struct apr_transport_t > { > apr_transport_id_t transport_id; > apr_socket_create_fn_t socket_create; > apr_socket_bind_fn_t socket_bind; > apr_socket_connect_fn_t socket_connect; > apr_socket_listen_fn_t socket_listen; > apr_socket_accept_fn_t socket_accept; > apr_socket_close_fn_t socket_close; > apr_socket_setopt_fn_t socket_setopt; > apr_socket_getopt_fn_t socket_getopt; > apr_socket_send_fn_t socket_send; > apr_socket_recv_fn_t socket_recv; > apr_socket_shutdown_fn_t socket_shutdown; > /* again, more functions that I possibly left out */ > > }; > > struct apr_socket_t > { > apr_transport_t *transport; > /* transport specific socket implementation follows (should be > defined by transport implementors) */ > > }; > > /* functions */ > > apr_status_t apr_transport_add(apr_transport_t *transport); > apr_status_t apr_transport_remove(apr_transport_t *transport); > apr_transport_t apr_transport_find(apr_transport_id_t transport_id); > > > /* XXX: maybe do the create using apr_transport_id_t?? */ > apr_status_t apr_socket_create(apr_transport_t *transport, > apr_socket_t **socket, > apr_pool_t *context); > > apr_status_t apr_socket_bind(apr_socket_t *socket, > apr_sockaddr_t *sa); > > apr_status_t apr_socket_connect(apr_socket_t *socket, > apr_sockaddr_t *sa); > > apr_status_t apr_socket_listen(apr_socket_t *socket, > apr_int32_t backlog); > > apr_status_t apr_socket_accept(apr_socket_t **client_socket, > apr_socket_t *socket, > apr_pool_t *connection_pool); > > apr_status_t apr_socket_close(apr_socket_t *socket); > > apr_status_t apr_socket_setopt(apr_socket_t *socket, > apr_int32_t opt, > apr_int32_t on); > > apr_status_t apr_socket_getopt(apr_socket_t *socket, > apr_int32_t opt, > apr_int32_t *on); > > apr_status_t apr_socket_send(apr_socket_t *socket, > const char *buf, > apr_size_t *len); > > apr_status_t apr_socket_recv(apr_socket_t *socket, > char *buf, > apr_size_t *len); > > apr_status_t apr_socket_shutdown(apr_socket_t *socket, > apr_shutdown_how_e how); > > > /* implementation */ > > /* XXX: maybe do the create using apr_transport_id_t?? */ > apr_status_t apr_socket_create(apr_transport_t *transport, > apr_socket_t **socket, > apr_pool_t *context) > { > assert(transport != NULL); > assert(transport->apr_socket_create != NULL); > > return transport->apr_socket_create(socket, context); > } > > apr_status_t apr_socket_bind(apr_socket_t *socket, > apr_sockaddr_t *sa) > { > assert(socket != NULL); > assert(socket->transport != NULL); > assert(socket->transport->socket_bind != NULL); > > return socket->transport->socket_bind(socket, sa); > } > > /* rest of high level implementation is trivially the same */ >
