From 4e9f3d169285127e60dc9e0437925c90600bfe05 Mon Sep 17 00:00:00 2001 From: brain Date: Wed, 25 May 2005 22:01:10 +0000 Subject: Added parameters git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@1522 e03df62e-2008-0410-955e-edbf42e46eb7 --- docs/module-doc/servers_8cpp-source.html | 885 +++++++++++++++++-------------- 1 file changed, 479 insertions(+), 406 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 306245ef0..4e57b19f7 100644 --- a/docs/module-doc/servers_8cpp-source.html +++ b/docs/module-doc/servers_8cpp-source.html @@ -44,424 +44,497 @@ 00037 extern time_t TIME; 00038 extern int MaxConn; 00039 -00040 std::deque<std::string> xsums; +00040 extern serverrec* me[32]; 00041 -00042 serverrec::serverrec() -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 } -00056 -00057 -00058 serverrec::~serverrec() -00059 { -00060 } -00061 -00062 serverrec::serverrec(char* n, long ver, bool jupe) +00042 extern bool has_been_netsplit; +00043 +00044 std::deque<std::string> xsums; +00045 +00046 serverrec::serverrec() +00047 { +00048 strlcpy(name,"",256); +00049 pingtime = 0; +00050 lastping = TIME; +00051 usercount_i = usercount = opercount = version = 0; +00052 hops_away = 1; +00053 signon = TIME; +00054 jupiter = false; +00055 fd = 0; +00056 sync_soon = false; +00057 strlcpy(nickserv,"",NICKMAX); +00058 connectors.clear(); +00059 } +00060 +00061 +00062 serverrec::~serverrec() 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; +00064 } +00065 +00066 serverrec::serverrec(char* n, long ver, bool jupe) +00067 { +00068 strlcpy(name,n,256); +00069 lastping = TIME; +00070 usercount_i = usercount = opercount = 0; +00071 version = ver; +00072 hops_away = 1; +00073 signon = TIME; +00074 jupiter = jupe; +00075 fd = 0; +00076 sync_soon = false; +00077 strlcpy(nickserv,"",NICKMAX); +00078 connectors.clear(); +00079 } +00080 +00081 bool serverrec::CreateListener(char* newhost, int p) +00082 { +00083 sockaddr_in host_address; +00084 int flags; +00085 in_addr addy; +00086 int on = 0; +00087 struct linger linger = { 0 }; +00088 +00089 this->port = p; +00090 +00091 fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); +00092 if (fd <= 0) +00093 { +00094 return false; +00095 } +00096 +00097 setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(const char*)&on,sizeof(on)); +00098 linger.l_onoff = 1; +00099 linger.l_linger = 1; +00100 setsockopt(fd,SOL_SOCKET,SO_LINGER,(const char*)&linger,sizeof(linger)); +00101 +00102 // attempt to increase socket sendq and recvq as high as its possible +00103 // to get them on linux. +00104 int sendbuf = 32768; +00105 int recvbuf = 32768; +00106 setsockopt(fd,SOL_SOCKET,SO_SNDBUF,(const void *)&sendbuf,sizeof(sendbuf)); +00107 setsockopt(fd,SOL_SOCKET,SO_RCVBUF,(const void *)&recvbuf,sizeof(sendbuf)); 00108 -00109 if (!strcmp(newhost,"")) -00110 { -00111 host_address.sin_addr.s_addr = htonl(INADDR_ANY); -00112 } -00113 else +00109 memset((void*)&host_address, 0, sizeof(host_address)); +00110 +00111 host_address.sin_family = AF_INET; +00112 +00113 if (!strcmp(newhost,"")) 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); +00115 host_address.sin_addr.s_addr = htonl(INADDR_ANY); +00116 } +00117 else +00118 { +00119 inet_aton(newhost,&addy); +00120 host_address.sin_addr = addy; +00121 } +00122 +00123 host_address.sin_port = htons(p); +00124 +00125 if (bind(fd,(sockaddr*)&host_address,sizeof(host_address))<0) +00126 { +00127 return false; +00128 } 00129 -00130 this->port = p; -00131 -00132 listen(this->fd, MaxConn); +00130 // make the socket non-blocking +00131 flags = fcntl(fd, F_GETFL, 0); +00132 fcntl(fd, F_SETFL, flags | O_NONBLOCK); 00133 -00134 return true; -00135 } -00136 +00134 this->port = p; +00135 +00136 listen(this->fd, MaxConn); 00137 -00138 bool serverrec::BeginLink(char* targethost, int newport, char* password, char* servername, int myport) -00139 { -00140 char connect[MAXBUF]; +00138 return true; +00139 } +00140 00141 -00142 ircd_connector connector; -00143 ircd_connector *cn = this->FindHost(servername); -00144 +00142 bool serverrec::BeginLink(char* targethost, int newport, char* password, char* servername, int myport) +00143 { +00144 char connect[MAXBUF]; 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; +00146 ircd_connector connector; +00147 ircd_connector *cn = this->FindHost(servername); +00148 +00149 +00150 if (cn) +00151 { +00152 WriteOpers("CONNECT aborted: Server %s already exists",servername); +00153 return false; +00154 } +00155 +00156 +00157 if (this->fd) +00158 { +00159 if (connector.MakeOutboundConnection(targethost,newport)) +00160 { +00161 // targethost has been turned into an ip... +00162 // we dont want this as the server name. +00163 connector.SetServerName(servername); +00164 snprintf(connect,MAXBUF,"S %s %s %lu %s :%s",getservername().c_str(),password,(unsigned long)myport,GetRevision().c_str(),getserverdesc().c_str()); +00165 connector.SetState(STATE_NOAUTH_OUTBOUND); +00166 connector.SetHostAndPort(targethost, newport); +00167 this->connectors.push_back(connector); +00168 // this packet isn't actually sent until the socket connects -- the STATE_NOAUTH_OUTBOUND state +00169 // queues outbound data until the socket is polled as writeable (e.g. the connection is established) +00170 return this->SendPacket(connect, servername); +00171 } +00172 else +00173 { +00174 connector.SetState(STATE_DISCONNECTED); +00175 WriteOpers("Could not create outbound connection to %s:%d",targethost,newport); +00176 } +00177 } +00178 return false; +00179 } +00180 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); +00182 bool serverrec::MeshCookie(char* targethost, int newport, unsigned long cookie, char* servername) +00183 { +00184 char connect[MAXBUF]; +00185 +00186 ircd_connector connector; +00187 +00188 WriteOpers("Establishing meshed link to %s:%d",servername,newport); +00189 +00190 if (this->fd) +00191 { +00192 if (connector.MakeOutboundConnection(targethost,newport)) +00193 { +00194 // targethost has been turned into an ip... +00195 // we dont want this as the server name. +00196 connector.SetServerName(servername); +00197 snprintf(connect,MAXBUF,"- %lu %s :%s",cookie,getservername().c_str(),getserverdesc().c_str()); +00198 connector.SetState(STATE_NOAUTH_OUTBOUND); +00199 connector.SetHostAndPort(targethost, newport); +00200 this->connectors.push_back(connector); +00201 return this->SendPacket(connect, servername); 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 } +00203 else +00204 { +00205 connector.SetState(STATE_DISCONNECTED); +00206 WriteOpers("Could not create outbound connection to %s:%d",targethost,newport); +00207 } +00208 } +00209 return false; +00210 } +00211 +00212 bool serverrec::AddIncoming(int newfd, char* targethost, int sourceport) +00213 { +00214 ircd_connector connector; +00215 +00216 // targethost has been turned into an ip... +00217 // we dont want this as the server name. +00218 connector.SetServerName(targethost); +00219 connector.SetDescriptor(newfd); +00220 connector.SetState(STATE_NOAUTH_INBOUND); +00221 int flags = fcntl(newfd, F_GETFL, 0); +00222 fcntl(newfd, F_SETFL, flags | O_NONBLOCK); +00223 int sendbuf = 32768; +00224 int recvbuf = 32768; +00225 setsockopt(newfd,SOL_SOCKET,SO_SNDBUF,(const void *)&sendbuf,sizeof(sendbuf)); +00226 setsockopt(newfd,SOL_SOCKET,SO_RCVBUF,(const void *)&recvbuf,sizeof(sendbuf)); +00227 connector.SetHostAndPort(targethost, sourceport); +00228 connector.SetState(STATE_NOAUTH_INBOUND); +00229 log(DEBUG,"serverrec::AddIncoming() Added connection: %s:%d",targethost,sourceport); +00230 this->connectors.push_back(connector); +00231 return true; +00232 } +00233 +00234 void serverrec::TerminateLink(char* targethost) +00235 { +00236 // this locates the targethost in the serverrec::connectors vector of the class, +00237 // and terminates it by sending it an SQUIT token and closing its descriptor. +00238 // TerminateLink with a null string causes a terminate of ALL links +00239 } +00240 +00241 // Returns a pointer to the connector for 'host' +00242 ircd_connector* serverrec::FindHost(std::string findhost) +00243 { +00244 for (int i = 0; i < this->connectors.size(); i++) +00245 { +00246 if (this->connectors[i].GetServerName() == findhost) +00247 { +00248 return &this->connectors[i]; +00249 } +00250 } +00251 return NULL; +00252 } +00253 +00254 +00255 // Checks to see if we can still reach a server at all (e.g. is it in ANY routing table?) +00256 bool IsRoutable(std::string servername) +00257 { +00258 for (int x = 0; x < 32; x++) if (me[x]) +00259 { +00260 ircd_connector* cn = me[x]->FindHost(servername.c_str()); +00261 if (cn) +00262 { +00263 if (cn->GetState() == STATE_DISCONNECTED) +00264 { +00265 for (int k = 0; k < me[x]->connectors.size(); k++) +00266 { +00267 for (int m = 0; m < me[x]->connectors[k].routes.size(); m++) +00268 { +00269 if (!strcasecmp(me[x]->connectors[k].routes[m].c_str(),servername.c_str())) +00270 { +00271 return true; +00272 } +00273 } +00274 } +00275 return false; +00276 } +00277 else return true; +00278 } +00279 } +00280 return false; +00281 } +00282 +00283 +00284 void serverrec::FlushWriteBuffers() +00285 { +00286 for (int i = 0; i < this->connectors.size(); i++) +00287 { +00288 // don't try and ping a NOAUTH_OUTBOUND state, its not authed yet! +00289 if ((this->connectors[i].GetState() == STATE_NOAUTH_OUTBOUND) && (TIME > this->connectors[i].age+30)) +00290 { +00291 // however if we reach this timer its connected timed out :) +00292 WriteOpers("*** Connection to %s timed out",this->connectors[i].GetServerName().c_str()); +00293 DoSplit(this->connectors[i].GetServerName().c_str()); +00294 return; +00295 } +00296 else if ((this->connectors[i].GetState() == STATE_NOAUTH_INBOUND) && (TIME > this->connectors[i].age+30)) +00297 { +00298 WriteOpers("*** Connection from %s timed out",this->connectors[i].GetServerName().c_str()); +00299 DoSplit(this->connectors[i].GetServerName().c_str()); +00300 return; +00301 } +00302 else if (this->connectors[i].GetState() != STATE_DISCONNECTED) +00303 { +00304 if (!this->connectors[i].CheckPing()) +00305 { +00306 WriteOpers("*** Lost single connection to %s: Ping timeout",this->connectors[i].GetServerName().c_str()); +00307 this->connectors[i].CloseConnection(); +00308 this->connectors[i].SetState(STATE_DISCONNECTED); +00309 if (!IsRoutable(this->connectors[i].GetServerName())) +00310 { +00311 WriteOpers("*** Server %s is no longer routable, disconnecting.",this->connectors[i].GetServerName().c_str()); +00312 DoSplit(this->connectors[i].GetServerName().c_str()); 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 +00314 has_been_netsplit = true; +00315 } +00316 } +00317 if (this->connectors[i].HasBufferedOutput()) +00318 { +00319 if (!this->connectors[i].FlushWriteBuf()) +00320 { +00321 // if we're here the write() caused an error, we cannot proceed +00322 WriteOpers("*** Lost single connection to %s, link inactive and retrying: %s",this->connectors[i].GetServerName().c_str(),this->connectors[i].GetWriteError().c_str()); +00323 this->connectors[i].CloseConnection(); +00324 this->connectors[i].SetState(STATE_DISCONNECTED); +00325 if (!IsRoutable(this->connectors[i].GetServerName())) +00326 { +00327 WriteOpers("*** Server %s is no longer routable, disconnecting.",this->connectors[i].GetServerName().c_str()); +00328 DoSplit(this->connectors[i].GetServerName().c_str()); +00329 } +00330 has_been_netsplit = true; +00331 } +00332 } +00333 } +00334 } +00335 +00336 bool serverrec::SendPacket(char *message, const char* sendhost) +00337 { +00338 if ((!message) || (!sendhost)) +00339 return true; +00340 +00341 ircd_connector* cn = this->FindHost(sendhost); +00342 +00343 if (!strchr(message,'\n')) +00344 { +00345 strlcat(message,"\n",MAXBUF); +00346 } +00347 +00348 if (cn) +00349 { +00350 log(DEBUG,"main: serverrec::SendPacket() sent '%s' to %s",message,cn->GetServerName().c_str()); +00351 +00352 if (cn->GetState() == STATE_DISCONNECTED) +00353 { +00354 // fix: can only route one hop to avoid a loop +00355 if (strncmp(message,"R ",2)) +00356 { +00357 log(DEBUG,"Not a double reroute"); +00358 // this route is down, we must re-route the packet through an available point in the mesh. +00359 for (int k = 0; k < this->connectors.size(); k++) +00360 { +00361 log(DEBUG,"Check connector %d: %s",k,this->connectors[k].GetServerName().c_str()); +00362 // search for another point in the mesh which can 'reach' where we want to go +00363 for (int m = 0; m < this->connectors[k].routes.size(); m++) +00364 { +00365 if (!strcasecmp(this->connectors[k].routes[m].c_str(),sendhost)) +00366 { +00367 log(DEBUG,"Found alternative route for packet: %s",this->connectors[k].GetServerName().c_str()); +00368 char buffer[MAXBUF]; +00369 snprintf(buffer,MAXBUF,"R %s %s",sendhost,message); +00370 this->SendPacket(buffer,this->connectors[k].GetServerName().c_str()); +00371 return true; +00372 } +00373 } +00374 } +00375 } +00376 char buffer[MAXBUF]; +00377 snprintf(buffer,MAXBUF,"& %s",sendhost); +00378 WriteOpers("*** All connections to %s lost.",sendhost); +00379 NetSendToAllExcept(sendhost,buffer); +00380 DoSplit(sendhost); +00381 return false; +00382 } +00383 +00384 // returns false if the packet could not be sent (e.g. target host down) +00385 if (!cn->AddWriteBuf(message)) +00386 { +00387 // if we're here, there was an error pending, and the send cannot proceed +00388 log(DEBUG,"cn->AddWriteBuf() failed for serverrec::SendPacket(): %s",cn->GetWriteError().c_str()); +00389 log(DEBUG,"Disabling connector: %s",cn->GetServerName().c_str()); +00390 cn->CloseConnection(); +00391 cn->SetState(STATE_DISCONNECTED); +00392 WriteOpers("*** Lost single connection to %s, link inactive and retrying: %s",cn->GetServerName().c_str(),cn->GetWriteError().c_str()); +00393 // retry the packet along a new route so either arrival OR failure are gauranteed (bugfix) +00394 return this->SendPacket(message,sendhost); +00395 } +00396 if (!cn->FlushWriteBuf()) +00397 { +00398 // if we're here the write() caused an error, we cannot proceed +00399 log(DEBUG,"cn->FlushWriteBuf() failed for serverrec::SendPacket(): %s",cn->GetWriteError().c_str()); +00400 log(DEBUG,"Disabling connector: %s",cn->GetServerName().c_str()); +00401 cn->CloseConnection(); +00402 cn->SetState(STATE_DISCONNECTED); +00403 WriteOpers("*** Lost single connection to %s, link inactive and retrying: %s",cn->GetServerName().c_str(),cn->GetWriteError().c_str()); +00404 // retry the packet along a new route so either arrival OR failure are gauranteed +00405 return this->SendPacket(message,sendhost); +00406 } +00407 return true; +00408 } +00409 } +00410 +00411 bool already_have_sum(std::string sum) +00412 { +00413 for (int i = 0; i < xsums.size(); i++) +00414 { +00415 if (xsums[i] == sum) +00416 { +00417 return true; +00418 } +00419 } +00420 if (xsums.size() >= 128) +00421 { +00422 xsums.pop_front(); +00423 } +00424 xsums.push_back(sum); +00425 return false; +00426 } +00427 +00428 // receives a packet from any where there is data waiting, first come, first served +00429 // fills the message and host values with the host where the data came from. +00430 +00431 bool serverrec::RecvPacket(std::deque<std::string> &messages, char* recvhost,std::deque<std::string> &sums) +00432 { +00433 char data[65536]; +00434 memset(data, 0, 65536); +00435 for (int i = 0; i < this->connectors.size(); i++) +00436 { +00437 if (this->connectors[i].GetState() != STATE_DISCONNECTED) +00438 { +00439 // returns false if the packet could not be sent (e.g. target host down) +00440 int rcvsize = 0; +00441 +00442 // check if theres any data on this socket +00443 // if not, continue onwards to the next. +00444 pollfd polls; +00445 polls.fd = this->connectors[i].GetDescriptor(); +00446 polls.events = POLLIN; +00447 int ret = poll(&polls,1,1); +00448 if (ret <= 0) continue; +00449 +00450 rcvsize = recv(this->connectors[i].GetDescriptor(),data,65000,0); +00451 data[rcvsize] = '\0'; +00452 if (rcvsize == -1) +00453 { +00454 if (errno != EAGAIN) +00455 { +00456 log(DEBUG,"recv() failed for serverrec::RecvPacket(): %s",strerror(errno)); +00457 log(DEBUG,"Disabling connector: %s",this->connectors[i].GetServerName().c_str()); +00458 this->connectors[i].CloseConnection(); +00459 this->connectors[i].SetState(STATE_DISCONNECTED); +00460 if (!IsRoutable(this->connectors[i].GetServerName())) +00461 { +00462 WriteOpers("*** Server %s is no longer routable, disconnecting.",this->connectors[i].GetServerName().c_str()); +00463 DoSplit(this->connectors[i].GetServerName().c_str()); +00464 } +00465 has_been_netsplit = true; +00466 } +00467 } +00468 int pushed = 0; +00469 if (rcvsize > 0) +00470 { +00471 if (!this->connectors[i].AddBuffer(data)) +00472 { +00473 WriteOpers("*** Read buffer for %s exceeds maximum, closing connection!",this->connectors[i].GetServerName().c_str()); +00474 this->connectors[i].CloseConnection(); +00475 this->connectors[i].SetState(STATE_DISCONNECTED); +00476 if (!IsRoutable(this->connectors[i].GetServerName())) +00477 { +00478 WriteOpers("*** Server %s is no longer routable, disconnecting.",this->connectors[i].GetServerName().c_str()); +00479 DoSplit(this->connectors[i].GetServerName().c_str()); +00480 } +00481 has_been_netsplit = true; +00482 } +00483 if (this->connectors[i].BufferIsComplete()) +00484 { +00485 this->connectors[i].ResetPing(); +00486 while (this->connectors[i].BufferIsComplete()) +00487 { +00488 std::string text = this->connectors[i].GetBuffer(); +00489 if (text != "") +00490 { +00491 if ((text[0] == ':') && (text.find(" ") != std::string::npos)) +00492 { +00493 std::string orig = text; +00494 log(DEBUG,"Original: %s",text.c_str()); +00495 std::string sum = text.substr(1,text.find(" ")-1); +00496 text = text.substr(text.find(" ")+1,text.length()); +00497 std::string possible_token = text.substr(1,text.find(" ")-1); +00498 if (possible_token.length() > 1) +00499 { +00500 sums.push_back("*"); +00501 text = orig; +00502 log(DEBUG,"Non-mesh, non-tokenized string passed up the chain"); +00503 } +00504 else +00505 { +00506 log(DEBUG,"Packet sum: '%s'",sum.c_str()); +00507 if ((already_have_sum(sum)) && (sum != "*")) +00508 { +00509 // we don't accept dupes +00510 continue; +00511 } +00512 sums.push_back(sum.c_str()); +00513 } +00514 } +00515 else sums.push_back("*"); +00516 messages.push_back(text.c_str()); +00517 strlcpy(recvhost,this->connectors[i].GetServerName().c_str(),160); +00518 log(DEBUG,"serverrec::RecvPacket() %d:%s->%s",pushed++,recvhost,text.c_str()); +00519 } +00520 } +00521 return true; +00522 } +00523 } +00524 } +00525 } +00526 // nothing new yet -- message and host will be undefined +00527 return false; +00528 } +00529 +
Generated on Wed May 25 21:42:14 2005 for InspIRCd by doxygen 1.3.3
-- cgit v1.2.3