aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
diff options
context:
space:
mode:
authorJohn Hurliman2009-10-06 10:12:59 -0700
committerJohn Hurliman2009-10-06 10:12:59 -0700
commitfb19d1ca0a7c6e82c540c4e8d22c82c09b7bec98 (patch)
treebef6315759b63e337e17d7d1e717929e08778f8c /OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
parentFixing a few compile errors in the previous commit (diff)
downloadopensim-SC-fb19d1ca0a7c6e82c540c4e8d22c82c09b7bec98.zip
opensim-SC-fb19d1ca0a7c6e82c540c4e8d22c82c09b7bec98.tar.gz
opensim-SC-fb19d1ca0a7c6e82c540c4e8d22c82c09b7bec98.tar.bz2
opensim-SC-fb19d1ca0a7c6e82c540c4e8d22c82c09b7bec98.tar.xz
* Try/catch around EndInvoke() when Util.FireAndForget() returns to catch exceptions thrown in the async method
* Added packet stats handling to the new LLUDP implementation * Attempting to avoid a race condition when creating a new LLUDPClient
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs147
1 files changed, 81 insertions, 66 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index 348615e..38890da 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -359,6 +359,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
359 // is actually sent out again 359 // is actually sent out again
360 outgoingPacket.TickCount = 0; 360 outgoingPacket.TickCount = 0;
361 361
362 // Bump up the resend count on this packet
362 Interlocked.Increment(ref outgoingPacket.ResendCount); 363 Interlocked.Increment(ref outgoingPacket.ResendCount);
363 //Interlocked.Increment(ref Stats.ResentPackets); 364 //Interlocked.Increment(ref Stats.ResentPackets);
364 365
@@ -393,6 +394,68 @@ namespace OpenSim.Region.ClientStack.LindenUDP
393 394
394 public void Flush() 395 public void Flush()
395 { 396 {
397 // FIXME: Implement?
398 }
399
400 internal void SendPacketFinal(OutgoingPacket outgoingPacket)
401 {
402 UDPPacketBuffer buffer = outgoingPacket.Buffer;
403 byte flags = buffer.Data[0];
404 bool isResend = (flags & Helpers.MSG_RESENT) != 0;
405 bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0;
406 LLUDPClient client = outgoingPacket.Client;
407
408 // Keep track of when this packet was sent out (right now)
409 outgoingPacket.TickCount = Environment.TickCount;
410
411 #region ACK Appending
412
413 int dataLength = buffer.DataLength;
414
415 // Keep appending ACKs until there is no room left in the packet or there are
416 // no more ACKs to append
417 uint ackCount = 0;
418 uint ack;
419 while (dataLength + 5 < buffer.Data.Length && client.PendingAcks.Dequeue(out ack))
420 {
421 Utils.UIntToBytesBig(ack, buffer.Data, dataLength);
422 dataLength += 4;
423 ++ackCount;
424 }
425
426 if (ackCount > 0)
427 {
428 // Set the last byte of the packet equal to the number of appended ACKs
429 buffer.Data[dataLength++] = (byte)ackCount;
430 // Set the appended ACKs flag on this packet
431 buffer.Data[0] = (byte)(buffer.Data[0] | Helpers.MSG_APPENDED_ACKS);
432 }
433
434 buffer.DataLength = dataLength;
435
436 #endregion ACK Appending
437
438 if (!isResend)
439 {
440 // Not a resend, assign a new sequence number
441 uint sequenceNumber = (uint)Interlocked.Increment(ref client.CurrentSequence);
442 Utils.UIntToBytesBig(sequenceNumber, buffer.Data, 1);
443 outgoingPacket.SequenceNumber = sequenceNumber;
444
445 if (isReliable)
446 {
447 // Add this packet to the list of ACK responses we are waiting on from the server
448 client.NeedAcks.Add(outgoingPacket);
449 }
450 }
451
452 // Stats tracking
453 Interlocked.Increment(ref client.PacketsSent);
454 if (isReliable)
455 Interlocked.Add(ref client.UnackedBytes, outgoingPacket.Buffer.DataLength);
456
457 // Put the UDP payload on the wire
458 AsyncBeginSend(buffer);
396 } 459 }
397 460
398 protected override void PacketReceived(UDPPacketBuffer buffer) 461 protected override void PacketReceived(UDPPacketBuffer buffer)
@@ -456,8 +519,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
456 519
457 #endregion UseCircuitCode Handling 520 #endregion UseCircuitCode Handling
458 521
459 //if (packet.Header.Resent) 522 // Stats tracking
460 // Interlocked.Increment(ref Stats.ReceivedResends); 523 Interlocked.Increment(ref client.PacketsReceived);
461 524
462 #region ACK Receiving 525 #region ACK Receiving
463 526
@@ -581,7 +644,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
581 { 644 {
582 // Create the LLUDPClient 645 // Create the LLUDPClient
583 LLUDPClient client = new LLUDPClient(this, m_throttleRates, m_throttle, circuitCode, agentID, remoteEndPoint); 646 LLUDPClient client = new LLUDPClient(this, m_throttleRates, m_throttle, circuitCode, agentID, remoteEndPoint);
584 clients.Add(agentID, client.RemoteEndPoint, client);
585 647
586 // Create the LLClientView 648 // Create the LLClientView
587 LLClientView clientApi = new LLClientView(remoteEndPoint, m_scene, this, client, sessionInfo, agentID, sessionID, circuitCode); 649 LLClientView clientApi = new LLClientView(remoteEndPoint, m_scene, this, client, sessionInfo, agentID, sessionID, circuitCode);
@@ -589,12 +651,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
589 clientApi.OnLogout += LogoutHandler; 651 clientApi.OnLogout += LogoutHandler;
590 clientApi.OnConnectionClosed += RemoveClient; 652 clientApi.OnConnectionClosed += RemoveClient;
591 653
592 // Give LLUDPClient a reference to IClientAPI
593 client.ClientAPI = clientApi;
594
595 // Start the IClientAPI 654 // Start the IClientAPI
596 m_scene.ClientManager.Add(circuitCode, clientApi); 655 m_scene.ClientManager.Add(circuitCode, clientApi);
597 clientApi.Start(); 656 clientApi.Start();
657
658 // Give LLUDPClient a reference to IClientAPI
659 client.ClientAPI = clientApi;
660
661 // Add the new client to our list of tracked clients
662 clients.Add(agentID, client.RemoteEndPoint, client);
598 } 663 }
599 664
600 private void AcknowledgePacket(LLUDPClient client, uint ack, int currentTime, bool fromResend) 665 private void AcknowledgePacket(LLUDPClient client, uint ack, int currentTime, bool fromResend)
@@ -602,6 +667,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
602 OutgoingPacket ackedPacket; 667 OutgoingPacket ackedPacket;
603 if (client.NeedAcks.RemoveUnsafe(ack, out ackedPacket) && !fromResend) 668 if (client.NeedAcks.RemoveUnsafe(ack, out ackedPacket) && !fromResend)
604 { 669 {
670 // Update stats
671 Interlocked.Add(ref client.UnackedBytes, -ackedPacket.Buffer.DataLength);
672
605 // Calculate the round-trip time for this packet and its ACK 673 // Calculate the round-trip time for this packet and its ACK
606 int rtt = currentTime - ackedPacket.TickCount; 674 int rtt = currentTime - ackedPacket.TickCount;
607 if (rtt > 0) 675 if (rtt > 0)
@@ -650,7 +718,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
650 StatsManager.SimExtraStats.AddAbnormalClientThreadTermination(); 718 StatsManager.SimExtraStats.AddAbnormalClientThreadTermination();
651 719
652 // Don't let a failure in an individual client thread crash the whole sim. 720 // Don't let a failure in an individual client thread crash the whole sim.
653 m_log.ErrorFormat("[LLUDPSERVER]: Client thread for {0} {1} crashed. Logging them out", client.ClientAPI.Name, client.AgentID); 721 m_log.ErrorFormat("[LLUDPSERVER]: Client thread for {0} crashed. Logging them out", client.AgentID);
654 m_log.Error(e.Message, e); 722 m_log.Error(e.Message, e);
655 723
656 try 724 try
@@ -674,7 +742,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
674 } 742 }
675 catch (Exception e2) 743 catch (Exception e2)
676 { 744 {
677 m_log.Error("[LLUDPSERVER]: Further exception thrown on forced session logout for " + client.ClientAPI.Name); 745 m_log.Error("[LLUDPSERVER]: Further exception thrown on forced session logout for " + client.AgentID);
678 m_log.Error(e2.Message, e2); 746 m_log.Error(e2.Message, e2);
679 } 747 }
680 } 748 }
@@ -715,8 +783,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
715 elapsed100MS = 0; 783 elapsed100MS = 0;
716 ++elapsed500MS; 784 ++elapsed500MS;
717 } 785 }
718 // Send pings to clients every 2000ms 786 // Send pings to clients every 5000ms
719 if (elapsed500MS >= 4) 787 if (elapsed500MS >= 10)
720 { 788 {
721 sendPings = true; 789 sendPings = true;
722 elapsed500MS = 0; 790 elapsed500MS = 0;
@@ -730,7 +798,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
730 if (resendUnacked) 798 if (resendUnacked)
731 ResendUnacked(client); 799 ResendUnacked(client);
732 if (sendAcks) 800 if (sendAcks)
801 {
733 SendAcks(client); 802 SendAcks(client);
803 client.SendPacketStats();
804 }
734 if (sendPings) 805 if (sendPings)
735 SendPing(client); 806 SendPing(client);
736 } 807 }
@@ -746,61 +817,5 @@ namespace OpenSim.Region.ClientStack.LindenUDP
746 client.SendLogoutPacket(); 817 client.SendLogoutPacket();
747 RemoveClient(client); 818 RemoveClient(client);
748 } 819 }
749
750 internal void SendPacketFinal(OutgoingPacket outgoingPacket)
751 {
752 UDPPacketBuffer buffer = outgoingPacket.Buffer;
753 byte flags = buffer.Data[0];
754 bool isResend = (flags & Helpers.MSG_RESENT) != 0;
755 bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0;
756 LLUDPClient client = outgoingPacket.Client;
757
758 // Keep track of when this packet was sent out (right now)
759 outgoingPacket.TickCount = Environment.TickCount;
760
761 #region ACK Appending
762
763 int dataLength = buffer.DataLength;
764
765 // Keep appending ACKs until there is no room left in the packet or there are
766 // no more ACKs to append
767 uint ackCount = 0;
768 uint ack;
769 while (dataLength + 5 < buffer.Data.Length && client.PendingAcks.Dequeue(out ack))
770 {
771 Utils.UIntToBytesBig(ack, buffer.Data, dataLength);
772 dataLength += 4;
773 ++ackCount;
774 }
775
776 if (ackCount > 0)
777 {
778 // Set the last byte of the packet equal to the number of appended ACKs
779 buffer.Data[dataLength++] = (byte)ackCount;
780 // Set the appended ACKs flag on this packet
781 buffer.Data[0] = (byte)(buffer.Data[0] | Helpers.MSG_APPENDED_ACKS);
782 }
783
784 buffer.DataLength = dataLength;
785
786 #endregion ACK Appending
787
788 if (!isResend)
789 {
790 // Not a resend, assign a new sequence number
791 uint sequenceNumber = (uint)Interlocked.Increment(ref client.CurrentSequence);
792 Utils.UIntToBytesBig(sequenceNumber, buffer.Data, 1);
793 outgoingPacket.SequenceNumber = sequenceNumber;
794
795 if (isReliable)
796 {
797 // Add this packet to the list of ACK responses we are waiting on from the server
798 client.NeedAcks.Add(outgoingPacket);
799 }
800 }
801
802 // Put the UDP payload on the wire
803 AsyncBeginSend(buffer);
804 }
805 } 820 }
806} 821}