diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | 147 |
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 | } |