#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>
-#include "connection.h"
+#ifdef THREADED_DNS
+#include <pthread.h>
+#endif
#include "users.h"
-#include "servers.h"
#include "ctables.h"
#include "globals.h"
#include "modules.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;
-serverrec* me[32];
+Server* MyServer = new Server;
FILE *log_file;
char MyExecutable[1024];
int boundPortCount = 0;
int portCount = 0, SERVERportCount = 0, ports[MAXSOCKS];
-int defaultRoute = 0;
+
char ModPath[MAXBUF];
/* prototypes */
bool IsDenied(userrec *user);
void AddWhoWas(userrec* u);
-std::vector<long> auth_cookies;
std::stringstream config_f(stringstream::in | stringstream::out);
std::vector<userrec*> all_opers;
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;
Ptr->AddUser((char*)user);
WriteChannel(Ptr,user,"JOIN :%s",Ptr->name);
- if (!override) // we're not overriding... so this isnt part of a netburst, broadcast it.
- {
- // use the stamdard J token with no privilages.
- char buffer[MAXBUF];
- if (created == 2)
- {
- snprintf(buffer,MAXBUF,"J %s @%s",user->nick,Ptr->name);
- }
- else
- {
- snprintf(buffer,MAXBUF,"J %s %s",user->nick,Ptr->name);
- }
- NetSendToAll(buffer);
- }
-
log(DEBUG,"Sent JOIN to client");
if (Ptr->topicset)
if (reason)
{
WriteChannel(Ptr,user,"PART %s :%s",Ptr->name, reason);
-
- if (!local)
- {
- char buffer[MAXBUF];
- snprintf(buffer,MAXBUF,"L %s %s :%s",user->nick,Ptr->name,reason);
- NetSendToAll(buffer);
- }
-
-
}
else
{
- if (!local)
- {
- char buffer[MAXBUF];
- snprintf(buffer,MAXBUF,"L %s %s :",user->nick,Ptr->name);
- NetSendToAll(buffer);
- }
-
WriteChannel(Ptr,user,"PART :%s",Ptr->name);
}
user->chans[i].uc_modes = 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);
-
- // Q token must go to ALL servers!!!
- char buffer[MAXBUF];
- snprintf(buffer,MAXBUF,"Q %s :%s",user->nick,reason);
- NetSendToAll(buffer);
}
user->FlushWriteBuf();
user->FlushWriteBuf();
if (user->registered == 7) {
- FOREACH_MOD OnUserQuit(user);
+ FOREACH_MOD OnUserQuit(user,reason);
WriteCommonExcept(user,"QUIT :%s",reason);
-
- // Q token must go to ALL servers!!!
- char buffer[MAXBUF];
- snprintf(buffer,MAXBUF,"Q %s :%s",user->nick,reason);
- NetSendToAll(buffer);
}
FOREACH_MOD OnUserDisconnect(user);
}
+/*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);
- char buffer[MAXBUF];
- snprintf(buffer,MAXBUF,"N %lu %s %s %s %s +%s %s %s :%s",(unsigned long)user->age,user->nick,user->host,user->dhost,user->ident,user->modes,user->ip,ServerName,user->fullname);
- NetSendToAll(buffer);
-
- // 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;
}
void handle_version(char **parameters, int pcnt, userrec *user)
{
- if (!pcnt)
- {
- WriteServ(user->fd,"351 %s :%s",user->nick,GetVersionString().c_str());
- }
- else
+ WriteServ(user->fd,"351 %s :%s",user->nick,GetVersionString().c_str());
+}
+
+
+bool is_valid_cmd(const char* commandname, int pcnt, userrec * user)
+{
+ for (unsigned int i = 0; i < cmdlist.size(); i++)
{
- if (!strcmp(parameters[0],"*"))
+ if (!strcasecmp(cmdlist[i].command,commandname))
{
- for (int j = 0; j < 32; j++)
+ if (cmdlist[i].handler_function)
{
- if (me[j] != NULL)
+ if ((pcnt>=cmdlist[i].min_params) && (strcasecmp(cmdlist[i].source,"<core>")))
{
- for (unsigned int x = 0; x < me[j]->connectors.size(); x++)
+ if ((strchr(user->modes,cmdlist[i].flags_needed)) || (!cmdlist[i].flags_needed))
{
- WriteServ(user->fd,"351 %s :Server %d:%d (%s): %s",user->nick,j,x,me[j]->connectors[x].GetServerName().c_str(),me[j]->connectors[x].GetVersionString().c_str());
- }
- }
- }
- return;
- }
- if (match(ServerName,parameters[0]))
- {
- WriteServ(user->fd,"351 %s :%s",user->nick,GetVersionString().c_str());
- return;
- }
- bool displayed = false, found = false;
- for (int j = 0; j < 32; j++)
- {
- if (me[j] != NULL)
- {
- for (unsigned int x = 0; x < me[j]->connectors.size(); x++)
- {
- if (match(me[j]->connectors[x].GetServerName().c_str(),parameters[0]))
- {
- found = true;
- if ((me[j]->connectors[x].GetVersionString() != "") && (!displayed))
+ if (cmdlist[i].flags_needed)
{
- displayed = true;
- WriteServ(user->fd,"351 %s :%s",user->nick,me[j]->connectors[x].GetVersionString().c_str());
+ if ((user->HasPermission((char*)commandname)) || (is_uline(user->server)))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
}
+ return true;
}
}
}
}
- if ((!displayed) && (found))
- {
- WriteServ(user->fd,"402 %s %s :Server %s has no version information",user->nick,parameters[0],parameters[0]);
- return;
- }
- if (!found)
- {
- WriteServ(user->fd,"402 %s %s :No such server",user->nick,parameters[0]);
- }
}
- return;
+ 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);
}
}
}
}
-}
-
-void DoSplitEveryone()
-{
- bool go_again = true;
- while (go_again)
- {
- go_again = false;
- for (int i = 0; i < 32; i++)
- {
- if (me[i] != NULL)
- {
- for (vector<ircd_connector>::iterator j = me[i]->connectors.begin(); j != me[i]->connectors.end(); j++)
- {
- if (strcasecmp(j->GetServerName().c_str(),ServerName))
- {
- j->routes.clear();
- j->CloseConnection();
- me[i]->connectors.erase(j);
- go_again = true;
- break;
- }
- }
- }
- }
}
- log(DEBUG,"Removed server. Will remove clients...");
- // iterate through the userlist and remove all users on this server.
- // because we're dealing with a mesh, we dont have to deal with anything
- // "down-route" from this server (nice huh)
- go_again = true;
- char reason[MAXBUF];
- while (go_again)
- {
- go_again = false;
- for (user_hash::const_iterator u = clientlist.begin(); u != clientlist.end(); u++)
- {
- if (strcasecmp(u->second->server,ServerName))
- {
- snprintf(reason,MAXBUF,"%s %s",ServerName,u->second->server);
- kill_link(u->second,reason);
- go_again = true;
- break;
- }
- }
- }
- has_been_netsplit = true;
- log(DEBUG,"Clients removed.");
}
-
void force_nickchange(userrec* user,const char* newnick)
{
char nick[MAXBUF];
}
}
-void DoSync(serverrec* serv, char* tcp_host)
-{
- char data[MAXBUF];
- log(DEBUG,"Sending sync");
- // send start of sync marker: Y <timestamp>
- // at this point the ircd receiving it starts broadcasting this netburst to all ircds
- // except the ones its receiving it from.
- snprintf(data,MAXBUF,"%s Y %lu",CreateSum().c_str(),(unsigned long)TIME);
- serv->SendPacket(data,tcp_host);
- // send users and channels
-
- NetSendMyRoutingTable();
-
- // send all routing table and uline voodoo. The ordering of these commands is IMPORTANT!
- for (int j = 0; j < 32; j++)
- {
- if (me[j] != NULL)
- {
- for (unsigned int k = 0; k < me[j]->connectors.size(); k++)
- {
- if (is_uline(me[j]->connectors[k].GetServerName().c_str()))
- {
- snprintf(data,MAXBUF,"%s H %s",CreateSum().c_str(),me[j]->connectors[k].GetServerName().c_str());
- serv->SendPacket(data,tcp_host);
- }
- }
- }
- }
-
- // send our version for the remote side to cache
- snprintf(data,MAXBUF,"%s v %s %s",CreateSum().c_str(),ServerName,GetVersionString().c_str());
- serv->SendPacket(data,tcp_host);
-
- // sync the users and channels, give the modules a look-in.
- for (user_hash::iterator u = clientlist.begin(); u != clientlist.end(); u++)
- {
- snprintf(data,MAXBUF,"%s N %lu %s %s %s %s +%s %s %s :%s",CreateSum().c_str(),(unsigned long)u->second->age,u->second->nick,u->second->host,u->second->dhost,u->second->ident,u->second->modes,u->second->ip,u->second->server,u->second->fullname);
- serv->SendPacket(data,tcp_host);
- if (strchr(u->second->modes,'o'))
- {
- snprintf(data,MAXBUF,"%s | %s %s",CreateSum().c_str(),u->second->nick,u->second->oper);
- serv->SendPacket(data,tcp_host);
- }
- for (int i = 0; i <= MODCOUNT; i++)
- {
- string_list l = modules[i]->OnUserSync(u->second);
- for (unsigned int j = 0; j < l.size(); j++)
- {
- snprintf(data,MAXBUF,"%s %s",CreateSum().c_str(),l[j].c_str());
- serv->SendPacket(data,tcp_host);
- }
- }
- char* chl = chlist(u->second,u->second);
- if (strcmp(chl,""))
- {
- snprintf(data,MAXBUF,"%s J %s %s",CreateSum().c_str(),u->second->nick,chl);
- serv->SendPacket(data,tcp_host);
- }
- }
- // send channel modes, topics etc...
- for (chan_hash::iterator c = chanlist.begin(); c != chanlist.end(); c++)
- {
- snprintf(data,MAXBUF,"M %s +%s",c->second->name,chanmodes(c->second));
- serv->SendPacket(data,tcp_host);
- for (int i = 0; i <= MODCOUNT; i++)
- {
- string_list l = modules[i]->OnChannelSync(c->second);
- for (unsigned int j = 0; j < l.size(); j++)
- {
- snprintf(data,MAXBUF,"%s %s",CreateSum().c_str(),l[j].c_str());
- serv->SendPacket(data,tcp_host);
- }
- }
- if (c->second->topic[0])
- {
- snprintf(data,MAXBUF,"%s T %lu %s %s :%s",CreateSum().c_str(),(unsigned long)c->second->topicset,c->second->setby,c->second->name,c->second->topic);
- serv->SendPacket(data,tcp_host);
- }
- // send current banlist
-
- for (BanList::iterator b = c->second->bans.begin(); b != c->second->bans.end(); b++)
- {
- snprintf(data,MAXBUF,"%s M %s +b %s",CreateSum().c_str(),c->second->name,b->data);
- serv->SendPacket(data,tcp_host);
- }
- }
- // sync global zlines, glines, etc
- sync_xlines(serv,tcp_host);
-
- snprintf(data,MAXBUF,"%s F %lu",CreateSum().c_str(),(unsigned long)TIME);
- serv->SendPacket(data,tcp_host);
- log(DEBUG,"Sent sync");
- // ircd sends its serverlist after the end of sync here
-}
-
-
-void NetSendMyRoutingTable()
-{
- // send out a line saying what is reachable to us.
- // E.g. if A is linked to B C and D, send out:
- // $ A B C D
- // if its only linked to B and D send out:
- // $ A B D
- // if it has no links, dont even send out the line at all.
- char buffer[MAXBUF];
- snprintf(buffer,MAXBUF,"$ %s",ServerName);
- bool sendit = false;
- for (int i = 0; i < 32; i++)
- {
- if (me[i] != NULL)
- {
- for (unsigned int j = 0; j < me[i]->connectors.size(); j++)
- {
- if ((me[i]->connectors[j].GetState() != STATE_DISCONNECTED) || (is_uline(me[i]->connectors[j].GetServerName().c_str())))
- {
- strlcat(buffer," ",MAXBUF);
- strlcat(buffer,me[i]->connectors[j].GetServerName().c_str(),MAXBUF);
- sendit = true;
- }
- }
- }
- }
- if (sendit)
- NetSendToAll(buffer);
-}
-
-
-void DoSplit(const char* params)
-{
- bool go_again = true;
- int x = 0;
- while (go_again)
- {
- go_again = false;
- for (int i = 0; i < 32; i++)
- {
- if (me[i] != NULL)
- {
- for (vector<ircd_connector>::iterator j = me[i]->connectors.begin(); j != me[i]->connectors.end(); j++)
- {
- if (!strcasecmp(j->GetServerName().c_str(),params))
- {
- log(DEBUG,"Removing %s",j->GetServerName().c_str());
- j->routes.clear();
- j->CloseConnection();
- me[i]->connectors.erase(j);
- go_again = true;
- x++;
- break;
- }
- }
- }
- }
- }
- if (!x)
- {
- log(DEBUG,"No clients to remove.");
- return;
- }
- log(DEBUG,"Removed server. Will remove clients...");
- // iterate through the userlist and remove all users on this server.
- // because we're dealing with a mesh, we dont have to deal with anything
- // "down-route" from this server (nice huh)
- go_again = true;
- char reason[MAXBUF];
- snprintf(reason,MAXBUF,"%s %s",ServerName,params);
- while (go_again)
- {
- go_again = false;
- for (user_hash::const_iterator u = clientlist.begin(); u != clientlist.end(); u++)
- {
- if (!strcasecmp(u->second->server,params))
- {
- kill_link(u->second,reason);
- go_again = true;
- break;
- }
- }
- }
- has_been_netsplit = true;
- log(DEBUG,"Removed clients (DoSplit)");
-}
-
-// removes a server. Will NOT remove its users!
-
-void RemoveServer(const char* name)
-{
- bool go_again = true;
- while (go_again)
- {
- go_again = false;
- for (int i = 0; i < 32; i++)
- {
- if (me[i] != NULL)
- {
- for (vector<ircd_connector>::iterator j = me[i]->connectors.begin(); j != me[i]->connectors.end(); j++)
- {
- if (!strcasecmp(j->GetServerName().c_str(),name))
- {
- j->routes.clear();
- j->CloseConnection();
- me[i]->connectors.erase(j);
- go_again = true;
- break;
- }
- }
- }
- }
- }
-}
-
-
char MODERR[MAXBUF];
char* ModuleError()
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 :/ */
}
-bool GotServer(std::string name)
-{
- for (int j = 0; j < 32; j++)
- {
- if (me[j] != NULL)
- {
- for (unsigned int k = 0; k < me[j]->connectors.size(); k++)
- {
- if (name == me[j]->connectors[k].GetServerName())
- {
- return true;
- }
- }
- }
- }
- return false;
-}
-
-
int InspIRCd(char** argv, int argc)
{
struct sockaddr_in client,server;
AddServerName(ServerName);
- int clientportcount = 0, serverportcount = 0;
+ int clientportcount = 0;
for (count = 0; count < ConfValueEnum("bind",&config_f); count++)
{
ConfValue("bind","type",count,Type,&config_f);
if (!strcmp(Type,"servers"))
{
- char Default[MAXBUF];
- strcpy(Default,"no");
- ConfValue("bind","default",count,Default,&config_f);
- if (strchr(Default,'y'))
- {
- defaultRoute = serverportcount;
- log(DEBUG,"InspIRCd: startup: binding '%s:%s' is default server route",Addr,configToken);
- }
- me[serverportcount] = new serverrec(ServerName,100L,false);
- if (!me[serverportcount]->CreateListener(Addr,atoi(configToken)))
- {
- log(DEFAULT,"Warning: Failed to bind port %lu",(unsigned long)atoi(configToken));
- printf("Warning: Failed to bind port %lu\n",(unsigned long)atoi(configToken));
- }
- else
- {
- serverportcount++;
- }
+ // modules handle this bind type now.
}
else
{
log(DEBUG,"InspIRCd: startup: read binding %s:%s [%s] from config",Addr,configToken, Type);
}
portCount = clientportcount;
- SERVERportCount = serverportcount;
- log(DEBUG,"InspIRCd: startup: read %lu total client ports and %lu total server ports",(unsigned long)portCount,(unsigned long)SERVERportCount);
+ log(DEBUG,"InspIRCd: startup: read %lu total client ports",(unsigned long)portCount);
log(DEBUG,"InspIRCd: startup: InspIRCd is now starting!");
printf("\n");
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++)
{
InspSocket* s = (InspSocket*)*a;
- if (!s->Poll())
+ if ((s) && (!s->Poll()))
{
- delete s;
+ log(DEBUG,"Socket poll returned false, close and bail");
+ s->Close();
module_sockets.erase(a);
+ delete s;
break;
}
+ // we gained a socket, sarper
+ if (module_sockets.size() != numsockets) break;
}
// *FIX* Instead of closing sockets in kill_link when they receive the ERROR :blah line, we should queue
char target[MAXBUF], resolved[MAXBUF];
length = sizeof (client);
incomingSockfd = accept (openSockfd[count], (struct sockaddr *) &client, &length);
+ log(DEBUG,"Accepted socket %d",incomingSockfd);
strlcpy (target, (char *) inet_ntoa (client.sin_addr), MAXBUF);
strlcpy (resolved, target, MAXBUF);