diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs | 54 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | 4 |
2 files changed, 42 insertions, 16 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index d2cd6d9..0948e1c 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs | |||
@@ -144,6 +144,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
144 | private readonly OutgoingPacket[] m_nextPackets = new OutgoingPacket[THROTTLE_CATEGORY_COUNT]; | 144 | private readonly OutgoingPacket[] m_nextPackets = new OutgoingPacket[THROTTLE_CATEGORY_COUNT]; |
145 | /// <summary>A reference to the LLUDPServer that is managing this client</summary> | 145 | /// <summary>A reference to the LLUDPServer that is managing this client</summary> |
146 | private readonly LLUDPServer m_udpServer; | 146 | private readonly LLUDPServer m_udpServer; |
147 | /// <summary>Locks access to the variables used while calculating round-trip | ||
148 | /// packet times and the retransmission timeout</summary> | ||
149 | private readonly object m_roundTripCalcLock = new object(); | ||
147 | 150 | ||
148 | /// <summary> | 151 | /// <summary> |
149 | /// Default constructor | 152 | /// Default constructor |
@@ -484,29 +487,52 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
484 | const float BETA = 0.25f; | 487 | const float BETA = 0.25f; |
485 | const float K = 4.0f; | 488 | const float K = 4.0f; |
486 | 489 | ||
487 | if (RTTVAR == 0.0f) | 490 | lock (m_roundTripCalcLock) |
488 | { | 491 | { |
489 | // First RTT measurement | 492 | if (RTTVAR == 0.0f) |
490 | SRTT = r; | 493 | { |
491 | RTTVAR = r * 0.5f; | 494 | // First RTT measurement |
492 | } | 495 | SRTT = r; |
493 | else | 496 | RTTVAR = r * 0.5f; |
494 | { | 497 | } |
495 | // Subsequence RTT measurement | 498 | else |
496 | RTTVAR = (1.0f - BETA) * RTTVAR + BETA * Math.Abs(SRTT - r); | 499 | { |
497 | SRTT = (1.0f - ALPHA) * SRTT + ALPHA * r; | 500 | // Subsequence RTT measurement |
498 | } | 501 | RTTVAR = (1.0f - BETA) * RTTVAR + BETA * Math.Abs(SRTT - r); |
502 | SRTT = (1.0f - ALPHA) * SRTT + ALPHA * r; | ||
503 | } | ||
499 | 504 | ||
500 | RTO = (int)(SRTT + Math.Max(m_udpServer.TickCountResolution, K * RTTVAR)); | 505 | int rto = (int)(SRTT + Math.Max(m_udpServer.TickCountResolution, K * RTTVAR)); |
501 | 506 | ||
502 | // Clamp the retransmission timeout to manageable values | 507 | // Clamp the retransmission timeout to manageable values |
503 | RTO = Utils.Clamp(RTO, 3000, 60000); | 508 | rto = Utils.Clamp(RTO, 3000, 60000); |
509 | |||
510 | RTO = rto; | ||
511 | } | ||
504 | 512 | ||
505 | //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 " + |
506 | // RTTVAR + " based on new RTT of " + r + "ms"); | 514 | // RTTVAR + " based on new RTT of " + r + "ms"); |
507 | } | 515 | } |
508 | 516 | ||
509 | /// <summary> | 517 | /// <summary> |
518 | /// Exponential backoff of the retransmission timeout, per section 5.5 | ||
519 | /// of RFC 2988 | ||
520 | /// </summary> | ||
521 | public void BackoffRTO() | ||
522 | { | ||
523 | lock (m_roundTripCalcLock) | ||
524 | { | ||
525 | // Reset SRTT and RTTVAR, we assume they are bogus since things | ||
526 | // didn't work out and we're backing off the timeout | ||
527 | SRTT = 0.0f; | ||
528 | RTTVAR = 0.0f; | ||
529 | |||
530 | // Double the retransmission timeout | ||
531 | RTO = Math.Min(RTO * 2, 60000); | ||
532 | } | ||
533 | } | ||
534 | |||
535 | /// <summary> | ||
510 | /// Does an early check to see if this queue empty callback is already | 536 | /// Does an early check to see if this queue empty callback is already |
511 | /// running, then asynchronously firing the event | 537 | /// running, then asynchronously firing the event |
512 | /// </summary> | 538 | /// </summary> |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index 1dd58bf..82ae640 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | |||
@@ -431,8 +431,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
431 | { | 431 | { |
432 | m_log.Debug("[LLUDPSERVER]: Resending " + expiredPackets.Count + " packets to " + udpClient.AgentID + ", RTO=" + udpClient.RTO); | 432 | m_log.Debug("[LLUDPSERVER]: Resending " + expiredPackets.Count + " packets to " + udpClient.AgentID + ", RTO=" + udpClient.RTO); |
433 | 433 | ||
434 | // Backoff the RTO | 434 | // Exponential backoff of the retransmission timeout |
435 | udpClient.RTO = Math.Min(udpClient.RTO * 2, 60000); | 435 | udpClient.BackoffRTO(); |
436 | 436 | ||
437 | // Resend packets | 437 | // Resend packets |
438 | for (int i = 0; i < expiredPackets.Count; i++) | 438 | for (int i = 0; i < expiredPackets.Count; i++) |