From 66f0cd6469d2643858c2fcd14726d362696bd68d Mon Sep 17 00:00:00 2001 From: brain Date: Tue, 24 May 2005 02:34:33 +0000 Subject: New methods, new docs git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@1484 e03df62e-2008-0410-955e-edbf42e46eb7 --- docs/module-doc/servers_8cpp-source.html | 483 ++++++++++++++++++++++++++++--- 1 file changed, 440 insertions(+), 43 deletions(-) (limited to 'docs/module-doc/servers_8cpp-source.html') diff --git a/docs/module-doc/servers_8cpp-source.html b/docs/module-doc/servers_8cpp-source.html index 64824c917..306245ef0 100644 --- a/docs/module-doc/servers_8cpp-source.html +++ b/docs/module-doc/servers_8cpp-source.html @@ -21,50 +21,447 @@ 00014 * --------------------------------------------------- 00015 */ 00016 -00017 #include "inspircd_config.h" -00018 #include "servers.h" -00019 #include "inspircd.h" -00020 #include <stdio.h> -00021 #include <map> -00022 #include "inspstring.h" -00023 #include "helperfuncs.h" -00024 -00025 extern time_t TIME; -00026 -00027 serverrec::serverrec() -00028 { -00029 strlcpy(name,"",256); -00030 pingtime = 0; -00031 lastping = TIME; -00032 usercount_i = usercount = opercount = version = 0; -00033 hops_away = 1; -00034 signon = TIME; -00035 jupiter = false; -00036 fd = 0; -00037 sync_soon = false; -00038 strlcpy(nickserv,"",NICKMAX); -00039 } -00040 -00041 -00042 serverrec::~serverrec() +00017 using namespace std; +00018 +00019 #include "inspircd_config.h" +00020 #include "servers.h" +00021 #include "inspircd.h" +00022 #include <unistd.h> +00023 #include <fcntl.h> +00024 #include <poll.h> +00025 #include <sys/errno.h> +00026 #include <sys/ioctl.h> +00027 #include <sys/utsname.h> +00028 #include <vector> +00029 #include <string> +00030 #include <deque> +00031 #include <sstream> +00032 #include <map> +00033 #include "inspstring.h" +00034 #include "helperfuncs.h" +00035 #include "connection.h" +00036 +00037 extern time_t TIME; +00038 extern int MaxConn; +00039 +00040 std::deque<std::string> xsums; +00041 +00042 serverrec::serverrec() 00043 { -00044 } -00045 -00046 serverrec::serverrec(char* n, long ver, bool jupe) -00047 { -00048 strlcpy(name,n,256); -00049 lastping = TIME; -00050 usercount_i = usercount = opercount = 0; -00051 version = ver; -00052 hops_away = 1; -00053 signon = TIME; -00054 jupiter = jupe; -00055 fd = 0; -00056 sync_soon = false; -00057 strlcpy(nickserv,"",NICKMAX); -00058 } -00059 -
Generated on Sun May 15 18:36:02 2005 for InspIRCd by +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 } +00056 +00057 +00058 serverrec::~serverrec() +00059 { +00060 } +00061 +00062 serverrec::serverrec(char* n, long ver, bool jupe) +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 } +00076 +00077 bool serverrec::CreateListener(char* newhost, int p) +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 } +00136 +00137 +00138 bool serverrec::BeginLink(char* targethost, int newport, char* password, char* servername, int myport) +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 } +00174 +00175 +00176 bool serverrec::MeshCookie(char* targethost, int newport, unsigned long cookie, char* servername) +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 } +00206 +00207 bool serverrec::AddIncoming(int newfd, char* targethost, int sourceport) +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 } +00228 +00229 void serverrec::TerminateLink(char* targethost) +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 } +00235 +00236 // Returns a pointer to the connector for 'host' +00237 ircd_connector* serverrec::FindHost(std::string findhost) +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 } +00248 +00249 void serverrec::FlushWriteBuffers() +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 } +00274 +00275 bool serverrec::SendPacket(char *message, const char* sendhost) +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 } +00349 +00350 bool already_have_sum(std::string sum) +00351 { +00352 for (int i = 0; i < xsums.size(); i++) +00353 { +00354 if (xsums[i] == sum) +00355 { +00356 return true; +00357 } +00358 } +00359 if (xsums.size() >= 128) +00360 { +00361 xsums.pop_front(); +00362 } +00363 xsums.push_back(sum); +00364 return false; +00365 } +00366 +00367 // receives a packet from any where there is data waiting, first come, first served +00368 // fills the message and host values with the host where the data came from. +00369 +00370 bool serverrec::RecvPacket(std::deque<std::string> &messages, char* recvhost,std::deque<std::string> &sums) +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 } +00456 +
Generated on Tue May 24 02:30:06 2005 for InspIRCd by doxygen 1.3.3
-- cgit v1.2.3