summaryrefslogtreecommitdiff
path: root/docs/man/man3/serverrec.3
diff options
context:
space:
mode:
Diffstat (limited to 'docs/man/man3/serverrec.3')
-rw-r--r--docs/man/man3/serverrec.3489
1 files changed, 266 insertions, 223 deletions
diff --git a/docs/man/man3/serverrec.3 b/docs/man/man3/serverrec.3
index 756987d57..428f509df 100644
--- a/docs/man/man3/serverrec.3
+++ b/docs/man/man3/serverrec.3
@@ -1,4 +1,4 @@
-.TH "serverrec" 3 "25 May 2005" "InspIRCd" \" -*- nroff -*-
+.TH "serverrec" 3 "30 May 2005" "InspIRCd" \" -*- nroff -*-
.ad l
.nh
.SH NAME
@@ -317,7 +317,7 @@ Find the \fBircd_connector\fP oject related to a certain servername given in 'ho
.PP
References connectors.
.PP
-Referenced by BeginLink(), IsRoutable(), and SendPacket().
+Referenced by BeginLink(), and SendPacket().
.PP
.nf
243 {
@@ -333,61 +333,85 @@ Referenced by BeginLink(), IsRoutable(), and SendPacket().
.fi
.SS "void serverrec::FlushWriteBuffers ()"
.PP
-Flushes all data waiting to be written for all of this server's connections. Definition at line 284 of file servers.cpp.
+Flushes all data waiting to be written for all of this server's connections. Definition at line 274 of file servers.cpp.
.PP
References connectors, has_been_netsplit, IsRoutable(), STATE_DISCONNECTED, STATE_NOAUTH_INBOUND, STATE_NOAUTH_OUTBOUND, and TIME.
.PP
.nf
-285 {
-286 for (int i = 0; i < this->connectors.size(); i++)
-287 {
-288 // don't try and ping a NOAUTH_OUTBOUND state, its not authed yet!
-289 if ((this->connectors[i].GetState() == STATE_NOAUTH_OUTBOUND) && (TIME > this->connectors[i].age+30))
+275 {
+276 char buffer[MAXBUF];
+277 for (int i = 0; i < this->connectors.size(); i++)
+278 {
+279 // don't try and ping a NOAUTH_OUTBOUND state, its not authed yet!
+280 if ((this->connectors[i].GetState() == STATE_NOAUTH_OUTBOUND) && (TIME > this->connectors[i].age+30))
+281 {
+282 // however if we reach this timer its connected timed out :)
+283 WriteOpers('*** Connection to %s timed out',this->connectors[i].GetServerName().c_str());
+284 snprintf(buffer,MAXBUF,'& %s',this->connectors[i].GetServerName().c_str());
+285 NetSendToAllExcept(this->connectors[i].GetServerName().c_str(),buffer);
+286 DoSplit(this->connectors[i].GetServerName().c_str());
+287 return;
+288 }
+289 if ((this->connectors[i].GetState() == STATE_NOAUTH_INBOUND) && (TIME > this->connectors[i].age+30))
290 {
-291 // however if we reach this timer its connected timed out :)
-292 WriteOpers('*** Connection to %s timed out',this->connectors[i].GetServerName().c_str());
-293 DoSplit(this->connectors[i].GetServerName().c_str());
-294 return;
-295 }
-296 else if ((this->connectors[i].GetState() == STATE_NOAUTH_INBOUND) && (TIME > this->connectors[i].age+30))
-297 {
-298 WriteOpers('*** Connection from %s timed out',this->connectors[i].GetServerName().c_str());
-299 DoSplit(this->connectors[i].GetServerName().c_str());
-300 return;
-301 }
-302 else if (this->connectors[i].GetState() != STATE_DISCONNECTED)
-303 {
-304 if (!this->connectors[i].CheckPing())
-305 {
-306 WriteOpers('*** Lost single connection to %s: Ping timeout',this->connectors[i].GetServerName().c_str());
-307 this->connectors[i].CloseConnection();
-308 this->connectors[i].SetState(STATE_DISCONNECTED);
-309 if (!IsRoutable(this->connectors[i].GetServerName()))
-310 {
-311 WriteOpers('*** Server %s is no longer routable, disconnecting.',this->connectors[i].GetServerName().c_str());
-312 DoSplit(this->connectors[i].GetServerName().c_str());
-313 }
-314 has_been_netsplit = true;
-315 }
-316 }
-317 if (this->connectors[i].HasBufferedOutput())
-318 {
-319 if (!this->connectors[i].FlushWriteBuf())
-320 {
-321 // if we're here the write() caused an error, we cannot proceed
-322 WriteOpers('*** Lost single connection to %s, link inactive and retrying: %s',this->connectors[i].GetServerName().c_str(),this->connectors[i].GetWriteError().c_str());
-323 this->connectors[i].CloseConnection();
-324 this->connectors[i].SetState(STATE_DISCONNECTED);
-325 if (!IsRoutable(this->connectors[i].GetServerName()))
-326 {
-327 WriteOpers('*** Server %s is no longer routable, disconnecting.',this->connectors[i].GetServerName().c_str());
-328 DoSplit(this->connectors[i].GetServerName().c_str());
-329 }
-330 has_been_netsplit = true;
-331 }
-332 }
-333 }
-334 }
+291 WriteOpers('*** Connection from %s timed out',this->connectors[i].GetServerName().c_str());
+292 snprintf(buffer,MAXBUF,'& %s',this->connectors[i].GetServerName().c_str());
+293 NetSendToAllExcept(this->connectors[i].GetServerName().c_str(),buffer);
+294 DoSplit(this->connectors[i].GetServerName().c_str());
+295 return;
+296 }
+297 if (this->connectors[i].GetState() != STATE_DISCONNECTED)
+298 {
+299 if (!this->connectors[i].CheckPing())
+300 {
+301 WriteOpers('*** Lost single connection to %s: Ping timeout',this->connectors[i].GetServerName().c_str());
+302 this->connectors[i].CloseConnection();
+303 this->connectors[i].SetState(STATE_DISCONNECTED);
+304 if (!IsRoutable(this->connectors[i].GetServerName()))
+305 {
+306 WriteOpers('*** Server %s is no longer routable, disconnecting.',this->connectors[i].GetServerName().c_str());
+307 snprintf(buffer,MAXBUF,'& %s',this->connectors[i].GetServerName().c_str());
+308 NetSendToAllExcept(this->connectors[i].GetServerName().c_str(),buffer);
+309 DoSplit(this->connectors[i].GetServerName().c_str());
+310 }
+311 has_been_netsplit = true;
+312 }
+313 }
+314 if ((this->connectors[i].GetWriteError() !='') && (this->connectors[i].GetState() != STATE_DISCONNECTED))
+315 {
+316 // if we're here the write() caused an error, we cannot proceed
+317 WriteOpers('*** Lost single connection to %s, link inactive and retrying: %s',this->connectors[i].GetServerName().c_str(),this->connectors[i].GetWriteError().c_str());
+318 this->connectors[i].CloseConnection();
+319 this->connectors[i].SetState(STATE_DISCONNECTED);
+320 if (!IsRoutable(this->connectors[i].GetServerName()))
+321 {
+322 WriteOpers('*** Server %s is no longer routable, disconnecting.',this->connectors[i].GetServerName().c_str());
+323 snprintf(buffer,MAXBUF,'& %s',this->connectors[i].GetServerName().c_str());
+324 NetSendToAllExcept(this->connectors[i].GetServerName().c_str(),buffer);
+325 DoSplit(this->connectors[i].GetServerName().c_str());
+326 }
+327 has_been_netsplit = true;
+328 }
+329 if ((this->connectors[i].HasBufferedOutput()) && (this->connectors[i].GetState() != STATE_DISCONNECTED))
+330 {
+331 if (!this->connectors[i].FlushWriteBuf())
+332 {
+333 // if we're here the write() caused an error, we cannot proceed
+334 WriteOpers('*** Lost single connection to %s, link inactive and retrying: %s',this->connectors[i].GetServerName().c_str(),this->connectors[i].GetWriteError().c_str());
+335 this->connectors[i].CloseConnection();
+336 this->connectors[i].SetState(STATE_DISCONNECTED);
+337 if (!IsRoutable(this->connectors[i].GetServerName()))
+338 {
+339 WriteOpers('*** Server %s is no longer routable, disconnecting.',this->connectors[i].GetServerName().c_str());
+340 snprintf(buffer,MAXBUF,'& %s',this->connectors[i].GetServerName().c_str());
+341 NetSendToAllExcept(this->connectors[i].GetServerName().c_str(),buffer);
+342 DoSplit(this->connectors[i].GetServerName().c_str());
+343 }
+344 has_been_netsplit = true;
+345 }
+346 }
+347 }
+348 }
.fi
.SS "bool serverrec::MeshCookie (char * targethost, int port, unsigned long cookie, char * servername)"
.PP
@@ -427,191 +451,210 @@ References connectors, connection::fd, ircd_connector::MakeOutboundConnection(),
.fi
.SS "bool serverrec::RecvPacket (std::deque< std::string > & messages, char * host, std::deque< std::string > & sums)"
.PP
-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 431 of file servers.cpp.
+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 445 of file servers.cpp.
.PP
References already_have_sum(), connectors, DEBUG, has_been_netsplit, IsRoutable(), and STATE_DISCONNECTED.
.PP
.nf
-432 {
-433 char data[65536];
-434 memset(data, 0, 65536);
-435 for (int i = 0; i < this->connectors.size(); i++)
-436 {
-437 if (this->connectors[i].GetState() != STATE_DISCONNECTED)
-438 {
-439 // returns false if the packet could not be sent (e.g. target host down)
-440 int rcvsize = 0;
-441
-442 // check if theres any data on this socket
-443 // if not, continue onwards to the next.
-444 pollfd polls;
-445 polls.fd = this->connectors[i].GetDescriptor();
-446 polls.events = POLLIN;
-447 int ret = poll(&polls,1,1);
-448 if (ret <= 0) continue;
-449
-450 rcvsize = recv(this->connectors[i].GetDescriptor(),data,65000,0);
-451 data[rcvsize] = '\0';
-452 if (rcvsize == -1)
-453 {
-454 if (errno != EAGAIN)
-455 {
-456 log(DEBUG,'recv() failed for serverrec::RecvPacket(): %s',strerror(errno));
-457 log(DEBUG,'Disabling connector: %s',this->connectors[i].GetServerName().c_str());
-458 this->connectors[i].CloseConnection();
-459 this->connectors[i].SetState(STATE_DISCONNECTED);
-460 if (!IsRoutable(this->connectors[i].GetServerName()))
-461 {
-462 WriteOpers('*** Server %s is no longer routable, disconnecting.',this->connectors[i].GetServerName().c_str());
-463 DoSplit(this->connectors[i].GetServerName().c_str());
-464 }
-465 has_been_netsplit = true;
-466 }
-467 }
-468 int pushed = 0;
-469 if (rcvsize > 0)
-470 {
-471 if (!this->connectors[i].AddBuffer(data))
-472 {
-473 WriteOpers('*** Read buffer for %s exceeds maximum, closing connection!',this->connectors[i].GetServerName().c_str());
-474 this->connectors[i].CloseConnection();
-475 this->connectors[i].SetState(STATE_DISCONNECTED);
-476 if (!IsRoutable(this->connectors[i].GetServerName()))
-477 {
-478 WriteOpers('*** Server %s is no longer routable, disconnecting.',this->connectors[i].GetServerName().c_str());
-479 DoSplit(this->connectors[i].GetServerName().c_str());
-480 }
-481 has_been_netsplit = true;
-482 }
-483 if (this->connectors[i].BufferIsComplete())
+446 {
+447 char data[65536],buffer[MAXBUF];
+448 memset(data, 0, 65536);
+449 for (int i = 0; i < this->connectors.size(); i++)
+450 {
+451 if (this->connectors[i].GetState() != STATE_DISCONNECTED)
+452 {
+453 // returns false if the packet could not be sent (e.g. target host down)
+454 int rcvsize = 0;
+455
+456 // check if theres any data on this socket
+457 // if not, continue onwards to the next.
+458 pollfd polls;
+459 polls.fd = this->connectors[i].GetDescriptor();
+460 polls.events = POLLIN;
+461 int ret = poll(&polls,1,1);
+462 if (ret <= 0) continue;
+463
+464 rcvsize = recv(this->connectors[i].GetDescriptor(),data,65000,0);
+465 data[rcvsize] = '\0';
+466 if (rcvsize == 0)
+467 {
+468 log(DEBUG,'recv() failed for serverrec::RecvPacket(): EOF');
+469 log(DEBUG,'Disabling connector: %s',this->connectors[i].GetServerName().c_str());
+470 this->connectors[i].CloseConnection();
+471 this->connectors[i].SetState(STATE_DISCONNECTED);
+472 if (!IsRoutable(this->connectors[i].GetServerName()))
+473 {
+474 WriteOpers('*** Server %s is no longer routable, disconnecting (EOF)',this->connectors[i].GetServerName().c_str());
+475 snprintf(buffer,MAXBUF,'& %s',this->connectors[i].GetServerName().c_str());
+476 NetSendToAllExcept(this->connectors[i].GetServerName().c_str(),buffer);
+477 DoSplit(this->connectors[i].GetServerName().c_str());
+478 }
+479 has_been_netsplit = true;
+480 }
+481 if (rcvsize == -1)
+482 {
+483 if (errno != EAGAIN)
484 {
-485 this->connectors[i].ResetPing();
-486 while (this->connectors[i].BufferIsComplete())
-487 {
-488 std::string text = this->connectors[i].GetBuffer();
-489 if (text != '')
-490 {
-491 if ((text[0] == ':') && (text.find(' ') != std::string::npos))
-492 {
-493 std::string orig = text;
-494 log(DEBUG,'Original: %s',text.c_str());
-495 std::string sum = text.substr(1,text.find(' ')-1);
-496 text = text.substr(text.find(' ')+1,text.length());
-497 std::string possible_token = text.substr(1,text.find(' ')-1);
-498 if (possible_token.length() > 1)
-499 {
-500 sums.push_back('*');
-501 text = orig;
-502 log(DEBUG,'Non-mesh, non-tokenized string passed up the chain');
-503 }
-504 else
-505 {
-506 log(DEBUG,'Packet sum: '%s'',sum.c_str());
-507 if ((already_have_sum(sum)) && (sum != '*'))
-508 {
-509 // we don't accept dupes
-510 continue;
-511 }
-512 sums.push_back(sum.c_str());
-513 }
-514 }
-515 else sums.push_back('*');
-516 messages.push_back(text.c_str());
-517 strlcpy(recvhost,this->connectors[i].GetServerName().c_str(),160);
-518 log(DEBUG,'serverrec::RecvPacket() %d:%s->%s',pushed++,recvhost,text.c_str());
-519 }
-520 }
-521 return true;
-522 }
-523 }
-524 }
-525 }
-526 // nothing new yet -- message and host will be undefined
-527 return false;
-528 }
+485 log(DEBUG,'recv() failed for serverrec::RecvPacket(): %s',strerror(errno));
+486 log(DEBUG,'Disabling connector: %s',this->connectors[i].GetServerName().c_str());
+487 this->connectors[i].CloseConnection();
+488 this->connectors[i].SetState(STATE_DISCONNECTED);
+489 if (!IsRoutable(this->connectors[i].GetServerName()))
+490 {
+491 WriteOpers('*** Server %s is no longer routable, disconnecting.',this->connectors[i].GetServerName().c_str());
+492 snprintf(buffer,MAXBUF,'& %s',this->connectors[i].GetServerName().c_str());
+493 NetSendToAllExcept(this->connectors[i].GetServerName().c_str(),buffer);
+494 DoSplit(this->connectors[i].GetServerName().c_str());
+495 }
+496 has_been_netsplit = true;
+497 }
+498 }
+499 int pushed = 0;
+500 if (rcvsize > 0)
+501 {
+502 if (!this->connectors[i].AddBuffer(data))
+503 {
+504 WriteOpers('*** Read buffer for %s exceeds maximum, closing connection!',this->connectors[i].GetServerName().c_str());
+505 this->connectors[i].CloseConnection();
+506 this->connectors[i].SetState(STATE_DISCONNECTED);
+507 if (!IsRoutable(this->connectors[i].GetServerName()))
+508 {
+509 WriteOpers('*** Server %s is no longer routable, disconnecting.',this->connectors[i].GetServerName().c_str());
+510 snprintf(buffer,MAXBUF,'& %s',this->connectors[i].GetServerName().c_str());
+511 NetSendToAllExcept(this->connectors[i].GetServerName().c_str(),buffer);
+512 DoSplit(this->connectors[i].GetServerName().c_str());
+513 }
+514 has_been_netsplit = true;
+515 }
+516 if (this->connectors[i].BufferIsComplete())
+517 {
+518 this->connectors[i].ResetPing();
+519 while (this->connectors[i].BufferIsComplete())
+520 {
+521 std::string text = this->connectors[i].GetBuffer();
+522 if (text != '')
+523 {
+524 if ((text[0] == ':') && (text.find(' ') != std::string::npos))
+525 {
+526 std::string orig = text;
+527 log(DEBUG,'Original: %s',text.c_str());
+528 std::string sum = text.substr(1,text.find(' ')-1);
+529 text = text.substr(text.find(' ')+1,text.length());
+530 std::string possible_token = text.substr(1,text.find(' ')-1);
+531 if (possible_token.length() > 1)
+532 {
+533 sums.push_back('*');
+534 text = orig;
+535 log(DEBUG,'Non-mesh, non-tokenized string passed up the chain');
+536 }
+537 else
+538 {
+539 log(DEBUG,'Packet sum: '%s'',sum.c_str());
+540 if ((already_have_sum(sum)) && (sum != '*'))
+541 {
+542 // we don't accept dupes
+543 continue;
+544 }
+545 sums.push_back(sum.c_str());
+546 }
+547 }
+548 else sums.push_back('*');
+549 messages.push_back(text.c_str());
+550 strlcpy(recvhost,this->connectors[i].GetServerName().c_str(),160);
+551 log(DEBUG,'serverrec::RecvPacket() %d:%s->%s',pushed++,recvhost,text.c_str());
+552 }
+553 }
+554 return true;
+555 }
+556 }
+557 }
+558 }
+559 // nothing new yet -- message and host will be undefined
+560 return false;
+561 }
.fi
.SS "bool serverrec::SendPacket (char * message, const char * host)"
.PP
-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 336 of file servers.cpp.
+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 350 of file servers.cpp.
.PP
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.
.PP
Referenced by BeginLink(), and MeshCookie().
.PP
.nf
-337 {
-338 if ((!message) || (!sendhost))
-339 return true;
-340
-341 ircd_connector* cn = this->FindHost(sendhost);
-342
-343 if (!strchr(message,'\n'))
-344 {
-345 strlcat(message,'\n',MAXBUF);
-346 }
-347
-348 if (cn)
-349 {
-350 log(DEBUG,'main: serverrec::SendPacket() sent '%s' to %s',message,cn->GetServerName().c_str());
-351
-352 if (cn->GetState() == STATE_DISCONNECTED)
-353 {
-354 // fix: can only route one hop to avoid a loop
-355 if (strncmp(message,'R ',2))
-356 {
-357 log(DEBUG,'Not a double reroute');
-358 // this route is down, we must re-route the packet through an available point in the mesh.
-359 for (int k = 0; k < this->connectors.size(); k++)
-360 {
-361 log(DEBUG,'Check connector %d: %s',k,this->connectors[k].GetServerName().c_str());
-362 // search for another point in the mesh which can 'reach' where we want to go
-363 for (int m = 0; m < this->connectors[k].routes.size(); m++)
-364 {
-365 if (!strcasecmp(this->connectors[k].routes[m].c_str(),sendhost))
-366 {
-367 log(DEBUG,'Found alternative route for packet: %s',this->connectors[k].GetServerName().c_str());
-368 char buffer[MAXBUF];
-369 snprintf(buffer,MAXBUF,'R %s %s',sendhost,message);
-370 this->SendPacket(buffer,this->connectors[k].GetServerName().c_str());
-371 return true;
-372 }
-373 }
-374 }
-375 }
-376 char buffer[MAXBUF];
-377 snprintf(buffer,MAXBUF,'& %s',sendhost);
-378 WriteOpers('*** All connections to %s lost.',sendhost);
-379 NetSendToAllExcept(sendhost,buffer);
-380 DoSplit(sendhost);
-381 return false;
-382 }
-383
-384 // returns false if the packet could not be sent (e.g. target host down)
-385 if (!cn->AddWriteBuf(message))
-386 {
-387 // if we're here, there was an error pending, and the send cannot proceed
-388 log(DEBUG,'cn->AddWriteBuf() failed for serverrec::SendPacket(): %s',cn->GetWriteError().c_str());
-389 log(DEBUG,'Disabling connector: %s',cn->GetServerName().c_str());
-390 cn->CloseConnection();
-391 cn->SetState(STATE_DISCONNECTED);
-392 WriteOpers('*** Lost single connection to %s, link inactive and retrying: %s',cn->GetServerName().c_str(),cn->GetWriteError().c_str());
-393 // retry the packet along a new route so either arrival OR failure are gauranteed (bugfix)
-394 return this->SendPacket(message,sendhost);
-395 }
-396 if (!cn->FlushWriteBuf())
-397 {
-398 // if we're here the write() caused an error, we cannot proceed
-399 log(DEBUG,'cn->FlushWriteBuf() failed for serverrec::SendPacket(): %s',cn->GetWriteError().c_str());
-400 log(DEBUG,'Disabling connector: %s',cn->GetServerName().c_str());
-401 cn->CloseConnection();
-402 cn->SetState(STATE_DISCONNECTED);
-403 WriteOpers('*** Lost single connection to %s, link inactive and retrying: %s',cn->GetServerName().c_str(),cn->GetWriteError().c_str());
-404 // retry the packet along a new route so either arrival OR failure are gauranteed
-405 return this->SendPacket(message,sendhost);
-406 }
-407 return true;
-408 }
-409 }
+351 {
+352 if ((!message) || (!sendhost))
+353 return true;
+354
+355 ircd_connector* cn = this->FindHost(sendhost);
+356
+357 if (!strchr(message,'\n'))
+358 {
+359 strlcat(message,'\n',MAXBUF);
+360 }
+361
+362 if (cn)
+363 {
+364 log(DEBUG,'main: serverrec::SendPacket() sent '%s' to %s',message,cn->GetServerName().c_str());
+365
+366 if (cn->GetState() == STATE_DISCONNECTED)
+367 {
+368 // fix: can only route one hop to avoid a loop
+369 if (strncmp(message,'R ',2))
+370 {
+371 log(DEBUG,'Not a double reroute');
+372 // this route is down, we must re-route the packet through an available point in the mesh.
+373 for (int k = 0; k < this->connectors.size(); k++)
+374 {
+375 log(DEBUG,'Check connector %d: %s',k,this->connectors[k].GetServerName().c_str());
+376 // search for another point in the mesh which can 'reach' where we want to go
+377 for (int m = 0; m < this->connectors[k].routes.size(); m++)
+378 {
+379 if (!strcasecmp(this->connectors[k].routes[m].c_str(),sendhost))
+380 {
+381 log(DEBUG,'Found alternative route for packet: %s',this->connectors[k].GetServerName().c_str());
+382 char buffer[MAXBUF];
+383 snprintf(buffer,MAXBUF,'R %s %s',sendhost,message);
+384 this->SendPacket(buffer,this->connectors[k].GetServerName().c_str());
+385 return true;
+386 }
+387 }
+388 }
+389 }
+390 char buffer[MAXBUF];
+391 snprintf(buffer,MAXBUF,'& %s',sendhost);
+392 WriteOpers('*** All connections to %s lost.',sendhost);
+393 NetSendToAllExcept(sendhost,buffer);
+394 DoSplit(sendhost);
+395 return false;
+396 }
+397
+398 // returns false if the packet could not be sent (e.g. target host down)
+399 if (!cn->AddWriteBuf(message))
+400 {
+401 // if we're here, there was an error pending, and the send cannot proceed
+402 log(DEBUG,'cn->AddWriteBuf() failed for serverrec::SendPacket(): %s',cn->GetWriteError().c_str());
+403 log(DEBUG,'Disabling connector: %s',cn->GetServerName().c_str());
+404 cn->CloseConnection();
+405 cn->SetState(STATE_DISCONNECTED);
+406 WriteOpers('*** Lost single connection to %s, link inactive and retrying: %s',cn->GetServerName().c_str(),cn->GetWriteError().c_str());
+407 // retry the packet along a new route so either arrival OR failure are gauranteed (bugfix)
+408 return this->SendPacket(message,sendhost);
+409 }
+410 if (!cn->FlushWriteBuf())
+411 {
+412 // if we're here the write() caused an error, we cannot proceed
+413 log(DEBUG,'cn->FlushWriteBuf() failed for serverrec::SendPacket(): %s',cn->GetWriteError().c_str());
+414 log(DEBUG,'Disabling connector: %s',cn->GetServerName().c_str());
+415 cn->CloseConnection();
+416 cn->SetState(STATE_DISCONNECTED);
+417 WriteOpers('*** Lost single connection to %s, link inactive and retrying: %s',cn->GetServerName().c_str(),cn->GetWriteError().c_str());
+418 // retry the packet along a new route so either arrival OR failure are gauranteed
+419 return this->SendPacket(message,sendhost);
+420 }
+421 return true;
+422 }
+423 }
.fi
.SS "void serverrec::TerminateLink (char * targethost)"
.PP