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')
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs350
1 files changed, 163 insertions, 187 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 35d29a5..2300800 100644..100755
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -256,6 +256,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
256 256
257 /// <summary>Maximum transmission unit, or UDP packet size, for the LLUDP protocol</summary> 257 /// <summary>Maximum transmission unit, or UDP packet size, for the LLUDP protocol</summary>
258 public const int MTU = 1400; 258 public const int MTU = 1400;
259 public const int MAXPAYLOAD = 1250;
259 260
260 /// <summary>Number of forced client logouts due to no receipt of packets before timeout.</summary> 261 /// <summary>Number of forced client logouts due to no receipt of packets before timeout.</summary>
261 public int ClientLogoutsDueToNoReceives { get; protected set; } 262 public int ClientLogoutsDueToNoReceives { get; protected set; }
@@ -274,10 +275,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
274 /// <summary>The measured resolution of Environment.TickCount</summary> 275 /// <summary>The measured resolution of Environment.TickCount</summary>
275 public readonly float TickCountResolution; 276 public readonly float TickCountResolution;
276 277
277 /// <summary>Number of prim updates to put on the queue each time the
278 /// OnQueueEmpty event is triggered for updates</summary>
279 public readonly int PrimUpdatesPerCallback;
280
281 /// <summary>Number of texture packets to put on the queue each time the 278 /// <summary>Number of texture packets to put on the queue each time the
282 /// OnQueueEmpty event is triggered for textures</summary> 279 /// OnQueueEmpty event is triggered for textures</summary>
283 public readonly int TextureSendLimit; 280 public readonly int TextureSendLimit;
@@ -344,18 +341,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
344 341
345 protected ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>(); 342 protected ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
346 343
347 protected Pool<IncomingPacket> m_incomingPacketPool;
348
349 /// <summary>
350 /// Stat for number of packets in the main pool awaiting use.
351 /// </summary>
352 protected Stat m_poolCountStat;
353
354 /// <summary>
355 /// Stat for number of packets in the inbound packet pool awaiting use.
356 /// </summary>
357 protected Stat m_incomingPacketPoolStat;
358
359 protected int m_defaultRTO = 0; 344 protected int m_defaultRTO = 0;
360 protected int m_maxRTO = 0; 345 protected int m_maxRTO = 0;
361 protected int m_ackTimeout = 0; 346 protected int m_ackTimeout = 0;
@@ -452,7 +437,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
452 m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0); 437 m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0);
453 sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0); 438 sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0);
454 439
455 PrimUpdatesPerCallback = config.GetInt("PrimUpdatesPerCallback", 100);
456 TextureSendLimit = config.GetInt("TextureSendLimit", 20); 440 TextureSendLimit = config.GetInt("TextureSendLimit", 20);
457 441
458 m_defaultRTO = config.GetInt("DefaultRTO", 0); 442 m_defaultRTO = config.GetInt("DefaultRTO", 0);
@@ -463,7 +447,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
463 } 447 }
464 else 448 else
465 { 449 {
466 PrimUpdatesPerCallback = 100;
467 TextureSendLimit = 20; 450 TextureSendLimit = 20;
468 m_ackTimeout = 1000 * 60; // 1 minute 451 m_ackTimeout = 1000 * 60; // 1 minute
469 m_pausedAckTimeout = 1000 * 300; // 5 minutes 452 m_pausedAckTimeout = 1000 * 300; // 5 minutes
@@ -498,7 +481,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
498 481
499// if (usePools) 482// if (usePools)
500// EnablePools(); 483// EnablePools();
501 base.DisablePools();
502 } 484 }
503 485
504 public void Start() 486 public void Start()
@@ -554,83 +536,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
554 OqrEngine.Stop(); 536 OqrEngine.Stop();
555 } 537 }
556 538
557 public override bool EnablePools()
558 {
559 if (!UsePools)
560 {
561 base.EnablePools();
562
563 m_incomingPacketPool = new Pool<IncomingPacket>(() => new IncomingPacket(), 500);
564
565 return true;
566 }
567
568 return false;
569 }
570
571 public override bool DisablePools()
572 {
573 if (UsePools)
574 {
575 base.DisablePools();
576
577 StatsManager.DeregisterStat(m_incomingPacketPoolStat);
578
579 // We won't null out the pool to avoid a race condition with code that may be in the middle of using it.
580
581 return true;
582 }
583
584 return false;
585 }
586
587 /// <summary>
588 /// This is a seperate method so that it can be called once we have an m_scene to distinguish different scene
589 /// stats.
590 /// </summary>
591 protected internal void EnablePoolStats()
592 {
593 m_poolCountStat
594 = new Stat(
595 "UDPPacketBufferPoolCount",
596 "Objects within the UDPPacketBuffer pool",
597 "The number of objects currently stored within the UDPPacketBuffer pool",
598 "",
599 "clientstack",
600 Scene.Name,
601 StatType.Pull,
602 stat => stat.Value = Pool.Count,
603 StatVerbosity.Debug);
604
605 StatsManager.RegisterStat(m_poolCountStat);
606
607 m_incomingPacketPoolStat
608 = new Stat(
609 "IncomingPacketPoolCount",
610 "Objects within incoming packet pool",
611 "The number of objects currently stored within the incoming packet pool",
612 "",
613 "clientstack",
614 Scene.Name,
615 StatType.Pull,
616 stat => stat.Value = m_incomingPacketPool.Count,
617 StatVerbosity.Debug);
618
619 StatsManager.RegisterStat(m_incomingPacketPoolStat);
620 }
621
622 /// <summary>
623 /// Disables pool stats.
624 /// </summary>
625 protected internal void DisablePoolStats()
626 {
627 StatsManager.DeregisterStat(m_poolCountStat);
628 m_poolCountStat = null;
629
630 StatsManager.DeregisterStat(m_incomingPacketPoolStat);
631 m_incomingPacketPoolStat = null;
632 }
633
634 /// <summary> 539 /// <summary>
635 /// If the outgoing UDP thread times out, then return client that was being processed to help with debugging. 540 /// If the outgoing UDP thread times out, then return client that was being processed to help with debugging.
636 /// </summary> 541 /// </summary>
@@ -658,8 +563,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
658 string.Format("Incoming Packet Async Handling Engine ({0})", Scene.Name), 563 string.Format("Incoming Packet Async Handling Engine ({0})", Scene.Name),
659 "INCOMING PACKET ASYNC HANDLING ENGINE"); 564 "INCOMING PACKET ASYNC HANDLING ENGINE");
660*/ 565*/
661 OqrEngine 566 OqrEngine = new JobEngine(
662 = new JobEngine(
663 string.Format("Outgoing Queue Refill Engine ({0})", Scene.Name), 567 string.Format("Outgoing Queue Refill Engine ({0})", Scene.Name),
664 "OUTGOING QUEUE REFILL ENGINE"); 568 "OUTGOING QUEUE REFILL ENGINE");
665 569
@@ -769,15 +673,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
769 stat => stat.Value = OqrEngine.JobsWaiting, 673 stat => stat.Value = OqrEngine.JobsWaiting,
770 StatVerbosity.Debug)); 674 StatVerbosity.Debug));
771 675
772 // We delay enabling pool stats to AddScene() instead of Initialize() so that we can distinguish pool stats by 676 StatsManager.RegisterStat(
773 // scene name 677 new Stat(
774 if (UsePools) 678 "UDPBuffersPoolCount",
775 EnablePoolStats(); 679 "Buffers in the UDP buffers pool",
776 680 "The number of buffers currently stored within the UDP buffers pool",
681 "",
682 "clientstack",
683 Scene.Name,
684 StatType.Pull,
685 stat => stat.Value = m_udpBuffersPoolPtr + 1,
686 StatVerbosity.Debug));
777 687
778 LLUDPServerCommands commands = new LLUDPServerCommands(MainConsole.Instance, this); 688 LLUDPServerCommands commands = new LLUDPServerCommands(MainConsole.Instance, this);
779 commands.Register(); 689 commands.Register();
780
781 } 690 }
782 691
783 public bool HandlesRegion(Location x) 692 public bool HandlesRegion(Location x)
@@ -939,9 +848,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
939 // The vast majority of packets are less than 200 bytes, although due to asset transfers and packet splitting 848 // The vast majority of packets are less than 200 bytes, although due to asset transfers and packet splitting
940 // there are a decent number of packets in the 1000-1140 byte range. We allocate one of two sizes of data here 849 // there are a decent number of packets in the 1000-1140 byte range. We allocate one of two sizes of data here
941 // to accomodate for both common scenarios and provide ample room for ACK appending in both 850 // to accomodate for both common scenarios and provide ample room for ACK appending in both
942 int bufferSize = (dataLength > 180) ? LLUDPServer.MTU : 200; 851 //int bufferSize = (dataLength > 180) ? LLUDPServer.MTU : 200;
943 852
944 UDPPacketBuffer buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, bufferSize); 853 //UDPPacketBuffer buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, bufferSize);
854 UDPPacketBuffer buffer = GetNewUDPBuffer(udpClient.RemoteEndPoint);
945 855
946 // Zerocode if needed 856 // Zerocode if needed
947 if (doZerocode) 857 if (doZerocode)
@@ -971,7 +881,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
971 // If the packet data wasn't already copied during zerocoding, copy it now 881 // If the packet data wasn't already copied during zerocoding, copy it now
972 if (doCopy) 882 if (doCopy)
973 { 883 {
974 if (dataLength <= buffer.Data.Length) 884 //if (dataLength <= buffer.Data.Length)
885 if (dataLength <= LLUDPServer.MTU)
975 { 886 {
976 Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength); 887 Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength);
977 } 888 }
@@ -979,7 +890,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
979 { 890 {
980 m_log.Error("[LLUDPSERVER]: Packet exceeded buffer size! This could be an indication of packet assembly not obeying the MTU. Type=" + 891 m_log.Error("[LLUDPSERVER]: Packet exceeded buffer size! This could be an indication of packet assembly not obeying the MTU. Type=" +
981 type + ", DataLength=" + dataLength + ", BufferLength=" + buffer.Data.Length); 892 type + ", DataLength=" + dataLength + ", BufferLength=" + buffer.Data.Length);
982 buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, dataLength); 893 // buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, dataLength);
894 buffer = GetNewUDPBuffer(udpClient.RemoteEndPoint);
983 Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength); 895 Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength);
984 } 896 }
985 } 897 }
@@ -1017,6 +929,89 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1017 #endregion Queue or Send 929 #endregion Queue or Send
1018 } 930 }
1019 931
932 public unsafe UDPPacketBuffer ZeroEncode(UDPPacketBuffer input)
933 {
934 UDPPacketBuffer zb = GetNewUDPBuffer(null);
935 int srclen = input.DataLength;
936 byte[] src = input.Data;
937 byte[] dest = zb.Data;
938
939 int zerolen = 6;
940 byte zerocount = 0;
941
942 for (int i = zerolen; i < srclen; i++)
943 {
944 if (src[i] == 0x00)
945 {
946 zerocount++;
947 if (zerocount == 0)
948 {
949 dest[zerolen++] = 0x00;
950 dest[zerolen++] = 0xff;
951 zerocount++;
952 }
953 }
954 else
955 {
956 if (zerocount != 0)
957 {
958 dest[zerolen++] = 0x00;
959 dest[zerolen++] = zerocount;
960 zerocount = 0;
961 }
962
963 dest[zerolen++] = src[i];
964 }
965 }
966
967 if (zerocount != 0)
968 {
969 dest[zerolen++] = 0x00;
970 dest[zerolen++] = zerocount;
971 }
972
973 if(zerolen >= srclen)
974 {
975 FreeUDPBuffer(zb);
976
977 src[0] &= unchecked((byte)~Helpers.MSG_ZEROCODED);
978 return input;
979 }
980
981 Buffer.BlockCopy(src, 0, dest, 0, 6);
982
983 zb.RemoteEndPoint = input.RemoteEndPoint;
984 zb.DataLength = zerolen;
985
986 FreeUDPBuffer(input);
987
988 return zb;
989 }
990
991 public void SendUDPPacket(
992 LLUDPClient udpClient, UDPPacketBuffer buffer, ThrottleOutPacketType category, UnackedPacketMethod method, bool forcequeue, bool zerocode)
993 {
994 bool highPriority = false;
995
996 if(zerocode)
997 buffer = ZeroEncode(buffer);
998
999 if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0)
1000 {
1001 category = (ThrottleOutPacketType)((int)category & 127);
1002 highPriority = true;
1003 }
1004
1005 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null);
1006
1007 // If we were not provided a method for handling unacked, use the UDPServer default method
1008 if ((outgoingPacket.Buffer.Data[0] & Helpers.MSG_RELIABLE) != 0)
1009 outgoingPacket.UnackedMethod = ((method == null) ? delegate (OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method);
1010
1011 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, forcequeue, highPriority))
1012 SendPacketFinal(outgoingPacket);
1013 }
1014
1020 public void SendAcks(LLUDPClient udpClient) 1015 public void SendAcks(LLUDPClient udpClient)
1021 { 1016 {
1022 uint ack; 1017 uint ack;
@@ -1066,7 +1061,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1066 { 1061 {
1067 LLUDPClient udpClient = client.UDPClient; 1062 LLUDPClient udpClient = client.UDPClient;
1068 1063
1069 if (!udpClient.IsConnected) 1064 if (!client.IsActive || !udpClient.IsConnected)
1070 return; 1065 return;
1071 1066
1072 // Disconnect an agent if no packets are received for some time 1067 // Disconnect an agent if no packets are received for some time
@@ -1136,14 +1131,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1136 internal void SendPacketFinal(OutgoingPacket outgoingPacket) 1131 internal void SendPacketFinal(OutgoingPacket outgoingPacket)
1137 { 1132 {
1138 UDPPacketBuffer buffer = outgoingPacket.Buffer; 1133 UDPPacketBuffer buffer = outgoingPacket.Buffer;
1134 if(buffer == null) // canceled packet
1135 return;
1136 LLUDPClient udpClient = outgoingPacket.Client;
1137 if (!udpClient.IsConnected)
1138 return;
1139
1139 byte flags = buffer.Data[0]; 1140 byte flags = buffer.Data[0];
1140 bool isResend = (flags & Helpers.MSG_RESENT) != 0; 1141 bool isResend = (flags & Helpers.MSG_RESENT) != 0;
1141 bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0; 1142 bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0;
1142 bool isZerocoded = (flags & Helpers.MSG_ZEROCODED) != 0; 1143 bool isZerocoded = (flags & Helpers.MSG_ZEROCODED) != 0;
1143 LLUDPClient udpClient = outgoingPacket.Client;
1144
1145 if (!udpClient.IsConnected)
1146 return;
1147 1144
1148 int dataLength = buffer.DataLength; 1145 int dataLength = buffer.DataLength;
1149 1146
@@ -1154,7 +1151,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1154 // no more ACKs to append 1151 // no more ACKs to append
1155 int ackCount = 0; 1152 int ackCount = 0;
1156 uint ack; 1153 uint ack;
1157 while (dataLength + 5 < buffer.Data.Length && ackCount < 256 && udpClient.PendingAcks.Dequeue(out ack)) 1154 while (dataLength + 5 < MTU && ackCount < 256 && udpClient.PendingAcks.Dequeue(out ack))
1158 { 1155 {
1159 Utils.UIntToBytesBig(ack, buffer.Data, dataLength); 1156 Utils.UIntToBytesBig(ack, buffer.Data, dataLength);
1160 dataLength += 4; 1157 dataLength += 4;
@@ -1168,22 +1165,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1168 // Set the appended ACKs flag on this packet 1165 // Set the appended ACKs flag on this packet
1169 buffer.Data[0] = (byte)(buffer.Data[0] | Helpers.MSG_APPENDED_ACKS); 1166 buffer.Data[0] = (byte)(buffer.Data[0] | Helpers.MSG_APPENDED_ACKS);
1170 } 1167 }
1168 buffer.DataLength = dataLength;
1171 } 1169 }
1172 1170
1173 buffer.DataLength = dataLength;
1174
1175 if (!isResend) 1171 if (!isResend)
1176 { 1172 {
1177 // Not a resend, assign a new sequence number 1173 // Not a resend, assign a new sequence number
1178 uint sequenceNumber = (uint)Interlocked.Increment(ref udpClient.CurrentSequence); 1174 uint sequenceNumber = (uint)Interlocked.Increment(ref udpClient.CurrentSequence);
1179 Utils.UIntToBytesBig(sequenceNumber, buffer.Data, 1); 1175 Utils.UIntToBytesBig(sequenceNumber, buffer.Data, 1);
1180 outgoingPacket.SequenceNumber = sequenceNumber; 1176 outgoingPacket.SequenceNumber = sequenceNumber;
1181
1182 if (isReliable)
1183 {
1184 // Add this packet to the list of ACK responses we are waiting on from the server
1185 udpClient.NeedAcks.Add(outgoingPacket);
1186 }
1187 } 1177 }
1188 else 1178 else
1189 { 1179 {
@@ -1196,9 +1186,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1196 PacketsSentCount++; 1186 PacketsSentCount++;
1197 1187
1198 SyncSend(buffer); 1188 SyncSend(buffer);
1189
1199 // Keep track of when this packet was sent out (right now) 1190 // Keep track of when this packet was sent out (right now)
1200 outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue; 1191 outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue;
1201 1192
1193 if (outgoingPacket.UnackedMethod == null)
1194 FreeUDPBuffer(buffer);
1195 else if(!isResend)
1196 {
1197 // Add this packet to the list of ACK responses we are waiting on from the server
1198 udpClient.NeedAcks.Add(outgoingPacket);
1199 }
1200
1202 if (udpClient.DebugDataOutLevel > 0) 1201 if (udpClient.DebugDataOutLevel > 0)
1203 m_log.DebugFormat( 1202 m_log.DebugFormat(
1204 "[LLUDPSERVER]: Sending packet #{0} (rel: {1}, res: {2}) to {3} from {4}", 1203 "[LLUDPSERVER]: Sending packet #{0} (rel: {1}, res: {2}) to {3} from {4}",
@@ -1240,7 +1239,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1240// buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); 1239// buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
1241 1240
1242 RecordMalformedInboundPacket(endPoint); 1241 RecordMalformedInboundPacket(endPoint);
1243 1242 FreeUDPBuffer(buffer);
1244 return; // Drop undersized packet 1243 return; // Drop undersized packet
1245 } 1244 }
1246 1245
@@ -1260,21 +1259,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1260// buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); 1259// buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
1261 1260
1262 RecordMalformedInboundPacket(endPoint); 1261 RecordMalformedInboundPacket(endPoint);
1263 1262 FreeUDPBuffer(buffer);
1264 return; // Malformed header 1263 return; // Malformed header
1265 } 1264 }
1266 1265
1267 try 1266 try
1268 { 1267 {
1269// packet = Packet.BuildPacket(buffer.Data, ref packetEnd, 1268 // get a buffer for zero decode using the udp buffers pool
1270// // Only allocate a buffer for zerodecoding if the packet is zerocoded 1269 UDPPacketBuffer zerodecodebufferholder = null;
1271// ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); 1270 byte[] zerodecodebuffer = null;
1271 // only if needed
1272 if (((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0))
1273 {
1274 zerodecodebufferholder = GetNewUDPBuffer(null);
1275 zerodecodebuffer = zerodecodebufferholder.Data;
1276 }
1277
1278 packet = Packet.BuildPacket(buffer.Data, ref packetEnd, zerodecodebuffer);
1272 // If OpenSimUDPBase.UsePool == true (which is currently separate from the PacketPool) then we 1279 // If OpenSimUDPBase.UsePool == true (which is currently separate from the PacketPool) then we
1273 // assume that packet construction does not retain a reference to byte[] buffer.Data (instead, all 1280 // assume that packet construction does not retain a reference to byte[] buffer.Data (instead, all
1274 // bytes are copied out). 1281 // bytes are copied out).
1275 packet = PacketPool.Instance.GetPacket(buffer.Data, ref packetEnd, 1282 // packet = PacketPool.Instance.GetPacket(buffer.Data, ref packetEnd, zerodecodebuffer);
1276 // Only allocate a buffer for zerodecoding if the packet is zerocoded 1283 if(zerodecodebufferholder != null)
1277 ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); 1284 FreeUDPBuffer(zerodecodebufferholder);
1278 } 1285 }
1279 catch (Exception e) 1286 catch (Exception e)
1280 { 1287 {
@@ -1292,7 +1299,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1292 } 1299 }
1293 1300
1294 RecordMalformedInboundPacket(endPoint); 1301 RecordMalformedInboundPacket(endPoint);
1295 1302 FreeUDPBuffer(buffer);
1296 return; 1303 return;
1297 } 1304 }
1298 1305
@@ -1311,17 +1318,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1311 lock (m_pendingCache) 1318 lock (m_pendingCache)
1312 { 1319 {
1313 if (m_pendingCache.Contains(endPoint)) 1320 if (m_pendingCache.Contains(endPoint))
1321 {
1322 FreeUDPBuffer(buffer);
1314 return; 1323 return;
1324 }
1315 1325
1316 m_pendingCache.AddOrUpdate(endPoint, new Queue<UDPPacketBuffer>(), 60); 1326 m_pendingCache.AddOrUpdate(endPoint, new Queue<UDPPacketBuffer>(), 60);
1317 } 1327 }
1318 1328
1319 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the 1329 Util.FireAndForget(HandleUseCircuitCode, new object[] { endPoint, packet });
1320 // buffer. 1330 FreeUDPBuffer(buffer);
1321 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1322
1323 Util.FireAndForget(HandleUseCircuitCode, array);
1324
1325 return; 1331 return;
1326 } 1332 }
1327 } 1333 }
@@ -1336,24 +1342,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1336 queue.Enqueue(buffer); 1342 queue.Enqueue(buffer);
1337 return; 1343 return;
1338 } 1344 }
1339
1340/*
1341 else if (packet.Type == PacketType.CompleteAgentMovement)
1342 {
1343 // Send ack straight away to let the viewer know that we got it.
1344 SendAckImmediate(endPoint, packet.Header.Sequence);
1345
1346 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1347 // buffer.
1348 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1349
1350 Util.FireAndForget(HandleCompleteMovementIntoRegion, array);
1351
1352 return;
1353 }
1354 */
1355 } 1345 }
1356 1346
1347 FreeUDPBuffer(buffer);
1348
1357 // Determine which agent this packet came from 1349 // Determine which agent this packet came from
1358 if (client == null || !(client is LLClientView)) 1350 if (client == null || !(client is LLClientView))
1359 { 1351 {
@@ -1471,10 +1463,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1471 LogPacketHeader(true, udpClient.CircuitCode, 0, packet.Type, (ushort)packet.Length); 1463 LogPacketHeader(true, udpClient.CircuitCode, 0, packet.Type, (ushort)packet.Length);
1472 #endregion BinaryStats 1464 #endregion BinaryStats
1473 1465
1474
1475//AgentUpdate removed from here
1476
1477
1478 #region Ping Check Handling 1466 #region Ping Check Handling
1479 1467
1480 if (packet.Type == PacketType.StartPingCheck) 1468 if (packet.Type == PacketType.StartPingCheck)
@@ -1506,17 +1494,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1506 1494
1507 IncomingPacket incomingPacket; 1495 IncomingPacket incomingPacket;
1508 1496
1509 // Inbox insertion 1497 incomingPacket = new IncomingPacket((LLClientView)client, packet);
1510 if (UsePools)
1511 {
1512 incomingPacket = m_incomingPacketPool.GetObject();
1513 incomingPacket.Client = (LLClientView)client;
1514 incomingPacket.Packet = packet;
1515 }
1516 else
1517 {
1518 incomingPacket = new IncomingPacket((LLClientView)client, packet);
1519 }
1520 1498
1521// if (incomingPacket.Packet.Type == PacketType.AgentUpdate || 1499// if (incomingPacket.Packet.Type == PacketType.AgentUpdate ||
1522// incomingPacket.Packet.Type == PacketType.ChatFromViewer) 1500// incomingPacket.Packet.Type == PacketType.ChatFromViewer)
@@ -1525,7 +1503,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1525// else 1503// else
1526// packetInbox.Enqueue(incomingPacket); 1504// packetInbox.Enqueue(incomingPacket);
1527 packetInbox.Add(incomingPacket); 1505 packetInbox.Add(incomingPacket);
1528
1529 } 1506 }
1530 1507
1531 #region BinaryStats 1508 #region BinaryStats
@@ -1685,7 +1662,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1685 { 1662 {
1686 m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present"); 1663 m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present");
1687 return; 1664 return;
1688
1689 } 1665 }
1690 m_pendingCache.Remove(endPoint); 1666 m_pendingCache.Remove(endPoint);
1691 } 1667 }
@@ -1881,13 +1857,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1881 byte[] packetData = ack.ToBytes(); 1857 byte[] packetData = ack.ToBytes();
1882 int length = packetData.Length; 1858 int length = packetData.Length;
1883 1859
1884 UDPPacketBuffer buffer = new UDPPacketBuffer(remoteEndpoint, length); 1860 UDPPacketBuffer buffer = GetNewUDPBuffer(remoteEndpoint);
1885 buffer.DataLength = length; 1861 buffer.DataLength = length;
1886 1862
1887 Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length); 1863 Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length);
1888 1864
1889// AsyncBeginSend(buffer); 1865// AsyncBeginSend(buffer);
1890 SyncSend(buffer); 1866 SyncSend(buffer);
1867 FreeUDPBuffer(buffer);
1891 } 1868 }
1892 1869
1893 protected bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo) 1870 protected bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo)
@@ -1982,21 +1959,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1982 Scene.ThreadAlive(1); 1959 Scene.ThreadAlive(1);
1983 try 1960 try
1984 { 1961 {
1985 packetInbox.TryTake(out incomingPacket, 250); 1962 packetInbox.TryTake(out incomingPacket, 4500);
1986 1963
1987 if (incomingPacket != null && IsRunningInbound) 1964 if (incomingPacket != null && IsRunningInbound)
1988 { 1965 {
1989 ProcessInPacket(incomingPacket); 1966 ProcessInPacket(incomingPacket);
1990
1991 if (UsePools)
1992 {
1993 incomingPacket.Client = null;
1994 m_incomingPacketPool.ReturnObject(incomingPacket);
1995 }
1996 incomingPacket = null; 1967 incomingPacket = null;
1997 } 1968 }
1998 } 1969 }
1999 catch(Exception ex) 1970 catch (ThreadAbortException)
1971 {
1972 Thread.ResetAbort();
1973 }
1974 catch (Exception ex)
2000 { 1975 {
2001 m_log.Error("[LLUDPSERVER]: Error in the incoming packet handler loop: " + ex.Message, ex); 1976 m_log.Error("[LLUDPSERVER]: Error in the incoming packet handler loop: " + ex.Message, ex);
2002 } 1977 }
@@ -2025,7 +2000,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2025 { 2000 {
2026 Scene.ThreadAlive(2); 2001 Scene.ThreadAlive(2);
2027 2002
2028
2029 try 2003 try
2030 { 2004 {
2031 m_packetSent = false; 2005 m_packetSent = false;
@@ -2080,7 +2054,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2080 } 2054 }
2081 else if (!m_packetSent) 2055 else if (!m_packetSent)
2082// Thread.Sleep((int)TickCountResolution); outch this is bad on linux 2056// Thread.Sleep((int)TickCountResolution); outch this is bad on linux
2083 Thread.Sleep(15); // match the 16ms of windows7, dont ask 16 or win may decide to do 32ms. 2057 Thread.Sleep(15); // match the 16ms of windows, dont ask 16 or win may decide to do 32ms.
2084 2058
2085 Watchdog.UpdateThread(); 2059 Watchdog.UpdateThread();
2086 } 2060 }
@@ -2104,14 +2078,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2104 2078
2105 if (udpClient.IsConnected) 2079 if (udpClient.IsConnected)
2106 { 2080 {
2107 if (m_resendUnacked) 2081 if (client.IsActive && m_resendUnacked)
2108 HandleUnacked(llClient); 2082 HandleUnacked(llClient);
2109 2083
2110 if (m_sendAcks) 2084 if (client.IsActive)
2111 SendAcks(udpClient); 2085 {
2086 if (m_sendAcks)
2087 SendAcks(udpClient);
2112 2088
2113 if (m_sendPing) 2089 if (m_sendPing)
2114 SendPing(udpClient); 2090 SendPing(udpClient);
2091 }
2115 2092
2116 // Dequeue any outgoing packets that are within the throttle limits 2093 // Dequeue any outgoing packets that are within the throttle limits
2117 if (udpClient.DequeueOutgoing()) 2094 if (udpClient.DequeueOutgoing())
@@ -2124,7 +2101,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2124 m_log.Error( 2101 m_log.Error(
2125 string.Format("[LLUDPSERVER]: OutgoingPacketHandler iteration for {0} threw ", client.Name), ex); 2102 string.Format("[LLUDPSERVER]: OutgoingPacketHandler iteration for {0} threw ", client.Name), ex);
2126 } 2103 }
2127 client = null;
2128 } 2104 }
2129 2105
2130 #region Emergency Monitoring 2106 #region Emergency Monitoring