apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Sander Striker" <stri...@samba-tng.org>
Subject [RFC] Network Abstraction Layer
Date Wed, 28 Feb 2001 10:47:26 GMT

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

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



/* 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
                                                 apr_socket_t *socket,

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 */

View raw message