summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/tsocket/config.mk5
-rw-r--r--lib/tsocket/tsocket.c145
-rw-r--r--lib/tsocket/tsocket.h115
-rw-r--r--lib/tsocket/tsocket_bsd.c687
-rw-r--r--lib/tsocket/tsocket_connect.c122
-rw-r--r--lib/tsocket/tsocket_helpers.c121
-rw-r--r--lib/tsocket/tsocket_internal.h91
-rw-r--r--lib/tsocket/tsocket_readv.c222
-rw-r--r--lib/tsocket/tsocket_writev.c316
9 files changed, 17 insertions, 1807 deletions
diff --git a/lib/tsocket/config.mk b/lib/tsocket/config.mk
index 2e05f544c9..016663ffea 100644
--- a/lib/tsocket/config.mk
+++ b/lib/tsocket/config.mk
@@ -4,10 +4,7 @@ PRIVATE_DEPENDENCIES = LIBTALLOC LIBTEVENT LIBREPLACE_NETWORK
LIBTSOCKET_OBJ_FILES = $(addprefix ../lib/tsocket/, \
tsocket.o \
tsocket_helpers.o \
- tsocket_bsd.o \
- tsocket_connect.o \
- tsocket_writev.o \
- tsocket_readv.o)
+ tsocket_bsd.o)
PUBLIC_HEADERS += $(addprefix ../lib/tsocket/, \
tsocket.h\
diff --git a/lib/tsocket/tsocket.c b/lib/tsocket/tsocket.c
index 076c6474a0..8e97997d85 100644
--- a/lib/tsocket/tsocket.c
+++ b/lib/tsocket/tsocket.c
@@ -26,142 +26,6 @@
#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);
-}
-
-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,
@@ -205,15 +69,6 @@ struct tsocket_address *_tsocket_address_copy(const struct tsocket_address *addr
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);
-}
-
struct tdgram_context {
const char *location;
const struct tdgram_context_ops *ops;
diff --git a/lib/tsocket/tsocket.h b/lib/tsocket/tsocket.h
index 8f69490012..84e74afa89 100644
--- a/lib/tsocket/tsocket.h
+++ b/lib/tsocket/tsocket.h
@@ -27,72 +27,13 @@
#include <talloc.h>
#include <tevent.h>
-struct tsocket_context;
struct tsocket_address;
struct tdgram_context;
struct iovec;
-enum tsocket_type {
- TSOCKET_TYPE_STREAM = 1,
- 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);
-
-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);
-
+/*
+ * tsocket_address related functions
+ */
char *tsocket_address_string(const struct tsocket_address *addr,
TALLOC_CTX *mem_ctx);
@@ -103,15 +44,6 @@ struct tsocket_address *_tsocket_address_copy(const struct tsocket_address *addr
#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__)
-
/*
* tdgram_context related functions
*/
@@ -170,14 +102,6 @@ int _tsocket_address_unix_from_path(TALLOC_CTX *mem_ctx,
char *tsocket_address_unix_path(const struct tsocket_address *addr,
TALLOC_CTX *mem_ctx);
-int _tsocket_context_bsd_wrap_existing(TALLOC_CTX *mem_ctx,
- int fd, bool close_on_disconnect,
- struct tsocket_context **_sock,
- const char *location);
-#define tsocket_context_bsd_wrap_existing(mem_ctx, fd, cod, _sock) \
- _tsocket_context_bsd_wrap_existing(mem_ctx, fd, cod, _sock, \
- __location__)
-
int _tdgram_inet_udp_socket(const struct tsocket_address *local,
const struct tsocket_address *remote,
TALLOC_CTX *mem_ctx,
@@ -195,39 +119,6 @@ int _tdgram_unix_dgram_socket(const struct tsocket_address *local,
_tdgram_unix_dgram_socket(local, remote, mem_ctx, dgram, __location__)
/*
- * Async helpers
- */
-
-struct tevent_req *tsocket_connect_send(struct tsocket_context *sock,
- TALLOC_CTX *mem_ctx,
- const struct tsocket_address *dst);
-int tsocket_connect_recv(struct tevent_req *req, int *perrno);
-
-struct tevent_req *tsocket_writev_send(struct tsocket_context *sock,
- TALLOC_CTX *mem_ctx,
- const struct iovec *vector,
- size_t count);
-int tsocket_writev_recv(struct tevent_req *req, int *perrno);
-
-struct tevent_req *tsocket_writev_queue_send(TALLOC_CTX *mem_ctx,
- struct tsocket_context *sock,
- struct tevent_queue *queue,
- const struct iovec *vector,
- size_t count);
-int tsocket_writev_queue_recv(struct tevent_req *req, int *perrno);
-
-typedef int (*tsocket_readv_next_iovec_t)(struct tsocket_context *sock,
- void *private_data,
- TALLOC_CTX *mem_ctx,
- struct iovec **vector,
- size_t *count);
-struct tevent_req *tsocket_readv_send(struct tsocket_context *sock,
- TALLOC_CTX *mem_ctx,
- tsocket_readv_next_iovec_t next_iovec_fn,
- void *private_data);
-int tsocket_readv_recv(struct tevent_req *req, int *perrno);
-
-/*
* Queue helpers
*/
diff --git a/lib/tsocket/tsocket_bsd.c b/lib/tsocket/tsocket_bsd.c
index 29097bd987..e260b1fa25 100644
--- a/lib/tsocket/tsocket_bsd.c
+++ b/lib/tsocket/tsocket_bsd.c
@@ -24,7 +24,6 @@
#include "replace.h"
#include "system/filesys.h"
#include "system/network.h"
-#include "system/filesys.h"
#include "tsocket.h"
#include "tsocket_internal.h"
@@ -186,22 +185,9 @@ static ssize_t tsocket_bsd_pending(int fd)
return -1;
}
-static const struct tsocket_context_ops tsocket_context_bsd_ops;
static const struct tsocket_address_ops tsocket_address_bsd_ops;
-static int tsocket_context_bsd_set_option(const struct tsocket_context *sock,
- const char *option,
- bool force,
- const char *value);
-
-struct tsocket_context_bsd {
- bool close_on_disconnect;
- int fd;
- struct tevent_fd *fde;
-};
-
struct tsocket_address_bsd {
- bool broadcast;
union {
struct sockaddr sa;
struct sockaddr_in in;
@@ -443,19 +429,6 @@ int tsocket_address_inet_set_port(struct tsocket_address *addr,
return 0;
}
-void tsocket_address_inet_set_broadcast(struct tsocket_address *addr,
- bool broadcast)
-{
- struct tsocket_address_bsd *bsda = talloc_get_type(addr->private_data,
- struct tsocket_address_bsd);
-
- if (!bsda) {
- return;
- }
-
- bsda->broadcast = broadcast;
-}
-
int _tsocket_address_unix_from_path(TALLOC_CTX *mem_ctx,
const char *path,
struct tsocket_address **_addr,
@@ -565,654 +538,13 @@ static struct tsocket_address *tsocket_address_bsd_copy(const struct tsocket_add
return NULL;
}
- tsocket_address_inet_set_broadcast(copy, bsda->broadcast);
return copy;
}
-int _tsocket_context_bsd_wrap_existing(TALLOC_CTX *mem_ctx,
- int fd, bool close_on_disconnect,
- struct tsocket_context **_sock,
- const char *location)
-{
- struct tsocket_context *sock;
- struct tsocket_context_bsd *bsds;
-
- sock = tsocket_context_create(mem_ctx,
- &tsocket_context_bsd_ops,
- &bsds,
- struct tsocket_context_bsd,
- location);
- if (!sock) {
- return -1;
- }
-
- bsds->close_on_disconnect = close_on_disconnect;
- bsds->fd = fd;
- bsds->fde = NULL;
-
- *_sock = sock;
- return 0;
-}
-
-static int tsocket_address_bsd_create_socket(const struct tsocket_address *addr,
- enum tsocket_type type,
- TALLOC_CTX *mem_ctx,
- struct tsocket_context **_sock,
- const char *location)
-{
- struct tsocket_address_bsd *bsda = talloc_get_type(addr->private_data,
- struct tsocket_address_bsd);
- struct tsocket_context *sock;
- int bsd_type;
- int fd;
- int ret;
- bool do_bind = false;
- bool do_reuseaddr = false;
-
- switch (type) {
- case TSOCKET_TYPE_STREAM:
- if (bsda->broadcast) {
- errno = EINVAL;
- return -1;
- }
- bsd_type = SOCK_STREAM;
- break;
- default:
- errno = EPROTONOSUPPORT;
- return -1;
- }
-
- switch (bsda->u.sa.sa_family) {
- case AF_UNIX:
- if (bsda->broadcast) {
- errno = EINVAL;
- return -1;
- }
- if (bsda->u.un.sun_path[0] != 0) {
- do_bind = true;
- }
- break;
- case AF_INET:
- if (bsda->u.in.sin_port != 0) {
- do_reuseaddr = true;
- do_bind = true;
- }
- if (bsda->u.in.sin_addr.s_addr == INADDR_ANY) {
- do_bind = true;
- }
- break;
-#ifdef HAVE_IPV6
- case AF_INET6:
- if (bsda->u.in6.sin6_port != 0) {
- do_reuseaddr = true;
- do_bind = true;
- }
- if (memcmp(&in6addr_any,
- &bsda->u.in6.sin6_addr,
- sizeof(in6addr_any)) != 0) {
- do_bind = true;
- }
- break;
-#endif
- default:
- errno = EINVAL;
- return -1;
- }
-
- fd = socket(bsda->u.sa.sa_family, bsd_type, 0);
- if (fd < 0) {
- return fd;
- }
-
- fd = tsocket_common_prepare_fd(fd, true);
- if (fd < 0) {
- return fd;
- }
-
- ret = _tsocket_context_bsd_wrap_existing(mem_ctx, fd, true,
- &sock, location);
- if (ret != 0) {
- int saved_errno = errno;
- close(fd);
- errno = saved_errno;
- return ret;
- }
-
- if (bsda->broadcast) {
- ret = tsocket_context_bsd_set_option(sock, "SO_BROADCAST", true, "1");
- if (ret != 0) {
- int saved_errno = errno;
- talloc_free(sock);
- errno = saved_errno;
- return ret;
- }
- }
-
- if (do_reuseaddr) {
- ret = tsocket_context_bsd_set_option(sock, "SO_REUSEADDR", true, "1");
- if (ret != 0) {
- int saved_errno = errno;
- talloc_free(sock);
- errno = saved_errno;
- return ret;
- }
- }
-
- if (do_bind) {
- ret = bind(fd, &bsda->u.sa, sizeof(bsda->u.ss));
- if (ret != 0) {
- int saved_errno = errno;
- talloc_free(sock);
- errno = saved_errno;
- return ret;
- }
- }
-
- *_sock = sock;
- return 0;
-}
-
static const struct tsocket_address_ops tsocket_address_bsd_ops = {
.name = "bsd",
.string = tsocket_address_bsd_string,
.copy = tsocket_address_bsd_copy,
- .create_socket = tsocket_address_bsd_create_socket
-};
-
-static void tsocket_context_bsd_fde_handler(struct tevent_context *ev,
- struct tevent_fd *fde,
- uint16_t flags,
- void *private_data)
-{
- struct tsocket_context *sock = talloc_get_type(private_data,
- struct tsocket_context);
-
- if (flags & TEVENT_FD_WRITE) {
- sock->event.write_handler(sock, sock->event.write_private);
- return;
- }
- if (flags & TEVENT_FD_READ) {
- sock->event.read_handler(sock, sock->event.read_private);
- return;
- }
-}
-
-static int tsocket_context_bsd_set_event_context(struct tsocket_context *sock,
- struct tevent_context *ev)
-{
- struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
- struct tsocket_context_bsd);
-
- talloc_free(bsds->fde);
- bsds->fde = NULL;
- ZERO_STRUCT(sock->event);
-
- if (!ev) {
- return 0;
- }
-
- bsds->fde = tevent_add_fd(ev, bsds,
- bsds->fd,
- 0,
- tsocket_context_bsd_fde_handler,
- sock);
- if (!bsds->fde) {
- if (errno == 0) {
- errno = ENOMEM;
- }
- return -1;
- }
-
- sock->event.ctx = ev;
-
- return 0;
-}
-
-static int tsocket_context_bsd_set_read_handler(struct tsocket_context *sock,
- tsocket_event_handler_t handler,
- void *private_data)
-{
- struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
- struct tsocket_context_bsd);
-
- if (sock->event.read_handler && !handler) {
- TEVENT_FD_NOT_READABLE(bsds->fde);
- } else if (!sock->event.read_handler && handler) {
- TEVENT_FD_READABLE(bsds->fde);
- }
-
- sock->event.read_handler = handler;
- sock->event.read_private = private_data;
-
- return 0;
-}
-
-static int tsocket_context_bsd_set_write_handler(struct tsocket_context *sock,
- tsocket_event_handler_t handler,
- void *private_data)
-{
- struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
- struct tsocket_context_bsd);
-
- if (sock->event.write_handler && !handler) {
- TEVENT_FD_NOT_WRITEABLE(bsds->fde);
- } else if (!sock->event.write_handler && handler) {
- TEVENT_FD_WRITEABLE(bsds->fde);
- }
-
- sock->event.write_handler = handler;
- sock->event.write_private = private_data;
-
- return 0;
-}
-
-static int tsocket_context_bsd_connect_to(struct tsocket_context *sock,
- const struct tsocket_address *remote)
-{
- struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
- struct tsocket_context_bsd);
- struct tsocket_address_bsd *bsda = talloc_get_type(remote->private_data,
- struct tsocket_address_bsd);
- int ret;
-
- ret = connect(bsds->fd, &bsda->u.sa,
- sizeof(bsda->u.ss));
-
- return ret;
-}
-
-static int tsocket_context_bsd_listen_on(struct tsocket_context *sock,
- int queue_size)
-{
- struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
- struct tsocket_context_bsd);
- int ret;
-
- ret = listen(bsds->fd, queue_size);
-
- return ret;
-}
-
-static int tsocket_context_bsd_accept_new(struct tsocket_context *sock,
- TALLOC_CTX *mem_ctx,
- struct tsocket_context **_new_sock,
- const char *location)
-{
- struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
- struct tsocket_context_bsd);
- int new_fd;
- struct tsocket_context *new_sock;
- struct tsocket_context_bsd *new_bsds;
- struct sockaddr_storage ss;
- void *p = &ss;
- socklen_t ss_len = sizeof(ss);
-
- new_fd = accept(bsds->fd, (struct sockaddr *)p, &ss_len);
- if (new_fd < 0) {
- return new_fd;
- }
-
- new_fd = tsocket_common_prepare_fd(new_fd, true);
- if (new_fd < 0) {
- return new_fd;
- }
-
- new_sock = tsocket_context_create(mem_ctx,
- &tsocket_context_bsd_ops,
- &new_bsds,
- struct tsocket_context_bsd,
- location);
- if (!new_sock) {
- int saved_errno = errno;
- close(new_fd);
- errno = saved_errno;
- return -1;
- }
-
- new_bsds->close_on_disconnect = true;
- new_bsds->fd = new_fd;
- new_bsds->fde = NULL;
-
- *_new_sock = new_sock;
- return 0;
-}
-
-static ssize_t tsocket_context_bsd_pending_data(struct tsocket_context *sock)
-{
- struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
- struct tsocket_context_bsd);
- int ret;
- int value = 0;
-
- ret = ioctl(bsds->fd, FIONREAD, &value);
- if (ret == -1) {
- return ret;
- }
-
- if (ret == 0) {
- if (value == 0) {
- int error=0;
- socklen_t len = sizeof(error);
- /*
- * if no data is available check if the socket
- * is in error state. For dgram sockets
- * it's the way to return ICMP error messages
- * of connected sockets to the caller.
- */
- ret = getsockopt(bsds->fd, SOL_SOCKET, SO_ERROR,
- &error, &len);
- if (ret == -1) {
- return ret;
- }
- if (error != 0) {
- errno = error;
- return -1;
- }
- }
- return value;
- }
-
- /* this should not be reached */
- errno = EIO;
- return -1;
-}
-
-static int tsocket_context_bsd_readv_data(struct tsocket_context *sock,
- const struct iovec *vector,
- size_t count)
-{
- struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
- struct tsocket_context_bsd);
- int ret;
-
- ret = readv(bsds->fd, vector, count);
-
- return ret;
-}
-
-static int tsocket_context_bsd_writev_data(struct tsocket_context *sock,
- const struct iovec *vector,
- size_t count)
-{
- struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
- struct tsocket_context_bsd);
- int ret;
-
- ret = writev(bsds->fd, vector, count);
-
- return ret;
-}
-
-static int tsocket_context_bsd_get_status(const struct tsocket_context *sock)
-{
- struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
- struct tsocket_context_bsd);
- int ret;
- int error=0;
- socklen_t len = sizeof(error);
-
- if (bsds->fd == -1) {
- errno = EPIPE;
- return -1;
- }
-
- ret = getsockopt(bsds->fd, SOL_SOCKET, SO_ERROR, &error, &len);
- if (ret == -1) {
- return ret;
- }
- if (error != 0) {
- errno = error;
- return -1;
- }
-
- return 0;
-}
-
-static int tsocket_context_bsd_get_local_address(const struct tsocket_context *sock,
- TALLOC_CTX *mem_ctx,
- struct tsocket_address **_addr,
- const char *location)
-{
- struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
- struct tsocket_context_bsd);
- struct tsocket_address *addr;
- struct tsocket_address_bsd *bsda;
- ssize_t ret;
- socklen_t sa_len;
-
- addr = tsocket_address_create(mem_ctx,
- &tsocket_address_bsd_ops,
- &bsda,
- struct tsocket_address_bsd,
- location);
- if (!addr) {
- return -1;
- }
-
- ZERO_STRUCTP(bsda);
-
- sa_len = sizeof(bsda->u.ss);
- ret = getsockname(bsds->fd, &bsda->u.sa, &sa_len);
- if (ret < 0) {
- int saved_errno = errno;
- talloc_free(addr);
- errno = saved_errno;
- return ret;
- }
-
- *_addr = addr;
- return 0;
-}
-
-static int tsocket_context_bsd_get_remote_address(const struct tsocket_context *sock,
- TALLOC_CTX *mem_ctx,
- struct tsocket_address **_addr,
- const char *location)
-{
- struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
- struct tsocket_context_bsd);
- struct tsocket_address *addr;
- struct tsocket_address_bsd *bsda;
- ssize_t ret;
- socklen_t sa_len;
-
- addr = tsocket_address_create(mem_ctx,
- &tsocket_address_bsd_ops,
- &bsda,
- struct tsocket_address_bsd,
- location);
- if (!addr) {
- return -1;
- }
-
- ZERO_STRUCTP(bsda);
-
- sa_len = sizeof(bsda->u.ss);
- ret = getpeername(bsds->fd, &bsda->u.sa, &sa_len);
- if (ret < 0) {
- int saved_errno = errno;
- talloc_free(addr);
- errno = saved_errno;
- return ret;
- }
-
- *_addr = addr;
- return 0;
-}
-
-static const struct tsocket_context_bsd_option {
- const char *name;
- int level;
- int optnum;
- int optval;
-} tsocket_context_bsd_options[] = {
-#define TSOCKET_OPTION(_level, _optnum, _optval) { \
- .name = #_optnum, \
- .level = _level, \
- .optnum = _optnum, \
- .optval = _optval \
-}
- TSOCKET_OPTION(SOL_SOCKET, SO_REUSEADDR, 0),
- TSOCKET_OPTION(SOL_SOCKET, SO_BROADCAST, 0)
-};
-
-static int tsocket_context_bsd_get_option(const struct tsocket_context *sock,
- const char *option,
- TALLOC_CTX *mem_ctx,
- char **_value)
-{
- struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
- struct tsocket_context_bsd);
- const struct tsocket_context_bsd_option *opt = NULL;
- uint32_t i;
- int optval;
- socklen_t optval_len = sizeof(optval);
- char *value;
- int ret;
-
- for (i=0; i < ARRAY_SIZE(tsocket_context_bsd_options); i++) {
- if (strcmp(option, tsocket_context_bsd_options[i].name) != 0) {
- continue;
- }
-
- opt = &tsocket_context_bsd_options[i];
- break;
- }
-
- if (!opt) {
- goto nosys;
- }
-
- ret = getsockopt(bsds->fd, opt->level, opt->optnum,
- (void *)&optval, &optval_len);
- if (ret != 0) {
- return ret;
- }
-
- if (optval_len != sizeof(optval)) {
- value = NULL;
- } if (opt->optval != 0) {
- if (optval == opt->optval) {
- value = talloc_strdup(mem_ctx, "1");
- } else {
- value = talloc_strdup(mem_ctx, "0");
- }
- if (!value) {
- goto nomem;
- }
- } else {
- value = talloc_asprintf(mem_ctx, "%d", optval);
- if (!value) {
- goto nomem;
- }
- }
-
- *_value = value;
- return 0;
-
- nomem:
- errno = ENOMEM;
- return -1;
- nosys:
- errno = ENOSYS;
- return -1;
-}
-
-static int tsocket_context_bsd_set_option(const struct tsocket_context *sock,
- const char *option,
- bool force,
- const char *value)
-{
- struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
- struct tsocket_context_bsd);
- const struct tsocket_context_bsd_option *opt = NULL;
- uint32_t i;
- int optval;
- int ret;
-
- for (i=0; i < ARRAY_SIZE(tsocket_context_bsd_options); i++) {
- if (strcmp(option, tsocket_context_bsd_options[i].name) != 0) {
- continue;
- }
-
- opt = &tsocket_context_bsd_options[i];
- break;
- }
-
- if (!opt) {
- goto nosys;
- }
-
- if (value) {
- if (opt->optval != 0) {
- errno = EINVAL;
- return -1;
- }
-
- optval = atoi(value);
- } else {
- optval = opt->optval;
- }
-
- ret = setsockopt(bsds->fd, opt->level, opt->optnum,
- (const void *)&optval, sizeof(optval));
- if (ret != 0) {
- if (!force) {
- errno = 0;
- return 0;
- }
- return ret;
- }
-
- return 0;
-
- nosys:
- if (!force) {
- return 0;
- }
-
- errno = ENOSYS;
- return -1;
-}
-
-static void tsocket_context_bsd_disconnect(struct tsocket_context *sock)
-{
- struct tsocket_context_bsd *bsds = talloc_get_type(sock->private_data,
- struct tsocket_context_bsd);
-
- tsocket_context_bsd_set_event_context(sock, NULL);
-
- if (bsds->fd != -1) {
- if (bsds->close_on_disconnect) {
- close(bsds->fd);
- }
- bsds->fd = -1;
- }
-}
-
-static const struct tsocket_context_ops tsocket_context_bsd_ops = {
- .name = "bsd",
-
- .set_event_context = tsocket_context_bsd_set_event_context,
- .set_read_handler = tsocket_context_bsd_set_read_handler,
- .set_write_handler = tsocket_context_bsd_set_write_handler,
-
- .connect_to = tsocket_context_bsd_connect_to,
- .listen_on = tsocket_context_bsd_listen_on,
- .accept_new = tsocket_context_bsd_accept_new,
-
- .pending_data = tsocket_context_bsd_pending_data,
- .readv_data = tsocket_context_bsd_readv_data,
- .writev_data = tsocket_context_bsd_writev_data,
-
- .get_status = tsocket_context_bsd_get_status,
- .get_local_address = tsocket_context_bsd_get_local_address,
- .get_remote_address = tsocket_context_bsd_get_remote_address,
-
- .get_option = tsocket_context_bsd_get_option,
- .set_option = tsocket_context_bsd_set_option,
-
- .disconnect = tsocket_context_bsd_disconnect
};
struct tdgram_bsd {
@@ -1482,7 +814,7 @@ static void tdgram_bsd_recvfrom_handler(void *private_data)
sa_len = sizeof(bsda->u.ss);
ret = recvfrom(bsds->fd, state->buf, state->len, 0, sa, &sa_len);
- err = tsocket_error_from_errno(ret, errno, &retry);
+ err = tsocket_bsd_error_from_errno(ret, errno, &retry);
if (retry) {
/* retry later */
return;
@@ -1630,7 +962,7 @@ static void tdgram_bsd_sendto_handler(void *private_data)
}
ret = sendto(bsds->fd, state->buf, state->len, 0, sa, sa_len);
- err = tsocket_error_from_errno(ret, errno, &retry);
+ err = tsocket_bsd_error_from_errno(ret, errno, &retry);
if (retry) {
/* retry later */
return;
@@ -1692,7 +1024,7 @@ static struct tevent_req *tdgram_bsd_disconnect_send(TALLOC_CTX *mem_ctx,
ret = close(bsds->fd);
bsds->fd = -1;
- err = tsocket_error_from_errno(ret, errno, &dummy);
+ err = tsocket_bsd_error_from_errno(ret, errno, &dummy);
if (tevent_req_error(req, err)) {
goto post;
}
@@ -1739,6 +1071,7 @@ static int tdgram_bsd_destructor(struct tdgram_bsd *bsds)
static int tdgram_bsd_dgram_socket(const struct tsocket_address *local,
const struct tsocket_address *remote,
+ bool broadcast,
TALLOC_CTX *mem_ctx,
struct tdgram_context **_dgram,
const char *location)
@@ -1761,6 +1094,10 @@ static int tdgram_bsd_dgram_socket(const struct tsocket_address *local,
switch (lbsda->u.sa.sa_family) {
case AF_UNIX:
+ if (broadcast) {
+ errno = EINVAL;
+ return -1;
+ }
if (lbsda->u.un.sun_path[0] != 0) {
do_reuseaddr = true;
do_bind = true;
@@ -1818,7 +1155,7 @@ static int tdgram_bsd_dgram_socket(const struct tsocket_address *local,
bsds->fd = fd;
talloc_set_destructor(bsds, tdgram_bsd_destructor);
- if (lbsda->broadcast) {
+ if (broadcast) {
int val = 1;
ret = setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
@@ -1891,7 +1228,8 @@ int _tdgram_inet_udp_socket(const struct tsocket_address *local,
return -1;
}
- ret = tdgram_bsd_dgram_socket(local, remote, mem_ctx, dgram, location);
+ ret = tdgram_bsd_dgram_socket(local, remote, false,
+ mem_ctx, dgram, location);
return ret;
}
@@ -1915,7 +1253,8 @@ int _tdgram_unix_dgram_socket(const struct tsocket_address *local,
return -1;
}
- ret = tdgram_bsd_dgram_socket(local, remote, mem_ctx, dgram, location);
+ ret = tdgram_bsd_dgram_socket(local, remote, false,
+ mem_ctx, dgram, location);
return ret;
}
diff --git a/lib/tsocket/tsocket_connect.c b/lib/tsocket/tsocket_connect.c
deleted file mode 100644
index 7a9d4b8381..0000000000
--- a/lib/tsocket/tsocket_connect.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- 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"
-
-struct tsocket_connect_state {
- /* this structs are owned by the caller */
- struct {
- struct tsocket_context *sock;
- const struct tsocket_address *dst;
- } caller;
-};
-
-static void tsocket_connect_handler(struct tsocket_context *sock,
- void *private_data);
-
-struct tevent_req *tsocket_connect_send(struct tsocket_context *sock,
- TALLOC_CTX *mem_ctx,
- const struct tsocket_address *dst)
-{
- struct tevent_req *req;
- struct tsocket_connect_state *state;
- int ret;
- int err;
- bool retry;
- bool dummy;
-
- req = tevent_req_create(mem_ctx, &state,
- struct tsocket_connect_state);
- if (!req) {
- return NULL;
- }
-
- state->caller.sock = sock;
- state->caller.dst = dst;
-
- ret = tsocket_connect(state->caller.sock,
- state->caller.dst);
- err = tsocket_error_from_errno(ret, errno, &retry);
- if (retry) {
- /* retry later */
- goto async;
- }
- if (tevent_req_error(req, err)) {
- goto post;
- }
-
- tevent_req_done(req);
- goto post;
-
- async:
- ret = tsocket_set_readable_handler(state->caller.sock,
- tsocket_connect_handler,
- req);
- err = tsocket_error_from_errno(ret, errno, &dummy);
- if (tevent_req_error(req, err)) {
- goto post;
- }
-
- return req;
-
- post:
- return tevent_req_post(req, sock->event.ctx);
-}
-
-static void tsocket_connect_handler(struct tsocket_context *sock,
- void *private_data)
-{
- struct tevent_req *req = talloc_get_type(private_data,
- struct tevent_req);
- struct tsocket_connect_state *state = tevent_req_data(req,
- struct tsocket_connect_state);
- int ret;
- int err;
- bool retry;
-
- ret = tsocket_get_status(state->caller.sock);
- err = tsocket_error_from_errno(ret, errno, &retry);
- if (retry) {
- /* retry later */
- return;
- }
- if (tevent_req_error(req, err)) {
- return;
- }
-
- tevent_req_done(req);
-}
-
-int tsocket_connect_recv(struct tevent_req *req, int *perrno)
-{
- int ret;
-
- ret = tsocket_simple_int_recv(req, perrno);
-
- tevent_req_received(req);
- return ret;
-}
-
diff --git a/lib/tsocket/tsocket_helpers.c b/lib/tsocket/tsocket_helpers.c
index b2edf43d97..303be2de11 100644
--- a/lib/tsocket/tsocket_helpers.c
+++ b/lib/tsocket/tsocket_helpers.c
@@ -27,49 +27,6 @@
#include "tsocket.h"
#include "tsocket_internal.h"
-int tsocket_error_from_errno(int ret,
- int sys_errno,
- bool *retry)
-{
- *retry = false;
-
- if (ret >= 0) {
- return 0;
- }
-
- if (ret != -1) {
- return EIO;
- }
-
- if (sys_errno == 0) {
- return EIO;
- }
-
- if (sys_errno == EINTR) {
- *retry = true;
- return sys_errno;
- }
-
- if (sys_errno == EINPROGRESS) {
- *retry = true;
- return sys_errno;
- }
-
- if (sys_errno == EAGAIN) {
- *retry = true;
- return sys_errno;
- }
-
-#ifdef EWOULDBLOCK
- if (sys_errno == EWOULDBLOCK) {
- *retry = true;
- return sys_errno;
- }
-#endif
-
- return sys_errno;
-}
-
int tsocket_simple_int_recv(struct tevent_req *req, int *perrno)
{
enum tevent_req_state state;
@@ -97,81 +54,3 @@ int tsocket_simple_int_recv(struct tevent_req *req, int *perrno)
*perrno = EIO;
return -1;
}
-
-int tsocket_common_prepare_fd(int fd, bool high_fd)
-{
- int i;
- int sys_errno = 0;
- int fds[3];
- int num_fds = 0;
-
- int result, flags;
-
- if (fd == -1) {
- return -1;
- }
-
- /* first make a fd >= 3 */
- if (high_fd) {
- while (fd < 3) {
- fds[num_fds++] = fd;
- fd = dup(fd);
- if (fd == -1) {
- sys_errno = errno;
- break;
- }
- }
- for (i=0; i<num_fds; i++) {
- close(fds[i]);
- }
- if (fd == -1) {
- errno = sys_errno;
- return fd;
- }
- }
-
- /* fd should be nonblocking. */
-
-#ifdef O_NONBLOCK
-#define FLAG_TO_SET O_NONBLOCK
-#else
-#ifdef SYSV
-#define FLAG_TO_SET O_NDELAY
-#else /* BSD */
-#define FLAG_TO_SET FNDELAY
-#endif
-#endif
-
- if ((flags = fcntl(fd, F_GETFL)) == -1) {
- goto fail;
- }
-
- flags |= FLAG_TO_SET;
- if (fcntl(fd, F_SETFL, flags) == -1) {
- goto fail;
- }
-
-#undef FLAG_TO_SET
-
- /* fd should be closed on exec() */
-#ifdef FD_CLOEXEC
- result = flags = fcntl(fd, F_GETFD, 0);
- if (flags >= 0) {
- flags |= FD_CLOEXEC;
- result = fcntl(fd, F_SETFD, flags);
- }
- if (result < 0) {
- goto fail;
- }
-#endif
- return fd;
-
- fail:
- if (fd != -1) {
- sys_errno = errno;
- close(fd);
- errno = sys_errno;
- }
- return -1;
-}
-
diff --git a/lib/tsocket/tsocket_internal.h b/lib/tsocket/tsocket_internal.h
index 893394405f..a03dc9bde0 100644
--- a/lib/tsocket/tsocket_internal.h
+++ b/lib/tsocket/tsocket_internal.h
@@ -24,89 +24,6 @@
#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);
-
- /* 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;
@@ -116,12 +33,6 @@ struct tsocket_address_ops {
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 {
@@ -182,9 +93,7 @@ void *_tdgram_context_data(struct tdgram_context *dgram);
#define tdgram_context_data(_req, _type) \
talloc_get_type_abort(_tdgram_context_data(_req), _type)
-int tsocket_error_from_errno(int ret, int sys_errno, bool *retry);
int tsocket_simple_int_recv(struct tevent_req *req, int *perrno);
-int tsocket_common_prepare_fd(int fd, bool high_fd);
#endif /* _TSOCKET_H */
diff --git a/lib/tsocket/tsocket_readv.c b/lib/tsocket/tsocket_readv.c
deleted file mode 100644
index 2c8483ec7e..0000000000
--- a/lib/tsocket/tsocket_readv.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- 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"
-
-struct tsocket_readv_state {
- /* this structs are owned by the caller */
- struct {
- struct tsocket_context *sock;
- tsocket_readv_next_iovec_t next_iovec_fn;
- void *private_data;
- } caller;
-
- /*
- * Each call to the callback resets iov and count
- * the callback allocated the iov as child of our state,
- * that means we are allowed to modify and free it.
- *
- * we should call the callback every time we filled the given
- * vector and ask for a new vector. We return if the callback
- * ask for 0 bytes.
- */
- struct iovec *iov;
- size_t count;
-
- /*
- * the total number of bytes we read,
- * the return value of the _recv function
- */
- int total_read;
-};
-
-static int tsocket_readv_state_destructor(struct tsocket_readv_state *state)
-{
- if (state->caller.sock) {
- tsocket_set_readable_handler(state->caller.sock, NULL, NULL);
- }
- ZERO_STRUCT(state->caller);
-
- return 0;
-}
-
-static bool tsocket_readv_ask_for_next_vector(struct tevent_req *req,
- struct tsocket_readv_state *state)
-{
- int ret;
- int err;
- bool dummy;
- size_t to_read = 0;
- size_t i;
-
- talloc_free(state->iov);
- state->iov = NULL;
- state->count = 0;
-
- ret = state->caller.next_iovec_fn(state->caller.sock,
- state->caller.private_data,
- state, &state->iov, &state->count);
- err = tsocket_error_from_errno(ret, errno, &dummy);
- if (tevent_req_error(req, err)) {
- return false;
- }
-
- for (i=0; i < state->count; i++) {
- size_t tmp = to_read;
- tmp += state->iov[i].iov_len;
-
- if (tmp < to_read) {
- tevent_req_error(req, EMSGSIZE);
- return false;
- }
-
- to_read = tmp;
- }
-
- if (to_read == 0) {
- tevent_req_done(req);
- return false;
- }
-
- if (state->total_read + to_read < state->total_read) {
- tevent_req_error(req, EMSGSIZE);
- return false;
- }
-
- return true;
-}
-
-static void tsocket_readv_handler(struct tsocket_context *sock,
- void *private_data);
-
-struct tevent_req *tsocket_readv_send(struct tsocket_context *sock,
- TALLOC_CTX *mem_ctx,
- tsocket_readv_next_iovec_t next_iovec_fn,
- void *private_data)
-{
- struct tevent_req *req;
- struct tsocket_readv_state *state;
- int ret;
- int err;
- bool dummy;
-
- req = tevent_req_create(mem_ctx, &state,
- struct tsocket_readv_state);
- if (!req) {
- return NULL;
- }
-
- state->caller.sock = sock;
- state->caller.next_iovec_fn = next_iovec_fn;
- state->caller.private_data = private_data;
-
- state->iov = NULL;
- state->count = 0;
- state->total_read = 0;
-
- if (!tsocket_readv_ask_for_next_vector(req, state)) {
- goto post;
- }
-
- talloc_set_destructor(state, tsocket_readv_state_destructor);
-
- ret = tsocket_set_readable_handler(sock,
- tsocket_readv_handler,
- req);
- err = tsocket_error_from_errno(ret, errno, &dummy);
- if (tevent_req_error(req, err)) {
- goto post;
- }
-
- return req;
-
- post:
- return tevent_req_post(req, sock->event.ctx);
-}
-
-static void tsocket_readv_handler(struct tsocket_context *sock,
- void *private_data)
-{
- struct tevent_req *req = talloc_get_type(private_data,
- struct tevent_req);
- struct tsocket_readv_state *state = tevent_req_data(req,
- struct tsocket_readv_state);
- ssize_t ret;
- int err;
- bool retry;
-
- ret = tsocket_readv(state->caller.sock,
- state->iov,
- state->count);
- err = tsocket_error_from_errno(ret, errno, &retry);
- if (retry) {
- /* retry later */
- return;
- }
- if (tevent_req_error(req, err)) {
- return;
- }
-
- state->total_read += ret;
-
- while (ret > 0) {
- if (ret < state->iov[0].iov_len) {
- uint8_t *base;
- base = (uint8_t *)state->iov[0].iov_base;
- base += ret;
- state->iov[0].iov_base = base;
- state->iov[0].iov_len -= ret;
- break;
- }
- ret -= state->iov[0].iov_len;
- state->iov += 1;
- state->count -= 1;
- }
-
- if (state->count) {
- /* we have more to read */
- return;
- }
-
- /* ask the callback for a new vector we should fill */
- tsocket_readv_ask_for_next_vector(req, state);
-}
-
-int tsocket_readv_recv(struct tevent_req *req, int *perrno)
-{
- struct tsocket_readv_state *state = tevent_req_data(req,
- struct tsocket_readv_state);
- int ret;
-
- ret = tsocket_simple_int_recv(req, perrno);
- if (ret == 0) {
- ret = state->total_read;
- }
-
- tevent_req_received(req);
- return ret;
-}
-
diff --git a/lib/tsocket/tsocket_writev.c b/lib/tsocket/tsocket_writev.c
deleted file mode 100644
index 8c5cd40385..0000000000
--- a/lib/tsocket/tsocket_writev.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- 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"
-
-struct tsocket_writev_state {
- /* this structs are owned by the caller */
- struct {
- struct tsocket_context *sock;
- const struct iovec *vector;
- size_t count;
- } caller;
-
- struct iovec *iov;
- size_t count;
- int total_written;
-};
-
-static int tsocket_writev_state_destructor(struct tsocket_writev_state *state)
-{
- if (state->caller.sock) {
- tsocket_set_writeable_handler(state->caller.sock, NULL, NULL);
- }
- ZERO_STRUCT(state->caller);
-
- return 0;
-}
-
-static void tsocket_writev_handler(struct tsocket_context *sock,
- void *private_data);
-
-struct tevent_req *tsocket_writev_send(struct tsocket_context *sock,
- TALLOC_CTX *mem_ctx,
- const struct iovec *vector,
- size_t count)
-{
- struct tevent_req *req;
- struct tsocket_writev_state *state;
- int ret;
- int err;
- bool dummy;
- int to_write = 0;
- size_t i;
-
- req = tevent_req_create(mem_ctx, &state,
- struct tsocket_writev_state);
- if (!req) {
- return NULL;
- }
-
- state->caller.sock = sock;
- state->caller.vector = vector;
- state->caller.count = count;
-
- state->iov = NULL;
- state->count = count;
- state->total_written = 0;
-
- state->iov = talloc_array(state, struct iovec, count);
- if (tevent_req_nomem(state->iov, req)) {
- goto post;
- }
- memcpy(state->iov, vector, sizeof(struct iovec) * count);
-
- for (i=0; i < count; i++) {
- int tmp = to_write;
-
- tmp += state->iov[i].iov_len;
-
- if (tmp < to_write) {
- tevent_req_error(req, EMSGSIZE);
- goto post;
- }
-
- to_write = tmp;
- }
-
- if (to_write == 0) {
- tevent_req_done(req);
- goto post;
- }
-
- /*
- * this is a fast path, not waiting for the
- * socket to become explicit writeable gains
- * about 10%-20% performance in benchmark tests.
- */
- tsocket_writev_handler(sock, req);
- if (!tevent_req_is_in_progress(req)) {
- goto post;
- }
-
- talloc_set_destructor(state, tsocket_writev_state_destructor);
-
- ret = tsocket_set_writeable_handler(sock,
- tsocket_writev_handler,
- req);
- err = tsocket_error_from_errno(ret, errno, &dummy);
- if (tevent_req_error(req, err)) {
- goto post;
- }
-
- return req;
-
- post:
- return tevent_req_post(req, sock->event.ctx);
-}
-
-static void tsocket_writev_handler(struct tsocket_context *sock,
- void *private_data)
-{
- struct tevent_req *req = talloc_get_type(private_data,
- struct tevent_req);
- struct tsocket_writev_state *state = tevent_req_data(req,
- struct tsocket_writev_state);
- int ret;
- int err;
- bool retry;
-
- ret = tsocket_writev(state->caller.sock,
- state->iov,
- state->count);
- err = tsocket_error_from_errno(ret, errno, &retry);
- if (retry) {
- /* retry later */
- return;
- }
- if (tevent_req_error(req, err)) {
- return;
- }
-
- state->total_written += ret;
-
- /*
- * we have not written everything yet, so we need to truncate
- * the already written bytes from our iov copy
- */
- while (ret > 0) {
- if (ret < state->iov[0].iov_len) {
- uint8_t *base;
- base = (uint8_t *)state->iov[0].iov_base;
- base += ret;
- state->iov[0].iov_base = base;
- state->iov[0].iov_len -= ret;
- break;
- }
- ret -= state->iov[0].iov_len;
- state->iov += 1;
- state->count -= 1;
- }
-
- if (state->count > 0) {
- /* more to write */
- return;
- }
-
- tevent_req_done(req);
-}
-
-int tsocket_writev_recv(struct tevent_req *req, int *perrno)
-{
- struct tsocket_writev_state *state = tevent_req_data(req,
- struct tsocket_writev_state);
- int ret;
-
- ret = tsocket_simple_int_recv(req, perrno);
- if (ret == 0) {
- ret = state->total_written;
- }
-
- tevent_req_received(req);
- return ret;
-}
-
-struct tsocket_writev_queue_state {
- /* this structs are owned by the caller */
- struct {
- struct tsocket_context *sock;
- const struct iovec *vector;
- size_t count;
- } caller;
- int ret;
-};
-
-static void tsocket_writev_queue_trigger(struct tevent_req *req,
- void *private_data);
-static void tsocket_writev_queue_done(struct tevent_req *subreq);
-
-/**
- * @brief Queue a dgram blob for sending through the socket
- * @param[in] mem_ctx The memory context for the result
- * @param[in] sock The socket to send data through
- * @param[in] queue The existing send queue
- * @param[in] vector The iovec vector so write
- * @param[in] count The size of the vector
- * @retval The async request handle
- *
- * This function queues a blob for sending to destination through an existing
- * dgram socket. The async callback is triggered when the whole blob is
- * delivered to the underlying system socket.
- *
- * The caller needs to make sure that all non-scalar input parameters hang
- * arround for the whole lifetime of the request.
- */
-struct tevent_req *tsocket_writev_queue_send(TALLOC_CTX *mem_ctx,
- struct tsocket_context *sock,
- struct tevent_queue *queue,
- const struct iovec *vector,
- size_t count)
-{
- struct tevent_req *req;
- struct tsocket_writev_queue_state *state;
- bool ok;
-
- req = tevent_req_create(mem_ctx, &state,
- struct tsocket_writev_queue_state);
- if (!req) {
- return NULL;
- }
-
- state->caller.sock = sock;
- state->caller.vector = vector;
- state->caller.count = count;
- state->ret = -1;
-
- ok = tevent_queue_add(queue,
- sock->event.ctx,
- req,
- tsocket_writev_queue_trigger,
- NULL);
- if (!ok) {
- tevent_req_nomem(NULL, req);
- goto post;
- }
-
- return req;
-
- post:
- return tevent_req_post(req, sock->event.ctx);
-}
-
-static void tsocket_writev_queue_trigger(struct tevent_req *req,
- void *private_data)
-{
- struct tsocket_writev_queue_state *state = tevent_req_data(req,
- struct tsocket_writev_queue_state);
- struct tevent_req *subreq;
-
- subreq = tsocket_writev_send(state->caller.sock,
- state,
- state->caller.vector,
- state->caller.count);
- if (tevent_req_nomem(subreq, req)) {
- return;
- }
- tevent_req_set_callback(subreq, tsocket_writev_queue_done ,req);
-}
-
-static void tsocket_writev_queue_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct tsocket_writev_queue_state *state = tevent_req_data(req,
- struct tsocket_writev_queue_state);
- int ret;
- int sys_errno;
-
- ret = tsocket_writev_recv(subreq, &sys_errno);
- talloc_free(subreq);
- if (ret == -1) {
- tevent_req_error(req, sys_errno);
- return;
- }
- state->ret = ret;
-
- tevent_req_done(req);
-}
-
-int tsocket_writev_queue_recv(struct tevent_req *req, int *perrno)
-{
- struct tsocket_writev_queue_state *state = tevent_req_data(req,
- struct tsocket_writev_queue_state);
- int ret;
-
- ret = tsocket_simple_int_recv(req, perrno);
- if (ret == 0) {
- ret = state->ret;
- }
-
- tevent_req_received(req);
- return ret;
-}
-