lludp: direct encode PacketAck, StartPingCheck and CompletePingCheck
parent
ee8ad3e69d
commit
8bb0c05825
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue