#ifdef USE_EPOLL
#include <sys/epoll.h>
-#define EP_DELAY 50
+#define EP_DELAY 5
#endif
#include <time.h>
#include <vector>
#include <deque>
#include <sched.h>
+#ifdef THREADED_DNS
+#include <pthread.h>
+#endif
#include "users.h"
#include "ctables.h"
#include "globals.h"
#include "hashcomp.h"
#include "socketengine.h"
#include "socket.h"
+#include "dns.h"
int LogLevel = DEFAULT;
char ServerName[MAXBUF];
int statsAccept = 0, statsRefused = 0, statsUnknown = 0, statsCollisions = 0, statsDns = 0, statsDnsGood = 0, statsDnsBad = 0, statsConnects = 0, statsSent= 0, statsRecv = 0;
-
+Server* MyServer = new Server;
FILE *log_file;
if (*a == servername)
return a->c_str();
}
- return "";
+ AddServerName(servername);
+ return FindServerNamePtr(servername);
}
void DeleteOper(userrec* user)
}
else
{
- WriteOpers("There were errors in the configuration file:",user->nick);
+ WriteOpers("There were errors in the configuration file:");
while (!errstr.eof())
{
errstr.getline(dataline,1024);
if (!FindChan(cname))
{
- MOD_RESULT = 0;
- FOREACH_RESULT(OnUserPreJoin(user,NULL,cname));
- if (MOD_RESULT == 1) {
- return NULL;
+ if (!strcasecmp(ServerName,user->server))
+ {
+ MOD_RESULT = 0;
+ FOREACH_RESULT(OnUserPreJoin(user,NULL,cname));
+ if (MOD_RESULT == 1) {
+ return NULL;
+ }
}
/* create a new one */
{
log(DEBUG,"add_channel: joining to: %s",Ptr->name);
- // the override flag allows us to bypass channel modes
+ // remote users are allowed us to bypass channel modes
// and bans (used by servers)
- if ((!override) || (!strcasecmp(user->server,ServerName)))
+ if (!strcasecmp(ServerName,user->server))
{
log(DEBUG,"Not overriding...");
MOD_RESULT = 0;
int MOD_RESULT = 0;
FOREACH_RESULT(OnAccessCheck(src,user,Ptr,AC_KICK));
- if (MOD_RESULT == ACR_DENY)
+ if ((MOD_RESULT == ACR_DENY) && (!is_uline(src->server)))
return;
- if (MOD_RESULT == ACR_DEFAULT)
+ if ((MOD_RESULT == ACR_DEFAULT) || (!is_uline(src->server)))
{
- if (((cstatus(src,Ptr) < STATUS_HOP) || (cstatus(src,Ptr) < cstatus(user,Ptr))) && (!is_uline(src->server)))
+ if ((cstatus(src,Ptr) < STATUS_HOP) || (cstatus(src,Ptr) < cstatus(user,Ptr)))
{
if (cstatus(src,Ptr) == STATUS_HOP)
{
}
}
- MOD_RESULT = 0;
- FOREACH_RESULT(OnUserPreKick(src,user,Ptr,reason));
- if (MOD_RESULT)
- return;
+ if (!is_uline(src->server))
+ {
+ MOD_RESULT = 0;
+ FOREACH_RESULT(OnUserPreKick(src,user,Ptr,reason));
+ if (MOD_RESULT)
+ return;
+ }
FOREACH_MOD OnUserKick(src,user,Ptr,reason);
log(DEBUG,"closing fd %lu",(unsigned long)user->fd);
if (user->registered == 7) {
- FOREACH_MOD OnUserQuit(user);
+ FOREACH_MOD OnUserQuit(user,reason);
WriteCommonExcept(user,"QUIT :%s",reason);
}
user->FlushWriteBuf();
if (user->registered == 7) {
- FOREACH_MOD OnUserQuit(user);
+ FOREACH_MOD OnUserQuit(user,reason);
WriteCommonExcept(user,"QUIT :%s",reason);
}
}
+/*void *task(void *arg)
+{
+ for (;;) {
+ cout << (char *)arg;
+ cout.flush();
+ }
+ return NULL;
+}*/
+
int main(int argc, char** argv)
{
Start();
}
}
}
+
strlcpy(MyExecutable,argv[0],MAXBUF);
// initialize the lowercase mapping table
}
}
+#ifdef THREADED_DNS
+void* dns_task(void* arg)
+{
+ userrec* u = (userrec*)arg;
+ log(DEBUG,"DNS thread for user %s",u->nick);
+ DNS dns1;
+ DNS dns2;
+ std::string host;
+ std::string ip;
+ if (dns1.ReverseLookup(u->ip))
+ {
+ log(DEBUG,"DNS Step 1");
+ while (!dns1.HasResult())
+ {
+ usleep(100);
+ }
+ host = dns1.GetResult();
+ if (host != "")
+ {
+ log(DEBUG,"DNS Step 2: '%s'",host.c_str());
+ if (dns2.ForwardLookup(host))
+ {
+ while (!dns2.HasResult())
+ {
+ usleep(100);
+ }
+ ip = dns2.GetResultIP();
+ log(DEBUG,"DNS Step 3 '%s'(%d) '%s'(%d)",ip.c_str(),ip.length(),u->ip,strlen(u->ip));
+ if (ip == std::string(u->ip))
+ {
+ log(DEBUG,"DNS Step 4");
+ if (host.length() < 160)
+ {
+ log(DEBUG,"DNS Step 5");
+ strcpy(u->host,host.c_str());
+ strcpy(u->dhost,host.c_str());
+ }
+ }
+ }
+ }
+ }
+ u->dns_done = true;
+ return NULL;
+}
+#endif
/* add a client connection to the sockets list */
void AddClient(int socket, char* host, int port, bool iscached, char* ip)
}
fd_ref_table[socket] = clientlist[tempnick];
engine_add_fd;
+
+ // initialize their dns lookup thread
+ //if (pthread_create(&clientlist[tempnick]->dnsthread, NULL, dns_task, (void *)clientlist[tempnick]) != 0)
+ //{
+ // log(DEBUG,"Failed to create DNS lookup thread for user %s",clientlist[tempnick]->nick);
+ //}
}
/* shows the message of the day, and any other on-logon stuff */
}
}
- // fix by brain: move this below the xline checks to prevent spurious quits going onto the net that dont belong
- user->registered = 7;
WriteServ(user->fd,"NOTICE Auth :Welcome to \002%s\002!",Network);
WriteServ(user->fd,"001 %s :Welcome to the %s IRC Network %s!%s@%s",user->nick,Network,user->nick,user->ident,user->host);
WriteServ(user->fd,"004 %s %s %s iowghraAsORVSxNCWqBzvdHtGI lvhopsmntikrRcaqOALQbSeKVfHGCuzN",user->nick,ServerName,VERSION);
// the neatest way to construct the initial 005 numeric, considering the number of configure constants to go in it...
std::stringstream v;
- v << "MESHED WALLCHOPS MODES=13 CHANTYPES=# PREFIX=(ohv)@%+ MAP SAFELIST MAXCHANNELS=" << MAXCHANS;
+ v << "WALLCHOPS MODES=13 CHANTYPES=# PREFIX=(ohv)@%+ MAP SAFELIST MAXCHANNELS=" << MAXCHANS;
v << " MAXBANS=60 NICKLEN=" << NICKMAX;
v << " TOPICLEN=" << MAXTOPIC << " KICKLEN=" << MAXKICK << " MAXTARGETS=20 AWAYLEN=" << MAXAWAY << " CHANMODES=ohvb,k,l,psmnti NETWORK=";
v << Network;
}
ShowMOTD(user);
- // fix by brain: these should be AFTER the N token, so other servers know what the HELL we're on about... :)
+ // fix 3 by brain, move registered = 7 below these so that spurious modes and host changes dont go out
+ // onto the network and produce 'fake direction'
FOREACH_MOD OnUserConnect(user);
FOREACH_MOD OnGlobalConnect(user);
+ user->registered = 7;
WriteOpers("*** Client connecting on port %lu: %s!%s@%s [%s]",(unsigned long)user->port,user->nick,user->ident,user->host,user->ip);
}
v2 = strtok_r(s1," ",&savept);
s1 = savept;
char socketengine[] = engine_name;
- snprintf(versiondata,MAXBUF,"%s Rev. %s %s :%s (O=%lu) [SE=%s]",VERSION,v2,ServerName,SYSTEM,(unsigned long)OPTIMISATION,socketengine);
+#ifdef THREADED_DNS
+ char dnsengine[] = "multithread";
+#else
+ char dnsengine[] = "singlethread";
+#endif
+ snprintf(versiondata,MAXBUF,"%s Rev. %s %s :%s [FLAGS=%lu,%s,%s]",VERSION,v2,ServerName,SYSTEM,(unsigned long)OPTIMISATION,socketengine,dnsengine);
return versiondata;
}
}
+bool is_valid_cmd(const char* commandname, int pcnt, userrec * user)
+{
+ for (unsigned int i = 0; i < cmdlist.size(); i++)
+ {
+ if (!strcasecmp(cmdlist[i].command,commandname))
+ {
+ if (cmdlist[i].handler_function)
+ {
+ if ((pcnt>=cmdlist[i].min_params) && (strcasecmp(cmdlist[i].source,"<core>")))
+ {
+ if ((strchr(user->modes,cmdlist[i].flags_needed)) || (!cmdlist[i].flags_needed))
+ {
+ if (cmdlist[i].flags_needed)
+ {
+ if ((user->HasPermission((char*)commandname)) || (is_uline(user->server)))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+}
+
// calls a handler function for a command
void call_handler(const char* commandname,char **parameters, int pcnt, userrec *user)
{
- for (unsigned int i = 0; i < cmdlist.size(); i++)
+ for (unsigned int i = 0; i < cmdlist.size(); i++)
+ {
+ if (!strcasecmp(cmdlist[i].command,commandname))
{
- if (!strcasecmp(cmdlist[i].command,commandname))
+ if (cmdlist[i].handler_function)
{
- if (cmdlist[i].handler_function)
+ if (pcnt>=cmdlist[i].min_params)
{
- if (pcnt>=cmdlist[i].min_params)
+ if ((strchr(user->modes,cmdlist[i].flags_needed)) || (!cmdlist[i].flags_needed))
{
- if (strchr(user->modes,cmdlist[i].flags_needed))
+ if (cmdlist[i].flags_needed)
+ {
+ if ((user->HasPermission((char*)commandname)) || (is_uline(user->server)))
+ {
+ cmdlist[i].handler_function(parameters,pcnt,user);
+ }
+ }
+ else
{
cmdlist[i].handler_function(parameters,pcnt,user);
}
}
}
}
+ }
}
snprintf(MODERR,MAXBUF,"Module not unloadable (marked static)");
return false;
}
+ /* Give the module a chance to tidy out all its metadata */
+ for (chan_hash::iterator c = chanlist.begin(); c != chanlist.end(); c++)
+ {
+ modules[j]->OnCleanup(TYPE_CHANNEL,c->second);
+ }
+ for (user_hash::iterator u = clientlist.begin(); u != clientlist.end(); u++)
+ {
+ modules[j]->OnCleanup(TYPE_USER,u->second);
+ }
FOREACH_MOD OnUnloadModule(modules[j],module_names[j]);
// found the module
log(DEBUG,"Deleting module...");
}
if (factory[MODCOUNT+1]->factory)
{
- Module* m = factory[MODCOUNT+1]->factory->CreateModule();
+ Module* m = factory[MODCOUNT+1]->factory->CreateModule(MyServer);
modules[MODCOUNT+1] = m;
/* save the module and the module's classfactory, if
* this isnt done, random crashes can occur :/ */
OLDTIME = TIME;
TIME = time(NULL);
+#ifndef THREADED_DNS
dns_poll();
+#endif
unsigned int numsockets = module_sockets.size();
for (std::vector<InspSocket*>::iterator a = module_sockets.begin(); a < module_sockets.end(); a++)