lib/tsocket: add generic socket abstraction layer
authorStefan Metzmacher <metze@samba.org>
Wed, 18 Feb 2009 08:10:54 +0000 (09:10 +0100)
committerStefan Metzmacher <metze@samba.org>
Thu, 19 Mar 2009 14:01:12 +0000 (15:01 +0100)
This will replace source4/lib/socket/.

metze

lib/tsocket/config.mk [new file with mode: 0644]
lib/tsocket/tsocket.c [new file with mode: 0644]
lib/tsocket/tsocket.h [new file with mode: 0644]
lib/tsocket/tsocket_internal.h [new file with mode: 0644]
source4/headermap.txt
source4/main.mk

diff --git a/lib/tsocket/config.mk b/lib/tsocket/config.mk
new file mode 100644 (file)
index 0000000..afc625d
--- /dev/null
@@ -0,0 +1,10 @@
+[SUBSYSTEM::LIBTSOCKET]
+PRIVATE_DEPENDENCIES = LIBTALLOC LIBTEVENT LIBREPLACE_NETWORK
+
+LIBTSOCKET_OBJ_FILES = $(addprefix ../lib/tsocket/, \
+                                       tsocket.o)
+
+PUBLIC_HEADERS += $(addprefix ../lib/tsocket/, \
+                                tsocket.h\
+                                tsocket_internal.h)
+
diff --git a/lib/tsocket/tsocket.c b/lib/tsocket/tsocket.c
new file mode 100644 (file)
index 0000000..1a12e69
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   Copyright (C) Stefan Metzmacher 2009
+
+     ** NOTE! The following LGPL license applies to the tevent
+     ** library. This does NOT imply that all of Samba is released
+     ** under the LGPL
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/network.h"
+#include "tsocket.h"
+#include "tsocket_internal.h"
+
+static int tsocket_context_destructor(struct tsocket_context *sock)
+{
+       tsocket_disconnect(sock);
+       return 0;
+}
+
+struct tsocket_context *_tsocket_context_create(TALLOC_CTX *mem_ctx,
+                                               const struct tsocket_context_ops *ops,
+                                               void *pstate,
+                                               size_t psize,
+                                               const char *type,
+                                               const char *location)
+{
+       void **ppstate = (void **)pstate;
+       struct tsocket_context *sock;
+
+       sock = talloc_zero(mem_ctx, struct tsocket_context);
+       if (!sock) {
+               return NULL;
+       }
+       sock->ops = ops;
+       sock->location = location;
+       sock->private_data = talloc_size(sock, psize);
+       if (!sock->private_data) {
+               talloc_free(sock);
+               return NULL;
+       }
+       talloc_set_name_const(sock->private_data, type);
+
+       talloc_set_destructor(sock, tsocket_context_destructor);
+
+       *ppstate = sock->private_data;
+       return sock;
+}
+
+int tsocket_set_event_context(struct tsocket_context *sock,
+                             struct tevent_context *ev)
+{
+       return sock->ops->set_event_context(sock, ev);
+}
+
+int tsocket_set_readable_handler(struct tsocket_context *sock,
+                                tsocket_event_handler_t handler,
+                                void *private_data)
+{
+       return sock->ops->set_read_handler(sock, handler, private_data);
+}
+
+int tsocket_set_writeable_handler(struct tsocket_context *sock,
+                                 tsocket_event_handler_t handler,
+                                 void *private_data)
+{
+       return sock->ops->set_write_handler(sock, handler, private_data);
+}
+
+int tsocket_connect(struct tsocket_context *sock,
+                   const struct tsocket_address *remote_addr)
+{
+       return sock->ops->connect_to(sock, remote_addr);
+}
+
+int tsocket_listen(struct tsocket_context *sock,
+                  int queue_size)
+{
+       return sock->ops->listen_on(sock, queue_size);
+}
+
+int _tsocket_accept(struct tsocket_context *sock,
+                   TALLOC_CTX *mem_ctx,
+                   struct tsocket_context **new_sock,
+                   const char *location)
+{
+       return sock->ops->accept_new(sock, mem_ctx, new_sock, location);
+}
+
+ssize_t tsocket_pending(struct tsocket_context *sock)
+{
+       return sock->ops->pending_data(sock);
+}
+
+int tsocket_readv(struct tsocket_context *sock,
+                 const struct iovec *vector, size_t count)
+{
+       return sock->ops->readv_data(sock, vector, count);
+}
+
+int tsocket_writev(struct tsocket_context *sock,
+                  const struct iovec *vector, size_t count)
+{
+       return sock->ops->writev_data(sock, vector, count);
+}
+
+ssize_t tsocket_recvfrom(struct tsocket_context *sock,
+                        uint8_t *data, size_t len,
+                        TALLOC_CTX *addr_ctx,
+                        struct tsocket_address **src_addr)
+{
+       return sock->ops->recvfrom_data(sock, data, len, addr_ctx, src_addr);
+}
+
+ssize_t tsocket_sendto(struct tsocket_context *sock,
+                      const uint8_t *data, size_t len,
+                      const struct tsocket_address *dest_addr)
+{
+       return sock->ops->sendto_data(sock, data, len, dest_addr);
+}
+
+int tsocket_get_status(const struct tsocket_context *sock)
+{
+       return sock->ops->get_status(sock);
+}
+
+int _tsocket_get_local_address(const struct tsocket_context *sock,
+                              TALLOC_CTX *mem_ctx,
+                              struct tsocket_address **local_addr,
+                              const char *location)
+{
+       return sock->ops->get_local_address(sock, mem_ctx,
+                                           local_addr, location);
+}
+
+int _tsocket_get_remote_address(const struct tsocket_context *sock,
+                               TALLOC_CTX *mem_ctx,
+                               struct tsocket_address **remote_addr,
+                               const char *location)
+{
+       return sock->ops->get_remote_address(sock, mem_ctx,
+                                            remote_addr, location);
+}
+
+int tsocket_get_option(const struct tsocket_context *sock,
+                      const char *option,
+                      TALLOC_CTX *mem_ctx,
+                      char **value)
+{
+       return sock->ops->get_option(sock, option, mem_ctx, value);
+}
+
+int tsocket_set_option(const struct tsocket_context *sock,
+                      const char *option,
+                      bool force,
+                      const char *value)
+{
+       return sock->ops->set_option(sock, option, force, value);
+}
+
+void tsocket_disconnect(struct tsocket_context *sock)
+{
+       sock->ops->disconnect(sock);
+}
+
+struct tsocket_address *_tsocket_address_create(TALLOC_CTX *mem_ctx,
+                                               const struct tsocket_address_ops *ops,
+                                               void *pstate,
+                                               size_t psize,
+                                               const char *type,
+                                               const char *location)
+{
+       void **ppstate = (void **)pstate;
+       struct tsocket_address *addr;
+
+       addr = talloc_zero(mem_ctx, struct tsocket_address);
+       if (!addr) {
+               return NULL;
+       }
+       addr->ops = ops;
+       addr->location = location;
+       addr->private_data = talloc_size(addr, psize);
+       if (!addr->private_data) {
+               talloc_free(addr);
+               return NULL;
+       }
+       talloc_set_name_const(addr->private_data, type);
+
+       *ppstate = addr->private_data;
+       return addr;
+}
+
+char *tsocket_address_string(const struct tsocket_address *addr,
+                            TALLOC_CTX *mem_ctx)
+{
+       if (!addr) {
+               return talloc_strdup(mem_ctx, "NULL");
+       }
+       return addr->ops->string(addr, mem_ctx);
+}
+
+struct tsocket_address *_tsocket_address_copy(const struct tsocket_address *addr,
+                                             TALLOC_CTX *mem_ctx,
+                                             const char *location)
+{
+       return addr->ops->copy(addr, mem_ctx, location);
+}
+
+int _tsocket_address_create_socket(const struct tsocket_address *addr,
+                                  enum tsocket_type type,
+                                  TALLOC_CTX *mem_ctx,
+                                  struct tsocket_context **sock,
+                                  const char *location)
+{
+       return addr->ops->create_socket(addr, type, mem_ctx, sock, location);
+}
+
diff --git a/lib/tsocket/tsocket.h b/lib/tsocket/tsocket.h
new file mode 100644 (file)
index 0000000..fd05e39
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   Copyright (C) Stefan Metzmacher 2009
+
+     ** NOTE! The following LGPL license applies to the tevent
+     ** library. This does NOT imply that all of Samba is released
+     ** under the LGPL
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _TSOCKET_H
+#define _TSOCKET_H
+
+#include <talloc.h>
+#include <tevent.h>
+
+struct tsocket_context;
+struct tsocket_address;
+struct iovec;
+
+enum tsocket_type {
+       TSOCKET_TYPE_STREAM = 1,
+       TSOCKET_TYPE_DGRAM,
+       TSOCKET_TYPE_MESSAGE
+};
+
+typedef void (*tsocket_event_handler_t)(struct tsocket_context *, void *);
+int tsocket_set_event_context(struct tsocket_context *sock,
+                             struct tevent_context *ev);
+int tsocket_set_readable_handler(struct tsocket_context *sock,
+                                tsocket_event_handler_t handler,
+                                void *private_data);
+int tsocket_set_writeable_handler(struct tsocket_context *sock,
+                                 tsocket_event_handler_t handler,
+                                 void *private_data);
+
+int tsocket_connect(struct tsocket_context *sock,
+                   const struct tsocket_address *remote_addr);
+
+int tsocket_listen(struct tsocket_context *sock,
+                  int queue_size);
+
+int _tsocket_accept(struct tsocket_context *sock,
+                   TALLOC_CTX *mem_ctx,
+                   struct tsocket_context **new_sock,
+                   const char *location);
+#define tsocket_accept(sock, mem_ctx, new_sock) \
+       _tsocket_accept(sock, mem_ctx, new_sock, __location__)
+
+ssize_t tsocket_pending(struct tsocket_context *sock);
+
+int tsocket_readv(struct tsocket_context *sock,
+                 const struct iovec *vector, size_t count);
+int tsocket_writev(struct tsocket_context *sock,
+                  const struct iovec *vector, size_t count);
+
+ssize_t tsocket_recvfrom(struct tsocket_context *sock,
+                        uint8_t *data, size_t len,
+                        TALLOC_CTX *addr_ctx,
+                        struct tsocket_address **src_addr);
+ssize_t tsocket_sendto(struct tsocket_context *sock,
+                      const uint8_t *data, size_t len,
+                      const struct tsocket_address *dest_addr);
+
+int tsocket_get_status(const struct tsocket_context *sock);
+
+int _tsocket_get_local_address(const struct tsocket_context *sock,
+                              TALLOC_CTX *mem_ctx,
+                              struct tsocket_address **local_addr,
+                              const char *location);
+#define tsocket_get_local_address(sock, mem_ctx, local_addr) \
+       _tsocket_get_local_address(sock, mem_ctx, local_addr, __location__)
+int _tsocket_get_remote_address(const struct tsocket_context *sock,
+                               TALLOC_CTX *mem_ctx,
+                               struct tsocket_address **remote_addr,
+                               const char *location);
+#define tsocket_get_remote_address(sock, mem_ctx, remote_addr) \
+       _tsocket_get_remote_address(sock, mem_ctx, remote_addr, __location__)
+
+int tsocket_get_option(const struct tsocket_context *sock,
+                      const char *option,
+                      TALLOC_CTX *mem_ctx,
+                      char **value);
+int tsocket_set_option(const struct tsocket_context *sock,
+                      const char *option,
+                      bool force,
+                      const char *value);
+
+void tsocket_disconnect(struct tsocket_context *sock);
+
+char *tsocket_address_string(const struct tsocket_address *addr,
+                            TALLOC_CTX *mem_ctx);
+
+struct tsocket_address *_tsocket_address_copy(const struct tsocket_address *addr,
+                                             TALLOC_CTX *mem_ctx,
+                                             const char *location);
+
+#define tsocket_address_copy(addr, mem_ctx) \
+       _tsocket_address_copy(addr, mem_ctx, __location__)
+
+int _tsocket_address_create_socket(const struct tsocket_address *addr,
+                                  enum tsocket_type type,
+                                  TALLOC_CTX *mem_ctx,
+                                  struct tsocket_context **sock,
+                                  const char *location);
+#define tsocket_address_create_socket(addr, type, mem_ctx, sock) \
+       _tsocket_address_create_socket(addr, type, mem_ctx, sock,\
+                                      __location__)
+
+#endif /* _TSOCKET_H */
+
diff --git a/lib/tsocket/tsocket_internal.h b/lib/tsocket/tsocket_internal.h
new file mode 100644 (file)
index 0000000..fccd1fb
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   Copyright (C) Stefan Metzmacher 2009
+
+     ** NOTE! The following LGPL license applies to the tevent
+     ** library. This does NOT imply that all of Samba is released
+     ** under the LGPL
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _TSOCKET_INTERNAL_H
+#define _TSOCKET_INTERNAL_H
+
+struct tsocket_context_ops {
+       const char *name;
+
+       /* event handling */
+       int (*set_event_context)(struct tsocket_context *sock,
+                                struct tevent_context *ev);
+       int (*set_read_handler)(struct tsocket_context *sock,
+                               tsocket_event_handler_t handler,
+                               void *private_data);
+       int (*set_write_handler)(struct tsocket_context *sock,
+                                tsocket_event_handler_t handler,
+                                void *private_data);
+
+       /* client ops */
+       int (*connect_to)(struct tsocket_context *sock,
+                         const struct tsocket_address *remote_addr);
+
+       /* server ops */
+       int (*listen_on)(struct tsocket_context *sock,
+                        int queue_size);
+       int (*accept_new)(struct tsocket_context *sock,
+                         TALLOC_CTX *mem_ctx,
+                         struct tsocket_context **new_sock,
+                         const char *location);
+
+       /* general ops */
+       ssize_t (*pending_data)(struct tsocket_context *sock);
+
+       int (*readv_data)(struct tsocket_context *sock,
+                         const struct iovec *vector, size_t count);
+       int (*writev_data)(struct tsocket_context *sock,
+                          const struct iovec *vector, size_t count);
+
+       ssize_t (*recvfrom_data)(struct tsocket_context *sock,
+                                uint8_t *data, size_t len,
+                                TALLOC_CTX *addr_ctx,
+                                struct tsocket_address **remote_addr);
+       ssize_t (*sendto_data)(struct tsocket_context *sock,
+                              const uint8_t *data, size_t len,
+                              const struct tsocket_address *remote_addr);
+
+       /* info */
+       int (*get_status)(const struct tsocket_context *sock);
+       int (*get_local_address)(const struct tsocket_context *sock,
+                               TALLOC_CTX *mem_ctx,
+                               struct tsocket_address **local_addr,
+                               const char *location);
+       int (*get_remote_address)(const struct tsocket_context *sock,
+                                 TALLOC_CTX *mem_ctx,
+                                 struct tsocket_address **remote_addr,
+                                 const char *location);
+
+       /* options */
+       int (*get_option)(const struct tsocket_context *sock,
+                         const char *option,
+                         TALLOC_CTX *mem_ctx,
+                         char **value);
+       int (*set_option)(const struct tsocket_context *sock,
+                         const char *option,
+                         bool force,
+                         const char *value);
+
+       /* close/disconnect */
+       void (*disconnect)(struct tsocket_context *sock);
+};
+
+struct tsocket_context {
+       const char *location;
+       const struct tsocket_context_ops *ops;
+
+       void *private_data;
+
+       struct {
+               struct tevent_context *ctx;
+               void *read_private;
+               tsocket_event_handler_t read_handler;
+               void *write_private;
+               tsocket_event_handler_t write_handler;
+       } event;
+};
+
+struct tsocket_context *_tsocket_context_create(TALLOC_CTX *mem_ctx,
+                                       const struct tsocket_context_ops *ops,
+                                       void *pstate,
+                                       size_t psize,
+                                       const char *type,
+                                       const char *location);
+#define tsocket_context_create(mem_ctx, ops, state, type, location) \
+       _tsocket_context_create(mem_ctx, ops, state, sizeof(type), \
+                               #type, location)
+
+struct tsocket_address_ops {
+       const char *name;
+
+       char *(*string)(const struct tsocket_address *addr,
+                       TALLOC_CTX *mem_ctx);
+
+       struct tsocket_address *(*copy)(const struct tsocket_address *addr,
+                                       TALLOC_CTX *mem_ctx,
+                                       const char *location);
+
+       int (*create_socket)(const struct tsocket_address *addr,
+                            enum tsocket_type,
+                            TALLOC_CTX *mem_ctx,
+                            struct tsocket_context **sock,
+                            const char *location);
+};
+
+struct tsocket_address {
+       const char *location;
+       const struct tsocket_address_ops *ops;
+
+       void *private_data;
+};
+
+struct tsocket_address *_tsocket_address_create(TALLOC_CTX *mem_ctx,
+                                       const struct tsocket_address_ops *ops,
+                                       void *pstate,
+                                       size_t psize,
+                                       const char *type,
+                                       const char *location);
+#define tsocket_address_create(mem_ctx, ops, state, type, location) \
+       _tsocket_address_create(mem_ctx, ops, state, sizeof(type), \
+                               #type, location)
+
+#endif /* _TSOCKET_H */
+
index 9de5b1cc0cc4dd7dde55d0916ddd3beca07158d0..d0d0a575d8332a9e4348769b087628dd311edc23 100644 (file)
@@ -10,6 +10,8 @@
 ../lib/util/talloc_stack.h: util/talloc_stack.h
 ../lib/util/xfile.h: util/xfile.h
 ../lib/tdr/tdr.h: tdr.h
+../lib/tsocket/tsocket.h: tsocket.h
+../lib/tsocket/tsocket_internal.h: tsocket_internal.h
 librpc/rpc/dcerpc.h: dcerpc.h
 lib/ldb/include/ldb.h: ldb.h
 lib/ldb/include/ldb_errors.h: ldb_errors.h
index 8ea9727ed3bc2a92a3c92339ce642f4b65b0073a..a143604f33c818df66c418d8e82e79dadaa410c1 100644 (file)
@@ -21,6 +21,7 @@ mkinclude ../lib/nss_wrapper/config.mk
 mkinclude lib/stream/config.mk
 mkinclude ../lib/util/config.mk
 mkinclude ../lib/tdr/config.mk
+mkinclude ../lib/tsocket/config.mk
 mkinclude ../lib/crypto/config.mk
 mkinclude ../lib/torture/config.mk
 mkinclude lib/basic.mk