#include "inspircd_util.h"
#include "inspircd_config.h"
#include <unistd.h>
-#include <fcntl.h>
#include <sys/errno.h>
#include <sys/ioctl.h>
#include <sys/utsname.h>
+#ifdef USE_KQUEUE
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/time.h>
+#endif
#include <cstdio>
#include <time.h>
#include <string>
#include <map>
#include <sstream>
#include <vector>
-#include <errno.h>
#include <deque>
-#include <errno.h>
-#include <unistd.h>
-#include <sched.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#ifndef RUSAGE_SELF
+#define RUSAGE_SELF 0
+#define RUSAGE_CHILDREN -1
+#endif
#include "connection.h"
#include "users.h"
#include "servers.h"
#include "xline.h"
#include "inspstring.h"
#include "dnsqueue.h"
-
-#ifdef GCC3
-#define nspace __gnu_cxx
-#else
-#define nspace std
-#endif
+#include "helperfuncs.h"
+#include "hashcomp.h"
using namespace std;
+#ifdef USE_KQUEUE
+extern int kq;
+#endif
+
extern int MODCOUNT;
extern std::vector<Module*> modules;
extern std::vector<ircd_module*> factory;
extern char MyExecutable[1024];
extern int boundPortCount;
extern int portCount;
-extern int UDPportCount;
+extern int SERVERportCount;
extern int ports[MAXSOCKS];
extern int defaultRoute;
const long duration_w = duration_d * 7;
const long duration_y = duration_w * 52;
-namespace nspace
-{
-#ifdef GCC34
- template<> struct hash<in_addr>
-#else
- template<> struct nspace::hash<in_addr>
-#endif
- {
- size_t operator()(const struct in_addr &a) const
- {
- size_t q;
- memcpy(&q,&a,sizeof(size_t));
- return q;
- }
- };
-#ifdef GCC34
- template<> struct hash<string>
-#else
- template<> struct nspace::hash<string>
-#endif
- {
- size_t operator()(const string &s) const
- {
- char a[MAXBUF];
- static struct hash<const char *> strhash;
- strlcpy(a,s.c_str(),MAXBUF);
- strlower(a);
- return strhash(a);
- }
- };
-}
-
-
-struct StrHashComp
-{
-
- bool operator()(const string& s1, const string& s2) const
- {
- char a[MAXBUF],b[MAXBUF];
- strlcpy(a,s1.c_str(),MAXBUF);
- strlcpy(b,s2.c_str(),MAXBUF);
- strlower(a);
- strlower(b);
- return (strcasecmp(a,b) == 0);
- }
-
-};
-
-struct InAddr_HashComp
-{
-
- bool operator()(const in_addr &s1, const in_addr &s2) const
- {
- size_t q;
- size_t p;
-
- memcpy(&q,&s1,sizeof(size_t));
- memcpy(&p,&s2,sizeof(size_t));
-
- return (q == p);
- }
-
-};
-
-
-typedef nspace::hash_map<std::string, userrec*, nspace::hash<string>, StrHashComp> user_hash;
-typedef nspace::hash_map<std::string, chanrec*, nspace::hash<string>, StrHashComp> chan_hash;
-typedef nspace::hash_map<in_addr,string*, nspace::hash<in_addr>, InAddr_HashComp> address_cache;
+typedef nspace::hash_map<std::string, userrec*, nspace::hash<string>, irc::StrHashComp> user_hash;
+typedef nspace::hash_map<std::string, chanrec*, nspace::hash<string>, irc::StrHashComp> chan_hash;
+typedef nspace::hash_map<in_addr,string*, nspace::hash<in_addr>, irc::InAddr_HashComp> address_cache;
+typedef nspace::hash_map<std::string, WhoWasUser*, nspace::hash<string>, irc::StrHashComp> whowas_hash;
typedef std::deque<command_t> command_table;
extern user_hash clientlist;
extern chan_hash chanlist;
-extern user_hash whowas;
+extern whowas_hash whowas;
extern command_table cmdlist;
extern file_cache MOTD;
extern file_cache RULES;
extern address_cache IP;
+extern std::vector<userrec*> all_opers;
+
+// This table references users by file descriptor.
+// its an array to make it VERY fast, as all lookups are referenced
+// by an integer, meaning there is no need for a scan/search operation.
+extern userrec* fd_ref_table[65536];
+
+extern int statsAccept,statsRefused,statsUnknown,statsCollisions,statsDns,statsDnsGood,statsDnsBad,statsConnects,statsSent,statsRecv;
void handle_join(char **parameters, int pcnt, userrec *user)
{
chanrec* Ptr;
- int i = 0;
if (loop_call(handle_join,parameters,pcnt,user,0,0,1))
return;
void handle_part(char **parameters, int pcnt, userrec *user)
{
- chanrec* Ptr;
-
if (pcnt > 1)
{
if (loop_call(handle_part,parameters,pcnt,user,0,pcnt-2,0))
if ((!u) || (!Ptr))
{
- WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, parameters[0]);
+ WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]);
return;
}
void handle_restart(char **parameters, int pcnt, userrec *user)
{
- char restart[1024];
char *argv[32];
log(DEFAULT,"Restart: %s",user->nick);
if (!strcmp(parameters[0],restartpass))
if (iter != clientlist.end())
{
log(DEBUG,"deleting user hash value %d",iter->second);
- if ((iter->second) && (user->registered == 7)) {
- delete iter->second;
- }
clientlist.erase(iter);
}
- purge_empty_chans();
+ if (u->registered == 7)
+ {
+ purge_empty_chans(u);
+ }
+ if (u->fd > -1)
+ fd_ref_table[u->fd] = NULL;
+ delete u;
}
else
{
}
else
{
- WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, parameters[0]);
+ WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]);
}
}
void handle_invite(char **parameters, int pcnt, userrec *user)
{
- userrec* u = Find(parameters[0]);
- chanrec* c = FindChan(parameters[1]);
-
- if ((!c) || (!u))
+ if (pcnt == 2)
{
- if (!c)
+ userrec* u = Find(parameters[0]);
+ chanrec* c = FindChan(parameters[1]);
+
+ if ((!c) || (!u))
{
- WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[1]);
+ if (!c)
+ {
+ WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[1]);
+ }
+ else
+ {
+ if (c->binarymodes & CM_INVITEONLY)
+ {
+ WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]);
+ }
+ }
+
+ return;
}
- else
+
+ if (c->binarymodes & CM_INVITEONLY)
{
- if (c->inviteonly)
+ if (cstatus(user,c) < STATUS_HOP)
{
- WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]);
+ WriteServ(user->fd,"482 %s %s :You must be at least a half-operator to change modes on this channel",user->nick, c->name);
+ return;
}
}
+ if (has_channel(u,c))
+ {
+ WriteServ(user->fd,"443 %s %s %s :Is already on channel %s",user->nick,u->nick,c->name,c->name);
+ return;
+ }
+ if (!has_channel(user,c))
+ {
+ WriteServ(user->fd,"442 %s %s :You're not on that channel!",user->nick, c->name);
+ return;
+ }
- return;
- }
+ int MOD_RESULT = 0;
+ FOREACH_RESULT(OnUserPreInvite(user,u,c));
+ if (MOD_RESULT == 1) {
+ return;
+ }
- if (c->inviteonly)
+ u->InviteTo(c->name);
+ WriteFrom(u->fd,user,"INVITE %s :%s",u->nick,c->name);
+ WriteServ(user->fd,"341 %s %s %s",user->nick,u->nick,c->name);
+
+ // i token must go to ALL servers!!!
+ char buffer[MAXBUF];
+ snprintf(buffer,MAXBUF,"i %s %s %s",u->nick,user->nick,c->name);
+ NetSendToAll(buffer);
+ }
+ else
{
- if (cstatus(user,c) < STATUS_HOP)
+ // pinched from ircu - invite with not enough parameters shows channels
+ // youve been invited to but haven't joined yet.
+ InvitedList* il = user->GetInviteList();
+ for (InvitedList::iterator i = il->begin(); i != il->end(); i++)
{
- WriteServ(user->fd,"482 %s %s :You must be at least a half-operator to change modes on this channel",user->nick, c->name);
- return;
+ if (i->channel) {
+ WriteServ(user->fd,"346 %s :%s",user->nick,i->channel);
+ }
}
+ WriteServ(user->fd,"347 %s :End of INVITE list",user->nick);
}
- if (has_channel(u,c))
- {
- WriteServ(user->fd,"443 %s %s %s :Is already on channel %s",user->nick,u->nick,c->name,c->name);
- return;
- }
- if (!has_channel(user,c))
- {
- WriteServ(user->fd,"442 %s %s :You're not on that channel!",user->nick, c->name);
- return;
- }
-
- int MOD_RESULT = 0;
- FOREACH_RESULT(OnUserPreInvite(user,u,c));
- if (MOD_RESULT == 1) {
- return;
- }
-
- u->InviteTo(c->name);
- WriteFrom(u->fd,user,"INVITE %s :%s",u->nick,c->name);
- WriteServ(user->fd,"341 %s %s %s",user->nick,u->nick,c->name);
-
- // i token must go to ALL servers!!!
- char buffer[MAXBUF];
- snprintf(buffer,MAXBUF,"i %s %s %s",u->nick,user->nick,c->name);
- NetSendToAll(buffer);
}
void handle_topic(char **parameters, int pcnt, userrec *user)
Ptr = FindChan(parameters[0]);
if (Ptr)
{
- if (((Ptr) && (!has_channel(user,Ptr))) && (Ptr->secret))
+ if (((Ptr) && (!has_channel(user,Ptr))) && (Ptr->binarymodes & CM_SECRET))
{
WriteServ(user->fd,"442 %s %s :You're not on that channel!",user->nick, Ptr->name);
return;
}
else
{
- WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, parameters[0]);
+ WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]);
}
}
return;
WriteServ(user->fd,"442 %s %s :You're not on that channel!",user->nick, Ptr->name);
return;
}
- if ((Ptr->topiclock) && (cstatus(user,Ptr)<STATUS_HOP))
+ if ((Ptr->binarymodes & CM_TOPICLOCK) && (cstatus(user,Ptr)<STATUS_HOP))
{
WriteServ(user->fd,"482 %s %s :You must be at least a half-operator to change modes on this channel", user->nick, Ptr->name);
return;
}
else
{
- WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, parameters[0]);
+ WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]);
}
}
}
c = FindChan(parameters[0]);
if (c)
{
- if (((c) && (!has_channel(user,c))) && (c->secret))
+ if (((c) && (!has_channel(user,c))) && (c->binarymodes & CM_SECRET))
{
WriteServ(user->fd,"442 %s %s :You're not on that channel!",user->nick, c->name);
return;
}
else
{
- WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, parameters[0]);
+ WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]);
}
}
chan = FindChan(parameters[0]);
if (chan)
{
- if ((chan->noexternal) && (!has_channel(user,chan)))
+ if ((chan->binarymodes & CM_NOEXTERNAL) && (!has_channel(user,chan)))
{
WriteServ(user->fd,"404 %s %s :Cannot send to channel (no external messages)", user->nick, chan->name);
return;
}
- if ((chan->moderated) && (cstatus(user,chan)<STATUS_VOICE))
+ if ((chan->binarymodes & CM_MODERATED) && (cstatus(user,chan)<STATUS_VOICE))
{
WriteServ(user->fd,"404 %s %s :Cannot send to channel (+m)", user->nick, chan->name);
return;
return;
}
parameters[1] = (char*)temp.c_str();
+
+ if (temp == "")
+ {
+ WriteServ(user->fd,"412 %s No text to send", user->nick);
+ return;
+ }
ChanExceptSender(chan, user, "PRIVMSG %s :%s", chan->name, parameters[1]);
else
{
/* no such nick/channel */
- WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, parameters[0]);
+ WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]);
}
return;
}
else
{
/* no such nick/channel */
- WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, parameters[0]);
+ WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]);
}
}
chan = FindChan(parameters[0]);
if (chan)
{
- if ((chan->noexternal) && (!has_channel(user,chan)))
+ if ((chan->binarymodes & CM_NOEXTERNAL) && (!has_channel(user,chan)))
{
WriteServ(user->fd,"404 %s %s :Cannot send to channel (no external messages)", user->nick, chan->name);
return;
}
- if ((chan->moderated) && (cstatus(user,chan)<STATUS_VOICE))
+ if ((chan->binarymodes & CM_MODERATED) && (cstatus(user,chan)<STATUS_VOICE))
{
WriteServ(user->fd,"404 %s %s :Cannot send to channel (+m)", user->nick, chan->name);
return;
}
parameters[1] = (char*)temp.c_str();
+ if (temp == "")
+ {
+ WriteServ(user->fd,"412 %s No text to send", user->nick);
+ return;
+ }
+
ChanExceptSender(chan, user, "NOTICE %s :%s", chan->name, parameters[1]);
// if any users of this channel are on remote servers, broadcast the packet
else
{
/* no such nick/channel */
- WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, parameters[0]);
+ WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]);
}
return;
}
else
{
/* no such nick/channel */
- WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, parameters[0]);
+ WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]);
}
}
void handle_whois(char **parameters, int pcnt, userrec *user)
{
userrec *dest;
- char *t;
if (loop_call(handle_whois,parameters,pcnt,user,0,pcnt-1,0))
return;
WriteServ(user->fd,"311 %s %s %s %s * :%s",user->nick, dest->nick, dest->ident, dest->dhost, dest->fullname);
if ((user == dest) || (strchr(user->modes,'o')))
{
- WriteServ(user->fd,"378 %s %s :is connecting from *@%s",user->nick, dest->nick, dest->host);
+ WriteServ(user->fd,"378 %s %s :is connecting from *@%s %s",user->nick, dest->nick, dest->host, dest->ip);
}
- if (strcmp(chlist(dest),""))
+ char* cl = chlist(dest,user);
+ if (strcmp(cl,""))
{
- WriteServ(user->fd,"319 %s %s :%s",user->nick, dest->nick, chlist(dest));
+ WriteServ(user->fd,"319 %s %s :%s",user->nick, dest->nick, cl);
}
WriteServ(user->fd,"312 %s %s %s :%s",user->nick, dest->nick, dest->server, GetServerDescription(dest->server).c_str());
if (strcmp(dest->awaymsg,""))
}
else
{
- WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, parameters[0]);
+ WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]);
+ WriteServ(user->fd,"318 %s %s :End of /WHOIS list.",user->nick, parameters[0]);
}
}
else
{
/* no such nick/channel */
- WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, parameters[0]);
+ WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]);
+ WriteServ(user->fd,"318 %s %s :End of /WHOIS list.",user->nick, parameters[0]);
}
}
reason[MAXQUIT-1] = '\0';
}
- Write(user->fd,"ERROR :Closing link (%s@%s) [%s]",user->ident,user->host,parameters[0]);
- WriteOpers("*** Client exiting: %s!%s@%s [%s]",user->nick,user->ident,user->host,parameters[0]);
+ Write(user->fd,"ERROR :Closing link (%s@%s) [%s%s]",user->ident,user->host,PrefixQuit,parameters[0]);
+ WriteOpers("*** Client exiting: %s!%s@%s [%s%s]",user->nick,user->ident,user->host,PrefixQuit,parameters[0]);
WriteCommonExcept(user,"QUIT :%s%s",PrefixQuit,parameters[0]);
char buffer[MAXBUF];
/* push the socket on a stack of sockets due to be closed at the next opportunity */
if (user->fd > -1)
{
- shutdown(user->fd,2);
- close(user->fd);
+#ifdef USE_KQUEUE
+ struct kevent ke;
+ EV_SET(&ke, user->fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
+ int i = kevent(kq, &ke, 1, 0, 0, NULL);
+ if (i == -1)
+ {
+ log(DEBUG,"kqueue: Failed to remove user from queue!");
+ }
+#endif
+ shutdown(user->fd,2);
+ close(user->fd);
}
if (iter != clientlist.end())
{
clientlist.erase(iter);
- log(DEBUG,"deleting user hash value %d",iter->second);
- //if ((user) && (user->registered == 7)) {
- //delete user;
- //}
}
if (user->registered == 7) {
- purge_empty_chans();
+ purge_empty_chans(user);
}
+ if (user->fd > -1)
+ fd_ref_table[user->fd] = NULL;
+ delete user;
}
void handle_who(char **parameters, int pcnt, userrec *user)
// Bug Fix #29
strcpy(tmp, "");
if (strcmp(i->second->awaymsg, "")) {
- strncat(tmp, "G", 9);
+ strlcat(tmp, "G", 9);
} else {
- strncat(tmp, "H", 9);
+ strlcat(tmp, "H", 9);
}
- if (strchr(i->second->modes,'o')) { strncat(tmp, "*", 9); }
+ if (strchr(i->second->modes,'o')) { strlcat(tmp, "*", 9); }
WriteServ(user->fd,"352 %s %s %s %s %s %s %s :0 %s",user->nick, Ptr ? Ptr->name : "*", i->second->ident, i->second->dhost, i->second->server, i->second->nick, tmp, i->second->fullname);
n_list++;
if (n_list > MaxWhoResults)
// Fix Bug #29 - Part 2..
strcpy(tmp, "");
if (strcmp(i->second->awaymsg, "")) {
- strncat(tmp, "G", 9);
+ strlcat(tmp, "G", 9);
} else {
- strncat(tmp, "H", 9);
+ strlcat(tmp, "H", 9);
}
- if (strchr(i->second->modes,'o')) { strncat(tmp, "*", 9); }
- strcat(tmp, cmode(i->second, Ptr));
+ if (strchr(i->second->modes,'o')) { strlcat(tmp, "*", 9); }
+ strlcat(tmp, cmode(i->second, Ptr),5);
WriteServ(user->fd,"352 %s %s %s %s %s %s %s :0 %s",user->nick, Ptr->name, i->second->ident, i->second->dhost, i->second->server, i->second->nick, tmp, i->second->fullname);
}
}
}
else
{
- WriteServ(user->fd,"401 %s %s :No suck nick/channel",user->nick, parameters[0]);
+ WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]);
}
}
else
// Bug Fix #29 -- Part 29..
strcpy(tmp, "");
if (strcmp(u->awaymsg, "")) {
- strncat(tmp, "G" ,9);
+ strlcat(tmp, "G" ,9);
} else {
- strncat(tmp, "H" ,9);
+ strlcat(tmp, "H" ,9);
}
- if (strchr(u->modes,'o')) { strncat(tmp, "*" ,9); }
- WriteServ(user->fd,"352 %s %s %s %s %s %s %s :0 %s",user->nick, u->nick, u->ident, u->dhost, u->server, u->nick, tmp, u->fullname);
+ if (strchr(u->modes,'o')) { strlcat(tmp, "*" ,9); }
+ WriteServ(user->fd,"352 %s %s %s %s %s %s %s :0 %s",user->nick, u->chans[0].channel ? u->chans[0].channel->name
+ : "*", u->ident, u->dhost, u->server, u->nick, tmp, u->fullname);
}
WriteServ(user->fd,"315 %s %s :End of /WHO list.",user->nick, parameters[0]);
}
{
if ((!strcmp(parameters[0],"0")) || (!strcmp(parameters[0],"*")) && (!strcmp(parameters[1],"o")))
{
- for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
+ for (std::vector<userrec*>::iterator i = all_opers.begin(); i != all_opers.end(); i++)
{
- if ((common_channels(user,i->second)) && (isnick(i->second->nick)))
- {
- if (strchr(i->second->modes,'o'))
- {
- // If i were a rich man.. I wouldn't need to me making these bugfixes..
- // But i'm a poor bastard with nothing better to do.
- strcpy(tmp, "");
- if (strcmp(i->second->awaymsg, "")) {
- strncat(tmp, "G" ,9);
- } else {
- strncat(tmp, "H" ,9);
- }
-
- WriteServ(user->fd,"352 %s %s %s %s %s %s %s* :0 %s",user->nick, user->nick, i->second->ident, i->second->dhost, i->second->server, i->second->nick, tmp, i->second->fullname);
- }
- }
+ // If i were a rich man.. I wouldn't need to me making these bugfixes..
+ // But i'm a poor bastard with nothing better to do.
+ userrec* oper = *i;
+ strcpy(tmp, "");
+ if (strcmp(oper->awaymsg, "")) {
+ strlcat(tmp, "G" ,9);
+ } else {
+ strlcat(tmp, "H" ,9);
+ }
+ WriteServ(user->fd,"352 %s %s %s %s %s %s %s* :0 %s", user->nick, oper->chans[0].channel ? oper->chans[0].channel->name
+ : "*", oper->ident, oper->dhost, oper->server, oper->nick, tmp, oper->fullname);
}
WriteServ(user->fd,"315 %s %s :End of /WHO list.",user->nick, parameters[0]);
return;
void handle_list(char **parameters, int pcnt, userrec *user)
{
- chanrec* Ptr;
-
WriteServ(user->fd,"321 %s Channel :Users Name",user->nick);
for (chan_hash::const_iterator i = chanlist.begin(); i != chanlist.end(); i++)
{
- if ((!i->second->c_private) && (!i->second->secret))
+ // if the channel is not private/secret, OR the user is on the channel anyway
+ if (((!(i->second->binarymodes & CM_PRIVATE)) && (!(i->second->binarymodes & CM_SECRET))) || (has_channel(user,i->second)))
{
WriteServ(user->fd,"322 %s %s %d :[+%s] %s",user->nick,i->second->name,usercount_i(i->second),chanmodes(i->second),i->second->topic);
}
void handle_whowas(char **parameters, int pcnt, userrec* user)
{
- user_hash::iterator i = whowas.find(parameters[0]);
+ whowas_hash::iterator i = whowas.find(parameters[0]);
if (i == whowas.end())
{
strlcat(flagstate,", common",MAXBUF);
if (V.Flags & VF_SERVICEPROVIDER)
strlcat(flagstate,", service provider",MAXBUF);
- if (!strlen(flagstate))
+ if (!flagstate[0])
strcpy(flagstate," <no flags>");
strlcpy(modulename,module_names[i].c_str(),256);
if (strchr(user->modes,'o'))
WriteServ(user->fd,"900 %s :%s",user->nick,CleanFilename(modulename));
}
}
+ WriteServ(user->fd,"901 %s :End of MODULES list",user->nick);
}
void handle_stats(char **parameters, int pcnt, userrec *user)
FOREACH_MOD OnStats(*parameters[0]);
- if (!strcasecmp(parameters[0],"c"))
+ if (*parameters[0] == 'c')
{
for (int i = 0; i < ConfValueEnum("link",&config_f); i++)
{
}
}
- if (!strcasecmp(parameters[0],"i"))
+ if (*parameters[0] == 'i')
{
int idx = 0;
for (ClassVector::iterator i = Classes.begin(); i != Classes.end(); i++)
}
}
- if (!strcasecmp(parameters[0],"y"))
+ if (*parameters[0] == 'y')
{
int idx = 0;
for (ClassVector::iterator i = Classes.begin(); i != Classes.end(); i++)
}
}
- if (!strcmp(parameters[0],"U"))
+ if (*parameters[0] == 'U')
{
for (int i = 0; i < ConfValueEnum("uline",&config_f); i++)
{
}
}
- if (!strcmp(parameters[0],"P"))
+ if (*parameters[0] == 'P')
{
int idx = 0;
for (user_hash::iterator i = clientlist.begin(); i != clientlist.end(); i++)
//249 [Brain] :bwoadway-monitor (~wgmon@204.152.186.58) Idle: 18
}
- if (!strcmp(parameters[0],"k"))
+ if (*parameters[0] == 'k')
{
stats_k(user);
}
- if (!strcmp(parameters[0],"g"))
+ if (*parameters[0] == 'g')
{
stats_g(user);
}
- if (!strcmp(parameters[0],"q"))
+ if (*parameters[0] == 'q')
{
stats_q(user);
}
- if (!strcmp(parameters[0],"Z"))
+ if (*parameters[0] == 'Z')
{
stats_z(user);
}
- if (!strcmp(parameters[0],"e"))
+ if (*parameters[0] == 'e')
{
stats_e(user);
}
/* stats m (list number of times each command has been used, plus bytecount) */
- if (!strcmp(parameters[0],"m"))
+ if (*parameters[0] == 'm')
{
for (int i = 0; i < cmdlist.size(); i++)
{
}
/* stats z (debug and memory info) */
- if (!strcmp(parameters[0],"z"))
+ if (*parameters[0] == 'z')
{
+ rusage R;
WriteServ(user->fd,"249 %s :Users(HASH_MAP) %d (%d bytes, %d buckets)",user->nick,clientlist.size(),clientlist.size()*sizeof(userrec),clientlist.bucket_count());
WriteServ(user->fd,"249 %s :Channels(HASH_MAP) %d (%d bytes, %d buckets)",user->nick,chanlist.size(),chanlist.size()*sizeof(chanrec),chanlist.bucket_count());
WriteServ(user->fd,"249 %s :Commands(VECTOR) %d (%d bytes)",user->nick,cmdlist.size(),cmdlist.size()*sizeof(command_t));
WriteServ(user->fd,"249 %s :Modules(VECTOR) %d (%d)",user->nick,modules.size(),modules.size()*sizeof(Module));
WriteServ(user->fd,"249 %s :ClassFactories(VECTOR) %d (%d)",user->nick,factory.size(),factory.size()*sizeof(ircd_module));
WriteServ(user->fd,"249 %s :Ports(STATIC_ARRAY) %d",user->nick,boundPortCount);
+ if (!getrusage(RUSAGE_SELF,&R))
+ {
+ WriteServ(user->fd,"249 %s :Total allocation: %luK (0x%lx)",user->nick,R.ru_maxrss,R.ru_maxrss);
+ WriteServ(user->fd,"249 %s :Signals: %lu (0x%lx)",user->nick,R.ru_nsignals,R.ru_nsignals);
+ WriteServ(user->fd,"249 %s :Page faults: %lu (0x%lx)",user->nick,R.ru_majflt,R.ru_majflt);
+ WriteServ(user->fd,"249 %s :Swaps: %lu (0x%lx)",user->nick,R.ru_nswap,R.ru_nswap);
+ WriteServ(user->fd,"249 %s :Context Switches: %lu (0x%lx)",user->nick,R.ru_nvcsw+R.ru_nivcsw,R.ru_nvcsw+R.ru_nivcsw);
+ }
+ }
+
+ if (*parameters[0] == 'T')
+ {
+ WriteServ(user->fd,"249 Brain :accepts %d refused %d",statsAccept,statsRefused);
+ WriteServ(user->fd,"249 Brain :unknown commands %d",statsUnknown);
+ WriteServ(user->fd,"249 Brain :nick collisions %d",statsCollisions);
+ WriteServ(user->fd,"249 Brain :dns requests %d succeeded %d failed %d",statsDns,statsDnsGood,statsDnsBad);
+ WriteServ(user->fd,"249 Brain :connections %d",statsConnects);
+ WriteServ(user->fd,"249 Brain :bytes sent %dK recv %dK",(statsSent / 1024),(statsRecv / 1024));
}
/* stats o */
- if (!strcmp(parameters[0],"o"))
+ if (*parameters[0] == 'o')
{
for (int i = 0; i < ConfValueEnum("oper",&config_f); i++)
{
}
/* stats l (show user I/O stats) */
- if (!strcmp(parameters[0],"l"))
+ if (*parameters[0] == 'l')
{
WriteServ(user->fd,"211 %s :server:port nick bytes_in cmds_in bytes_out cmds_out",user->nick);
for (user_hash::iterator i = clientlist.begin(); i != clientlist.end(); i++)
}
/* stats u (show server uptime) */
- if (!strcmp(parameters[0],"u"))
+ if (*parameters[0] == 'u')
{
time_t current_time = 0;
current_time = TIME;
}
else
{
- WriteServ(user->fd,"NOTICE :*** Remote SQUIT not supported yet.");
+ if (!strcasecmp("*",parameters[0]))
+ {
+ WriteServ(user->fd,"NOTICE %s :*** You cannot issue an SQUIT this wide! If this is REALLY what you want, use a less wide mask.",user->nick);
+ WriteOpers("*** WARNING! %s tried to SQUIT all servers at once!",user->nick);
+ return;
+ }
+ if (!strcasecmp(ServerName,parameters[0]))
+ {
+ WriteServ(user->fd,"NOTICE %s :*** To take the local server out of the mesh, just use /SQUIT with no parameters instead.",user->nick);
+ return;
+ }
+ bool have_this_server = true;
+ int n_count = 0;
+ std::string server_to_squit = "";
+ while (have_this_server)
+ {
+ have_this_server = false;
+ for (int j = 0; j < 32; j++)
+ {
+ if (me[j] != NULL)
+ {
+ for (int x = 0; x < me[j]->connectors.size(); x++)
+ {
+ if (match(me[j]->connectors[x].GetServerName().c_str(),parameters[0]))
+ {
+ // found a valid ircd_connector.
+ have_this_server = true;
+ server_to_squit = me[j]->connectors[x].GetServerName().c_str();
+ break;
+ }
+ }
+ }
+ }
+ if (have_this_server)
+ {
+ WriteOpers("SQUIT command issued by %s to remove %s from the mesh",user->nick,server_to_squit.c_str());
+ WriteServ(user->fd,"NOTICE %s :*** Removing remote server %s.",user->nick,server_to_squit.c_str());
+ char buffer[MAXBUF];
+ snprintf(buffer,MAXBUF,"& %s",server_to_squit.c_str());
+ NetSendToAll(buffer);
+ DoSplit(server_to_squit.c_str());
+ n_count++;
+ }
+ }
+ if (!n_count)
+ {
+ WriteServ(user->fd,"402 %s %s :Your pattern did not match any servers.",user->nick,parameters[0]);
+ }
}
}
bool is_uline(const char* server)
{
+ if (!server)
+ return false;
+ if (!(*server))
+ return true;
char ServName[MAXBUF];
- int i,j;
-
for (int i = 0; i < ConfValueEnum("uline",&config_f); i++)
{
ConfValue("uline","server",i,ServName,&config_f);
{
int MOD_RESULT = 0;
FOREACH_RESULT(OnOperCompare(data,input))
+ log(DEBUG,"operstrcmp: %d",MOD_RESULT);
if (MOD_RESULT == 1)
return 0;
if (MOD_RESULT == -1)
return 1;
+ log(DEBUG,"strcmp fallback: '%s' '%s' %d",data,input,strcmp(data,input));
return strcmp(data,input);
}
char TypeName[MAXBUF];
char HostName[MAXBUF];
char TheHost[MAXBUF];
- int i,j;
+ int j;
bool found = false;
bool fail2 = false;
char global[MAXBUF];
NetSendToAll(global);
FOREACH_MOD OnOper(user);
log(DEFAULT,"OPER: %s!%s@%s opered as type: %s",user->nick,user->ident,user->host,OperType);
+ AddOper(user);
}
}
else
log(DEBUG,"invalid parameter passed to handle_nick");
return;
}
- if (!strlen(parameters[0]))
+ if (!parameters[0][0])
{
log(DEBUG,"zero length new nick passed to handle_nick");
return;
WriteCommon(user,"NICK %s",parameters[0]);
- // Q token must go to ALL servers!!!
+ // N token must go to ALL servers!!!
char buffer[MAXBUF];
snprintf(buffer,MAXBUF,"n %s %s",user->nick,parameters[0]);
NetSendToAll(buffer);
}
+void handle_v(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
+{
+ char* servername = strtok(params," ");
+ char* versionstr = strtok(NULL,"\r\n");
+
+ if ((!servername) || (!versionstr))
+ return;
+
+ for (int j = 0; j < 32; j++)
+ {
+ if (me[j] != NULL)
+ {
+ for (int x = 0; x < me[j]->connectors.size(); x++)
+ {
+ if (!strcasecmp(me[j]->connectors[x].GetServerName().c_str(),servername))
+ {
+ me[j]->connectors[x].SetVersionString(versionstr);
+ WriteOpers("Server '%s' (%d:%d) announces itself as version '%s'",me[j]->connectors[x].GetServerName().c_str(),j,x,me[j]->connectors[x].GetVersionString().c_str());
+ }
+ }
+ }
+ }
+}
-void handle_V(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_V(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
char* src = strtok(params," ");
char* dest = strtok(NULL," :");
char* text = strtok(NULL,"\r\n");
+
+ if ((!src) || (!dest) || (!text))
+ return;
+
text++;
userrec* user = Find(src);
if (user)
{
- userrec* dst = Find(dest);
-
- if (dst)
+ // notice all - only issuable by a server
+ if (!strcmp(dest,"*"))
+ {
+ NoticeAll(user,true,"%s",text);
+ }
+ if (!strcmp(dest,"@*"))
{
- WriteTo(user, dst, "NOTICE %s :%s", dst->nick, text);
+ NoticeAllOpers(user,true,"%s",text);
}
else
{
- chanrec* d = FindChan(dest);
- if (d)
+ userrec* dst = Find(dest);
+ if (dst)
{
- ChanExceptSender(d, user, "NOTICE %s :%s", d->name, text);
+ WriteTo(user, dst, "NOTICE %s :%s", dst->nick, text);
+ }
+ else
+ {
+ chanrec* d = FindChan(dest);
+ if (d)
+ {
+ ChanExceptSender(d, user, "NOTICE %s :%s", d->name, text);
+ }
}
}
}
}
-void handle_P(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_P(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
char* src = strtok(params," ");
char* dest = strtok(NULL," :");
char* text = strtok(NULL,"\r\n");
+
+ if ((!src) || (!dest) || (!text))
+ return;
+
text++;
userrec* user = Find(src);
}
-void handle_i(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_i(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
char* nick = strtok(params," ");
char* from = strtok(NULL," ");
char* channel = strtok(NULL," ");
+
+ if ((!nick) || (!from) || (!channel))
+ return;
+
userrec* u = Find(nick);
userrec* user = Find(from);
chanrec* c = FindChan(channel);
}
}
-void handle_t(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_t(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
char* setby = strtok(params," ");
char* channel = strtok(NULL," :");
char* topic = strtok(NULL,"\r\n");
+
+ if ((!setby) || (!channel) || (!topic))
+ return;
+
topic++;
userrec* u = Find(setby);
chanrec* c = FindChan(channel);
}
-void handle_T(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_T(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
char* tm = strtok(params," ");
char* setby = strtok(NULL," ");
char* channel = strtok(NULL," :");
char* topic = strtok(NULL,"\r\n");
+
+ if ((!tm) || (!setby) || (!channel) || (!topic))
+ return;
+
topic++;
time_t TS = atoi(tm);
chanrec* c = FindChan(channel);
}
}
-void handle_M(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_M(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
char* pars[128];
char original[MAXBUF],target[MAXBUF];
strlcpy(original,params,MAXBUF);
int index = 0;
char* parameter = strtok(params," ");
+
+ if (!parameter)
+ return;
+
strlcpy(target,parameter,MAXBUF);
while (parameter)
{
pars[index++] = parameter;
parameter = strtok(NULL," ");
}
- log(DEBUG,"*** MODE: %s %s",pars[0],pars[1]);
+ log(DEBUG,"*** MODE: '%s %s'",pars[0],pars[1]);
merge_mode(pars,index);
if (FindChan(target))
{
WriteChannelLocal(FindChan(target), NULL, "MODE %s",original);
+ return;
}
if (Find(target))
{
- Write(Find(target)->fd,":%s MODE %s",ServerName,original);
+ if (original[0])
+ Write(Find(target)->fd,":%s MODE %s",ServerName,original);
}
}
// m is modes set by users only (not servers) valid targets are channels or users.
-void handle_m(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_m(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
// m blah #chatspike +b *!test@*4
char* pars[128];
char original[MAXBUF];
+
+ if (!params)
+ return;
+
strlcpy(original,params,MAXBUF);
if (!strchr(params,' '))
int index = 0;
char* src = strtok(params," ");
+
+ if (!src)
+ return;
+
userrec* user = Find(src);
if (user)
}
log(DEBUG,"Calling merge_mode2");
- merge_mode2(pars,index,user);
+ if (index)
+ merge_mode2(pars,index,user);
}
}
-void handle_L(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_L(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
char* nick = NULL;
char* channel = NULL;
{
nick = strtok(params," ");
channel = strtok(NULL,"\r\n");
+ if ((!nick) || (!channel))
+ return;
channel++;
reason = "";
}
nick = strtok(params," ");
channel = strtok(NULL," :");
reason = strtok(NULL,"\r\n");
+ if ((!nick) || (!channel) || (!reason))
+ return;
reason++;
}
userrec* user = Find(nick);
}
}
-void handle_K(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_K(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
char* src = strtok(params," ");
char* nick = strtok(NULL," :");
char* reason = strtok(NULL,"\r\n");
+ if ((!src) || (!nick) || (!reason))
+ return;
char kreason[MAXBUF];
reason++;
if ((user) && (u))
{
- WriteTo(user, u, "KILL %s :%s!%s!%s!%s (%s)", u->nick, source->name, ServerName, user->dhost,user->nick,reason);
- WriteOpers("*** Remote kill from %s by %s: %s!%s@%s (%s)",source->name,user->nick,u->nick,u->ident,u->host,reason);
- snprintf(kreason,MAXBUF,"[%s] Killed (%s (%s))",source->name,user->nick,reason);
+ WriteTo(user, u, "KILL %s :%s!%s!%s!%s (%s)", u->nick, tcp_host, ServerName, user->dhost,user->nick,reason);
+ WriteOpers("*** Remote kill from %s by %s: %s!%s@%s (%s)",tcp_host,user->nick,u->nick,u->ident,u->host,reason);
+ snprintf(kreason,MAXBUF,"[%s] Killed (From: '%s' (%s))",tcp_host,user->nick,reason);
kill_link(u,kreason);
}
}
-void handle_Q(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_Q(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
char* nick = strtok(params," :");
char* reason = strtok(NULL,"\r\n");
+
+ if ((!nick) || (!reason))
+ return;
reason++;
userrec* user = Find(nick);
if (iter != clientlist.end())
{
log(DEBUG,"deleting user hash value %d",iter->second);
- if ((iter->second) && (user->registered == 7)) {
- delete iter->second;
- }
clientlist.erase(iter);
}
- purge_empty_chans();
+ if (user->registered == 7)
+ {
+ purge_empty_chans(user);
+ }
+ delete user;
}
}
-void handle_n(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_n(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
char* oldnick = strtok(params," ");
char* newnick = strtok(NULL," ");
+
+ if ((!oldnick) || (!newnick))
+ return;
userrec* user = Find(oldnick);
-
+
if (user)
{
- WriteCommon(user,"NICK %s",newnick);
if (is_uline(tcp_host))
{
int MOD_RESULT = 0;
FOREACH_RESULT(OnUserPreNick(user,newnick));
if (MOD_RESULT) {
// if a module returns true, the nick change couldnt be allowed
+ statsCollisions++;
kill_link(user,"Nickname collision");
return;
}
if (matches_qline(newnick))
{
+ statsCollisions++;
kill_link(user,"Nickname collision");
return;
}
// broadcast this because its a services thingy
char buffer[MAXBUF];
snprintf(buffer,MAXBUF,"n %s %s",user->nick,newnick);
- NetSendToAll(buffer);
+ NetSendToAllExcept_WithSum(tcp_host,buffer,tcp_sum);
}
+ WriteCommon(user,"NICK %s",newnick);
user = ReHashNick(user->nick, newnick);
if (!user) return;
if (!user->nick) return;
}
// k <SOURCE> <DEST> <CHANNEL> :<REASON>
-void handle_k(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_k(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
char* src = strtok(params," ");
char* dest = strtok(NULL," ");
char* channel = strtok(NULL," :");
char* reason = strtok(NULL,"\r\n");
+
+ if ((!src) || (!dest) || (!channel) || (!reason))
+ return;
+
reason++;
userrec* s = Find(src);
userrec* d = Find(dest);
}
}
-void handle_AT(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_AT(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
char* who = strtok(params," :");
char* text = strtok(NULL,"\r\n");
+
+ if ((!who) || (!text))
+ return;
+
text++;
userrec* s = Find(who);
if (s)
}
}
-void handle_H(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_H(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
log(DEBUG,"Adding ULined server %s to my map",params);
ircd_connector s;
s.SetState(STATE_DISCONNECTED);
+
+ if (!params)
+ return;
+
s.SetServerName(params);
for (int j = 0; j < 32; j++)
WriteOpers("Non-Mesh server %s has joined the network",params);
}
-void handle_N(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_N(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
char* tm = strtok(params," ");
char* nick = strtok(NULL," ");
char* ipaddr = strtok(NULL," ");
char* server = strtok(NULL," :");
char* gecos = strtok(NULL,"\r\n");
- gecos++;
- modes++;
+
+ if ((!tm) || (!nick) || (!host) || (!dhost) || (!ident) || (!modes) || (!ipaddr) || (!server) || (!gecos))
+ return;
+
+ if (*gecos == ':')
+ gecos++;
+
+ if (*modes == '+')
+ modes++;
+
time_t TS = atoi(tm);
user_hash::iterator iter = clientlist.find(nick);
if (iter != clientlist.end())
{
// nick collision
+ statsCollisions++;
WriteOpers("Nickname collision: %s@%s != %s@%s",nick,server,iter->second->nick,iter->second->server);
char str[MAXBUF];
snprintf(str,MAXBUF,"Killed (Nick Collision (%s@%s < %s@%s))",nick,server,iter->second->nick,iter->second->server);
strlcpy(clientlist[nick]->server, server,256);
strlcpy(clientlist[nick]->ident, ident,10); // +1 char to compensate for tilde
strlcpy(clientlist[nick]->fullname, gecos,128);
+ strlcpy(clientlist[nick]->ip,ipaddr,16);
clientlist[nick]->signon = TS;
clientlist[nick]->nping = 0; // this is ignored for a remote user anyway.
clientlist[nick]->lastping = 1;
clientlist[nick]->idle_lastmsg = TIME; // this is unrealiable and wont actually be used locally
for (int i = 0; i < MAXCHANS; i++)
{
- clientlist[nick]->chans[i].channel = NULL;
- clientlist[nick]->chans[i].uc_modes = 0;
- }
+ clientlist[nick]->chans[i].channel = NULL;
+ clientlist[nick]->chans[i].uc_modes = 0;
+ }
+ FOREACH_MOD OnGlobalConnect(clientlist[nick]);
+ if (strchr(clientlist[nick]->modes,'o'))
+ {
+ FOREACH_MOD OnGlobalOper(clientlist[nick]);
+ }
}
-void handle_F(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_F(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
+ if (!params)
+ return;
long tdiff = TIME - atoi(params);
if (tdiff)
WriteOpers("TS split for %s -> %s: %d",source->name,reply->name,tdiff);
}
-void handle_a(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_a(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
char* nick = strtok(params," :");
char* gecos = strtok(NULL,"\r\n");
+
+ if ((!nick) || (!gecos))
+ return;
userrec* user = Find(nick);
strlcpy(user->fullname,gecos,MAXBUF);
}
-void handle_b(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_b(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
char* nick = strtok(params," ");
char* host = strtok(NULL," ");
+
+ if ((!nick) || (!host))
+ return;
userrec* user = Find(nick);
strlcpy(user->dhost,host,160);
}
-void handle_plus(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_plus(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
// %s %s %d %d
// + test3.chatspike.net 7010 -2016508415
char* ipaddr = strtok(NULL," ");
char* ipport = strtok(NULL," ");
char* cookie = strtok(NULL," ");
+
+ if ((!servername) || (!ipaddr) || (!ipport) || (!cookie))
+ return;
+
log(DEBUG,"*** Connecting back to %s:%d",ipaddr,atoi(ipport));
me[defaultRoute]->MeshCookie(ipaddr,atoi(ipport),atoi(cookie),servername);
}
-void handle_R(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_R(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
char* server = strtok(params," ");
char* data = strtok(NULL,"\r\n");
+
if ((!data) || (!server))
{
log(DEBUG,"Someones playing silly buggers, attempting to send to a null server or send a null message (BUG?)");
NetSendToOne(server,data);
}
-void handle_J(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_J(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
- // IMPORTANT NOTE
- // The J token currently has no timestamp - this needs looking at
- // because it will allow splitriding.
char* nick = strtok(params," ");
char* channel = strtok(NULL," ");
+
+ if ((!nick) || (!channel))
+ return;
+
userrec* user = Find(nick);
+
while (channel)
{
if ((user != NULL) && (strcmp(channel,"")))
}
}
-void handle_dollar(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_dollar(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
log(DEBUG,"Storing routing table...");
char* sourceserver = strtok(params," ");
char* server = strtok(NULL," ");
+
+ if ((!sourceserver) || (!server))
+ return;
+
for (int i = 0; i < 32; i++)
{
if (me[i] != NULL)
log(DEBUG,"Warning! routing table received from nonexistent server!");
}
-void handle_amp(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_amp(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
+ if (!params)
+ return;
+
log(DEBUG,"Netsplit! %s split from mesh, removing!",params);
WriteOpers("*** NOTICE - Controlled netsplit: %s split from %s",params,ServerName);
bool go_again = true;
}
}
-long authcookie;
+unsigned long authcookie;
-void handle_hash(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_hash(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
// # <mask> <who-set-it> <time-set> <duration> :<reason>
log(DEBUG,"Adding G-line");
char* create_time = strtok(NULL," ");
char* duration = strtok(NULL," :");
char* reason = strtok(NULL,"\r\n");
+
+ if ((!mask) || (!who) || (!create_time) || (!duration) || (!reason))
+ return;
+
+ reason++;
add_gline(atoi(duration),(const char*)who,(const char*)reason,(const char*)mask);
// we must update the creation time on this gline
// now that we've added it, or it wont expire at the right time.
apply_lines();
}
-void handle_dot(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_dot(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
log(DEBUG,"Removing G-line");
char* mask = strtok(params," ");
char* who = strtok(NULL," ");
+
+ if ((!mask) || (!who))
+ return;
+
if (mask)
{
if (del_gline((const char*)mask))
}
}
-void handle_add_sqline(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_add_sqline(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
// { <mask> <who-set-it> <time-set> <duration> :<reason>
log(DEBUG,"Adding Q-line");
char* create_time = strtok(NULL," ");
char* duration = strtok(NULL," :");
char* reason = strtok(NULL,"\r\n");
+
+ if ((!mask) || (!who) || (!create_time) || (!duration) || (!reason))
+ return;
+
+ reason++;
add_qline(atoi(duration),(const char*)who,(const char*)reason,(const char*)mask);
// we must update the creation time on this gline
// now that we've added it, or it wont expire at the right time.
apply_lines();
}
-void handle_del_sqline(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_del_sqline(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
log(DEBUG,"Removing Q-line");
char* mask = strtok(params," ");
char* who = strtok(NULL," ");
+
+ if ((!mask) || (!who))
+ return;
+
if (mask)
{
if (del_qline((const char*)mask))
}
}
-void handle_add_szline(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_add_szline(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
// } <mask> <who-set-it> <time-set> <duration> :<reason>
log(DEBUG,"Adding Z-line");
char* create_time = strtok(NULL," ");
char* duration = strtok(NULL," :");
char* reason = strtok(NULL,"\r\n");
+
+ if ((!mask) || (!who) || (!create_time) || (!duration) || (!reason))
+ return;
+
+ reason++;
add_zline(atoi(duration),(const char*)who,(const char*)reason,(const char*)mask);
// we must update the creation time on this gline
// now that we've added it, or it wont expire at the right time.
apply_lines();
}
-void handle_del_szline(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_del_szline(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
log(DEBUG,"Removing Z-line");
char* mask = strtok(params," ");
char* who = strtok(NULL," ");
+
+ if ((!mask) || (!who))
+ return;
+
if (mask)
{
if (del_zline((const char*)mask))
}
}
-void handle_pipe(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host)
+void handle_pipe(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
char* nick = strtok(params," ");
char* type = strtok(params," ");
+
+ if ((!nick) || (!type))
+ return;
+
userrec* u = Find(nick);
if (u)
{
}
-void process_restricted_commands(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host,char* ipaddr,int port)
+void process_restricted_commands(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host,char* ipaddr,int port,char* tcp_sum)
{
char buffer[MAXBUF];
int MOD_RESULT = 0;
// now broadcast this new servers address out to all servers that are linked to us,
// except the newcomer. They'll all attempt to connect back to it.
authcookie = rand()*rand();
- snprintf(buffer,MAXBUF,"~ %d",authcookie);
- NetSendToAll(buffer);
+ snprintf(buffer,MAXBUF,"~ %lu",(unsigned long)authcookie);
+ NetSendToAll_WithSum(buffer,tcp_sum);
break;
// ~
// Store authcookie
break;
// connect back to a server using an authcookie
case '+':
- handle_plus(token,params,source,reply,tcp_host);
+ handle_plus(token,params,source,reply,tcp_host,tcp_sum);
break;
// routing table
case '$':
- handle_dollar(token,params,source,reply,tcp_host);
+ handle_dollar(token,params,source,reply,tcp_host,tcp_sum);
break;
// node unreachable - we cant route to a server, sooooo we slit it off.
// servers can generate these for themselves for an squit.
case '&':
- handle_amp(token,params,source,reply,tcp_host);
+ handle_amp(token,params,source,reply,tcp_host,tcp_sum);
break;
// R <server> <data>
// redirect token, send all of <data> along to the given
// server as this server has been found to still have a route to it
case 'R':
- handle_R(token,params,source,reply,tcp_host);
+ handle_R(token,params,source,reply,tcp_host,tcp_sum);
break;
// ?
// ping
// no operation
case '*':
break;
+ // no operation - reserved to prevent services issues
+ case ':':
+ break;
// N <TS> <NICK> <HOST> <DHOST> <IDENT> <MODES> <SERVER> :<GECOS>
// introduce remote client
case 'N':
- handle_N(token,params,source,reply,tcp_host);
+ handle_N(token,params,source,reply,tcp_host,tcp_sum);
break;
// a <NICK> :<GECOS>
// change GECOS (SETNAME)
case 'a':
- handle_a(token,params,source,reply,tcp_host);
+ handle_a(token,params,source,reply,tcp_host,tcp_sum);
break;
// b <NICK> :<HOST>
// change displayed host (SETHOST)
case 'b':
- handle_b(token,params,source,reply,tcp_host);
+ handle_b(token,params,source,reply,tcp_host,tcp_sum);
break;
// t <NICK> <CHANNEL> :<TOPIC>
// change a channel topic
case 't':
- handle_t(token,params,source,reply,tcp_host);
+ handle_t(token,params,source,reply,tcp_host,tcp_sum);
break;
// i <NICK> <CHANNEL>
// invite a user to a channel
case 'i':
- handle_i(token,params,source,reply,tcp_host);
+ handle_i(token,params,source,reply,tcp_host,tcp_sum);
break;
// k <SOURCE> <DEST> <CHANNEL> :<REASON>
// kick a user from a channel
case 'k':
- handle_k(token,params,source,reply,tcp_host);
+ handle_k(token,params,source,reply,tcp_host,tcp_sum);
break;
// n <NICK> <NEWNICK>
// change nickname of client -- a server should only be able to
// change the nicknames of clients that reside on it unless
// they are ulined.
case 'n':
- handle_n(token,params,source,reply,tcp_host);
+ handle_n(token,params,source,reply,tcp_host,tcp_sum);
break;
// J <NICK> <CHANLIST>
// Join user to channel list, merge channel permissions
case 'J':
- handle_J(token,params,source,reply,tcp_host);
+ handle_J(token,params,source,reply,tcp_host,tcp_sum);
break;
// T <TS> <CHANNEL> <TOPICSETTER> :<TOPIC>
// change channel topic (netburst only)
case 'T':
- handle_T(token,params,source,reply,tcp_host);
+ handle_T(token,params,source,reply,tcp_host,tcp_sum);
break;
// M <TARGET> <MODES> [MODE-PARAMETERS]
// Server setting modes on an object
case 'M':
- handle_M(token,params,source,reply,tcp_host);
+ handle_M(token,params,source,reply,tcp_host,tcp_sum);
break;
// m <SOURCE> <TARGET> <MODES> [MODE-PARAMETERS]
// User setting modes on an object
case 'm':
- handle_m(token,params,source,reply,tcp_host);
+ handle_m(token,params,source,reply,tcp_host,tcp_sum);
break;
// P <SOURCE> <TARGET> :<TEXT>
// Send a private/channel message
case 'P':
- handle_P(token,params,source,reply,tcp_host);
+ handle_P(token,params,source,reply,tcp_host,tcp_sum);
break;
// V <SOURCE> <TARGET> :<TEXT>
// Send a private/channel notice
case 'V':
- handle_V(token,params,source,reply,tcp_host);
+ handle_V(token,params,source,reply,tcp_host,tcp_sum);
+ break;
+ // v <servername> <arbitary version string>
+ case 'v':
+ handle_v(token,params,source,reply,tcp_host,tcp_sum);
break;
// L <SOURCE> <CHANNEL> :<REASON>
// User parting a channel
case 'L':
- handle_L(token,params,source,reply,tcp_host);
+ handle_L(token,params,source,reply,tcp_host,tcp_sum);
break;
// Q <SOURCE> :<REASON>
// user quitting
case 'Q':
- handle_Q(token,params,source,reply,tcp_host);
+ handle_Q(token,params,source,reply,tcp_host,tcp_sum);
break;
// H <SERVER>
// introduce non-meshable server (such as a services server)
case 'H':
- handle_H(token,params,source,reply,tcp_host);
+ handle_H(token,params,source,reply,tcp_host,tcp_sum);
break;
// K <SOURCE> <DEST> :<REASON>
// remote kill
case 'K':
- handle_K(token,params,source,reply,tcp_host);
+ handle_K(token,params,source,reply,tcp_host,tcp_sum);
break;
// @ <SOURCE> :<TEXT>
// wallops
case '@':
- handle_AT(token,params,source,reply,tcp_host);
+ handle_AT(token,params,source,reply,tcp_host,tcp_sum);
break;
// # <mask> <who-set-it> <time-set> <duration> :<reason>
// add gline
case '#':
- handle_hash(token,params,source,reply,tcp_host);
+ handle_hash(token,params,source,reply,tcp_host,tcp_sum);
break;
// . <mask> <who>
// remove gline
case '.':
- handle_dot(token,params,source,reply,tcp_host);
+ handle_dot(token,params,source,reply,tcp_host,tcp_sum);
break;
// # <mask> <who-set-it> <time-set> <duration> :<reason>
// add gline
case '{':
- handle_add_sqline(token,params,source,reply,tcp_host);
+ handle_add_sqline(token,params,source,reply,tcp_host,tcp_sum);
break;
// . <mask> <who>
// remove gline
case '[':
- handle_del_sqline(token,params,source,reply,tcp_host);
+ handle_del_sqline(token,params,source,reply,tcp_host,tcp_sum);
break;
// # <mask> <who-set-it> <time-set> <duration> :<reason>
// add gline
case '}':
- handle_add_szline(token,params,source,reply,tcp_host);
+ handle_add_szline(token,params,source,reply,tcp_host,tcp_sum);
break;
// . <mask> <who>
// remove gline
case ']':
- handle_del_szline(token,params,source,reply,tcp_host);
+ handle_del_szline(token,params,source,reply,tcp_host,tcp_sum);
break;
// | <nick> <opertype>
// set opertype
case '|':
- handle_pipe(token,params,source,reply,tcp_host);
+ handle_pipe(token,params,source,reply,tcp_host,tcp_sum);
break;
// F <TS>
// end netburst
case 'F':
WriteOpers("Server %s has completed netburst. (%d secs)",tcp_host,TIME-nb_start);
- handle_F(token,params,source,reply,tcp_host);
+ handle_F(token,params,source,reply,tcp_host,tcp_sum);
nb_start = 0;
// tell all the other servers to use this authcookie to connect back again
// got '+ test3.chatspike.net 7010 -2016508415' from test.chatspike.net
- snprintf(buffer,MAXBUF,"+ %s %s %d %d",tcp_host,ipaddr,port,authcookie);
- NetSendToAllExcept(tcp_host,buffer);
+ snprintf(buffer,MAXBUF,"+ %s %s %d %lu",tcp_host,ipaddr,port,(unsigned long)authcookie);
+ NetSendToAllExcept_WithSum(tcp_host,buffer,tcp_sum);
break;
case '/':
WriteOpers("Server %s is IRCServices-based server (assumes-SVSMODE) - Nickname Services: %s",tcp_host,params);
// end netburst with no mesh creation
case 'f':
WriteOpers("Server %s has completed netburst. (%d secs)",tcp_host,TIME-nb_start);
- handle_F(token,params,source,reply,tcp_host);
+ handle_F(token,params,source,reply,tcp_host,tcp_sum);
nb_start = 0;
// tell everyone else about the new server name so they just add it in the disconnected
// state
snprintf(buffer,MAXBUF,"u %s :%s",tcp_host,GetServerDescription(tcp_host).c_str());
- NetSendToAllExcept(tcp_host,buffer);
+ NetSendToAllExcept_WithSum(tcp_host,buffer,tcp_sum);
break;
// X <reserved>
// Send netburst now
}
-void handle_link_packet(char* udp_msg, char* tcp_host, serverrec *serv)
+void handle_link_packet(char* tcp_msg, char* tcp_host, serverrec *serv,char* tcp_sum)
{
- if ((!strncmp(udp_msg,"USER ",5)) || (!strncmp(udp_msg,"NICK ",5)))
+ if ((!strncmp(tcp_msg,"USER ",5)) || (!strncmp(tcp_msg,"NICK ",5)) || (!strncmp(tcp_msg,"PASS ",5)) || (!strncmp(tcp_msg,"SERVER ",7)))
{
// a user on a server port, just close their connection.
RemoveServer(tcp_host);
}
char response[10240];
- char old2[MAXBUF];
- char token = udp_msg[0];
- char* old = udp_msg;
+ char token = tcp_msg[0];
+ char* old = tcp_msg;
+
+ if (!strncmp(tcp_msg,"PING",4))
+ {
+ // some muppet of a server is sending PING. We don't know what PING is. drop it silently.
+ return;
+ }
- if ((token != ':') && (strlen(udp_msg)>1) && (udp_msg[1] != ' '))
+ if ((token != ':') && (strlen(tcp_msg)>1) && (tcp_msg[1] != ' '))
{
- WriteOpers("*** Discarded %d chars illegal data from %s",strlen(udp_msg),tcp_host);
+ WriteOpers("*** Discarded %d chars illegal data from %s",strlen(tcp_msg),tcp_host);
}
if (token == ':') // leading :servername or details - strip them off (services does this, sucky)
{
- char* src = udp_msg+1;
- while (udp_msg[0] != ' ')
- udp_msg++;
- udp_msg[0] = 0;
- udp_msg++;
- char* comd = udp_msg;
- while (udp_msg[0] != ' ')
- udp_msg++;
- udp_msg[0] = 0;
- udp_msg++;
+ char* src = tcp_msg+1;
+ while (tcp_msg[0] != ' ')
+ tcp_msg++;
+ tcp_msg[0] = 0;
+ tcp_msg++;
+ char* comd = tcp_msg;
+ while (tcp_msg[0] != ' ')
+ tcp_msg++;
+ tcp_msg[0] = 0;
+ tcp_msg++;
char data[MAXBUF];
char source[MAXBUF];
char command[MAXBUF];
- strlcpy(data,udp_msg,512);
+ strlcpy(data,tcp_msg,512);
strlcpy(source,src,MAXBUF);
strlcpy(command,comd,MAXBUF);
- udp_msg = old;
+ tcp_msg = old;
// unused numeric:
// :services-dev.chatspike.net 433 Craig Craig :Nickname is registered to someone else
}
if (!strcmp(command,"NOTICE"))
{
- snprintf(udp_msg,MAXBUF,"V %s %s",source,data);
- log(DEBUG,"Rewrote NOTICE from services to: '%s'",udp_msg);
- token = udp_msg[0];
+ snprintf(tcp_msg,MAXBUF,"V %s %s",source,data);
+ log(DEBUG,"Rewrote NOTICE from services to: '%s'",tcp_msg);
+ token = tcp_msg[0];
}
if (!strcmp(command,"QUIT"))
{
- if ((!udp_msg) || (!strcmp(data,"")) || (strcmp(data,":")))
+ if ((!tcp_msg) || (!strcmp(data,"")) || (strcmp(data,":")))
{
strcpy(data,":No reason");
}
{
strcpy(data,":No reason");
}
- snprintf(udp_msg,MAXBUF,"Q %s %s",source,data);
- log(DEBUG,"Rewrote QUIT from services to: '%s'",udp_msg);
- token = udp_msg[0];
+ snprintf(tcp_msg,MAXBUF,"Q %s %s",source,data);
+ log(DEBUG,"Rewrote QUIT from services to: '%s'",tcp_msg);
+ token = tcp_msg[0];
}
if (!strcmp(command,"SQUIT"))
{
- snprintf(udp_msg,MAXBUF,"& %s",source);
- log(DEBUG,"Rewrote SQUIT from services to: '%s'",udp_msg);
- token = udp_msg[0];
+ snprintf(tcp_msg,MAXBUF,"& %s",source);
+ log(DEBUG,"Rewrote SQUIT from services to: '%s'",tcp_msg);
+ token = tcp_msg[0];
}
if (!strcmp(command,"SVSMODE"))
{
- snprintf(udp_msg,MAXBUF,"m %s %s",source,data);
- log(DEBUG,"Rewrote SVSMODE from services to: '%s'",udp_msg);
- token = udp_msg[0];
+ snprintf(tcp_msg,MAXBUF,"m %s %s",source,data);
+ log(DEBUG,"Rewrote SVSMODE from services to: '%s'",tcp_msg);
+ token = tcp_msg[0];
}
if (!strcmp(command,"SVS2MODE"))
{
- snprintf(udp_msg,MAXBUF,"m %s %s",source,data);
- log(DEBUG,"Rewrote SVS2MODE from services to: '%s'",udp_msg);
- token = udp_msg[0];
+ snprintf(tcp_msg,MAXBUF,"m %s %s",source,data);
+ log(DEBUG,"Rewrote SVS2MODE from services to: '%s'",tcp_msg);
+ token = tcp_msg[0];
}
// todo: this wont work without u:lines
// in give_ops etc allow nick on a u:lined serv to do just about anything
if (!strcmp(command,"MODE"))
{
- snprintf(udp_msg,MAXBUF,"m %s %s",source,data);
- log(DEBUG,"Rewrote MODE from services to: '%s'",udp_msg);
- token = udp_msg[0];
+ snprintf(tcp_msg,MAXBUF,"m %s %s",source,data);
+ log(DEBUG,"Rewrote MODE from services to: '%s'",tcp_msg);
+ token = tcp_msg[0];
}
if (!strcmp(command,"KICK"))
{
- snprintf(udp_msg,MAXBUF,"k %s %s",source,data);
- log(DEBUG,"Rewrote KICK from services to: '%s'",udp_msg);
- token = udp_msg[0];
+ snprintf(tcp_msg,MAXBUF,"k %s %s",source,data);
+ log(DEBUG,"Rewrote KICK from services to: '%s'",tcp_msg);
+ token = tcp_msg[0];
}
if (!strcmp(command,"KILL"))
{
- snprintf(udp_msg,MAXBUF,"K %s %s",source,data);
- log(DEBUG,"Rewrote KILL from services to: '%s'",udp_msg);
- token = udp_msg[0];
+ snprintf(tcp_msg,MAXBUF,"K %s %s",source,data);
+ log(DEBUG,"Rewrote KILL from services to: '%s'",tcp_msg);
+ token = tcp_msg[0];
}
if (!strcmp(command,"SVSJOIN"))
{
- snprintf(udp_msg,MAXBUF,"J %s",data);
- NetSendToOne(tcp_host,udp_msg);
+ snprintf(tcp_msg,MAXBUF,"J %s",data);
+ NetSendToOne(tcp_host,tcp_msg);
char* nick = strtok(data," ");
char* chan = strtok(NULL," ");
- log(DEBUG,"Rewrote SVSJOIN from services to: '%s'",udp_msg);
+ log(DEBUG,"Rewrote SVSJOIN from services to: '%s'",tcp_msg);
userrec* u = Find(nick);
if (u)
{
add_channel(u,chan,"",true);
}
- token = udp_msg[0];
+ token = tcp_msg[0];
}
}
- char* params = udp_msg + 2;
+ char* params = tcp_msg + 2;
char finalparam[1024];
strcpy(finalparam," :xxxx");
- if (strstr(udp_msg," :")) {
- strlcpy(finalparam,strstr(udp_msg," :"),1024);
+ if (strstr(tcp_msg," :")) {
+ strlcpy(finalparam,strstr(tcp_msg," :"),1024);
}
char* servername = strtok(NULL," ");
char* serverdesc = finalparam+2;
+ if ((!cookie) || (!servername) || (!serverdesc))
+ return;
+
+
WriteOpers("AuthCookie CONNECT from %s (%s)",servername,tcp_host);
for (int u = 0; u < auth_cookies.size(); u++)
char* revision = strtok(NULL," ");
char* serverdesc = finalparam+2;
+ if ((!servername) || (!password) || (!myport) || (!revision) || (!serverdesc))
+ return;
+
WriteOpers("CONNECT from %s (%s) (their port: %d)",servername,tcp_host,atoi(myport));
ircd_connector* cn = serv->FindHost(servername);
{
WriteOpers("CONNECT aborted: Could not link to %s, is an incompatible version %s, our version is %d",servername,revision,GetRevision());
char buffer[MAXBUF];
- sprintf(buffer,"E :Version number mismatch");
+ snprintf(buffer,MAXBUF,"E :Version number mismatch");
serv->SendPacket(buffer,tcp_host);
RemoveServer(tcp_host);
RemoveServer(servername);
{
// we have a matching link line -
// send a 'diminutive' server message back...
- snprintf(response,10240,"s %s %s :%s",ServerName,Link_SendPass,ServerDesc);
+ snprintf(response,10240,"%s s %s %s :%s",CreateSum().c_str(),ServerName,Link_SendPass,ServerDesc);
serv->SendPacket(response,servername);
for (int t = 0; t < serv->connectors.size(); t++)
}
}
char buffer[MAXBUF];
- sprintf(buffer,"E :Access is denied (no matching link block)");
+ snprintf(buffer,MAXBUF,"E :Access is denied (no matching link block)");
serv->SendPacket(buffer,tcp_host);
WriteOpers("CONNECT from %s denied, no matching link block",servername);
RemoveServer(tcp_host);
char* servername = strtok(params," ");
char* password = strtok(NULL," ");
char* serverdesc = finalparam+2;
-
+
+ if ((!servername) || (!password) || (!serverdesc))
+ return;
+
// TODO: we should do a check here to ensure that this server is one we recently initiated a
// link with, and didnt hear an 's' or 'E' back from yet (these are the only two valid responses
// to an 'S' command. If we didn't recently send an 'S' to this server, theyre trying to spoof
char buffer[MAXBUF];
me[j]->connectors[k].SetDescription(serverdesc);
me[j]->connectors[k].SetState(STATE_CONNECTED);
- sprintf(buffer,"X 0");
+ snprintf(buffer,MAXBUF,"%s X 0",CreateSum().c_str());
serv->SendPacket(buffer,tcp_host);
DoSync(me[j],tcp_host);
NetSendMyRoutingTable();
}
}
}
- WriteOpers("\2WARNING!\2 %s sent us an authentication packet but we are not authenticating with this server right noe! Possible intrusion attempt!",tcp_host);
- return;
}
}
else {
}
}
char buffer[MAXBUF];
- sprintf(buffer,"E :Access is denied (no matching link block)");
+ snprintf(buffer,MAXBUF,"E :Access is denied (no matching link block)");
serv->SendPacket(buffer,tcp_host);
WriteOpers("CONNECT from %s denied, no matching link block",servername);
RemoveServer(tcp_host);
char* servername = strtok(params," ");
char* password = strtok(NULL," ");
char* serverdesc = finalparam+2;
+
+ if ((!password) || (!servername) || (!serverdesc))
+ return;
char Link_ServerName[1024];
char Link_IPAddr[1024];
char Link_SendPass[1024];
int LinkPort = 0;
- log(DEBUG,"U-token linked server detected.");
+ log(DEBUG,"U-token linked server detected.\n\nservername='%s' password='%s'\n\n",servername,password);
for (int j = 0; j < 32; j++)
if (!strcasecmp(me[j]->connectors[k].GetServerName().c_str(),servername))
{
char buffer[MAXBUF];
- sprintf(buffer,"E :Access is denied (Server exists in the mesh)");
+ snprintf(buffer,MAXBUF,"E :Access is denied (Server exists in the mesh)");
serv->SendPacket(buffer,tcp_host);
WriteOpers("CONNECT from %s denied, \"%s\" already exists!",tcp_host,servername);
RemoveServer(tcp_host);
if (!strcasecmp(me[j]->connectors[k].GetServerName().c_str(),tcp_host))
{
char buffer[MAXBUF];
+ log(DEBUG,"Found matching link block");
me[j]->connectors[k].SetDescription(serverdesc);
me[j]->connectors[k].SetServerName(servername);
me[j]->connectors[k].SetState(STATE_SERVICES);
- sprintf(buffer,"X 0");
+ snprintf(buffer,MAXBUF,"%s X 0",CreateSum().c_str());
serv->SendPacket(buffer,servername);
- sprintf(buffer,"s %s %s %lu :%s",ServerName,Link_SendPass,LinkPort,ServerDesc);
+ snprintf(buffer,MAXBUF,"%s s %s %s %lu :%s",CreateSum().c_str(),ServerName,Link_SendPass,LinkPort,ServerDesc);
serv->SendPacket(buffer,servername);
DoSync(me[j],servername);
snprintf(buffer,MAXBUF,"H %s",servername);
}
}
}
- WriteOpers("\2WARNING!\2 %s sent us an authentication packet but we are not authenticating with this server right noe! Possible intrusion attempt!",tcp_host);
- return;
}
}
else {
log(DEBUG,"Server names '%s' and '%s' don't match",Link_ServerName,servername);
}
}
+ log(DEBUG,"No matching link block found");
char buffer[MAXBUF];
- sprintf(buffer,"E :Access is denied (no matching link block)");
+ snprintf(buffer,MAXBUF,"E :Access is denied (no matching link block)");
serv->SendPacket(buffer,tcp_host);
WriteOpers("CONNECT from %s denied, no matching link block",servername);
RemoveServer(tcp_host);
else
if (token == 'E') {
char* error_message = finalparam+2;
+
+ if (!error_message)
+ return;
+
WriteOpers("ERROR from %s: %s",tcp_host,error_message);
return;
}
else {
-
- serverrec* source_server = NULL;
-
for (int j = 0; j < 32; j++)
{
if (me[j] != NULL)
if ((me[j]->connectors[x].GetState() == STATE_CONNECTED) || (me[j]->connectors[x].GetState() == STATE_SERVICES))
{
// found a valid ircd_connector.
- process_restricted_commands(token,params,me[j],serv,tcp_host,me[j]->connectors[x].GetServerIP(),me[j]->connectors[x].GetServerPort());
+ if ((params) && (*params))
+ process_restricted_commands(token,params,me[j],serv,tcp_host,me[j]->connectors[x].GetServerIP(),me[j]->connectors[x].GetServerPort(),tcp_sum);
return;
}
}
{
add_gline(duration(parameters[1]),user->nick,parameters[2],parameters[0]);
// # <mask> <who-set-it> <time-set> <duration> :<reason>
- snprintf(netdata,MAXBUF,"# %s %s %ld %ld :%s",parameters[0],user->nick,TIME,duration(parameters[1]),parameters[2]);
+ snprintf(netdata,MAXBUF,"# %s %s %lu %lu :%s",parameters[0],user->nick,(unsigned long)TIME,(unsigned long)duration(parameters[1]),parameters[2]);
NetSendToAll(netdata);
if (!duration(parameters[1]))
{