lludp: direct encode PacketAck, StartPingCheck and CompletePingCheck

0.9.1.0-post-fixes
UbitUmarov 2019-03-17 18:16:38 +00:00
parent ee8ad3e69d
commit 8bb0c05825
1 changed files with 73 additions and 26 deletions

View File

@ -989,49 +989,96 @@ namespace OpenSim.Region.ClientStack.LindenUDP
SendPacketFinal(outgoingPacket);
}
static private readonly byte[] PacketAckHeader = new byte[] {
0,
0, 0, 0, 0, // sequence number
0, // extra
0xff, 0xff, 0xff, 0xfb // ID 65531 (low frequency bigendian)
};
public void SendAcks(LLUDPClient udpClient)
{
if(udpClient.PendingAcks.Count == 0)
return;
UDPPacketBuffer buf = GetNewUDPBuffer(udpClient.RemoteEndPoint);
Buffer.BlockCopy(PacketAckHeader, 0, buf.Data, 0, 10);
byte[] data = buf.Data;
// count at position 10
int pos = 11;
uint ack;
if (udpClient.PendingAcks.Dequeue(out ack))
int count = 0;
while (udpClient.PendingAcks.Dequeue(out ack))
{
List<PacketAckPacket.PacketsBlock> blocks = new List<PacketAckPacket.PacketsBlock>();
PacketAckPacket.PacketsBlock block = new PacketAckPacket.PacketsBlock();
block.ID = ack;
blocks.Add(block);
Utils.UIntToBytes(ack, data, pos); pos += 4;
++count;
while (udpClient.PendingAcks.Dequeue(out ack))
if (count == 255)
{
block = new PacketAckPacket.PacketsBlock();
block.ID = ack;
blocks.Add(block);
data[10] = 255;
buf.DataLength = pos;
SendUDPPacket(udpClient, buf, ThrottleOutPacketType.Unknown, null, false, false);
buf = GetNewUDPBuffer(udpClient.RemoteEndPoint);
Buffer.BlockCopy(PacketAckHeader, 0, buf.Data, 0, 10);
data = buf.Data;
pos = 11;
count = 0;
}
PacketAckPacket packet = new PacketAckPacket();
packet.Header.Reliable = false;
packet.Packets = blocks.ToArray();
SendPacket(udpClient, packet, ThrottleOutPacketType.Unknown, true, null);
}
if (count > 0)
{
data[10] = (byte)count;
buf.DataLength = pos;
SendUDPPacket(udpClient, buf, ThrottleOutPacketType.Unknown, null, false, false);
}
}
static private readonly byte[] StartPingCheckHeader = new byte[] {
0,
0, 0, 0, 0, // sequence number
0, // extra
1 // ID 1 (high frequency)
};
public void SendPing(LLUDPClient udpClient)
{
StartPingCheckPacket pc = (StartPingCheckPacket)PacketPool.Instance.GetPacket(PacketType.StartPingCheck);
UDPPacketBuffer buf = GetNewUDPBuffer(udpClient.RemoteEndPoint);
Buffer.BlockCopy(StartPingCheckHeader, 0, buf.Data, 0, 7);
byte[] data = buf.Data;
pc.PingID.PingID = (byte)udpClient.CurrentPingSequence++;
// We *could* get OldestUnacked, but it would hurt performance and not provide any benefit
pc.PingID.OldestUnacked = 0;
data[7] = udpClient.CurrentPingSequence++;
// older seq number of our un ack packets, so viewers could clean deduplication lists TODO
//Utils.UIntToBytes(0, data, 8);
data[8] = 0;
data[9] = 0;
data[10] = 0;
data[11] = 0;
buf.DataLength = 12;
SendUDPPacket(udpClient, buf, ThrottleOutPacketType.Unknown, null, false, false);
SendPacket(udpClient, pc, ThrottleOutPacketType.Unknown, false, null);
udpClient.m_lastStartpingTimeMS = Util.EnvironmentTickCount();
}
static private readonly byte[] CompletePingCheckHeader = new byte[] {
0,
0, 0, 0, 0, // sequence number
0, // extra
2 // ID 1 (high frequency)
};
public void CompletePing(LLUDPClient udpClient, byte pingID)
{
CompletePingCheckPacket completePing = new CompletePingCheckPacket();
completePing.PingID.PingID = pingID;
SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false, null);
UDPPacketBuffer buf = GetNewUDPBuffer(udpClient.RemoteEndPoint);
Buffer.BlockCopy(CompletePingCheckHeader, 0, buf.Data, 0, 7);
byte[] data = buf.Data;
data[7] = pingID;
buf.DataLength = 8;
SendUDPPacket(udpClient, buf, ThrottleOutPacketType.Unknown, null, false, false);
}
public void HandleUnacked(LLClientView client)
@ -1121,8 +1168,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
int dataLength = buffer.DataLength;
// NOTE: I'm seeing problems with some viewers when ACKs are appended to zerocoded packets so I've disabled that here
if (!isZerocoded && !isResend && outgoingPacket.UnackedMethod == null)
// only append acks on plain reliable messages
if (flags == Helpers.MSG_RELIABLE && outgoingPacket.UnackedMethod == null)
{
// Keep appending ACKs until there is no room left in the buffer or there are
// no more ACKs to append