aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
diff options
context:
space:
mode:
authorJohn Hurliman2009-10-13 18:56:54 -0700
committerJohn Hurliman2009-10-13 18:56:54 -0700
commite8c1e69a0dbab1a7db894eeff6b052bbd350a8f5 (patch)
tree6d29a3bae418c1c5a06e3f1b8ad4a59db57a8d9e /OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
parent* Consolidated adding / removing ClientManager IClientAPIs to two places in S... (diff)
downloadopensim-SC-e8c1e69a0dbab1a7db894eeff6b052bbd350a8f5.zip
opensim-SC-e8c1e69a0dbab1a7db894eeff6b052bbd350a8f5.tar.gz
opensim-SC-e8c1e69a0dbab1a7db894eeff6b052bbd350a8f5.tar.bz2
opensim-SC-e8c1e69a0dbab1a7db894eeff6b052bbd350a8f5.tar.xz
* Copied LocklessQueue.cs into OpenSim.Framework and added the .Count property and .Clear() method
* Changed the way the QueueEmpty callback is fired. It will be fired asynchronously as soon as an empty queue is detected (this can happen immediately following a dequeue), and will not be fired again until at least one packet is dequeued from that queue. This will give callbacks advanced notice of an empty queue and prevent callbacks from stacking up while the queue is empty * Added LLUDPClient.IsConnected checks in several places to prevent unwanted network activity after a client disconnects * Prevent LLClientView.Close() from being called twice every disconnect * Removed the packet resend limit and improved the client timeout check
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs107
1 files changed, 48 insertions, 59 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index 8689af3..57fee59 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -332,8 +332,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
332 332
333 public void ResendUnacked(LLUDPClient udpClient) 333 public void ResendUnacked(LLUDPClient udpClient)
334 { 334 {
335 if (udpClient.NeedAcks.Count > 0) 335 if (udpClient.IsConnected && udpClient.NeedAcks.Count > 0)
336 { 336 {
337 // Disconnect an agent if no packets are received for some time
338 //FIXME: Make 60 an .ini setting
339 if (Environment.TickCount - udpClient.TickLastPacketReceived > 1000 * 60)
340 {
341 m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID);
342
343 RemoveClient(udpClient);
344 return;
345 }
346
347 // Get a list of all of the packets that have been sitting unacked longer than udpClient.RTO
337 List<OutgoingPacket> expiredPackets = udpClient.NeedAcks.GetExpiredPackets(udpClient.RTO); 348 List<OutgoingPacket> expiredPackets = udpClient.NeedAcks.GetExpiredPackets(udpClient.RTO);
338 349
339 if (expiredPackets != null) 350 if (expiredPackets != null)
@@ -343,48 +354,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
343 { 354 {
344 OutgoingPacket outgoingPacket = expiredPackets[i]; 355 OutgoingPacket outgoingPacket = expiredPackets[i];
345 356
346 // FIXME: Make this an .ini setting 357 //m_log.DebugFormat("[LLUDPSERVER]: Resending packet #{0} (attempt {1}), {2}ms have passed",
347 if (outgoingPacket.ResendCount < 3) 358 // outgoingPacket.SequenceNumber, outgoingPacket.ResendCount, Environment.TickCount - outgoingPacket.TickCount);
348 {
349 //Logger.Debug(String.Format("Resending packet #{0} (attempt {1}), {2}ms have passed",
350 // outgoingPacket.SequenceNumber, outgoingPacket.ResendCount, Environment.TickCount - outgoingPacket.TickCount));
351 359
352 // Set the resent flag 360 // Set the resent flag
353 outgoingPacket.Buffer.Data[0] = (byte)(outgoingPacket.Buffer.Data[0] | Helpers.MSG_RESENT); 361 outgoingPacket.Buffer.Data[0] = (byte)(outgoingPacket.Buffer.Data[0] | Helpers.MSG_RESENT);
354 outgoingPacket.Category = ThrottleOutPacketType.Resend; 362 outgoingPacket.Category = ThrottleOutPacketType.Resend;
355 363
356 // The TickCount will be set to the current time when the packet 364 // The TickCount will be set to the current time when the packet
357 // is actually sent out again 365 // is actually sent out again
358 outgoingPacket.TickCount = 0; 366 outgoingPacket.TickCount = 0;
359 367
360 // Bump up the resend count on this packet 368 // Bump up the resend count on this packet
361 Interlocked.Increment(ref outgoingPacket.ResendCount); 369 Interlocked.Increment(ref outgoingPacket.ResendCount);
362 //Interlocked.Increment(ref Stats.ResentPackets); 370 //Interlocked.Increment(ref Stats.ResentPackets);
363 371
364 // Queue or (re)send the packet 372 // Requeue or resend the packet
365 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket)) 373 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket))
366 SendPacketFinal(outgoingPacket); 374 SendPacketFinal(outgoingPacket);
367 }
368 else
369 {
370 m_log.DebugFormat("[LLUDPSERVER]: Dropping packet #{0} for agent {1} after {2} failed attempts",
371 outgoingPacket.SequenceNumber, outgoingPacket.Client.RemoteEndPoint, outgoingPacket.ResendCount);
372
373 lock (udpClient.NeedAcks.SyncRoot)
374 udpClient.NeedAcks.RemoveUnsafe(outgoingPacket.SequenceNumber);
375
376 //Interlocked.Increment(ref Stats.DroppedPackets);
377
378 // Disconnect an agent if no packets are received for some time
379 //FIXME: Make 60 an .ini setting
380 if (Environment.TickCount - udpClient.TickLastPacketReceived > 1000 * 60)
381 {
382 m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID);
383
384 RemoveClient(udpClient);
385 return;
386 }
387 }
388 } 375 }
389 } 376 }
390 } 377 }
@@ -403,6 +390,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
403 bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0; 390 bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0;
404 LLUDPClient udpClient = outgoingPacket.Client; 391 LLUDPClient udpClient = outgoingPacket.Client;
405 392
393 if (!udpClient.IsConnected)
394 return;
395
406 // Keep track of when this packet was sent out (right now) 396 // Keep track of when this packet was sent out (right now)
407 outgoingPacket.TickCount = Environment.TickCount; 397 outgoingPacket.TickCount = Environment.TickCount;
408 398
@@ -481,14 +471,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
481 } 471 }
482 catch (MalformedDataException) 472 catch (MalformedDataException)
483 { 473 {
484 m_log.ErrorFormat("[LLUDPSERVER]: Malformed data, cannot parse packet:\n{0}", 474 m_log.ErrorFormat("[LLUDPSERVER]: Malformed data, cannot parse packet from {0}:\n{1}",
485 Utils.BytesToHexString(buffer.Data, buffer.DataLength, null)); 475 buffer.RemoteEndPoint, Utils.BytesToHexString(buffer.Data, buffer.DataLength, null));
486 } 476 }
487 477
488 // Fail-safe check 478 // Fail-safe check
489 if (packet == null) 479 if (packet == null)
490 { 480 {
491 m_log.Warn("[LLUDPSERVER]: Couldn't build a message from the incoming data"); 481 m_log.Warn("[LLUDPSERVER]: Couldn't build a message from incoming data " + buffer.DataLength +
482 " bytes long from " + buffer.RemoteEndPoint);
492 return; 483 return;
493 } 484 }
494 485
@@ -513,6 +504,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
513 504
514 udpClient = ((LLClientView)client).UDPClient; 505 udpClient = ((LLClientView)client).UDPClient;
515 506
507 if (!udpClient.IsConnected)
508 return;
509
516 #endregion Packet to Client Mapping 510 #endregion Packet to Client Mapping
517 511
518 // Stats tracking 512 // Stats tracking
@@ -643,7 +637,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
643 // Create the LLClientView 637 // Create the LLClientView
644 LLClientView client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode); 638 LLClientView client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
645 client.OnLogout += LogoutHandler; 639 client.OnLogout += LogoutHandler;
646 client.OnConnectionClosed += ConnectionClosedHandler;
647 640
648 // Start the IClientAPI 641 // Start the IClientAPI
649 client.Start(); 642 client.Start();
@@ -745,17 +738,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
745 { 738 {
746 LLUDPClient udpClient = ((LLClientView)client).UDPClient; 739 LLUDPClient udpClient = ((LLClientView)client).UDPClient;
747 740
748 if (udpClient.DequeueOutgoing()) 741 if (udpClient.IsConnected)
749 packetSent = true;
750 if (resendUnacked)
751 ResendUnacked(udpClient);
752 if (sendAcks)
753 { 742 {
754 SendAcks(udpClient); 743 if (udpClient.DequeueOutgoing())
755 udpClient.SendPacketStats(); 744 packetSent = true;
745 if (resendUnacked)
746 ResendUnacked(udpClient);
747 if (sendAcks)
748 {
749 SendAcks(udpClient);
750 udpClient.SendPacketStats();
751 }
752 if (sendPings)
753 SendPing(udpClient);
756 } 754 }
757 if (sendPings)
758 SendPing(udpClient);
759 } 755 }
760 } 756 }
761 ); 757 );
@@ -808,14 +804,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
808 804
809 private void LogoutHandler(IClientAPI client) 805 private void LogoutHandler(IClientAPI client)
810 { 806 {
811 client.OnLogout -= LogoutHandler;
812 client.SendLogoutPacket(); 807 client.SendLogoutPacket();
813 } 808 }
814
815 private void ConnectionClosedHandler(IClientAPI client)
816 {
817 client.OnConnectionClosed -= ConnectionClosedHandler;
818 RemoveClient(((LLClientView)client).UDPClient);
819 }
820 } 809 }
821} 810}