[or-cvs] Adopt socketpair implementation from perl. For now, always ...
Nick Mathewson
nickm at seul.org
Tue Aug 12 07:43:17 UTC 2003
Update of /home/or/cvsroot/src/common
In directory moria.mit.edu:/tmp/cvs-serv4331/src/common
Modified Files:
util.c util.h
Log Message:
Adopt socketpair implementation from perl. For now, always use it.
Index: util.c
===================================================================
RCS file: /home/or/cvsroot/src/common/util.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- util.c 12 Aug 2003 07:01:20 -0000 1.10
+++ util.c 12 Aug 2003 07:43:15 -0000 1.11
@@ -18,6 +18,15 @@
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
@@ -25,6 +34,8 @@
#include <unistd.h>
#endif
#include <assert.h>
+#include <errno.h>
+#include <string.h>
#include "util.h"
#include "log.h"
@@ -145,5 +156,98 @@
_endthread();
#else
exit(0);
+#endif
+}
+
+
+/* Fake socket pair over TCP. Code adapted from perl 5.8.0's util.c */
+int
+tor_socketpair(int family, int type, int protocol, int fd[2])
+{
+#ifdef HAVE_SOCKETPAIR_XXX
+ /* For testing purposes, we never fall back to real socketpairs. */
+ return socketpair(family, type, protocol, fd);
+#else
+ int listener = -1;
+ int connector = -1;
+ int acceptor = -1;
+ struct sockaddr_in listen_addr;
+ struct sockaddr_in connect_addr;
+ size_t size;
+
+ if (protocol
+#ifdef AF_UNIX
+ || family != AF_UNIX
+#endif
+ ) {
+ errno = EAFNOSUPPORT;
+ return -1;
+ }
+ if (!fd) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ listener = socket(AF_INET, type, 0);
+ if (listener == -1)
+ return -1;
+ memset (&listen_addr, 0, sizeof (listen_addr));
+ listen_addr.sin_family = AF_INET;
+ listen_addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+ listen_addr.sin_port = 0; /* kernel choses port. */
+ if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr))
+ == -1)
+ goto tidy_up_and_fail;
+ if (listen(listener, 1) == -1)
+ goto tidy_up_and_fail;
+
+ connector = socket(AF_INET, type, 0);
+ if (connector == -1)
+ goto tidy_up_and_fail;
+ /* We want to find out the port number to connect to. */
+ size = sizeof (connect_addr);
+ if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1)
+ goto tidy_up_and_fail;
+ if (size != sizeof (connect_addr))
+ goto abort_tidy_up_and_fail;
+ if (connect(connector, (struct sockaddr *) &connect_addr,
+ sizeof (connect_addr)) == -1)
+ goto tidy_up_and_fail;
+
+ size = sizeof (listen_addr);
+ acceptor = accept(listener, (struct sockaddr *) &listen_addr, &size);
+ if (acceptor == -1)
+ goto tidy_up_and_fail;
+ if (size != sizeof(listen_addr))
+ goto abort_tidy_up_and_fail;
+ close(listener);
+ /* Now check we are talking to ourself by matching port and host on the
+ two sockets. */
+ if (getsockname(connector, (struct sockaddr *) &connect_addr, &size) == -1)
+ goto tidy_up_and_fail;
+ if (size != sizeof (connect_addr)
+ || listen_addr.sin_family != connect_addr.sin_family
+ || listen_addr.sin_addr.s_addr != connect_addr.sin_addr.s_addr
+ || listen_addr.sin_port != connect_addr.sin_port) {
+ goto abort_tidy_up_and_fail;
+ }
+ fd[0] = connector;
+ fd[1] = acceptor;
+ return 0;
+
+ abort_tidy_up_and_fail:
+ errno = ECONNABORTED; /* I hope this is portable and appropriate. */
+ tidy_up_and_fail:
+ {
+ int save_errno = errno;
+ if (listener != -1)
+ close(listener);
+ if (connector != -1)
+ close(connector);
+ if (acceptor != -1)
+ close(acceptor);
+ errno = save_errno;
+ return -1;
+ }
#endif
}
Index: util.h
===================================================================
RCS file: /home/or/cvsroot/src/common/util.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- util.h 12 Aug 2003 07:01:20 -0000 1.5
+++ util.h 12 Aug 2003 07:43:15 -0000 1.6
@@ -52,4 +52,6 @@
int spawn_func(int (*func)(void *), void *data);
void spawn_exit();
+int tor_socketpair(int family, int type, int protocol, int fd[2]);
+
#endif
More information about the tor-commits
mailing list