diff --git a/Changes b/Changes index 29b8f53c2..9ac365e5a 100644 --- a/Changes +++ b/Changes @@ -2605,3 +2605,6 @@ seen. gmtime warning still there (#0001365) - Fixed a bug with SVSNLINE - reported by FreakyComputer and fixed by AngryWolf (#0001399) +- example.conf: added +i in modes-on-connect. +- Temporarely added fdlist debugcode, please report any bugreports it gives, + it would especially be helpful if you know _what_ triggered the error :). diff --git a/doc/example.conf b/doc/example.conf index 4265e8862..3aa5f87ad 100644 --- a/doc/example.conf +++ b/doc/example.conf @@ -701,7 +701,7 @@ set { set { kline-address "set.this.email"; - modes-on-connect "+xw"; + modes-on-connect "+ixw"; modes-on-oper "+xwgs"; oper-auto-join "#opers"; dns { diff --git a/src/fdlist.c b/src/fdlist.c index 38e21dbbc..7a27aec7a 100644 --- a/src/fdlist.c +++ b/src/fdlist.c @@ -33,9 +33,14 @@ extern fdlist busycli_fdlist; extern fdlist serv_fdlist; extern fdlist oper_fdlist; +#define FDLIST_DEBUG + void addto_fdlist(int fd, fdlist * listp) { int index; +#ifdef FDLIST_DEBUG + int i; +#endif /* I prefer this little 5-cpu-cycles-check over memory corruption. -- Syzop */ if ((fd < 0) || (fd >= MAXCONNECTIONS)) @@ -49,6 +54,21 @@ void addto_fdlist(int fd, fdlist * listp) return; } +#ifdef FDLIST_DEBUG + for (i = listp->last_entry; i; i--) + { + if (listp->entry[i] == fd) + { + char buf[2048]; + ircsprintf(buf, "[BUG] addto_fdlist() called for duplicate entry! fd=%d, fdlist=%p, client=%s (%p/%p/%p/%p)", + fd, listp, local[fd] ? local[fd]->name : "", &default_fdlist, &busycli_fdlist, &serv_fdlist, &oper_fdlist); + sendto_realops("%s", buf); + ircd_log(LOG_ERROR, "%s", buf); + return; + } + } +#endif + if ((index = ++listp->last_entry) >= MAXCONNECTIONS) { /* @@ -66,6 +86,9 @@ void addto_fdlist(int fd, fdlist * listp) void delfrom_fdlist(int fd, fdlist * listp) { int i; +#ifdef FDLIST_DEBUG + int cnt = 0; +#endif /* I prefer this little 5-cpu-cycles-check over memory corruption. -- Syzop */ if ((fd < 0) || (fd >= MAXCONNECTIONS)) @@ -79,6 +102,24 @@ void delfrom_fdlist(int fd, fdlist * listp) return; } +#ifdef FDLIST_DEBUG + for (i = listp->last_entry; i; i--) + { + if (listp->entry[i] == fd) + cnt++; + } + if (cnt > 1) + { + char buf[2048]; + ircsprintf(buf, "[BUG] delfrom_fdlist() called, duplicate entries detected! fd=%d, fdlist=%p, client=%s (%p/%p/%p/%p)", + fd, listp, local[fd] ? local[fd]->name : "", &default_fdlist, &busycli_fdlist, &serv_fdlist, &oper_fdlist); + sendto_realops("%s", buf); + ircd_log(LOG_ERROR, "%s", buf); + return; + } +#endif + + for (i = listp->last_entry; i; i--) { if (listp->entry[i] == fd) diff --git a/src/s_misc.c b/src/s_misc.c index 13db7f4a7..713d82867 100644 --- a/src/s_misc.c +++ b/src/s_misc.c @@ -385,6 +385,29 @@ int exit_client(aClient *cptr, aClient *sptr, aClient *from, char *comment) if (MyConnect(sptr)) { #ifndef NO_FDLIST +#define FDLIST_DEBUG +#ifdef FDLIST_DEBUG + { + int i; + int cnt = 0; + + if (!IsAnOper(sptr)) + { + for (i = oper_fdlist.last_entry; i; i--) + { + if (oper_fdlist.entry[i] == sptr->slot) + { + sendto_realops("[BUG] exit_client: oper_fdlist entry while not oper, fd=%d, user='%s'", + sptr->slot, sptr->name); + ircd_log(LOG_ERROR, "[BUG] exit_client: oper_fdlist entry while not oper, fd=%d, user='%s'", + sptr->slot, sptr->name); + delfrom_fdlist(sptr->slot, &oper_fdlist); /* be kind of enough to fix the problem.. */ + break; /* MUST break here */ + } + } + } + } +#endif if (IsAnOper(sptr)) delfrom_fdlist(sptr->slot, &oper_fdlist); if (IsServer(sptr))