aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack
diff options
context:
space:
mode:
authorJohn Hurliman2009-10-21 13:47:16 -0700
committerJohn Hurliman2009-10-21 13:47:16 -0700
commit7ee422a344ff22cf988aea2355628d2dee831983 (patch)
treeb0ee8d6004b501f940ecfcc2d00a52a74cabfa25 /OpenSim/Region/ClientStack
parent* Replaced the UnackedPacketCollection with a lockless implementation. The ti... (diff)
downloadopensim-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')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs7
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs47
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs8
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