If we are using select, make sure we stay within FD_SETSIZE.

svn:r3051
This commit is contained in:
Nick Mathewson
2004-12-01 03:15:59 +00:00
parent bde1d5bfb2
commit 6e88abf418
4 changed files with 58 additions and 9 deletions
+13
View File
@@ -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);
+1 -5
View File
@@ -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
+24 -1
View File
@@ -44,7 +44,30 @@ struct pollfd {
#define POLLNVAL 0x0020
#endif
#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
+20 -3
View File
@@ -363,6 +363,10 @@ static int connection_create_listener(const char *bindaddress, uint16_t bindport
if (s < 0) {
log_fn(LOG_WARN,"Socket creation failed.");
return -1;
} else if (!SOCKET_IS_POLLABLE(s)) {
log_fn(LOG_WARN,"Too many connections; can't create pollable listener.");
tor_close_socket(s);
return -1;
}
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*) &one, sizeof(one));
@@ -410,8 +414,16 @@ static int connection_handle_listener_read(connection_t *conn, int new_type) {
int remotelen = sizeof(struct sockaddr_in);
news = accept(conn->s,(struct sockaddr *)&remote,&remotelen);
if (news == -1) { /* accept() error */
int e = tor_socket_errno(conn->s);
if (!SOCKET_IS_POLLABLE(news)) {
/* accept() error, or two many conns to poll */
int e;
if (news>=0) {
/* Too many conns to poll. */
log_fn(LOG_WARN,"Too many connections; couldn't accept connection.");
tor_close_socket(news);
return 0;
}
e = tor_socket_errno(conn->s);
if (ERRNO_IS_ACCEPT_EAGAIN(e)) {
return 0; /* he hung up before we could accept(). that's fine. */
} else if (ERRNO_IS_ACCEPT_RESOURCE_LIMIT(e)) {
@@ -505,11 +517,16 @@ int connection_connect(connection_t *conn, char *address, uint32_t addr, uint16_
struct sockaddr_in dest_addr;
or_options_t *options = get_options();
s=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
s = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
if (s < 0) {
log_fn(LOG_WARN,"Error creating network socket: %s",
tor_socket_strerror(tor_socket_errno(-1)));
return -1;
} else if (!SOCKET_IS_POLLABLE(s)) {
log_fn(LOG_WARN,
"Too many connections; can't create pollable connection to %s", address);
tor_close_socket(s);
return -1;
}
if (options->OutboundBindAddress) {