summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorburlex <burlex@e03df62e-2008-0410-955e-edbf42e46eb7>2007-09-04 12:36:05 +0000
committerburlex <burlex@e03df62e-2008-0410-955e-edbf42e46eb7>2007-09-04 12:36:05 +0000
commite51c8a5cf66d1d3eb475b967f99587b5a59ca442 (patch)
treee886e012e37b99a8d107a5ec1caf37e5f01fa537
parent4c83624ed825ca123401a45c8d2844ba6453a85b (diff)
* Fixed some incorrect declarations in IOCPEngine
* Fixed the virtual socket wrapper functions in IOCPEngine {these should really be inlined on unix} * Fixed several compilation issues under Win32 * Fixed calls to close() which should've been changed to SE->Close() + Added a crashdump saving system to Win32 builds. Dumps are saved in the format of dump-<exename>-<year>-<month>-<day>-<hour>-<minute>-<second>.dmp in the working directory. Enabled by default, undefine ENABLE_CRASHDUMPS to disable. + Added m_operflood, this is a module I've had lying around for some time but some users may like it as it allows unreal-like behaviour without increasing flood limits for non-opers. git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@8015 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r--include/socketengine.h2
-rw-r--r--include/socketengine_iocp.h2
-rw-r--r--include/users.h30
-rw-r--r--src/inspircd.cpp19
-rw-r--r--src/modules/m_ident.cpp2
-rw-r--r--src/modules/m_operflood.cpp45
-rw-r--r--src/modules/m_spanningtree/treesocket2.cpp2
-rw-r--r--src/socket.cpp2
-rw-r--r--src/socketengine.cpp63
-rw-r--r--src/socketengine_iocp.cpp10
-rw-r--r--win/inspircdVC71.vcproj2
-rw-r--r--win/inspircd_win32wrapper.cpp64
-rw-r--r--win/inspircd_win32wrapper.h10
13 files changed, 214 insertions, 39 deletions
diff --git a/include/socketengine.h b/include/socketengine.h
index 95688117e..887d2dd56 100644
--- a/include/socketengine.h
+++ b/include/socketengine.h
@@ -353,7 +353,7 @@ public:
*/
virtual int Shutdown(EventHandler* fd, int how);
- /** Abstraction for BSD sockets shutdownt(2).
+ /** Abstraction for BSD sockets shutdown(2).
* This function should emulate its namesake system call exactly.
* @return This method should return exactly the same values as the system call it emulates.
*/
diff --git a/include/socketengine_iocp.h b/include/socketengine_iocp.h
index cf1a08c4c..b024828f1 100644
--- a/include/socketengine_iocp.h
+++ b/include/socketengine_iocp.h
@@ -221,7 +221,7 @@ public:
virtual int NonBlocking(int fd);
- virtual int GetSockName(EventHandler* fd, sockaddr *name, socklen_t* name);
+ virtual int GetSockName(EventHandler* fd, sockaddr *name, socklen_t* namelen);
virtual int Close(int fd);
diff --git a/include/users.h b/include/users.h
index 40c360351..28bc895a5 100644
--- a/include/users.h
+++ b/include/users.h
@@ -175,6 +175,16 @@ class CoreExport ConnectClass : public classbase
public:
+ /** Create a new connect class based on an existing connect class. This is required for std::vector (at least under windows).
+ */
+ ConnectClass(const ConnectClass& source) : type(source.type), name(source.name),
+ registration_timeout(source.registration_timeout), flood(source.flood), host(source.host),
+ pingtime(source.pingtime), pass(source.pass), threshold(source.threshold), sendqmax(source.sendqmax),
+ recvqmax(source.recvqmax), maxlocal(source.maxlocal), maxglobal(source.maxglobal), maxchans(source.maxchans),
+ port(source.port)
+ {
+ }
+
/** Create a new connect class with no settings.
*/
ConnectClass() : type(CC_DENY), name("unnamed"), registration_timeout(0), flood(0), host(""), pingtime(0), pass(""),
@@ -351,10 +361,28 @@ public:
return maxglobal;
}
- bool operator= (ConnectClass &other)
+ bool operator== (ConnectClass &other)
{
return (other.GetName() == name);
}
+
+ void operator=(const ConnectClass & other)
+ {
+ type = other.type;
+ name = other.name;
+ registration_timeout = other.registration_timeout;
+ flood = other.flood;
+ host = other.host;
+ pingtime = other.pingtime;
+ pass = other.pass;
+ threshold = other.threshold;
+ sendqmax = other.sendqmax;
+ recvqmax = other.recvqmax;
+ maxlocal = other.maxlocal;
+ maxglobal = other.maxglobal;
+ maxchans = other.maxchans;
+ port = other.port;
+ }
};
/** Holds a complete list of all channels to which a user has been invited and has not yet joined.
diff --git a/src/inspircd.cpp b/src/inspircd.cpp
index a96e16c45..31219b410 100644
--- a/src/inspircd.cpp
+++ b/src/inspircd.cpp
@@ -695,7 +695,7 @@ int InspIRCd::Run()
* An ircd in four lines! bwahahaha. ahahahahaha. ahahah *cough*.
*/
-int main(int argc, char** argv)
+int ircd(int argc, char ** argv)
{
SI = new InspIRCd(argc, argv);
mysig = &SI->s_signal;
@@ -704,6 +704,23 @@ int main(int argc, char** argv)
return 0;
}
+#ifdef WINDOWS
+
+int main(int argc, char ** argv)
+{
+ __try {
+ ircd(argc,argv);
+ } __except(__exceptionHandler(GetExceptionInformation())) {}
+ return 0;
+}
+
+#else
+int main(int argc, char** argv)
+{
+ return ircd(argc,argv);
+}
+#endif
+
/* this returns true when all modules are satisfied that the user should be allowed onto the irc server
* (until this returns true, a user will block in the waiting state, waiting to connect up to the
* registration timeout maximum seconds)
diff --git a/src/modules/m_ident.cpp b/src/modules/m_ident.cpp
index 28617c56b..c80c53b72 100644
--- a/src/modules/m_ident.cpp
+++ b/src/modules/m_ident.cpp
@@ -149,7 +149,7 @@ class ModuleIdent : public Module
std::string IdentBindIP;
public:
ModuleIdent(InspIRCd *Me)
- : Module::Module(Me)
+ : Module(Me)
{
OnRehash(NULL, "");
}
diff --git a/src/modules/m_operflood.cpp b/src/modules/m_operflood.cpp
new file mode 100644
index 000000000..390dd1fe1
--- /dev/null
+++ b/src/modules/m_operflood.cpp
@@ -0,0 +1,45 @@
+/* +------------------------------------+
+ * | Inspire Internet Relay Chat Daemon |
+ * +------------------------------------+
+ *
+ * InspIRCd: (C) 2002-2007 InspIRCd Development Team
+ * See: http://www.inspircd.org/wiki/index.php/Credits
+ *
+ * This program is free but copyrighted software; see
+ * the file COPYING for details.
+ *
+ * ---------------------------------------------------
+ */
+
+#include "inspircd.h"
+#include "users.h"
+#include "channels.h"
+#include "modules.h"
+
+/* $ModDesc: Removes flood limits from users upon opering up. */
+class ModuleOperFlood : public Module
+{
+public:
+ ModuleOperFlood(InspIRCd * Me) : Module(Me) {}
+
+ void Implements(char * List)
+ {
+ List[I_OnPostOper] = 1;
+ }
+
+ Version GetVersion()
+ {
+ return Version(1,1,0,1,VF_VENDOR,API_VERSION);
+ }
+
+ void OnPostOper(userrec* user, const std::string &opertype)
+ {
+ if(!IS_LOCAL(user))
+ return;
+
+ user->flood = 0;
+ user->WriteServ("NOTICE %s :*** You are now free from flood limits.", user->nick);
+ }
+};
+
+MODULE_INIT(ModuleOperFlood);
diff --git a/src/modules/m_spanningtree/treesocket2.cpp b/src/modules/m_spanningtree/treesocket2.cpp
index 1d6b0dfa8..579276b54 100644
--- a/src/modules/m_spanningtree/treesocket2.cpp
+++ b/src/modules/m_spanningtree/treesocket2.cpp
@@ -1681,7 +1681,7 @@ int TreeSocket::OnIncomingConnection(int newsock, char* ip)
if (!found)
{
Utils->Creator->RemoteMessage(NULL,"Server connection from %s denied (no link blocks with that IP address)", ip);
- close(newsock);
+ Instance->SE->Close(newsock);
return false;
}
}
diff --git a/src/socket.cpp b/src/socket.cpp
index c33eee5a6..38178cab8 100644
--- a/src/socket.cpp
+++ b/src/socket.cpp
@@ -120,7 +120,7 @@ void ListenSocket::HandleEvent(EventType et, int errornum)
else
{
ServerInstance->SE->Shutdown(incomingSockfd, 2);
- close(incomingSockfd);
+ ServerInstance->SE->Close(incomingSockfd);
ServerInstance->stats->statsRefused++;
}
delete[] client;
diff --git a/src/socketengine.cpp b/src/socketengine.cpp
index d8291073e..3e4fc7815 100644
--- a/src/socketengine.cpp
+++ b/src/socketengine.cpp
@@ -100,6 +100,17 @@ bool SocketEngine::BoundsCheckFd(EventHandler* eh)
return true;
}
+#ifdef WINDOWS
+
+int SocketEngine::Accept(EventHandler* fd, sockaddr *addr, socklen_t *addrlen) { return -1; }
+int SocketEngine::Close(int fd) { return -1; }
+int SocketEngine::Close(EventHandler* fd) { return -1; }
+int SocketEngine::Blocking(int fd) { return -1; }
+int SocketEngine::NonBlocking(int fd) { return -1; }
+int SocketEngine::GetSockName(EventHandler* fd, sockaddr *name, socklen_t* namelen) { return -1; }
+int SocketEngine::RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, sockaddr *from, socklen_t *fromlen) { return -1; }
+
+#else
int SocketEngine::Accept(EventHandler* fd, sockaddr *addr, socklen_t *addrlen)
{
@@ -111,14 +122,26 @@ int SocketEngine::Close(EventHandler* fd)
return close(fd->GetFd());
}
-int SocketEngine::Send(EventHandler* fd, const void *buf, size_t len, int flags)
+int SocketEngine::Close(int fd)
{
- return send(fd->GetFd(), buf, len, flags);
+ return close(fd);
}
-int SocketEngine::Recv(EventHandler* fd, void *buf, size_t len, int flags)
+int SocketEngine::Blocking(int fd)
+{
+ int flags = fcntl(fd, F_GETFL, 0);
+ return fcntl(fd, F_SETFL, flags ^ O_NONBLOCK);
+}
+
+int SocketEngine::NonBlocking(int fd)
+{
+ int flags = fcntl(fd, F_GETFL, 0);
+ return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+}
+
+int SocketEngine::GetSockName(EventHandler* fd, sockaddr *name, socklen_t* namelen)
{
- return recv(fd->GetFd(), buf, len, flags);
+ return getsockname(fd->GetFd(), name, namelen);
}
int SocketEngine::RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, sockaddr *from, socklen_t *fromlen)
@@ -126,26 +149,26 @@ int SocketEngine::RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, s
return recvfrom(fd->GetFd(), buf, len, flags, from, fromlen);
}
-int SocketEngine::SendTo(EventHandler* fd, const void *buf, size_t len, int flags, const sockaddr *to, socklen_t tolen)
+#endif
+
+int SocketEngine::Send(EventHandler* fd, const void *buf, size_t len, int flags)
{
- return sendto(fd->GetFd(), buf, len, flags, to, tolen);
+ return send(fd->GetFd(), (const char*)buf, len, flags);
}
-int SocketEngine::Connect(EventHandler* fd, const sockaddr *serv_addr, socklen_t addrlen)
+int SocketEngine::Recv(EventHandler* fd, void *buf, size_t len, int flags)
{
- return connect(fd->GetFd(), serv_addr, addrlen);
+ return recv(fd->GetFd(), (char*)buf, len, flags);
}
-int SocketEngine::Blocking(int fd)
+int SocketEngine::SendTo(EventHandler* fd, const void *buf, size_t len, int flags, const sockaddr *to, socklen_t tolen)
{
- int flags = fcntl(fd, F_GETFL, 0);
- return fcntl(fd, F_SETFL, flags ^ O_NONBLOCK);
+ return sendto(fd->GetFd(), (const char*)buf, len, flags, to, tolen);
}
-int SocketEngine::NonBlocking(int fd)
+int SocketEngine::Connect(EventHandler* fd, const sockaddr *serv_addr, socklen_t addrlen)
{
- int flags = fcntl(fd, F_GETFL, 0);
- return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+ return connect(fd->GetFd(), serv_addr, addrlen);
}
int SocketEngine::Shutdown(EventHandler* fd, int how)
@@ -153,33 +176,21 @@ int SocketEngine::Shutdown(EventHandler* fd, int how)
return shutdown(fd->GetFd(), how);
}
-
int SocketEngine::Bind(int fd, const sockaddr *my_addr, socklen_t addrlen)
{
return bind(fd, my_addr, addrlen);
}
-int SocketEngine::GetSockName(EventHandler* fd, sockaddr *name, socklen_t* namelen)
-{
- return getsockname(fd->GetFd(), name, namelen);
-}
-
int SocketEngine::Listen(int sockfd, int backlog)
{
return listen(sockfd, backlog);
}
-
int SocketEngine::Shutdown(int fd, int how)
{
return shutdown(fd, how);
}
-int SocketEngine::Close(int fd)
-{
- return close(fd);
-}
-
void SocketEngine::RecoverFromFork()
{
}
diff --git a/src/socketengine_iocp.cpp b/src/socketengine_iocp.cpp
index f7448f85f..eba88ad7e 100644
--- a/src/socketengine_iocp.cpp
+++ b/src/socketengine_iocp.cpp
@@ -464,11 +464,11 @@ int IOCPEngine::Accept(EventHandler* fd, sockaddr *addr, socklen_t *addrlen)
return ov->socket;
}
-int IOCPEngine::GetSockName(EventHandler* fd, sockaddr *name, socklen_t* name)
+int IOCPEngine::GetSockName(EventHandler* fd, sockaddr *name, socklen_t* namelen)
{
Overlapped* ovl = NULL;
- if (!fd->GetExt("windows_acceptevent", acceptevent))
+ if (!fd->GetExt("windows_acceptevent", ovl))
return -1;
accept_overlap* ov = (accept_overlap*)ovl->m_params;
@@ -495,18 +495,18 @@ int IOCPEngine::RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, str
int IOCPEngine::Blocking(int fd)
{
unsigned long opt = 0;
- ioctlsocket(s, FIONBIO, &opt);
+ return ioctlsocket(fd, FIONBIO, &opt);
}
int IOCPEngine::NonBlocking(int fd)
{
unsigned long opt = 1;
- ioctlsocket(s, FIONBIO, &opt);
+ return ioctlsocket(fd, FIONBIO, &opt);
}
int IOCPEngine::Close(int fd)
{
- return closesocket(socket);
+ return closesocket(fd);
}
int IOCPEngine::Close(EventHandler* fd)
diff --git a/win/inspircdVC71.vcproj b/win/inspircdVC71.vcproj
index 1bcac8fcd..60dbaad0c 100644
--- a/win/inspircdVC71.vcproj
+++ b/win/inspircdVC71.vcproj
@@ -33,7 +33,7 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="ws2_32.lib mswsock.lib"
+ AdditionalDependencies="ws2_32.lib mswsock.lib dbghelp.lib"
ShowProgress="0"
OutputFile="$(OutDir)/inspircd.exe"
LinkIncremental="1"
diff --git a/win/inspircd_win32wrapper.cpp b/win/inspircd_win32wrapper.cpp
index e6f25df18..a25544aab 100644
--- a/win/inspircd_win32wrapper.cpp
+++ b/win/inspircd_win32wrapper.cpp
@@ -654,3 +654,67 @@ int gettimeofday(struct timeval * tv, void * tz)
tv->tv_usec = (mstime - (tv->tv_sec * 1000)) * 1000;
return 0;
}
+
+int __exceptionHandler(PEXCEPTION_POINTERS pExceptPtrs)
+{
+ SYSTEMTIME _time;
+ HANDLE hDump;
+ char mod[MAX_PATH*2];
+ char * pMod = mod;
+ char dump_filename[MAX_PATH];
+ MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
+ DWORD code;
+
+ if(pExceptPtrs == NULL) {
+ __try {
+ RaiseException(EXCEPTION_BREAKPOINT, 0, 0, NULL);
+ } __except(__exceptionHandler(GetExceptionInformation()), EXCEPTION_CONTINUE_EXECUTION) {}
+ }
+
+ printf("Exception caught at 0x%.8X! Attempting to write crash dump file.\n", (unsigned long)pExceptPtrs->ExceptionRecord->ExceptionAddress);
+
+ if(GetModuleFileName(0, mod, MAX_PATH*2) > 0)
+ {
+ if( (pMod = strrchr(mod, '\\')) != NULL )
+ ++pMod;
+ else
+ strcpy(mod, "unk");
+ }
+ else
+ strcpy(mod, "unk");
+
+ GetSystemTime(&_time);
+ snprintf(dump_filename, MAX_PATH, "dump-%s-%u-%u-%u-%u-%u-%u.dmp",
+ pMod, _time.wYear, _time.wMonth, _time.wDay, _time.wHour, _time.wMinute, _time.wSecond);
+
+ hDump = CreateFile(dump_filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, 0);
+ if(hDump != INVALID_HANDLE_VALUE)
+ {
+ dumpInfo.ClientPointers = FALSE;
+ dumpInfo.ExceptionPointers = pExceptPtrs;
+ dumpInfo.ThreadId = GetCurrentThreadId();
+
+ /* let's write a full memory dump. insp shouldn't be using much memory anyway, and it will help a lot with debugging. */
+ MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDump, MiniDumpWithFullMemory, &dumpInfo, NULL, NULL);
+ FlushFileBuffers(hDump);
+ CloseHandle(hDump);
+ }
+
+ /* check for a debugger */
+ __asm {
+ pushad
+ pushfd
+ mov eax, fs:[18h]
+ mov eax, dword ptr [eax+30h]
+ mov ebx, dword ptr [eax]
+ mov code, ebx
+ popfd
+ popad
+ }
+
+ /* break into debugger if we have one */
+ if(code & 0x10000)
+ return EXCEPTION_CONTINUE_SEARCH;
+ else /* otherwise exit abnormally */
+ return EXCEPTION_CONTINUE_EXECUTION;
+}
diff --git a/win/inspircd_win32wrapper.h b/win/inspircd_win32wrapper.h
index 6d03d0507..a6d023c56 100644
--- a/win/inspircd_win32wrapper.h
+++ b/win/inspircd_win32wrapper.h
@@ -21,6 +21,7 @@
/* Define the WINDOWS macro. This means we're building on windows to the rest of the server.
I think this is more reasonable than using WIN32, especially if we're gonna be doing 64-bit compiles */
#define WINDOWS 1
+#define ENABLE_CRASHDUMPS 1
/* Make builds smaller, leaner and faster */
#define VC_EXTRALEAN
@@ -70,6 +71,10 @@
#include <stdio.h>
#include <algorithm>
+#ifdef ENABLE_CRASHDUMPS
+#include <DbgHelp.h>
+#endif
+
/* strcasecmp is not defined on windows by default */
#define strcasecmp _stricmp
@@ -199,5 +204,10 @@ void ChangeWindowsSpecificPointers(InspIRCd* Instance);
bool ValidateWindowsDnsServer(ServerConfig* conf, const char* tag, const char* value, ValueItem &data);
+#ifdef ENABLE_CRASHDUMPS
+typedef struct _EXCEPTION_POINTERS EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
+int __cdecl __exceptionHandler(PEXCEPTION_POINTERS pExceptPtrs);
+#endif
+
#endif