[SCM] Socket Wrapper Repository - branch master updated
Andreas Schneider
asn at samba.org
Tue Jan 28 07:18:20 MST 2014
The branch, master has been updated
via bb4dd1f src: Handle stale fds in dup() and dup2().
via 9c03935 src: Add timerfd_create() to handle stale fds.
via f850820 src: Add eventfd() to handle stale fds.
via dc00232 src: Add signalfd() to handle stale fds.
via 95520f6 src: Add socketpair() to handle stale fds.
via ea45102 src: Add pipe() to handle stale fds.
via 0627527 src: Check for stale fds in swrap_accept().
via 5acfcfe src: Check for stale fds in swrap_socket().
via 05cb607 src: Handle stale fds in swrap_recvmsg_after().
via 3ab00f5 src: Handle stale fds in swrap_sendmsg_after().
via de94be7 src: Try to recover when reading from a fd returns ENOTSOCK.
via 27b2055 src: Try to recover when writing to fd returns ENOTSOCK.
via 1462a69 src: Try to recover when sockets are closed elsewhere.
via 019e4f3 src: Use swrap_recvmsg_(before|after) for swrap_readv().
via e200ed8 Update TODO.
via 553d8a2 Update ChangeLog.
from bede01d Update TODO.
http://gitweb.samba.org/?p=socket_wrapper.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit bb4dd1f1733fe80493e3f165f206df675fb32beb
Author: Andreas Schneider <asn at samba.org>
Date: Tue Jan 28 14:10:53 2014 +0100
src: Handle stale fds in dup() and dup2().
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 9c03935fc0abb033a32683f5e9d8bd6b2136b8fd
Author: Andreas Schneider <asn at samba.org>
Date: Tue Jan 28 13:48:52 2014 +0100
src: Add timerfd_create() to handle stale fds.
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit f8508200e90048523fc7c78467dc8e565744f7f9
Author: Andreas Schneider <asn at samba.org>
Date: Tue Jan 28 13:42:38 2014 +0100
src: Add eventfd() to handle stale fds.
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit dc0023293292d5247a5984e78fc10de9399da5f5
Author: Andreas Schneider <asn at samba.org>
Date: Tue Jan 28 13:33:23 2014 +0100
src: Add signalfd() to handle stale fds.
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 95520f672f3cbf311b503d61e2ac9e2a22d209e9
Author: Andreas Schneider <asn at samba.org>
Date: Tue Jan 28 13:20:20 2014 +0100
src: Add socketpair() to handle stale fds.
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit ea45102993c0800a8a62137da09dbb2787834ed4
Author: Andreas Schneider <asn at samba.org>
Date: Tue Jan 28 13:15:34 2014 +0100
src: Add pipe() to handle stale fds.
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 0627527da3abbafdb6f171dbdbc3b719a96a2b62
Author: Andreas Schneider <asn at samba.org>
Date: Tue Jan 28 13:10:01 2014 +0100
src: Check for stale fds in swrap_accept().
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 5acfcfea50ce2dd1b0388c33c849ce19007cf77b
Author: Andreas Schneider <asn at samba.org>
Date: Tue Jan 28 10:33:36 2014 +0100
src: Check for stale fds in swrap_socket().
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 05cb607f08321b1680e51cb3bb33222922f46401
Author: Andreas Schneider <asn at samba.org>
Date: Tue Jan 28 11:34:03 2014 +0100
src: Handle stale fds in swrap_recvmsg_after().
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 3ab00f5deaefa2dbdac9ba71841e178a78988dd2
Author: Andreas Schneider <asn at samba.org>
Date: Tue Jan 28 11:30:20 2014 +0100
src: Handle stale fds in swrap_sendmsg_after().
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit de94be7e4b83283f3b46320706fef19b8203b52c
Author: Nalin Dahyabhai <nalin at dahyabhai.net>
Date: Tue Jan 28 11:25:40 2014 +0100
src: Try to recover when reading from a fd returns ENOTSOCK.
When attempting to read from a descriptor, if an underlying
autobind fails because it's not a socket, stop intercepting uses of that
descriptor.
Reviewed-by: Andreas Schneider <asn at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 27b2055291caf67c6a23e829f596cc6751ce5aad
Author: Nalin Dahyabhai <nalin at dahyabhai.net>
Date: Tue Jan 28 11:24:27 2014 +0100
src: Try to recover when writing to fd returns ENOTSOCK.
When attempting to write to a descriptor, if an underlying autobind
fails because it's not a socket, stop intercepting uses of that
descriptor.
Reviewed-by: Andreas Schneider <asn at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 1462a69c0a96605081f9f1c0dc5bb54aa98aa202
Author: Nalin Dahyabhai <nalin at dahyabhai.net>
Date: Tue Jan 28 11:22:26 2014 +0100
src: Try to recover when sockets are closed elsewhere.
There are methods for closing descriptors (libc-internal code paths,
direct syscalls) which close descriptors in ways that we
can't intercept, so try to recover when we notice that that's happened:
* If we see a descriptor being handed back from open() that we thought
was a socket, stop intercepting uses of that descriptor.
Reviewed-by: Andreas Schneider <asn at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 019e4f3bb6e5589ad8fe0ca0c07b197cb8cbb677
Author: Andreas Schneider <asn at samba.org>
Date: Tue Jan 28 10:06:18 2014 +0100
src: Use swrap_recvmsg_(before|after) for swrap_readv().
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit e200ed88dbf6c9969daee83f9fcdca2c5bd1c0e7
Author: Andreas Schneider <asn at samba.org>
Date: Tue Jan 28 10:14:08 2014 +0100
Update TODO.
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 553d8a25f86db7935617fdf4326ac9859d5ebb31
Author: Andreas Schneider <asn at samba.org>
Date: Tue Jan 28 10:14:17 2014 +0100
Update ChangeLog.
Reviewed-by: Stefan Metzmacher <metze at samba.org>
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 5 +
ConfigureChecks.cmake | 13 +-
TODO | 3 +
config.h.cmake | 7 +
src/socket_wrapper.c | 448 +++++++++++++++++++++++++++++++++++++++---------
5 files changed, 385 insertions(+), 91 deletions(-)
Changeset truncated at 500 lines:
diff --git a/ChangeLog b/ChangeLog
index e69de29..d2f5d4e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -0,0 +1,5 @@
+ChangeLog
+==========
+
+version 1.0.0 (released 2014-02-02)
+ * Initial release
diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake
index 2d8e690..c05cbb9 100644
--- a/ConfigureChecks.cmake
+++ b/ConfigureChecks.cmake
@@ -48,18 +48,17 @@ endif(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW AND NOT OS2)
# HEADERS
check_include_file(sys/filio.h HAVE_SYS_FILIO_H)
+check_include_file(sys/signalfd.h HAVE_SYS_SIGNALFD_H)
+check_include_file(sys/eventfd.h HAVE_SYS_EVENTFD_H)
+check_include_file(sys/timerfd.h HAVE_SYS_TIMERFD_H)
# FUNCTIONS
check_function_exists(strncpy HAVE_STRNCPY)
check_function_exists(vsnprintf HAVE_VSNPRINTF)
check_function_exists(snprintf HAVE_SNPRINTF)
-
-if (WIN32)
- check_function_exists(_vsnprintf_s HAVE__VSNPRINTF_S)
- check_function_exists(_vsnprintf HAVE__VSNPRINTF)
- check_function_exists(_snprintf HAVE__SNPRINTF)
- check_function_exists(_snprintf_s HAVE__SNPRINTF_S)
-endif (WIN32)
+check_function_exists(signalfd HAVE_SIGNALFD)
+check_function_exists(eventfd HAVE_EVENTFD)
+check_function_exists(timerfd_create HAVE_TIMERFD_CREATE)
if (UNIX)
if (NOT LINUX)
diff --git a/TODO b/TODO
index 2ce46ff..205cfaf 100644
--- a/TODO
+++ b/TODO
@@ -10,6 +10,8 @@ Library:
We accept a connection from a client and need to pass the fd to another
child we forked. socket_wrapper then needs to send the 'struct socket_info'
to the child first and set it up there.
+ Or do it like swrap_accept() and call getpeername() and getsockname().
+* Add support for threading.
Testing:
---------
@@ -17,3 +19,4 @@ Testing:
* Add a test for sento() to broadcast 255.255.255.255.
* Add a test to check that read/readv/send/ only work on connected sockets.
* Add unit tests for conversion functions like convert_in_un_remote().
+* Add threaded tests.
diff --git a/config.h.cmake b/config.h.cmake
index 63bbdb4..abbf133 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -15,6 +15,9 @@
/************************** HEADER FILES *************************/
#cmakedefine HAVE_SYS_FILIO_H 1
+#cmakedefine HAVE_SYS_SIGNALFD_H 1
+#cmakedefine HAVE_SYS_EVENTFD_H 1
+#cmakedefine HAVE_SYS_TIMERFD_H 1
/************************ STRUCT MEMBERS *************************/
@@ -25,6 +28,10 @@
/* Define to 1 if you have the `getaddrinfo' function. */
#cmakedefine HAVE_GETADDRINFO 1
+#cmakedefine HAVE_SIGNALFD 1
+#cmakedefine HAVE_EVENTFD 1
+#cmakedefine HAVE_TIMERFD_CREATE 1
+
#cmakedefine HAVE_ACCEPT_PSOCKLEN_T 1
#cmakedefine HAVE_IOCTL_INT 1
diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c
index 2ea35a9..353a9a5 100644
--- a/src/socket_wrapper.c
+++ b/src/socket_wrapper.c
@@ -50,6 +50,15 @@
#ifdef HAVE_SYS_FILIO_H
#include <sys/filio.h>
#endif
+#ifdef HAVE_SYS_SIGNALFD_H
+#include <sys/signalfd.h>
+#endif
+#ifdef HAVE_SYS_EVENTFD_H
+#include <sys/eventfd.h>
+#endif
+#ifdef HAVE_SYS_TIMERFD_H
+#include <sys/timerfd.h>
+#endif
#include <sys/uio.h>
#include <errno.h>
#include <sys/un.h>
@@ -283,6 +292,9 @@ struct swrap_libc_fns {
socklen_t addrlen);
int (*libc_dup)(int fd);
int (*libc_dup2)(int oldfd, int newfd);
+#ifdef HAVE_EVENTFD
+ int (*libc_eventfd)(int count, int flags);
+#endif
int (*libc_getpeername)(int sockfd,
struct sockaddr *addr,
socklen_t *addrlen);
@@ -296,6 +308,8 @@ struct swrap_libc_fns {
socklen_t *optlen);
int (*libc_ioctl)(int d, unsigned long int request, ...);
int (*libc_listen)(int sockfd, int backlog);
+ int (*libc_open)(const char *pathname, int flags, mode_t mode);
+ int (*libc_pipe)(int pipefd[2]);
int (*libc_read)(int fd, void *buf, size_t count);
ssize_t (*libc_readv)(int fd, const struct iovec *iov, int iovcnt);
int (*libc_recv)(int sockfd, void *buf, size_t len, int flags);
@@ -319,7 +333,14 @@ struct swrap_libc_fns {
int optname,
const void *optval,
socklen_t optlen);
+#ifdef HAVE_SIGNALFD
+ int (*libc_signalfd)(int fd, const sigset_t *mask, int flags);
+#endif
int (*libc_socket)(int domain, int type, int protocol);
+ int (*libc_socketpair)(int domain, int type, int protocol, int sv[2]);
+#ifdef HAVE_TIMERFD_CREATE
+ int (*libc_timerfd_create)(int clockid, int flags);
+#endif
ssize_t (*libc_writev)(int fd, const struct iovec *iov, int iovcnt);
};
@@ -505,6 +526,15 @@ static int libc_dup2(int oldfd, int newfd)
return swrap.fns.libc_dup2(oldfd, newfd);
}
+#ifdef HAVE_EVENTFD
+static int libc_eventfd(int count, int flags)
+{
+ swrap_load_lib_function(SWRAP_LIBC, eventfd);
+
+ return swrap.fns.libc_eventfd(count, flags);
+}
+#endif
+
static int libc_getpeername(int sockfd,
struct sockaddr *addr,
socklen_t *addrlen)
@@ -563,6 +593,20 @@ static int libc_listen(int sockfd, int backlog)
return swrap.fns.libc_listen(sockfd, backlog);
}
+static int libc_open(const char *pathname, int flags, mode_t mode)
+{
+ swrap_load_lib_function(SWRAP_LIBC, open);
+
+ return swrap.fns.libc_open(pathname, flags, mode);
+}
+
+static int libc_pipe(int pipefd[2])
+{
+ swrap_load_lib_function(SWRAP_LIBSOCKET, pipe);
+
+ return swrap.fns.libc_pipe(pipefd);
+}
+
static int libc_read(int fd, void *buf, size_t count)
{
swrap_load_lib_function(SWRAP_LIBC, read);
@@ -640,6 +684,15 @@ static int libc_setsockopt(int sockfd,
return swrap.fns.libc_setsockopt(sockfd, level, optname, optval, optlen);
}
+#ifdef HAVE_SIGNALFD
+static int libc_signalfd(int fd, const sigset_t *mask, int flags)
+{
+ swrap_load_lib_function(SWRAP_LIBSOCKET, signalfd);
+
+ return swrap.fns.libc_signalfd(fd, mask, flags);
+}
+#endif
+
static int libc_socket(int domain, int type, int protocol)
{
swrap_load_lib_function(SWRAP_LIBSOCKET, socket);
@@ -647,6 +700,22 @@ static int libc_socket(int domain, int type, int protocol)
return swrap.fns.libc_socket(domain, type, protocol);
}
+static int libc_socketpair(int domain, int type, int protocol, int sv[2])
+{
+ swrap_load_lib_function(SWRAP_LIBSOCKET, socketpair);
+
+ return swrap.fns.libc_socketpair(domain, type, protocol, sv);
+}
+
+#ifdef HAVE_TIMERFD_CREATE
+static int libc_timerfd_create(int clockid, int flags)
+{
+ swrap_load_lib_function(SWRAP_LIBC, timerfd_create);
+
+ return swrap.fns.libc_timerfd_create(clockid, flags);
+}
+#endif
+
static ssize_t libc_writev(int fd, const struct iovec *iov, int iovcnt)
{
swrap_load_lib_function(SWRAP_LIBSOCKET, writev);
@@ -1095,6 +1164,27 @@ static struct socket_info *find_socket_info(int fd)
return NULL;
}
+static void swrap_remove_stale(int fd)
+{
+ struct socket_info *si = find_socket_info(fd);
+ struct socket_info_fd *fi;
+
+ if (si != NULL) {
+ for (fi = si->fds; fi; fi = fi->next) {
+ if (fi->fd == fd) {
+ SWRAP_LOG(SWRAP_LOG_TRACE, "remove stale wrapper for %d", fd);
+ SWRAP_DLIST_REMOVE(si->fds, fi);
+ free(fi);
+ break;
+ }
+ }
+
+ if (si->fds == NULL) {
+ SWRAP_DLIST_REMOVE(sockets, si);
+ }
+ }
+}
+
static int sockaddr_convert_to_un(struct socket_info *si,
const struct sockaddr *in_addr,
socklen_t in_len,
@@ -1921,6 +2011,29 @@ static void swrap_dump_packet(struct socket_info *si,
}
/****************************************************************************
+ * SIGNALFD
+ ***************************************************************************/
+
+#ifdef HAVE_SIGNALFD
+static int swrap_signalfd(int fd, const sigset_t *mask, int flags)
+{
+ int rc;
+
+ rc = libc_signalfd(fd, mask, flags);
+ if (rc != -1) {
+ swrap_remove_stale(fd);
+ }
+
+ return rc;
+}
+
+int signalfd(int fd, const sigset_t *mask, int flags)
+{
+ return swrap_signalfd(fd, mask, flags);
+}
+#endif
+
+/****************************************************************************
* SOCKET
***************************************************************************/
@@ -1994,7 +2107,15 @@ static int swrap_socket(int family, int type, int protocol)
*/
fd = libc_socket(AF_UNIX, type, 0);
- if (fd == -1) return -1;
+ if (fd == -1) {
+ return -1;
+ }
+
+ /* Check if we have a stale fd and remove it */
+ si = find_socket_info(fd);
+ if (si != NULL) {
+ swrap_remove_stale(fd);
+ }
si = (struct socket_info *)malloc(sizeof(struct socket_info));
memset(si, 0, sizeof(struct socket_info));
@@ -2031,6 +2152,73 @@ int socket(int family, int type, int protocol)
}
/****************************************************************************
+ * SOCKETPAIR
+ ***************************************************************************/
+
+static int swrap_socketpair(int family, int type, int protocol, int sv[2])
+{
+ int rc;
+
+ rc = libc_socketpair(family, type, protocol, sv);
+ if (rc != -1) {
+ swrap_remove_stale(sv[0]);
+ swrap_remove_stale(sv[1]);
+ }
+
+ return rc;
+}
+
+int socketpair(int family, int type, int protocol, int sv[2])
+{
+ return swrap_socketpair(family, type, protocol, sv);
+}
+
+/****************************************************************************
+ * SOCKETPAIR
+ ***************************************************************************/
+
+#ifdef HAVE_TIMERFD_CREATE
+static int swrap_timerfd_create(int clockid, int flags)
+{
+ int fd;
+
+ fd = libc_timerfd_create(clockid, flags);
+ if (fd != -1) {
+ swrap_remove_stale(fd);
+ }
+
+ return fd;
+}
+
+int timerfd_create(int clockid, int flags)
+{
+ return swrap_timerfd_create(clockid, flags);
+}
+#endif
+
+/****************************************************************************
+ * PIPE
+ ***************************************************************************/
+
+static int swrap_pipe(int pipefd[2])
+{
+ int rc;
+
+ rc = libc_pipe(pipefd);
+ if (rc != -1) {
+ swrap_remove_stale(pipefd[0]);
+ swrap_remove_stale(pipefd[1]);
+ }
+
+ return rc;
+}
+
+int pipe(int pipefd[2])
+{
+ return swrap_pipe(pipefd);
+}
+
+/****************************************************************************
* ACCEPT
***************************************************************************/
@@ -2072,6 +2260,10 @@ static int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
ret = libc_accept(s, (struct sockaddr *)(void *)&un_addr, &un_addrlen);
if (ret == -1) {
+ if (errno == ENOTSOCK) {
+ /* Remove stale fds */
+ swrap_remove_stale(s);
+ }
free(my_addr);
return ret;
}
@@ -2435,6 +2627,38 @@ int listen(int s, int backlog)
}
/****************************************************************************
+ * OPEN
+ ***************************************************************************/
+
+static int swrap_open(const char *pathname, int flags, mode_t mode)
+{
+ int ret;
+
+ ret = libc_open(pathname, flags, mode);
+ if (ret != -1) {
+ /*
+ * There are methods for closing descriptors (libc-internal code
+ * paths, direct syscalls) which close descriptors in ways that
+ * we can't intercept, so try to recover when we notice that
+ * that's happened
+ */
+ swrap_remove_stale(ret);
+ }
+ return ret;
+}
+
+int open(const char *pathname, int flags, ...)
+{
+ mode_t mode;
+ va_list ap;
+
+ va_start(ap, flags);
+ mode = va_arg(ap, mode_t);
+ va_end(ap);
+ return swrap_open(pathname, flags, mode);
+}
+
+/****************************************************************************
* GETPEERNAME
***************************************************************************/
@@ -2711,7 +2935,15 @@ static ssize_t swrap_sendmsg_before(int fd,
if (si->bound == 0) {
ret = swrap_auto_bind(fd, si, si->family);
- if (ret == -1) return -1;
+ if (ret == -1) {
+ if (errno == ENOTSOCK) {
+ swrap_remove_stale(fd);
+ return -ENOTSOCK;
+ } else {
+ SWRAP_LOG(SWRAP_LOG_ERROR, "swrap_sendmsg_before failed");
+ return -1;
+ }
+ }
}
if (!si->defer_connect) {
@@ -2745,7 +2977,8 @@ static ssize_t swrap_sendmsg_before(int fd,
return 0;
}
-static void swrap_sendmsg_after(struct socket_info *si,
+static void swrap_sendmsg_after(int fd,
+ struct socket_info *si,
struct msghdr *msg,
const struct sockaddr *to,
ssize_t ret)
@@ -2758,8 +2991,13 @@ static void swrap_sendmsg_after(struct socket_info *si,
size_t remain;
/* to give better errors */
- if (ret == -1 && saved_errno == ENOENT) {
- saved_errno = EHOSTUNREACH;
+ if (ret == -1) {
+ if (saved_errno == ENOENT) {
+ saved_errno = EHOSTUNREACH;
+ } else if (saved_errno == ENOTSOCK) {
+ /* If the fd is not a socket, remove it */
+ swrap_remove_stale(fd);
+ }
}
for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
@@ -2867,7 +3105,20 @@ static int swrap_recvmsg_before(int fd,
if (si->bound == 0) {
ret = swrap_auto_bind(fd, si, si->family);
if (ret == -1) {
- return -1;
+ /*
+ * When attempting to read or write to a
+ * descriptor, if an underlying autobind fails
+ * because it's not a socket, stop intercepting
+ * uses of that descriptor.
+ */
+ if (errno == ENOTSOCK) {
+ swrap_remove_stale(fd);
+ return -ENOTSOCK;
+ } else {
+ SWRAP_LOG(SWRAP_LOG_ERROR,
+ "swrap_recvmsg_before failed");
+ return -1;
+ }
}
}
break;
@@ -2879,7 +3130,8 @@ static int swrap_recvmsg_before(int fd,
return 0;
}
-static int swrap_recvmsg_after(struct socket_info *si,
+static int swrap_recvmsg_after(int fd,
+ struct socket_info *si,
struct msghdr *msg,
const struct sockaddr_un *un_addr,
socklen_t un_addrlen,
@@ -2893,8 +3145,13 @@ static int swrap_recvmsg_after(struct socket_info *si,
size_t remain;
/* to give better errors */
- if (ret == -1 && saved_errno == ENOENT) {
- saved_errno = EHOSTUNREACH;
+ if (ret == -1) {
+ if (saved_errno == ENOENT) {
+ saved_errno = EHOSTUNREACH;
+ } else if (saved_errno == ENOTSOCK) {
+ /* If the fd is not a socket, remove it */
+ swrap_remove_stale(fd);
+ }
}
--
Socket Wrapper Repository
More information about the samba-cvs
mailing list