diff options
author | John Hurliman | 2009-10-21 13:47:16 -0700 |
---|---|---|
committer | John Hurliman | 2009-10-21 13:47:16 -0700 |
commit | 7ee422a344ff22cf988aea2355628d2dee831983 (patch) | |
tree | b0ee8d6004b501f940ecfcc2d00a52a74cabfa25 /OpenSim/Region/ClientStack | |
parent | * Replaced the UnackedPacketCollection with a lockless implementation. The ti... (diff) | |
download | opensim-SC-7ee422a344ff22cf988aea2355628d2dee831983.zip opensim-SC-7ee422a344ff22cf988aea2355628d2dee831983.tar.gz opensim-SC-7ee422a344ff22cf988aea2355628d2dee831983.tar.bz2 opensim-SC-7ee422a344ff22cf988aea2355628d2dee831983.tar.xz |
* Handle UseCircuitCode packets asynchronously. Adding an agent to a scene can take several seconds, and was blocking up packet handling in the meantime
* Clamp retransmission timeout values between three and 10 seconds
* Log outgoing time for a packet right after it is sent instead of well before
* Loop through the entire UnackedPacketCollection when looking for expired packets
Diffstat (limited to 'OpenSim/Region/ClientStack')
3 files changed, 49 insertions, 13 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index 458e78d..a43197d 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs | |||
@@ -505,8 +505,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
505 | SRTT = (1.0f - ALPHA) * SRTT + ALPHA * r; | 505 | SRTT = (1.0f - ALPHA) * SRTT + ALPHA * r; |
506 | } | 506 | } |
507 | 507 | ||
508 | // Always round retransmission timeout up to two seconds | 508 | RTO = (int)(SRTT + Math.Max(m_udpServer.TickCountResolution, K * RTTVAR)); |
509 | RTO = Math.Max(2000, (int)(SRTT + Math.Max(m_udpServer.TickCountResolution, K * RTTVAR))); | 509 | |
510 | // Clamp the retransmission timeout to manageable values | ||
511 | RTO = Utils.Clamp(RTO, 3000, 10000); | ||
512 | |||
510 | //m_log.Debug("[LLUDPCLIENT]: Setting agent " + this.Agent.FullName + "'s RTO to " + RTO + "ms with an RTTVAR of " + | 513 | //m_log.Debug("[LLUDPCLIENT]: Setting agent " + this.Agent.FullName + "'s RTO to " + RTO + "ms with an RTTVAR of " + |
511 | // RTTVAR + " based on new RTT of " + r + "ms"); | 514 | // RTTVAR + " based on new RTT of " + r + "ms"); |
512 | } | 515 | } |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index a8ce102..209c0e0 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | |||
@@ -381,7 +381,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
381 | 381 | ||
382 | // Disconnect an agent if no packets are received for some time | 382 | // Disconnect an agent if no packets are received for some time |
383 | //FIXME: Make 60 an .ini setting | 383 | //FIXME: Make 60 an .ini setting |
384 | if (Environment.TickCount - udpClient.TickLastPacketReceived > 1000 * 60) | 384 | if ((Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > 1000 * 60) |
385 | { | 385 | { |
386 | m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID); | 386 | m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID); |
387 | 387 | ||
@@ -439,9 +439,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
439 | if (!udpClient.IsConnected) | 439 | if (!udpClient.IsConnected) |
440 | return; | 440 | return; |
441 | 441 | ||
442 | // Keep track of when this packet was sent out (right now) | ||
443 | outgoingPacket.TickCount = Environment.TickCount; | ||
444 | |||
445 | #region ACK Appending | 442 | #region ACK Appending |
446 | 443 | ||
447 | int dataLength = buffer.DataLength; | 444 | int dataLength = buffer.DataLength; |
@@ -494,6 +491,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
494 | 491 | ||
495 | // Put the UDP payload on the wire | 492 | // Put the UDP payload on the wire |
496 | AsyncBeginSend(buffer); | 493 | AsyncBeginSend(buffer); |
494 | |||
495 | // Keep track of when this packet was sent out (right now) | ||
496 | outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue; | ||
497 | } | 497 | } |
498 | 498 | ||
499 | protected override void PacketReceived(UDPPacketBuffer buffer) | 499 | protected override void PacketReceived(UDPPacketBuffer buffer) |
@@ -536,7 +536,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
536 | // UseCircuitCode handling | 536 | // UseCircuitCode handling |
537 | if (packet.Type == PacketType.UseCircuitCode) | 537 | if (packet.Type == PacketType.UseCircuitCode) |
538 | { | 538 | { |
539 | AddNewClient((UseCircuitCodePacket)packet, (IPEndPoint)buffer.RemoteEndPoint); | 539 | Util.FireAndForget( |
540 | delegate(object o) | ||
541 | { | ||
542 | IPEndPoint remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint; | ||
543 | |||
544 | // Begin the process of adding the client to the simulator | ||
545 | AddNewClient((UseCircuitCodePacket)packet, remoteEndPoint); | ||
546 | |||
547 | // Acknowledge the UseCircuitCode packet | ||
548 | SendAckImmediate(remoteEndPoint, packet.Header.Sequence); | ||
549 | } | ||
550 | ); | ||
551 | return; | ||
540 | } | 552 | } |
541 | 553 | ||
542 | // Determine which agent this packet came from | 554 | // Determine which agent this packet came from |
@@ -558,11 +570,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
558 | // Stats tracking | 570 | // Stats tracking |
559 | Interlocked.Increment(ref udpClient.PacketsReceived); | 571 | Interlocked.Increment(ref udpClient.PacketsReceived); |
560 | 572 | ||
561 | #region ACK Receiving | 573 | int now = Environment.TickCount & Int32.MaxValue; |
562 | |||
563 | int now = Environment.TickCount; | ||
564 | udpClient.TickLastPacketReceived = now; | 574 | udpClient.TickLastPacketReceived = now; |
565 | 575 | ||
576 | #region ACK Receiving | ||
577 | |||
566 | // Handle appended ACKs | 578 | // Handle appended ACKs |
567 | if (packet.Header.AppendedAcks && packet.Header.AckList != null) | 579 | if (packet.Header.AppendedAcks && packet.Header.AckList != null) |
568 | { | 580 | { |
@@ -650,6 +662,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
650 | { | 662 | { |
651 | } | 663 | } |
652 | 664 | ||
665 | private void SendAckImmediate(IPEndPoint remoteEndpoint, uint sequenceNumber) | ||
666 | { | ||
667 | PacketAckPacket ack = new PacketAckPacket(); | ||
668 | ack.Header.Reliable = false; | ||
669 | ack.Packets = new PacketAckPacket.PacketsBlock[1]; | ||
670 | ack.Packets[0] = new PacketAckPacket.PacketsBlock(); | ||
671 | ack.Packets[0].ID = sequenceNumber; | ||
672 | |||
673 | byte[] packetData = ack.ToBytes(); | ||
674 | int length = packetData.Length; | ||
675 | |||
676 | UDPPacketBuffer buffer = new UDPPacketBuffer(remoteEndpoint, length); | ||
677 | buffer.DataLength = length; | ||
678 | |||
679 | Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length); | ||
680 | |||
681 | AsyncBeginSend(buffer); | ||
682 | } | ||
683 | |||
653 | private bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo) | 684 | private bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo) |
654 | { | 685 | { |
655 | UUID agentID = useCircuitCode.CircuitCode.ID; | 686 | UUID agentID = useCircuitCode.CircuitCode.ID; |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs index 12f0c0a..bd5fe1c 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs | |||
@@ -85,6 +85,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
85 | /// <param name="sequenceNumber">Sequence number of the packet to | 85 | /// <param name="sequenceNumber">Sequence number of the packet to |
86 | /// acknowledge</param> | 86 | /// acknowledge</param> |
87 | /// <param name="currentTime">Current value of Environment.TickCount</param> | 87 | /// <param name="currentTime">Current value of Environment.TickCount</param> |
88 | /// <remarks>This does not immediately acknowledge the packet, it only | ||
89 | /// queues the ack so it can be handled in a thread-safe way later</remarks> | ||
88 | public void Remove(uint sequenceNumber, int currentTime, bool fromResend) | 90 | public void Remove(uint sequenceNumber, int currentTime, bool fromResend) |
89 | { | 91 | { |
90 | m_pendingRemoves.Enqueue(new PendingAck(sequenceNumber, currentTime, fromResend)); | 92 | m_pendingRemoves.Enqueue(new PendingAck(sequenceNumber, currentTime, fromResend)); |
@@ -108,7 +110,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
108 | 110 | ||
109 | if (m_packets.Count > 0) | 111 | if (m_packets.Count > 0) |
110 | { | 112 | { |
111 | int now = Environment.TickCount; | 113 | int now = Environment.TickCount & Int32.MaxValue; |
112 | 114 | ||
113 | foreach (OutgoingPacket packet in m_packets.Values) | 115 | foreach (OutgoingPacket packet in m_packets.Values) |
114 | { | 116 | { |
@@ -123,10 +125,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
123 | expiredPackets = new List<OutgoingPacket>(); | 125 | expiredPackets = new List<OutgoingPacket>(); |
124 | expiredPackets.Add(packet); | 126 | expiredPackets.Add(packet); |
125 | } | 127 | } |
126 | else | 128 | /*else |
127 | { | 129 | { |
128 | break; | 130 | break; |
129 | } | 131 | }*/ |
130 | } | 132 | } |
131 | } | 133 | } |
132 | 134 | ||