diff options
author | brain <brain@e03df62e-2008-0410-955e-edbf42e46eb7> | 2005-11-25 12:17:34 +0000 |
---|---|---|
committer | brain <brain@e03df62e-2008-0410-955e-edbf42e46eb7> | 2005-11-25 12:17:34 +0000 |
commit | 31d07a9bd2702085aaabe2ad5105f58c70e2ec40 (patch) | |
tree | c2b3e41b138b8af69e9238988ab629f40dee8883 /src | |
parent | 8eac4c6b605fb21361e66b75a2468948d7331f1d (diff) |
Removed static meshed linking from core
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@1940 e03df62e-2008-0410-955e-edbf42e46eb7
Diffstat (limited to 'src')
-rw-r--r-- | src/connection.cpp | 398 | ||||
-rw-r--r-- | src/servers.cpp | 548 |
2 files changed, 0 insertions, 946 deletions
diff --git a/src/connection.cpp b/src/connection.cpp deleted file mode 100644 index f5640e5be..000000000 --- a/src/connection.cpp +++ /dev/null @@ -1,398 +0,0 @@ -/* +------------------------------------+ - * | Inspire Internet Relay Chat Daemon | - * +------------------------------------+ - * - * Inspire is copyright (C) 2002-2004 ChatSpike-Dev. - * E-mail: - * <brain@chatspike.net> - * <Craig@chatspike.net> - * - * Written by Craig Edwards, Craig McLure, and others. - * This program is free but copyrighted software; see - * the file COPYING for details. - * - * --------------------------------------------------- - */ - -using namespace std; - -#include "inspircd.h" -#include "connection.h" -#include <unistd.h> -#include <fcntl.h> -#include <poll.h> -#include <sys/errno.h> -#include <sys/ioctl.h> -#include <sys/utsname.h> -#include <vector> -#include <string> -#include <deque> -#include <sstream> -#include "modules.h" -#include "inspstring.h" -#include "helperfuncs.h" - -extern char ServerName[MAXBUF]; -extern serverrec* me[32]; -extern bool has_been_netsplit; -extern std::vector<Module*> modules; -extern std::vector<ircd_module*> factory; - -extern int MODCOUNT; - -extern time_t TIME; - - -/** - * The InspIRCd mesh network is maintained by a tree of objects which reference *themselves*. - * Every local server has an array of 32 *serverrecs, known as me[]. Each of these represents - * a local listening port, and is not null if the user has opened a listening port on the server. - * It is assumed nobody will ever want to open more than 32 listening server ports at any one - * time (i mean come on, why would you want more, the ircd works fine with ONE). - * Each me[] entry has multiple classes within it of type ircd_connector. These are stored in a vector - * and each represents a server linked via this socket. If the connection was created outbound, - * the connection is bound to the default ip address by using me[defaultRoute] (defaultRoute being - * a global variable which indicates the default server to make connections on). If the connection - * was created inbound, it is attached to the port the connection came in on. There may be as many - * ircd_connector objects as needed in each me[] entry. Each ircd_connector implements the specifics - * of an ircd connection in the mesh, however each ircd may have multiple ircd_connector connections - * to it, to maintain the mesh link. - */ - -char* xsumtable = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - -// creates a random id for a line for detection of duplicate messages -std::string CreateSum() -{ - char sum[9]; - sum[0] = ':'; - sum[8] = '\0'; - for(int q = 1; q < 8; q++) - sum[q] = xsumtable[rand()%52]; - return sum; -} - -connection::connection() -{ - fd = -1; -} - - -ircd_connector::ircd_connector() -{ - fd = -1; - port = 0; - sendq = ""; - WriteError = ""; - nextping = TIME+120; - replied = false; -} - -char* ircd_connector::GetServerIP() -{ - return this->host; -} - -int ircd_connector::GetServerPort() -{ - return this->port; -} - -bool ircd_connector::SetHostAndPort(char* newhost, int newport) -{ - strncpy(this->host,newhost,160); - this->port = newport; - return true; -} - -bool ircd_connector::SetHostAddress(char* newhost, int newport) -{ - strncpy(this->host,newhost,160); - this->port = newport; - memset((void*)&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - inet_aton(host,&addr.sin_addr); - addr.sin_port = htons(port); - return true; -} - -void ircd_connector::SetServerPort(int p) -{ - this->port = p; -} - -bool ircd_connector::AddBuffer(std::string a) -{ - std::string b = ""; - for (unsigned int i = 0; i < a.length(); i++) - if (a[i] != '\r') - b = b + a[i]; - - std::stringstream stream(ircdbuffer); - stream << b; - log(DEBUG,"AddBuffer: %s",b.c_str()); - ircdbuffer = stream.str(); - return (ircdbuffer.length() < 1048576); -} - -bool ircd_connector::BufferIsComplete() -{ - for (unsigned int i = 0; i < ircdbuffer.length(); i++) - if (ircdbuffer[i] == '\n') - return true; - return false; -} - -void ircd_connector::ClearBuffer() -{ - ircdbuffer = ""; -} - -std::string ircd_connector::GetBuffer() -{ - // Fix by Brain 28th Apr 2005 - // seems my stringstream code isnt liked by linux - // EVEN THOUGH IT IS CORRECT! Fixed by using a different - // (SLOWER) algorithm... - char* line = (char*)ircdbuffer.c_str(); - std::string ret = ""; - while ((*line != '\n') && (strlen(line))) - { - ret = ret + *line; - line++; - } - if ((*line == '\n') || (*line == '\r')) - line++; - ircdbuffer = line; - return ret; -} - -bool ircd_connector::AddWriteBuf(std::string data) -{ - log(DEBUG,"connector::AddWriteBuf(%s)",data.c_str()); - if (this->GetWriteError() != "") - return false; - if (this->GetState() == STATE_DISCONNECTED) - return false; - std::stringstream stream; - stream << sendq << data; - sendq = stream.str(); - return (sendq.length() < 1048576); -} - -bool ircd_connector::HasBufferedOutput() -{ - return (sendq.length() > 0); -} - -bool ircd_connector::CheckPing() -{ - if (TIME > this->nextping) - { - if (this->replied) - { - this->AddWriteBuf("?\n"); - this->nextping = TIME+120; - this->replied = false; - return true; - } - else - { - if (this->GetState() == STATE_CONNECTED) - { - this->SetWriteError("Ping timeout"); - this->CloseConnection(); - this->SetState(STATE_DISCONNECTED); - WriteOpers("*** Ping timeout on link to %s (more routes may remain)",this->GetServerName().c_str()); - has_been_netsplit = true; - return false; - } - } - } - return true; -} - -void ircd_connector::ResetPing() -{ - log(DEBUG,"Reset ping counter"); - this->replied = true; - this->nextping = TIME+120; -} - -// send AS MUCH OF THE USERS SENDQ as we are able to (might not be all of it) -bool ircd_connector::FlushWriteBuf() -{ - char buffer[MAXBUF]; - 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 - // have a timeout somewhere, 10 secs should suffice. ;-) - pollfd polls; - polls.fd = this->fd; - polls.events = POLLOUT; - int ret = poll(&polls,1,1); - if (ret < 1) - 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); - } - } - } - snprintf(buffer,MAXBUF,"%s v %s %s\r\n",CreateSum().c_str(),ServerName,GetVersionString().c_str()); - this->AddWriteBuf(buffer); - } - if ((sendq.length()) && (this->GetState() != STATE_DISCONNECTED)) - { - char* tb = (char*)this->sendq.c_str(); - int n_sent = write(this->fd,tb,this->sendq.length()); - if (n_sent != 0) - { - if (n_sent == -1) - { - this->SetWriteError(strerror(errno)); - return false; - } - else - { - log(DEBUG,"Wrote %d chars to socket",n_sent); - // advance the queue - tb += n_sent; - this->sendq = tb; - return true; - } - } - } - return true; -} - -void ircd_connector::SetWriteError(std::string error) -{ - if (this->WriteError == "") - this->WriteError = error; -} - -std::string ircd_connector::GetWriteError() -{ - return this->WriteError; -} - - -bool ircd_connector::MakeOutboundConnection(char* newhost, int newport) -{ - log(DEBUG,"MakeOutboundConnection: Original param: %s",newhost); - ClearBuffer(); - hostent* hoste = gethostbyname(newhost); - if (!hoste) - { - log(DEBUG,"MakeOutboundConnection: gethostbyname was NULL, setting %s",newhost); - this->SetHostAddress(newhost,newport); - SetHostAndPort(newhost,newport); - } - else - { - struct in_addr* ia = (in_addr*)hoste->h_addr; - log(DEBUG,"MakeOutboundConnection: gethostbyname was valid, setting %s",inet_ntoa(*ia)); - this->SetHostAddress(inet_ntoa(*ia),newport); - SetHostAndPort(inet_ntoa(*ia),newport); - } - - this->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (this->fd >= 0) - { - int flags = fcntl(this->fd, F_GETFL, 0); - fcntl(this->fd, F_SETFL, flags | O_NONBLOCK); - if(connect(this->fd, (sockaddr*)&this->addr,sizeof(this->addr)) == -1) - { - if (errno != EINPROGRESS) - { - WriteOpers("connect() failed for %s",host); - return false; - } - } - int sendbuf = 32768; - int recvbuf = 32768; - setsockopt(this->fd,SOL_SOCKET,SO_SNDBUF,(const void *)&sendbuf,sizeof(sendbuf)); - setsockopt(this->fd,SOL_SOCKET,SO_RCVBUF,(const void *)&recvbuf,sizeof(sendbuf)); - return true; - } - else - { - WriteOpers("socket() failed!"); - } - - return false; -} - - -void ircd_connector::SetVersionString(std::string newversion) -{ - log(DEBUG,"Set version of %s to %s",this->servername.c_str(),newversion.c_str()); - this->version = newversion; -} - -std::string ircd_connector::GetVersionString() -{ - return this->version; -} - - -std::string ircd_connector::GetServerName() -{ - return this->servername; -} - -std::string ircd_connector::GetDescription() -{ - return this->description; -} - -void ircd_connector::SetServerName(std::string serv) -{ - this->servername = serv; -} - -void ircd_connector::SetDescription(std::string desc) -{ - this->description = desc; -} - - -int ircd_connector::GetDescriptor() -{ - return this->fd; -} - -int ircd_connector::GetState() -{ - return this->state; -} - - -void ircd_connector::SetState(int newstate) -{ - this->state = newstate; -} - -void ircd_connector::CloseConnection() -{ - log(DEBUG,"Closing connection"); - // flush the queues - shutdown(this->fd,2); - close(this->fd); -} - -void ircd_connector::SetDescriptor(int newfd) -{ - this->fd = newfd; -} diff --git a/src/servers.cpp b/src/servers.cpp deleted file mode 100644 index f392c9510..000000000 --- a/src/servers.cpp +++ /dev/null @@ -1,548 +0,0 @@ -/* +------------------------------------+ - * | Inspire Internet Relay Chat Daemon | - * +------------------------------------+ - * - * Inspire is copyright (C) 2002-2004 ChatSpike-Dev. - * E-mail: - * <brain@chatspike.net> - * <Craig@chatspike.net> - * - * Written by Craig Edwards, Craig McLure, and others. - * This program is free but copyrighted software; see - * the file COPYING for details. - * - * --------------------------------------------------- - */ - -using namespace std; - -#include "inspircd_config.h" -#include "servers.h" -#include "inspircd.h" -#include <unistd.h> -#include <fcntl.h> -#include <poll.h> -#include <sys/errno.h> -#include <sys/ioctl.h> -#include <sys/utsname.h> -#include <vector> -#include <string> -#include <deque> -#include <sstream> -#include <map> -#include "inspstring.h" -#include "helperfuncs.h" -#include "connection.h" - -extern time_t TIME; -extern int MaxConn; - -extern serverrec* me[32]; - -extern bool has_been_netsplit; - -std::deque<std::string> xsums; - -serverrec::serverrec() -{ - strlcpy(name,"",256); - pingtime = 0; - lastping = TIME; - usercount_i = usercount = opercount = version = 0; - hops_away = 1; - signon = TIME; - jupiter = false; - fd = 0; - sync_soon = false; - strlcpy(nickserv,"",NICKMAX); - connectors.clear(); -} - - -serverrec::~serverrec() -{ -} - -serverrec::serverrec(char* n, long ver, bool jupe) -{ - strlcpy(name,n,256); - lastping = TIME; - usercount_i = usercount = opercount = 0; - version = ver; - hops_away = 1; - signon = TIME; - jupiter = jupe; - fd = 0; - sync_soon = false; - strlcpy(nickserv,"",NICKMAX); - connectors.clear(); -} - -bool serverrec::CreateListener(char* newhost, int p) -{ - sockaddr_in host_address; - int flags; - in_addr addy; - int on = 0; - struct linger linger = { 0 }; - - this->port = p; - - fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (fd <= 0) - { - return false; - } - - setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(const char*)&on,sizeof(on)); - linger.l_onoff = 1; - linger.l_linger = 1; - setsockopt(fd,SOL_SOCKET,SO_LINGER,(const char*)&linger,sizeof(linger)); - - // attempt to increase socket sendq and recvq as high as its possible - // to get them on linux. - int sendbuf = 32768; - int recvbuf = 32768; - setsockopt(fd,SOL_SOCKET,SO_SNDBUF,(const void *)&sendbuf,sizeof(sendbuf)); - setsockopt(fd,SOL_SOCKET,SO_RCVBUF,(const void *)&recvbuf,sizeof(sendbuf)); - - memset((void*)&host_address, 0, sizeof(host_address)); - - host_address.sin_family = AF_INET; - - if (!strcmp(newhost,"")) - { - host_address.sin_addr.s_addr = htonl(INADDR_ANY); - } - else - { - inet_aton(newhost,&addy); - host_address.sin_addr = addy; - } - - host_address.sin_port = htons(p); - - if (bind(fd,(sockaddr*)&host_address,sizeof(host_address))<0) - { - return false; - } - - // make the socket non-blocking - flags = fcntl(fd, F_GETFL, 0); - fcntl(fd, F_SETFL, flags | O_NONBLOCK); - - this->port = p; - - listen(this->fd, MaxConn); - - return true; -} - - -bool serverrec::BeginLink(char* targethost, int newport, char* password, char* servername, int myport) -{ - char connect[MAXBUF]; - - ircd_connector connector; - ircd_connector *cn = this->FindHost(servername); - - - if (cn) - { - WriteOpers("CONNECT aborted: Server %s already exists",servername); - return false; - } - - - if (this->fd) - { - if (connector.MakeOutboundConnection(targethost,newport)) - { - // targethost has been turned into an ip... - // we dont want this as the server name. - connector.SetServerName(servername); - snprintf(connect,MAXBUF,"S %s %s %lu %s :%s",getservername().c_str(),password,(unsigned long)myport,GetRevision().c_str(),getserverdesc().c_str()); - connector.SetState(STATE_NOAUTH_OUTBOUND); - connector.SetHostAndPort(targethost, newport); - this->connectors.push_back(connector); - // this packet isn't actually sent until the socket connects -- the STATE_NOAUTH_OUTBOUND state - // queues outbound data until the socket is polled as writeable (e.g. the connection is established) - return this->SendPacket(connect, servername); - } - else - { - connector.SetState(STATE_DISCONNECTED); - WriteOpers("Could not create outbound connection to %s:%d",targethost,newport); - return false; - } - } - return false; -} - - -bool serverrec::MeshCookie(char* targethost, int newport, unsigned long cookie, char* servername) -{ - char connect[MAXBUF]; - - ircd_connector connector; - - WriteOpers("Establishing meshed link to %s:%d",servername,newport); - - if (this->fd) - { - if (connector.MakeOutboundConnection(targethost,newport)) - { - // targethost has been turned into an ip... - // 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_COOKIE_OUTBOUND); - connector.SetHostAndPort(targethost, newport); - this->connectors.push_back(connector); - return this->SendPacket(connect, servername); - } - else - { - connector.SetState(STATE_DISCONNECTED); - WriteOpers("Could not create outbound connection to %s:%d",targethost,newport); - } - } - return false; -} - -bool serverrec::AddIncoming(int newfd, char* targethost, int sourceport) -{ - ircd_connector connector; - - // targethost has been turned into an ip... - // we dont want this as the server name. - connector.SetServerName(targethost); - connector.SetDescriptor(newfd); - connector.SetState(STATE_NOAUTH_INBOUND); - int flags = fcntl(newfd, F_GETFL, 0); - fcntl(newfd, F_SETFL, flags | O_NONBLOCK); - int sendbuf = 32768; - int recvbuf = 32768; - setsockopt(newfd,SOL_SOCKET,SO_SNDBUF,(const void *)&sendbuf,sizeof(sendbuf)); - setsockopt(newfd,SOL_SOCKET,SO_RCVBUF,(const void *)&recvbuf,sizeof(sendbuf)); - connector.SetHostAndPort(targethost, sourceport); - connector.SetState(STATE_NOAUTH_INBOUND); - log(DEBUG,"serverrec::AddIncoming() Added connection: %s:%d",targethost,sourceport); - this->connectors.push_back(connector); - return true; -} - -void serverrec::TerminateLink(char* targethost) -{ - // this locates the targethost in the serverrec::connectors vector of the class, - // and terminates it by sending it an SQUIT token and closing its descriptor. - // TerminateLink with a null string causes a terminate of ALL links -} - -// Returns a pointer to the connector for 'host' -ircd_connector* serverrec::FindHost(std::string findhost) -{ - for (unsigned int i = 0; i < this->connectors.size(); i++) - { - if (this->connectors[i].GetServerName() == findhost) - { - return &this->connectors[i]; - } - } - return NULL; -} - - -// Checks to see if we can still reach a server at all (e.g. is it in ANY routing table?) -bool IsRoutable(std::string servername) -{ - int c = 0; - for (int x = 0; x < 32; x++) - if (me[x]) - { - for (unsigned int i = 0; i < me[x]->connectors.size(); i++) - { - if ((me[x]->connectors[i].GetServerName() == servername) && (me[x]->connectors[i].GetState() != STATE_DISCONNECTED)) - { - c++; - } - } - } - return (c != 0); -} - - -void serverrec::FlushWriteBuffers() -{ - char buffer[MAXBUF]; - for (unsigned int i = 0; i < this->connectors.size(); i++) - { - // don't try and ping a NOAUTH_OUTBOUND state, its not authed yet! - if ((this->connectors[i].GetState() == STATE_NOAUTH_OUTBOUND) && (TIME > this->connectors[i].age+30)) - { - // however if we reach this timer its connected timed out :) - WriteOpers("*** Connection to %s timed out",this->connectors[i].GetServerName().c_str()); - return; - } - if ((this->connectors[i].GetState() == STATE_NOAUTH_INBOUND) && (TIME > this->connectors[i].age+30)) - { - WriteOpers("*** Connection from %s timed out",this->connectors[i].GetServerName().c_str()); - return; - } - if (this->connectors[i].GetState() != STATE_DISCONNECTED) - { - if (!this->connectors[i].CheckPing()) - { - WriteOpers("*** Lost single connection to %s: Ping timeout",this->connectors[i].GetServerName().c_str()); - this->connectors[i].SetState(STATE_DISCONNECTED); - if (!IsRoutable(this->connectors[i].GetServerName())) - { - WriteOpers("*** Server %s is no longer routable, disconnecting.",this->connectors[i].GetServerName().c_str()); - } - this->connectors[i].CloseConnection(); - has_been_netsplit = true; - } - } - if ((this->connectors[i].GetWriteError() !="") && (this->connectors[i].GetState() != STATE_DISCONNECTED)) - { - // if we're here the write() caused an error, we cannot proceed - WriteOpers("*** Lost single connection to %s, link inactive and retrying: %s",this->connectors[i].GetServerName().c_str(),this->connectors[i].GetWriteError().c_str()); - this->connectors[i].SetState(STATE_DISCONNECTED); - if (!IsRoutable(this->connectors[i].GetServerName())) - { - WriteOpers("*** Server %s is no longer routable, disconnecting.",this->connectors[i].GetServerName().c_str()); - } - this->connectors[i].CloseConnection(); - has_been_netsplit = true; - } - if ((this->connectors[i].HasBufferedOutput()) && (this->connectors[i].GetState() != STATE_DISCONNECTED)) - { - if (!this->connectors[i].FlushWriteBuf()) - { - // if we're here the write() caused an error, we cannot proceed - WriteOpers("*** Lost single connection to %s, link inactive and retrying: %s",this->connectors[i].GetServerName().c_str(),this->connectors[i].GetWriteError().c_str()); - this->connectors[i].SetState(STATE_DISCONNECTED); - if (!IsRoutable(this->connectors[i].GetServerName())) - { - WriteOpers("*** Server %s is no longer routable, disconnecting.",this->connectors[i].GetServerName().c_str()); - } - this->connectors[i].CloseConnection(); - has_been_netsplit = true; - } - } - } -} - -bool serverrec::SendPacket(char *message, const char* sendhost) -{ - if ((!message) || (!sendhost)) - return true; - - ircd_connector* cn = this->FindHost(sendhost); - - if (!strchr(message,'\n')) - { - strlcat(message,"\n",MAXBUF); - } - - if (cn) - { - log(DEBUG,"main: serverrec::SendPacket() sent '%s' to %s",message,cn->GetServerName().c_str()); - - if (cn->GetState() == STATE_DISCONNECTED) - { - // fix: can only route one hop to avoid a loop - if (strncmp(message,"R ",2)) - { - log(DEBUG,"Not a double reroute"); - // this route is down, we must re-route the packet through an available point in the mesh. - for (unsigned int k = 0; k < this->connectors.size(); k++) - { - log(DEBUG,"Check connector %d: %s",k,this->connectors[k].GetServerName().c_str()); - // search for another point in the mesh which can 'reach' where we want to go - for (unsigned int m = 0; m < this->connectors[k].routes.size(); m++) - { - if (!strcasecmp(this->connectors[k].routes[m].c_str(),sendhost)) - { - log(DEBUG,"Found alternative route for packet: %s",this->connectors[k].GetServerName().c_str()); - if (this->connectors[k].GetState() != STATE_DISCONNECTED) - { - char buffer[MAXBUF]; - snprintf(buffer,MAXBUF,"R %s %s",sendhost,message); - this->SendPacket(buffer,this->connectors[k].GetServerName().c_str()); - return true; - } - else - { - log(DEBUG,"Nope, this route is down..."); - return false; - } - } - } - } - } - char buffer[MAXBUF]; - snprintf(buffer,MAXBUF,"& %s",sendhost); - return false; - } - - // returns false if the packet could not be sent (e.g. target host down) - if (!cn->AddWriteBuf(message)) - { - // if we're here, there was an error pending, and the send cannot proceed - log(DEBUG,"cn->AddWriteBuf() failed for serverrec::SendPacket(): %s",cn->GetWriteError().c_str()); - log(DEBUG,"Disabling connector: %s",cn->GetServerName().c_str()); - cn->CloseConnection(); - cn->SetState(STATE_DISCONNECTED); - WriteOpers("*** Lost single connection to %s, link inactive and retrying: %s",cn->GetServerName().c_str(),cn->GetWriteError().c_str()); - // retry the packet along a new route so either arrival OR failure are gauranteed (bugfix) - return this->SendPacket(message,sendhost); - } - if (!cn->FlushWriteBuf()) - { - // if we're here the write() caused an error, we cannot proceed - log(DEBUG,"cn->FlushWriteBuf() failed for serverrec::SendPacket(): %s",cn->GetWriteError().c_str()); - log(DEBUG,"Disabling connector: %s",cn->GetServerName().c_str()); - cn->CloseConnection(); - cn->SetState(STATE_DISCONNECTED); - WriteOpers("*** Lost single connection to %s, link inactive and retrying: %s",cn->GetServerName().c_str(),cn->GetWriteError().c_str()); - // retry the packet along a new route so either arrival OR failure are gauranteed - return this->SendPacket(message,sendhost); - } - return true; - } - return false; -} - -bool already_have_sum(std::string sum) -{ - for (unsigned int i = 0; i < xsums.size(); i++) - { - if (xsums[i] == sum) - { - return true; - } - } - if (xsums.size() >= 128) - { - xsums.pop_front(); - } - xsums.push_back(sum); - return false; -} - -// receives a packet from any where there is data waiting, first come, first served -// fills the message and host values with the host where the data came from. - -bool serverrec::RecvPacket(std::deque<std::string> &messages, char* recvhost,std::deque<std::string> &sums) -{ - char data[65536],buffer[MAXBUF]; - memset(data, 0, 65536); - for (unsigned int i = 0; i < this->connectors.size(); i++) - { - if (this->connectors[i].GetState() != STATE_DISCONNECTED) - { - // returns false if the packet could not be sent (e.g. target host down) - int rcvsize = 0; - - // check if theres any data on this socket - // if not, continue onwards to the next. - pollfd polls; - polls.fd = this->connectors[i].GetDescriptor(); - polls.events = POLLIN; - int ret = poll(&polls,1,1); - if (ret <= 0) continue; - - rcvsize = recv(this->connectors[i].GetDescriptor(),data,65000,0); - data[rcvsize] = '\0'; - if (rcvsize == 0) - { - log(DEBUG,"recv() failed for serverrec::RecvPacket(): EOF"); - std::string sn = this->connectors[i].GetServerName(); - log(DEBUG,"Disabling connector: %s",sn.c_str()); - this->connectors[i].SetState(STATE_DISCONNECTED); - if (!IsRoutable(sn)) - { - WriteOpers("*** Server %s is no longer routable, disconnecting (EOF)",sn.c_str()); - } - this->connectors[i].CloseConnection(); - has_been_netsplit = true; - } - if (rcvsize == -1) - { - if (errno != EAGAIN) - { - log(DEBUG,"recv() failed for serverrec::RecvPacket(): %s",strerror(errno)); - std::string sn = this->connectors[i].GetServerName(); - log(DEBUG,"Disabling connector: %s",sn.c_str()); - this->connectors[i].SetState(STATE_DISCONNECTED); - if (!IsRoutable(sn)) - { - WriteOpers("*** Server %s is no longer routable, disconnecting.",sn.c_str()); - } - has_been_netsplit = true; - this->connectors[i].CloseConnection(); - } - } - int pushed = 0; - if (rcvsize > 0) - { - if (!this->connectors[i].AddBuffer(data)) - { - std::string sn = this->connectors[i].GetServerName(); - WriteOpers("*** Read buffer for %s exceeds maximum, closing connection!",sn.c_str()); - this->connectors[i].SetState(STATE_DISCONNECTED); - if (!IsRoutable(sn)) - { - WriteOpers("*** Server %s is no longer routable, disconnecting.",sn.c_str()); - } - has_been_netsplit = true; - this->connectors[i].CloseConnection(); - } - if (this->connectors[i].BufferIsComplete()) - { - this->connectors[i].ResetPing(); - while (this->connectors[i].BufferIsComplete()) - { - std::string text = this->connectors[i].GetBuffer(); - if (text != "") - { - if ((text[0] == ':') && (text.find(" ") != std::string::npos)) - { - std::string orig = text; - log(DEBUG,"Original: %s",text.c_str()); - std::string sum = text.substr(1,text.find(" ")-1); - text = text.substr(text.find(" ")+1,text.length()); - std::string possible_token = text.substr(1,text.find(" ")-1); - if (possible_token.length() > 1) - { - sums.push_back("*"); - text = orig; - log(DEBUG,"Non-mesh, non-tokenized string passed up the chain"); - } - else - { - log(DEBUG,"Packet sum: '%s'",sum.c_str()); - if ((already_have_sum(sum)) && (sum != "*")) - { - // we don't accept dupes - continue; - } - sums.push_back(sum.c_str()); - } - } - else sums.push_back("*"); - messages.push_back(text.c_str()); - strlcpy(recvhost,this->connectors[i].GetServerName().c_str(),160); - log(DEBUG,"serverrec::RecvPacket() %d:%s->%s",pushed++,recvhost,text.c_str()); - } - } - return true; - } - } - } - } - // nothing new yet -- message and host will be undefined - return false; -} - |