aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs93
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)