aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/UDP
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP')
-rwxr-xr-xOpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs99
1 files changed, 73 insertions, 26 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 780e8f8..79f5fe6 100755
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -989,49 +989,96 @@ namespace OpenSim.Region.ClientStack.LindenUDP
989 SendPacketFinal(outgoingPacket); 989 SendPacketFinal(outgoingPacket);
990 } 990 }
991 991
992 static private readonly byte[] PacketAckHeader = new byte[] {
993 0,
994 0, 0, 0, 0, // sequence number
995 0, // extra
996 0xff, 0xff, 0xff, 0xfb // ID 65531 (low frequency bigendian)
997 };
998
992 public void SendAcks(LLUDPClient udpClient) 999 public void SendAcks(LLUDPClient udpClient)
993 { 1000 {
994 uint ack; 1001 if(udpClient.PendingAcks.Count == 0)
1002 return;
1003
1004 UDPPacketBuffer buf = GetNewUDPBuffer(udpClient.RemoteEndPoint);
1005 Buffer.BlockCopy(PacketAckHeader, 0, buf.Data, 0, 10);
1006 byte[] data = buf.Data;
1007 // count at position 10
1008 int pos = 11;
995 1009
996 if (udpClient.PendingAcks.Dequeue(out ack)) 1010 uint ack;
1011 int count = 0;
1012 while (udpClient.PendingAcks.Dequeue(out ack))
997 { 1013 {
998 List<PacketAckPacket.PacketsBlock> blocks = new List<PacketAckPacket.PacketsBlock>(); 1014 Utils.UIntToBytes(ack, data, pos); pos += 4;
999 PacketAckPacket.PacketsBlock block = new PacketAckPacket.PacketsBlock(); 1015 ++count;
1000 block.ID = ack;
1001 blocks.Add(block);
1002 1016
1003 while (udpClient.PendingAcks.Dequeue(out ack)) 1017 if (count == 255)
1004 { 1018 {
1005 block = new PacketAckPacket.PacketsBlock(); 1019 data[10] = 255;
1006 block.ID = ack; 1020 buf.DataLength = pos;
1007 blocks.Add(block); 1021 SendUDPPacket(udpClient, buf, ThrottleOutPacketType.Unknown, null, false, false);
1022
1023 buf = GetNewUDPBuffer(udpClient.RemoteEndPoint);
1024 Buffer.BlockCopy(PacketAckHeader, 0, buf.Data, 0, 10);
1025 data = buf.Data;
1026 pos = 11;
1027 count = 0;
1008 } 1028 }
1009 1029 }
1010 PacketAckPacket packet = new PacketAckPacket(); 1030 if (count > 0)
1011 packet.Header.Reliable = false; 1031 {
1012 packet.Packets = blocks.ToArray(); 1032 data[10] = (byte)count;
1013 1033 buf.DataLength = pos;
1014 SendPacket(udpClient, packet, ThrottleOutPacketType.Unknown, true, null); 1034 SendUDPPacket(udpClient, buf, ThrottleOutPacketType.Unknown, null, false, false);
1015 } 1035 }
1016 } 1036 }
1017 1037
1038 static private readonly byte[] StartPingCheckHeader = new byte[] {
1039 0,
1040 0, 0, 0, 0, // sequence number
1041 0, // extra
1042 1 // ID 1 (high frequency)
1043 };
1044
1018 public void SendPing(LLUDPClient udpClient) 1045 public void SendPing(LLUDPClient udpClient)
1019 { 1046 {
1020 StartPingCheckPacket pc = (StartPingCheckPacket)PacketPool.Instance.GetPacket(PacketType.StartPingCheck); 1047 UDPPacketBuffer buf = GetNewUDPBuffer(udpClient.RemoteEndPoint);
1048 Buffer.BlockCopy(StartPingCheckHeader, 0, buf.Data, 0, 7);
1049 byte[] data = buf.Data;
1050
1051 data[7] = udpClient.CurrentPingSequence++;
1052 // older seq number of our un ack packets, so viewers could clean deduplication lists TODO
1053 //Utils.UIntToBytes(0, data, 8);
1054 data[8] = 0;
1055 data[9] = 0;
1056 data[10] = 0;
1057 data[11] = 0;
1021 1058
1022 pc.PingID.PingID = (byte)udpClient.CurrentPingSequence++; 1059 buf.DataLength = 12;
1023 // We *could* get OldestUnacked, but it would hurt performance and not provide any benefit 1060 SendUDPPacket(udpClient, buf, ThrottleOutPacketType.Unknown, null, false, false);
1024 pc.PingID.OldestUnacked = 0;
1025 1061
1026 SendPacket(udpClient, pc, ThrottleOutPacketType.Unknown, false, null);
1027 udpClient.m_lastStartpingTimeMS = Util.EnvironmentTickCount(); 1062 udpClient.m_lastStartpingTimeMS = Util.EnvironmentTickCount();
1028 } 1063 }
1029 1064
1065 static private readonly byte[] CompletePingCheckHeader = new byte[] {
1066 0,
1067 0, 0, 0, 0, // sequence number
1068 0, // extra
1069 2 // ID 1 (high frequency)
1070 };
1071
1030 public void CompletePing(LLUDPClient udpClient, byte pingID) 1072 public void CompletePing(LLUDPClient udpClient, byte pingID)
1031 { 1073 {
1032 CompletePingCheckPacket completePing = new CompletePingCheckPacket(); 1074 UDPPacketBuffer buf = GetNewUDPBuffer(udpClient.RemoteEndPoint);
1033 completePing.PingID.PingID = pingID; 1075 Buffer.BlockCopy(CompletePingCheckHeader, 0, buf.Data, 0, 7);
1034 SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false, null); 1076 byte[] data = buf.Data;
1077
1078 data[7] = pingID;
1079
1080 buf.DataLength = 8;
1081 SendUDPPacket(udpClient, buf, ThrottleOutPacketType.Unknown, null, false, false);
1035 } 1082 }
1036 1083
1037 public void HandleUnacked(LLClientView client) 1084 public void HandleUnacked(LLClientView client)
@@ -1121,8 +1168,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1121 1168
1122 int dataLength = buffer.DataLength; 1169 int dataLength = buffer.DataLength;
1123 1170
1124 // NOTE: I'm seeing problems with some viewers when ACKs are appended to zerocoded packets so I've disabled that here 1171 // only append acks on plain reliable messages
1125 if (!isZerocoded && !isResend && outgoingPacket.UnackedMethod == null) 1172 if (flags == Helpers.MSG_RELIABLE && outgoingPacket.UnackedMethod == null)
1126 { 1173 {
1127 // Keep appending ACKs until there is no room left in the buffer or there are 1174 // Keep appending ACKs until there is no room left in the buffer or there are
1128 // no more ACKs to append 1175 // no more ACKs to append