mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
If we are using select, make sure we stay within FD_SETSIZE.
svn:r3051
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user