[tor-commits] [orbot/master] add linancillary for badvpn tun2socks update for DNS

n8fr8 at torproject.org n8fr8 at torproject.org
Mon Jan 4 06:45:32 UTC 2016


commit 699b60db566aeba8f6265e7d474f2686d5ca5b83
Author: Nathan Freitas <nathan at freitas.net>
Date:   Wed Dec 30 09:52:56 2015 -0500

    add linancillary for badvpn tun2socks update for DNS
---
 jni/libancillary/API         |  139 ++++++++++++++++++++++++++++++++++++++++++
 jni/libancillary/COPYING     |   21 +++++++
 jni/libancillary/Makefile    |   73 ++++++++++++++++++++++
 jni/libancillary/ancillary.h |  131 +++++++++++++++++++++++++++++++++++++++
 jni/libancillary/fd_recv.c   |   98 +++++++++++++++++++++++++++++
 jni/libancillary/fd_send.c   |   92 ++++++++++++++++++++++++++++
 jni/libancillary/test.c      |  112 ++++++++++++++++++++++++++++++++++
 7 files changed, 666 insertions(+)

diff --git a/jni/libancillary/API b/jni/libancillary/API
new file mode 100644
index 0000000..b558995
--- /dev/null
+++ b/jni/libancillary/API
@@ -0,0 +1,139 @@
+  This library provide an easy interface to the black magic that can be done
+  on Unix domain sockets, like passing file descriptors from one process to
+  another.
+
+  Programs that uses this library should include the ancillary.h header file.
+  Nothing else is required.
+
+  All functions of this library require the following header:
+
+	#include <ancillary.h>
+
+  At this time, the only ancillary data defined by the Single Unix
+  Specification (v3) is file descriptors.
+
+Passing file descriptors
+
+	int ancil_send_fd(socket, file_descriptor)
+	  int socket: the Unix socket
+	  int file_descriptor: the file descriptor
+	  Return value: 0 for success, -1 for failure.
+
+  Sends one file descriptor on a socket.
+  In case of failure, errno is set; the possible values are the ones of the
+  sendmsg(2) system call.
+
+
+	int ancil_recv_fd(socket, file_descriptor)
+	  int socket: the Unix socket
+	  int *file_descriptor: pointer to the returned file descriptor
+	  Return value: 0 for success, -1 for failure
+
+  Receives one file descriptor from a socket.
+  In case of success, the file descriptor is stored in the integer pointed
+  to by file_descriptor.
+  In case of failure, errno is set; the possible values are the ones of the
+  recvmsg(2) system call.
+  The behavior is undefined if the recv_fd does not match a send_fd* on the
+  other side.
+
+
+	int ancil_send_fds(socket, file_descriptors, num_file_descriptors)
+	  int socket: the Unix socket
+	  const int *file_descriptors: array of file descriptors
+	  unsigned num_file_descriptors: number of file descriptors
+	  Return value: 0 for success, -1 for failure
+
+  Sends several file descriptors on a socket.
+  In case of failure, errno is set; the possible values are the ones of the
+  sendmsg(2) system call.
+  The maximum number of file descriptors that can be sent using this
+  function is ANCIL_MAX_N_FDS; the behavior is undefined in case of
+  overflow, probably a stack corruption.
+
+
+	int ancil_recv_fds(socket, file_descriptors, num_file_descriptors)
+	  int socket: the Unix socket
+	  int *file_descriptors: return array of file descriptors
+	  unsigned num_file_descriptors: number of file descriptors
+	  Return value: number of received fd for success, -1 for failure
+
+  Receives several file descriptors from a socket, no more than
+  num_file_descriptors.
+  In case of success, the received file descriptors are stored in the array
+  pointed to by file_descriptors.
+  In case of failure, errno is set; the possible values are the ones of the
+  recvmsg(2) system call.
+  The maximum number of file descriptors that can be received using this
+  function is ANCIL_MAX_N_FDS; the behavior is undefined in case of
+  overflow, probably a stack corruption.
+  The behavior is undefined if the recv_fds does not match a send_fd* on
+  the other side, or if the number of received file descriptors is more than
+  num_file_descriptors.
+
+
+	int ancil_send_fds_with_buffer(socket, fds, num, buffer)
+	  int socket: the Unix socket
+	  const int *fds: array of file descriptors
+	  unsigned num: number of file descriptors
+	  void *buffer: buffer to hold the system data structures
+	  Return value: 0 for success, -1 for failure
+
+  Sends several file descriptors on a socket.
+  In case of failure, errno is set; the possible values are the ones of the
+  sendmsg(2) system call.
+  The buffer argument must point to a memory area large enough to hold the
+  system data structures, see ANCIL_FD_BUFFER.
+
+
+	int ancil_send_fds_with_buffer(socket, fds, num, buffer)
+	  int socket: the Unix socket
+	  int *fds: return array of file descriptors
+	  unsigned num: number of file descriptors
+	  void *buffer: buffer to hold the system data structures
+	  Return value: number of received fd for success, -1 for failure
+
+  Receives several file descriptors from a socket, no more than
+  num_file_descriptors.
+  In case of success, the received file descriptors are stored in the array
+  pointed to by file_descriptors.
+  In case of failure, errno is set; the possible values are the ones of the
+  recvmsg(2) system call.
+  The behavior is undefined if the recv_fds does not match a send_fd* on
+  the other side, or if the number of received file descriptors is more than
+  num_file_descriptors.
+  The buffer argument must point to a memory area large enough to hold the
+  system data structures, see ANCIL_FD_BUFFER.
+
+
+	ANCIL_MAX_N_FDS
+
+  Maximum number of file descriptors that can be sent with the sent_fds and
+  recv_fds functions. If you have to send more at once, use the
+  *_with_buffer versions. The value is enough to send "quite a few" file
+  descriptors.
+
+
+	ANCIL_FD_BUFFER(n)
+	  int n: number of file descriptors
+
+  Expands to a structure data type large enough to hold the system data
+  structures for n file descriptors. So the address of a variable declared
+  of type ANCIL_FD_BUFFER(n) is suitable as the buffer argument for
+  *_with_buffer on n file descriptors.
+  To use this macro, you need <sys/types.h> and <sys/socket.h>. Bevare: with
+  Solaris, the _XPG4_2 macro must be defined before sys/socket is included.
+
+
+Tuning the compilation
+
+  This library is designed to be included in projects, not installed in
+  /usr/lib. If your project does not use some of the functions, the
+  TUNE_OPTS variable in the Makefile allows not to build them. It is a list
+  of proprocessor options:
+
+  -DNDEBUG: turn assertions off (see assert(3))
+  -DSPARE_SEND_FDS: do not build ancil_send_fds
+  -DSPARE_SEND_FD:  do not build ancil_send_fd
+  -DSPARE_RECV_FDS: do not build ancil_recv_fds
+  -DSPARE_RECV_FD:  do not build ancil_recv_fd
diff --git a/jni/libancillary/COPYING b/jni/libancillary/COPYING
new file mode 100644
index 0000000..5bcd9c2
--- /dev/null
+++ b/jni/libancillary/COPYING
@@ -0,0 +1,21 @@
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/jni/libancillary/Makefile b/jni/libancillary/Makefile
new file mode 100644
index 0000000..3d32533
--- /dev/null
+++ b/jni/libancillary/Makefile
@@ -0,0 +1,73 @@
+###########################################################################
+# libancillary - black magic on Unix domain sockets
+# (C) Nicolas George
+# Makefile - guess what
+###########################################################################
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# 
+#  1. Redistributions of source code must retain the above copyright notice,
+#     this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#  3. The name of the author may not be used to endorse or promote products
+#     derived from this software without specific prior written permission.
+# 
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+CC=gcc
+CFLAGS=-Wall -g -O2
+LDFLAGS=
+LIBS=
+AR=ar
+RANLIB=ranlib
+RM=rm
+CP=cp
+MKDIR=mkdir
+TAR=tar
+GZIP=gzip -9
+
+NAME=libancillary
+DISTRIBUTION=API COPYING Makefile ancillary.h fd_send.c fd_recv.c test.c
+VERSION=0.9.1
+
+OBJECTS=fd_send.o fd_recv.o
+
+TUNE_OPTS=-DNDEBUG
+#TUNE_OPTS=-DNDEBUG \
+	-DSPARE_SEND_FDS -DSPARE_SEND_FD -DSPARE_RECV_FDS -DSPARE_RECV_FD
+
+.c.o:
+	$(CC) -c $(CFLAGS) $(TUNE_OPTS) $<
+
+all: libancillary.a
+
+libancillary.a: $(OBJECTS)
+	$(AR) cr $@ $(OBJECTS)
+	$(RANLIB) $@
+
+fd_send.o: ancillary.h
+fd_recv.o: ancillary.h
+
+test: test.c libancillary.a
+	$(CC) -o $@ $(CFLAGS) $(LDFLAGS) -L. test.c -lancillary $(LIBS)
+
+clean:
+	-$(RM) -f *.o *.a test 
+
+dist:
+	$(MKDIR) $(NAME)-$(VERSION)
+	$(CP) $(DISTRIBUTION) $(NAME)-$(VERSION)
+	$(TAR) -cf - $(NAME)-$(VERSION) | $(GZIP) > $(NAME)-$(VERSION).tar.gz
+	$(RM) -rf $(NAME)-$(VERSION)
diff --git a/jni/libancillary/ancillary.h b/jni/libancillary/ancillary.h
new file mode 100644
index 0000000..636d867
--- /dev/null
+++ b/jni/libancillary/ancillary.h
@@ -0,0 +1,131 @@
+/***************************************************************************
+ * libancillary - black magic on Unix domain sockets
+ * (C) Nicolas George
+ * ancillary.c - public header
+ ***************************************************************************/
+
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ *  1. Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. The name of the author may not be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ANCILLARY_H__
+#define ANCILLARY_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************************************************************
+ * Start of the readable part.
+ ***************************************************************************/
+
+#define ANCIL_MAX_N_FDS 960
+/*
+ * Maximum number of fds that can be sent or received using the "esay"
+ * functions; this is so that all can fit in one page.
+ */
+
+extern int
+ancil_send_fds_with_buffer(int, const int *, unsigned, void *);
+/*
+ * ancil_send_fds_with_buffer(sock, n_fds, fds, buffer)
+ *
+ * Sends the file descriptors in the array pointed by fds, of length n_fds
+ * on the socket sock.
+ * buffer is a writeable memory area large enough to hold the required data
+ * structures.
+ * Returns: -1 and errno in case of error, 0 in case of success.
+ */
+
+extern int
+ancil_recv_fds_with_buffer(int, int *, unsigned, void *);
+/*
+ * ancil_recv_fds_with_buffer(sock, n_fds, fds, buffer)
+ *
+ * Receives *n_fds file descriptors into the array pointed by fds
+ * from the socket sock.
+ * buffer is a writeable memory area large enough to hold the required data
+ * structures.
+ * Returns: -1 and errno in case of error, the actual number of received fd
+ * in case of success
+ */
+
+#define ANCIL_FD_BUFFER(n) \
+    struct { \
+	struct cmsghdr h; \
+	int fd[n]; \
+    }
+/* ANCIL_FD_BUFFER(n)
+ *
+ * A structure type suitable to be used as buffer for n file descriptors.
+ * Requires <sys/socket.h>.
+ * Example:
+ * ANCIL_FD_BUFFER(42) buffer;
+ * ancil_recv_fds_with_buffer(sock, 42, my_fds, &buffer);
+ */
+
+extern int
+ancil_send_fds(int, const int *, unsigned);
+/*
+ * ancil_send_fds(sock, n_fds, fds)
+ *
+ * Sends the file descriptors in the array pointed by fds, of length n_fds
+ * on the socket sock.
+ * n_fds must not be greater than ANCIL_MAX_N_FDS.
+ * Returns: -1 and errno in case of error, 0 in case of success.
+ */
+
+extern int
+ancil_recv_fds(int, int *, unsigned);
+/*
+ * ancil_recv_fds(sock, n_fds, fds)
+ *
+ * Receives *n_fds file descriptors into the array pointed by fds
+ * from the socket sock.
+ * *n_fds must not be greater than ANCIL_MAX_N_FDS.
+ * Returns: -1 and errno in case of error, the actual number of received fd
+ * in case of success.
+ */
+
+
+extern int
+ancil_send_fd(int, int);
+/* ancil_recv_fd(sock, fd);
+ *
+ * Sends the file descriptor fd on the socket sock.
+ * Returns : -1 and errno in case of error, 0 in case of success.
+ */
+
+extern int
+ancil_recv_fd(int, int *);
+/* ancil_send_fd(sock, &fd);
+ *
+ * Receives the file descriptor fd from the socket sock.
+ * Returns : -1 and errno in case of error, 0 in case of success.
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ANCILLARY_H__ */
diff --git a/jni/libancillary/fd_recv.c b/jni/libancillary/fd_recv.c
new file mode 100644
index 0000000..46c2e69
--- /dev/null
+++ b/jni/libancillary/fd_recv.c
@@ -0,0 +1,98 @@
+/***************************************************************************
+ * libancillary - black magic on Unix domain sockets
+ * (C) Nicolas George
+ * fd_send.c - receiving file descriptors
+ ***************************************************************************/
+
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ *  1. Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. The name of the author may not be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _XPG4_2 /* Solaris sucks */
+# define _XPG4_2
+#endif
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <assert.h>
+#if defined(__FreeBSD__)
+# include <sys/param.h> /* FreeBSD sucks */
+#endif
+
+#include "ancillary.h"
+
+int
+ancil_recv_fds_with_buffer(int sock, int *fds, unsigned n_fds, void *buffer)
+{
+    struct msghdr msghdr;
+    char nothing;
+    struct iovec nothing_ptr;
+    struct cmsghdr *cmsg;
+    int i;
+
+    nothing_ptr.iov_base = ¬hing;
+    nothing_ptr.iov_len = 1;
+    msghdr.msg_name = NULL;
+    msghdr.msg_namelen = 0;
+    msghdr.msg_iov = &nothing_ptr;
+    msghdr.msg_iovlen = 1;
+    msghdr.msg_flags = 0;
+    msghdr.msg_control = buffer;
+    msghdr.msg_controllen = sizeof(struct cmsghdr) + sizeof(int) * n_fds;
+    cmsg = CMSG_FIRSTHDR(&msghdr);
+    cmsg->cmsg_len = msghdr.msg_controllen;
+    cmsg->cmsg_level = SOL_SOCKET;
+    cmsg->cmsg_type = SCM_RIGHTS;
+    for(i = 0; i < n_fds; i++)
+	((int *)CMSG_DATA(cmsg))[i] = -1;
+    
+    if(recvmsg(sock, &msghdr, 0) < 0)
+	return(-1);
+    for(i = 0; i < n_fds; i++)
+	fds[i] = ((int *)CMSG_DATA(cmsg))[i];
+    n_fds = (msghdr.msg_controllen - sizeof(struct cmsghdr)) / sizeof(int);
+    return(n_fds);
+}
+
+#ifndef SPARE_RECV_FDS
+int
+ancil_recv_fds(int sock, int *fd, unsigned n_fds)
+{
+    ANCIL_FD_BUFFER(ANCIL_MAX_N_FDS) buffer;
+
+    assert(n_fds <= ANCIL_MAX_N_FDS);
+    return(ancil_recv_fds_with_buffer(sock, fd, n_fds, &buffer));
+}
+#endif /* SPARE_RECV_FDS */
+
+#ifndef SPARE_RECV_FD
+int
+ancil_recv_fd(int sock, int *fd)
+{
+    ANCIL_FD_BUFFER(1) buffer;
+
+    return(ancil_recv_fds_with_buffer(sock, fd, 1, &buffer) == 1 ? 0 : -1);
+}
+#endif /* SPARE_RECV_FD */
diff --git a/jni/libancillary/fd_send.c b/jni/libancillary/fd_send.c
new file mode 100644
index 0000000..01de87f
--- /dev/null
+++ b/jni/libancillary/fd_send.c
@@ -0,0 +1,92 @@
+/***************************************************************************
+ * libancillary - black magic on Unix domain sockets
+ * (C) Nicolas George
+ * fd_send.c - sending file descriptors
+ ***************************************************************************/
+
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ *  1. Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. The name of the author may not be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _XPG4_2 /* Solaris sucks */
+# define _XPG4_2
+#endif
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <assert.h>
+#if defined(__FreeBSD__)
+# include <sys/param.h> /* FreeBSD sucks */
+#endif
+
+#include "ancillary.h"
+
+int
+ancil_send_fds_with_buffer(int sock, const int *fds, unsigned n_fds, void *buffer)
+{
+    struct msghdr msghdr;
+    char nothing = '!';
+    struct iovec nothing_ptr;
+    struct cmsghdr *cmsg;
+    int i;
+
+    nothing_ptr.iov_base = ¬hing;
+    nothing_ptr.iov_len = 1;
+    msghdr.msg_name = NULL;
+    msghdr.msg_namelen = 0;
+    msghdr.msg_iov = &nothing_ptr;
+    msghdr.msg_iovlen = 1;
+    msghdr.msg_flags = 0;
+    msghdr.msg_control = buffer;
+    msghdr.msg_controllen = sizeof(struct cmsghdr) + sizeof(int) * n_fds;
+    cmsg = CMSG_FIRSTHDR(&msghdr);
+    cmsg->cmsg_len = msghdr.msg_controllen;
+    cmsg->cmsg_level = SOL_SOCKET;
+    cmsg->cmsg_type = SCM_RIGHTS;
+    for(i = 0; i < n_fds; i++)
+	((int *)CMSG_DATA(cmsg))[i] = fds[i];
+    return(sendmsg(sock, &msghdr, 0) >= 0 ? 0 : -1);
+}
+
+#ifndef SPARE_SEND_FDS
+int
+ancil_send_fds(int sock, const int *fds, unsigned n_fds)
+{
+    ANCIL_FD_BUFFER(ANCIL_MAX_N_FDS) buffer;
+
+    assert(n_fds <= ANCIL_MAX_N_FDS);
+    return(ancil_send_fds_with_buffer(sock, fds, n_fds, &buffer));
+}
+#endif /* SPARE_SEND_FDS */
+
+#ifndef SPARE_SEND_FD
+int
+ancil_send_fd(int sock, int fd)
+{
+    ANCIL_FD_BUFFER(1) buffer;
+
+    return(ancil_send_fds_with_buffer(sock, &fd, 1, &buffer));
+}
+#endif /* SPARE_SEND_FD */
diff --git a/jni/libancillary/test.c b/jni/libancillary/test.c
new file mode 100644
index 0000000..d3c1fda
--- /dev/null
+++ b/jni/libancillary/test.c
@@ -0,0 +1,112 @@
+/***************************************************************************
+ * libancillary - black magic on Unix domain sockets
+ * (C) Nicolas George
+ * test.c - testing and example program
+ ***************************************************************************/
+
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ *  1. Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. The name of the author may not be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include "ancillary.h"
+
+void child_process(int sock)
+{
+    int fd;
+    int fds[3], nfds;
+    char b[] = "This is on the received fd!\n";
+
+    if(ancil_recv_fd(sock, &fd)) {
+	perror("ancil_recv_fd");
+	exit(1);
+    } else {
+	printf("Received fd: %d\n", fd);
+    }
+    write(fd, b, sizeof(b));
+    close(fd);
+    sleep(2);
+
+    nfds = ancil_recv_fds(sock, fds, 3);
+    if(nfds < 0) {
+	perror("ancil_recv_fds");
+	exit(1);
+    } else {
+	printf("Received %d/3 fds : %d %d %d.\n", nfds,
+	    fds[0], fds[1], fds[2]);
+    }
+}
+
+void parent_process(int sock)
+{
+    int fds[2] = { 1, 2 };
+
+    if(ancil_send_fd(sock, 1)) {
+	perror("ancil_send_fd");
+	exit(1);
+    } else {
+	printf("Sent fd.\n");
+    }
+    sleep(1);
+
+    if(ancil_send_fds(sock, fds, 2)) {
+	perror("ancil_send_fds");
+	exit(1);
+    } else {
+	printf("Sent two fds.\n");
+    }
+}
+
+int main(void)
+{
+    int sock[2];
+
+    if(socketpair(PF_UNIX, SOCK_STREAM, 0, sock)) {
+	perror("socketpair");
+	exit(1);
+    } else {
+	printf("Established socket pair: (%d, %d)\n", sock[0], sock[1]);
+    }
+
+    switch(fork()) {
+	case 0:
+	    close(sock[0]);
+	    child_process(sock[1]);
+	    break;
+	case -1:
+	    perror("fork");
+	    exit(1);
+	default:
+	    close(sock[1]);
+	    parent_process(sock[0]);
+	    wait(NULL);
+	    break;
+    }
+    return(0);
+}





More information about the tor-commits mailing list