#include <servers.h>
Inheritance diagram for serverrec:
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_connector * | FindHost (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_connector > | connectors |
With a serverrec, this is a list of all established server connections. |
Definition at line 30 of file servers.h.
|
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 } |
|
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.
|
|
Destructor.
Definition at line 58 of file servers.cpp.
00059 { 00060 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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(). |
|
Description of the server.
|
|
number of hops away (for quick access)
Definition at line 51 of file servers.h. Referenced by serverrec(). |
|
is a JUPE server (faked to enforce a server ban)
Definition at line 57 of file servers.h. Referenced by serverrec(). |
|
server name
Definition at line 36 of file servers.h. Referenced by serverrec(). |
|
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(). |
|
opers on server
Definition at line 48 of file servers.h. Referenced by serverrec(). |
|
last ping response (ms)
Definition at line 39 of file servers.h. Referenced by serverrec(). |
|
Definition at line 67 of file servers.h. Referenced by serverrec(). |
|
non-invisible users on server
Definition at line 45 of file servers.h. Referenced by serverrec(). |
|
invisible users on server
Definition at line 42 of file servers.h. Referenced by serverrec(). |
|
ircd version
Definition at line 54 of file servers.h. Referenced by serverrec(). |