diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP')
-rwxr-xr-x | OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 99 |
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 |