diff options
-rw-r--r-- | include/connection.h | 13 | ||||
-rw-r--r-- | src/InspIRCd.layout | 18 | ||||
-rw-r--r-- | src/connection.cpp | 59 | ||||
-rw-r--r-- | src/inspircd.cpp | 22 |
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); |