Spent a bit of time reviewing the thread and I still think the Samba team proposal looks very worthwhile (and it scratches a couple of itches for me :-). The NAL enables an architecturally clean solution to a whole class of problems. +1 on implementing against the API posted by Sander. I expect we will tweak things as we begin to use the API but it is an excellent start. And I agree with the concensus that we not commit code untill after Apache 2.0 is released.
Bill > > I was under the impression that we had already decided, the last time this > thread surfaced, that all of this was possible with filters. We can > redirect to different kinds of network primitives with a different "core" > filter. The "core" filters don't even need to use sockets, they can store > their own communication medium in the conn_rec, and just use that. The > only drawback, is that Apache will still require a single socket to > operate, but I am not sure that can't be worked around. A REALLY QUICK > grep through the source has us referencing the client socket 28 times > directly from the conn_rec. I am not convinced that some of those can't > just be moved to inside a filter. > > I guess I am asking what this is supposed to accomplish. > > Ryan > > On Tue, 12 Jun 2001, Bill Stoddard wrote: > > > 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 */ > > > > > > > > > > _______________________________________________________________________________ > Ryan Bloom [EMAIL PROTECTED] > 406 29th St. > San Francisco, CA 94131 > ------------------------------------------------------------------------------- >
