Return-Path: Delivered-To: apmail-apr-dev-archive@apr.apache.org Received: (qmail 76756 invoked by uid 500); 28 Feb 2001 10:42:06 -0000 Mailing-List: contact dev-help@apr.apache.org; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: Delivered-To: mailing list dev@apr.apache.org Received: (qmail 76719 invoked from network); 28 Feb 2001 10:42:03 -0000 Reply-To: From: "Sander Striker" To: Cc: , Subject: [RFC] Network Abstraction Layer Date: Wed, 28 Feb 2001 11:47:26 +0100 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2911.0) X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4133.2400 Importance: Normal X-Spam-Rating: h31.sny.collab.net 1.6.2 0/1000/N 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 */