You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by Bill Stoddard <bi...@wstoddard.com> on 2001/06/13 05:22:13 UTC

Re: [RFC] Network Abstraction Layer - redux

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" <st...@samba-tng.org>
To: <de...@apr.apache.org>
Cc: <lk...@samba-tng.org>; <el...@samba-tng.org>
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 */
>


Re: [RFC] Network Abstraction Layer - redux

Posted by Luke Kenneth Casson Leighton <lk...@samba-tng.org>.
On Wed, Jun 13, 2001 at 09:59:57AM -0400, Bill Stoddard wrote:
> Spent a bit of time reviewing the thread and I still think the Samba team proposal 

hiya bill,

quick reality-check, please consider this as independent from
the NAL proposal, and also that i don't speak for sander or elrond.

just to let you know: we're nothing to do with the samba team.

we're the people who are responsible for creating samba's DCE/RPC
capability.  they then decided they could do a better job
['surely it can't be as complicated as all that????'].

i shan't go in to detail: for me, working with APR represents a
clean break from a complete nightmare.


it's past.  history.  time to move on, and working with APR
is how i'd like to do that.

thanks,

luke


Re: [RFC] Network Abstraction Layer - redux

Posted by Bill Stoddard <bi...@wstoddard.com>.
> From: "Bill Stoddard" <bi...@wstoddard.com>
> Sent: Wednesday, June 13, 2001 8:59 AM
>
>
> > 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.
>
> You misssed it :-)  Commit code to apr.  That's not the issue.
>
> Until we can prove an overwhelming requirement, and begin Apache 2.1 tree developement,
> simply _don't__use__the__code__in__httpd_.  That's all I'm asking.  If this is a useful
> library, we will introduce things.
>
> Perhaps we need to keep in STATUS a list of 'release' features, 'beta' features, and
> 'under development-experimental' features.  So parts of apr and apr-util can evolve, but
> avoid pi$$ing people off that we keep 'breaking' it.
>
> Just a suggestion, any comments?
>

Only that getting NAL into APR -could- break the API (maybe I'm wrong about that) and that
would impact Apache 2.0. Yea, I am being httpd centric :-) But your point is taken and I
generally agree.

Bill


Re: [RFC] Network Abstraction Layer - redux

Posted by "William A. Rowe, Jr." <ad...@rowe-clan.net>.
From: "Bill Stoddard" <bi...@wstoddard.com>
Sent: Wednesday, June 13, 2001 8:59 AM


> 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.

You misssed it :-)  Commit code to apr.  That's not the issue.

Until we can prove an overwhelming requirement, and begin Apache 2.1 tree developement,
simply _don't__use__the__code__in__httpd_.  That's all I'm asking.  If this is a useful
library, we will introduce things.

Perhaps we need to keep in STATUS a list of 'release' features, 'beta' features, and
'under development-experimental' features.  So parts of apr and apr-util can evolve, but
avoid pi$$ing people off that we keep 'breaking' it.

Just a suggestion, any comments?

Bill



Re: [RFC] Network Abstraction Layer - redux

Posted by rb...@covalent.net.
I have read and reviewed the entire thread.  I read and reviewed it when
it was first posted, and I still agree with the decision that was reached
the first time.  Please, post specifics about what itches you are trying
to scratch.  What does this solve?  Without specifics, this is just
hand-waving.

Ryan

On Wed, 13 Jun 2001, Bill Stoddard wrote:

> 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" <st...@samba-tng.org>
> > > To: <de...@apr.apache.org>
> > > Cc: <lk...@samba-tng.org>; <el...@samba-tng.org>
> > > 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                        rbb@apache.org
> > 406 29th St.
> > San Francisco, CA 94131
> > -------------------------------------------------------------------------------
> >
>
>


_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


Re: [RFC] Network Abstraction Layer - redux

Posted by Bill Stoddard <bi...@wstoddard.com>.
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" <st...@samba-tng.org>
> > To: <de...@apr.apache.org>
> > Cc: <lk...@samba-tng.org>; <el...@samba-tng.org>
> > 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                        rbb@apache.org
> 406 29th St.
> San Francisco, CA 94131
> -------------------------------------------------------------------------------
>


Re: [RFC] Network Abstraction Layer - redux

Posted by Elrond <el...@samba-tng.org>.
On Wed, Jun 13, 2001 at 01:35:18AM -0400, Bill Stoddard wrote:
> I need to catch up on the other messages in this thread

Yes, please do!

The last message I posted on this thread contains even some
important info for apr_socket_t (which gets near the NAL,
but not as far). I even pointed out some problems in
apr_socket_t.
I haven't gotten a response to this posting till now (I'm
not on the list!)

> so I conceed you may be right,

>From a performance point of view, filters are probably the
right way to do this.

We (the Samba TNG people) asked for NAL, because we
currently don't need performance but _extremely clean_
design and abstraction.


> but one thing I -think- this proposal helps us avoid is
> replicating a lot of code in the core_filters (in and
> out) just to access a different network i/o primitive. 
> Mucking with the core filters seems a clunky way to do
> what the NAL does.

Cool... so someone sees a use outside our goals! :)


> Bill
> 
> ----- Original Message -----
> From: <rb...@covalent.net>
[...]


    Elrond

Re: [RFC] Network Abstraction Layer - redux

Posted by Luke Kenneth Casson Leighton <lk...@samba-tng.org>.
the purpose of adding a NAL is to be able to farm out 
responsibility for dealing with other transports to
other programs, as proxies for those transports.

given that the filter code is designed to be in-memory,
the only way to achieve inter-process communication
is to use sh-mem, and that's a path i forsee as tricky,
at best.

it also ties in with the proposed apr_namedpipe_xxx() API.

that's _another_ type of communication / transport
that can be added to the list in the NALs.

do you _really_ want to write special filters to have to
deal with each and every single one of these transports?

if i can possibly explain this well enough, i think you
may agree that being able to bounce in-and-out of
separate programs at well-defined boundaries, with one
program being responsible for part of a message [a
header, for example], and treating the rest as opaque
data, makes a lot of sense.

TNG and NT are chock full of such things, and i _know_
that NT has a fully featured implementation of
bucket brigages / filters _and_ a NAL that is extensively
used to provide transport independence and processing of
TCP, UDP, IPX, SPX, NetBIOS, DECNet, SMB, DCE/RPC, Pipes,
LANMAN, IPC$, the whole lot.

luke

> ----- Original Message -----
> From: <rb...@covalent.net>
> To: "Bill Stoddard" <bi...@wstoddard.com>
> Cc: <st...@samba-tng.org>; <de...@apr.apache.org>; <lk...@samba-tng.org>;
> <el...@samba-tng.org>
> Sent: Tuesday, June 12, 2001 11:41 PM
> Subject: Re: [RFC] Network Abstraction Layer - redux
> 
> 
> >
> > 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.

> > > > 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:

Re: [RFC] Network Abstraction Layer - redux

Posted by Bill Stoddard <bi...@wstoddard.com>.
I need to catch up on the other messages in this thread so I conceed you may be right, but
one thing I -think- this proposal helps us avoid is replicating a lot of code in the
core_filters (in and out) just to access a different network i/o primitive.  Mucking with
the core filters seems a clunky way to do what the NAL does.

Bill

----- Original Message -----
From: <rb...@covalent.net>
To: "Bill Stoddard" <bi...@wstoddard.com>
Cc: <st...@samba-tng.org>; <de...@apr.apache.org>; <lk...@samba-tng.org>;
<el...@samba-tng.org>
Sent: Tuesday, June 12, 2001 11:41 PM
Subject: Re: [RFC] Network Abstraction Layer - redux


>
> 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" <st...@samba-tng.org>
> > To: <de...@apr.apache.org>
> > Cc: <lk...@samba-tng.org>; <el...@samba-tng.org>
> > 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                        rbb@apache.org
> 406 29th St.
> San Francisco, CA 94131
> -------------------------------------------------------------------------------
>


Re: [RFC] Network Abstraction Layer - redux

Posted by Luke Kenneth Casson Leighton <lk...@samba-tng.org>.
> But can we, absolutely, postively, table any change that affects an httpd 2.0
> release?  

ack! agree! :)


Re: [RFC] Network Abstraction Layer - redux

Posted by rb...@covalent.net.
> > 2. I gave a pitch about IBM's Fast Response Cache Accelerator (aka AFPA) at ApacheCon a
> > few years back. The AFPA implementation on Windows uses it's own socket API (afpa_read,
> > afpa_accept, afpa_send, et. al.).  Again, the NAL provides a clean way for my Apache
> > module to hook the right NAL implementing my specific network io primitives with the
> > minimum amount of shuffleing httpd code.
> >
> > Can I do both of these with filters? Sure, but the code architecturally ugly as sin.
> > Allan Edwards solved both of these problems cleanly in early Apache 2.0 iterations using
> > Dean Gaudet's IOLs. NAL is essentially a scaled back version of Dean's IOLs (NAL is
> > focused just on network i/o, not filtering). And I know what Luke is talking about as
> > well.  Windows NT does implement filters (AFPA uses file system filters) in addition to a
> > network io abstraction layer.  NAL is a great compliment to filters.
>
> So ... why did we drop IOL? :-)

Because they were complex, and couldn't do what they were supposed to do,
namely implement filtering.  They just weren't necessary anymore.  Maybe
they are now, I don't think so, but I am willing to be wrong.  If we do
re-implement them, I would appreciate it if IOL's were easier to debug
this time.  The original IOL's were almost impossible to debug, because
you couldn't get to the underlying transport mechanism.

Ryan

_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


Re: [RFC] Network Abstraction Layer - redux

Posted by Ben Laurie <be...@algroup.co.uk>.
Bill Stoddard wrote:
> I would argue that we do not have a good (read architecturally clean) way to abstract
> network io with filters. The NAL is a perfect compliment to the filter code. Here are my
> specific itches:
> 
> 1.  My SSL library API uses a different model than OpenSSL. Specifically, it uses uses
> secure_socket calls (e.g., secure_read(), secure_write(), etc.).  I -could- integrate SSL
> into Apache 2.0 using filters, but I would have to replace core_inout_filter and
> core_output_filter with my own filters, possibly implement special bucket types
> (apr_bucket_secure_socket_t, etc.)  With NAL, I can just hook the network io primitives
> with my own calls and use the filters already in Apache. I hope to use OpenSSL but that is
> just not a possibility now. My itch is real to me even if you don;t feel it :-)

FWIW you can also run OpenSSL in this mode, but I elected not to (coz
then SSL will work automagically over other transports).

> 2. I gave a pitch about IBM's Fast Response Cache Accelerator (aka AFPA) at ApacheCon a
> few years back. The AFPA implementation on Windows uses it's own socket API (afpa_read,
> afpa_accept, afpa_send, et. al.).  Again, the NAL provides a clean way for my Apache
> module to hook the right NAL implementing my specific network io primitives with the
> minimum amount of shuffleing httpd code.
> 
> Can I do both of these with filters? Sure, but the code architecturally ugly as sin.
> Allan Edwards solved both of these problems cleanly in early Apache 2.0 iterations using
> Dean Gaudet's IOLs. NAL is essentially a scaled back version of Dean's IOLs (NAL is
> focused just on network i/o, not filtering). And I know what Luke is talking about as
> well.  Windows NT does implement filters (AFPA uses file system filters) in addition to a
> network io abstraction layer.  NAL is a great compliment to filters.

So ... why did we drop IOL? :-)

Cheers,

Ben.

--
http://www.apache-ssl.org/ben.html

"There is no limit to what a man can do or how far he can go if he
doesn't mind who gets the credit." - Robert Woodruff

Re: [RFC] Network Abstraction Layer - redux

Posted by Ben Laurie <be...@algroup.co.uk>.
Bill Stoddard wrote:
> Third, all the network io is done via apr_socket_t structs which are created in the MPMs
> and propogated to other parts of Apache.  By definition, I am not interested in dealing
> with apr_socket_t structs (slightly modfied apr_socket_t structs maybe).  How do we handle
> each place in the Apache code where we frob (look at, call an API with, whatever) an
> apr_socket_t and expect a real 'socket'?  Where do I store my custom structure I use for
> networkio? I would like to be able to use the apr_socket_t structure and tweak it slightly
> for my custom calls, but that structure is opaque to Apache.

Gleep! Tell me we don't do this!

Cheers,

Ben.

--
http://www.apache-ssl.org/ben.html

"There is no limit to what a man can do or how far he can go if he
doesn't mind who gets the credit." - Robert Woodruff

Re: [RFC] Network Abstraction Layer - redux

Posted by Bill Stoddard <bi...@wstoddard.com>.
> > > The problem I have with this code idea isn't that it isn't useful to
> > > httpd.  It is that we have been down this road once, and the model wasn't
> > > flexible enough.  What problem are we trying to solve that the filter
> > > mechanism doesn't solve?  If the answer to that question is "filters are
> > > in Apache, and we want this out of Apache", then move filters out of
> > > Apache.
> >
> > No way man :-)
>
> Why not?

"No way man" is my answer to your question about possibly removing filters from Apache.
Filters are good. :-)

>
> > > If the answer is, "We need a better way to abstract the network
> > > for x, y, and z", then cool let's do it.
> >
> > I would argue that we do not have a good (read architecturally clean) way to abstract
> > network io with filters. The NAL is a perfect compliment to the filter code. Here are
my
> > specific itches:
> >
> > 1.  My SSL library API uses a different model than OpenSSL. Specifically, it uses uses
> > secure_socket calls (e.g., secure_read(), secure_write(), etc.).  I -could- integrate
SSL
> > into Apache 2.0 using filters, but I would have to replace core_inout_filter and
> > core_output_filter with my own filters, possibly implement special bucket types
> > (apr_bucket_secure_socket_t, etc.)  With NAL, I can just hook the network io
primitives
> > with my own calls and use the filters already in Apache. I hope to use OpenSSL but
that is
> > just not a possibility now. My itch is real to me even if you don;t feel it :-)
>
> I'm not saying your itch isn't real, I'm saying I disagree with how you
> want to scratch it.  :-)
>
> > 2. I gave a pitch about IBM's Fast Response Cache Accelerator (aka AFPA) at ApacheCon
a
> > few years back. The AFPA implementation on Windows uses it's own socket API
(afpa_read,
> > afpa_accept, afpa_send, et. al.).  Again, the NAL provides a clean way for my Apache
> > module to hook the right NAL implementing my specific network io primitives with the
> > minimum amount of shuffleing httpd code.
> >
> > Can I do both of these with filters? Sure, but the code architecturally ugly as sin.
> > Allan Edwards solved both of these problems cleanly in early Apache 2.0 iterations
using
> > Dean Gaudet's IOLs. NAL is essentially a scaled back version of Dean's IOLs (NAL is
> > focused just on network i/o, not filtering). And I know what Luke is talking about as
> > well.  Windows NT does implement filters (AFPA uses file system filters) in addition
to a
> > network io abstraction layer.  NAL is a great compliment to filters.
>
> I'm saying that the code doesn't need to be architecturally ugly.  The
> problem, is that our core filters are big and do too much, IMNSHO.  Break
> out the core filters to smaller chunks that are available to other
> filters, and I believe this will solve your problem completely.
>

I think you are saying that you believe it is possible to make the 'last filter'
(currently the core_[input|output]_filter) a very thin filter whose primary purpose is to
do network io; either via an apr_network_io interface, or via a custom interface? Is that
about right?   If so, I think that has some problems (perhaps solvable in a clean way).

First problem is with where the network abstraction occurs. In the NAL, the abstraction is
at the lowest possible level, at the core network io primitive level.  With your solution,
the abstraction occurs at the apr_network_io level. This means that my primitives will
have to reimplement a lot of the buffering/locking/whatever code that is currently
implemented in the apr_network_io code.  Custom network io primitives must be semantically
identical to the network io primitives they are replacing. It is much easier to do this at
the socket level than at the apr_network_io level.

Second, not all the network i/o we do is in the core filters.  MPMs do network operations
(accept, lingering close, etc.).

Third, all the network io is done via apr_socket_t structs which are created in the MPMs
and propogated to other parts of Apache.  By definition, I am not interested in dealing
with apr_socket_t structs (slightly modfied apr_socket_t structs maybe).  How do we handle
each place in the Apache code where we frob (look at, call an API with, whatever) an
apr_socket_t and expect a real 'socket'?  Where do I store my custom structure I use for
networkio? I would like to be able to use the apr_socket_t structure and tweak it slightly
for my custom calls, but that structure is opaque to Apache.

Bill




Re: [RFC] Network Abstraction Layer - redux

Posted by rb...@covalent.net.
> > The problem I have with this code idea isn't that it isn't useful to
> > httpd.  It is that we have been down this road once, and the model wasn't
> > flexible enough.  What problem are we trying to solve that the filter
> > mechanism doesn't solve?  If the answer to that question is "filters are
> > in Apache, and we want this out of Apache", then move filters out of
> > Apache.
>
> No way man :-)

Why not?

> > If the answer is, "We need a better way to abstract the network
> > for x, y, and z", then cool let's do it.
>
> I would argue that we do not have a good (read architecturally clean) way to abstract
> network io with filters. The NAL is a perfect compliment to the filter code. Here are my
> specific itches:
>
> 1.  My SSL library API uses a different model than OpenSSL. Specifically, it uses uses
> secure_socket calls (e.g., secure_read(), secure_write(), etc.).  I -could- integrate SSL
> into Apache 2.0 using filters, but I would have to replace core_inout_filter and
> core_output_filter with my own filters, possibly implement special bucket types
> (apr_bucket_secure_socket_t, etc.)  With NAL, I can just hook the network io primitives
> with my own calls and use the filters already in Apache. I hope to use OpenSSL but that is
> just not a possibility now. My itch is real to me even if you don;t feel it :-)

I'm not saying your itch isn't real, I'm saying I disagree with how you
want to scratch it.  :-)

> 2. I gave a pitch about IBM's Fast Response Cache Accelerator (aka AFPA) at ApacheCon a
> few years back. The AFPA implementation on Windows uses it's own socket API (afpa_read,
> afpa_accept, afpa_send, et. al.).  Again, the NAL provides a clean way for my Apache
> module to hook the right NAL implementing my specific network io primitives with the
> minimum amount of shuffleing httpd code.
>
> Can I do both of these with filters? Sure, but the code architecturally ugly as sin.
> Allan Edwards solved both of these problems cleanly in early Apache 2.0 iterations using
> Dean Gaudet's IOLs. NAL is essentially a scaled back version of Dean's IOLs (NAL is
> focused just on network i/o, not filtering). And I know what Luke is talking about as
> well.  Windows NT does implement filters (AFPA uses file system filters) in addition to a
> network io abstraction layer.  NAL is a great compliment to filters.

I'm saying that the code doesn't need to be architecturally ugly.  The
problem, is that our core filters are big and do too much, IMNSHO.  Break
out the core filters to smaller chunks that are available to other
filters, and I believe this will solve your problem completely.

Ryan

_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


Re: [RFC] Network Abstraction Layer - redux

Posted by Bill Stoddard <bi...@wstoddard.com>.
> On Tue, 12 Jun 2001, William A. Rowe, Jr. wrote:
>
> > From: <rb...@covalent.net>
> > Sent: Tuesday, June 12, 2001 10:41 PM
> >
> >
> > > 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.
> >
> > In all fairness,
> >
> > APR does bucket brigades.  It does socket management.  I think this would be a fine
> > addition to our APR arsenal.
> >
> > But can we, absolutely, postively, table any change that affects an httpd 2.0
> > release?  IOW, no samba-team iol into Apache 2.0.  Develop the API, impement the
> > code, go to town.  But I think we've reached a juncture...
> >
> >     not everything in apr exists for or is even used by Apache
> >
> > If what results can improve httpd 2.1, then fantastic!  If not, it's still fantastic
:-)
> > There's alot more to do on the net beyond Apache, if we can fuel those directions,
then
> > we really have a worthwhile library project, and not just an adjunct of httpd.
>
> The problem I have with this code idea isn't that it isn't useful to
> httpd.  It is that we have been down this road once, and the model wasn't
> flexible enough.  What problem are we trying to solve that the filter
> mechanism doesn't solve?  If the answer to that question is "filters are
> in Apache, and we want this out of Apache", then move filters out of
> Apache.

No way man :-)

> If the answer is, "We need a better way to abstract the network
> for x, y, and z", then cool let's do it.

I would argue that we do not have a good (read architecturally clean) way to abstract
network io with filters. The NAL is a perfect compliment to the filter code. Here are my
specific itches:

1.  My SSL library API uses a different model than OpenSSL. Specifically, it uses uses
secure_socket calls (e.g., secure_read(), secure_write(), etc.).  I -could- integrate SSL
into Apache 2.0 using filters, but I would have to replace core_inout_filter and
core_output_filter with my own filters, possibly implement special bucket types
(apr_bucket_secure_socket_t, etc.)  With NAL, I can just hook the network io primitives
with my own calls and use the filters already in Apache. I hope to use OpenSSL but that is
just not a possibility now. My itch is real to me even if you don;t feel it :-)

2. I gave a pitch about IBM's Fast Response Cache Accelerator (aka AFPA) at ApacheCon a
few years back. The AFPA implementation on Windows uses it's own socket API (afpa_read,
afpa_accept, afpa_send, et. al.).  Again, the NAL provides a clean way for my Apache
module to hook the right NAL implementing my specific network io primitives with the
minimum amount of shuffleing httpd code.

Can I do both of these with filters? Sure, but the code architecturally ugly as sin.
Allan Edwards solved both of these problems cleanly in early Apache 2.0 iterations using
Dean Gaudet's IOLs. NAL is essentially a scaled back version of Dean's IOLs (NAL is
focused just on network i/o, not filtering). And I know what Luke is talking about as
well.  Windows NT does implement filters (AFPA uses file system filters) in addition to a
network io abstraction layer.  NAL is a great compliment to filters.

Bill


Re: [RFC] Network Abstraction Layer - redux

Posted by rb...@covalent.net.
On Tue, 12 Jun 2001, William A. Rowe, Jr. wrote:

> From: <rb...@covalent.net>
> Sent: Tuesday, June 12, 2001 10:41 PM
>
>
> > 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.
>
> In all fairness,
>
> APR does bucket brigades.  It does socket management.  I think this would be a fine
> addition to our APR arsenal.
>
> But can we, absolutely, postively, table any change that affects an httpd 2.0
> release?  IOW, no samba-team iol into Apache 2.0.  Develop the API, impement the
> code, go to town.  But I think we've reached a juncture...
>
>     not everything in apr exists for or is even used by Apache
>
> If what results can improve httpd 2.1, then fantastic!  If not, it's still fantastic :-)
> There's alot more to do on the net beyond Apache, if we can fuel those directions, then
> we really have a worthwhile library project, and not just an adjunct of httpd.

The problem I have with this code idea isn't that it isn't useful to
httpd.  It is that we have been down this road once, and the model wasn't
flexible enough.  What problem are we trying to solve that the filter
mechanism doesn't solve?  If the answer to that question is "filters are
in Apache, and we want this out of Apache", then move filters out of
Apache.  If the answer is, "We need a better way to abstract the network
for x, y, and z", then cool let's do it.  I haven't heard x, y, and z yet,
and the last time we talked about this, filters could solve any problem
that this model was trying to solve.

Ryan

_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


Re: [RFC] Network Abstraction Layer - redux

Posted by "William A. Rowe, Jr." <ad...@rowe-clan.net>.
From: <rb...@covalent.net>
Sent: Tuesday, June 12, 2001 10:41 PM


> 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.

In all fairness,

APR does bucket brigades.  It does socket management.  I think this would be a fine
addition to our APR arsenal.

But can we, absolutely, postively, table any change that affects an httpd 2.0
release?  IOW, no samba-team iol into Apache 2.0.  Develop the API, impement the
code, go to town.  But I think we've reached a juncture...

    not everything in apr exists for or is even used by Apache

If what results can improve httpd 2.1, then fantastic!  If not, it's still fantastic :-)
There's alot more to do on the net beyond Apache, if we can fuel those directions, then
we really have a worthwhile library project, and not just an adjunct of httpd.

> 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).
> >
> > From: "Sander Striker" <st...@samba-tng.org>
> > Sent: Wednesday, February 28, 2001 6:47 AM
> >
> > > 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.



Re: [RFC] Network Abstraction Layer - redux

Posted by rb...@covalent.net.
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" <st...@samba-tng.org>
> To: <de...@apr.apache.org>
> Cc: <lk...@samba-tng.org>; <el...@samba-tng.org>
> 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                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------