diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs')
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 93 |
1 files changed, 57 insertions, 36 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 70cca51..b8ea6c1 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | |||
@@ -855,12 +855,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
855 | LLUDPClient udpClient, Packet packet, ThrottleOutPacketType category, bool allowSplitting, UnackedPacketMethod method) | 855 | LLUDPClient udpClient, Packet packet, ThrottleOutPacketType category, bool allowSplitting, UnackedPacketMethod method) |
856 | { | 856 | { |
857 | // CoarseLocationUpdate packets cannot be split in an automated way | 857 | // CoarseLocationUpdate packets cannot be split in an automated way |
858 | if (allowSplitting && packet.Type == PacketType.CoarseLocationUpdate) | 858 | if (allowSplitting && packet.HasVariableBlocks && packet.Type != PacketType.CoarseLocationUpdate) |
859 | allowSplitting = false; | ||
860 | |||
861 | // bool packetQueued = false; | ||
862 | |||
863 | if (allowSplitting && packet.HasVariableBlocks) | ||
864 | { | 859 | { |
865 | byte[][] datas = packet.ToBytesMultiple(); | 860 | byte[][] datas = packet.ToBytesMultiple(); |
866 | int packetCount = datas.Length; | 861 | int packetCount = datas.Length; |
@@ -887,6 +882,46 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
887 | PacketPool.Instance.ReturnPacket(packet); | 882 | PacketPool.Instance.ReturnPacket(packet); |
888 | } | 883 | } |
889 | 884 | ||
885 | public static int ZeroEncode(byte[] src, int srclen, byte[] dest) | ||
886 | { | ||
887 | Buffer.BlockCopy(src, 0, dest, 0, 6); | ||
888 | |||
889 | int zerolen = 6; | ||
890 | byte zerocount = 0; | ||
891 | |||
892 | for (int i = zerolen; i < srclen; i++) | ||
893 | { | ||
894 | if (src[i] == 0x00) | ||
895 | { | ||
896 | zerocount++; | ||
897 | if (zerocount == 0) | ||
898 | { | ||
899 | dest[zerolen++] = 0x00; | ||
900 | dest[zerolen++] = 0xff; | ||
901 | zerocount++; | ||
902 | } | ||
903 | } | ||
904 | else | ||
905 | { | ||
906 | if (zerocount != 0) | ||
907 | { | ||
908 | dest[zerolen++] = 0x00; | ||
909 | dest[zerolen++] = (byte)zerocount; | ||
910 | zerocount = 0; | ||
911 | } | ||
912 | |||
913 | dest[zerolen++] = src[i]; | ||
914 | } | ||
915 | } | ||
916 | |||
917 | if (zerocount != 0) | ||
918 | { | ||
919 | dest[zerolen++] = 0x00; | ||
920 | dest[zerolen++] = (byte)zerocount; | ||
921 | } | ||
922 | |||
923 | return (int)zerolen; | ||
924 | } | ||
890 | /// <summary> | 925 | /// <summary> |
891 | /// Start the process of sending a packet to the client. | 926 | /// Start the process of sending a packet to the client. |
892 | /// </summary> | 927 | /// </summary> |
@@ -919,8 +954,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
919 | { | 954 | { |
920 | try | 955 | try |
921 | { | 956 | { |
922 | dataLength = Helpers.ZeroEncode(data, dataLength, buffer.Data); | 957 | int testlen = ZeroEncode(data, dataLength, buffer.Data); |
923 | doCopy = false; | 958 | if(testlen <= dataLength) |
959 | { | ||
960 | dataLength = testlen; | ||
961 | doCopy = false; | ||
962 | } | ||
963 | else | ||
964 | data[0] = (byte)(data[0] & ~Helpers.MSG_ZEROCODED); | ||
924 | } | 965 | } |
925 | catch (IndexOutOfRangeException) | 966 | catch (IndexOutOfRangeException) |
926 | { | 967 | { |
@@ -942,15 +983,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
942 | } | 983 | } |
943 | else | 984 | else |
944 | { | 985 | { |
945 | bufferSize = dataLength; | ||
946 | buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, bufferSize); | ||
947 | |||
948 | m_log.Error("[LLUDPSERVER]: Packet exceeded buffer size! This could be an indication of packet assembly not obeying the MTU. Type=" + | 986 | m_log.Error("[LLUDPSERVER]: Packet exceeded buffer size! This could be an indication of packet assembly not obeying the MTU. Type=" + |
949 | type + ", DataLength=" + dataLength + ", BufferLength=" + buffer.Data.Length); | 987 | type + ", DataLength=" + dataLength + ", BufferLength=" + buffer.Data.Length); |
988 | buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, dataLength); | ||
950 | Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength); | 989 | Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength); |
951 | } | 990 | } |
952 | } | 991 | } |
953 | 992 | data = null; | |
954 | buffer.DataLength = dataLength; | 993 | buffer.DataLength = dataLength; |
955 | 994 | ||
956 | #region Queue or Send | 995 | #region Queue or Send |
@@ -972,7 +1011,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
972 | // If a Linden Lab 1.23.5 client receives an update packet after a kill packet for an object, it will | 1011 | // If a Linden Lab 1.23.5 client receives an update packet after a kill packet for an object, it will |
973 | // continue to display the deleted object until relog. Therefore, we need to always queue a kill object | 1012 | // continue to display the deleted object until relog. Therefore, we need to always queue a kill object |
974 | // packet so that it isn't sent before a queued update packet. | 1013 | // packet so that it isn't sent before a queued update packet. |
975 | |||
976 | bool requestQueue = type == PacketType.KillObject; | 1014 | bool requestQueue = type == PacketType.KillObject; |
977 | if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue, highPriority)) | 1015 | if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue, highPriority)) |
978 | { | 1016 | { |
@@ -1113,8 +1151,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1113 | if (!udpClient.IsConnected) | 1151 | if (!udpClient.IsConnected) |
1114 | return; | 1152 | return; |
1115 | 1153 | ||
1116 | #region ACK Appending | ||
1117 | |||
1118 | int dataLength = buffer.DataLength; | 1154 | int dataLength = buffer.DataLength; |
1119 | 1155 | ||
1120 | // NOTE: I'm seeing problems with some viewers when ACKs are appended to zerocoded packets so I've disabled that here | 1156 | // NOTE: I'm seeing problems with some viewers when ACKs are appended to zerocoded packets so I've disabled that here |
@@ -1122,9 +1158,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1122 | { | 1158 | { |
1123 | // Keep appending ACKs until there is no room left in the buffer or there are | 1159 | // Keep appending ACKs until there is no room left in the buffer or there are |
1124 | // no more ACKs to append | 1160 | // no more ACKs to append |
1125 | uint ackCount = 0; | 1161 | int ackCount = 0; |
1126 | uint ack; | 1162 | uint ack; |
1127 | while (dataLength + 5 < buffer.Data.Length && udpClient.PendingAcks.Dequeue(out ack)) | 1163 | while (dataLength + 5 < buffer.Data.Length && ackCount < 256 && udpClient.PendingAcks.Dequeue(out ack)) |
1128 | { | 1164 | { |
1129 | Utils.UIntToBytesBig(ack, buffer.Data, dataLength); | 1165 | Utils.UIntToBytesBig(ack, buffer.Data, dataLength); |
1130 | dataLength += 4; | 1166 | dataLength += 4; |
@@ -1142,10 +1178,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1142 | 1178 | ||
1143 | buffer.DataLength = dataLength; | 1179 | buffer.DataLength = dataLength; |
1144 | 1180 | ||
1145 | #endregion ACK Appending | ||
1146 | |||
1147 | #region Sequence Number Assignment | ||
1148 | |||
1149 | if (!isResend) | 1181 | if (!isResend) |
1150 | { | 1182 | { |
1151 | // Not a resend, assign a new sequence number | 1183 | // Not a resend, assign a new sequence number |
@@ -1162,32 +1194,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1162 | else | 1194 | else |
1163 | { | 1195 | { |
1164 | Interlocked.Increment(ref udpClient.PacketsResent); | 1196 | Interlocked.Increment(ref udpClient.PacketsResent); |
1165 | |||
1166 | // We're not going to worry about interlock yet since its not currently critical that this total count | ||
1167 | // is 100% correct | ||
1168 | PacketsResentCount++; | 1197 | PacketsResentCount++; |
1169 | } | 1198 | } |
1170 | 1199 | ||
1171 | #endregion Sequence Number Assignment | ||
1172 | |||
1173 | // Stats tracking | 1200 | // Stats tracking |
1174 | Interlocked.Increment(ref udpClient.PacketsSent); | 1201 | Interlocked.Increment(ref udpClient.PacketsSent); |
1175 | |||
1176 | // We're not going to worry about interlock yet since its not currently critical that this total count | ||
1177 | // is 100% correct | ||
1178 | PacketsSentCount++; | 1202 | PacketsSentCount++; |
1179 | 1203 | ||
1204 | SyncSend(buffer); | ||
1205 | // Keep track of when this packet was sent out (right now) | ||
1206 | outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue; | ||
1207 | |||
1180 | if (udpClient.DebugDataOutLevel > 0) | 1208 | if (udpClient.DebugDataOutLevel > 0) |
1181 | m_log.DebugFormat( | 1209 | m_log.DebugFormat( |
1182 | "[LLUDPSERVER]: Sending packet #{0} (rel: {1}, res: {2}) to {3} from {4}", | 1210 | "[LLUDPSERVER]: Sending packet #{0} (rel: {1}, res: {2}) to {3} from {4}", |
1183 | outgoingPacket.SequenceNumber, isReliable, isResend, udpClient.AgentID, Scene.Name); | 1211 | outgoingPacket.SequenceNumber, isReliable, isResend, udpClient.AgentID, Scene.Name); |
1184 | |||
1185 | // Put the UDP payload on the wire | ||
1186 | // AsyncBeginSend(buffer); | ||
1187 | SyncSend(buffer); | ||
1188 | |||
1189 | // Keep track of when this packet was sent out (right now) | ||
1190 | outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue; | ||
1191 | } | 1212 | } |
1192 | 1213 | ||
1193 | protected void RecordMalformedInboundPacket(IPEndPoint endPoint) | 1214 | protected void RecordMalformedInboundPacket(IPEndPoint endPoint) |