* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
- * Inspire is copyright (C) 2002-2006 ChatSpike-Dev.
+ * InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
userrec::userrec()
{
// the PROPER way to do it, AVOID bzero at *ALL* costs
- *nick = *ident = *host = *dhost = *fullname = *modes = *awaymsg = *oper = *ip = 0;
+ *password = *nick = *ident = *host = *dhost = *fullname = *modes = *awaymsg = *oper = 0;
server = (char*)FindServerNamePtr(Config->ServerName);
reset_due = TIME;
lines_in = fd = lastping = signon = idle_lastmsg = nping = registered = 0;
{
}
+void userrec::MakeHost(char* nhost)
+{
+ /* This is much faster than snprintf */
+ char* t = nhost;
+ for(char* n = ident; *n; n++)
+ *t++ = *n;
+ *t++ = '@';
+ for(char* n = host; *n; n++)
+ *t++ = *n;
+ *t = 0;
+}
+
void userrec::CloseSocket()
{
shutdown(this->fd,2);
char* userrec::GetFullHost()
{
static char result[MAXBUF];
- snprintf(result,MAXBUF,"%s!%s@%s",nick,ident,dhost);
+ char* t = result;
+ for(char* n = nick; *n; n++)
+ *t++ = *n;
+ *t++ = '!';
+ for(char* n = ident; *n; n++)
+ *t++ = *n;
+ *t++ = '@';
+ for(char* n = dhost; *n; n++)
+ *t++ = *n;
+ *t = 0;
return result;
}
+char* userrec::MakeWildHost()
+{
+ static char nresult[MAXBUF];
+ char* t = nresult;
+ *t++ = '*'; *t++ = '!';
+ *t++ = '*'; *t++ = '@';
+ for(char* n = dhost; *n; n++)
+ *t++ = *n;
+ *t = 0;
+ return nresult;
+}
+
int userrec::ReadData(void* buffer, size_t size)
{
if (this->fd > -1)
char* userrec::GetFullRealHost()
{
static char fresult[MAXBUF];
- snprintf(fresult,MAXBUF,"%s!%s@%s",nick,ident,host);
+ char* t = fresult;
+ for(char* n = nick; *n; n++)
+ *t++ = *n;
+ *t++ = '!';
+ for(char* n = ident; *n; n++)
+ *t++ = *n;
+ *t++ = '@';
+ for(char* n = host; *n; n++)
+ *t++ = *n;
+ *t = 0;
return fresult;
}
return true;
// are they even an oper at all?
- if (strchr(this->modes,'o'))
+ if (*this->oper)
{
for (int j =0; j < Config->ConfValueEnum("type",&Config->config_f); j++)
{
bool userrec::BufferIsReady()
{
- for (unsigned int i = 0; i < recvq.length(); i++)
+ unsigned int t = recvq.length();
+ for (unsigned int i = 0; i < t; i++)
if (recvq[i] == '\n')
return true;
return false;
return "";
char* line = (char*)recvq.c_str();
std::string ret = "";
- while ((*line != '\n') && (strlen(line)))
+ while ((*line != '\n') && (*line))
{
ret = ret + *line;
line++;
char reason[MAXBUF];
- strncpy(reason,r,MAXBUF);
+ strlcpy(reason,r,MAXBUF);
if (strlen(reason)>MAXQUIT)
{
log(DEBUG,"closing fd %lu",(unsigned long)user->fd);
if (user->registered == 7) {
+ purge_empty_chans(user);
FOREACH_MOD(I_OnUserQuit,OnUserQuit(user,reason));
WriteCommonExcept(user,"QUIT :%s",reason);
}
{
if (Config->GetIOHook(user->port))
{
- Config->GetIOHook(user->port)->OnRawSocketClose(user->fd);
+ try
+ {
+ Config->GetIOHook(user->port)->OnRawSocketClose(user->fd);
+ }
+ catch (ModuleException& modexcept)
+ {
+ log(DEBUG,"Module exception cought: %s",modexcept.GetReason()); \
+ }
}
ServerInstance->SE->DelFd(user->fd);
user->CloseSocket();
// this must come before the WriteOpers so that it doesnt try to fill their buffer with anything
// if they were an oper with +s.
if (user->registered == 7) {
- purge_empty_chans(user);
// fix by brain: only show local quits because we only show local connects (it just makes SENSE)
if (user->fd > -1)
WriteOpers("*** Client exiting: %s!%s@%s [%s]",user->nick,user->ident,user->host,reason);
char reason[MAXBUF];
- strncpy(reason,r,MAXBUF);
+ strlcpy(reason,r,MAXBUF);
if (strlen(reason)>MAXQUIT)
{
{
if (Config->GetIOHook(user->port))
{
- Config->GetIOHook(user->port)->OnRawSocketClose(user->fd);
+ try
+ {
+ Config->GetIOHook(user->port)->OnRawSocketClose(user->fd);
+ }
+ catch (ModuleException& modexcept)
+ {
+ log(DEBUG,"Module exception cought: %s",modexcept.GetReason()); \
+ }
}
ServerInstance->SE->DelFd(user->fd);
user->CloseSocket();
{
whowas_hash::iterator iter = whowas.find(u->nick);
WhoWasUser *a = new WhoWasUser();
- strlcpy(a->nick,u->nick,NICKMAX);
+ strlcpy(a->nick,u->nick,NICKMAX-1);
strlcpy(a->ident,u->ident,IDENTMAX);
strlcpy(a->dhost,u->dhost,160);
strlcpy(a->host,u->host,160);
}
/* add a client connection to the sockets list */
-void AddClient(int socket, char* host, int port, bool iscached, char* ip)
+void AddClient(int socket, int port, bool iscached, in_addr ip4)
{
string tempnick;
char tn2[MAXBUF];
user_hash::iterator iter;
tempnick = ConvToStr(socket) + "-unknown";
- sprintf(tn2,"%lu-unknown",(unsigned long)socket);
+ sprintf(tn2,"%d-unknown",socket);
iter = clientlist.find(tempnick);
*/
clientlist[tempnick] = new userrec();
- log(DEBUG,"AddClient: %lu %s %d %s",(unsigned long)socket,host,port,ip);
+ char *ipaddr = (char*)inet_ntoa(ip4);
+
+ log(DEBUG,"AddClient: %d %d %s",socket,port,ipaddr);
clientlist[tempnick]->fd = socket;
- strlcpy(clientlist[tempnick]->nick, tn2,NICKMAX);
- strlcpy(clientlist[tempnick]->host, host,160);
- strlcpy(clientlist[tempnick]->dhost, host,160);
+ strlcpy(clientlist[tempnick]->nick, tn2,NICKMAX-1);
+ /* We don't know the host yet, dns lookup could still be going on,
+ * so instead we just put the ip address here, for now.
+ */
+ strlcpy(clientlist[tempnick]->host, ipaddr, 160);
+ strlcpy(clientlist[tempnick]->dhost, ipaddr, 160);
clientlist[tempnick]->server = (char*)FindServerNamePtr(Config->ServerName);
strlcpy(clientlist[tempnick]->ident, "unknown",IDENTMAX);
clientlist[tempnick]->registered = 0;
clientlist[tempnick]->signon = TIME + Config->dns_timeout;
clientlist[tempnick]->lastping = 1;
+ clientlist[tempnick]->ip4 = ip4;
clientlist[tempnick]->port = port;
- strlcpy(clientlist[tempnick]->ip,ip,16);
// set the registration timeout for this user
unsigned long class_regtimeout = 90;
for (ClassVector::iterator i = Config->Classes.begin(); i != Config->Classes.end(); i++)
{
- if (match(clientlist[tempnick]->host,i->host.c_str()) && (i->type == CC_ALLOW))
+ if (match(ipaddr,i->host.c_str()) && (i->type == CC_ALLOW))
{
class_regtimeout = (unsigned long)i->registration_timeout;
class_flood = i->flood;
kill_link(clientlist[tempnick],"Server is full");
return;
}
- char* e = matches_exception(ip);
+ char* e = matches_exception(ipaddr);
if (!e)
{
- char* r = matches_zline(ip);
+ char* r = matches_zline(ipaddr);
if (r)
{
char reason[MAXBUF];
WriteServ(clientlist[tempnick]->fd,"NOTICE Auth :*** Looking up your hostname...");
}
+long FindMatchingGlobal(userrec* user)
+{
+ long x = 0;
+ for (user_hash::const_iterator a = clientlist.begin(); a != clientlist.end(); a++)
+ {
+ if (a->second->ip4.s_addr == user->ip4.s_addr)
+ x++;
+ }
+ return x;
+}
+
+long FindMatchingLocal(userrec* user)
+{
+ long x = 0;
+ for (std::vector<userrec*>::const_iterator a = local_users.begin(); a != local_users.end(); a++)
+ {
+ userrec* comp = (userrec*)(*a);
+ if (comp->ip4.s_addr == user->ip4.s_addr)
+ x++;
+ }
+ return x;
+}
+
void FullConnectUser(userrec* user, CullList* Goners)
{
ServerInstance->stats->statsConnects++;
Goners->AddItem(user,"Invalid password");
return;
}
+ if (FindMatchingLocal(user) > a.maxlocal)
+ {
+ Goners->AddItem(user,"No more connections allowed from your host via this connect class (local)");
+ WriteOpers("*** WARNING: maximum LOCAL connections (%ld) exceeded for IP %s",a.maxlocal,(char*)inet_ntoa(user->ip4));
+ return;
+ }
+ else if (FindMatchingGlobal(user) > a.maxglobal)
+ {
+ Goners->AddItem(user,"No more connections allowed from your host via this connect class (global)");
+ WriteOpers("*** WARNING: maximum GLOBAL connections (%ld) exceeded for IP %s",a.maxglobal,(char*)inet_ntoa(user->ip4));
+ return;
+ }
char match_against[MAXBUF];
snprintf(match_against,MAXBUF,"%s@%s",user->ident,user->host);
WriteServ(user->fd,"001 %s :Welcome to the %s IRC Network %s!%s@%s",user->nick,Config->Network,user->nick,user->ident,user->host);
WriteServ(user->fd,"002 %s :Your host is %s, running version %s",user->nick,Config->ServerName,VERSION);
WriteServ(user->fd,"003 %s :This server was created %s %s",user->nick,__TIME__,__DATE__);
- WriteServ(user->fd,"004 %s %s %s iowghrasxRVSCWBG lvhopsmntikrcaqbegOLQRSKVHGCNT",user->nick,Config->ServerName,VERSION);
+ WriteServ(user->fd,"004 %s %s %s iowghrasxRVSCWBG lvhopsmntikrcaqbegIOLQRSKVHGCNT vhobeIaqglk",user->nick,Config->ServerName,VERSION);
// anfl @ #ratbox, efnet reminded me that according to the RFC this cant contain more than 13 tokens per line...
// so i'd better split it :)
std::stringstream out(Config->data005);
FOREACH_MOD(I_OnUserConnect,OnUserConnect(user));
FOREACH_MOD(I_OnGlobalConnect,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);
+ WriteOpers("*** Client connecting on port %lu: %s!%s@%s [%s]",(unsigned long)user->port,user->nick,user->ident,user->host,(char*)inet_ntoa(user->ip4));
}
/* re-allocates a nick in the user_hash after they change nicknames,
{
if (newnick)
{
- strncpy(nick,newnick,MAXBUF);
+ strlcpy(nick,newnick,MAXBUF);
}
if (user->registered == 7)
{