summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/connection.cpp398
-rw-r--r--src/servers.cpp548
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;
-}
-