summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2006-01-27 15:26:59 +0000
committerbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2006-01-27 15:26:59 +0000
commit653638c68684ec035fd58bc2d0d91c9bf9aa2ab9 (patch)
tree364fd9cce4e2e8d6e86ddc3f1267b98dbed51854 /src
parent469c2e7f5ad7d3f4d7d150d643ce363a650f19b9 (diff)
Improved IP handling. Now uses in_addr to store client ip, not char[16]!
Added global and local session limits All of this needs TESTING. git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@2934 e03df62e-2008-0410-955e-edbf42e46eb7
Diffstat (limited to 'src')
-rw-r--r--src/commands.cpp4
-rw-r--r--src/dnsqueue.cpp2
-rw-r--r--src/inspircd.cpp5
-rw-r--r--src/inspircd_io.cpp13
-rw-r--r--src/modules/m_spanningtree.cpp8
-rw-r--r--src/modules/m_userip.cpp2
-rw-r--r--src/userprocess.cpp14
-rw-r--r--src/users.cpp60
-rw-r--r--src/xline.cpp2
9 files changed, 80 insertions, 30 deletions
diff --git a/src/commands.cpp b/src/commands.cpp
index e9b921beb..37f1fcef2 100644
--- a/src/commands.cpp
+++ b/src/commands.cpp
@@ -119,7 +119,7 @@ void do_whois(userrec* user, userrec* dest,unsigned long signon, unsigned long i
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 %s",user->nick, dest->nick, dest->host, dest->ip);
+ WriteServ(user->fd,"378 %s %s :is connecting from *@%s %s",user->nick, dest->nick, dest->host, (char*)inet_ntoa(dest->ip4));
}
std::string cl = chlist(dest,user);
if (cl.length())
@@ -309,7 +309,7 @@ bool ip_matches_everyone(std::string ip, userrec* user)
long matches = 0;
for (user_hash::iterator u = clientlist.begin(); u != clientlist.end(); u++)
{
- if (match(u->second->ip,ip.c_str()))
+ if (match((char*)inet_ntoa(u->second->ip4),ip.c_str()))
matches++;
}
float percent = ((float)matches / (float)clientlist.size()) * 100;
diff --git a/src/dnsqueue.cpp b/src/dnsqueue.cpp
index 7e2ad86c3..dee671aa1 100644
--- a/src/dnsqueue.cpp
+++ b/src/dnsqueue.cpp
@@ -125,7 +125,7 @@ public:
}
if ((hostname != "") && (usr->registered != 7))
{
- if (std::string(usr->ip) == ip)
+ if (std::string((char*)inet_ntoa(usr->ip4)) == ip)
{
strlcpy(usr->host,hostname.c_str(),MAXBUF);
strlcpy(usr->dhost,hostname.c_str(),MAXBUF);
diff --git a/src/inspircd.cpp b/src/inspircd.cpp
index 4b390eeb0..a834d4d5c 100644
--- a/src/inspircd.cpp
+++ b/src/inspircd.cpp
@@ -714,7 +714,6 @@ int InspIRCd::Run()
{
in_port = ntohs(sock_us.sin_port);
log(DEBUG,"Accepted socket %d",incomingSockfd);
- target = (char*)inet_ntoa(client.sin_addr);
/* Years and years ago, we used to resolve here
* using gethostbyaddr(). That is sucky and we
* don't do that any more...
@@ -722,10 +721,10 @@ int InspIRCd::Run()
NonBlocking(incomingSockfd);
if (Config->GetIOHook(in_port))
{
- Config->GetIOHook(in_port)->OnRawSocketAccept(incomingSockfd, target, in_port);
+ Config->GetIOHook(in_port)->OnRawSocketAccept(incomingSockfd, (char*)inet_ntoa(client.sin_addr), in_port);
}
stats->statsAccept++;
- AddClient(incomingSockfd, target, in_port, false, target);
+ AddClient(incomingSockfd, in_port, false, client.sin_addr);
log(DEBUG,"Adding client on port %lu fd=%lu",(unsigned long)in_port,(unsigned long)incomingSockfd);
}
else
diff --git a/src/inspircd_io.cpp b/src/inspircd_io.cpp
index a52c5933b..8534af18e 100644
--- a/src/inspircd_io.cpp
+++ b/src/inspircd_io.cpp
@@ -149,6 +149,7 @@ void ServerConfig::Read(bool bail, userrec* user)
{
char dbg[MAXBUF],pauseval[MAXBUF],Value[MAXBUF],timeout[MAXBUF],NB[MAXBUF],flood[MAXBUF],MW[MAXBUF],MCON[MAXBUF],MT[MAXBUF];
char AH[MAXBUF],AP[MAXBUF],AF[MAXBUF],DNT[MAXBUF],pfreq[MAXBUF],thold[MAXBUF],sqmax[MAXBUF],rqmax[MAXBUF],SLIMT[MAXBUF];
+ char localmax[MAXBUF],globalmax[MAXBUF];
ConnectClass c;
std::stringstream errstr;
include_stack.clear();
@@ -293,6 +294,8 @@ void ServerConfig::Read(bool bail, userrec* user)
ConfValue("connect","threshold",i,thold,&Config->config_f);
ConfValue("connect","sendq",i,sqmax,&Config->config_f);
ConfValue("connect","recvq",i,rqmax,&Config->config_f);
+ ConfValue("connect","localmax",i,localmax,&Config->config_f);
+ ConfValue("connect","globalmax",i,globalmax,&Config->config_f);
if (*Value)
{
c.host = Value;
@@ -306,6 +309,16 @@ void ServerConfig::Read(bool bail, userrec* user)
c.threshold = 5;
c.sendqmax = 262144; // 256k
c.recvqmax = 4096; // 4k
+ c.maxlocal = 3;
+ c.maxglobal = 3;
+ if (atoi(localmax)>0)
+ {
+ c.maxlocal = atoi(localmax);
+ }
+ if (atoi(globalmax)>0)
+ {
+ c.maxglobal = atoi(globalmax);
+ }
if (atoi(thold)>0)
{
c.threshold = atoi(thold);
diff --git a/src/modules/m_spanningtree.cpp b/src/modules/m_spanningtree.cpp
index e694c4570..160632bef 100644
--- a/src/modules/m_spanningtree.cpp
+++ b/src/modules/m_spanningtree.cpp
@@ -1069,7 +1069,7 @@ class TreeSocket : public InspSocket
clientlist[tempnick]->registered = 7;
clientlist[tempnick]->signon = age;
strlcpy(clientlist[tempnick]->modes, modes.c_str(),53);
- strlcpy(clientlist[tempnick]->ip,ip.c_str(),16);
+ inet_aton(ip.c_str(),&clientlist[tempnick]->ip4);
ucrec a;
a.channel = NULL;
@@ -1079,7 +1079,7 @@ class TreeSocket : public InspSocket
if (!this->bursting)
{
- WriteOpers("*** Client connecting at %s: %s!%s@%s [%s]",clientlist[tempnick]->server,clientlist[tempnick]->nick,clientlist[tempnick]->ident,clientlist[tempnick]->host,clientlist[tempnick]->ip);
+ WriteOpers("*** Client connecting at %s: %s!%s@%s [%s]",clientlist[tempnick]->server,clientlist[tempnick]->nick,clientlist[tempnick]->ident,clientlist[tempnick]->host,(char*)inet_ntoa(clientlist[tempnick]->ip4));
}
params[7] = ":" + params[7];
DoOneToAllButSender(source,"NICK",params,source);
@@ -1210,7 +1210,7 @@ class TreeSocket : public InspSocket
{
if (u->second->registered == 7)
{
- snprintf(data,MAXBUF,":%s NICK %lu %s %s %s %s +%s %s :%s",u->second->server,(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->fullname);
+ snprintf(data,MAXBUF,":%s NICK %lu %s %s %s %s +%s %s :%s",u->second->server,(unsigned long)u->second->age,u->second->nick,u->second->host,u->second->dhost,u->second->ident,u->second->modes,(char*)inet_ntoa(u->second->ip4),u->second->fullname);
this->WriteLine(data);
if (strchr(u->second->modes,'o'))
{
@@ -3028,7 +3028,7 @@ class ModuleSpanningTree : public Module
params.push_back(user->dhost);
params.push_back(user->ident);
params.push_back("+"+std::string(user->modes));
- params.push_back(user->ip);
+ params.push_back((char*)inet_ntoa(user->ip4));
params.push_back(":"+std::string(user->fullname));
DoOneToMany(Srv->GetServerName(),"NICK",params);
diff --git a/src/modules/m_userip.cpp b/src/modules/m_userip.cpp
index fe37ebc7f..48befe370 100644
--- a/src/modules/m_userip.cpp
+++ b/src/modules/m_userip.cpp
@@ -44,7 +44,7 @@ class cmd_userip : public command_t
userrec *u = Find(parameters[i]);
if (u)
{
- snprintf(junk,MAXBUF,"%s%s=+%s@%s ",u->nick,strchr(u->modes,'o') ? "*" : "",u->ident,u->ip);
+ snprintf(junk,MAXBUF,"%s%s=+%s@%s ",u->nick,strchr(u->modes,'o') ? "*" : "",u->ident,(char*)inet_ntoa(u->ip4));
strlcat(Return,junk,MAXBUF);
}
}
diff --git a/src/userprocess.cpp b/src/userprocess.cpp
index c7e7aa545..29560871f 100644
--- a/src/userprocess.cpp
+++ b/src/userprocess.cpp
@@ -148,9 +148,9 @@ void ProcessUser(userrec* cu)
}
else
{
- WriteOpers("*** Excess flood from %s",current->ip);
- log(DEFAULT,"Excess flood from: %s",current->ip);
- add_zline(120,Config->ServerName,"Flood from unregistered connection",current->ip);
+ WriteOpers("*** Excess flood from %s",(char*)inet_ntoa(current->ip4));
+ log(DEFAULT,"Excess flood from: %s",(char*)inet_ntoa(current->ip4));
+ add_zline(120,Config->ServerName,"Flood from unregistered connection",(char*)inet_ntoa(current->ip4));
apply_lines(APPLY_ZLINES);
}
return;
@@ -163,9 +163,9 @@ void ProcessUser(userrec* cu)
}
else
{
- WriteOpers("*** Excess flood from %s",current->ip);
- log(DEFAULT,"Excess flood from: %s",current->ip);
- add_zline(120,Config->ServerName,"Flood from unregistered connection",current->ip);
+ WriteOpers("*** Excess flood from %s",(char*)inet_ntoa(current->ip4));
+ log(DEFAULT,"Excess flood from: %s",(char*)inet_ntoa(current->ip4));
+ add_zline(120,Config->ServerName,"Flood from unregistered connection",(char*)inet_ntoa(current->ip4));
apply_lines(APPLY_ZLINES);
}
return;
@@ -197,7 +197,7 @@ void ProcessUser(userrec* cu)
}
else
{
- add_zline(120,Config->ServerName,"Flood from unregistered connection",current->ip);
+ add_zline(120,Config->ServerName,"Flood from unregistered connection",(char*)inet_ntoa(current->ip4));
apply_lines(APPLY_ZLINES);
}
return;
diff --git a/src/users.cpp b/src/users.cpp
index 8bc2f8baa..8089f5c23 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -64,7 +64,7 @@ template<typename T> inline string ConvToStr(const T &in)
userrec::userrec()
{
// the PROPER way to do it, AVOID bzero at *ALL* costs
- *nick = *ident = *host = *dhost = *fullname = *modes = *awaymsg = *oper = *ip = 0;
+ *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;
@@ -554,14 +554,14 @@ void AddWhoWas(userrec* u)
}
/* 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);
@@ -588,19 +588,24 @@ void AddClient(int socket, char* host, int port, bool iscached, char* ip)
*/
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);
+ /* 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;
@@ -611,7 +616,7 @@ void AddClient(int socket, char* host, int port, bool iscached, char* ip)
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;
@@ -660,10 +665,10 @@ void AddClient(int socket, char* host, int port, bool iscached, char* ip)
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];
@@ -679,6 +684,29 @@ void AddClient(int socket, char* host, int port, bool iscached, char* ip)
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++;
@@ -697,6 +725,16 @@ void FullConnectUser(userrec* user, CullList* Goners)
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)");
+ return;
+ }
+ if (FindMatchingGlobal(user) > a.maxglobal)
+ {
+ Goners->AddItem(user,"No more connections allowed from your host via this connect class (global)");
+ return;
+ }
char match_against[MAXBUF];
snprintf(match_against,MAXBUF,"%s@%s",user->ident,user->host);
@@ -752,7 +790,7 @@ void FullConnectUser(userrec* user, CullList* Goners)
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,
diff --git a/src/xline.cpp b/src/xline.cpp
index ed16fc4c1..bfffd0d84 100644
--- a/src/xline.cpp
+++ b/src/xline.cpp
@@ -692,7 +692,7 @@ void apply_lines(const int What)
}
if ((What & APPLY_ZLINES) && (zlines.size() || pzlines.size()))
{
- if ((check = matches_zline(u->ip)))
+ if ((check = matches_zline((char*)inet_ntoa(u->ip4))))
{
snprintf(reason,MAXBUF,"Z-Lined: %s",check);
Goners->AddItem(u,reason);