summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2005-05-01 21:24:59 +0000
committerbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2005-05-01 21:24:59 +0000
commitb7b2eeaeb9e3168698e9d17e73bcc79022f987a2 (patch)
treeb83b100c29a2dea1358d486ecf24e6afa2ae62c9
parenta643172dd76776544773eeb4aa49b79a98ac5ca1 (diff)
Sanity checks for fd_ref in addclient
Fixed 'server ignores me forever if i throttle the server with connections' bug git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@1272 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r--.inspircd.inc4
-rw-r--r--src/inspircd.cpp31
2 files changed, 32 insertions, 3 deletions
diff --git a/.inspircd.inc b/.inspircd.inc
index e86ad18d4..4f70bad75 100644
--- a/.inspircd.inc
+++ b/.inspircd.inc
@@ -110,7 +110,7 @@ sub debug {
sub stop {
- if (getstatus() == 0) { print "InspIRCd is not running. (Or PID File not found)"; return 0; }
+ if (getstatus() == 0) { print "InspIRCd is not running. (Or PID File not found)\n"; return 0; }
# Get to here, we have something to kill.
my $pid = getprocessid();
print "Stopping InspIRCd...\n";
@@ -126,7 +126,7 @@ sub stop {
sub getpidfile {
- open INFILE, "< $conffile" or die "Couldn't open $conffile";
+ open INFILE, "< $conffile" or die "Couldn't open $conffile\n";
my(@lines) = <INFILE>;
close INFILE;
chomp(@lines);
diff --git a/src/inspircd.cpp b/src/inspircd.cpp
index fa7171248..0870116b2 100644
--- a/src/inspircd.cpp
+++ b/src/inspircd.cpp
@@ -2482,7 +2482,17 @@ void AddClient(int socket, char* host, int port, bool iscached, char* ip)
iter = clientlist.find(tempnick);
- if (iter != clientlist.end()) return;
+ // fix by brain.
+ // as these nicknames are 'RFC impossible', we can be sure nobody is going to be
+ // using one as a registered connection. As theyre per fd, we can also safely assume
+ // that we wont have collisions. Therefore, if the nick exists in the list, its only
+ // used by a dead socket, erase the iterator so that the new client may reclaim it.
+ // this was probably the cause of 'server ignores me when i hammer it with reconnects'
+ // issue in earlier alphas/betas
+ if (iter != clientlist.end())
+ {
+ clientlist.erase(iter);
+ }
/*
* It is OK to access the value here this way since we know
@@ -2537,7 +2547,23 @@ void AddClient(int socket, char* host, int port, bool iscached, char* ip)
}
if (clientlist.size() == MAXCLIENTS)
+ {
kill_link(clientlist[tempnick],"No more connections allowed in this class");
+ return;
+ }
+
+ // this is done as a safety check to keep the file descriptors within range of fd_ref_table.
+ // its a pretty big but for the moment valid assumption:
+ // file descriptors are handed out starting at 0, and are recycled as theyre freed.
+ // therefore if there is ever an fd over 65535, 65536 clients must be connected to the
+ // irc server at once (or the irc server otherwise initiating this many connections, files etc)
+ // which for the time being is a physical impossibility (even the largest networks dont have more
+ // than about 10,000 users on ONE server!)
+ if (socket > 65535)
+ {
+ kill_link(clientlist[tempnick],"Server is full");
+ return;
+ }
char* e = matches_exception(ip);
@@ -2549,6 +2575,7 @@ void AddClient(int socket, char* host, int port, bool iscached, char* ip)
char reason[MAXBUF];
snprintf(reason,MAXBUF,"Z-Lined: %s",r);
kill_link(clientlist[tempnick],reason);
+ return;
}
}
fd_ref_table[socket] = clientlist[tempnick];
@@ -4289,6 +4316,8 @@ int InspIRCd(void)
process_buffer(sanitized,current);
// look for the user's record in case it's changed... if theyve quit,
// we cant do anything more with their buffer, so bail.
+ // there used to be an ugly, slow loop here. Now we have a reference
+ // table, life is much easier (and FASTER)
if (!fd_ref_table[currfd])
goto label;