* 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 packetsprioritization
parent
9178537e94
commit
7ee422a344
|
@ -505,8 +505,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
SRTT = (1.0f - ALPHA) * SRTT + ALPHA * r;
|
||||
}
|
||||
|
||||
// Always round retransmission timeout up to two seconds
|
||||
RTO = Math.Max(2000, (int)(SRTT + Math.Max(m_udpServer.TickCountResolution, K * RTTVAR)));
|
||||
RTO = (int)(SRTT + Math.Max(m_udpServer.TickCountResolution, K * RTTVAR));
|
||||
|
||||
// Clamp the retransmission timeout to manageable values
|
||||
RTO = Utils.Clamp(RTO, 3000, 10000);
|
||||
|
||||
//m_log.Debug("[LLUDPCLIENT]: Setting agent " + this.Agent.FullName + "'s RTO to " + RTO + "ms with an RTTVAR of " +
|
||||
// RTTVAR + " based on new RTT of " + r + "ms");
|
||||
}
|
||||
|
|
|
@ -381,7 +381,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
// Disconnect an agent if no packets are received for some time
|
||||
//FIXME: Make 60 an .ini setting
|
||||
if (Environment.TickCount - udpClient.TickLastPacketReceived > 1000 * 60)
|
||||
if ((Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > 1000 * 60)
|
||||
{
|
||||
m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID);
|
||||
|
||||
|
@ -439,9 +439,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
if (!udpClient.IsConnected)
|
||||
return;
|
||||
|
||||
// Keep track of when this packet was sent out (right now)
|
||||
outgoingPacket.TickCount = Environment.TickCount;
|
||||
|
||||
#region ACK Appending
|
||||
|
||||
int dataLength = buffer.DataLength;
|
||||
|
@ -494,6 +491,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
// Put the UDP payload on the wire
|
||||
AsyncBeginSend(buffer);
|
||||
|
||||
// Keep track of when this packet was sent out (right now)
|
||||
outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue;
|
||||
}
|
||||
|
||||
protected override void PacketReceived(UDPPacketBuffer buffer)
|
||||
|
@ -536,7 +536,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
// UseCircuitCode handling
|
||||
if (packet.Type == PacketType.UseCircuitCode)
|
||||
{
|
||||
AddNewClient((UseCircuitCodePacket)packet, (IPEndPoint)buffer.RemoteEndPoint);
|
||||
Util.FireAndForget(
|
||||
delegate(object o)
|
||||
{
|
||||
IPEndPoint remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
|
||||
|
||||
// Begin the process of adding the client to the simulator
|
||||
AddNewClient((UseCircuitCodePacket)packet, remoteEndPoint);
|
||||
|
||||
// Acknowledge the UseCircuitCode packet
|
||||
SendAckImmediate(remoteEndPoint, packet.Header.Sequence);
|
||||
}
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine which agent this packet came from
|
||||
|
@ -558,11 +570,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
// Stats tracking
|
||||
Interlocked.Increment(ref udpClient.PacketsReceived);
|
||||
|
||||
#region ACK Receiving
|
||||
|
||||
int now = Environment.TickCount;
|
||||
int now = Environment.TickCount & Int32.MaxValue;
|
||||
udpClient.TickLastPacketReceived = now;
|
||||
|
||||
#region ACK Receiving
|
||||
|
||||
// Handle appended ACKs
|
||||
if (packet.Header.AppendedAcks && packet.Header.AckList != null)
|
||||
{
|
||||
|
@ -650,6 +662,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
{
|
||||
}
|
||||
|
||||
private void SendAckImmediate(IPEndPoint remoteEndpoint, uint sequenceNumber)
|
||||
{
|
||||
PacketAckPacket ack = new PacketAckPacket();
|
||||
ack.Header.Reliable = false;
|
||||
ack.Packets = new PacketAckPacket.PacketsBlock[1];
|
||||
ack.Packets[0] = new PacketAckPacket.PacketsBlock();
|
||||
ack.Packets[0].ID = sequenceNumber;
|
||||
|
||||
byte[] packetData = ack.ToBytes();
|
||||
int length = packetData.Length;
|
||||
|
||||
UDPPacketBuffer buffer = new UDPPacketBuffer(remoteEndpoint, length);
|
||||
buffer.DataLength = length;
|
||||
|
||||
Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length);
|
||||
|
||||
AsyncBeginSend(buffer);
|
||||
}
|
||||
|
||||
private bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo)
|
||||
{
|
||||
UUID agentID = useCircuitCode.CircuitCode.ID;
|
||||
|
|
|
@ -85,6 +85,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
/// <param name="sequenceNumber">Sequence number of the packet to
|
||||
/// acknowledge</param>
|
||||
/// <param name="currentTime">Current value of Environment.TickCount</param>
|
||||
/// <remarks>This does not immediately acknowledge the packet, it only
|
||||
/// queues the ack so it can be handled in a thread-safe way later</remarks>
|
||||
public void Remove(uint sequenceNumber, int currentTime, bool fromResend)
|
||||
{
|
||||
m_pendingRemoves.Enqueue(new PendingAck(sequenceNumber, currentTime, fromResend));
|
||||
|
@ -108,7 +110,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
if (m_packets.Count > 0)
|
||||
{
|
||||
int now = Environment.TickCount;
|
||||
int now = Environment.TickCount & Int32.MaxValue;
|
||||
|
||||
foreach (OutgoingPacket packet in m_packets.Values)
|
||||
{
|
||||
|
@ -123,10 +125,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
expiredPackets = new List<OutgoingPacket>();
|
||||
expiredPackets.Add(packet);
|
||||
}
|
||||
else
|
||||
/*else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue