summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/connection.h1
-rw-r--r--src/commands.cpp41
-rw-r--r--src/connection.cpp15
-rw-r--r--src/inspircd.cpp25
-rw-r--r--src/message.cpp2
-rw-r--r--src/mode.cpp33
-rw-r--r--src/servers.cpp2
7 files changed, 95 insertions, 24 deletions
diff --git a/include/connection.h b/include/connection.h
index 2d473bde4..3699c1abb 100644
--- a/include/connection.h
+++ b/include/connection.h
@@ -38,6 +38,7 @@
#define STATE_NOAUTH_INBOUND 3
#define STATE_NOAUTH_OUTBOUND 4
#define STATE_SERVICES 5
+#define STATE_COOKIE_OUTBOUND 6
std::string CreateSum();
diff --git a/src/commands.cpp b/src/commands.cpp
index 6017148e9..df477a45f 100644
--- a/src/commands.cpp
+++ b/src/commands.cpp
@@ -1903,6 +1903,29 @@ void handle_nick(char **parameters, int pcnt, userrec *user)
}
}
+void handle_equals(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
+{
+ char* servername = strtok(params," ");
+ char* descr = strtok(NULL,"\r\n");
+
+ if ((!servername) || (!descr))
+ return;
+
+ for (int j = 0; j < 32; j++)
+ {
+ if (me[j] != NULL)
+ {
+ for (unsigned int x = 0; x < me[j]->connectors.size(); x++)
+ {
+ if (!strcasecmp(me[j]->connectors[x].GetServerName().c_str(),servername))
+ {
+ me[j]->connectors[x].SetDescription(descr);
+ }
+ }
+ }
+ }
+}
+
void handle_v(char token,char* params,serverrec* source,serverrec* reply, char* tcp_host, char* tcp_sum)
{
@@ -2390,6 +2413,8 @@ void handle_N(char token,char* params,serverrec* source,serverrec* reply, char*
if (*modes == '+')
modes++;
+ AddServerName(server);
+
time_t TS = atoi(tm);
user_hash::iterator iter = clientlist.find(nick);
if (iter != clientlist.end())
@@ -2414,6 +2439,7 @@ void handle_N(char token,char* params,serverrec* source,serverrec* reply, char*
strlcpy(clientlist[nick]->ident, ident,IDENTMAX+1); // +1 char to compensate for tilde
strlcpy(clientlist[nick]->fullname, gecos,MAXGECOS);
strlcpy(clientlist[nick]->ip,ipaddr,16);
+ strlcpy(clientlist[nick]->modes,modes,52);
clientlist[nick]->signon = TS;
clientlist[nick]->nping = 0; // this is ignored for a remote user anyway.
clientlist[nick]->lastping = 1;
@@ -2818,7 +2844,7 @@ void handle_del_szline(char token,char* params,serverrec* source,serverrec* repl
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," ");
+ char* type = strtok(NULL," ");
if ((!nick) || (!type))
return;
@@ -2968,6 +2994,9 @@ void process_restricted_commands(char token,char* params,serverrec* source,serve
case 'v':
handle_v(token,params,source,reply,tcp_host,tcp_sum);
break;
+ case '=':
+ handle_equals(token,params,source,reply,tcp_host,tcp_sum);
+ break;
// L <SOURCE> <CHANNEL> :<REASON>
// User parting a channel
case 'L':
@@ -3268,6 +3297,14 @@ void handle_link_packet(char* tcp_msg, char* tcp_host, serverrec *serv,char* tcp
me[j]->connectors[k].SetState(STATE_CONNECTED);
AddServerName(servername);
NetSendMyRoutingTable();
+ for (int t = 0; t < 32; t++) if (me[t]) for (unsigned int l = 0; l < me[t]->connectors.size(); l++)
+ {
+ if (me[t]->connectors[l].GetDescription() != "")
+ {
+ snprintf(buffer,MAXBUF,"%s = %s :%s",CreateSum().c_str(),me[t]->connectors[l].GetServerName().c_str(),me[t]->connectors[l].GetDescription().c_str());
+ serv->SendPacket(buffer,servername);
+ }
+ }
return;
}
}
@@ -3574,7 +3611,7 @@ void handle_link_packet(char* tcp_msg, char* tcp_host, serverrec *serv,char* tcp
log(DEBUG,"Servers are: '%s' '%s'",tcp_host,me[j]->connectors[x].GetServerName().c_str());
if (!strcasecmp(me[j]->connectors[x].GetServerName().c_str(),tcp_host))
{
- if ((me[j]->connectors[x].GetState() == STATE_CONNECTED) || (me[j]->connectors[x].GetState() == STATE_SERVICES))
+ if ((me[j]->connectors[x].GetState() == STATE_CONNECTED) || (me[j]->connectors[x].GetState() == STATE_SERVICES) || (me[j]->connectors[x].GetState() == STATE_COOKIE_OUTBOUND))
{
// found a valid ircd_connector.
if ((params) && (*params))
diff --git a/src/connection.cpp b/src/connection.cpp
index 4bd237e37..4db485a14 100644
--- a/src/connection.cpp
+++ b/src/connection.cpp
@@ -220,7 +220,7 @@ void ircd_connector::ResetPing()
// send AS MUCH OF THE USERS SENDQ as we are able to (might not be all of it)
bool ircd_connector::FlushWriteBuf()
{
- if (this->GetState() == STATE_NOAUTH_OUTBOUND)
+ if ((this->GetState() == STATE_NOAUTH_OUTBOUND) || (this->GetState() == STATE_COOKIE_OUTBOUND))
{
// if the outbound socket hasnt connected yet... return true and don't
// actually do anything until it IS connected. This should probably
@@ -233,6 +233,19 @@ bool ircd_connector::FlushWriteBuf()
return true;
// this falls through and sends any waiting data, which can put it into the
// connected state.
+ if (this->GetState() == STATE_COOKIE_OUTBOUND)
+ {
+ log(DEBUG,"Moving cookie_outbound into STATE_CONNECTED state");
+ this->SetState(STATE_CONNECTED);
+ for (int t = 0; t < 32; t++) if (me[t]) for (unsigned int l = 0; l < me[t]->connectors.size(); l++)
+ {
+ if (me[t]->connectors[l].GetDescription() != "")
+ {
+ snprintf(buffer,MAXBUF,"%s = %s :%s\r\n",CreateSum().c_str(),me[t]->connectors[l].GetServerName().c_str(),me[t]->connectors[l].GetDescription().c_str());
+ this->AddWriteBuf(buffer);
+ }
+ }
+ }
}
if ((sendq.length()) && (this->GetState() != STATE_DISCONNECTED))
{
diff --git a/src/inspircd.cpp b/src/inspircd.cpp
index 3ec24e38f..a1b601ea2 100644
--- a/src/inspircd.cpp
+++ b/src/inspircd.cpp
@@ -90,6 +90,7 @@ int DieDelay = 5;
time_t startup_time = time(NULL);
int NetBufferSize = 10240; // NetBufferSize used as the buffer size for all read() ops
int MaxConn = SOMAXCONN; // size of accept() backlog (128 by default on *BSD)
+unsigned int SoftLimit = MAXCLIENTS;
extern int MaxWhoResults;
time_t nb_start = 0;
int dns_timeout = 5;
@@ -184,6 +185,7 @@ void AddOper(userrec* user)
void AddServerName(std::string servername)
{
+ log(DEBUG,"Adding server name: %s",servername.c_str());
for (servernamelist::iterator a = servernames.begin(); a < servernames.end(); a++)
{
if (*a == servername)
@@ -261,7 +263,7 @@ std::string getadminnick()
void ReadConfig(bool bail, userrec* user)
{
char dbg[MAXBUF],pauseval[MAXBUF],Value[MAXBUF],timeout[MAXBUF],NB[MAXBUF],flood[MAXBUF],MW[MAXBUF],MCON[MAXBUF];
- char AH[MAXBUF],AP[MAXBUF],AF[MAXBUF],DNT[MAXBUF],pfreq[MAXBUF],thold[MAXBUF],sqmax[MAXBUF],rqmax[MAXBUF];
+ char AH[MAXBUF],AP[MAXBUF],AF[MAXBUF],DNT[MAXBUF],pfreq[MAXBUF],thold[MAXBUF],sqmax[MAXBUF],rqmax[MAXBUF],SLIMT[MAXBUF];
ConnectClass c;
std::stringstream errstr;
include_stack.clear();
@@ -324,7 +326,14 @@ void ReadConfig(bool bail, userrec* user)
ConfValue("options","moduledir",0,ModPath,&config_f);
ConfValue("disabled","commands",0,DisabledCommands,&config_f);
ConfValue("options","somaxconn",0,MCON,&config_f);
+ ConfValue("options","softlimit",0,SLIMT,&config_f);
+ SoftLimit = atoi(SLIMT);
+ if ((SoftLimit < 0) || (SoftLimit > MAXCLIENTS))
+ {
+ log(DEFAULT,"WARNING: <options:softlimit> value is greater than %d or less than 0, set to %d.",MAXCLIENTS,MAXCLIENTS);
+ SoftLimit = MaxClients;
+ }
MaxConn = atoi(MCON);
if (MaxConn > SOMAXCONN)
log(DEFAULT,"WARNING: <options:somaxconn> value may be higher than the system-defined SOMAXCONN value!");
@@ -1469,9 +1478,15 @@ void AddClient(int socket, char* host, int port, bool iscached, char* ip)
clientlist[tempnick]->chans[i].uc_modes = 0;
}
- if (clientlist.size() == MAXCLIENTS)
+ if (clientlist.size() > SoftLimit)
+ {
+ kill_link(clientlist[tempnick],"No more connections allowed");
+ return;
+ }
+
+ if (clientlist.size() >= MAXCLIENTS)
{
- kill_link(clientlist[tempnick],"No more connections allowed in this class");
+ kill_link(clientlist[tempnick],"No more connections allowed");
return;
}
@@ -1482,7 +1497,7 @@ void AddClient(int socket, char* host, int port, bool iscached, char* ip)
// irc server at once (or the irc server otherwise initiating this many connections, files etc)
// which for the time being is a physical impossibility (even the largest networks dont have more
// than about 10,000 users on ONE server!)
- if (socket > 65534)
+ if ((unsigned)socket > 65534)
{
kill_link(clientlist[tempnick],"Server is full");
return;
@@ -1580,7 +1595,7 @@ void FullConnectUser(userrec* user)
std::stringstream v;
v << "MESHED WALLCHOPS MODES=13 CHANTYPES=# PREFIX=(ohv)@%+ MAP SAFELIST MAXCHANNELS=" << MAXCHANS;
v << " MAXBANS=60 NICKLEN=" << NICKMAX;
- v << " TOPICLEN=307 KICKLEN=307 MAXTARGETS=20 AWAYLEN=307 CHANMODES=ohvb,k,l,psmnti NETWORK=";
+ v << " TOPICLEN=" << MAXTOPIC << " KICKLEN=" << MAXKICK << " MAXTARGETS=20 AWAYLEN=" << MAXAWAY << " CHANMODES=ohvb,k,l,psmnti NETWORK=";
v << Network;
std::string data005 = v.str();
FOREACH_MOD On005Numeric(data005);
diff --git a/src/message.cpp b/src/message.cpp
index c177eee93..6e024b027 100644
--- a/src/message.cpp
+++ b/src/message.cpp
@@ -261,7 +261,7 @@ int isident(const char* n)
return 0;
}
/* can't occur ANYWHERE in an Ident! */
- if (strchr("<>,./?:;@'~#=+()*&%$£ \"!",n[i]))
+ if (strchr("<>,/?:;@'~#=+()*&%$£ \"!",n[i]))
{
return 0;
}
diff --git a/src/mode.cpp b/src/mode.cpp
index 57db1d509..011fe513d 100644
--- a/src/mode.cpp
+++ b/src/mode.cpp
@@ -1173,9 +1173,14 @@ void process_modes(char **parameters,userrec* user,chanrec *chan,int status, int
// based on sourcemodes, return true or false to determine if umode is a valid mode a user may set on themselves or others.
-bool allowed_umode(char umode, char* sourcemodes,bool adding)
+bool allowed_umode(char umode, char* sourcemodes,bool adding,bool serveroverride)
{
log(DEBUG,"Allowed_umode: %c %s",umode,sourcemodes);
+ // Servers can +o and -o arbitrarily
+ if ((serveroverride == true) && (umode == 'o'))
+ {
+ return true;
+ }
// RFC1459 specified modes
if ((umode == 'w') || (umode == 's') || (umode == 'i'))
{
@@ -1363,7 +1368,7 @@ void handle_mode(char **parameters, int pcnt, userrec *user)
}
else
{
- if ((parameters[1][i] == 'i') || (parameters[1][i] == 'w') || (parameters[1][i] == 's') || (allowed_umode(parameters[1][i],user->modes,direction)))
+ if ((parameters[1][i] == 'i') || (parameters[1][i] == 'w') || (parameters[1][i] == 's') || (allowed_umode(parameters[1][i],user->modes,direction,false)))
{
can_change = 1;
}
@@ -1372,7 +1377,7 @@ void handle_mode(char **parameters, int pcnt, userrec *user)
{
if (direction == 1)
{
- if ((!strchr(dmodes,parameters[1][i])) && (allowed_umode(parameters[1][i],user->modes,true)))
+ if ((!strchr(dmodes,parameters[1][i])) && (allowed_umode(parameters[1][i],user->modes,true,false)))
{
char umode = parameters[1][i];
if ((process_module_umode(umode, user, dest, direction)) || (umode == 'i') || (umode == 's') || (umode == 'w') || (umode == 'o'))
@@ -1392,7 +1397,7 @@ void handle_mode(char **parameters, int pcnt, userrec *user)
}
else
{
- if ((allowed_umode(parameters[1][i],user->modes,false)) && (strchr(dmodes,parameters[1][i])))
+ if ((allowed_umode(parameters[1][i],user->modes,false,false)) && (strchr(dmodes,parameters[1][i])))
{
char umode = parameters[1][i];
if ((process_module_umode(umode, user, dest, direction)) || (umode == 'i') || (umode == 's') || (umode == 'w') || (umode == 'o'))
@@ -1632,7 +1637,7 @@ void server_mode(char **parameters, int pcnt, userrec *user)
if (direction == 1)
{
log(DEBUG,"umode %c being added",parameters[1][i]);
- if ((!strchr(dmodes,parameters[1][i])) && (allowed_umode(parameters[1][i],user->modes,true)))
+ if ((!strchr(dmodes,parameters[1][i])) && (allowed_umode(parameters[1][i],user->modes,true,true)))
{
char umode = parameters[1][i];
log(DEBUG,"umode %c is an allowed umode",umode);
@@ -1651,7 +1656,7 @@ void server_mode(char **parameters, int pcnt, userrec *user)
{
// can only remove a mode they already have
log(DEBUG,"umode %c being removed",parameters[1][i]);
- if ((allowed_umode(parameters[1][i],user->modes,false)) && (strchr(dmodes,parameters[1][i])))
+ if ((allowed_umode(parameters[1][i],user->modes,false,true)) && (strchr(dmodes,parameters[1][i])))
{
char umode = parameters[1][i];
log(DEBUG,"umode %c is an allowed umode",umode);
@@ -1828,7 +1833,7 @@ void merge_mode(char **parameters, int pcnt)
if (direction == 1)
{
log(DEBUG,"umode %c being added",parameters[1][i]);
- if ((!strchr(dmodes,parameters[1][i])) && (allowed_umode(parameters[1][i],"o",true)))
+ if ((!strchr(dmodes,parameters[1][i])) && (allowed_umode(parameters[1][i],"o",true,true)))
{
char umode = parameters[1][i];
log(DEBUG,"umode %c is an allowed umode",umode);
@@ -1847,7 +1852,7 @@ void merge_mode(char **parameters, int pcnt)
{
// can only remove a mode they already have
log(DEBUG,"umode %c being removed",parameters[1][i]);
- if ((allowed_umode(parameters[1][i],"o",false)) && (strchr(dmodes,parameters[1][i])))
+ if ((allowed_umode(parameters[1][i],"o",false,true)) && (strchr(dmodes,parameters[1][i])))
{
char umode = parameters[1][i];
log(DEBUG,"umode %c is an allowed umode",umode);
@@ -2019,7 +2024,7 @@ void merge_mode2(char **parameters, int pcnt, userrec* user)
if (direction == 1)
{
log(DEBUG,"umode %c being added",parameters[1][i]);
- if ((!strchr(dmodes,parameters[1][i])) && (allowed_umode(parameters[1][i],user->modes,true)))
+ if ((!strchr(dmodes,parameters[1][i])) && (allowed_umode(parameters[1][i],user->modes,true,false)))
{
char umode = parameters[1][i];
log(DEBUG,"umode %c is an allowed umode",umode);
@@ -2039,7 +2044,7 @@ void merge_mode2(char **parameters, int pcnt, userrec* user)
{
// can only remove a mode they already have
log(DEBUG,"umode %c being removed",parameters[1][i]);
- if ((allowed_umode(parameters[1][i],user->modes,false)) && (strchr(dmodes,parameters[1][i])))
+ if ((allowed_umode(parameters[1][i],user->modes,false,false)) && (strchr(dmodes,parameters[1][i])))
{
char umode = parameters[1][i];
log(DEBUG,"umode %c is an allowed umode",umode);
@@ -2131,10 +2136,10 @@ void merge_mode2(char **parameters, int pcnt, userrec* user)
log(DEBUG,"merge_mode2: found channel %s",Ptr->name);
if (Ptr)
{
- if ((cstatus(user,Ptr) < STATUS_HOP) && (!is_uline(user->server)))
- {
- return;
- }
+ //if ((cstatus(user,Ptr) < STATUS_HOP) && (!is_uline(user->server)))
+ //{
+ // return;
+ //}
process_modes(parameters,user,Ptr,cstatus(user,Ptr),pcnt,false,false,true);
}
}
diff --git a/src/servers.cpp b/src/servers.cpp
index 0660e0e3f..5448d01da 100644
--- a/src/servers.cpp
+++ b/src/servers.cpp
@@ -196,7 +196,7 @@ bool serverrec::MeshCookie(char* targethost, int newport, unsigned long cookie,
// we dont want this as the server name.
connector.SetServerName(servername);
snprintf(connect,MAXBUF,"- %lu %s :%s",cookie,getservername().c_str(),getserverdesc().c_str());
- connector.SetState(STATE_NOAUTH_OUTBOUND);
+ connector.SetState(STATE_COOKIE_OUTBOUND);
connector.SetHostAndPort(targethost, newport);
this->connectors.push_back(connector);
return this->SendPacket(connect, servername);