summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/connection.h13
-rw-r--r--src/InspIRCd.layout18
-rw-r--r--src/connection.cpp59
-rw-r--r--src/inspircd.cpp22
4 files changed, 86 insertions, 26 deletions
diff --git a/include/connection.h b/include/connection.h
index 954cc919b..3316bd6c0 100644
--- a/include/connection.h
+++ b/include/connection.h
@@ -48,12 +48,6 @@ class ircd_connector : public classbase
*/
std::string description;
- /** Server names of servers that this server is linked to
- * So for A->B->C, if this was the record for B it would contain A and C
- * whilever both servers are connected to B.
- */
- std::vector<std::string> routes;
-
/** State. STATE_NOAUTH_INBOUND, STATE_NOAUTH_OUTBOUND
* STATE_SYNC, STATE_DISCONNECTED, STATE_CONNECTED
*/
@@ -65,6 +59,12 @@ class ircd_connector : public classbase
char host[MAXBUF];
int port;
+ /** Server names of servers that this server is linked to
+ * So for A->B->C, if this was the record for B it would contain A and C
+ * whilever both servers are connected to B.
+ */
+ std::vector<std::string> routes;
+
bool MakeOutboundConnection(char* host, int port);
std::string GetServerName();
@@ -78,6 +78,7 @@ class ircd_connector : public classbase
void SetDescription(std::string desc);
int GetServerPort();
bool SetHostAndPort(char* host, int port);
+ void CloseConnection();
};
diff --git a/src/InspIRCd.layout b/src/InspIRCd.layout
index fcc5c1a7f..22664554c 100644
--- a/src/InspIRCd.layout
+++ b/src/InspIRCd.layout
@@ -13,9 +13,9 @@ LeftChar=1
[Editor_1]
Open=1
Top=0
-CursorCol=41
-CursorRow=7039
-TopLine=7007
+CursorCol=1
+CursorRow=7076
+TopLine=7039
LeftChar=1
[Editor_2]
@@ -109,9 +109,9 @@ LeftChar=1
[Editor_13]
Open=1
Top=0
-CursorCol=14
-CursorRow=73
-TopLine=29
+CursorCol=25
+CursorRow=81
+TopLine=4
LeftChar=1
[Editor_14]
@@ -197,9 +197,9 @@ LeftChar=1
[Editor_24]
Open=1
Top=1
-CursorCol=1
-CursorRow=129
-TopLine=108
+CursorCol=3
+CursorRow=380
+TopLine=360
LeftChar=1
[Editor_25]
Open=1
diff --git a/src/connection.cpp b/src/connection.cpp
index 413c1cf5d..52ec677c0 100644
--- a/src/connection.cpp
+++ b/src/connection.cpp
@@ -17,7 +17,6 @@ extern std::vector<ircd_module*> factory;
extern int MODCOUNT;
-
packet::packet()
{
srand(time(NULL));
@@ -207,6 +206,7 @@ bool connection::MeshCookie(char* targethost, int port, long cookie, char* serve
sprintf(connect,"- %d %s :%s",cookie,getservername().c_str(),getserverdesc().c_str());
connector.SetState(STATE_NOAUTH_OUTBOUND);
connector.SetHostAndPort(targethost, port);
+ connector.SetState(STATE_CONNECTED);
this->connectors.push_back(connector);
return this->SendPacket(connect, servername);
}
@@ -236,6 +236,7 @@ bool connection::AddIncoming(int fd, char* targethost, int sourceport)
setsockopt(fd,SOL_SOCKET,SO_SNDBUF,(const void *)&sendbuf,sizeof(sendbuf));
setsockopt(fd,SOL_SOCKET,SO_RCVBUF,(const void *)&recvbuf,sizeof(sendbuf));
connector.SetHostAndPort(targethost, sourceport);
+ connector.SetState(STATE_NOAUTH_INBOUND);
log(DEBUG,"connection::AddIncoming() Added connection: %s:%d",targethost,sourceport);
this->connectors.push_back(connector);
return true;
@@ -299,6 +300,15 @@ void ircd_connector::SetState(int state)
this->state = state;
}
+void ircd_connector::CloseConnection()
+{
+ int flags = fcntl(this->fd, F_GETFL, 0);
+ fcntl(this->fd, F_SETFL, flags ^ O_NONBLOCK);
+ close(this->fd);
+ flags = fcntl(this->fd, F_GETFL, 0);
+ fcntl(this->fd, F_SETFL, flags | O_NONBLOCK);
+}
+
void ircd_connector::SetDescriptor(int fd)
{
this->fd = fd;
@@ -307,16 +317,42 @@ void ircd_connector::SetDescriptor(int fd)
bool connection::SendPacket(char *message, const char* host)
{
ircd_connector* cn = this->FindHost(host);
-
+ strncat(message,"\n",MAXBUF);
+
if (cn)
{
log(DEBUG,"main: Connection::SendPacket() sent '%s' to %s",message,cn->GetServerName().c_str());
+
+ if (cn->GetState() == STATE_DISCONNECTED)
+ {
+ log(DEBUG,"Main route to %s is down, seeking alternative",host);
+ // this route is down, we must re-route the packet through an available point in the mesh.
+ for (int k = 0; k < this->connectors.size(); k++)
+ {
+ // search for another point in the mesh which can 'reach' where we want to go
+ for (int m = 0; m < this->connectors[k].routes.size(); m++)
+ {
+ if (!strcasecmp(this->connectors[k].routes[m].c_str(),host))
+ {
+ log(DEBUG,"Found alternative route for packet: %s",this->connectors[k].GetServerName().c_str());
+ char buffer[MAXBUF];
+ snprintf(buffer,MAXBUF,"R %s %s",host,message);
+ this->SendPacket(buffer,this->connectors[k].GetServerName().c_str());
+ return true;
+ }
+ }
+ }
+ log(DEBUG,"ERROR: Main route to %s is down and there are no possible routes to this server!",host);
+ return false;
+ }
- strncat(message,"\n",MAXBUF);
// returns false if the packet could not be sent (e.g. target host down)
if (send(cn->GetDescriptor(),message,strlen(message),0)<0)
{
log(DEBUG,"send() failed for Connection::SendPacket(): %s",strerror(errno));
+ log(DEBUG,"Disabling connector: %s",cn->GetServerName().c_str());
+ cn->CloseConnection();
+ cn->SetState(STATE_DISCONNECTED);
return false;
}
return true;
@@ -332,10 +368,21 @@ bool connection::RecvPacket(std::deque<std::string> &messages, char* host)
memset(data, 0, 32767);
for (int i = 0; i < this->connectors.size(); i++)
{
- // returns false if the packet could not be sent (e.g. target host down)
- int rcvsize = 0;
- if (rcvsize = recv(this->connectors[i].GetDescriptor(),data,32767,0))
+ if (this->connectors[i].GetState() != STATE_DISCONNECTED)
{
+ // returns false if the packet could not be sent (e.g. target host down)
+ int rcvsize = 0;
+ rcvsize = recv(this->connectors[i].GetDescriptor(),data,32767,0);
+ if (rcvsize == -1)
+ {
+ if (errno != EAGAIN)
+ {
+ log(DEBUG,"recv() failed for Connection::RecvPacket(): %s",strerror(errno));
+ log(DEBUG,"Disabling connector: %s",this->connectors[i].GetServerName().c_str());
+ this->connectors[i].CloseConnection();
+ this->connectors[i].SetState(STATE_DISCONNECTED);
+ }
+ }
if (rcvsize > 0)
{
char* l = strtok(data,"\n");
diff --git a/src/inspircd.cpp b/src/inspircd.cpp
index 07e04fad1..254723389 100644
--- a/src/inspircd.cpp
+++ b/src/inspircd.cpp
@@ -2819,7 +2819,6 @@ bool process_module_umode(char umode, userrec* source, void* dest, bool adding)
}
else
{
- log(DEBUG,"*** BUG *** Non-module umode passed to process_module_umode!");
if (faked)
{
delete s2;
@@ -5450,7 +5449,7 @@ void handle_oper(char **parameters, int pcnt, userrec *user)
{
/* found this oper's opertype */
ConfValue("type","host",j,Hostname,&config_f);
- strncpy(user->dhost,Hostname,256);
+ ChangeDisplayedHost(user,Hostname);
}
}
if (!strchr(user->modes,'o'))
@@ -6401,6 +6400,13 @@ void handle_plus(char token,char* params,serverrec* source,serverrec* reply, cha
log(DEBUG," ");
}
+void handle_R(char token,char* params,serverrec* source,serverrec* reply, char* udp_host)
+{
+ char* server = strtok(params," ");
+ char* data = strtok(NULL,"\r\n");
+ log(DEBUG,"Forwarded packet '%s' to '%s'",data,server);
+ NetSendToOne(server,data);
+}
void handle_J(char token,char* params,serverrec* source,serverrec* reply, char* udp_host)
{
@@ -6490,6 +6496,12 @@ void process_restricted_commands(char token,char* params,serverrec* source,serve
case '+':
handle_plus(token,params,source,reply,udp_host);
break;
+ // R <server> <data>
+ // redirect token, send all of <data> along to the given
+ // server as this server has been found to still have a route to it
+ case 'R':
+ handle_R(token,params,source,reply,udp_host);
+ break;
// ?
// ping
case '?':
@@ -7004,7 +7016,7 @@ int InspIRCd(void)
// *FIX* Instead of closing sockets in kill_link when they receive the ERROR :blah line, we should queue
// them in a list, then reap the list every second or so.
- if (reap_counter>5000)
+ if (reap_counter>2500)
{
if (fd_reap.size() > 0)
{
@@ -7018,6 +7030,7 @@ int InspIRCd(void)
fd_reap.clear();
reap_counter=0;
}
+ reap_counter++;
fd_set serverfds;
FD_ZERO(&serverfds);
@@ -7067,7 +7080,7 @@ int InspIRCd(void)
char udp_msg[MAXBUF];
strncpy(udp_msg,msgs[ctr].c_str(),MAXBUF);
if (strlen(udp_msg)<1)
- {
+ {
log(DEBUG,"Invalid string from %s [route%d]",udp_host,x);
break;
}
@@ -7262,7 +7275,6 @@ int InspIRCd(void)
FD_SET (openSockfd[count], &selectFds);
}
- reap_counter++;
tv.tv_usec = 1;
selectResult = select(MAXSOCKS, &selectFds, NULL, NULL, &tv);