summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2004-12-01 03:15:59 +0000
committerNick Mathewson <nickm@torproject.org>2004-12-01 03:15:59 +0000
commit6e88abf418684ccaf4a1d7146b0129857a3864fe (patch)
tree40fe96c95f262f00fdf714759553f42eb45429eb /src/common
parentbde1d5bfb2a6c1c39d51ff807e2d13ce6e8a30ce (diff)
downloadtor-6e88abf418684ccaf4a1d7146b0129857a3864fe.tar.gz
tor-6e88abf418684ccaf4a1d7146b0129857a3864fe.zip
If we are using select, make sure we stay within FD_SETSIZE.
svn:r3051
Diffstat (limited to 'src/common')
-rw-r--r--src/common/compat.c13
-rw-r--r--src/common/fakepoll.c6
-rw-r--r--src/common/fakepoll.h25
3 files changed, 38 insertions, 6 deletions
diff --git a/src/common/compat.c b/src/common/compat.c
index 528f0beed0..16e1bee4b6 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -241,6 +241,11 @@ tor_socketpair(int family, int type, int protocol, int fd[2])
listener = socket(AF_INET, type, 0);
if (listener == -1)
return -1;
+ if (!SOCKET_IS_POLLABLE(listener)) {
+ log_fn(LOG_WARN, "Too many connections; can't open socketpair");
+ tor_close_socket(listener);
+ return -1;
+ }
memset(&listen_addr, 0, sizeof(listen_addr));
listen_addr.sin_family = AF_INET;
listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
@@ -254,6 +259,10 @@ tor_socketpair(int family, int type, int protocol, int fd[2])
connector = socket(AF_INET, type, 0);
if (connector == -1)
goto tidy_up_and_fail;
+ if (!SOCKET_IS_POLLABLE(connector)) {
+ log_fn(LOG_WARN, "Too many connections; can't open socketpair");
+ 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)
@@ -268,6 +277,10 @@ tor_socketpair(int family, int type, int protocol, int fd[2])
acceptor = accept(listener, (struct sockaddr *) &listen_addr, &size);
if (acceptor == -1)
goto tidy_up_and_fail;
+ if (!SOCKET_IS_POLLABLE(acceptor)) {
+ log_fn(LOG_WARN, "Too many connections; can't open socketpair");
+ goto tidy_up_and_fail;
+ }
if (size != sizeof(listen_addr))
goto abort_tidy_up_and_fail;
tor_close_socket(listener);
diff --git a/src/common/fakepoll.c b/src/common/fakepoll.c
index 712f2bd365..02be8c9d8f 100644
--- a/src/common/fakepoll.c
+++ b/src/common/fakepoll.c
@@ -12,9 +12,6 @@ const char fakepoll_c_id[] = "$Id$";
#include "orconfig.h"
#include "fakepoll.h"
-#define MAXCONNECTIONS 10000 /* XXXX copied from or.h */
-#define FD_SETSIZE MAXCONNECTIONS
-
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
@@ -44,7 +41,6 @@ tor_poll(struct pollfd *ufds, unsigned int nfds, int timeout)
return poll(ufds,nfds,timeout);
}
#else
-
int
tor_poll(struct pollfd *ufds, unsigned int nfds, int timeout)
{
@@ -71,7 +67,7 @@ tor_poll(struct pollfd *ufds, unsigned int nfds, int timeout)
for (idx = 0; idx < nfds; ++idx) {
ufds[idx].revents = 0;
fd = ufds[idx].fd;
- tor_assert(fd >= 0);
+ tor_assert(SOCKET_SEEMS_POLLABLE(fd));
if (fd > maxfd) {
maxfd = fd;
#ifdef MS_WINDOWS
diff --git a/src/common/fakepoll.h b/src/common/fakepoll.h
index 44fc63d858..3f3d1610bb 100644
--- a/src/common/fakepoll.h
+++ b/src/common/fakepoll.h
@@ -44,7 +44,30 @@ struct pollfd {
#define POLLNVAL 0x0020
#endif
-int tor_poll(struct pollfd *ufds, unsigned int nfds, int timeout);
+#ifdef MS_WINDOWS
+#define MAXCONNECTIONS 10000 /* XXXX copied from or.h */
+/* This trick makes winsock resize fd_set, which defaults to the insanely low
+ * 64. */
+#define FD_SETSIZE MAXCONNECTIONS
+/* XXXX But Windows FD_SET and FD_CLR are tremendously ugly, and linear in
+ * the total number of sockets set! Perhaps we should eventually use
+ * WSAEventSelect and WSAWaitForMultipleEvents instead of select? */
+#endif
+#if defined(MS_WINDOWS) || ! defined(USE_FAKE_POLL)
+/* If we're using poll, we can poll as many sockets as we want.
+ * If we're on Windows, having too many sockets is harmless, since
+ * select stupidly uses an array of sockets rather than a bitfield. */
+#define SOCKET_IS_POLLABLE(fd) ((fd) >= 0)
+#else
+/* If we're using a real Posix select, then in order to be pollable, a socket
+ * must
+ * a) be valid (>= 0)
+ * b) be < FD_SETSIZE.
+ */
+#define SOCKET_IS_POLLABLE(fd) ((fd) >= 0 && (fd) < FD_SETSIZE)
#endif
+int tor_poll(struct pollfd *ufds, unsigned int nfds, int timeout);
+
+#endif