Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

serverrec Class Reference

A class that defines the local server or a remote server. More...

#include <servers.h>

Inheritance diagram for serverrec:

Inheritance graph
[legend]
Collaboration diagram for serverrec:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 serverrec ()
 Constructor.

 serverrec (char *n, long ver, bool jupe)
 Constructor which initialises some of the main variables.

 ~serverrec ()
 Destructor.

bool CreateListener (char *host, int p)
 Create a listening socket on 'host' using port number 'p'.

bool BeginLink (char *targethost, int port, char *password, char *servername, int myport)
 Begin an outbound link to another ircd at targethost.

bool MeshCookie (char *targethost, int port, unsigned long cookie, char *servername)
 Begin an outbound mesh link to another ircd on a network you are already an authenticated member of.

void TerminateLink (char *targethost)
 Terminate a link to 'targethost' by calling the ircd_connector::CloseConnection method.

bool SendPacket (char *message, const char *host)
 Send a message to a server by name, if the server is unavailable directly route the packet via another server If the server still cannot be reached after attempting to route the message remotely, returns false.

bool RecvPacket (std::deque< std::string > &messages, char *host, std::deque< std::string > &sums)
 Returns the next available packet and returns true if data is available.

ircd_connectorFindHost (std::string host)
 Find the ircd_connector oject related to a certain servername given in 'host'.

bool AddIncoming (int fd, char *targethost, int sourceport)
 Add an incoming connection to the connection pool.

void FlushWriteBuffers ()
 Flushes all data waiting to be written for all of this server's connections.


Public Attributes

char name [MAXBUF]
 server name

long pingtime
 last ping response (ms)

long usercount_i
 invisible users on server

long usercount
 non-invisible users on server

long opercount
 opers on server

int hops_away
 number of hops away (for quick access)

long version
 ircd version

bool jupiter
 is a JUPE server (faked to enforce a server ban)

char description [MAXBUF]
 Description of the server.

char nickserv [NICKMAX]
 Holds nickserv's name on U:lined (services) servers (this is a kludge for ircservices which ASSUMES things :/).

bool sync_soon
std::vector< ircd_connectorconnectors
 With a serverrec, this is a list of all established server connections.


Detailed Description

A class that defines the local server or a remote server.

Definition at line 30 of file servers.h.


Constructor & Destructor Documentation

serverrec::serverrec  ) 
 

Constructor.

Definition at line 42 of file servers.cpp.

References connectors, connection::fd, hops_away, jupiter, connection::lastping, name, nickserv, opercount, pingtime, connection::signon, sync_soon, TIME, usercount, usercount_i, and version.

00043 {
00044         strlcpy(name,"",256);
00045         pingtime = 0;
00046         lastping = TIME;
00047         usercount_i = usercount = opercount = version = 0;
00048         hops_away = 1;
00049         signon = TIME;
00050         jupiter = false;
00051         fd = 0;
00052         sync_soon = false;
00053         strlcpy(nickserv,"",NICKMAX);
00054         connectors.clear();
00055 }

serverrec::serverrec char *  n,
long  ver,
bool  jupe
 

Constructor which initialises some of the main variables.

Definition at line 62 of file servers.cpp.

References connectors, connection::fd, hops_away, jupiter, connection::lastping, name, nickserv, opercount, connection::signon, sync_soon, TIME, usercount, usercount_i, and version.

00063 {
00064         strlcpy(name,n,256);
00065         lastping = TIME;
00066         usercount_i = usercount = opercount = 0;
00067         version = ver;
00068         hops_away = 1;
00069         signon = TIME;
00070         jupiter = jupe;
00071         fd = 0;
00072         sync_soon = false;
00073         strlcpy(nickserv,"",NICKMAX);
00074         connectors.clear();
00075 }

serverrec::~serverrec  ) 
 

Destructor.

Definition at line 58 of file servers.cpp.

00059 {
00060 }


Member Function Documentation

bool serverrec::AddIncoming int  fd,
char *  targethost,
int  sourceport
 

Add an incoming connection to the connection pool.

(reserved for core use)

Definition at line 207 of file servers.cpp.

References connectors, DEBUG, ircd_connector::SetDescriptor(), ircd_connector::SetHostAndPort(), ircd_connector::SetServerName(), ircd_connector::SetState(), and STATE_NOAUTH_INBOUND.

00208 {
00209         ircd_connector connector;
00210 
00211         // targethost has been turned into an ip...
00212         // we dont want this as the server name.
00213         connector.SetServerName(targethost);
00214         connector.SetDescriptor(newfd);
00215         connector.SetState(STATE_NOAUTH_INBOUND);
00216         int flags = fcntl(newfd, F_GETFL, 0);
00217         fcntl(newfd, F_SETFL, flags | O_NONBLOCK);
00218         int sendbuf = 32768;
00219         int recvbuf = 32768;
00220         setsockopt(newfd,SOL_SOCKET,SO_SNDBUF,(const void *)&sendbuf,sizeof(sendbuf));
00221         setsockopt(newfd,SOL_SOCKET,SO_RCVBUF,(const void *)&recvbuf,sizeof(sendbuf));
00222         connector.SetHostAndPort(targethost, sourceport);
00223         connector.SetState(STATE_NOAUTH_INBOUND);
00224         log(DEBUG,"serverrec::AddIncoming() Added connection: %s:%d",targethost,sourceport);
00225         this->connectors.push_back(connector);
00226         return true;
00227 }

bool serverrec::BeginLink char *  targethost,
int  port,
char *  password,
char *  servername,
int  myport
 

Begin an outbound link to another ircd at targethost.

Definition at line 138 of file servers.cpp.

References connectors, connection::fd, FindHost(), ircd_connector::MakeOutboundConnection(), SendPacket(), ircd_connector::SetHostAndPort(), ircd_connector::SetServerName(), ircd_connector::SetState(), STATE_DISCONNECTED, and STATE_NOAUTH_OUTBOUND.

00139 {
00140         char connect[MAXBUF];
00141 
00142         ircd_connector connector;
00143         ircd_connector *cn = this->FindHost(servername);
00144 
00145 
00146         if (cn)
00147         {
00148                 WriteOpers("CONNECT aborted: Server %s already exists",servername);
00149                 return false;
00150         }
00151 
00152 
00153         if (this->fd)
00154         {
00155                 if (connector.MakeOutboundConnection(targethost,newport))
00156                 {
00157                         // targethost has been turned into an ip...
00158                         // we dont want this as the server name.
00159                         connector.SetServerName(servername);
00160                         snprintf(connect,MAXBUF,"S %s %s %lu %s :%s",getservername().c_str(),password,(unsigned long)myport,GetRevision().c_str(),getserverdesc().c_str());
00161                         connector.SetState(STATE_NOAUTH_OUTBOUND);
00162                         connector.SetHostAndPort(targethost, newport);
00163                         this->connectors.push_back(connector);
00164                         return this->SendPacket(connect, servername);
00165                 }
00166                 else
00167                 {
00168                         connector.SetState(STATE_DISCONNECTED);
00169                         WriteOpers("Could not create outbound connection to %s:%d",targethost,newport);
00170                 }
00171         }
00172         return false;
00173 }

bool serverrec::CreateListener char *  host,
int  p
 

Create a listening socket on 'host' using port number 'p'.

Definition at line 77 of file servers.cpp.

References connection::fd, MaxConn, and connection::port.

00078 {
00079         sockaddr_in host_address;
00080         int flags;
00081         in_addr addy;
00082         int on = 0;
00083         struct linger linger = { 0 };
00084 
00085         this->port = p;
00086 
00087         fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
00088         if (fd <= 0)
00089         {
00090                 return false;
00091         }
00092 
00093         setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(const char*)&on,sizeof(on));
00094         linger.l_onoff = 1;
00095         linger.l_linger = 1;
00096         setsockopt(fd,SOL_SOCKET,SO_LINGER,(const char*)&linger,sizeof(linger));
00097 
00098         // attempt to increase socket sendq and recvq as high as its possible
00099         // to get them on linux.
00100         int sendbuf = 32768;
00101         int recvbuf = 32768;
00102         setsockopt(fd,SOL_SOCKET,SO_SNDBUF,(const void *)&sendbuf,sizeof(sendbuf));
00103         setsockopt(fd,SOL_SOCKET,SO_RCVBUF,(const void *)&recvbuf,sizeof(sendbuf));
00104 
00105         memset((void*)&host_address, 0, sizeof(host_address));
00106 
00107         host_address.sin_family = AF_INET;
00108 
00109         if (!strcmp(newhost,""))
00110         {
00111                 host_address.sin_addr.s_addr = htonl(INADDR_ANY);
00112         }
00113         else
00114         {
00115                 inet_aton(newhost,&addy);
00116                 host_address.sin_addr = addy;
00117         }
00118 
00119         host_address.sin_port = htons(p);
00120 
00121         if (bind(fd,(sockaddr*)&host_address,sizeof(host_address))<0)
00122         {
00123                 return false;
00124         }
00125 
00126         // make the socket non-blocking
00127         flags = fcntl(fd, F_GETFL, 0);
00128         fcntl(fd, F_SETFL, flags | O_NONBLOCK);
00129 
00130         this->port = p;
00131 
00132         listen(this->fd, MaxConn);
00133 
00134         return true;
00135 }

ircd_connector * serverrec::FindHost std::string  host  ) 
 

Find the ircd_connector oject related to a certain servername given in 'host'.

Definition at line 237 of file servers.cpp.

References connectors.

Referenced by BeginLink(), and SendPacket().

00238 {
00239         for (int i = 0; i < this->connectors.size(); i++)
00240         {
00241                 if (this->connectors[i].GetServerName() == findhost)
00242                 {
00243                         return &this->connectors[i];
00244                 }
00245         }
00246         return NULL;
00247 }

void serverrec::FlushWriteBuffers  ) 
 

Flushes all data waiting to be written for all of this server's connections.

Definition at line 249 of file servers.cpp.

References connectors, and STATE_DISCONNECTED.

00250 {
00251         for (int i = 0; i < this->connectors.size(); i++)
00252         {
00253                 if (this->connectors[i].GetState() != STATE_DISCONNECTED)
00254                 {
00255                         if (!this->connectors[i].CheckPing())
00256                         {
00257                                 WriteOpers("*** Lost single connection to %s: Ping timeout",this->connectors[i].GetServerName().c_str());
00258                                 this->connectors[i].CloseConnection();
00259                                 this->connectors[i].SetState(STATE_DISCONNECTED);
00260                         }
00261                 }
00262                 if (this->connectors[i].HasBufferedOutput())
00263                 {
00264                         if (!this->connectors[i].FlushWriteBuf())
00265                         {
00266                                 // if we're here the write() caused an error, we cannot proceed
00267                                 WriteOpers("*** Lost single connection to %s, link inactive and retrying: %s",this->connectors[i].GetServerName().c_str(),this->connectors[i].GetWriteError().c_str());
00268                                 this->connectors[i].CloseConnection();
00269                                 this->connectors[i].SetState(STATE_DISCONNECTED);
00270                         }
00271                 }
00272         }
00273 }

bool serverrec::MeshCookie char *  targethost,
int  port,
unsigned long  cookie,
char *  servername
 

Begin an outbound mesh link to another ircd on a network you are already an authenticated member of.

Definition at line 176 of file servers.cpp.

References connectors, connection::fd, ircd_connector::MakeOutboundConnection(), SendPacket(), ircd_connector::SetHostAndPort(), ircd_connector::SetServerName(), ircd_connector::SetState(), STATE_CONNECTED, STATE_DISCONNECTED, and STATE_NOAUTH_OUTBOUND.

00177 {
00178         char connect[MAXBUF];
00179 
00180         ircd_connector connector;
00181 
00182         WriteOpers("Establishing meshed link to %s:%d",servername,newport);
00183 
00184         if (this->fd)
00185         {
00186                 if (connector.MakeOutboundConnection(targethost,newport))
00187                 {
00188                         // targethost has been turned into an ip...
00189                         // we dont want this as the server name.
00190                         connector.SetServerName(servername);
00191                         snprintf(connect,MAXBUF,"- %lu %s :%s",cookie,getservername().c_str(),getserverdesc().c_str());
00192                         connector.SetState(STATE_NOAUTH_OUTBOUND);
00193                         connector.SetHostAndPort(targethost, newport);
00194                         connector.SetState(STATE_CONNECTED);
00195                         this->connectors.push_back(connector);
00196                         return this->SendPacket(connect, servername);
00197                 }
00198                 else
00199                 {
00200                         connector.SetState(STATE_DISCONNECTED);
00201                         WriteOpers("Could not create outbound connection to %s:%d",targethost,newport);
00202                 }
00203         }
00204         return false;
00205 }

bool serverrec::RecvPacket std::deque< std::string > &  messages,
char *  host,
std::deque< std::string > &  sums
 

Returns the next available packet and returns true if data is available.

Writes the servername the data came from to 'host'. If no data is available this function returns false. This function will automatically close broken links and reroute pathways, generating split messages on the network.

Definition at line 370 of file servers.cpp.

References already_have_sum(), connectors, DEBUG, and STATE_DISCONNECTED.

00371 {
00372         char data[65536];
00373         memset(data, 0, 65536);
00374         for (int i = 0; i < this->connectors.size(); i++)
00375         {
00376                 if (this->connectors[i].GetState() != STATE_DISCONNECTED)
00377                 {
00378                         // returns false if the packet could not be sent (e.g. target host down)
00379                         int rcvsize = 0;
00380 
00381                         // check if theres any data on this socket
00382                         // if not, continue onwards to the next.
00383                         pollfd polls;
00384                         polls.fd = this->connectors[i].GetDescriptor();
00385                         polls.events = POLLIN;
00386                         int ret = poll(&polls,1,1);
00387                         if (ret <= 0) continue;
00388 
00389                         rcvsize = recv(this->connectors[i].GetDescriptor(),data,65000,0);
00390                         data[rcvsize] = '\0';
00391                         if (rcvsize == -1)
00392                         {
00393                                 if (errno != EAGAIN)
00394                                 {
00395                                         log(DEBUG,"recv() failed for serverrec::RecvPacket(): %s",strerror(errno));
00396                                         log(DEBUG,"Disabling connector: %s",this->connectors[i].GetServerName().c_str());
00397                                         this->connectors[i].CloseConnection();
00398                                         this->connectors[i].SetState(STATE_DISCONNECTED);
00399                                 }
00400                         }
00401                         int pushed = 0;
00402                         if (rcvsize > 0)
00403                         {
00404                                 if (!this->connectors[i].AddBuffer(data))
00405                                 {
00406                                         WriteOpers("*** Read buffer for %s exceeds maximum, closing connection!",this->connectors[i].GetServerName().c_str());
00407                                         this->connectors[i].CloseConnection();
00408                                         this->connectors[i].SetState(STATE_DISCONNECTED);
00409                                 }
00410                                 if (this->connectors[i].BufferIsComplete())
00411                                 {
00412                                         this->connectors[i].ResetPing();
00413                                         while (this->connectors[i].BufferIsComplete())
00414                                         {
00415                                                 std::string text = this->connectors[i].GetBuffer();
00416                                                 if (text != "")
00417                                                 {
00418                                                         if ((text[0] == ':') && (text.find(" ") != std::string::npos))
00419                                                         {
00420                                                                 std::string orig = text;
00421                                                                 log(DEBUG,"Original: %s",text.c_str());
00422                                                                 std::string sum = text.substr(1,text.find(" ")-1);
00423                                                                 text = text.substr(text.find(" ")+1,text.length());
00424                                                                 std::string possible_token = text.substr(1,text.find(" ")-1);
00425                                                                 if (possible_token.length() > 1)
00426                                                                 {
00427                                                                         sums.push_back("*");
00428                                                                         text = orig;
00429                                                                         log(DEBUG,"Non-mesh, non-tokenized string passed up the chain");
00430                                                                 }
00431                                                                 else
00432                                                                 {
00433                                                                         log(DEBUG,"Packet sum: '%s'",sum.c_str());
00434                                                                         if ((already_have_sum(sum)) && (sum != "*"))
00435                                                                         {
00436                                                                                 // we don't accept dupes
00437                                                                                 continue;
00438                                                                         }
00439                                                                         sums.push_back(sum.c_str());
00440                                                                 }
00441                                                         }
00442                                                         else sums.push_back("*");
00443                                                         messages.push_back(text.c_str());
00444                                                         strlcpy(recvhost,this->connectors[i].GetServerName().c_str(),160);
00445                                                         log(DEBUG,"serverrec::RecvPacket() %d:%s->%s",pushed++,recvhost,text.c_str());
00446                                                 }
00447                                         }
00448                                         return true;
00449                                 }
00450                         }
00451                 }
00452         }
00453         // nothing new yet -- message and host will be undefined
00454         return false;
00455 }

bool serverrec::SendPacket char *  message,
const char *  host
 

Send a message to a server by name, if the server is unavailable directly route the packet via another server If the server still cannot be reached after attempting to route the message remotely, returns false.

Definition at line 275 of file servers.cpp.

References ircd_connector::AddWriteBuf(), ircd_connector::CloseConnection(), connectors, DEBUG, FindHost(), ircd_connector::FlushWriteBuf(), ircd_connector::GetServerName(), ircd_connector::GetState(), ircd_connector::GetWriteError(), ircd_connector::SetState(), and STATE_DISCONNECTED.

Referenced by BeginLink(), and MeshCookie().

00276 {
00277         if ((!message) || (!sendhost))
00278                 return true;
00279 
00280         ircd_connector* cn = this->FindHost(sendhost);
00281 
00282         if (!strchr(message,'\n'))
00283         {
00284                 strlcat(message,"\n",MAXBUF);
00285         }
00286 
00287         if (cn)
00288         {
00289                 log(DEBUG,"main: serverrec::SendPacket() sent '%s' to %s",message,cn->GetServerName().c_str());
00290 
00291                 if (cn->GetState() == STATE_DISCONNECTED)
00292                 {
00293                         // fix: can only route one hop to avoid a loop
00294                         if (strncmp(message,"R ",2))
00295                         {
00296                                 log(DEBUG,"Not a double reroute");
00297                                 // this route is down, we must re-route the packet through an available point in the mesh.
00298                                 for (int k = 0; k < this->connectors.size(); k++)
00299                                 {
00300                                         log(DEBUG,"Check connector %d: %s",k,this->connectors[k].GetServerName().c_str());
00301                                         // search for another point in the mesh which can 'reach' where we want to go
00302                                         for (int m = 0; m < this->connectors[k].routes.size(); m++)
00303                                         {
00304                                                 if (!strcasecmp(this->connectors[k].routes[m].c_str(),sendhost))
00305                                                 {
00306                                                         log(DEBUG,"Found alternative route for packet: %s",this->connectors[k].GetServerName().c_str());
00307                                                         char buffer[MAXBUF];
00308                                                         snprintf(buffer,MAXBUF,"R %s %s",sendhost,message);
00309                                                         this->SendPacket(buffer,this->connectors[k].GetServerName().c_str());
00310                                                         return true;
00311                                                 }
00312                                         }
00313                                 }
00314                         }
00315                         char buffer[MAXBUF];
00316                         snprintf(buffer,MAXBUF,"& %s",sendhost);
00317                         WriteOpers("*** All connections to %s lost.",sendhost);
00318                         NetSendToAllExcept(sendhost,buffer);
00319                         DoSplit(sendhost);
00320                         return false;
00321                 }
00322 
00323                 // returns false if the packet could not be sent (e.g. target host down)
00324                 if (!cn->AddWriteBuf(message))
00325                 {
00326                         // if we're here, there was an error pending, and the send cannot proceed
00327                         log(DEBUG,"cn->AddWriteBuf() failed for serverrec::SendPacket(): %s",cn->GetWriteError().c_str());
00328                         log(DEBUG,"Disabling connector: %s",cn->GetServerName().c_str());
00329                         cn->CloseConnection();
00330                         cn->SetState(STATE_DISCONNECTED);
00331                         WriteOpers("*** Lost single connection to %s, link inactive and retrying: %s",cn->GetServerName().c_str(),cn->GetWriteError().c_str());
00332                         // retry the packet along a new route so either arrival OR failure are gauranteed (bugfix)
00333                         return this->SendPacket(message,sendhost);
00334                 }
00335                 if (!cn->FlushWriteBuf())
00336                 {
00337                         // if we're here the write() caused an error, we cannot proceed
00338                         log(DEBUG,"cn->FlushWriteBuf() failed for serverrec::SendPacket(): %s",cn->GetWriteError().c_str());
00339                         log(DEBUG,"Disabling connector: %s",cn->GetServerName().c_str());
00340                         cn->CloseConnection();
00341                         cn->SetState(STATE_DISCONNECTED);
00342                         WriteOpers("*** Lost single connection to %s, link inactive and retrying: %s",cn->GetServerName().c_str(),cn->GetWriteError().c_str());
00343                         // retry the packet along a new route so either arrival OR failure are gauranteed
00344                         return this->SendPacket(message,sendhost);
00345                 }
00346                 return true;
00347         }
00348 }

void serverrec::TerminateLink char *  targethost  ) 
 

Terminate a link to 'targethost' by calling the ircd_connector::CloseConnection method.

Definition at line 229 of file servers.cpp.

00230 {
00231         // this locates the targethost in the serverrec::connectors vector of the class,
00232         // and terminates it by sending it an SQUIT token and closing its descriptor.
00233         // TerminateLink with a null string causes a terminate of ALL links
00234 }


Member Data Documentation

std::vector<ircd_connector> serverrec::connectors
 

With a serverrec, this is a list of all established server connections.

Definition at line 81 of file servers.h.

Referenced by AddIncoming(), BeginLink(), FindHost(), FlushWriteBuffers(), MeshCookie(), RecvPacket(), SendPacket(), and serverrec().

char serverrec::description[MAXBUF]
 

Description of the server.

Definition at line 61 of file servers.h.

int serverrec::hops_away
 

number of hops away (for quick access)

Definition at line 51 of file servers.h.

Referenced by serverrec().

bool serverrec::jupiter
 

is a JUPE server (faked to enforce a server ban)

Definition at line 57 of file servers.h.

Referenced by serverrec().

char serverrec::name[MAXBUF]
 

server name

Definition at line 36 of file servers.h.

Referenced by serverrec().

char serverrec::nickserv[NICKMAX]
 

Holds nickserv's name on U:lined (services) servers (this is a kludge for ircservices which ASSUMES things :/).

Definition at line 65 of file servers.h.

Referenced by serverrec().

long serverrec::opercount
 

opers on server

Definition at line 48 of file servers.h.

Referenced by serverrec().

long serverrec::pingtime
 

last ping response (ms)

Definition at line 39 of file servers.h.

Referenced by serverrec().

bool serverrec::sync_soon
 

Definition at line 67 of file servers.h.

Referenced by serverrec().

long serverrec::usercount
 

non-invisible users on server

Definition at line 45 of file servers.h.

Referenced by serverrec().

long serverrec::usercount_i
 

invisible users on server

Definition at line 42 of file servers.h.

Referenced by serverrec().

long serverrec::version
 

ircd version

Definition at line 54 of file servers.h.

Referenced by serverrec().


The documentation for this class was generated from the following files:
Generated on Tue May 24 02:32:39 2005 for InspIRCd by doxygen 1.3.3