summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure1
-rw-r--r--include/modules.h6
-rw-r--r--include/socketengine.h4
-rw-r--r--include/socketengines/socketengine_epoll.h2
-rw-r--r--include/socketengines/socketengine_kqueue.h2
-rw-r--r--include/socketengines/socketengine_ports.h2
-rw-r--r--include/socketengines/socketengine_select.h2
-rw-r--r--src/inspircd.cpp4
-rw-r--r--src/modules/extra/m_ssl_gnutls.cpp18
-rw-r--r--src/modules/extra/m_ssl_openssl.cpp16
-rw-r--r--src/modules/extra/m_ziplink.cpp5
-rw-r--r--src/socketengine.cpp1
-rw-r--r--src/socketengines/socketengine_epoll.cpp35
-rw-r--r--src/socketengines/socketengine_iocp.cpp3
-rw-r--r--src/socketengines/socketengine_kqueue.cpp34
-rw-r--r--src/socketengines/socketengine_ports.cpp34
-rw-r--r--src/socketengines/socketengine_select.cpp15
-rw-r--r--src/usermanager.cpp2
-rw-r--r--src/users.cpp19
19 files changed, 150 insertions, 55 deletions
diff --git a/configure b/configure
index 56a85dac6..b1cbeb494 100755
--- a/configure
+++ b/configure
@@ -1224,7 +1224,6 @@ sub writefiles {
#define MAXCLIENTS $config{MAX_CLIENT}
#define MAXCLIENTS_S "$config{MAX_CLIENT}"
#define SOMAXCONN_S "$config{_SOMAXCONN}"
-#define MAX_DESCRIPTORS $config{MAX_DESCRIPTORS}
#define NICKMAX $NL
#define CHANMAX $CL
#define MAXMODES $config{MAXI_MODES}
diff --git a/include/modules.h b/include/modules.h
index ce6e3fa21..efb9113aa 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -230,13 +230,9 @@ do { \
#define FD_MAGIC_NUMBER -42
/* Useful macros */
-#ifdef WINDOWS
+
/** Is a local user */
#define IS_LOCAL(x) ((x->GetFd() > -1))
-#else
-/** Is a local user */
-#define IS_LOCAL(x) ((x->GetFd() > -1) && (x->GetFd() <= MAX_DESCRIPTORS))
-#endif
/** Is a remote user */
#define IS_REMOTE(x) (x->GetFd() < 0)
/** Is a module created user */
diff --git a/include/socketengine.h b/include/socketengine.h
index 3acc7bd4f..f647f4df3 100644
--- a/include/socketengine.h
+++ b/include/socketengine.h
@@ -167,7 +167,9 @@ protected:
int CurrentSetSize;
/** Reference table, contains all current handlers
*/
- EventHandler* ref[MAX_DESCRIPTORS];
+ EventHandler** ref;
+
+ int MAX_DESCRIPTORS;
public:
double TotalEvents;
diff --git a/include/socketengines/socketengine_epoll.h b/include/socketengines/socketengine_epoll.h
index 87829582a..07d0e3621 100644
--- a/include/socketengines/socketengine_epoll.h
+++ b/include/socketengines/socketengine_epoll.h
@@ -33,7 +33,7 @@ class EPollEngine : public SocketEngine
private:
/** These are used by epoll() to hold socket events
*/
- struct epoll_event events[MAX_DESCRIPTORS];
+ struct epoll_event* events;
public:
/** Create a new EPollEngine
* @param Instance The creator of this object
diff --git a/include/socketengines/socketengine_kqueue.h b/include/socketengines/socketengine_kqueue.h
index 7ef24085a..49b51590a 100644
--- a/include/socketengines/socketengine_kqueue.h
+++ b/include/socketengines/socketengine_kqueue.h
@@ -34,7 +34,7 @@ class KQueueEngine : public SocketEngine
private:
/** These are used by kqueue() to hold socket events
*/
- struct kevent ke_list[MAX_DESCRIPTORS];
+ struct kevent* ke_list;
/** This is a specialised time value used by kqueue()
*/
struct timespec ts;
diff --git a/include/socketengines/socketengine_ports.h b/include/socketengines/socketengine_ports.h
index d055912e5..519eaad8b 100644
--- a/include/socketengines/socketengine_ports.h
+++ b/include/socketengines/socketengine_ports.h
@@ -36,7 +36,7 @@ class PortsEngine : public SocketEngine
private:
/** These are used by epoll() to hold socket events
*/
- port_event_t events[MAX_DESCRIPTORS];
+ port_event_t* events;
public:
/** Create a new PortsEngine
* @param Instance The creator of this object
diff --git a/include/socketengines/socketengine_select.h b/include/socketengines/socketengine_select.h
index 83d92d48f..3540c0944 100644
--- a/include/socketengines/socketengine_select.h
+++ b/include/socketengines/socketengine_select.h
@@ -37,7 +37,7 @@ private:
std::map<int,int> fds;
/** List of writeable ones (WantWrite())
*/
- bool writeable[MAX_DESCRIPTORS];
+ bool* writeable;
/** The read set and write set, populated before each call to select().
*/
fd_set wfdset, rfdset, errfdset;
diff --git a/src/inspircd.cpp b/src/inspircd.cpp
index 1d6986f57..f7f969835 100644
--- a/src/inspircd.cpp
+++ b/src/inspircd.cpp
@@ -581,8 +581,8 @@ InspIRCd::InspIRCd(int argc, char** argv)
}
#endif
- printf("\nInspIRCd is now running as '%s'[%s]\n", Config->ServerName,Config->GetSID().c_str());
- Logs->Log("STARTUP", DEFAULT, "Startup complete as '%s'[%s]", Config->ServerName,Config->GetSID().c_str());
+ printf("\nInspIRCd is now running as '%s'[%s] with %d max open sockets\n", Config->ServerName,Config->GetSID().c_str(), SE->GetMaxFds());
+ Logs->Log("STARTUP", DEFAULT, "Startup complete as '%s'[%s], %d max open sockets", Config->ServerName,Config->GetSID().c_str(), SE->GetMaxFds());
this->WritePID(Config->PID);
}
diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp
index 3f9c4ac5d..797019fd4 100644
--- a/src/modules/extra/m_ssl_gnutls.cpp
+++ b/src/modules/extra/m_ssl_gnutls.cpp
@@ -28,8 +28,6 @@
#ifdef WINDOWS
#pragma comment(lib, "libgnutls-13.lib")
-#undef MAX_DESCRIPTORS
-#define MAX_DESCRIPTORS 10000
#endif
/* $ModDesc: Provides SSL support for clients */
@@ -94,7 +92,7 @@ class ModuleSSLGnuTLS : public Module
std::vector<std::string> listenports;
int inbufsize;
- issl_session sessions[MAX_DESCRIPTORS];
+ issl_session* sessions;
gnutls_certificate_credentials x509_cred;
gnutls_dh_params dh_params;
@@ -117,6 +115,8 @@ class ModuleSSLGnuTLS : public Module
{
ServerInstance->Modules->PublishInterface("BufferedSocketHook", this);
+ sessions = new issl_session[ServerInstance->SE->GetMaxFds()];
+
// Not rehashable...because I cba to reduce all the sizes of existing buffers.
inbufsize = ServerInstance->Config->NetBufferSize;
@@ -270,6 +270,8 @@ class ModuleSSLGnuTLS : public Module
gnutls_dh_params_deinit(dh_params);
gnutls_certificate_free_credentials(x509_cred);
gnutls_global_deinit();
+ ServerInstance->Modules->UnpublishInterface("BufferedSocketHook", this);
+ delete[] sessions;
}
virtual void OnCleanup(int target_type, void* item)
@@ -383,7 +385,7 @@ class ModuleSSLGnuTLS : public Module
virtual void OnRawSocketAccept(int fd, const std::string &ip, int localport)
{
/* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */
- if ((fd < 0) || (fd > MAX_DESCRIPTORS))
+ if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() - 1))
return;
issl_session* session = &sessions[fd];
@@ -416,7 +418,7 @@ class ModuleSSLGnuTLS : public Module
virtual void OnRawSocketConnect(int fd)
{
/* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */
- if ((fd < 0) || (fd > MAX_DESCRIPTORS))
+ if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() - 1))
return;
issl_session* session = &sessions[fd];
@@ -438,7 +440,7 @@ class ModuleSSLGnuTLS : public Module
virtual void OnRawSocketClose(int fd)
{
/* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */
- if ((fd < 0) || (fd > MAX_DESCRIPTORS))
+ if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds()))
return;
CloseSession(&sessions[fd]);
@@ -457,7 +459,7 @@ class ModuleSSLGnuTLS : public Module
virtual int OnRawSocketRead(int fd, char* buffer, unsigned int count, int &readresult)
{
/* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */
- if ((fd < 0) || (fd > MAX_DESCRIPTORS))
+ if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() - 1))
return 0;
issl_session* session = &sessions[fd];
@@ -552,7 +554,7 @@ class ModuleSSLGnuTLS : public Module
virtual int OnRawSocketWrite(int fd, const char* buffer, int count)
{
/* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */
- if ((fd < 0) || (fd > MAX_DESCRIPTORS))
+ if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() - 1))
return 0;
issl_session* session = &sessions[fd];
diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp
index de7101db1..83fa94e96 100644
--- a/src/modules/extra/m_ssl_openssl.cpp
+++ b/src/modules/extra/m_ssl_openssl.cpp
@@ -107,7 +107,7 @@ class ModuleSSLOpenSSL : public Module
std::vector<std::string> listenports;
int inbufsize;
- issl_session sessions[MAX_DESCRIPTORS];
+ issl_session* sessions;
SSL_CTX* ctx;
SSL_CTX* clictx;
@@ -133,6 +133,8 @@ class ModuleSSLOpenSSL : public Module
{
ServerInstance->Modules->PublishInterface("BufferedSocketHook", this);
+ sessions = new issl_session[ServerInstance->SE->GetMaxFds()];
+
// Not rehashable...because I cba to reduce all the sizes of existing buffers.
inbufsize = ServerInstance->Config->NetBufferSize;
@@ -302,6 +304,8 @@ class ModuleSSLOpenSSL : public Module
{
SSL_CTX_free(ctx);
SSL_CTX_free(clictx);
+ ServerInstance->Modules->UnpublishInterface("BufferedSocketHook", this);
+ delete[] sessions;
}
virtual void OnCleanup(int target_type, void* item)
@@ -396,7 +400,7 @@ class ModuleSSLOpenSSL : public Module
virtual void OnRawSocketAccept(int fd, const std::string &ip, int localport)
{
/* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */
- if ((fd < 0) || (fd > MAX_DESCRIPTORS))
+ if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() - 1))
return;
issl_session* session = &sessions[fd];
@@ -423,7 +427,7 @@ class ModuleSSLOpenSSL : public Module
virtual void OnRawSocketConnect(int fd)
{
/* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */
- if ((fd < 0) || (fd > MAX_DESCRIPTORS))
+ if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() -1))
return;
issl_session* session = &sessions[fd];
@@ -450,7 +454,7 @@ class ModuleSSLOpenSSL : public Module
virtual void OnRawSocketClose(int fd)
{
/* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */
- if ((fd < 0) || (fd > MAX_DESCRIPTORS))
+ if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() - 1))
return;
CloseSession(&sessions[fd]);
@@ -469,7 +473,7 @@ class ModuleSSLOpenSSL : public Module
virtual int OnRawSocketRead(int fd, char* buffer, unsigned int count, int &readresult)
{
/* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */
- if ((fd < 0) || (fd > MAX_DESCRIPTORS))
+ if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() - 1))
return 0;
issl_session* session = &sessions[fd];
@@ -546,7 +550,7 @@ class ModuleSSLOpenSSL : public Module
virtual int OnRawSocketWrite(int fd, const char* buffer, int count)
{
/* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */
- if ((fd < 0) || (fd > MAX_DESCRIPTORS))
+ if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() - 1))
return 0;
issl_session* session = &sessions[fd];
diff --git a/src/modules/extra/m_ziplink.cpp b/src/modules/extra/m_ziplink.cpp
index 5202287fa..7b1cb281c 100644
--- a/src/modules/extra/m_ziplink.cpp
+++ b/src/modules/extra/m_ziplink.cpp
@@ -137,7 +137,7 @@ class izip_session : public classbase
class ModuleZLib : public Module
{
- izip_session sessions[MAX_DESCRIPTORS];
+ izip_session* sessions;
/* Used for stats z extensions */
float total_out_compressed;
@@ -152,6 +152,8 @@ class ModuleZLib : public Module
{
ServerInstance->Modules->PublishInterface("BufferedSocketHook", this);
+ sessions = new izip_session[ServerInstance->SE->GetMaxFds()];
+
total_out_compressed = total_in_compressed = 0;
total_out_uncompressed = total_out_uncompressed = 0;
Implementation eventlist[] = { I_OnRawSocketConnect, I_OnRawSocketAccept, I_OnRawSocketClose, I_OnRawSocketRead, I_OnRawSocketWrite, I_OnStats, I_OnRequest };
@@ -161,6 +163,7 @@ class ModuleZLib : public Module
virtual ~ModuleZLib()
{
ServerInstance->Modules->UnpublishInterface("BufferedSocketHook", this);
+ delete[] sessions;
}
virtual Version GetVersion()
diff --git a/src/socketengine.cpp b/src/socketengine.cpp
index a4b6d7d29..d0c181be4 100644
--- a/src/socketengine.cpp
+++ b/src/socketengine.cpp
@@ -61,7 +61,6 @@ void SocketEngine::WantWrite(EventHandler* eh)
SocketEngine::SocketEngine(InspIRCd* Instance) : ServerInstance(Instance)
{
- memset(ref, 0, sizeof(ref));
TotalEvents = WriteEvents = ReadEvents = ErrorEvents = 0;
}
diff --git a/src/socketengines/socketengine_epoll.cpp b/src/socketengines/socketengine_epoll.cpp
index 1a0c5d53e..a749208d1 100644
--- a/src/socketengines/socketengine_epoll.cpp
+++ b/src/socketengines/socketengine_epoll.cpp
@@ -15,10 +15,11 @@
#include "exitcodes.h"
#include <sys/epoll.h>
#include "socketengines/socketengine_epoll.h"
+#include <ulimit.h>
EPollEngine::EPollEngine(InspIRCd* Instance) : SocketEngine(Instance)
{
- EngineHandle = epoll_create(MAX_DESCRIPTORS);
+ EngineHandle = epoll_create(GetMaxFds());
if (EngineHandle == -1)
{
@@ -29,17 +30,24 @@ EPollEngine::EPollEngine(InspIRCd* Instance) : SocketEngine(Instance)
ServerInstance->Exit(EXIT_STATUS_SOCKETENGINE);
}
CurrentSetSize = 0;
+
+ ref = new EventHandler* [GetMaxFds()];
+ events = new struct epoll_event[GetMaxFds()];
+
+ memset(ref, 0, GetMaxFds() * sizeof(EventHandler*));
}
EPollEngine::~EPollEngine()
{
this->Close(EngineHandle);
+ delete[] ref;
+ delete[] events;
}
bool EPollEngine::AddFd(EventHandler* eh)
{
int fd = eh->GetFd();
- if ((fd < 0) || (fd > MAX_DESCRIPTORS))
+ if ((fd < 0) || (fd > GetMaxFds() - 1))
{
ServerInstance->Logs->Log("SOCKET",DEBUG,"Out of range FD");
return false;
@@ -83,7 +91,7 @@ void EPollEngine::WantWrite(EventHandler* eh)
bool EPollEngine::DelFd(EventHandler* eh, bool force)
{
int fd = eh->GetFd();
- if ((fd < 0) || (fd > MAX_DESCRIPTORS))
+ if ((fd < 0) || (fd > GetMaxFds() - 1))
return false;
struct epoll_event ev;
@@ -107,19 +115,34 @@ bool EPollEngine::DelFd(EventHandler* eh, bool force)
int EPollEngine::GetMaxFds()
{
- return MAX_DESCRIPTORS;
+ if (MAX_DESCRIPTORS)
+ return MAX_DESCRIPTORS;
+
+ int max = ulimit(4, 0);
+ if (max > 0)
+ {
+ MAX_DESCRIPTORS = max;
+ return max;
+ }
+ else
+ {
+ ServerInstance->Logs->Log("SOCKET", DEFAULT, "ERROR: Can't determine maximum number of open sockets!");
+ printf("ERROR: Can't determine maximum number of open sockets!\n");
+ ServerInstance->Exit(EXIT_STATUS_SOCKETENGINE);
+ }
+ return 0;
}
int EPollEngine::GetRemainingFds()
{
- return MAX_DESCRIPTORS - CurrentSetSize;
+ return GetMaxFds() - CurrentSetSize;
}
int EPollEngine::DispatchEvents()
{
socklen_t codesize;
int errcode;
- int i = epoll_wait(EngineHandle, events, MAX_DESCRIPTORS, 1000);
+ int i = epoll_wait(EngineHandle, events, GetMaxFds() - 1, 1000);
TotalEvents += i;
diff --git a/src/socketengines/socketengine_iocp.cpp b/src/socketengines/socketengine_iocp.cpp
index 5bc1faed4..b27f96035 100644
--- a/src/socketengines/socketengine_iocp.cpp
+++ b/src/socketengines/socketengine_iocp.cpp
@@ -32,6 +32,8 @@ IOCPEngine::IOCPEngine(InspIRCd * Instance) : SocketEngine(Instance)
/* Null variables out. */
CurrentSetSize = 0;
EngineHandle = 0;
+ MAX_DESCRIPTORS = 10240;
+ ref = new EventHandler* [10240];
memset(ref, 0, sizeof(EventHandler*) * MAX_DESCRIPTORS);
}
@@ -40,6 +42,7 @@ IOCPEngine::~IOCPEngine()
/* Clean up winsock and close completion port */
CloseHandle(m_completionPort);
WSACleanup();
+ delete[] ref;
}
bool IOCPEngine::AddFd(EventHandler* eh)
diff --git a/src/socketengines/socketengine_kqueue.cpp b/src/socketengines/socketengine_kqueue.cpp
index f245830de..63a1844cb 100644
--- a/src/socketengines/socketengine_kqueue.cpp
+++ b/src/socketengines/socketengine_kqueue.cpp
@@ -6,7 +6,7 @@
* See: http://www.inspircd.org/wiki/index.php/Credits
*
* This program is free but copyrighted software; see
- * the file COPYING for details.
+ * the file COPYING for details.
*
* ---------------------------------------------------
*/
@@ -17,11 +17,13 @@
#include <sys/event.h>
#include <sys/time.h>
#include "socketengines/socketengine_kqueue.h"
-
+#include <ulimit.h>
KQueueEngine::KQueueEngine(InspIRCd* Instance) : SocketEngine(Instance)
{
this->RecoverFromFork();
+ ref = new EventHandler* [GetMaxFds()];
+ ke_list = new struct kevent[GetMaxFds()];
}
void KQueueEngine::RecoverFromFork()
@@ -41,18 +43,21 @@ void KQueueEngine::RecoverFromFork()
ServerInstance->Exit(EXIT_STATUS_SOCKETENGINE);
}
CurrentSetSize = 0;
+ memset(ref, 0, GetMaxFds() * sizeof(EventHandler*));
}
KQueueEngine::~KQueueEngine()
{
this->Close(EngineHandle);
+ delete[] ref;
+ delete[] ke_list;
}
bool KQueueEngine::AddFd(EventHandler* eh)
{
int fd = eh->GetFd();
- if ((fd < 0) || (fd > MAX_DESCRIPTORS))
+ if ((fd < 0) || (fd > GetMaxFds() - 1))
return false;
if (GetRemainingFds() <= 1)
@@ -81,7 +86,7 @@ bool KQueueEngine::DelFd(EventHandler* eh, bool force)
{
int fd = eh->GetFd();
- if ((fd < 0) || (fd > MAX_DESCRIPTORS))
+ if ((fd < 0) || (fd > GetMaxFds() - 1))
return false;
struct kevent ke;
@@ -116,12 +121,27 @@ void KQueueEngine::WantWrite(EventHandler* eh)
int KQueueEngine::GetMaxFds()
{
- return MAX_DESCRIPTORS;
+ if (MAX_DESCRIPTORS)
+ return MAX_DESCRIPTORS;
+
+ int max = ulimit(4, 0);
+ if (max > 0)
+ {
+ MAX_DESCRIPTORS = max;
+ return max;
+ }
+ else
+ {
+ ServerInstance->Logs->Log("SOCKET", DEFAULT, "ERROR: Can't determine maximum number of open sockets!");
+ printf("ERROR: Can't determine maximum number of open sockets!\n");
+ ServerInstance->Exit(EXIT_STATUS_SOCKETENGINE);
+ }
+ return 0;
}
int KQueueEngine::GetRemainingFds()
{
- return MAX_DESCRIPTORS - CurrentSetSize;
+ return GetMaxFds() - CurrentSetSize;
}
int KQueueEngine::DispatchEvents()
@@ -129,7 +149,7 @@ int KQueueEngine::DispatchEvents()
ts.tv_nsec = 0;
ts.tv_sec = 1;
- int i = kevent(EngineHandle, NULL, 0, &ke_list[0], MAX_DESCRIPTORS, &ts);
+ int i = kevent(EngineHandle, NULL, 0, &ke_list[0], GetMaxFds(), &ts);
TotalEvents += i;
diff --git a/src/socketengines/socketengine_ports.cpp b/src/socketengines/socketengine_ports.cpp
index 767ea0df0..113c6794e 100644
--- a/src/socketengines/socketengine_ports.cpp
+++ b/src/socketengines/socketengine_ports.cpp
@@ -6,7 +6,7 @@
* See: http://www.inspircd.org/wiki/index.php/Credits
*
* This program is free but copyrighted software; see
- * the file COPYING for details.
+ * the file COPYING for details.
*
* ---------------------------------------------------
*/
@@ -15,6 +15,7 @@
#include "exitcodes.h"
#include <port.h>
#include "socketengines/socketengine_ports.h"
+#include <ulimit.h>
PortsEngine::PortsEngine(InspIRCd* Instance) : SocketEngine(Instance)
{
@@ -29,17 +30,23 @@ PortsEngine::PortsEngine(InspIRCd* Instance) : SocketEngine(Instance)
ServerInstance->Exit(EXIT_STATUS_SOCKETENGINE);
}
CurrentSetSize = 0;
+
+ ref = new EventHandler* [GetMaxFds()];
+ events = new port_event_t[GetMaxFds()];
+ memset(ref, 0, GetMaxFds() * sizeof(EventHandler*));
}
PortsEngine::~PortsEngine()
{
this->Close(EngineHandle);
+ delete[] ref;
+ delete[] events;
}
bool PortsEngine::AddFd(EventHandler* eh)
{
int fd = eh->GetFd();
- if ((fd < 0) || (fd > MAX_DESCRIPTORS))
+ if ((fd < 0) || (fd > GetMaxFds() - 1))
return false;
if (GetRemainingFds() <= 1)
@@ -64,7 +71,7 @@ void PortsEngine::WantWrite(EventHandler* eh)
bool PortsEngine::DelFd(EventHandler* eh, bool force)
{
int fd = eh->GetFd();
- if ((fd < 0) || (fd > MAX_DESCRIPTORS))
+ if ((fd < 0) || (fd > GetMaxFds() - 1))
return false;
port_dissociate(EngineHandle, PORT_SOURCE_FD, fd);
@@ -78,12 +85,27 @@ bool PortsEngine::DelFd(EventHandler* eh, bool force)
int PortsEngine::GetMaxFds()
{
- return MAX_DESCRIPTORS;
+ if (MAX_DESCRIPTORS)
+ return MAX_DESCRIPTORS;
+
+ int max = ulimit(4, 0);
+ if (max > 0)
+ {
+ MAX_DESCRIPTORS = max;
+ return max;
+ }
+ else
+ {
+ ServerInstance->Logs->Log("SOCKET", DEFAULT, "ERROR: Can't determine maximum number of open sockets!");
+ printf("ERROR: Can't determine maximum number of open sockets!\n");
+ ServerInstance->Exit(EXIT_STATUS_SOCKETENGINE);
+ }
+#include <ulimit.h>
}
int PortsEngine::GetRemainingFds()
{
- return MAX_DESCRIPTORS - CurrentSetSize;
+ return GetMaxFds() - CurrentSetSize;
}
int PortsEngine::DispatchEvents()
@@ -94,7 +116,7 @@ int PortsEngine::DispatchEvents()
poll_time.tv_nsec = 0;
unsigned int nget = 1; // used to denote a retrieve request.
- int i = port_getn(EngineHandle, this->events, MAX_DESCRIPTORS, &nget, &poll_time);
+ int i = port_getn(EngineHandle, this->events, GetMaxFds() - 1, &nget, &poll_time);
// first handle an error condition
if (i == -1)
diff --git a/src/socketengines/socketengine_select.cpp b/src/socketengines/socketengine_select.cpp
index 055637890..5a5d61147 100644
--- a/src/socketengines/socketengine_select.cpp
+++ b/src/socketengines/socketengine_select.cpp
@@ -6,7 +6,7 @@
* See: http://www.inspircd.org/wiki/index.php/Credits
*
* This program is free but copyrighted software; see
- * the file COPYING for details.
+ * the file COPYING for details.
*
* ---------------------------------------------------
*/
@@ -22,17 +22,22 @@ SelectEngine::SelectEngine(InspIRCd* Instance) : SocketEngine(Instance)
{
EngineHandle = 0;
CurrentSetSize = 0;
+
+ writeable = new bool [GetMaxFds()];
memset(writeable, 0, sizeof(writeable));
+ ref = new EventHandler* [GetMaxFds()];
+ memset(ref, 0, GetMaxFds() * sizeof(EventHandler*));
}
SelectEngine::~SelectEngine()
{
+ delete[] ref;
}
bool SelectEngine::AddFd(EventHandler* eh)
{
int fd = eh->GetFd();
- if ((fd < 0) || (fd > MAX_DESCRIPTORS))
+ if ((fd < 0) || (fd > GetMaxFds() - 1))
return false;
if (GetRemainingFds() <= 1)
@@ -58,7 +63,7 @@ bool SelectEngine::DelFd(EventHandler* eh, bool force)
{
int fd = eh->GetFd();
- if ((fd < 0) || (fd > MAX_DESCRIPTORS))
+ if ((fd < 0) || (fd > GetMaxFds() - 1))
return false;
std::map<int,int>::iterator t = fds.find(fd);
@@ -79,7 +84,7 @@ int SelectEngine::GetMaxFds()
int SelectEngine::GetRemainingFds()
{
- return FD_SETSIZE - CurrentSetSize;
+ return GetMaxFds() - CurrentSetSize;
}
int SelectEngine::DispatchEvents()
@@ -87,7 +92,7 @@ int SelectEngine::DispatchEvents()
int result = 0;
timeval tval;
int sresult = 0;
- EventHandler* ev[MAX_DESCRIPTORS];
+ EventHandler* ev[GetMaxFds()];
socklen_t codesize;
int errcode;
diff --git a/src/usermanager.cpp b/src/usermanager.cpp
index af76f5651..6a23ad795 100644
--- a/src/usermanager.cpp
+++ b/src/usermanager.cpp
@@ -126,7 +126,7 @@ void UserManager::AddClient(InspIRCd* Instance, int socket, int port, bool iscac
* than about 10,000 users on ONE server!)
*/
#ifndef WINDOWS
- if ((unsigned int)socket >= MAX_DESCRIPTORS)
+ if (socket >= Instance->SE->GetMaxFds())
{
User::QuitUser(Instance, New, "Server is full");
return;
diff --git a/src/users.cpp b/src/users.cpp
index df7a36683..361b7ba21 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -21,7 +21,13 @@
#include "bancache.h"
#include "commands/cmd_whowas.h"
-static unsigned long already_sent[MAX_DESCRIPTORS] = {0};
+static unsigned long* already_sent = NULL;
+
+
+void InitializeAlreadySent(SocketEngine* SE)
+{
+ already_sent = new unsigned long[SE->GetMaxFds()];
+}
/* XXX: Used for speeding up WriteCommon operations */
unsigned long uniq_id = 0;
@@ -1322,6 +1328,9 @@ void User::WriteCommon(const std::string &text)
uniq_id++;
+ if (!already_sent)
+ InitializeAlreadySent(ServerInstance->SE);
+
/* We dont want to be doing this n times, just once */
snprintf(tb,MAXBUF,":%s %s",this->GetFullHost(),text.c_str());
std::string out = tb;
@@ -1376,6 +1385,10 @@ void User::WriteCommonQuit(const std::string &normal_text, const std::string &op
return;
uniq_id++;
+
+ if (!already_sent)
+ InitializeAlreadySent(ServerInstance->SE);
+
snprintf(tb1,MAXBUF,":%s QUIT :%s",this->GetFullHost(),normal_text.c_str());
snprintf(tb2,MAXBUF,":%s QUIT :%s",this->GetFullHost(),oper_text.c_str());
std::string out1 = tb1;
@@ -1407,6 +1420,10 @@ void User::WriteCommonExcept(const std::string &text)
return;
uniq_id++;
+
+ if (!already_sent)
+ InitializeAlreadySent(ServerInstance->SE);
+
snprintf(tb1,MAXBUF,":%s %s",this->GetFullHost(),text.c_str());
out1 = tb1;